> ## Documentation Index
> Fetch the complete documentation index at: https://paperplane-justin-winter-s-projects.vercel.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Payments

> How orders get paid — Stripe links and prepaid credit codes, and what the confirmation flow requires.

## Two ways to pay

Every order is an individual transaction. There's no wallet, no balance, no subscription.

### 1. Stripe checkout (cards + Apple Pay)

`POST /v1/orders` in live mode comes back `action_required` with a payment step to complete — which shape depends on the `checkout_ui_mode` you sent (default `"hosted"`; the response echoes back whichever mode produced it).

By default, it returns a `payment_url`. Give it to the human — they approve the card payment on Stripe's hosted page. After it settles, screening, printing, and mailing are automatic.

```json theme={null}
{
  "status": "action_required",
  "checkout_ui_mode": "hosted",
  "payment_url": "https://checkout.stripe.com/...",
  "reason": "The sender must authorize payment before we print.",
  "next": ["Open payment_url to pay..."]
}
```

Pass `checkout_ui_mode: "embedded"` (what paperplane's own `/embed` widget uses, since Stripe's hosted page refuses to render inside an iframe) and it returns a `payment_client_secret` to mount in place with Stripe.js's `initEmbeddedCheckout` instead:

```json theme={null}
{
  "status": "action_required",
  "checkout_ui_mode": "embedded",
  "payment_client_secret": "cs_test_..._secret_...",
  "reason": "The sender must authorize payment before we print.",
  "next": ["Mount payment_client_secret with Stripe.js initEmbeddedCheckout()..."]
}
```

The response is a discriminated union keyed on `checkout_ui_mode`: exactly one of `payment_url` / `payment_client_secret` ever appears, never both, and `checkout_ui_mode` says unambiguously which — a caller never has to guess the mode from which optional field happened to show up.

Either way, this matches the **confirmation step assistant platforms require** before a purchase — the human, not the agent, approves the charge. It's the same pattern on the MCP surface (`checkout_ui_mode` itself is REST/embed-only: an MCP agent has no frame to mount anything in, so it always gets `payment_url`).

### 2. Prepaid credit code

Buy a block of credit once, then pay per-letter by code — no card at checkout every time. See [Credits](/docs/guides/credits).

## Mail class pricing

| Class           | Base (1 pg) | Use for                                          |
| --------------- | ----------- | ------------------------------------------------ |
| `first_class`   | \$1.99      | Routine mail                                     |
| `certified`     | \$12.99     | Proof of mailing + tracking                      |
| `certified_err` | \$14.99     | Court-ready proof of delivery (e-Return Receipt) |
| `priority`      | \$24.99     | Flat-rate, urgent                                |

Extra pages +$0.25, color +$0.50/page, tracking +\$0.99 on first-class. The `/v1/quotes` endpoint returns the exact all-in total before you commit — always price first.

## Confirmation tokens and `credit_code` orders

* On the **agent surface**, every send requires a `confirmation_token` (see [Core concepts](/docs/concepts)).
* On the **web/REST surface**, payment is the gate — sandbox orders skip payment entirely.

<Note>
  A `credit_code` order redeems from the prepaid balance instead of a new card charge. If the code is invalid or has insufficient balance, the order is refused (402) before anything prints.
</Note>

## Refunds

A `refused` or `failed` order releases the payment — for credit-code orders the balance is restored; for card payments the Stripe hold is released. A card refund shows within 5–10 business days.
