OPay Recurring
OPay Recurring enables merchants in Nigeria to debit a customer's OPay wallet after the customer approves a recurring payment agreement in the OPay app. Merchants can create an enrollment only, or combine the enrollment with the first charge, depending on the billing use case.
OPay Recurring is available in Nigeria (ng) for payments in Nigerian naira (NGN). The payment method may also be referred to as OPay Debit.
Key Features
- Enrollment (one-time consent): customers approve the recurring agreement once in the OPay app.
- Two enrollment modes: enroll and charge (enrollment plus the first payment in a single request) or enrollment only (agreement set up now, charge later).
- Enroll and charge supports two use cases: subscription, for a fixed recurring amount, and variable on-file payments, for unfixed amounts on an unfixed cycle.
- Pre-debit notification: for the enroll and charge (subscription) flow only, EBANX sends OPay the amount and the debit date before each subsequent charge.
- Secure authentication: customers approve the agreement in the OPay mobile app with their OPay PIN or a phone OTP.
- Wallet-based debits: recurring charges are debited directly from the customer's OPay wallet balance.
- Minimum amount per transaction: 50 NGN.
- Maximum amount per transaction: 5,000,000 NGN.
- Refund date range: refunds can be processed within 180 days.
- Enrollment approval window: the customer has 30 minutes to approve the request in the OPay app. An enrollment that is still pending after 70 minutes expires and a new enrollment is required.
This guide explains how to create OPay Recurring enrollments, process recurring payments, monitor status changes, and cancel agreements through the EBANX API.
OPay Recurring must be displayed as a standalone payment method on the merchant checkout page. It should not be nested under another payment method, such as bank transfer. Contact our integration specialists for the official logo and branding guidelines.
Merchant onboarding and agreement template
Before integrating OPay Recurring, merchants must complete an onboarding process with OPay. This includes setting up an agreement template that defines the terms under which recurring debits are executed against customer OPay wallets. The agreement template must be created and approved by OPay before any enrollment or payment integration can begin.
The template is used to display the debit agreement to OPay wallet users when they are asked to authorize recurring payments, and it is identified by an agreement template ID assigned by OPay upon approval. There are two types of agreement templates:
- Enroll and charge - use it when the merchant needs to create the agreement and collect the first payment in one request. It supports fixed subscriptions and on-demand variable on-file payments.
- Enrollment only - use it when the merchant needs to create the agreement first and submit payment requests separately, including on-demand charges.
- For enroll and charge (subscription), a separate agreement template is required for each product offering. If you offer different products or plans (for example, a weekly, monthly or yearly package), an agreement template must be completed for each one.
- For enroll and charge (variable on-file payments), a single agreement template ID is required.
- For enrollment only, a single agreement template ID is enough. If required, separate agreement template IDs can be created for each product frequency (for example, daily, weekly, monthly or yearly).
Enrollment modes and use cases
Enroll and charge (subscription)
Use this flow for subscriptions with a fixed recurring amount defined in the agreement template — for example, a monthly streaming or membership plan. The customer authorizes the agreement and completes the first payment in the same journey: the first payment amount is sent in the request, and the fixed recurring amount is defined in the agreement template.
Enroll and charge (variable on-file payments)
Use this flow for enterprise merchants, such as retail merchants, that want to enable on-file style payments. The amount is not fixed: the merchant enrolls the customer once and can then charge unfixed amounts on an unfixed cycle. It suits retail and marketplace scenarios where the basket value and the billing frequency differ on each purchase, such as pay-as-you-go orders, top-ups or usage-based billing. For this use case, send frequency as ondemand.
Enrollment only
Use enrollment only when future charge amounts may change, or when you do not need to collect a payment during enrollment — typically for on-demand services. The integration requires two separate requests:
- Send an enrollment request without a payment amount, passing
frequencyasondemand. - Send a separate charge request to
/ws/directwhen the payment is due, which can be immediately after the enrollment is accepted.
Fixed amount and price changes (subscription use case): for enroll and charge (subscription), the amount set in the agreement is fixed and price changes are a manual process — they cannot be done through the API. To change a subscription price, contact your EBANX account manager or the sales engineering team with the new price, and EBANX coordinates the template update with OPay. If you anticipate frequent price changes, the enrollment only mode is more suitable, because it allows a different amount on each charge sent to /ws/direct.
Requirements
- API authentication - All API requests must be authenticated using JWS (JSON Web Signature). The legacy
integration_keyis being deprecated — if you still use it, follow the Migration Guide to transition to JWS. If you don't have credentials yet, complete the Merchant Signup Form. - Familiarity with EBANX Direct - This setup follows the same general structure as other payment methods, with a few unique steps for OPay Recurring, such as the pre-debit notification and the agreement management.
- OPay onboarding - The agreement template must be approved by OPay before you start the integration.
How it works
Customers authorize recurring payments through a cashier redirect flow. On enroll and charge, the merchant submits the enrollment and the first payment in a single request; on enrollment only, no payment is taken at the enrollment stage. In both modes, the customer is redirected to the OPay cashier page to authorize the agreement in the OPay app.
| Step | Action | Endpoint | Description |
|---|---|---|---|
| 1 | Create enrollment | /ws/userenrollment | Register the customer and define the recurring agreement terms |
| 2 | Customer approval | (via OPay app) | The customer is redirected to OPay to authorize the agreement in the OPay app |
| 3 | Query enrollment status | /ws/userenrollments/query | Poll this endpoint to confirm whether the enrollment was accepted |
| 4 | Pre-debit notification (enroll and charge subscription) | Handled by EBANX | Mandatory step: OPay is notified of the upcoming debit amount and date before each charge |
| 5 | Recurring payments | /ws/direct | Execute the recurring payment using the enrollment code linked to the OPay agreement |
| 6 | Enrollment cancellation | /ws/userenrollment | Where applicable, merchants can cancel the enrollment to terminate the agreement |
- Return URLs - the URL the customer returns to after the OPay approval flow is defined in the
back_urlsobject of the enrollment (back_urls.success). It applies to every OPay Recurring scenario and can also be sent in the recurring charge request. When it is not provided, EBANX uses the defaulturl_responseconfigured for your integration. - Enrollment status update - EBANX notifies you of enrollment status updates through webhooks sent to your registered URL.
- Pre-debit notification - for enroll and charge (subscription) only, EBANX sends OPay the upcoming amount and debit date before each subsequent charge.
- Subsequent payments - you submit
/ws/directrequests using themerchant_enrollment_code, which EBANX maps to the OPay agreement. - Payment status update - EBANX sends webhook notifications when the payment status changes.
- Pre-debit notification applies only to enroll and charge (subscription). It does not apply to enrollment only or to enroll and charge (variable on-file payments).
- Enrollment agreements can be canceled by the merchant through the
/ws/userenrollmentendpoint, or by the customer directly in the OPay app.
Instructions
To complete an OPay Recurring enrollment and process recurring payments, follow the steps below.
- Select your environment
Select the appropriate environment for your integration. Use the sandbox environment for testing, or the production environment for live transactions. Use the URL for your HTTP requests based on your selection.
Check the method's availability for your country and tenant in Payment Methods by Country. Questions about tenant and environment? Check our API Operability and API Endpoints.
Cross-border sandboxhttps://sandbox.ebanxpay.com/ws/direct - Define your enrollment parameters
To start the recurring payment process, enroll the customer using the
/ws/userenrollmentendpoint for enrollment only, or the/ws/directendpoint for enroll and charge. This step involves collecting the customer details and configuring the agreement.Basic parameters
These apply to all enrollment options.
Parameter Requirement Description integration_keyRequired Your EBANX integration key payment_type_codeRequired Must be opay-recurringoperationRequired Must be enrollmenton/ws/userenrollmentrequestsEnrollment data
The
phone_numberlinked to the customer's OPay wallet is required to initiate the transaction. Where each field goes depends on the endpoint you call:/ws/userenrollment(enrollment only) - send every field below inside theenrollmentobject, with thesubscriptionfields insideenrollment.subscription./ws/direct(enroll and charge) - send the customer fields (country,name,emailandphone_number) inside thepaymentobject, alongside the payment fields. Onlymerchant_enrollment_code,subscriptionandback_urlsgo insidepayment.enrollment.
Parameter Requirement Description countryRequired Must be ngemailRequired Customer's email address nameRequired Customer's full name phone_numberRequired Customer's phone number linked to the OPay wallet merchant_enrollment_codeRequired Your unique identifier for this enrollment subscription_nameRequired Descriptor of the service being provided, or a short description that helps the customer understand this enrollment frequencyRequired Billing cycle of the agreement. Supported values: daily,weekly,monthly,yearlyandondemandstart_dateOptional Scheduled date for the first transaction that starts the enrollment ( YYYY-MM-DD)expiration_dateOptional Defines when the enrollment is no longer valid, after which no further payments are charged ( YYYY-MM-DD)NotePass the
frequencythat corresponds to the agreement template created during onboarding, so the request is routed to the correct template in OPay. For enrollment only and for enroll and charge (variable on-file payments), passondemand.Return URLs (
back_urls)back_urlsdefines where the customer is sent back to after the OPay approval flow. It applies to every OPay Recurring scenario and can also be sent in the recurring charge request. Send it inside theenrollmentobject.Parameter Requirement Description back_urlsConditional Return URL configuration for the OPay approval flow. Required unless a default url_responseis already configured for your EBANX integrationback_urls.successRequired with back_urlsHTTPS URL where the customer is redirected after completing the OPay approval flow. This is the only URL used by OPay Recurring back_urls.failureRequired with back_urlsMust be included when back_urlsis provided, although it is not used by this flow. It can be an empty stringNoteFor OPay Recurring, EBANX uses only
back_urls.success. If you provide theback_urlsobject, you must include bothsuccessandfailure, andfailurecan be empty. You can omit the entireback_urlsobject when a default response URL (url_response) is configured for your EBANX integration. If you are unsure whetherurl_responseis configured, contact your EBANX integration representative. - Enrollment option one: Enroll and charge
This option creates the enrollment and processes the first payment in a single
/ws/directrequest: the customer signs the agreement and the first charge is executed in the same journey. Use it for a fixed subscription or for an unfixed-cycle, unfixed-amount variable on-file payment.In addition to the basic and enrollment fields, include the following payment fields:
Parameter Requirement Description operationRequired Must be requestmerchant_payment_codeRequired Your unique identifier for this payment currency_codeRequired Must be NGNamount_totalRequired Amount of the first payment, in naira Check a request example below:
Shellcurl -X POST 'https://sandbox.ebanxpay.com/ws/direct' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{{integration_key}}",
"operation": "request",
"payment": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "5555555555",
"country": "ng",
"payment_type_code": "opay-recurring",
"merchant_payment_code": "{{unique_merchant_code}}",
"currency_code": "NGN",
"amount_total": 99.85,
"enrollment": {
"merchant_enrollment_code": "{{unique_enrollment_code}}",
"subscription": {
"subscription_name": "{{subscription_name}}",
"frequency": "monthly"
},
"back_urls": {
"success": "https://merchant.example.com/callback/success",
"failure": ""
}
}
}
}'A successful response returns
status: SUCCESS, the payment data, and aredirect_url. Redirect the customer to this URL to authorize the agreement in OPay.JSON{
"payment": {
"hash": "69b7212caaacfdfcfe743224f7c40d4bbec37d53233b186c",
"country": "ng",
"merchant_payment_code": "{{unique_merchant_code}}",
"order_number": null,
"status": "PE",
"status_date": "2026-03-15 21:14:20",
"open_date": "2026-03-15 21:14:20",
"confirm_date": null,
"transfer_date": null,
"amount_br": "99.85",
"amount_ext": "99.85",
"amount_iof": "1",
"currency_rate": "1",
"currency_ext": "NGN",
"due_date": "2026-03-16",
"instalments": "1",
"payment_type_code": "opay-recurring",
"redirect_url": "https://sandbox.ebanxpay.com/ws/redirect?hash=69b7212caaacfdfcfe743224f7c40d4bbec37d53233b186c",
"pre_approved": false,
"capture_available": null,
"customer": {
"document": "",
"email": "john.doe@example.com",
"name": "John Doe",
"birth_date": null
}
},
"status": "SUCCESS",
"redirect_url": "https://sandbox.ebanxpay.com/ws/redirect?hash=69b7212caaacfdfcfe743224f7c40d4bbec37d53233b186c"
} - Enrollment option two: Enrollment only
This option creates the enrollment without processing a payment: the customer signs the agreement only, and charges are sent later with the enrollment code. No parameters beyond the basic and enrollment parameters are needed, and no amount is sent during the enrollment.
Check a request example below:
Shellcurl -X POST 'https://sandbox.ebanxpay.com/ws/userenrollment' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{{integration_key}}",
"payment_type_code": "opay-recurring",
"operation": "enrollment",
"enrollment": {
"country": "ng",
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "5555555555",
"merchant_enrollment_code": "{{unique_enrollment_code}}",
"subscription": {
"subscription_name": "{{subscription_name}}",
"frequency": "ondemand"
},
"back_urls": {
"success": "https://merchant.example.com/callback/success",
"failure": ""
}
}
}'Check a response example below:
JSON{
"status": "SUCCESS",
"redirect_url": "https://sandbox.ebanxpay.com/ws/redirect?hash=a4f9c1d7e83b6a5f2c9e0d14b7a62f3c8d1e9b4a7f6c2d10",
"enrollment": {
"merchant_enrollment_code": "{{unique_enrollment_code}}",
"country": "ng",
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "5555555555",
"back_urls": {
"success": "https://merchant.example.com/callback/success",
"failure": ""
},
"subscription": {
"frequency": "ondemand",
"subscription_name": "{{subscription_name}}"
}
}
} - Redirect the customer and check the enrollment status
After a successful enrollment request, redirect the customer to the returned
redirect_urlto authorize the recurring agreement in OPay. EBANX sends an asynchronous notification once OPay reports the agreement status:Textoperation=enrollment_status_change¬ification_type=update&merchant_enrollment_code={{unique_enrollment_code}}You can also retrieve the latest enrollment status before submitting a payment. Query
/ws/userenrollments/querywith themerchant_enrollment_codeto confirm that the enrollment was accepted.Parameter Requirement Description integration_keyRequired Your EBANX integration key enrollment.merchant_enrollment_codeRequired Unique identifier defined by the merchant for the enrollment Check a request example below:
Shellcurl -X POST 'https://sandbox.ebanxpay.com/ws/userenrollments/query' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{{integration_key}}",
"enrollment": {
"merchant_enrollment_code": "{{unique_enrollment_code}}"
}
}'A successful query returns
status: SUCCESS. An agreement authorized by the customer has an enrollment status ofaccepted:JSON{
"status": "SUCCESS",
"payment_type": "opay-recurring",
"enrollment": {
"status": "accepted",
"email": "john.doe@example.com"
}
}OPay agreement statuses map to EBANX enrollment statuses as follows:
OPay status Meaning EBANX enrollment status YSigned / active acceptedNTerminated revokedYDSigning in progress pendingNDTerminating in progress pending - Pre-debit notification (mandatory for subscriptions)
For the enroll and charge (subscription) use case, a pre-debit notification must be sent to the customer before each recurring charge. This is a mandatory step required by OPay's recurring payment infrastructure, so that customers are informed of upcoming debits from their wallet.
From the merchant perspective, only one request is required:
- Submit the recurring payment through
/ws/directusing themerchant_enrollment_codeof the accepted agreement. - EBANX sends the pre-debit notification to OPay. You do not need to call a separate endpoint.
- EBANX holds the payment during the mandatory 24-hour notification window.
- After the waiting period, EBANX submits the debit request to OPay.
- The payment stays pending (PE) during the window. After OPay confirms the debit it changes to confirmed (CO), and EBANX sends a status notification.
Note- Pre-debit notification applies only to enroll and charge (subscription). It does not apply to enrollment only or to the variable on-file payments flow.
- Each subsequent subscription charge requires a pre-debit notification.
- Allow at least 24 hours between submitting the payment request and the charge execution. This is a mandatory customer notification window.
- Configure payment notifications and use
/ws/querywhen you need to retrieve the latest payment status.
- Submit the recurring payment through
- Process recurring payments
After the enrollment is accepted, submit the charge through
/ws/direct. For the subscription flow, EBANX applies the required pre-debit notification window before executing the debit. The charge is debited from the customer's OPay wallet balance.Parameter Requirement Description integration_keyRequired Your EBANX integration key operationRequired Must be requestpayment_type_codeRequired Must be opay-recurringcountryRequired Must be ngcurrency_codeRequired Must be NGNamount_totalRequired Total amount to be charged, in naira merchant_payment_codeRequired Your unique identifier for this payment nameRequired Customer's full name emailRequired Customer's email address phone_numberRequired Customer's phone number linked to the OPay wallet merchant_enrollment_codeRequired Enrollment code created in the previous steps, sent inside the payment.enrollmentobject. The enrollment must have anacceptedstatus to be chargedback_urlsConditional Return URL configuration for the OPay approval flow. See Return URLs Check a request example below:
Shellcurl -X POST 'https://sandbox.ebanxpay.com/ws/direct' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{{integration_key}}",
"operation": "request",
"payment": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone_number": "5555555555",
"country": "ng",
"payment_type_code": "opay-recurring",
"merchant_payment_code": "{{unique_merchant_code}}",
"currency_code": "NGN",
"amount_total": 99.85,
"enrollment": {
"merchant_enrollment_code": "{{unique_enrollment_code}}"
}
}
}'A successful request returns
status: SUCCESS, and the payment stays pending (PE) until OPay confirms the debit.JSON{
"payment": {
"hash": "69b72acadc65a48bd0d7c3728705b4afa18289d4e61d58a7",
"country": "ng",
"merchant_payment_code": "{{unique_merchant_code}}",
"order_number": null,
"status": "PE",
"status_date": "2026-03-15 21:14:20",
"open_date": "2026-03-15 21:14:20",
"confirm_date": null,
"transfer_date": null,
"amount_br": "99.85",
"amount_ext": "99.85",
"amount_iof": "1",
"currency_rate": "1",
"currency_ext": "NGN",
"due_date": "2026-03-16",
"instalments": "1",
"payment_type_code": "opay-recurring",
"pre_approved": false,
"capture_available": null,
"customer": {
"document": "",
"email": "john.doe@example.com",
"name": "John Doe",
"birth_date": null
}
},
"status": "SUCCESS"
}NoteBefore retrying a failed or timed-out payment, query the original payment status to avoid creating a duplicate debit. Retry only after the original request is confirmed as unsuccessful.
Confirming the payment
As soon as the payment is confirmed, the payment status changes from
PEtoCOand a status update notification is sent to your configured webhook URL:JSON{
"operation": "payment_status_change",
"notification_type": "update",
"merchant_payment_code": "{{unique_merchant_code}}"
}Using the
hashreturned in the payment response, call the/ws/queryendpoint to get the latest status of the payment:Shellcurl -X POST 'https://sandbox.ebanxpay.com/ws/query' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{{integration_key}}",
"hash": "69b72acadc65a48bd0d7c3728705b4afa18289d4e61d58a7"
}'Now, repeat this step for each billing cycle. For enroll and charge (subscription), EBANX also repeats the pre-debit notification process.
- Enrollment cancellation
Customers can request the enrollment cancellation at any time. To comply with the request, cancel the enrollment by sending
operation: cancelto/ws/userenrollment. Once an enrollment is revoked it can no longer be used for future transactions, and a new enrollment is required to resume recurring debits.Check a request example below:
Shellcurl -X POST 'https://sandbox.ebanxpay.com/ws/userenrollment' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{{integration_key}}",
"operation": "cancel",
"payment_type_code": "opay-recurring",
"enrollment": {
"merchant_enrollment_code": "{{unique_enrollment_code}}"
}
}'Check a response example below:
JSON{
"status": "SUCCESS",
"enrollment": {
"status": "revoked",
"email": "john.doe@example.com"
}
}Notifications
-
EBANX sends a notification whenever a payment status changes.
-
Make sure your system is set up to receive notifications from EBANX for any changes in payment status.
Status
-
After receiving a notification that the status has changed, retrieve the payment status.
-
A successful payment changes from pending (PE) to confirmed (CO). An unsuccessful payment moves to canceled (CA) or to another failure status returned by the API.
-
- Congratulations!
You have successfully integrated OPay Recurring.
For more information, refer to theDirect API reference guidechevron_right
Error codes
When an enrollment or a charge request fails, EBANX returns the error in the status_code field of the response. The tables below list the errors you can expect when integrating OPay Recurring. For the full reference, see API Error Codes, APM Response Codes and Enrollment Response Codes.
Enrollment creation errors
| Code | Error message | Description |
|---|---|---|
BP-UE-42 | Provider rejected enrollment creation | OPay declined the enrollment. It happens when authentication fails on the provider side, the payment method is not supported, the request reference was already used, the merchant is not available, the agreement template expired, or the template only allows automatic renewal. The response does not indicate which cause applies. If the enrollment code was already used, generate a new, unique merchant_enrollment_code and retry. Otherwise, check your OPay configuration — payment method availability, merchant status and agreement template validity — and contact your EBANX integration representative if the rejection persists |
BP-UE-34 | Request with invalid params | One or more parameters were rejected by OPay: invalid request params, an agreement expiration date outside the allowed window, or an amount that does not match the agreed subscription amount |
BP-UE-12 | Failed to communicate with provider | Credential or agreement mismatch: the agreement template ID is incorrect, or the merchant ID does not match the agreement. Contact your EBANX integration representative |
BP-UE-32 | Provider internal server error | OPay is facing downtime, or the request was sent outside the time window in which it accepts the operation. Retry later |
Payment processing errors
When a charge is declined, the payment moves to canceled (CA) and the reason is returned in the transaction_status node of the payment query response, in both description and description_code:
"transaction_status": {
"acquirer": "EBANX",
"code": "NOK",
"description": "Not accepted",
"description_code": "NOT_ACCEPTED"
}
description_code | Payment step | Details |
|---|---|---|
NOT_ACCEPTED | Charge rejected by the provider | OPay declined the charge: do not honor, restricted or suspected fraud, transaction not permitted, or limits and attempts exceeded. Do not retry automatically |
INVALID_PARAMETERS | Charge rejected by the provider | The parameters sent in the charge request were rejected. Review the payload against the required fields and the amount limits of the agreement |
PAYMENT_NOT_VALID | Charge rejected by the provider | The payment method sent is not supported for the recurring charge. Confirm that payment_type_code is opay-recurring and that the enrollment is active |
DUPLICATE_TRANSACTION | Charge rejected by the provider | The merchant_payment_code was already used. Generate a new, unique code before retrying |
TIMEOUT | Charge not answered by the provider | OPay did not respond within the expected time. Query the payment status before retrying to avoid a double charge |
PROVIDER_RESPONSE_ERROR | Charge failed at the provider | OPay returned an internal or unexpected response. Retry later; if it persists, contact EBANX Support |
Enrollment cancellation reasons
When an enrollment status is not_accepted, expired or revoked, the query response includes the reason that caused its termination. Check the enrollment status with the /ws/userenrollments/query endpoint, referencing the merchant_enrollment_code. The response returns the latest status in status, the timestamp of the last change in status_date, the reason code in reason_code, and a description with more details:
"enrollment": {
"status": "not_accepted",
"status_date": "2026-08-03 10:16:43",
"reason_code": "NOT_ACCEPTED",
"description": "Not accepted"
}
reason_code | Description | Details |
|---|---|---|
NOT_ACCEPTED | Not accepted | OPay declined the request: do not honor, restricted or suspected fraud, transaction not permitted, invalid request, or limits and attempts exceeded. Do not retry automatically |
INVALID_PARAMETERS | Request with invalid params | OPay rejected the parameters sent in the request. Review the payload against the required fields and the amount limits of the agreement |
PAYMENT_NOT_VALID | Payment method not supported | The payment method sent is not supported for the recurring charge. Confirm that payment_type_code is opay-recurring and that the enrollment is active |
DUPLICATE_TRANSACTION | Duplicated request reference | The merchant_enrollment_code was already used. Generate a new, unique code and retry |
TIMEOUT | External service not available, try again | OPay did not respond within the expected time. Query the payment status before retrying to avoid a double charge |
PROVIDER_RESPONSE_ERROR | Provider response error | OPay returned an internal or unexpected response. Retry later; if it persists, contact EBANX Support |
OPay Recurring UX flow
The screens below illustrate the customer journey for each supported use case.
Enrollment only
Enable background charging on your platform without requiring customer re-authentication at every transaction: the customer authorizes the auto-debit once, and you trigger charges automatically within the agreed transaction limits.
Merchant checkout
The customer selects OPay as a payment method, reviews the service terms, debit priority, transaction limit and linked OPay account, and then activates the agreement. No payment is collected.
Payment authentication (PIN or OTP)
The customer confirms the agreement using the OPay payment PIN or a phone OTP.
Enrollment status (successful or failed)
Display the enrollment result, showing whether the agreement was activated or failed, and provide a clear return path to the merchant.
Enroll and charge (subscription)
Offer customers a recurring billing experience with automatic fixed-amount deductions from the OPay wallet. The customer authenticates once to authorize the recurring auto-debit, the subscription is activated, and you are notified of the successful payment.
Merchant checkout
The customer selects the subscription plan, chooses OPay, reviews the fixed recurring amount, and verifies the phone number linked to the wallet.
Auto-debit agreement
OPay displays the first payment amount, the fixed renewal amount, the next debit date and the wallet details before the customer selects Pay and Activate.
Payment authentication (PIN or OTP)
The customer selects the wallet balance and confirms the combined request with a PIN or a phone OTP.
Enroll and charge (variable on-file payments)
Accept OPay wallet payments with an express payment setup: the customer authenticates via PIN or OTP to complete the purchase, the order is confirmed, and the wallet is linked for faster future checkouts.
Merchant checkout
The customer selects OPay at checkout, reviews the current order amount and the variable payment agreement, and then chooses Pay and Activate.
Payment authentication (PIN or OTP)
The customer confirms the combined enrollment and first charge using the OPay PIN or a phone OTP.
Payment status and linked wallet
Show the activation and payment result. After a successful payment, display the linked OPay wallet as an available payment method for later purchases.
Customer notifications and agreement management
Successful auto-debit notification
After a successful debit, OPay can inform the customer through in-app messages, SMS, the transaction page and email.
Auto-debit management in the OPay app
Customers can review active agreements, inspect the debit terms, disable an agreement, and authenticate the change with their OPay PIN.
Resources
Use the following resources when testing in your sandbox environment.
API Reference
Click here to access detailed API documentation to integrate efficiently.
Mock Customer Data
Click here to view mock customer data for testing and validating user flows.
Error Codes
Click here to review common error codes to troubleshoot and resolve issues quickly.
Still need help?
We hope this article was helpful. If you still have questions, you can explore the following options:
- Merchant support: Contact our support team at sales.engineering@ebanx.com for assistance.
- Not a partner yet? Please complete the Merchant Signup Form, and our commercial team will reach out to you.