Skip to Content

Server to Server Card NGN Payments

Overview

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

Integration Steps

Follow these steps to integrate 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://api.cashonrails.com/api/v1/s2s

1. Collect Card Information

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

{ "data": { "number": "4242424242424242", "cvv": "123", "expiryMonth": "12", "expiryYear": "23", // 2 digits format "pin": "1234" // Required for local cards }, "reference": "{{reference}}" }

Required Fields:

FieldDescription
numberCard number
cvvCard verification value
expiryMonthCard expiry month (2 digits)
expiryYearCard expiry year (2 digits)
pinCard PIN (for local cards)
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: "4242424242424242", cvv: "123", expiryMonth: "12", expiryYear: "23", // 2 digits format pin: "1234" }; 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": "4242424242424242", "cvv": "123", "expiryMonth": "12", "expiryYear": "23", // 2 digits format "pin": "1234" // Required for local cards }, "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": "5000", "currency": "NGN", "email": "customer@example.com", "reference": "COR_202402210123456789" }'

4. Handle 3D Secure

If 3DS is required, you’ll receive a response with authentication URL:

{ "success": true, "message": "Proceed to card authentication", "data": { "gatewayRecommendation": "AUTHENTICATE", "transactionId": "cor_tx_20240221123456789", "orderId": "COR_202402210123456789" }, "_links": { "url": "https://api.cashonrails.com/api/v1/3ds/authenticate/cor_tx_20240221123456789", "method": "POST", "payload": "reference,transactionId,orderId" } }

After receiving this response, make a POST request to the URL provided in _links.url with the following data:

curl -X POST "https://api.cashonrails.com/api/v1/3ds/authenticate/cor_tx_20240221123456789" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_SECRET_KEY" \ -d '{ "reference": "COR_202402210123456789", "transactionId": "cor_tx_20240221123456789", "orderId": "COR_202402210123456789" }'

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

Card TypeNumberCVVExpiryPIN
Visa400000000000000913002/291234
Mastercard512345000000000932502/291234
Verve5060990580024711112102/351234
Verve (Failed)5060990520011000012102/261234
Last updated on