Kasera Threads

sequenceDiagram
    actor B as Buyer
    participant S as Shop backend
    participant K as Kasera
    B->>S: click Beli - POST /api/orders {item_id, case}
    Note over S: price looked up server-side, never taken from the client
    S->>K: POST /v1/transactions (Idempotency-Key: order id)
    K-->>S: payreq id + checkout_url
    S-->>B: checkout_url
    B->>K: redirected to hosted checkout - pays QRIS
    K-->>B: return_url back to the order page (?status=succeeded)
    Note over B,K: a query param proves nothing - the shop backend never learns of the payment (cases 2 and 3 fix this)
    
sequenceDiagram
    actor B as Buyer
    participant S as Shop backend
    participant K as Kasera
    B->>S: click Beli - POST /api/orders {item_id, case}
    S->>K: POST /v1/transactions (Idempotency-Key: order id)
    K-->>S: payreq id + checkout_url
    S-->>B: order page + checkout link
    B->>K: pays QRIS on hosted checkout
    K->>S: POST /webhook - signed payment.paid event
    S->>S: verify HMAC signature (constant-time) - mark order paid
    S-->>K: 200 OK (non-2xx would make Kasera retry)
    B->>S: order page polls GET /api/orders/:id (our backend only, never Kasera)
    S-->>B: status: paid
    
sequenceDiagram
    actor B as Buyer
    participant S as Shop backend
    participant K as Kasera
    B->>S: click Beli - POST /api/orders {item_id, case}
    S->>K: POST /v1/transactions (Idempotency-Key: order id)
    K-->>S: payreq id + checkout_url
    S-->>B: order page + checkout link
    B->>K: pays QRIS on hosted checkout
    loop while pending - each time the order page checks in
        B->>S: GET /api/orders/:id
        S->>K: GET /v1/transactions/:id - paid yet?
        K-->>S: status (pending, then succeeded)
        S-->>B: status
    end