DEV Community

Cover image for Implementing BayarCash Payment API with Ruby: Validate Checksum
Aisha A
Aisha A

Posted on

3 1

Implementing BayarCash Payment API with Ruby: Validate Checksum

If you’ve ever had to integrate a payment platform, you know the struggle can sometimes feel real when the company doesn't provide a doc in your preferred language. Recently, I helped ZFB Travel, a travel agency in Kuala Lumpur with Ruby on Rails backend, implement BayarCash, a local Malaysian payment platform. While the documentation provided a PHP example, there was no Ruby version, which left me as a Rails developer scratching head.

Let’s break this down step by step so you can validate a BayarCash checksum in Rails.

The PHP Example

BayarCash’s documentation gives a PHP implementation for generating a checksum. Here’s the snippet they provide:

<?php
$secretKey = 'xxxxx';  // Your API secret key from BayarCash portal

$payloadData = [
    "payment_channel"  => 1,
    "order_number"     => "ORD-0060",
    "amount"           => "60.00",
    "payer_name"       => "Mohd Ali",
    "payer_email"      => "mohd.ali@gmail.com"
];

ksort($payloadData);  // Sort the payload data by key
$payloadString = implode('|', $payloadData);  // Concatenate values with '|'

$checksum = hash_hmac('sha256', $payloadString, $secretKey);  // Generate HMAC SHA256 checksum
Enter fullscreen mode Exit fullscreen mode

It’s fairly straightforward: sort the payload, join the values with a pipe (|), and generate the checksum using HMAC SHA256.

But here’s the problem: if you’re working in Ruby, translating this into Ruby isn’t as intuitive as it seems.


Rails: Validating the Checksum

If you’re part of any local Rails groups, you might’ve seen people struggling with this. Some spend hours debugging this part of the integration. That’s why I’m sharing a clean solution to validate the BayarCash checksum in Ruby on Rails.

Here’s how you can do it:

# Your BayarcashService class

def valid_checksum?(params)
  # Extract the received checksum
  received_checksum = params['checksum']

  # Define the payload data in the exact order specified
  payload_data = {
    'record_type' => params['record_type'],
    'transaction_id' => params['transaction_id'],
    'exchange_reference_number' => params['exchange_reference_number'],
    'exchange_transaction_id' => params['exchange_transaction_id'],
    'order_number' => params['order_number'],
    'currency' => params['currency'],
    'amount' => params['amount'],
    'payer_name' => params['payer_name'],
    'payer_email' => params['payer_email'],
    'payer_bank_name' => params['payer_bank_name'],
    'status' => params['status'],
    'status_description' => params['status_description'],
    'datetime' => params['datetime']
  }

  # Sort the payload data by keys (similar to PHP's ksort)
  sorted_payload = payload_data.sort.to_h

  # Create payload string by joining values with '|'
  payload_string = sorted_payload.values.join('|')

  # Generate HMAC-SHA256 checksum
  generated_checksum = OpenSSL::HMAC.hexdigest(
    OpenSSL::Digest.new('sha256'), 
    SECRET_KEY, 
    payload_string
  )

  # Compare checksums (case-insensitive)
  ActiveSupport::SecurityUtils.secure_compare(
    generated_checksum.downcase, 
    received_checksum.downcase
  )
rescue => e
  Rails.logger.error "Checksum validation error: #{e.message}"
  false
end
Enter fullscreen mode Exit fullscreen mode
  1. Sorting the Payload: Like PHP’s ksort, Rails doesn’t have an out-of-the-box method to sort hashes by keys. Use hash.sort.to_h to get the same effect.
  2. String Formatting: Join the sorted hash values with a pipe (|) to match BayarCash’s requirements.
  3. Checksum Generation: Use OpenSSL::HMAC.hexdigest with the SHA256 algorithm and your secret key to generate the checksum.
  4. Secure Comparison: Comparing checksums securely ensures there’s no risk of timing attacks. Rails’ ActiveSupport::SecurityUtils.secure_compare is perfect for this.

Wrapping Up

With this implementation, you’ll be able to validate BayarCash checksums in your Rails app confidently. This approach not only saves you hours of debugging but also makes your integration seamless and secure. Let’s make Rails development smoother, one integration at a time!

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay