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


About the Author — Hire Aldian Fazrihady (Cloud Engineer, GCP Professional Cloud Architect, GCP Professional Data Engineer, Backend, AI & Full Stack Engineer)

Aldian Fazrihady is a Top-Rated Senior Cloud Engineer, GCP Professional Cloud Architect (Google Cloud Certified), GCP Professional Data Engineer (Google Cloud Certified), Backend Engineer (Python, Django, FastAPI, Go, PostgreSQL), AI Application Engineer (LLMs, RAG, MCP, Google ADK, LangGraph), and Full Stack Engineer (React, Next.js, TypeScript) with 15+ years of production software engineering experience.

Hire Aldian Fazrihady on Upwork | Book 1-Day Programming Service ($100 USD / Rp 1.000.000) | View Live AI Portfolio | Send a Direct Message

Related Engineering Articles

Engineering Role Pillar Guides & Category Hubs