Arsitektur Checkout Multi-Mata Uang Idempoten di Django & PostgreSQL: Auto-Capture Orders API v2, Verifikasi Webhook & QRIS
Pola Produksi FinTech & SaaS: Platform perangkat lunak global yang melayani pembayaran Kartu Kredit/Debit Internasional (USD) sekaligus QRIS & Virtual Account Bank Indonesia (IDR) sering menghadapi tiga risiko kritis: (1) pesanan berstatus APPROVED yang belum ter-capture ketika pengguna menutup tab browser sebelum redirect selesai, (2) pengiriman notifikasi ganda saat return URL berpacu dengan webhook asinkron, dan (3) pemalsuan payload webhook. Berikut adalah arsitektur Python, Django, dan PostgreSQL yang kami jalankan di produksi pada Google Cloud Run.
1. Siklus Dua Tahap: Auto-Capture saat Return URL + Pemulihan Webhook dengan SELECT FOR UPDATE
Pada alur pesanan dua tahap (intent: CAPTURE), persetujuan pembeli mengubah status pesanan menjadi APPROVED, dan dana baru berpindah setelah backend memanggil endpoint /capture dengan kunci idempotensi PayPal-Request-Id serta mengunci baris PostgreSQL menggunakan select_for_update():
from django.db import transaction
from django.utils import timezone
def finalize_paid_order_atomic(order_uuid: str, gateway_order_id: str, capture_id: str) -> bool:
from core.models import OneDayServiceRequest
with transaction.atomic():
locked = OneDayServiceRequest.objects.select_for_update().get(uuid=order_uuid)
if locked.payment_status == OneDayServiceRequest.PAYMENT_PAID:
return False # Sudah diproses oleh webhook atau SSR sebelumnya
locked.payment_status = OneDayServiceRequest.PAYMENT_PAID
locked.paypal_order_id = gateway_order_id
locked.paypal_capture_id = capture_id
locked.paid_at = timezone.now()
locked.save(update_fields=["payment_status", "paypal_order_id", "paypal_capture_id", "paid_at", "modified_at"])
return True
Jika terjadi race condition di mana proses paralel telah mengeksekusi capture terlebih dahulu (menghasilkan HTTP 422 ORDER_ALREADY_CAPTURED), backend cukup mengambil ulang detail pesanan terbaru, memvalidasi kesesuaian custom_id terhadap UUID transaksi internal agar tidak terjadi substitusi pesanan silang, lalu menyelesaikan status secara aman.
2. Verifikasi Kriptografis Tanda Tangan Webhook & Isolasi Mode Uji Coba
Setiap request masuk ke endpoint webhook wajib memverifikasi kelima header transmisi (TRANSMISSION-ID, TRANSMISSION-TIME, TRANSMISSION-SIG, CERT-URL, dan AUTH-ALGO) sebelum memproses status PAYMENT.CAPTURE.COMPLETED atau PAYMENT.CAPTURE.REFUNDED. Selain itu, pemilihan kredensial Sandbox maupun Live ditentukan sepenuhnya di sisi server berdasarkan daftar akun terverifikasi, bukan dari parameter URL klien.
3. Migrasi Skema Tanpa Waktu Henti (Zero-Downtime) di Cloud Run & Cloud SQL
Penambahan kolom baru dengan atribut NOT NULL DEFAULT '' pada PostgreSQL 11+ hanya memperbarui metadata katalog dalam hitungan milidetik tanpa mengunci tabel, sehingga revisi kontainer lama dan baru di Google Cloud Run tetap berjalan mulus selama proses rolling deployment.
4. Sewa Senior Backend, Cloud, Full Stack & AI Application Engineer
- Panduan Backend Engineer (Python, Django, FastAPI, Golang & PostgreSQL)
- Panduan Cloud Engineer (AWS, GCP, Terraform & FinOps)
- Panduan GCP Professional Cloud Architect & GCP Professional Data Engineer
- Panduan AI Application Engineer & Full Stack Engineer
- Pesan Layanan Pemrograman 1 Hari (Rp 1.000.000 / $100 USD)