Payment Intents

A payment intent tracks one payment from creation to a terminal state. Mockpay mirrors Stripe's shape and lifecycle. No money moves; every outcome is simulated from test payment method tokens.

Lifecycle

requires_payment_method → requires_confirmation → confirm
  capture_method=automatic → succeeded
  capture_method=manual    → requires_capture → capture → succeeded
any pre-terminal state → cancel → canceled
declined confirm → requires_payment_method (retryable, last_payment_error set)

Endpoints

MethodPathAction
POST/v1/payment_intentsCreate (optionally confirm in the same call)
GET/v1/payment_intentsList, newest first. limit 1–100 (default 10), starting_after cursor, has_more flag
GET/v1/payment_intents/:idRetrieve
POST/v1/payment_intents/:idUpdate. amount, currency, payment_method change only before confirmation; metadata merges (empty string removes a key)
POST/v1/payment_intents/:id/confirmConfirm with a test payment method
POST/v1/payment_intents/:id/captureCapture a requires_capture intent, in full or via amount_to_capture
POST/v1/payment_intents/:id/cancelCancel with optional cancellation_reason: abandoned, duplicate, fraudulent, requested_by_customer

Create parameters

  • amount (required): positive integer in the smallest currency unit, max 99999999.
  • currency (required): three-letter ISO code, stored lowercase.
  • capture_method: automatic (default) or manual.
  • payment_method: test token (pm_...). Attaching moves status to requires_confirmation.
  • confirm: true confirms in the same call; requires payment_method.
  • description, metadata: freeform.

Bodies are JSON or form-encoded.

Test payment methods

TokenOutcome
pm_card_visa, pm_card_mastercard, pm_card_amex, any unreserved pm_ tokenSucceeds
pm_card_chargeDeclined402 card_error / card_declined / generic_decline
pm_card_chargeDeclinedInsufficientFunds402 card_error / card_declined / insufficient_funds

A decline persists last_payment_error on the intent, detaches the payment method, and returns status to requires_payment_method. The intent stays retryable. The 402 body carries the full intent under error.payment_intent.

Errors

The /v1 lane answers errors in the Stripe shape: { "error": { "type", "code", "message" } }. Types: invalid_request_error (400, 401, 404), card_error (402), api_error (500). Unknown resources answer 404 with code: "resource_missing"; cross-account ids are indistinguishable from missing ids.

Example

curl https://api.mockpay.net/v1/payment_intents \
  -u mock_sk_51H8sandbox...: \
  -d amount=2000 \
  -d currency=usd \
  -d payment_method=pm_card_visa \
  -d confirm=true

Responds 200 with "status": "succeeded" and "amount_received": 2000.

Retention

Payment intents expire 365 days after creation. Updates never extend expiry. Platform records (accounts, keys) never expire.