rembrembdocs

The payment with OPay provides a seamless way to accept payments from customers with OPay wallets. Customers can securely authorize transactions directly from their OPay wallets, and funds are deposited into your Flutterwave account.

Whether you're a merchant expanding your payment options or an OPay customer seeking convenience and security, this method simplifies the overall payment experience.

🚧

Feature Availability

This payment method is only available for NGN (Nigerian Naira) transactions.

Before you begin, ensure the following prerequisites are met:

  1. Read the introduction section of this documentation.
  2. Retrieve your API keys from the Flutterwave dashboard.

👍

Customer Experience Tip

OPay customers must log into their wallets to authorize payments. Inform users in-app when they select this payment method to avoid confusion.

When a customer chooses OPay, they are redirected to the OPay platform to log in and authorize the transaction.

After authorization, the customer's wallet is debited, and Flutterwave sends a webhook notification to your server confirming the successful transaction.

To collect payments using OPay, follow these key steps:

  1. Initiate Transaction: Collect the customer’s details and define the transaction parameters (amount, currency, tx_ref, etc.).
  2. Redirect to OPay: Send the customer to the OPay authorization page to log in and complete the transaction.
  3. Verify Payment: After receiving the webhook or polling the transaction endpoint, confirm:
    1. status = "successful"
    2. Correct amount
    3. Matching customer_id
    4. Valid transaction_id

Only provide value after successful verification.

🚧

Integration Method

This guide follows the general integration flow. Please refer to the orchestrator flow for the alternative integration method.

To create a new customer, send a request to the create customer endpoint with relevant fields such as name, email, phone, and address.

While only the email field is required, we recommend collecting as much customer information as possible to support robust transaction records and future payments.

To retrieve existing customer details, use the retrieve customer endpoint. This is useful when initiating payments for returning users.

curl --request POST \
--url 'https://developersandbox-api.flutterwave.com/customers' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Idempotency-Key: {{YOUR_UNIQUE_INDEMPOTENCY_KEY}}' \
--data '{
   "address":{
      "city":"Shirley",
      "country":"US",
      "line1":"175 E Parkview Dr",
      "line2":"",
      "postal_code":"11967",
      "state":"New York"
   },
   "name":{
      "first":"John",
      "middle":"Agba",
      "last":"Doe"
   },
   "phone":{
      "country_code":"1",
      "number":"6313958745"
   },
   "email":"Johndoe@example.com"
}'

You'll get a response similar to this:

{
   "status":"success",
   "message":"Customer created",
   "data":{
      "id":"cus_dc0FUyBpd0",
      "address":{
         "city":"Shirley",
         "country":"US",
         "line1":"175 E Parkview Dr",
         "line2":"",
         "postal_code":"11967",
         "state":"New York"
      },
      "email":"Johndoe@example.com",
      "name":{
         "first":"John",
         "middle":"Agba",
         "last":"Doe"
      },
      "phone":{
         "country_code":"1",
         "number":"6313958745"
      },
      "meta":{
         
      },
      "created_datetime":"2024-12-25T20:16:38.246410457Z"
   }
}

To create an OPay payment method, send a request to the create payment method endpoint and set the type to opay.

curl --request POST \
--url 'https://developersandbox-api.flutterwave.com/payment-methods' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Idempotency-Key: {{YOUR_UNIQUE_INDEMPOTENCY_KEY}}' \
--data '{
   "type":"opay"
}'

You'll see a response similar to this:

{
  "status": "success",
  "message": "Payment method created",
  "data": {
    "type": "opay",
    "opay": {},
    "id": "pmd_uF9ADr9LvH",
    "meta": {},
    "created_datetime": "2024-12-26T14:38:25.179075400Z"
  }
}

To initiate an OPay charge, send a request to the create charge endpoint with the following parameters:

curl --request POST \
--url 'https://developersandbox-api.flutterwave.com/charges' \
--header 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: {{YOUR_UNIQUE_TRACE_ID}}' \
--header 'X-Idempotency-Key: {{YOUR_UNIQUE_INDEMPOTENCY_KEY}}' \
--data '{
   "currency":"NGN",
   "customer_id":"cus_dc0FUyBpd0",
   "payment_method_id":"pmd_uF9ADr9LvH",
   "amount":200,
   "reference":"ex61m23j6a3y0k34o9ilrri"
}'

You'll get a response similar to this:

{
   "status":"success",
   "message":"Charge created",
   "data":{
      "id":"chg_nONgeAGY97",
      "amount":200,
      "fees":[
         {
            "type":"vat",
            "amount":0
         },
         {
            "type":"app",
            "amount":0
         },
         {
            "type":"merchant",
            "amount":0
         },
         {
            "type":"stamp_duty",
            "amount":0
         }
      ],
      "currency":"NGN",
      "customer_id":"cus_dc0FUyBpd0",
      "settled":false,
      "settlement_id":[],
      "meta":{},
      "next_action":{
         "type":"redirect_url",
         "redirect_url":{
            "url":"https://developer-sandbox-ui-sit.flutterwave.cloud/redirects?opay&token=eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRJZCI6ImNiYThhMTkwLTE2OGUtNGNmZS05NmY5LTE2NDZhYjFhOWNkYiIsImNoYXJnZUlkIjoiY2hnX25PTmdlQUdZOTciLCJzdWIiOiJjYmE4YTE5MC0xNjhlLTRjZmUtOTZmOS0xNjQ2YWIxYTljZGIiLCJpYXQiOjE3MzgzMTc3MTAsImV4cCI6MTczODMxODAxMH0.QgLoZYfNhHJOJJvOsLA9eLoxOjGF0qnuehPMgMP4zD4"
         }
      },
      "payment_method_details":{
         "type":"opay",
         "opay":{},
         "id":"pmd_uF9ADr9LvH",
         "meta":{},
         "created_datetime":"2024-12-26T14:38:25.179Z"
      },
      "reference":"ex61m23j6a3y0k34o9ilrri",
      "status":"pending",
      "processor_response":{
         "type":"pending",
         "code":"02"
      },
      "created_datetime":"2025-01-31T10:01:50.209460744Z"
   }
}

The response from the charge initiation contains the next_action object with a redirect URL. This URL routes the customer to the OPay interface to authorise and complete the payment.

{
   "status":"success",
   "message":"Charge created",
   "data":{
      "id":"chg_nONgeAGY97",
      "amount":200,
      "fees":[
         {
            "type":"vat",
            "amount":0
         },
         {
            "type":"app",
            "amount":0
         },
         {
            "type":"merchant",
            "amount":0
         },
         {
            "type":"stamp_duty",
            "amount":0
         }
      ],
      "currency":"NGN",
      "customer_id":"cus_dc0FUyBpd0",
      "settled":false,
      "settlement_id":[],
      "meta":{},
      "next_action":{
         "type":"redirect_url",
         "redirect_url":{
            "url":"https://developer-sandbox-ui-sit.flutterwave.cloud/redirects?opay&token=eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRJZCI6ImNiYThhMTkwLTE2OGUtNGNmZS05NmY5LTE2NDZhYjFhOWNkYiIsImNoYXJnZUlkIjoiY2hnX25PTmdlQUdZOTciLCJzdWIiOiJjYmE4YTE5MC0xNjhlLTRjZmUtOTZmOS0xNjQ2YWIxYTljZGIiLCJpYXQiOjE3MzgzMTc3MTAsImV4cCI6MTczODMxODAxMH0.QgLoZYfNhHJOJJvOsLA9eLoxOjGF0qnuehPMgMP4zD4"
         }
      },
      "payment_method_details":{
         "type":"opay",
         "opay":{},
         "id":"pmd_uF9ADr9LvH",
         "meta":{},
         "created_datetime":"2024-12-26T14:38:25.179Z"
      },
      "reference":"ex61m23j6a3y0k34o9ilrri",
      "status":"pending",
      "processor_response":{
         "type":"pending",
         "code":"02"
      },
      "created_datetime":"2025-01-31T10:01:50.209460744Z"
   }
}

Flutterwave will then send a webhook notification with the final transaction status once the payment is completed and funds are received.

Refer to the next section to learn how to verify the transaction.

Before you provide value to the customer, confirm the transaction's final status and amount. You can verify the transaction information either using webhooks or by retrieving the charge details:

{
  "webhook_id": "wbk_z8BBd4nvlPxrg0GGTEFw",
  "timestamp": 1738317739798,
  "type": "charge.completed",
  "data": {
    "id": "chg_nONgeAGY97",
    "amount": 200,
    "currency": "NGN",
    "customer": {
      "id": "cus_dc0FUyBpd0",
      "address": {
        "city": "Shirley",
        "country": "US",
        "line1": "175 E Parkview Dr",
        "line2": "",
        "postal_code": "11967",
        "state": "New York"
      },
      "email": "Johndoe@example.com",
      "name": {
        "first": "John",
        "middle": "Agba",
        "last": "Doe"
      },
      "phone": {
        "country_code": "1",
        "number": "6313958745"
      },
      "meta": {},
      "created_datetime": "2024-12-25T20:16:38.246Z"
    },
    "description": null,
    "meta": {},
    "payment_method": {
      "type": "opay",
      "opay": {},
      "id": "pmd_uF9ADr9LvH",
      "customer_id": null,
      "meta": {},
      "device_fingerprint": null,
      "client_ip": null,
      "created_datetime": "2024-12-26T14:38:25.179Z"
    },
    "redirect_url": null,
    "reference": "ex61m23j6a3y0k34o9ilrri",
    "status": "succeeded",
    "processor_response": {
      "type": "approved",
      "code": "00"
    },
    "created_datetime": "2025-01-31T10:01:50.209Z"
  }
}
curl --request GET \
--url 'https://developersandbox-api.flutterwave.com/charges/id' \
--header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--header 'X-Trace-Id: <YOUR_UNIQUE_TRACE_ID>' \
--header 'X-Idempotency-Key: <YOUR_UNIQUE_INDEMPOTENCY_KEY>' \

You'll get a response similar to this:

{
  "status": "success",
  "message": "Charge fetched",
  "data": {
    "id": "chg_LgTqLXDGXq",
    "amount": 200,
    "currency": "NGN",
    "customer_id": "cus_dc0FUyBpd0",
    "settled": false,
    "settlement_id": [],
    "meta": {},
    "payment_method_details": {
      "type": "opay",
      "opay": {},
      "id": "pmd_uF9ADr9LvH",
      "meta": {},
      "created_datetime": "2024-12-26T14:38:25.179Z"
    },
    "reference": "ex61m23j6a3y0kk4o8ilrri",
    "status": "succeeded",
    "processor_response": {
      "type": "approved",
      "code": "00"
    },
    "created_datetime": "2024-12-27T08:52:18.128Z"
  }
}

Testing your integration requires no extra configuration or special data. Initiate the OPay charge, and we'll return a redirect link to our mock page, where you can simulate both successful and failed customer attempts.

That’s it! You’ve successfully integrated the OPay payment method. It doesn't end there, there is more:

Updated 7 months ago