Card Charge

To integrate card payments, follow this guide to initiate charges, handle multi-step authentication (3DS, OTP, PIN, AVS), and verify transaction outcomes.

1 - Initiate Card Charge

FieldTypeRequiredDescription
amountNumberAmount to charge (e.g. 1500)
currencyString3-letter currency code (e.g. KES, NGN, USD)
emailStringCustomer email
firstNameStringCard holder first name
lastNameStringCard holder last name
transactionIdStringYour transaction ID used for tracking
cardDetails.numberStringCard PAN
cardDetails.cvvStringCard CVV
cardDetails.expMonthStringExpiry month (MM)
cardDetails.expYearStringExpiry year (YY)
addressObjectBilling address (required for
device3DSInfoObject3DS device data
ipAddressStringCustomer IP address
redirectUrlStringOptional redirect return URL (provider dependent)

Note: The card charge is processed asynchronously. Use the transactionId to track status via the get transaction endpoint or listen for webhooks.

To charge a customer, collect the required card details and send them to the charge card endpoint.

Example Request:

{
    "amount": 10,
    "ipAddress": "159.26.101.81",
    "currency": "USD",
    "email": "[email protected]",
    "firstName": "Bruce",
    "lastName": "Wayne",
    "externalReference": "123456789",
    "cardDetails": {
        "cvv": "000",
        "number": "4242424242424242",
        "expMonth": "09",
        "expYear": "28"
    },
    "address": {
        "zip": "10025",
        "country": "US",
        "street1": "1007 Mountain Drive",
        "city": "Gotham City",
        "state": "NJ"
    },
    "device3DSInfo": {
        "colorDepth": 30,
        "screenHeight": 1050,
        "screenWidth": 1680,
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
        "timeZone": 180,
        "deviceId": "29b435613857666dhgfdhg3b0a778471fbe9dc72db044886c7cc1175e4af632d4eb"
    }
}
{
    "amount": 100,
    "ipAddress": "102.218.103.10",
    "currency": "NGN",
    "email": "[email protected]",
    "firstName": "Wally",
    "lastName": "West",
    "externalReference": "525252525",
    "cardDetails": {
        "cvv": "052",
        "number": "4242424242424242",
        "expMonth": "09",
        "expYear": "28"
    },
    "address": {
        "zip": "64101",
        "country": "US",
        "street1": "52 Flash Boulevard",
        "city": "Central City",
        "state": "MO"
    }
}

Below is an example of the response:

{  
  "success": true,  
  "status": "PENDING",  
  "message": "Request queued"  
}

2 - Get Transaction Status

Always verify the payment status before providing value to your customer. Use the get transaction endpoint with either:

  • The transactionId from the charge response or
  • Your externalReference

Here's an example of possible transaction objects with different steps required:

{
    "success": true,
    "data": {
        "transactionId": "TMNT-JLA-CRISIS-2026",
        "amount": 100,
        "currency": "NGN",
        "createdAt": 1772739561749,
        "chargeStatus": "pending",
        "receiverCurrency": "NGN",
        "receiverAmount": 100,
        "senderCurrency": "NGN",
        "senderAmount": 100,
        "status": "PENDING",
        "type": "deposit",
        "method": "card",
        "fullTimestamp": "2026-03-05T19:39:21+00:00",
        "externalReference": "EARTH-PRIME-01",
        "stepRequired": "pin",
        "metadata": {
            "senderAccountName": "Diana Prince",
            "cardFirstSix": "194110",
            "cardLastFour": "1984"
        }
    }
}
{
    "success": true,
    "data": {
        "transactionId": "TMNT-JLA-CRISIS-2026",
        "amount": 100,
        "currency": "NGN",
        "createdAt": 1772739561749,
        "chargeStatus": "pending",
        "receiverCurrency": "NGN",
        "receiverAmount": 100,
        "senderCurrency": "NGN",
        "senderAmount": 100,
        "status": "PENDING",
        "type": "deposit",
        "method": "card",
        "fullTimestamp": "2026-03-05T19:39:21+00:00",
        "externalReference": "EARTH-PRIME-01",
        "stepRequired": "otp",
        "metadata": {
            "senderAccountName": "Diana Prince",
            "cardFirstSix": "194110",
            "cardLastFour": "1984"
        }
    }
}
{
    "success": true,
    "data": {
        "transactionId": "TMNT-JLA-CRISIS-2026",
        "amount": 100,
        "currency": "NGN",
        "createdAt": 1772739561749,
        "chargeStatus": "pending",
        "receiverCurrency": "NGN",
        "receiverAmount": 100,
        "senderCurrency": "NGN",
        "senderAmount": 100,
        "status": "PENDING",
        "type": "deposit",
        "method": "card",
        "fullTimestamp": "2026-03-05T19:39:21+00:00",
        "externalReference": "EARTH-PRIME-01",
        "stepRequired": "address_verification",
        "metadata": {
            "senderAccountName": "Diana Prince",
            "cardFirstSix": "194110",
            "cardLastFour": "1984"
        }
    }
}
{
    "success": true,
    "data": {
        "transactionId": "ARKHAM-ASYLUM-777",
        "amount": 0.5,
        "currency": "USD",
        "createdAt": 1772739766529,
        "chargeStatus": "pending",
        "receiverCurrency": "USD",
        "receiverAmount": 0.5,
        "senderCurrency": "USD",
        "senderAmount": 0.5,
        "status": "PENDING",
        "type": "deposit",
        "method": "card",
        "fullTimestamp": "2026-03-05T19:42:46+00:00",
        "externalReference": "PUDDIN-01",
        "stepRequired": "redirect",
        "metadata": {
            "senderAccountName": "Harleen Quinzel",
            "cardFirstSix": "091192",
            "cardLastFour": "1992",
        },
        "redirectUrl": "https://redirect.com"
    }
}

3 - Handle Webhooks

Configure webhooks to receive real-time transaction updates instead of polling the status endpoint.

Setup

  1. Configure your webhook URL in your dashboard.
  2. Implement webhook endpoint security and validation.
  3. Handle the webhook notifications in your application.
{
    "event": "transaction_updated",
    "data": {
        "transactionId": "luQybnMnvjgnWEF6ZFyJ",
        "status": "pending",
        "type": "deposit",
        "stepRequired": "pin",
        "externalReference": "1234567890"
    },
    "timestamp": "2026-03-05T19:39:30.624Z"
}
{
    "event": "transaction_updated",
    "data": {
        "transactionId": "luQybnMnvjgnWEF6ZFyJ",
        "status": "pending",
        "type": "deposit",
        "stepRequired": "otp",
        "externalReference": "1234567890"
    },
    "timestamp": "2026-03-05T19:39:30.624Z"
}
{
    "event": "transaction_updated",
    "data": {
        "transactionId": "luQybnMnvjgnWEF6ZFyJ",
        "status": "pending",
        "type": "deposit",
        "stepRequired": "address_verification",
        "externalReference": "1234567890"
    },
    "timestamp": "2026-03-05T19:39:30.624Z"
}
{
    "event": "transaction_updated",
    "data": {
        "transactionId": "RFJZcgeeTGilZgPp9zyn",
        "status": "pending",
        "type": "deposit",
        "stepRequired": "redirect",
        "externalReference": "12fd3456789x",
        "redirectUrl": "https://redirect.com"
    },
    "timestamp": "2026-03-05T19:42:56.538Z"
}

When a stepRequired field is present:

  • otp — Prompt the customer to enter the OTP sent to their phone or email.
  • pin — Prompt the customer to enter their card PIN.
  • redirect — Redirect the customer to the provided redirectUrl to complete 3DS authentication.
  • address_verification — Collect the customer's billing address to verify against card records.

4 - Authorise Card Charge

If a webhook or status response contains a stepRequired of otp, pin, or address_verification, collect the required information and submit it to the authorise card charge endpoint.

FieldTypeRequiredDescription
typeStringThe step type: otp, pin, or address_verification
valueString | ObjectThe authorisation value. A string for otp/pin, or an address object for address_verification

Request Example:

{
  "type": "pin",
  "value": "1234",
}
{
  "type": "otp",
  "value": "123456"
}
{
  "type": "address_verification",
  "value": {
    "street1": "123 Main St",
    "city": "Lagos",
    "state": "Lagos",
    "zip": "100001",
    "country": "NG"
  },
  "transactionsLocation": "transactions"
}

Example Response:

{  
  "success": true,  
  "message": "Charge Authorisation successful."  
}
{  
  "success": true,  
  "message": "Verification successful. Next step: redirect",  
  "stepData": {  
    "stepRequired": "redirect",  
    "redirectUrl": "<https://3ds.bank.com/authorize?token=...">  
  }  
}

Note: After a successful authorisation the transaction continues processing in the background. You will receive a final successful or failed webhook when the transaction completes.

5 - Handle Redirects (3DS)

When stepRequired is redirect, the customer must be sent to the provided URL to complete 3D Secure authentication with their bank.

  • Extract the URL — Get redirectUrl from the webhook or the transaction status response.
  • Redirect the customer — Send the customer to this URL. They will land on their bank's secure authentication page.
  • Await the final status — After the customer completes (or abandons) authentication, wait for the final transaction_updated webhook with status: "successful" or status: "failed" before providing value.

Note: Do not poll aggressively during a redirect flow. The final outcome is delivered via webhook once the bank responds.