Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
OrganizationEventAdvent CalendarQiitadon (β)
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

ActiveMerchant and Payment Gateways


Note: For native English speakers and high ability non-native speakers
I have attempted to write this post using simplified English grammar to hopefully aid reading comprehension for English learners, and to also aid machine translation. So, I may use shorter sentences and less complicated grammar constructs.


In this post I will write about Payment Gateways and the card purchase process. After, I will then write about the ActiveMerchant RubyGem.

Payment Gateways and Credit Card Processing

How are Credit Card purchases processed?

Entities in Purchase process


The Process

The diagram above shows the key actors in the process. In my previous and current work experience, I've been writing the software at two places. First was for Issuing banks. (Integration from Bank to Visa). More recently, it is software at the Merchant.

During a purchases purchase:
1. Card Details (or a token representing a card) are passed from Customer
2. ... Into Merchant Software (the EC Site)
3. ... Sends request to Payment Gateway
4. ... Gateway selects which Payment Processor to communicate with
5. ... Sends request to Payment Processor
6. ... Sends request to correct Card Association
7. ... Sends request to Issuing Bank (except American Express and Discover, who are ALSO the Issuing Bank)

Payment Flow and State Transition

Below is generic description of the purchase flow.


Different Gateways may provide different, or additional functionality. In fact, each Gateway will have very specific differences which the merchant needs to handle.


  • Some Gateways only support AUTH and SALE using the Card Token obtained during STORE.
  • Some Gateways may NOT support VOID after a CAPTURE, and/or SALE.
  • Some Gateways may NOT support VOID after a CAPTURE, and/or SALE, if a certain time has expired.
  • Gateways will have different expirations for AUTH. If x time passes, and AUTH will be automatically VOIDed by Gateway, and a CAPTURE will fail.
  • Some Gateways may not support SALE.
  • Some Gateways may NOT support partial REFUND.

This means, if a Merchant needs to support multiple Gateways, a large amount of custom code will need to be written.

A merchant could write their own adapter layer. This will provide a unified API to the main merchant Store software.
The alternative is to use Open Source software.


ActiveMerchant is a RubyGem written and maintained by Shopify. It's goal is to provide a simple unified API to a lot of different Payment Gateways.

The source code is open source. So, you can contribute code for new gateways. You could also fork, and maintain your own version with custom Gateway integration.

In my previous employment, I maintained an ActiveMerchant fork. This contained our code for integration with three Payment Gateways not supported by the master ActiveMerchant branch.


ActiveMerchant provides a guide on how to use and write your own integration.

Typically, you will use an existing subclass of ActiveMerchant::Billing::Gateway, or write a new one.

Standard Methods

Typically, each ActiveMerchant::Billing::Gateway will provide implementation for the following:

Method State Equivalent Notes
purchase SALE Perform a combined AUTH/CAPTURE, with specified amount, using supplied Card Token (or supplied card details
authorize AUTH Perform an AUTH, for a specified amount, using supplied Card Token (or supplied card details
capture CAPTURE Capture a previous AUTH
void VOID Cancel a previous SALE, AUTH, or CAPTURE (if gateway supports it)
refund REFUND Perform a second transaction, to repay Cardholder. Partial may be possible.
verify Some Gateways support verification of card details
store STORE Use supplied card details, and obtain a card token.

Example Code

STRIPE requires the use of JSON in their calls. post is a Ruby hash with request parameters. These are then sent to STRIPE.

Also note, the payment parameter with STRIPE can ONLY be a card token (a String). It cannot be a ActiveMerchant::Billing::CreditCard instance, which the base class supports.

# To create a charge on a card or a token, call
#   purchase(money, card_hash_or_token, { ... })
# To create a charge on a customer, call
#   purchase(money, nil, { :customer => id, ... })
def purchase(money, payment, options = {})
  if ach?(payment)
    direct_bank_error = "Direct bank account transactions are not supported. Bank accounts must be stored and verified before use."
    return Response.new(false, direct_bank_error)

  MultiResponse.run do |r|
    if payment.is_a?(ApplePayPaymentToken)
      r.process { tokenize_apple_pay_token(payment) }
      payment = StripePaymentToken.new(r.params["token"]) if r.success?
    r.process do
      post = create_post_for_auth_or_purchase(money, payment, options)
      commit(:post, 'charges', post, options)

The full code is available here.

def authorize(money, credit_card_or_vault_id, options = {})
  create_transaction(:sale, money, credit_card_or_vault_id, options)

def capture(money, authorization, options = {})
  commit do
    result = @braintree_gateway.transaction.submit_for_settlement(authorization, amount(money).to_s)

def purchase(money, credit_card_or_vault_id, options = {})
  authorize(money, credit_card_or_vault_id, options.merge(:submit_for_settlement => true))

BrainTree Blue has a different implementation. But, you can see it exposes the same API to the calling Merchant code.

Sample Architecture


The diagram is a very rough layout of a possible architecture.

In the case of a monolithic Rails application, ActiveMerchant is included directly via Gemfile. Then, we could write some form Gateway Service class layer. Here, we could write code to store and manage Gateway configuration. There should be code to instantiate the correct ActiveMerchant Gateway instance. Perhaps we would wrap this in a decorator.
If necessary, the decorator could store Gateway specific information that may be necessary for certain operations.

The EC site code would then call the appropriate decorator class when payment operations are required.

Alternatively, the Gateway code could be extracted out into a micro-service. This micro-service would include ActiveMerchant in it's Gemfile. The EC site code would then call the Payment micro-service.

References, Further Reading

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Help us understand the problem. What are the problem?