OPay Wallet Payment

The OPay Wallet Payment API allows you to debit any of your customers’ OPay wallet for transactions initiated via your website or mobile app. The transaction will then be authorized using the customers’ PIN and uniquely generated OTP, details which will be forwarded to us via API.

Mandatory preparations to accept OPay wallet payments on your 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. Note your Secret & Public Keys as you’ll need them for your headers going forward.
  4. If an endpoint requires a signature for authorization, kindly use our online signature calculator here
  5. You could also specify a webhook URL if you desire to receive webhook transaction notifications from OPay. To calculate the callback signature, kindly use our online callback signature calculator here

Immediately the necessary credentials have been retrieved, you can:

a. Initiate a transaction
b. Close a transaction
c. Refund a transaction


A. Initiate a Transaction

Description

To initiate an OPay wallet transaction, follow the steps below to enable you debit any of your customer's OPay wallet for transactions initiated via your website or mobile app.

There are essentially 5 steps to initiate an OPay wallet transaction :

  1. Initialize a Wallet Payment transaction
  2. Verify/Authorize Transaction
  3. Request for OTP (Optional as OTP is sent by default the first time)
  4. Verify OTP
  5. Verify Status


Step 1: Initialize a Wallet Payment transaction

Step 1a : Your customer is to provide the mobile number linked to his/her OPay account (otherwise known as Wallet Number). This information will be passed to OPay via the Initialize API.

Step 1b : Specify the API url for the Initialize API and arrange the headers using the API credentials fetched from your dashboard (header format is as specified below).

HTTP Method

POST

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

API Endpoint

/certpay/initialize

TIP: Always arrange your request payload (i.e sort them in alphabetical order based on the property names)).

Sample Request

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

Step 1c : Arrange your request payload (which includes the customers’ wallet number and amount to be debited) and call the Initialize API. Kindly note that the Amount value is in Kobo.

Sample Request Body

post/certpay/initialize
{
   "reference": "opay-wallet01",
   "userPhone": "+2348160564736",
   "amount": "1000",
   "currency": "NGN",
   "userRequestIp": "123.123.123.123",
   "productName": "iPhone X",
   "productDesc": "The best iPhone",
   "expireAt": "30"
}
REQUEST PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
userPhoneUser's mobile phone number. e.g. +2348160564736
amountAmount in kobo
currencyCurrency charge should be performed in. Default is NGN
userRequestIpThis is the IP address of the user, it is required for anti-phishing verification
productNameProduct name, utf-8 encoded
productDescProduct description, utf-8 encoded
expireAtThis is the specified time at which the transaction window will close. Value is in minutes

Sample Response

post/certpay/initialize
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
       "reference": "opay-wallet01",
       "orderNo": "211118293566071771",
       "userPhone": "+2348160564736",
       "amount": "1000",
       "currency": "NGN",
       "status": "INITIAL"
   }
}
RESPONSE PROPERTYDESCRIPTION
orderNoOrder number from OPay payment
referenceOrder number of merchant (unique order number from merchant platform)
amountAmount in kobo
currencyThe currency in which the transaction should be performed.
The following currency types are accepted:
1. NGN
2. USD
statusINITIAL

Things To Note

1. If an issue occurs and OPay couldn’t accept the transaction for processing, the appropriate error code and reason will be returned in the code and message fields. Please see a sample below.

{
  "code": "04999",
  "message": "T.TT.I.04999 Transaction is being processed",
  "data": null
}

2. If OPay receives the API call & accepts it for processing, the code and message fields in the Initialize response will be:

{
  "code": "00000",
  "message": "SUCCESSFUL"
}

The above however doesn’t indicate that the transaction itself is successful, you need to pay attention to the Status field of the data object in your API response for the final transaction status.

3. Default status returned for this endpoint is INITIAL.

4. For the transaction to be successful, userPhone must be a valid OPay wallet number, for your test use +2348160564736.


Step 2: Verify/Authorize Transaction

Step 2a : Request for the wallet PIN from your customer. This is the unique ID used by the customer to authenticate transactions on his/her OPay app.

Step 2b : Specify the API url for the VerifyPIN API and arrange the headers using the API credentials fetched from your dashboard (header format is as specified below).

HTTP Method

POST

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

API Endpoint

/certpay/verifyPIN

TIP : Always arrange your request payload (i.e sort them in alphabetical order based on the property names)

Sample Request

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

Step 2c : Retrieve the OrderNo and ReferenceID returned in Step 1c, arrange your request payload (which also includes the customer's wallet number & specified PIN) then call the verifyPIN API to verify the customer's OPay PIN.

Sample Request Body

post/certpay/verifyPIN
{
   "reference": "opay-wallet01",
   "orderNo": "211118293566071771",
   "userPhone": "+2348160564736",
   "pin": "123456"
}
REQUEST PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment
userPhoneUser's mobile phone number. e.g. +2348160564736
pinThis is the customer’s wallet PIN,the unique ID used by the customer to authenticate transactions on his/her OPay app.

Sample Response

post/certpay/verifyPIN
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
      "reference": "opay-wallet01",
      "orderNo": "211118293566071771",
      "status": "PENDING",
      "payMethods": [
          {
              "BALANCE": "available"
          },
          {
              "SAVING": "unavailable"
          },
          {
              "CreditME": "available"
          }
      ]
   }
}
RESPONSE PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number from OPay payment
statusPENDING
payMethodsThis refers to Payment methods present. Payment methods are several OPay wallet services which can be used for payment by the customer:
BALANCE (Wallet Balance)
SAVING (OWealth)
CreditME (Loan)

Things To Note

1. Default Status returned for successfully verified pin is PENDING, however this does not indicate the status of the transaction.

2. For the transaction to be successful, userPhone must be a valid OPay wallet number, for your test use +2348160564736, PIN = 123456.

3. The Payment method with which the customer can pay would be returned in the API response i.e

 "payMethods": [
    {
        "BALANCE": "available"
    },
    {
        "SAVING": "available"
    },
   {
      "CreditME":"available"
   }
]

4. CreditME is currently not visible on sandbox but is available on production if the customer is eligible for CreditME.


Step 3: Request for OTP generation

Despite verifying the transaction with their wallet PIN, your customers still need to authenticate the payment transaction using an OTP that will be uniquely generated for them by OPay. Kindly note that OTP generation is automatically done when you call the VerifyPIN endpoint from the previous step. Hence if OTP is sent to the customer you can skip this step and move to step 4.

The SendOTP API enables you to request for OTP to be sent to your customers. Hence in scenarios when:
1. the initial OTP was not sent after calling VerifyPIN,
2. OTP expired or
3. the customer mistakenly entered the wrong OTP,
the SendOTP API can always be used.

Step 3a : Display available wallets (payMethod) to your customers to select from. If you do not specify this, the system will use the default wallet, which is BALANCE

Step 3b : Specify the API url for the SendOTP API and arrange the headers using the API credentials fetched from your dashboard (header format is as specified below).

HTTP Method

POST

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

API Endpoint

/certpay/sendOTP

TIP: Always arrange your request payload (i.e sort them in alphabetical order based on the property names)

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

Step 3c : Retrieve the OrderNo and ReferenceID returned in Step 1c, arrange your request payload (i.e sort them in alphabetical order based on the property names)) then call the SendOTP API to instruct OPay to generate an OTP and send to the users’ mobile number.

Sample Request Body

post/certpay/sendOTP
{
   "reference": "opay-wallet01",
   "orderNo": "211118293566071771",
   "payMethod": "BALANCE"
}
REQUEST PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment
payMethodPayment method user selectedif you do not specify this the system will use the default wallet - BALANCE

Sample Response

post/certpay/sendOTP
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
       "reference": "opay-wallet01",
       "orderNo": "211118293566071771",
       "status": "OTP_SENT"
   }
}
RESPONSE PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment
statusOTP_SENT

Things To Note

1. Expected Status returned for successfully generated OTP is OTP_SENT.


Step 4: Verify OTP

Request that your customers check the mobile number linked to their OPay wallet for the OTP that was sent to them via SMS and specify it on your payment page. This will then be forwarded to OPay via the VerifyOTP API for verification passing the OTP, wallet type, OrderNo and ReferenceID returned in Step 1c .

HTTP Method

POST

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

API Endpoint

/certpay/verifyOTP

TIP: Always arrange your request payload (i.e sort them in alphabetical order based on the property names)

Sample Request

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

Sample Request Body

post/certpay/verifyOTP
{
   "reference": "opay-wallet01",
   "orderNo": "211118293566071771",
   "otp": "660973",
   "payMethod": "BALANCE"
}
REQUEST PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment
otpOTP submitted by user
payMethodPayment method user selected

Sample Response

post/certpay/verifyOTP
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
      "reference": "opay-wallet01",
      "orderNo": "211118293566071771",
      "amount": "1000",
      "currency": "NGN",
      "userPhone": "+2348160564736",
      "status": "SUCCESS"
   }
}
RESPONSE PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment
amountAmount in kobo
currencyCurrency charge should be performed in. Default is NGN
userPhoneUser phone number sent by merchant
statusSUCCESS

Things To Note

  1. Default Status returned for successfully verified OTP is PENDING.
  2. For the transaction to be successful, userPhone must be a valid OPay wallet number, for your test use +2348160564736 , PIN = 123456
  3. To get the OTP to use for the transaction on sandbox:

    • Log on to the merchant dashboard
    • Navigate to the “Integration tool”
    • Input the phone number
    • Click on the search button to get the OTP sent for the transaction.

Step 5: Verify Status

Verify the status of the transaction by calling the Status API passing the OrderNo and ReferenceID returned in Step 1c. Ensure that a SUCCESS status is returned before assigning value to the customer on your platform.

HTTP Method

POST

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

API Endpoint

/certpay/status

TIP: Always arrange your request payload (i.e sort them in alphabetical order based on the property names)

Sample Request

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

Sample Request Body

post/certpay/status
{
   "reference": "opay-wallet01",
   "orderNo": "211118293566071771"
}
REQUEST PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment

Sample Response

post/certpay/status
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
       "userPhone": "+2348160564736",
       "reference": "opay-wallet01",
       "orderNo": "211118293566071771",
       "amount": "1000",
       "currency": "NGN",
       "status": "SUCCESS"
   }
}
RESPONSE PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment
amountAmount in kobo
currencyCurrency charge should be performed in. Default is NGN
statusINITIAL
PENDING
SUCCESS
FAIL

B. Close a transaction

Description

This is used to prevent duplicated or invalid payment. This endpoint is only used when the status of the transaction is returned as INITIAL.
Close a transaction to prevent duplicated or invalid payment.

HTTP Method

POST

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

API Endpoint

/certpay/close

TIP: Always arrange your request payload (i.e sort them in alphabetical order based on the property names)

Sample Request

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

Sample Request Body

post/certpay/close
{
   "reference": "opay-wallet01",
   "orderNo": "211117292586056594"
}
REQUEST PROPERTYDESCRIPTION
referenceOrder number of merchant (unique order number from merchant platform)
orderNoOrder number of OPay payment

Sample Response

post/certpay/close
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
       "reference": "opay-wallet01",
       "orderNo": "211117292586056594",
       "status": "FAIL"
   }
}
RESPONSE PROPERTYDESCRIPTION
orderNoOrder number from OPay payment
referenceOrder number of merchant (unique order number from merchant platform)
statusFAIL

C. Refund a Transaction

Description

This allows you to refund a transaction. Please note that only successful transactions can be refunded.

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.

There are essentially 2 steps to refund an OPay wallet transaction :

  1. Initialize the refund request
  2. Verify refund Status


Step 1: Initialize the refund request

Specify the API url for the refund API and arrange the headers using the API credentials fetched from your dashboard (header format is as specified below). Arrange your request payload and call the refund API.

HTTP Method

POST

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

API Endpoint

/certpay/refund

TIP: Always arrange your request payload (i.e sort them in alphabetical order based on the property names)

Sample Request

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

Sample Request Body

post/certpay/refund
{
   "refundReference": "ref_opay-wallet01",
   "reference": "opay-wallet01",
   "orderNo": "211118293566071771",
   "refundAmount": "1000",
   "currency": "NGN"
}
REQUEST PROPERTYDESCRIPTION
refundReferenceRefund order number of merchant (This is your unique reference for this refund)
referenceOrder number of merchant (this is your unique reference for the transaction to be refunded)
orderNoOrder number on OPay (this is OPay’s reference for the transaction to be refunded)
refundAmountAmount in kobo
currencyCurrency charge should be performed in. Default is NGN

Sample Response

post/certpay/refund
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
      "refundReference": "ref_opay-wallet01",
      "reference": "opay-wallet01",
      "refundOrderNo": "211118253515524554",
      "orderNo": "211118293566071771",
      "refundAmount": "1000",
      "currency": "NGN",
      "refundStatus": "SUCCESS"
   }
}
RESPONSE PROPERTYDESCRIPTION
refundReferenceRefund order number of merchant (This is your unique reference of this refund)
referenceOrder number of merchant (this is your reference for the transaction to be refunded)
refundOrderNoRefund order number on OPay (This is the unique order number generated for this refund)
orderNoOrder number on OPay (this is OPay’s reference for the transaction to be refunded)
refundAmountAmount in kobo
currencyCurrency charge should be performed in. Default is NGN
refundStatusSUCCESS

Step 2: Verify Refund Status

Description

This is an inquiry into a refund transaction status. When you get PENDING as a status or if there was an exception when calling any of the endpoints, wait 10 seconds or more, then make a check to see if its status has changed. Don't call too early as you may get a lot more pending than you should.

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

API Endpoint

/certpay/refundStatus

TIP: Always arrange your request payload (i.e sort them in alphabetical order based on the property names)

Sample Request

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

Sample Request Body

post/certpay/refundStatus
{
   "refundReference": "ref_opay-wallet01",
   "reference": "opay-wallet01",
   "refundOrderNo": "211118253515524554",
   "orderNo": "211118293566071771"
}
REQUEST PROPERTYDESCRIPTION
refundReferenceRefund order number of merchant (This is your unique reference of this refund)
referenceOrder number of merchant (this is your reference for the transaction to be refunded)
orderNoOrder number on OPay (this is OPay’s reference for the transaction to be refunded)
refundOrderNoRefund order number on OPay (This is the unique order number generated for this refund)

Sample Response

post/certpay/refundStatus
{
   "code": "00000",
   "message": "SUCCESSFUL",
   "data": {
      "refundReference": "ref_opay-wallet01",
      "reference": "opay-wallet01",
      "refundOrderNo": "211118253515524554",
      "orderNo": "211118293566071771",
      "refundAmount": "1000",
      "currency": "NGN",
      "refundStatus": "SUCCESS"
   }
}
RESPONSE PROPERTYDESCRIPTION
refundReferenceRefund order number of merchant (This is your unique reference of this refund)
referenceOrder number of merchant (this is your reference for the transaction to be refunded)
refundOrderNoRefund order number on OPay (This is the unique order number generated for this refund)
orderNoOrder number on OPay (this is OPay’s reference for the transaction to be refunded)
refundAmountAmount in kobo
currencyCurrency charge should be performed in. Default is NGN
refundStatusINITIAL
PENDING
SUCCESS
FAIL

Callback (Webhook)

When a payment is completed (successful or failed), a callback is automatically sent to you via your specified callback url (webhook url). Please see this for more information.

CONTENTS

  • Community

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