Payment (DOKU)
Payment adalah DOKU. Backend membuat payment dan memverifikasi callback; storefront membuka widget checkout DOKU.
Cara halaman ini diverifikasi
Dibaca pada 2026-09-15 dari module payments backend dan hook DOKU storefront.
Backend
Module payments tidak punya entity sendiri — data payment ada di order. Ia REST-only (tidak ada di include GraphQL).
PaymentsService(src/payments/services/payments.service.ts) adalah client DOKU:postPaymentRequestdancheckPaymentStatus. Base URLDOKU_BASEURL; kredensialDOKU_CLIENT_IDdanDOKU_SECRET_KEY; tiap request ditandatangani HMAC-SHA256 (HMACSHA256=<base64>). Payment window adalahDOKU_PAYMENT_DUE_DATE_MINUTE.- URL callback dibangun dari
APP_FRONTEND_STOREFRONT_BASE_URL; notify DOKU menuju${APP_BACKEND_BASE_URL}/webhooks/payments. webhook-payments.service.tshandleEvent: padatransaction.status === 'SUCCESS'ia memindahkan order keprocessing. Backend dibuat denganrawBody: trueagar bisa memverifikasi signature DOKU.
Order dibuat dengan payment link selama createOrder() — lihat Cart and checkout.
Storefront
src/hooks/useDokuCheckoutPayment.tsx memuat script Jokul Checkout DOKU (URL sandbox vs production berdasarkan NEXT_PUBLIC_DOKU_ENV) dan memanggil window.loadJokulCheckout(paymentUrl) dengan paymentLinkUrl yang dikembalikan frontValidateMemberCartCheckout. Saat ditutup, customer mendarat di /user/my-order?status=pending_payment. Hook yang sama menjalankan "pay again" dari detail order (src/modules/my-order/components/order-item-detail.tsx).
Order yang belum dibayar
Order yang tertinggal pending_payment melewati window-nya dibatalkan oleh order expiry cron, yang mengecek ulang DOKU lebih dulu.
Hal yang perlu diwaspadai
- Signature butuh raw body. Backend menjaga
rawBody: truejustru untuk ini — jangan hilangkan. - Di dev, DOKU adalah simulator. Simulator bisa memaksa DOKU error; kegagalan payment di dev bisa jadi toggle-nya, bukan kodenya.
- Jalur callback production yang masuk menyebar lewat webhook receiver → SNS, bukan langsung ke backend.