Card Payments

This API allows you to accept payment from your customers’ local cards (cards issued in Nigeria) or USD denominated international cards (USA, Canada, Europe and Australia). Cards are issued to customers by their different banks and the authentication protocol for each card is determined by the issuing bank.

These authentication protocols are means by which the customers authenticate their transactions and they include:

  1. One Time Pin (OTP)
  2. Card Pin (PIN)
  3. Address Verification Sytems (AVS)
  4. Date of Birth (DOB)
  5. 3Ds (3-D Secure)


Note
Please note that with Visa cards, the 3D Secure protocol is automatically launched.

Here, we describe how to use our card transaction API to enable you accept direct card payments without utilizing the full power of OPay’s payment gateway.


Mandatory preparations to accept card payments on OPay’s platform

  1. Create a merchant account here.
  2. Go to “Settings” and retrieve your Merchant ID
  3. Go to “Settings” and click on the “API Keys & Webhooks” tab
  4. Note your Secret & Public Keys as you’ll need them for your headers going forward


Step 1: Initialize a transaction

You can commence a card transaction using 3 different payment methods namely:

  1. Bank Card: This API requires you providing details of the customers’ card i.e. PAN, CVV, Expiry etc.
  2. Token: This is mostly used when you have a card that’s been tokenized & you have the token value.
  3. Bank Account: It’s for scenarios whereby the card details isn’t available but you have the details of the account linked to the card

Each payment method has their own unique request payload.


Step 1a: Initializing a transaction using a bank card

When using this payment method, you give customers the option to provide their card details such as card number, CVV and other relevant details. Go ahead and initialize payment by making a POST request to the /transaction/initialize endpoint using the pay by bank card request body below.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

Header Parameters

ParameterDescription
Content-typeapplication/JSON
MerchantIdOPay merchant ID is a unique 15-digit number assigned to all OPay merchants. To get your merchantID, login to your OPay Dashboard and click on Settings.
AuthorizationBearer + Public Key

Example bankcard pay request body

post/transaction/initialize
{
  "reference": "test_20191123132234",
  "amount": "10000",
  "currency": "NGN",
  "country": "NG",
  "payType": "bankcard",
  "firstName;": "firstName",
  "lastName": "lastName",
  "customerEmail": "123@qq.com",
  "cardNumber": "5399237079779357",
  "cardDateMonth": "11",
  "cardDateYear": "22",
  "cardCVC": "590",
  "return3dsUrl": "http://www.your.domain.com",
  "bankAccountNumber": "22445566787",
  "bankCode": "057",
  "reason": "transaction reason message",
  "callbackUrl": "https://you.domain.com/callbackUrl",
  "expireAt": "100",
  "billingZip": "xxx",
  "billingCity": "xxxx",
  "billingAddress": "xxxx",
  "billingState": "xxxx",
  "billingCountry": "xxxx"
}

Sample Response

{
    "code": "00000",
    "message": "SUCCESSFUL",
    "data": {
        "orderNo": "210323140538929542",
        "reference": "test_20191123132234",
        "amount": null,
        "currency": null,
        "status": "PENDING",
        "token": null,
        "authURL": null,
        "failureReason": null
    }
}
PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
amountFor NGN transactions, Amount in kobo
currencyThe following currency types are accepted:
1. NGN
2. USD
countryUSA, Canada, Europe and Australia international cards accepted
payTypetoken, bankCard, bankAccount
firstNameFirst name
lastNameLast name
customerEmailEmail address
cardNumberBankcard Number
cardDateMonthBankcard expiration month e.g. 01
cardDateYearBankcard expiration year e.g. 22
cardCVCBankcard cvc
return3dsUrlWhat page do you need to call back to after 3ds verification is successful
bankAccountNumberBank Account number, needed when payType is bankAccount
bankCodeBank code
reasonReason
expireAtTransaction would be closed within specific time. Value is in minutes
billingZipZip code or postal card registered with the card
billingCityThe city registered with the card
billingAddressThe house/building address registered with the card
billingStateThe state registered with the card. e.g. NY for New York, CA for California, etc
billingCountryThe country registered with the card. e.g. US, CA, AU, etc
Things to Note
  1. The following details are mandatory in the Initialize request payload:
    - Billing Zip code
    - Billing City
    - Billing Address
    - Billing State
    - Billing Country
  2. You will need to create a different merchant account to process USD transactions. You can’t utilize the same merchant account for a NGN & USD transaction. Kindly notify us at hackathonsupport@opay-inc.com immediately you create a merchant account to be utilized for USD transactions so we can activate all necessary permissions.
  3. When testing USD transactions, if test is conducted using a card not listed in the provided samples, the default transaction amount is 8.
Note
The callbackUrl is for webhook notifications.

Step 1a: Initializing a transaction using a token

Card payments can be processed using the token value associated with the card. Hence, by using this token, it will eliminate the need for customers to input other details like card number and expiry date in the request. You can now initialize payment by making a POST request to the /transaction/initialize endpoint using the pay by token request body below.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

Header Parameters

ParameterDescription
Content-typeapplication/JSON
MerchantIdOPay merchant ID is a unique 15-digit number assigned to all OPay merchants. To get your merchantID, login to your OPay Dashboard and click on Settings.
AuthorizationBearer + Public key

API Endpoint

/transaction/initialize

Sample Request

post/transaction/initialize
curl -X POST --header 'Authorization: Bearer public_key' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.opayweb.com/api/v3/transaction/initialize

Sample Token Pay Request Body

post/transaction/initialize
{
  "reference": "test_20191123132233",
  "amount": "10000",
  "currency": "NGN",
  "country": "NG",
  "payType": "token",
  "token": "BDEFDFDFE43F4DGD2",
  "customerPhone": "+2348686868686",
  "customerEmail": "123@qq.com",
  "reason": "transaction reason message",
  "callbackUrl": "https://you.domain.com/callbackUrl",
  "expireAt": "100",
}

Sample Response

post/transaction/initialize
{
    "code": "00000",
    "message": "SUCCESSFUL",
    "data": {
        "orderNo": "210319140538363559",
        "reference": "test_20191123133456",
        "amount": null,
        "currency": null,
        "status": "PENDING",
        "token": "BDEFDFDFE43F4DGD2",
        "authURL": null,
        "failureReason": null
    }
}
PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
amountFor NGN transactions, Amount in kobo
currencyThe following currency types are accepted:
1. NGN
2. USD
countryUSA, Canada, Europe and Australia international cards accepted
payTypetoken, bankCard, bankAccount
tokenIf it is token payment, you need to fill in here
customerPhonephone
customerEmailemail
reasonReason
callbackUrlThe asynchronous callback address after transaction successful
expireAtTransaction would be closed within specific time. Value is in minutes

Step 1b: Initializing a transaction using a bank account

Step 1b (part A) - Get list of supported banks and their codes

Before making this API call, you need to make a POST request to the transaction/banks API to fetch a list of all supported banks and their codes. Once completed, please proceed to calling the transaction/initialize endpoint using the pay by bank account request body.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

API Endpoint

/transaction/banks

Sample Request

post/transaction/banks
curl -X POST --header 'Authorization: Bearer public_key' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.operapay.com/api/v3/transaction/banks

Sample Request Body

post/transaction/banks
{
  "country": "NG"
}

Sample Response

{
    "code": "00000",
    "message": "SUCCESSFUL",
    "data": {
        "banks": [
            {
                "code": "011",
                "name": "First Bank Of Nigeria",
                "type": "firstBank",
                "icon": "https://owallet-prod-public.oss-eu-west-1.aliyuncs.com/images/api/icon/bank/firstBank.png",
                "color": "#CFD9E7",
                "isSupportBankAccount": true
            },
            {
                "code": "058",
                "name": "Guaranty Trust Bank",
                "type": "gtbBank",
                "icon": "https://owallet-prod-public.oss-eu-west-1.aliyuncs.com/images/api/icon/bank/gtbBank.png",
                "color": "#FDDFCE",
                "isSupportBankAccount": true
            },
            {
                "code": "133",
                "name": "Providus Bank Plc",
                "type": "providusBank",
                "icon": "https://owallet-prod-public.oss-eu-west-1.aliyuncs.com/images/api/icon/bank/providusBank.png",
                "color": "#FFF1D0",
                "isSupportBankAccount": true
            },
            {
                "code": "232",
                "name": "Sterling Bank",
                "type": "sterlingBank",
                "icon": "https://owallet-prod-public.oss-eu-west-1.aliyuncs.com/images/api/icon/bank/sterlingBank.png",
                "color": "#F6D6D8",
                "isSupportBankAccount": true
            },
            {
                "code": "033",
                "name": "United Bank For Africa",
                "type": "ubaBank",
                "icon": "https://owallet-prod-public.oss-eu-west-1.aliyuncs.com/images/api/icon/bank/ubaBank.png",
                "color": "#FBD2CF",
                "isSupportBankAccount": true
            },
            {
                "code": "215",
                "name": "Unity Bank Plc",
                "type": "unityBank",
                "icon": "https://owallet-prod-public.oss-eu-west-1.aliyuncs.com/images/api/icon/bank/unityBank.png",
                "color": "#E6F3DB",
                "isSupportBankAccount": true
            },
            {
                "code": "057",
                "name": "Zenith Bank",
                "type": "zenithBank",
                "icon": "https://owallet-prod-public.oss-eu-west-1.aliyuncs.com/images/api/icon/bank/zenithBank.png",
                "color": "#F9CCCF",
                "isSupportBankAccount": true
            }
        ],
        "commonBanks": null
    }
}
PROPERTYDESCRIPTION
codesupported bankAccount bank code
countrycountry
Step 1b (part B) - Initalize transaction using bankaccount request body

After successfully getting the list of supported banks and their codes from step 1a (part A) above, you can now initialize payment by making a POST request to the /transaction/initialize endpoint using the pay by bankaccount request body below.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

Header Parameters

ParameterDescription
Content-typeapplication/JSON
MerchantIdOPay merchant ID is a unique 15-digit number assigned to all OPay merchants. To get your merchantID, login to your OPay Dashboard and click on Settings.
AuthorizationBearer + Public Key

API Endpoint

/transaction/initialize

Sample Request

post/transaction/initialize
curl -X POST --header 'Authorization: Bearer public_key' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.opayweb.com/api/v3/transaction/initialize

Sample Request Body

Example bankaccount pay request body

post/transaction/initialize
{
  "reference": "test_20191123132236",
  "amount": "10000",
  "currency": "NGN",
  "country": "NG",
  "payType": "bankaccount",
  "bankAccountNumber": "22445566787",
  "bankCode": "057",
  "return3dsUrl": "http://www.your.domain.com",
  "reason": "transaction reason message",
  "customerPhone": "+2341234567890",
  "bvn": "1234567890",
  "dobDay": "20",
  "dobMonth": "04",
  "dobYear": "1999"
}

Sample Response

post/transaction/initialize
{
    "code": "00000",
    "message": "SUCCESSFUL",
    "data": {
        "orderNo": "210323140538925917",
        "reference": "test_20191123132236",
        "amount": null,
        "currency": null,
        "status": "PENDING",
        "token": null,
        "authURL": null,
        "failureReason": null
    }
}
PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
amountFor NGN transactions, Amount in kobo
currencyThe following currency types are accepted:
1. NGN
2. USD
countryUSA, Canada, Europe and Australia international cards accepted
payTypetoken, bankCard, bankAccount
bankAccountNumberBank Account number, needed when payType is bankAccount
bankCodeBank code
return3dsUrlWhat page do you need to call back to after 3ds verification is successful
reasonReason
customerPhonephone
bvnBVN
dobDayDay of birth
dobMonthMonth of birth
dobYearYear of birth

Step 2: Check the status of initialized transaction

For every Initialize Transaction call, the default status returned is “PENDING” or “INITIAL” as transactions are processed asynchronously. You’re to wait for 10 seconds or more before proceeding to check the status of the transaction.

Please note that the Authorization header consists of “Bearer Signature” which is essentially a HMAC SHA512 signature of the whole payload (arranged in alphabetical order) signed using your Secret Key. You can use our Signature calculator here.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

Header Parameters

ParameterDescription
Content-typeapplication/JSON
MerchantIdOPay merchant ID is a unique 15-digit number assigned to all OPay merchants. To get your merchantID, login to your OPay Dashboard and click on Settings.
AuthorizationBearer + Signature (Signature is a combination of both the payload and your secret key)
Note
You can requery the status of your transaction by passing either the ReferenceID and Order No in your request payload (as detailed in the sample below) or just the ReferenceID.

API Endpoint

/transaction/status

Sample Request

post/transaction/status
curl -X POST --header 'Authorization: Bearer Signature' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.opayweb.com/api/v3/transaction/status

Sample Request Body

post/transaction/status
{
"orderNo": "210323140538859499",
"reference": "test_20210302114235"
}

Sample Response

post/transaction/status
{
    "code": "00000",
    "message": "SUCCESSFUL",
    "data": {
        "amount": "100",
        "authURL": null,
        "currency": "NGN",
        "failureReason": "",
        "reference": "test_20210302114235",
        "status": "PENDING",
        "token": null,
        "orderNo": "210323140538859499"
    }
}
PROPERTYDESCRIPTION
amountAmount us in kobo
authURLIf status=3DSECURE, it will need customer to access authURL in brower to complete transaction
currencyNGN
failureReasonfailureReason
referenceOrder number of merchant (unique order number from merchant platform)
statusINITIAL
PENDING
SUCCESS
FAIL
INPUT-PIN
INPUT-OTP
INPUT-PHONE
3DSECURE
CLOSE
tokenOnly returned when tokenize is true
orderNoOrder number from OPay payment

Step 3: Take Note of the Payment Status in your Response

There are different status(es) that could be returned when you initialize/requery the status of an initialized transaction namely:

  1. INITIAL
  2. PENDING
  3. SUCCESS
  4. FAIL
  5. CLOSE
  6. INPUT-PIN
  7. INPUT-OTP
  8. INPUT-PHONE
  9. 3DSECURE



Things To Note When Querying Transaction Status
  1. When status returns “PENDING” or “INITIAL”, wait a few more seconds, then re-check to see if its status has changed. Don't call too early as you may get a lot more "PENDING" statuses than you should.
  2. When status returns “CLOSE”, it means the transaction has been closed/canceled (it either expired or the Close API was called to cancel the transaction). You can re-initiate with a different Reference ID.
  3. When status returns “FAIL”, it means the transaction failed, failure reason would be specified in the failureReason field while “SUCCESS” indicates that the transaction has been processed successfully.
  4. When status returns any of the following:
    • INPUT-PIN
    • INPUT-OTP
    • INPUT-PHONE
    • 3DSECURE
    • INPUT-DOB

    It means that an authorization is required from the customer before the transaction can be processed. The authorization protocol is determined by the card type & issuing bank.


Below is a list of accepted cards and recognized authorization protocol:

  1. Nigerian Issued Mastercard / Verve card: INPUT-PIN &/ INPUT-OTP
  2. VISA Cards: 3DSECURE
  3. Zenith Bank Issued Card: INPUT-PIN &/ INPUT-OTP &/ INPUT-DOB
  4. International Cards: AVS &/ 3DSECURE

Step 4: Respond to an Authorization Status

Step 4a: When Status : INPUT-PIN

Request for the card pin from your customer and call the Transaction/input-pin endpoint passing the orderNo & reference gotten from Step 1 or Step 2 above as well as the pin.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

Header Parameters

ParameterDescription
Content-typeapplication/JSON
MerchantIdOPay merchant ID is a unique 15-digit number assigned to all OPay merchants. To get your merchantID, login to your OPay Dashboard and click on Settings.
AuthorizationBearer + Public key

Sample Request

post/transaction/input-pin
curl -X POST --header 'Authorization: Bearer public_key' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.opayweb.com/api/v3/transaction/input-pin

Sample Request Body

post/transaction/input-pin
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "pin": "123456"
}

Sample Response

post/transaction/input-pin
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "status": "PENDING",
  "token": "xxxx",
  "authURL": "",
  "failureReason": "failureReason "
}
PROPERTYDESCRIPTION
orderNoOrder number from OPay payment
referenceOrder number of merchant (unique order number from merchant platform)
statusINITIAL
PENDING
SUCCESS
FAIL
INPUT-PIN
INPUT-OTP
INPUT-PHONE
3DSECURE
CLOSE
authURL
failureReasonfailureReason
pinPIN submitted by user

Step 4b: When Status : INPUT-OTP

A unique OTP would be generated by the customers’ issuing bank and sent to them via SMS or email. You are required to retrieve the OTP from your customer and call the Transaction/input-otp endpoint passing the orderNo & reference gotten from Step 1 or Step 2 above as well as the OTP.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

Header Parameters

ParameterDescription
Content-typeapplication/JSON
MerchantIdOPay merchant ID is a unique 15-digit number assigned to all OPay merchants. To get your merchantID, login to your OPay Dashboard and click on Settings.
AuthorizationBearer + Public key

Sample Request

post/transaction/input-otp
curl -X POST --header 'Authorization: Bearer public_key' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.opayweb.com/api/v3/transaction/input-otp

Sample Request Body

post/transaction/input-otp
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "otp": "123456"
}

Sample Response

post/transaction/input-otp
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "status": "PENDING",
  "token": "xxxx",
  "authURL": "",
  "failureReason": "failureReason "
}
PROPERTYDESCRIPTION
orderNoOrder number from OPay payment
referenceOrder number of merchant (unique order number from merchant platform)
statusINITIAL
PENDING
SUCCESS
FAIL
INPUT-PIN
INPUT-OTP
INPUT-PHONE
3DSECURE
CLOSE
authURL
failureReasonfailureReason

Step 4c: When Status : INPUT-PHONE

Request for the customers’ mobile number linked to the card account and call the Transaction/input-phone endpoint passing the orderNo & reference gotten from Step 1 or Step 2 above as well as the phone number.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

API Endpoint

/transaction/input-phone

Sample Request

post/transaction/input-phone
curl -X POST --header 'Authorization: Bearer public_key' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.opayweb.com/api/v3/transaction/input-phone

Sample Request Body

post/transaction/input-phone
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "phone": "+23401234567889"
}

Sample Response

post/transaction/input-phone
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "status": "PENDING",
  "token": "xxxx",
  "authURL": "",
  "failureReason": "failureReason "
}
PROPERTYDESCRIPTION
orderNoOrder number from OPay payment
referenceOrder number of merchant (unique order number from merchant platform)
statusINITIAL
PENDING
SUCCESS
FAIL
INPUT-PIN
INPUT-OTP
INPUT-PHONE
3DSECURE
CLOSE
tokenOnly returned when tokenize is true
authURL
failureReasonfailureReason
phonePhone number submitted by user

Step 4d: When Status : INPUT-DOB

Getting the customer's date of birth is a requirement for Zenith bank accounts. As a result, call the Transaction/input-dob endpoint passing the orderNo & reference gotten from Step 1 or Step 2 above as well as the dob.

HTTP Method

POST

Sandbox
http://sandbox-cashierapi.opayweb.com/api/v3
Production
https://cashierapi.opayweb.com/api/v3

API Endpoint

/transaction/input-dob

Sample Request

post/transaction/input-dob
curl -X POST --header 'Authorization: Bearer public_key' --header 'MerchantId:
256619092316009' --header 'content-type: application/json'
https://cashierapi.opayweb.com/api/v3/transaction/input-dob

Sample Request Body

post/transaction/input-dob
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "dob": "dd/mm/yyyy"
}

Sample Response

post/transaction/input-dob
{
  "orderNo": "20019212912901281821982",
  "reference": "test_20191123132233",
  "status": "PENDING",
  "token": "xxxx",
  "authURL": "",
  "failureReason": "failureReason "
}
PROPERTYDESCRIPTION
orderNoOrder number from OPay payment
referenceOrder number of merchant (unique order number from merchant platform)
statusINITIAL
PENDING
SUCCESS
FAIL
INPUT-PIN
INPUT-OTP
INPUT-PHONE
3DSECURE
CLOSE
tokenOnly returned when tokenize is true
authURL
failureReasonfailureReason
phonePhone submitted by user

Step 4e: When Status : 3DSECURE

A link would be returned in the authURL field when you get this status. Kindly redirect the customer to that link to complete the transaction.


Step 5: Verify Payment Status

After completing all payment steps and authorizing the transaction, you need to verify that the payment was successful with OPay before giving value to your customer on your website/app. To do so, call our /transaction/status endpoint with your orderNo & reference to ensure that the transaction went through successfully.

CONTENTS

  • Community

  • Official Website
  • Facebook
  • Linkedln
  • Twitter
Was this page helpful?
Yes
No

Help us make this page better

Please leave a comment on how we can improve your experience.