# Stripe

Stripe Express Checkout (wallet) + card-form checkout (select, create-intent, complete)

## GET /v1/stripe/select {#v1stripeselect}

Select a Stripe shield + publishable key from the key's pool

Called by `StripeShield.init` before mounting the wallet/card form. Checks origin via `Origin` when the key has `allowedOrigins` configured.

## POST /v1/stripe/create-intent {#v1stripecreateintent}

Create a Stripe PaymentIntent (deferred intent for wallet or card-form)

Checks origin via `Origin` when the key has `allowedOrigins` configured. `publishable_key` (from `/v1/stripe/select`) routes the request to the correct Stripe account and must be in the same pool as the presented `shield_key` (otherwise returns 403 `PK_POOL_MISMATCH`).

## POST /v1/stripe/complete {#v1stripecomplete}

Confirm a succeeded PaymentIntent and receive a signed envelope

No origin check (enforced via the PaymentIntent's own create-time metadata instead). The signed proof is the PRIMARY completion path (store completes immediately, no webhook wait). Retry policy (SDK): network errors and 502/503/504 with issue ∈ {SIGNING_UNAVAILABLE, SHIELD_REGISTRY_UNAVAILABLE, SHIELD_REGISTRY_STALE} (or no issue) are retried up to 3 times with 1s/3s/9s backoff — every other code is terminal. When retries are exhausted or a terminal error occurs after a confirmed charge, the SDK surfaces `charged_but_unconfirmed`: the buyer was already charged; do not retry or show an error — the order is completed by the AIO `transaction.completed` webhook (matched by `settle_ref`) as the fallback path. A key expired/revoked between create-intent and complete is still authorized if it was active at create-time (post-charge grace period). On success returns a `SignedEnvelope` whose `signed_payload` parses to `StripeCompleteV1Payload`, plus an unsigned `contact` field.

## POST /v1/wallet_beacon {#v1walletbeacon}

Best-effort client-side telemetry (never blocks checkout)

Checks origin via `Origin` when the key has `allowedOrigins` configured. Fire-and-forget from the SDK (`navigator.sendBeacon` or `fetch(..., {keepalive:true})`); errors here are never surfaced to the buyer.

