Skip to content

When to use this gateway

Pick the right method field on POST /v1/payments before writing any code. Mismatches surface as 422 errors at request time, but it’s faster to get it right up front.

Buyer pays inProduct typemethodRoutes toNotes
IDRAnythingqrisNICEPAYUniversal QR; any wallet (GoPay/OVO/DANA/ShopeePay/BCA Mobile) scans it.
IDRAnythingva_bca / va_mandiri / va_bni / va_bri / va_permataNICEPAYBank-specific virtual account; buyer transfers from the matching bank’s app.
IDRCard / wallet(not wired)Returns 422 no provider supports method=cc for currency=IDR. NICEPAY card processing pending merchant approval.
USD/EUR/GBPSaaS / digital product / one-time licensepolar (override)Polar.shMoR — Polar handles VAT + chargebacks globally.
USD/EUR/GBPServices (productized human work)paypal (override)PayPalPolar’s AUP rejects services; book.uncle-z.com is the canonical example.

paypal and polar are method overrides — they win over currency-based routing absolutely. Useful when you want to force a specific rail (e.g., a USD product that you’d rather charge through PayPal even though Polar is the default for non-IDR).

Stop and rethink if your use case is:

  • Subscription billing logic. Polar runs renewals; the gateway records the first charge and any cancel events but does NOT run dunning, prorations, or grace periods. Your product is the source of truth for “is this user’s subscription active right now.”
  • Tax computation. Polar / Paddle (when MoR) handle global VAT for non-IDR. IDR rails are domestic only. Don’t try to add VAT logic on top of the gateway.
  • Wallet / store credit / account balance. Each POST /v1/payments is a discrete charge. There’s no “user has $X in their account” concept on the gateway.
  • Invoice rendering. The gateway issues invoice_number to the PSP for receipt-traceability only. Customer-facing PDFs / emails / receipts are the product’s responsibility.
  • 3DS / SCA orchestration. The PSPs handle that on their hosted pages. If you need to embed a card form in your own UI with custom 3DS, you’re outside the gateway’s scope — talk to ops.

You don’t have to. But if you ever do:

  • Your product owns the payment record forever (the gateway only knows payment_id — your DB has booking_ref, subscription_id, etc.).
  • The gateway can be disabled per-app (archived_at) without losing history.
  • Outbound webhooks dead-letter cleanly if your endpoint goes away.