Skip to main content
Buy Now, Pay Later (BNPL) allows your customers to split their purchases into multiple instalments — while you receive the payment in full once the provider confirms the transaction.
It’s a popular financing option that improves conversion rates and average order values by offering customers greater payment flexibility without upfront burden.
Monxa’s BNPL integration simplifies the process by standardizing diverse provider APIs into a unified Charge API experience. Developers can enable multiple BNPL providers (e.g., Atome, Kredivo, PayLater) using the same flow, parameters, and webhook structure — without worrying about each provider’s technical nuances. BNPL payments on Monxa are direct-capture only, meaning that once the customer confirms the payment plan with the provider, the transaction is immediately captured. There is no authorisation or delayed capture step. Refunds, if supported, are handled through Monxa’s Refund API, and settlement follows the provider’s remittance schedule to your Monxa Balance or bank account.

Key Benefits

  • 💳 Increase conversion: Offer instalment options at checkout for affordability.
  • 🛒 Higher order value: Customers are more likely to spend more when paying later.
  • ⚙️ Unified API: Same request/response structure across providers and regions.
  • 🧾 Automatic capture: Simplifies fulfilment since funds are captured immediately.
  • 🔄 Refund support: Full or partial refunds available depending on provider policy.
  • 🌏 Regional reach: Support for major BNPL providers in Southeast Asia and beyond

1. Create a Charge

Initiate the payment by creating a charge in your system with the transaction details.

2. Redirect Customer to BNPL App

Use the redirect_url from Monxa to send the customer to their BNPL app or platform.

3. Customer Authorizes Payment

The customer confirms the transaction by entering their PASSWORD / PIN / OTP or using biometric authentication in their BNPL app.

4. Handle Webhooks

Once the e-wallet provider processes the payment, Monxa sends a webhook notification to update your system with the final status.

Supported Channels

Payment Flow

Status Lifecycle (BNPL)

Step 1: Create a Charge

Create a charge with a BNPL channel_code (examples: bnpl_atome, bnpl_kredivo, etc.) and include a return_url so we can return customers to your site/app after they complete the BNPL flow.
Endpoint: POST /v1/charges
The response includes a qr_data that contains the information needed to generate a scannable QR code (qr_data).

Step 2: Redirect the Customer

Use actions.redirect_url to send the customer to the BNPL provider’s hosted checkout. Do not generate a QR code—BNPL is a redirect + hosted authentication flow (KYC/eligibility and plan selection happen on the provider’s side).
  • Web: HTTP 302 or client-side redirect.
  • Mobile: Open in an in-app webview or external browser; handle the return_url to resume your flow.

Step 3: Customer Authorizes & Selects a Plan

On the provider page, the customer:
  1. Logs in or signs up (provider KYC/eligibility).
  2. Selects an installment plan (tenor/fees shown by the provider).
  3. Confirms the payment.
If approved, the provider captures the amount (direct capture) and we update the charge status.

Step 4: Handle Webhooks & Update Your Order

Rely on webhooks to make authoritative updates to your order or fulfillment state. Key events
  • charge.succeeded — BNPL approved & captured; safe to deliver goods/services.
  • charge.failed — Rejected, canceled, or provider error.
  • charge.expired — Customer didn’t complete within the session window.
  • refund.succeeded / refund.failed — If you initiate a refund later (subject to provider rules).
Always verify the event by fetching the charge (GET /v1/charges/) before updating your system.

Refunds (Provider-Dependent)

  • Supported: Usually allowed post-capture; partial refunds may be supported depending on the BNPL provider and time window.
  • Not Supported / Window Lapsed: Some providers restrict partial refunds or disallow refunds beyond a certain number of days.
  • API: Use POST /v1/refunds with charge_id, amount (optional for partial), and reason. Monitor refund.succeeded / refund.failed.
    For operational certainty, maintain a BNPL provider matrix in your ops/wallet config (flags for supports_partial_refund, refund_window_days, fees, etc.).

Error Handling & Retries

  • Idempotency: Always set a unique Idempotency-Key per create attempt. Reuse the same key on client/network retries to avoid double charges.
  • Common errors:
    • 400 invalid_channel_properties — Missing/invalid return_url.
    • 400 unsupported_channel — BNPL provider not enabled for your account/country.
    • 402 provider_declined — Eligibility/credit check failed.
    • 409 duplicate_reference — If your environment enforces unique reference_id.
  • Recovery: On failed/expired, offer retry (create a new charge with a fresh Idempotency-Key).