Dokumen ini menjadi panduan untuk menambahkan provider baru ke Rute Bayar tanpa mengganggu core logic.
Setiap provider adapter wajib menyediakan:
- create payment
- get payment status
- refund payment
- verify webhook
- parse webhook event
- map status provider ke status internal
- capability declaration
Core system harus punya status netral provider, misalnya:
pendingpaidfailedexpiredcancelledrefundedpartial_refundedsettledauthorizedcaptured
Provider-specific status harus selalu dipetakan ke status internal ini.
pending->pendingsettlement->settledcapture+fraud_status: accept->capturedcapture+ fraud status selainaccept->pendingdeny->failedfailure->failedcancel->cancelledexpire->expiredrefund->refundedpartial_refund->partial_refunded
Catatan: mapping settlement -> settled dipilih agar status provider tetap informatif. Jika consumer butuh status bisnis yang lebih sederhana, application layer bisa memperlakukan settled sebagai paid-like final state.
- Payment Session
ACTIVE->pending
Mapping Xendit lain perlu dilengkapi saat implementasi create/status Payment Session masuk.
- Checkout
ORDER_GENERATED->pending - Transaction
PENDING->pending - Transaction
SUCCESS->paid - Transaction
FAILED->failed - Transaction
EXPIRED->expired - Transaction
REFUNDED->refunded - Transaction
PARTIAL_REFUNDED->partial_refunded
status_code=-2->expiredstatus_code=0->pendingstatus_code=1->paidstatus_code=2->failedstatus_code=3->refundedstatus_code=4->failedstatus_code=5->failedstatus_code=6->paidstatus_code=7/StatusDesc=EscrowdenganPaidStatus=paid->paid(terlihat pada sandbox QRIS iPaymu setelah pembayaran sukses)
- Endpoint aktif:
POST /sessions(Payment Session API). CreatePaymentRequestdipetakan ke payloadreference_id,session_type=PAY,mode=PAYMENT_LINK,amount,currency,country,items[],customer.reference_iddiisi dariexternal reference.items[].categorydanitems[].typewajib sesuai simulasi untuk menghindari validasi gagal.- Response status awal umumnya
ACTIVEdan dipetakan kepending. - URL pembayaran diambil dari
payment_link_urldan ditampilkan sebagairedirect_url.
- Endpoint aktif:
POST /checkout/v1/payment. CreatePaymentRequestdipetakan ke payloadorder.amount,order.invoice_number,order.currency, danpayment.payment_due_date.--method checkoutmembiarkan DOKU Checkout menampilkan metode pembayaran aktif dari dashboard.--notification-urldikirim sebagaiadditional_info.override_notification_url.- Request ditandatangani dengan header
Client-Id,Request-Id,Request-Timestamp,Digest, danSignature. - URL pembayaran diambil dari
response.payment.urldan ditampilkan sebagairedirect_url.
Untuk setiap provider:
- Verifikasi webhook sesuai mekanisme resmi provider.
- Simpan payload mentah dan headers mentah.
- Cek dedup/idempotency.
- Normalisasi event.
- Update payment state.
- Jika forwarding aktif, kirim payload asli ke target user.
Webhook tidak boleh jadi satu-satunya sumber kebenaran.
Jika webhook gagal, terlambat, atau status belum final, sistem harus bisa:
- mengecek status lewat API provider
- membandingkan hasilnya dengan state internal
- memperbarui state bila ada perubahan
Untuk debugging, semua provider harus menyimpan:
- outbound request JSON
- outbound response JSON
- inbound webhook JSON
- inbound webhook headers JSON
Implementasi awal pay create untuk Midtrans memakai Core API bank transfer:
payment_type=bank_transfertransaction_details.order_idberasal dari external reference internaltransaction_details.gross_amountberasal dari amount requestbank_transfer.bankberasal dari bank/channel yang dipilih user
Untuk validasi webhook sandbox, pay create mendukung override URL notifikasi Midtrans per transaksi:
rutebayar pay create \
--provider midtrans \
--method qris \
--bank gopay \
--reference rb-midtrans-qris-001 \
--amount 15000 \
--notification-url https://<public-domain>/webhooks/midtransNilai tersebut dikirim sebagai header X-Override-Notification pada request Midtrans Core API.
Untuk Xendit Payment Sessions, pay create --notification-url tidak didukung karena dokumentasi resmi Xendit tidak menyediakan override webhook per transaksi.
Konfigurasikan webhook/callback URL di Xendit Dashboard ke endpoint daemon:
https://<public-domain>/webhooks/xendit
Jika payload perlu diteruskan ke aplikasi lain, gunakan fitur forwarding Rute Bayar agar webhook tetap masuk, tersimpan, diverifikasi, dan bisa direplay dari daemon.
Adapter harus menyimpan raw request dan raw response JSON ke payment attempt.
Konfigurasikan notification URL DOKU ke endpoint daemon:
https://<public-domain>/webhooks/doku
Rute Bayar memverifikasi Signature DOKU dengan target path webhook, digest body, client ID, request ID, timestamp, dan secret key.
Untuk per-payment override, gunakan:
rutebayar pay create \
--provider doku \
--method checkout \
--reference rb-doku-001 \
--amount 15000 \
--notification-url https://<public-domain>/webhooks/dokuRefund DOKU belum diaktifkan karena membutuhkan setup Refund API/disbursement.
- Base URL sandbox:
https://sandbox.ipaymu.com. - Base URL production:
https://my.ipaymu.com. - Redirect payment memakai
POST /api/v2/payment. - Request body iPaymu API v2 dikirim sebagai JSON; signature dihitung dari JSON body tersebut sesuai dokumen signature iPaymu.
notifyUrlwajib untuk create payment sandbox/production, termasuk redirect payment.- Direct payment memakai
POST /api/v2/payment/directuntuk metode/channel yang dikirim via--methoddan--bank. - Status lookup memakai
POST /api/v2/transactiondengantransactionIdprovider. - Sandbox QRIS dapat mengirim callback
pendinglaluberhasil, tetapi callback memakaiapplication/x-www-form-urlencoded; pastikan verifikasi signature webhook memakai canonical body callback yang benar, dan gunakan reconciliation sebagai fallback source-of-truth jika verifikasi gagal. - Credential onboarding menyimpan
va,api_key, dan optionalaccount:
rutebayar onboard ipaymu \
--va "$IPAYMU_VA" \
--api-key "$IPAYMU_API_KEY" \
--environment sandboxCreate redirect payment:
rutebayar pay create \
--provider ipaymu \
--method redirect \
--reference rb-ipaymu-001 \
--amount 15000 \
--notification-url https://<public-domain>/webhooks/ipaymu- Refund iPaymu belum diimplementasikan dan belum dapat diverifikasi lewat API publik iPaymu v2. Collection publik iPaymu tidak mengekspos endpoint refund; probe sandbox bertanda tangan ke beberapa kandidat endpoint refund/cancel juga mengembalikan
404/405bahkan untuk transaksi QRIS paid. Perlakukan refund iPaymu sebagai unsupported sampai iPaymu support/dashboard memberikan endpoint resmi dan payload yang dibutuhkan.
- Forwarding bersifat pass-through.
- Payload yang diforward tetap apa adanya dari provider.
- Retry policy default berlaku jika user tidak mengubahnya via CLI.
- Provider adapter tidak perlu tahu target forwarding; logic forwarding berada di daemon/application layer.
Kalau provider baru ditambahkan nanti, langkah minimum:
- Tambah adapter baru.
- Tambah capability registry.
- Tambah mapping status.
- Tambah webhook endpoint.
- Tambah onboarding flow di CLI.
- Tambah test sandbox.