Accept Payment
Server to Server
Pay with OPay

Server to Server (Pay with OPay)

The Pay with OPay API lets your customers pay from their OPay wallet. You start the payment from your server, send the customer to the OPay checkout page, and then check the payment status using the transaction reference.

⚠️

Only NGN is supported.

Quick overview

  1. Initialize OPay Payment: Use the pay-with-opay endpoint to create the transaction and get a checkout URL.
  2. Store the reference: Save the transaction reference against the customer's order.
  3. Redirect the customer: Send the customer to the checkout URL to finish the payment on OPay.
  4. Verify the payment: When the customer lands on your redirectUrl, call the Verify Transaction endpoint with the reference.

Test or live mode is set by the secret key you send. Use sk_test_… for test and sk_live_… for live.


Step 1: Initialize OPay Payment

Use the pay-with-opay endpoint to create the transaction. The response contains the OPay checkout URL.

Headers
ParameterDescription
URLhttps://api.budpay.com/api/s2s/pay-with-opay (opens in a new tab)
MethodPOST
Content-TypeThe content type of the request. Set this to application/json.
AcceptSet this to application/json.
AuthorizationThe secret key used to authenticate the request, set this to Bearer YOUR_SECRET_KEY.
Request Body
ParameterTypeRequiredDescription
emailstringYesCustomer's email address. Minimum of 6 characters.
amountstringYesAmount to charge, e.g. "5000".
currencystringYesCurrency of the payment. Must be NGN.
descriptionstringYesDescription of the payment. It appears on the OPay payment page.
redirectUrlstringYesThe URL OPay sends the customer to after payment.
referencestringNoUnique reference for the transaction. BudPay generates one if you leave it out.
first_namestringNoCustomer's first name. Saved on the customer record.
last_namestringNoCustomer's last name. Saved on the customer record.
phonestringNoCustomer's phone number. Saved on the customer record.
productstringNoProduct name sent to the gateway. Defaults to budpay.
Sample Request:

Endpoint: POST https://api.budpay.com/api/s2s/pay-with-opay

1curl -X POST 'https://api.budpay.com/api/s2s/pay-with-opay' \2  -H 'Content-Type: application/json' \3  -H 'Accept: application/json' \4  -H 'Authorization: Bearer YOUR_SECRET_KEY' \5  -d '{6  "email": "user@example.com",7  "amount": "5000",8  "currency": "NGN",9  "description": "Order #1234",10  "redirectUrl": "https://yourapp.com/payment/callback",11  "reference": "ORD-1234",12  "first_name": "Ada",13  "last_name": "Okafor",14  "phone": "08012345678"15}'
{  "message": "SUCCESSFUL",  "status": true,  "data": "https://express.opaycheckout.com/apiCashier/redirect/payment/checkoutHome?orderToken=TOKEN.a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"}
Response

A successful request returns the OPay checkout URL as a string in data. Send the customer to that URL.

{
    "message": "SUCCESSFUL",
    "status": true,
    "data": "https://express.opaycheckout.com/apiCashier/redirect/payment/checkoutHome?orderToken=TOKEN.a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
FieldTypeDescription
statusbooleantrue when the checkout was created.
messagestringSUCCESSFUL on success.
datastringThe OPay checkout URL. Redirect the customer here.

The response does not include the transaction reference. Send your own reference in the request and store it, so you can verify the payment in Step 3.

Error Responses
StatusReason
400Validation failed. message lists every failed field.
401Invalid merchant authorization, business not found, currency is not NGN or there is a wallet issue, or the reference already exists.
403Collection is disabled for your business.
500Server error. This is not a payment status. Verify the reference before you retry, so you don't create a duplicate payment.

Missing authorization returns HTTP 401:

{
    "status": false,
    "message": "Merchant Authorization is required"
}

Blocked customer:

{
    "success": false,
    "message": "Customer account has been blocked."
}

Step 2: Redirect the customer

Save the reference you sent, then send the customer to the checkout URL in data from Step 1. When the customer finishes on OPay, they are sent back to your redirectUrl.

⚠️

A redirect to your redirectUrl does not confirm payment. Always verify the transaction (Step 3) before you deliver value to the customer.


Step 3: Verify the transaction

Use the standard Verify Transaction endpoint with your transaction reference to confirm the payment status. Only deliver value when data.status is success and the amount matches your order. You can poll this endpoint if the payment is still pending.

Endpoint: GET https://api.budpay.com/api/v2/transaction/verify/:reference

1curl -X GET 'https://api.budpay.com/api/v2/transaction/verify/ORD-1234' \2  -H 'Authorization: Bearer YOUR_SECRET_KEY'
{  "status": true,  "message": "Verification successful",  "data": {    "id": 10000001,    "amount": "5250",    "currency": "NGN",    "status": "pending",    "transaction_date": null,    "reference": "ORD-1234",    "domain": "live",    "gateway_response": null,    "channel": "opay",    "ip_address": null,    "originator_name": "",    "originator_account_number": "",    "originator_bank_name": "",    "originator_bank_code": "",    "originator_session_id": "",    "originator_narration": "",    "receiver_account_name": "",    "receiver_account_number": "",    "fees": "250",    "plan": null,    "requested_amount": "5000"  },  "customer": {    "id": 1000001,    "customer_code": "CUS_xxxxxxxxxxxxxxx",    "first_name": "Ada",    "last_name": "Okafor",    "email": "user@example.com"  },  "metadata": ""}

The 200 example above shows a payment the customer has not completed yet (data.status is pending). data.channel is opay. data.amount includes fees, and data.requested_amount is the amount you sent. See Verify Transaction for the status values.


Integration Checklist

  • Send your secret key as a Bearer token on every request (sk_test_… or sk_live_…).
  • Only NGN is accepted.
  • description is required for OPay.
  • Use your own reference so you can match payments to orders. It must be unique for each merchant and environment.
  • Always call the Verify Transaction endpoint before you mark an order as paid.