> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mealops.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Payments

> Charged-first payments: start, charge, void, reconcile, and settle — before and after submit.

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](/guides/agent-onboarding#payments) in Agent Onboarding for how to pick a flow.

## start\_payment

Start a customer payment before the final submit. The branch is chosen from what is supplied:

| Supplied                            | Branch                                                            |
| ----------------------------------- | ----------------------------------------------------------------- |
| `customer_id` + `payment_method_id` | `saved_method` — charge a saved card                              |
| `payment_token`                     | `shared_token` — confirm a Stripe-shareable token                 |
| neither                             | `hosted_redirect` — Stripe Checkout, saves the card for next time |

Input:

```json theme={null}
{
  "restaurant_id": "rest_lb_steakhouse",
  "order": {},
  "success_url": "https://yourapp.example/order/success?orderId=abc123",
  "cancel_url": "https://yourapp.example/checkout?cartId=cart_123",
  "customer_id": "cus_123",
  "payment_method_id": "pm_123",
  "payment_token": null
}
```

Output:

```json theme={null}
{
  "ok": true,
  "status": "redirect_required | paid | authorized | requires_action | canceled | pending_external_confirmation | failed",
  "redirectUrl": "https://payments.example/session/abc123",
  "clientSecret": null,
  "branch": "hosted_redirect",
  "paymentReference": "pay_123",
  "totalCents": 6187,
  "currency": "USD",
  "message": "Hosted payment session created.",
  "raw": {}
}
```

## charge\_saved\_card

Charge the eater's saved card (vaulted on the shared MealOps Stripe account) for the order's quote total **before** submitting. Phantom is charged-first merchant of record.

Input: `{ "restaurant_id": "…", "order": {}, "customer_id": "cus_123", "payment_method_id": "pm_123" }`

Output:

```json theme={null}
{
  "ok": true,
  "status": "authorized | paid | requires_action | redirect_required | failed",
  "clientSecret": null,
  "paymentIntentId": "pi_123",
  "declineCode": null,
  "amountCents": 6187,
  "currency": "usd"
}
```

## charge\_payment

Charge the saved card for an **already-submitted** order, then pay out the restaurant.

Input: `{ "order_id": "order_123", "customer_id": "cus_123", "payment_method_id": "pm_123" }`

Output:

```json theme={null}
{
  "ok": true,
  "status": "pending | processing | paid | failed | refunded | partially_refunded",
  "paymentIntentId": "pi_123",
  "amountCents": 6187,
  "currency": "usd",
  "payoutTriggered": true
}
```

## create\_payout

Reconcile fallback: link an order's pre-submit charge and settle it (capture + restaurant payout). This normally runs **automatically** when the restaurant accepts the order. While the order is still pre-acceptance the call defers (`deferred: true`) without capturing.

Input: `{ "order_id": "order_123" }`

Output: `{ "ok": true, "payoutTriggered": false, "paymentStatus": "authorized", "deferred": true }`

## void\_payment

Release a held authorization (e.g. the order failed to submit). No funds are charged.

Input: `{ "restaurant_id": "…", "order": {} }`

Output: `{ "ok": true, "status": "canceled", "paymentIntentId": "pi_123" }`

## get\_payment\_status

Reconciliation: the current stored payment status for an order's external reference.

Input: `{ "external_reference": "yourapp-order-1001" }`

Output:

```json theme={null}
{ "found": true, "status": "authorized", "paymentIntentId": "pi_123", "amountCents": 6187, "declineCode": null }
```

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.
