Skip to main content
Phantom is charged-first merchant of record: the eater pays (or a hold is placed) before submit, and the restaurant is paid out on acceptance. See the payment branches in Agent Onboarding for how to pick a flow.

start_payment

The single checkout entry point: start — and for saved cards, complete — the customer payment before the final submit. Every order is prepaid; there is no post-submit charging path. The branch is chosen from what is supplied: A 3DS challenge on the saved-card branch comes back as requires_action with clientSecret — finish authentication on-session with Stripe.js, which leaves the funds authorized (held). Re-pricing an order. Payments are keyed by external_order_reference, and most clients keep that reference stable across cart edits. Calling start_payment again on the same reference with a new total releases the previous hold and authorizes the new amount — one live hold per reference, never two. A retry at the same amount is idempotent and reuses the original authorization. An already-captured payment is returned untouched (refund it instead of re-starting). The amount is enforced at submit. submit_order rejects an authorization that does not cover the order total with payment_amount_insufficient — a stale hold from a smaller cart cannot carry a larger order. Capture is bounded the other way: when the hold exceeds the order (a cart the eater shrank), only the order total is captured, and the payment record reflects what was actually taken. Input:
Every field except restaurant_id and order is optional, and each is what selects a branch — send only the ones your branch needs. Omit the ones you are not using rather than sending null: these are optional strings, and an explicit null fails schema validation. Output:

void_payment

Release a held authorization (e.g. the order failed to submit). No funds are charged. Input — identify the payment either way:
external_reference is the light form, and the only one available once you no longer hold the order intent. Supplying neither throws. Output: { "ok": true, "status": "canceled", "paymentIntentId": "pi_123" } void_payment works even when the restaurant has since stopped accepting orders — that is usually why the submit failed. Only ownership gates it: you can void a payment your agent owns, nothing else.

get_payment_status

Reconciliation: the current stored payment status for an order’s external reference. Input: { "external_reference": "yourapp-order-1001" } Output:
Ownership: a payment is the agent’s when its linked order is theirs, or — pre-submit, when no order exists yet — when the payment carries their agent stamp in metadata.