Payment Flow
The store service owns the shopping cart and the payment checkout session for a booking. A client never calls a single "pay" endpoint — it walks an ordered sequence that resets any stale state, builds a cart, opens a checkout session, flags whether the booking is corporate, and only then executes the payment.
This page documents the order those calls must happen in and what each one is responsible for.
This page currently specifies the call sequence and the branch conditions. Per-operation request/response payloads, per-step error codes, and the transport details are not documented yet — see Still to document. For the errors any call in the sequence can return, see Middleware Errors.
The sequence
Step 3 is not a store-service call — the cart line item is created by the service that owns the product being booked. Everything else in the chain is the store service.
Step by step
| # | Operation | Owner | Why it's here |
|---|---|---|---|
| 1 | clear_shopping_items | Store service | Empties the cart so items left over from an abandoned checkout can't be paid for by accident. |
| 2 | cancel_payment_checkout_session | Store service | Closes any checkout session still open from a previous attempt. Steps 1–2 together are the reset preamble — they make the sequence safe to re-enter. |
| 3 | create shopping_item | Other service | The product service (flight, hotel, …) writes the line item into the now-empty cart. |
| 4 | begin_payment_checkout_session | Store service | Opens a fresh checkout session over the cart's contents. Everything downstream operates on this session. |
| 5 | update_corporate_payment | Store service | Toggles the corporate flag on the session. Defaults to false, so this is only required for corporate bookings — see The corporate branch. |
| 6 | update_booking_note | Store service | Attaches the booking note to the session. |
| 7 | confirm_payment | Store service | Confirms the session and locks it for payment. |
| 8 | pay_with_corporate / pay_with_wallet / … | Store service | Executes the payment against the chosen funding source. |
The corporate branch
update_corporate_payment sets one toggle on the checkout session. A session opened at step 4
starts with enable = false — the call is a switch, not a one-shot, so it can flip the session
between corporate and non-corporate as many times as the user changes their mind before payment.
| State | enable | How it's reached |
|---|---|---|
| Default | false | Set when begin_payment_checkout_session opens the session — no call needed |
| Corporate booking | true | update_corporate_payment with enable = true |
| Switched back off | false | update_corporate_payment with enable = false |
So step 5 is a branch in value, not in control flow — but only the true path actually changes
anything on a fresh session. Step 5b is redundant on a first pass, since false is already the
default. It's worth calling anyway for two reasons:
- The client keeps a single unconditional code path instead of a conditional call.
- It's the call you need when the user turns corporate payment off after having turned it on — the same operation, reused to switch back.
Payment methods
Step 8 picks one terminal operation, one per funding source:
| Operation | Funds from |
|---|---|
pay_with_corporate | Corporate payment (the path enabled at step 5) |
pay_with_wallet | User / company wallet |
pay_with_… | Additional methods follow the same pay_with_* naming |
pay_with_corporate is the natural pair for a session where step 5 set enable = true.
Ordering rules
- Steps 1–2 come before step 3. The cart is cleared first, then filled — reversing them wipes the item that was just created.
- Step 4 comes after step 3. The checkout session is opened over a cart that already holds its items.
- Steps 5–7 all operate on the session opened at step 4. They fail without it.
- Step 5 is repeatable. It's a toggle on the live session, so it can be called more than once to flip the corporate flag before the session is confirmed.
- Step 7 precedes step 8. Payment executes against a confirmed session.
Error reference
Operation-specific errors are documented on the operation's own page under
APIs — so far
pay_with_corporate.
Errors that aren't tied to one step live under Errors:
- Middleware Errors — authentication, authorization, delegation, and OTP failures raised before any call reaches the store service.
- Trip-Related Errors — budget, guest, and traveller validation failures on trip bookings.
Still to document
The following need input from the backend team before this page is a complete API reference:
- Transport and path for each operation.
pay_with_corporateis confirmed as a GraphQL mutation; the rest are presumed to be too, unconfirmed. - Request and response shapes, with a field table per operation.
- Authentication — presumably the standard
Authorizationuser token, unconfirmed. - Error responses per step, and what recovery looks like when a step fails mid-sequence (does the client restart at step 1?).
- The full list of
pay_with_*methods, each of which needs its own page under APIs. - Whether
update_corporate_paymentis still accepted afterconfirm_payment, or whether confirming locks the flag. - Idempotency behaviour — whether re-running the sequence with the same cart is safe.
Once those land, this page should also get matching Bruno requests under
api-tests/backend/store-service/, each carrying a
- Doc: `docs/backend-service/store-service/payment-flow.mdx` line so the results surface in
this page's API & Tests panel.