gopay-merchant-qris-gateway: add analysis §10 — gateway-equivalence mapping (initiation / webhook / order-binding emulation)
This commit is contained in:
parent
376a811476
commit
ee2f9a01c5
1 changed files with 20 additions and 0 deletions
|
|
@ -152,3 +152,23 @@ Two buyers paying the same nominal at the same time is the core race condition.
|
|||
- **Feed anomalies** — field report of `getHistory` returning empty for all ranges; maintainer replied it still works (likely account/data scope, not endpoint death). [S14]
|
||||
- **OTP delivery** — an open issue asks why OTP doesn't arrive; consistent with version-gating/format issues rather than a dead flow. [S14]
|
||||
- **Single point of failure** — every design depends on one portal account's session; suspension or forced logout stalls all automation. No repo implements failover to a second account. [inference]
|
||||
|
||||
## 10. Gateway equivalence — why the seller's backend sees a "gateway API"
|
||||
|
||||
The full loop — **buyer pays by QRIS → seller gets an authoritative confirmation → seller proceeds (fulfil, deliver, activate)** — is precisely the loop a commercial payment gateway exists to serve. A licensed PJP gateway (Midtrans, Xendit, DOKU, …) provides it via three services. This stack emulates all three, sourcing each from a non-gateway surface:
|
||||
|
||||
**1. Payment initiation (the "charge" call).**
|
||||
- *Gateway:* `POST /charge` → the provider registers a transaction and returns a pay-handle (QR/VA/redirect) with provider-side TTL.
|
||||
- *Here:* no call and no registration — the handle is **derived offline** from the merchant's own static QR (TLV edit + CRC16). Nothing exists in any provider system until the buyer's app acts on the QR; the 5-minute expiry is local bookkeeping only.
|
||||
|
||||
**2. Status / notification (the webhook).**
|
||||
- *Gateway:* signed push callback to the store, plus a status-query API.
|
||||
- *Here:* **pull instead of push** — the tool polls the merchant's own transaction feed (~6 s) and synthesizes the "order paid" event locally. No webhook can be provisioned because the flow has no gateway product behind it; the notification channel is "the merchant can see their own payments", made machine-readable by session replay.
|
||||
|
||||
**3. Order binding (transaction ↔ order, 1:1).**
|
||||
- *Gateway:* the provider maintains handle ↔ order mapping and guarantees a payment is claimable once.
|
||||
- *Here:* reconstructed locally — amount + time-window matching + a claim registry (`trx_id` scoping / seen-set dedupe), with the unique-nominal (Rp1–99) trick as the practical binding. This is *why* the double-claim problem exists here at all: it is the gap left by the missing provider-side registry.
|
||||
|
||||
**Net effect.** The store-facing contract is gateway-shaped (create QR → poll/wait → receive "paid" → fulfil). Functionally, for the seller's backend, this **is** a payment gateway API. Structurally it is a **merchant-side reconciliation emulator** built from consumer-grade surfaces — which is also why its failure classes (drift, suspension, claims lost on restart, no delivery guarantees) are exactly the guarantees a real gateway product sells. Coverage is the happy path: paid/pending/expired for QRIS/GOPAY payins; refunds, cancellations, disputes, retryable webhooks and reconciliation reports sit outside the emulation (feeds expose refund statuses, but no audited repo drives those workflows).
|
||||
|
||||
[inference throughout — this section maps the audited mechanics onto standard gateway concepts; the per-leg mechanics are sourced in §3–§8.]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue