Collect Invoice

View as Markdown
Collect payment on an invoice. Called by the Restate workflow handler for: - Initial payment (checkout) - Subscription renewal - Dunning retries Handles invoices in DRAFT, OPEN, or PAST_DUE state. DRAFT invoices are finalized before processor attempt. Requirements: - Invoice must be in DRAFT, OPEN, or PAST_DUE state - Invoice must have a payment method (for payment to be attempted) Headers: - Idempotency-Key: Optional key to prevent duplicate payment attempts Returns (200 OK - Payment Succeeded): - invoice_id: ID of the invoice - invoice_status: "paid" (invoice fully paid) - subscription_id: ID of linked subscription (if any) - payment_status: "paid" or "processing" (ACH/bank transfer pending) - payment_error: null - error_message: null (deprecated, use payment_error) - orchestrator_summary: null Returns (402 Payment Required - Payment Failed): - invoice_id: ID of the invoice - invoice_status: "past_due" or "open" (invoice not paid) - subscription_id: ID of linked subscription (if any) - payment_status: "failed", "requires_action", "no_payment_method", "skipped", "on_session_checkout_invoice", "hard_cap_exceeded", or "subscription_cancelled" The last three answer 402 because nothing was collected: - on_session_checkout_invoice: the invoice was created by a hosted checkout (CIT). Automated retries are never attempted on it; a deliberate call to this endpoint IS attempted, so seeing this status here means the caller was an internal automated path. - hard_cap_exceeded / subscription_cancelled: previously answered 200 with a populated payment_error, which contradicted the guidance below. They are failures — no money moved — and now answer 402. - payment_error: Detailed processor decline reason (e.g., "Insufficient funds", "Card declined") - error_message: Same as payment_error (deprecated, kept for backward compatibility) - orchestrator_summary: High-level summary (e.g., "All payment methods exhausted") - is_dunning: Whether this was a dunning retry attempt - dunning_attempt: Dunning attempt number (0 = first attempt) Returns (200 OK - Collection Deferred, payment_status "au_deferred"): - The card is mid-refresh at the card network's Account Updater, so no charge was attempted, no decline was recorded, and no retry was consumed. Retry shortly. This is NOT a payment — see the warning below. Returns (200 OK - Collection Suppressed, payment_status "duplicate_suppressed"): - An automated caller arrived inside the previous attempt's processor duplicate-submission window, so no charge was submitted, no decline was recorded and no retry was consumed. This is the fingerprint of an at-least-once re-invocation of a collect that already ran; the original run owns the next attempt, so the caller should stop rather than retry. Like "au_deferred", this is NOT a payment — see the warning below. **CRITICAL for one-time product purchases:** Only grant product access/credits when `payment_status` is "paid" or "processing". HTTP 200 alone is not enough: "au_deferred", "too_early", "stale_trigger" and "duplicate_suppressed" all return 200 and all mean no money moved. Never grant access on HTTP 402 (payment failed).

Authentication

AuthorizationBearer

Bearer authentication of the form Bearer <token>, where token is your auth token.

Path parameters

external_idstringRequired
account_idstringRequired

Headers

Idempotency-Keystring or nullOptional
X-Restate-Secret-Keystring or nullOptional
X-System-Reasonstring or nullOptional

Request

This endpoint expects a nullable object.
payment_method_idstring or nullOptional
ID of the payment method to use for payment

Response

Successful Response

Errors

422
Unprocessable Entity Error