---
title: "Create a TEST-mode Stripe PaymentIntent for the invoice (unauthenticated)"
method: POST
path: "/public/invoices/{token}/payment-intent"
tags: ["Public"]
---

# Create a TEST-mode Stripe PaymentIntent for the invoice (unauthenticated)

`POST /public/invoices/{token}/payment-intent`

## Request

- Base URL: `https://api.medianfi.com/api/v1`
- URL: `https://api.medianfi.com/api/v1/public/invoices/{token}/payment-intent`
- Auth: none required

AR charge rail (Stage 3 — TEST MODE ONLY). UNAUTHENTICATED; rate-limited per-IP and per-token. The request body is EMPTY and ignored: the amount is SERVER-authoritative (outstanding = amount − paid; force-absorb means the payer is charged the principal only), and no caller-supplied field reaches the intent — the idempotency key is a pure function of (token, outstanding), so one pay link yields at most ONE PaymentIntent. (The payer's card receipt is set browser-side at confirm time via Stripe's `receipt_email`.) Returns { clientSecret, publishableKey (TEST), connectedAccountId, amountChargedCents } for Stripe.js; the card is tokenized in-browser and PAN/CVC never reach this API. Marks nothing paid — settlement is the signature-verified Stage-4 webhook. Same uniform-404 token gate as the GET.

## Response `200`

{ clientSecret, publishableKey, connectedAccountId, amountChargedCents }

## Other responses

- `404`: Uniform not-found (same semantics as GET)
- `409`: INVOICE_NOT_PAYABLE — already paid or no outstanding balance
- `422`: STRIPE_ACCOUNT_CANNOT_CHARGE — card rail unavailable (disabled toggle or the connected account cannot charge right now)
- `429`: Rate limited (per-IP or per-token)
- `503`: Card charging is not configured on this deployment

---

[API](https://skmtc.dev/medianfi/apis/median-api.md) · [All operations](https://skmtc.dev/medianfi/apis/median-api/llms.txt) · [OpenAPI document](https://skmtc.dev/medianfi/apis/median-api/revisions/20090ea32b0d?raw)
