Why Is ActiveMerchant Your Secret Weapon for Payment Gateways in Ruby on Rails?

Breathe New Life into Payments with ActiveMerchant in Your Rails App

Why Is ActiveMerchant Your Secret Weapon for Payment Gateways in Ruby on Rails?

When thinking about baking payment gateways into your Ruby on Rails app, a must-have tool in your kit is the ActiveMerchant gem. It’s a favorite among developers for its flexibility and ease of use, providing a unified API to juggle dozens of different payment gateways.

ActiveMerchant is the brainchild of the e-commerce giant Shopify, extracted to offer a seamless interface across all supported gateways. It’s been around since June 2006 and has become a go-to for many modern Ruby applications that need to handle financial transactions.

So, what makes ActiveMerchant so sweet? First off, it’s got this unified API that makes dealing with different payment gateways a breeze. This unified approach means you’re not tied down to one provider; you can switch easily if you find a better deal or need different features. Secondly, ActiveMerchant shines in its support for multiple payment gateways, such as Stripe, PayPal, and Authorize.net, among others. This means you can pick and choose the best solutions to fit your app’s needs.

Another high note is PCI compliance, a non-negotiable when handling financial data. ActiveMerchant nudges you toward using tokens rather than raw credit card information, keeping sensitive data at arm’s length and enhancing your app’s security posture.

Now, Stripe is among the top picks for payment gateways, loved for its robustness and user-friendly features. Let’s dive into how you can pair Stripe with ActiveMerchant in your Rails app.

Start by adding the ActiveMerchant gem to your app through your Gemfile:

gem 'activemerchant'

Hit up bundle install to get the gem in place.

Next, create a Stripe gateway object. Here’s how you can set up a Stripe gateway in test mode:

ActiveMerchant::Billing::Base.mode = :test
gateway = ActiveMerchant::Billing::StripeGateway.new(
  login: Rails.application.credentials.development[:stripe_private_key]
)

Handling credit card details securely is as critical as making the payment itself. Instead of pushing raw credit card details straight to the gateway, use Stripe’s Checkout or Elements libraries to create a token client-side and then send that to your server. Here’s a snippet of how this looks on the client-side:

// Client-side code to create a token
const stripe = Stripe('your_stripe_public_key');
const elements = stripe.elements();
const card = elements.create('card');
card.mount('#card-element');

const form = document.getElementById('payment-form');
form.addEventListener('submit', async (event) => {
  event.preventDefault();
  const { token } = await stripe.createToken(card);
  if (token) {
    // Send the token to your server
    const response = await fetch('/create-charge', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token: token.id }),
    });
    const responseData = await response.json();
    // Handle the response
  } else {
    // Handle the error
  }
});

Once the token is on the server, authorize or capture payments like this:

# Server-side code to authorize a payment using the token
token = params[:token]
gateway = ActiveMerchant::Billing::StripeGateway.new(
  login: Rails.application.credentials.development[:stripe_private_key]
)
response = gateway.authorize(1000, token)
if response.success?
  # Capture the money
  gateway.capture(1000, response.authorization)
else
  raise StandardError, response.message
end

Let’s put this all together in a full example:

  1. Set Up the Gateway:

    # config/initializers/active_merchant.rb
    ActiveMerchant::Billing::Base.mode = :test
    ::GATEWAY = ActiveMerchant::Billing::StripeGateway.new(
      login: Rails.application.credentials.development[:stripe_private_key]
    )
    
  2. Create a Form to Collect Payment Information:

    <!-- app/views/orders/new.html.erb -->
    <form id="payment-form">
      <div id="card-element"></div>
      <button type="submit">Submit Payment</button>
    </form>
    
    <script>
      const stripe = Stripe('your_stripe_public_key');
      const elements = stripe.elements();
      const card = elements.create('card');
      card.mount('#card-element');
    
      const form = document.getElementById('payment-form');
      form.addEventListener('submit', async (event) => {
        event.preventDefault();
        const { token } = await stripe.createToken(card);
        if (token) {
          // Send the token to your server
          const response = await fetch('/create-charge', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ token: token.id }),
          });
          const responseData = await response.json();
          // Handle the response
        } else {
          // Handle the error
        }
      });
    </script>
    
  3. Handle the Payment on the Server Side:

    # app/controllers/orders_controller.rb
    class OrdersController < ApplicationController
      def create
        token = params[:token]
        response = ::GATEWAY.authorize(1000, token)
        if response.success?
          # Capture the money
          ::GATEWAY.capture(1000, response.authorization)
          render :action => "success"
        else
          raise StandardError, response.message
        end
      end
    end
    

Using ActiveMerchant has its perks. The unified API means less hassle wrangling different payment providers. Security gets a boost with tokenization, hugging PCI compliance tight and reducing exposure to risks. Plus, the gem simplifies the whole integration process, letting you focus more on other parts of your application.

ActiveMerchant, when used with Stripe, can streamline your payment processes, making them secure and efficient. The examples show how to create a Stripe gateway, deal with credit card info securely, and process payments with tokens. This method not only tidies up your code but also bolsters the security and reliability of your financial transactions.

Integrating ActiveMerchant into your Rails application ensures a payment system that’s both smooth and safeguarded. For every app dealing with financial transactions, ActiveMerchant is a vital addition to the toolkit.