Server to Server Card GHS Payments

Overview

Process GHS card payments directly through your server using Cashonrails S2S APIs.

Integration Steps

Follow these steps to integrate GHS card payments using our Server to Server APIs:

  1. Collect Card Information

  2. Encrypt Card Data

  3. Initialize Transaction

  4. Handle 3D Secure

  5. Verify Transaction

  6. Cancel Transaction

  7. Test Cards

Each step has specific requirements and security considerations. Follow the detailed guides below for implementation.

Base URL

https://mainapi.cashonrails.com/api/v1/s2s

1. Collect Card Information

Collect the customer’s card details securely within your application:

{
  "data": {
    "number": "5123450000000008",
    "cvv": "100",
    "expiryMonth": "01",
    "expiryYear": "2039"
  },
  "reference": "{{reference}}"
}

Required Fields:

FieldDescription
numberCard number
cvvCard verification value
expiryMonthCard expiry month
expiryYearCard expiry year
referenceUnique transaction reference

2. Encrypt Card Data

Card details must be encrypted using AES-256-CBC encryption before transmission. This ensures sensitive data remains secure during the API call.

Encryption Requirements
ParameterDescription
AlgorithmAES-256-CBC
KeyYour Cashonrails public key
IVFirst 16 characters of transaction reference
Input FormatJSON string of card data
Output FormatHexadecimal string
Code Examples
const crypto = require('crypto');
 
function encryptCardDetails(cardData, publicKey) {
  // Generate reference with prefix and timestamp
  const reference = `COR_${Date.now()}`;
  
  // Use first 16 chars of reference as IV
  const iv = reference.slice(0, 16);
  
  // Prepare the encryption key
  const key = Buffer.from(publicKey, 'utf-8');
  const ivBuffer = Buffer.from(iv, 'utf-8');
  
  try {
    // Create cipher
    const cipher = crypto.createCipheriv('aes-256-cbc', key, ivBuffer);
    
    // Encrypt the data
    let encrypted = cipher.update(JSON.stringify(cardData), 'utf8', 'hex');
    encrypted += cipher.final('hex');
    
    return {
      encryptedData: encrypted,
      reference: reference
    };
  } catch (error) {
    throw new Error(`Encryption failed: ${error.message}`);
  }
}
 
// Usage example
const cardData = {
  number: "5123450000000008",
  cvv: "100",
  expiryMonth: "01",
  expiryYear: "2039"
};
 
const result = encryptCardDetails(cardData, 'YOUR_PUBLIC_KEY');
console.log(result);
Testing Encryption

To verify your encryption implementation:

  1. Generate encrypted data using the code above
  2. Test the encryption using our verification endpoint:
curl -X POST {{baseurl}}/test/encryption \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-d '{
  "data": {
    "number": "5123450000000008",
    "cvv": "100",
    "expiryMonth": "01",
    "expiryYear": "2039"
  },
  "reference": "COR_202402210123456789"
}'

Success response:

{
    "status": true,
    "message": "Encryption verified successfully"
}

The encryption verification endpoint helps ensure your implementation is correct before attempting actual transactions.

Common Encryption Issues
  1. Invalid IV Length: Ensure your IV is exactly 16 bytes
  2. Incorrect Key Format: Use the raw public key string without formatting
  3. Data Structure: Card data must be a valid JSON object before encryption
  4. Reference: Must always be unique for every transaction
⚠️

Never log or store the raw card details. Only work with encrypted values when saving to your database.

3. Initialize Transaction

Send encrypted card data to initialize the transaction:

curl -X POST {{baseurl}}/card/initialize \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-d '{
    "card": "encrypted_card_data",
    "amount": "500",
    "currency": "GHS",
    "email": "customer@example.com",
    "reference": "COR_202402210123456789"
}'

4. Handle 3D Secure

For GHS payments, 3D Secure authentication is typically required. After initialization, you’ll receive a response with 3DS details:

{
    "success": true,
    "message": "Proceed to card authentication",
    "data": {
        "redirectHtml": "<div id='redirectTo3ds1AcsSimple' xmlns='http://www.w3.org/1999/html'> <iframe id='redirectTo3ds1Frame' name='redirectTo3ds1Frame' height='100%' width='100%' > </iframe> <form id ='redirectTo3ds1Form' method='POST' action='https://mtf.gateway.mastercard.com/acs/VisaACS/068406b2-1421-4c48-bad4-d617612fda07' target='redirectTo3ds1Frame'> <input type='hidden' name='PaReq' value='eAFVkk9vgkAQxe9N+h0I6VV2F1ihZlyD0lZjqf8P7Y3CRkkEdMGq376z1GrLBd6bncfwG6B3yrfGl1RVVhZdk1nUNGSRlGlWrLvmavnc8s2euL+D5UZJGS5kclBSQCSrKl5LI0uxh+Jl+57fZjYzBUyDudwLuGQKjLRsIL8SW1WyiYtaQJzs+6M34TKbcgfIRUIu1SgUDuUe53yow/EO5MeGIs6l+Hh6Gy2HxsvrpB+8ToN3o2U8tQaTKALS1CEpD0WtzoK320B+BRzUVmzqeld1CDkej9Z6W37G2118tpIyt4o1EH0CyG3E6UEPW+EXn7JU1C/DXDp+NA5X+9mcn0ZR2H8fT88zVXaB6BOQxrUUNrU55cwxGOtQr+NSII0Pca7nEqtFaDwgF/QvDuz0i4KfMgIF8tcAhK5wK2fh66yrAnnalYXERAR8fQZym3ow1JiTGoG6zPdcznzXpdxt248aeFPQKRmychj1mhgtgOhWctklEmn2jc6//+D+7huloLbr' /> <input type='hidden' name='TermUrl' value='https://mtf.gateway.mastercard.com/callbackInterface/gateway/63af772bed0bf45feaa703bac6aa55ae0da1a8648195d9f23cffd9a1cb3d0a76' /> <input type='hidden' name='MD' value='' /> </form> <script id='authenticate-payer-script'> var e=document.getElementById('redirectTo3ds1Form'); if (e) { e.submit(); if (e.parentNode !== null) { e.parentNode.removeChild(e); } } </script> </div>",
        "do3dsAuth": true,
        "paymentCompleted": false,
        "threeDsUrl": "",
        "formData": ""
    },
    "_links": {
        "url": "https://mainapi.cashonrails.com/auth-payer/vxr2n5frkpl6wxm5sq3ckbbv8hwy46tl",
        "method": "GET"
    }
}

If the response shows "paymentCompleted": true, the payment was successful without requiring 3D Secure, and you can proceed to verify the transaction.

But if "do3dsAuth": true and "paymentCompleted": false, you need to handle 3D Secure authentication.

You have two options to handle 3D Secure authentication for GHS payments:

  1. Redirect the customer to the URL provided in _links.url
  2. Render the HTML content in data.redirectHtml within an iframe in your application
⚠️

GHS payments typically require 3D Secure authentication. Make sure your application can handle the redirect or iframe rendering as needed.

5. Verify Transaction

Always verify the transaction status before providing value:

curl -X GET {{baseurl}}/transaction/verify/{reference} \
-H "Authorization: Bearer YOUR_SECRET_KEY"

6. Cancel Transaction

You can cancel a transaction that is still pending or in progress:

curl -X GET {{baseurl}}/transaction/cancel/{reference} \
-H "Authorization: Bearer YOUR_SECRET_KEY"

Replace {reference} with your transaction reference.

Cancellation Rules
⚠️
  • Only pending or processing transactions can be cancelled
  • Completed transactions cannot be cancelled (use refund instead)
  • Failed transactions are already inactive and don’t need cancellation
  • Once cancelled, a transaction cannot be resumed

7. Test Cards for GHS

Card TypeNumberSuccessExpiryCVV
Mastercard5123450000000008True01/39100
Mastercard5111111111111118False01/39100