CheddarGetter Beginner

Paul A.'s Avatar

Paul A.

18 Jul, 2010 01:02 AM

Hi! I'm looking to implement CheddarGetter into a rails app I've built. I've decided to go with the "cheddargetter" gem since it's the only one that provided documentation. As a beginner developer, however, I am unsure where in my models/controllers I should put in what. Any suggestions?

  1. 1 Posted by Paul A. on 18 Jul, 2010 04:06 AM

    Paul A.'s Avatar

    better yet, can someone provide a good (working) example of Mousetrap or cheddargetter?

  2. Support Staff 2 Posted by Marc Guyer on 18 Jul, 2010 09:43 PM

    Marc Guyer's Avatar

    Hi l4rk & Cameron! Would you guys mind pointing Paul in the right direction?

  3. 3 Posted by Charlie Zhao on 17 Oct, 2010 03:56 AM

    Charlie Zhao's Avatar

    I am interested in this too. An example with controller/model/view which is using cheddargetter gem will be appreciated.

  4. 4 Posted by Phil on 25 Oct, 2010 02:38 PM

    Phil's Avatar

    Using this library: You can do something like the following in you controller...

     @cheddar_getter =, CHEDDAR_PASS, CHEDDAR_PRODUCT)
     @cheddar_getter.create_customer("code" => params[:account][:name].upcase, "firstName" => params[:user][:first_name], "lastName" => params[:user][:last_name], "email" => params[:user][:email], "subscription[planCode]" => params[:account][:plan].upcase, "subscription[ccNumber]" => params[:cc_number], "subscription[ccExpiration]" => "#{params[:cc_expiration_month]}/#{params[:cc_expiration_year]}", "subscription[ccCardCode]" => params[:cc_card_code], "subscription[ccFirstName]" => params[:user][:first_name], "subscription[ccLastName]" => params[:user][:last_name], "subscription[ccZip]" => params[:cc_post_code], "subscription[ccCompany]" => params[:account][:name].capitalize)
  5. 5 Posted by Jon Larkowski on 26 Oct, 2010 03:23 PM

    Jon Larkowski's Avatar

    Here's an extract of some actual code I have that consumes my Mousetrap gem The concepts may be general enough to help with whatever wrapper you choose.

    A few notes:

    1. I deleted a bunch of code from the actual production code to remove noise and highlight the main concepts at play. So, don't expect this code to actually run.
    2. The main trick to note is that we validate locally in the controller, before we ever even attempt to talk to CheddarGetter API. This keeps us from unnecessarily sending invalid data to CheddarGetter.
    3. We also don't even save the subscription record locally unless CheddarGetter reports no errors. This keeps us from having a subscription locally with no actual subscription on CheddarGetter.
    4. We make use of nested attributes. The Business model accepts nested attributes for Subscription (the app used to save business information fields at the same time as credit card data, all in one form). Then we do a homemade version of nested attributes where the Subscription accepts credit card attributes. The credit card is validated by the ActiveMerchant gem, but we don't use ActiveMerchant for anything else.


    class SubscriptionPlansController < ApplicationController
      def update
        @business =
        old_subscription = @business.subscription
        @subscription =[:business][:subscription_attributes])
        @subscription.business_id =
        cheddar_getter_error_message = nil
        if @subscription.valid? && !(cheddar_getter_error_message = @subscription.save_on_cheddar_getter)
          old_subscription.cancel! if old_subscription
          @subscription.errors.add_to_base cheddar_getter_error_message if cheddar_getter_error_message.present?
      def destroy
        @business =

    Subscription model

    class Subscription < ActiveRecord::Base
      belongs_to :business
      attr_reader :credit_card
      attr_accessor :credit_card_number
      before_validation_on_create :assign_customer_code
      validates_format_of :billing_zip_code, :with => /^\d{5}$/, :message => "must be five digits"
      validates_presence_of :credit_card_last_digits
      validates_presence_of :customer_code
      validate :validate_credit_card
      def cancel!
        update_attribute :canceled_at,
      def credit_card
        @credit_card || make_credit_card
      def credit_card=(card)
        @credit_card = card
        self.credit_card_number           = @credit_card.try :number
        self.credit_card_expiration_month = @credit_card.try :month
        self.credit_card_expiration_year  = @credit_card.try :year
        self.credit_card_last_digits      = @credit_card.try :last_digits
        self.billing_first_name           = @credit_card.try :first_name
        self.billing_last_name            = @credit_card.try :last_name
      def credit_card_attributes=(attributes)
        self.credit_card = make_credit_card(attributes)
      def save_on_cheddar_getter
        new_record? ? create_on_cheddar_getter : update_on_cheddar_getter
      def create_on_cheddar_getter
        customer_attributes = {
          :email      =>,
          :code       => customer_code,
          :first_name => business.user.first_name,
          :last_name  => business.user.last_name,
          :company    => business.subdomain,
          :subscription_attributes => {
            :plan_code                    => 'SOME_PLAN_CODE',
            :credit_card_number           => credit_card_number,
            :credit_card_expiration_month => credit_card_expiration_month,
            :credit_card_expiration_year  => credit_card_expiration_year,
            :billing_first_name           => billing_first_name,
            :billing_last_name            => billing_last_name,
            :billing_zip_code             => billing_zip_code,
        Mousetrap::Customer.create customer_attributes
      rescue => error
        Rails.logger.error error.message
      def update_on_cheddar_getter
        mousetrap_attributes = {}
        MOUSETRAP_SYNC_FIELDS.each do |f|
          field_symbol = f.to_sym
          mousetrap_attributes[field_symbol] = send(field_symbol)
        Mousetrap::Subscription.update(customer_code, mousetrap_attributes)
      rescue => error
        Rails.logger.error error.message
      def cancel_customer_on_cheddar_getter
        customer = Mousetrap::Customer[customer_code]
      def credit_card_display_number
      def assign_customer_code
        self.customer_code ||= UUIDTools::UUID.random_create.to_s
      def make_credit_card(attributes = {})
        ActiveMerchant::Billing::CreditCard.require_verification_value = false
        credit_card =
        def credit_card.new_record?
      def validate_credit_card
        unless credit_card.valid?
          credit_card.errors.each do |field, messages|
            messages.each do |message|
              errors.add("credit_card_#{field}".to_sym, message)

    Portion of the view

    - form_for @business, :url => subscription_plan_path do |bf|
      - bf.fields_for :subscription do |sf|
        - sf.fields_for :credit_card do |fc|
            .label_card_type= fc.label :type, "Card Type"
            = :type, [['Visa', 'visa'], ['MasterCard', 'master']]
            .label= fc.label :number, "Card Number"
            .entry= fc.text_field :number
            .label= fc.label :year, "Expiration Date"
              = :month, '01'..'12', :selected => @credit_card.month.to_s.rjust(2, "0")
              = :year,
            .label= fc.label :first_name, "Billing First Name"
            .entry= fc.text_field :first_name
            .label= fc.label :last_name, "Billing Last Name"
            .entry= fc.text_field :last_name
            .label= sf.label :billing_zip_code, "Billing Zip Code"
            .entry= f.text_field :billing_zip_code, :maxlength => 5
      = bf.submit
  6. 6 Posted by joshua on 25 Nov, 2010 04:30 PM

    joshua's Avatar

    Thanks for this detailed example Jon. Am I correct in assuming that you save the credit card number in your local subscription table? Is that a problem for PCI compliance? So far I am only storing the last 4 digits locally.

  7. 7 Posted by Jon Larkowski on 25 Nov, 2010 05:04 PM

    Jon Larkowski's Avatar

    @joshua You're welcome. No, I don't save the full credit card number. That would definitely be a PCI issue. Want to avoid as many of those as possible. ;) Like you, I just store the last four digits.

  8. 8 Posted by joshua on 25 Nov, 2010 07:53 PM

    joshua's Avatar

    Jon, thanks for the quick reply. Just one question then - where does the following variable live if the model has no credit card fields?

    self.credit_card_expiration_month = @credit_card.try :month
  9. 9 Posted by Jon Larkowski on 13 Dec, 2010 07:55 PM

    Jon Larkowski's Avatar

    @joshua Sorry for the delay. I just had to quit my job and move cross-country quick. ;)

    I do store the credit_card_expiration_month field in the database. Pretty much everything except the actual credit card number is stored. Here's the relevant portion of the schema.rb file.

    create_table "subscriptions", :force => true do |t|
      t.integer  "business_id"
      t.string   "plan_code"
      t.datetime "canceled_at"
      t.datetime "suspended_at"
      t.string   "billing_first_name"
      t.string   "billing_last_name"
      t.integer  "credit_card_expiration_month"
      t.integer  "credit_card_expiration_year"
      t.string   "credit_card_last_digits"
      t.string   "billing_zip_code"
      t.datetime "created_at"
      t.datetime "updated_at"
      t.string   "customer_code"
  10. 10 Posted by joshua on 13 Dec, 2010 08:15 PM

    joshua's Avatar

    Thanks Jon - i figured that bit out. I was wondering if this is a PCI issue, storing some but not all CC info?

    Anyway, thanks for the assistance, this helped me move along with my setup.

  11. Dean closed this discussion on 16 Jan, 2013 03:41 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts


? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac