Read my latest article: Was away on vacation (posted Sun, 11 May 2008 22:33:00 GMT)

Be Careful that you don't Stub your Big Toe 6

Posted by Robby Russell Tue, 13 Feb 2007 07:09:00 GMT

In a project that I’m currently working on, we’re handling recurring payments for subscribers. I’ve decided to play with a different payment service API on this project (TrustCommerce), which supposedly has one of the easier systems to handle recurring payments as well as one-time charges to the same credit cards. They store all the credit card data so that our delivered product to the client is CISP-compliant.

I came across the TrustCommerce Subscription plugin for Rails, which does just everything that I need to do in this first product release… as well as things that aren’t requirements just yet.

Well, I got my test account from TrustCommerce and was working on some RSpecs to test my new subscription and noticed that it was failing. After some snooping around the error responses, I realized that… test accounts don’t give you the ability to test the Citadel features of TrustCommerce. It’ll be another week or so before finish getting our account setup, so what am I to do? I really want to finish writing these specs and move on to the other portions that are dependent upon this working.

Suppose that you were going to perform something like this in an AR callback.


class BillingDetail < ActiveRecord::Base

  # validations    

  before_create :store_credit_card_data_with_trust_commerce

  private 

    def store_credit_card_data_with_trust_commerce
      # some of this is still test data... prettyu much copied from the README
      # TODO: refactor... but keep me out of controllers!
      response = TrustCommerceGateway::Subscription.create(
          :cc =>  self.credit_card_number, 
          :exp => '0412', 
          :name => self.customer_name,
          :amount => 1,
          :cycle => '1y',
          :demo => 'y'
        )

      if response['status'] == 'approved'
          self.billing_id = response['billingid']
        else
        # handle failure
        end
    end
end

Enter Mock Objects

Since I am unable to succesfully use the TrustCommerceGateway::Subscription.create method until I get our real account, I needed a simple way to emulate the interaction with the web service.

This can be done by using a Mock object, which RSpec provides for you.


TrustCommerceGateway::Subscription.stub!(:create).and_return( {expected response} )

Let’s look at the following spec file (much of it removed to protect the innocent).


module ValidBillingDetail
  def valid_attributes
    { # a hash of valid key/values for this model }
  end

  def approved_trust_commerce_subscription
    { 'status' => 'approved', 'billingid' => '1093423' } 
  end
end

context "A new billing detail" do
  include ValidBillingDetail

  setup do
    TrustCommerceGateway::Subscription.stub!(:create).and_return( approved_trust_commerce_subscription )
  end

  # bunch of other specs

  specify "should store new billing info with 3rd party API and store the billingid" do
    @billing_detail = BillingDetail.create( valid_attributes )
    @billing_detail.billing_id.should_not_be nil
  end
end  

You’ll notice a few things. First, you’ll see that I’ve stubbed the create method and when it is called in the method in my model, it’ll return the hash that I’ve specified.

TrustCommerceGateway::Subscription.stub!(:create).and_return( approved_trust_commerce_subscription )

In the spec, you will see that I am checking that that the .billing_id.should_not_be nil. If you look back in the method in the model above, you will notice that an approved subscription returns a billing_id, which is set when the transaction is successful.

This is working out great for me and because the documentation is fairly easy to follow, I’m going to be able to mock much of the behavior that I’ll be using in the application, without needing to even connect to their API.

If you’re using RSpec, I highly encourage you to read more about mocks objects.

Subscribe to my RSS feed Enjoying the content? Be sure to subscribe to my RSS feed.
Comments

Leave a response

  1. Avatar
    Marston Tue, 13 Feb 2007 09:10:05 GMT

    Hey Robby,

    Very interesting. I’m mulling over subscription based ecommerce solutions for our app as well. Its been a bit sticky regarding a solid solution for recurring subscriptions.

    Are you guys using something like ActiveMerchant with this project (I’ve heard it works well with TrustCommerce?) or are you using just the TrustCommerce subscription plugin?

    From what I’ve seen it seems TrustCommerce is probably the best way to go in regards to Rails payment processing with recurring subscriptions. More than say PayPal Payment Pro. Would you agree?

  2. Avatar
    Robby Russell Tue, 13 Feb 2007 13:47:47 GMT

    Marston,

    Based on my research on the available options that have a nice API for managing recurring payments… and I was impressed with their platform as a whole.

    One of my requirements for an API was that I need to be able to make a charge against the credit card information that the 3rd party service is charging. In an effort to be CISP-compliant, they’ll host everything and I can make charges against the card based on my own recurring cycles.

    As far as the library, I am currently just going to tuse the TrustCommerce plugin because of it’s focus on subscription type transactions, which is all that I’m working on in the application that I’m working on with my team.

  3. Avatar
    Zack Tue, 13 Feb 2007 21:29:18 GMT

    Glad you find the subscription plugin useful. I have been very happy with TC in general. The API is intuitive and simple. As far as waiting for the Citadel features to be added, just ask. I have a test account enabled with full Citadel functionality.

  4. Avatar
    Jesse Wed, 28 Feb 2007 01:16:07 GMT

    Hi Robby,

    Glad you found a solution that worked for you. Just thought I’d let you know that you can also just ask TrustCommerce to enable Citadel for your test account. That’s what I did. :)

  5. Avatar
    Marston A. Thu, 31 May 2007 22:30:40 GMT

    Hey Robby,

    I noticed in another blog post regarding the TC subscriptions plugin you had the following error:

    {“status”=>”baddata”, “error”=>”merchantcantaccept”, “offenders”=>”action”}

    You then posted a comment saying it was working. I’m getting the same errors in my test and was wondering what you did to solve the problem? (I’ve verified our account has Citadel enabled). Thanks if you can give any assistance.

  6. Avatar
    jake Fri, 30 Nov 2007 20:54:14 GMT

    Marston,

    I am having a similar problem, tests run like a dream but… when I run my code I get

    {“status”=>”baddata”, “error”=>”merchantcantaccept”, “offenders”=>”action”}

    What was your fix? My environment.rb set up looks like this

    TrustCommerceGateway::ACCOUNT_SETTINGS = { :custid => ‘123456’, :password => ‘password’, :vault_password => ‘password’ }

Share your thoughts... (really...I want to hear them)

Comments