# Payments

## Payment lifecycle

created → authorized → captured
       ↘             ↘ refunded / partially_refunded
        → cancelled
        → failed

A sale skips authorization and goes directly to captured in one call.

## Create a payment

POST /v1/payments
Authorization: Bearer sk_live_...
Content-Type: application/json

{
  "amount_minor": 5000,
  "currency": "USD",
  "method": "card",
  "processor": "stripe",
  "customer_id": "01927b3e-...",
  "description": "Pro plan subscription",
  "idempotency_key": "pay_sub_june_2026"
}

amount_minor is always in the currency&#39;s minor unit (cents for USD).

## Capture

Capture an authorized payment:

POST /v1/payments/{id}/capture

## Cancel

Cancel a pending or authorized payment:

POST /v1/payments/{id}/cancel

## Refund

Refund fully or partially:

POST /v1/payments/{id}/refunds
Content-Type: application/json

{
  "amount_minor": 2500,
  "reason": "customer_request",
  "idempotency_key": "refund_order_1234_1"
}

Omit amount_minor to refund the full remaining amount.

## Idempotency

Always pass a unique idempotency_key on POST requests. Replaying the same key within 24 hours returns the cached response — safe to retry on network failures.

## Scopes required

Operation
Scope

Create, capture, cancel, refund
payment:write

Retrieve, list
payment:read