> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stablegenius.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Intents

> Create, track, and manage stablecoin payments

# Payment Intents

A payment intent represents a customer's intention to pay a specific amount to a merchant. It's the core object in the Stable Genius API — every payment starts with creating one.

## Lifecycle

A payment intent moves through the following statuses:

```mermaid theme={null}
stateDiagram-v2
    [*] --> awaiting_payment: Created
    awaiting_payment --> confirmed: USDC received
    awaiting_payment --> expired: TTL exceeded (5 min)
    awaiting_payment --> cancelled: Cancelled by integrator
    confirmed --> settled: Funds sent to bank
    expired --> [*]
    cancelled --> [*]
    settled --> [*]
```

| Status             | Description                                                                           |
| ------------------ | ------------------------------------------------------------------------------------- |
| `awaiting_payment` | Payment intent created. QR code displayed. Waiting for customer to send USDC.         |
| `confirmed`        | USDC received and confirmed on-chain. Webhook fired. Fees split.                      |
| `expired`          | No payment received within the TTL window (default: 5 minutes).                       |
| `cancelled`        | Integrator cancelled the payment intent before payment was received.                  |
| `settled`          | Funds have been withdrawn from the merchant's on-chain wallet and sent to their bank. |

## Creating a Payment Intent

```bash theme={null}
POST /v1/payment-intents
```

### Required Fields

| Field         | Type     | Description                                              |
| ------------- | -------- | -------------------------------------------------------- |
| `amount`      | `number` | Payment amount in USD. Minimum: $0.01. Maximum: $10,000. |
| `currency`    | `string` | Always `"usd"` for now.                                  |
| `merchant_id` | `string` | The merchant's Stable Genius ID (format: `mer_*`).       |

### Optional Fields

| Field             | Type      | Description                                                                                                                                                                  |
| ----------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata`        | `object`  | Arbitrary key-value pairs attached to the payment intent. Returned in webhooks. Use for order IDs, terminal IDs, customer references, etc. Max 10 keys, 500 chars per value. |
| `ttl`             | `integer` | Time-to-live in seconds before the intent expires. Default: 300 (5 minutes). Min: 60. Max: 3600.                                                                             |
| `idempotency_key` | `string`  | Unique key to prevent duplicate payment intents. If you send the same key within 24 hours, we return the existing intent instead of creating a new one.                      |

## Response Fields

| Field             | Type     | Description                                                     |
| ----------------- | -------- | --------------------------------------------------------------- |
| `id`              | `string` | Unique payment intent ID (format: `pi_*`).                      |
| `status`          | `string` | Current status (see lifecycle above).                           |
| `amount`          | `number` | Payment amount in USD.                                          |
| `payment_address` | `string` | The on-chain address the customer should send USDC to.          |
| `chain`           | `string` | Blockchain network (`base`).                                    |
| `token`           | `string` | Token symbol (`USDC`).                                          |
| `qr_payload`      | `string` | EIP-681 formatted URI for QR code rendering. Wallet-compatible. |
| `qr_image_url`    | `string` | Hosted PNG image of the QR code. 400x400px.                     |
| `expires_at`      | `string` | ISO 8601 timestamp when the intent expires.                     |
| `metadata`        | `object` | Your attached metadata, returned as-is.                         |
| `created_at`      | `string` | ISO 8601 timestamp.                                             |

## Idempotency

Use the `idempotency_key` field to safely retry requests. If a network error occurs and you're unsure whether the payment intent was created, resend the same request with the same idempotency key. We'll return the existing intent if it was already created, or create a new one if it wasn't.

```bash theme={null}
curl -X POST https://api.stablegenius.co/v1/payment-intents \
  -H "Authorization: Bearer sk_test_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4.50,
    "currency": "usd",
    "merchant_id": "mer_abc123",
    "idempotency_key": "order_456_attempt_1"
  }'
```

Idempotency keys expire after 24 hours.

## Expiration

Payment intents expire after the TTL window (default: 5 minutes). If no USDC is received by `expires_at`, the status transitions to `expired` and the payment address is released.

<Warning>
  If a customer sends USDC to an expired payment intent's address, the funds are still received by the merchant's proxy contract and will be recorded as a transaction — but no `payment_intent.confirmed` webhook will fire for that specific intent. Use the `transaction.created` webhook to catch these edge cases.
</Warning>

## Metadata

Attach up to 10 key-value pairs to a payment intent. Metadata is not used by Stable Genius — it's passed through to webhooks so your system can correlate payments with orders, terminals, or customers.

Common metadata patterns:

```json theme={null}
{
  "metadata": {
    "order_id": "order_456",
    "terminal_id": "pos_01",
    "customer_ref": "cust_789",
    "location": "sf_ferry_building"
  }
}
```
