Skip to content

Payment flow ​

Reached from the shipping page via "Go to payment". Three options branch off the payment page — and this is where the flow and the API diverge most: one option maps cleanly, one maps to something quite different from what its label suggests, and one has no endpoint at all.

Stages ​

API calls by stage ​

StageActionAPI callAuth
4Payment page loads — which options to showGET /api/v1/mobile/payment/gateways — "gateways for the token's hub"Brand
4Order total to displayThe last syncBag response, or GET /api/v1/mobile/order/:orderId for the order just createdCustomer
4cPay with cardPOST /api/v1/mobile/payment/link/:paymentGatewayId — currency required, plus orderId and email. Returns a payment link, so the card form is the gateway's, not the app'sCustomer
4cGateway needs the shopper enrolled firstGET /api/v1/mobile/payment/gateways/user-info/:paymentGatewayId, then POST /api/v1/mobile/payment/gateways/user/confirm with user_pg_id, phone_number, codeCustomer
4a"Check wallet"No wallet endpoint exists in the mobile API set — see below—
4b"Enter giftcard"No redeem-a-code endpoint exists — the gift-card endpoints go the other way, see below—
5Order placedNo call. The order was already created at purchase stage 3c; confirmation would read it back with GET /api/v1/mobile/order/:orderIdCustomer

payment/link returns a link and takes the orderId, which pins two things down: the order must exist before payment starts, and the card fields are not the app's to design. The flow needs a webview/browser hop and a return path — neither is in the diagram yet, and no callback or webhook endpoint appears in the mobile API set, so on return the app has to re-read the order to learn what happened.

"Wallet" has no endpoint, and the word is overloaded ​

Nothing in the mobile APIs exposes a spendable wallet balance. Three different things in Batch answer to "wallet", and the spec should say which one this button means:

  1. Loyalty points — the closest thing to a balance the API has, via GET /api/v2/brand/mobile/loyalty/points or GET /api/v1/mobile/loyalty/customer. Points are spent through the cart, not here: points on syncBag and on createOrder, with points_source per bag line. If "check wallet" means "see and spend my points", it belongs on the cart screen, and the payment page only shows the remainder.
  2. Apple / Google Wallet passes — an EventBridge-driven integration on the notification side (see the architecture overview), nothing to do with paying.
  3. A crypto wallet section — an optional per-brand storefront feature, unrelated to both of the above and to Batch collectibles.

Reading "check wallet" as points is an inference, not something the API states. It is the only reading with endpoints behind it, which is why it is worth confirming before build.

Gift cards run the opposite direction ​

The gift-card endpoints sell gift cards for points; they do not accept a gift-card code as payment:

EndpointWhat it does
GET /api/v1/brand/mobile/shopify-gift-cardsThe brand's redeemable denominations
POST /api/v1/user/mobile/gift-card/redeemSpends points and issues a Shopify gift card
GET /api/v1/user/mobile/shopify-gift-cardsThe cards this user already holds
POST /api/v1/user/mobile/gift-card/refundDeactivates a card and converts the balance back to points

No order payload accepts a gift-card code — neither syncBag, createOrder nor create-order has a field for one, and discounts[] takes discount codes, which are a different entity. So "enter giftcard" is either a capability the backend does not have yet, or the button is really an entry point to the redeem points for a gift card flow — a different screen with a different meaning. That needs deciding, not designing around.

Paths ​

Wallet Payment Page → Check wallet button → wallet details

Giftcard Payment Page → Enter giftcard button → giftcard entry

Card Payment Page → Pay with card button → card payment

Open questions ​

All three branches currently stop at the point of opening, so the actual payment outcome is undefined across the board.

Per option

  • Wallet — "check wallet" reads as viewing a balance rather than paying. Is the wallet a payment method, or just an informational panel with a separate "pay with wallet" action? Where does the balance come from — top-ups, refunds, referral credit from refer a friend? Note the points ledger does have a manual write: POST /api/v1/mobile/loyalty/create-user-point-transaction takes a reason and exactly one of points_used / points_earned / amount_spend / amount_earned.
  • Giftcard — is this a full payment method or a credit applied against the total? What happens when the giftcard covers only part of the order (fall through to card for the remainder)? Invalid / expired / already-redeemed code paths. As above, none of this exists server-side today.
  • Card — new card entry form, or saved cards plus "add new" like the address step? Fields not specified. The API answers part of this: the gateway hosts the form via payment/link, so the app does not own the fields, and gateways/user-info + user/confirm is the saved-shopper path for gateways that support it.

Across the flow

  • Success path is missing — no order confirmation screen, no order ID, no receipt, no "back to home / view order". The order ID is available (the app created the order), and GET /api/v1/mobile/orders / GET /api/v1/mobile/order/:orderId back an order-history screen whenever one is designed.
  • Failure path is missing — declined card, cancelled payment, network drop mid-payment. Does the user land back on the payment page with the cart intact? Worth noting the order already exists by then, and PUT /api/v1/mobile/order/cancel/:orderId is the only documented way to clear it.
  • Can methods be combined (wallet + card, giftcard + card)? That's a meaningful build decision — partial payment changes the data model, not just the UI. Points are the one thing that already combines this way, because they are applied in the cart before the payable total is struck.
  • Order total isn't shown anywhere in the flow yet — the value comes from syncBag; see the open question in the purchase flow.
  • Back navigation from payment to shipping — allowed, and does it preserve entered details? The server-side cart survives (syncBag persisted it); the form state does not.
  • createOrder accepts isPrepaidOrder. Which of these three options counts as prepaid, and who sets that flag, is unstated.

Batch platform, Shopify app and API documentation