# Crypto payment intents

A crypto payment intent creates a temporary collection address for one order or invoice. Relay watches the address, accounts for confirmed funds, and manages the configured post-payment settlement flow.

## Create a crypto payment intent

`POST /payment/create-crypto-Payment-Intent`

Returns HTTP `201 Created` with a [payment object](/docs/reference/payment-object).

### Request fields

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | number | yes | Merchant amount before Relay's quoted crypto fee. Must be positive and fit token precision. |
| `txRef` | string | yes | Your order or invoice reference. This is not an idempotency key. |
| `type` | string | yes | Must be `crypto`. |
| `direction` | string | yes | Use `deposit` for the supported collection flow. |
| `cryptonetwork` | string | yes | Enabled network returned by the active-assets endpoint; currently `tron` or `solana`. |
| `cryptotoken` | string | yes | Enabled token for the selected network, normally `USDT` or `USDC`. |
| `metadata` | object | yes | Your structured data. Keep it small and do not place secrets in it. |
| `useremail` | string | yes | Valid customer email address. |
| `postTransactionType` | string | yes | Choose `external_wallet` or `organization_settlement`. |
| `postTransactionAddress` | string | conditional | Required for `external_wallet`; omit for `organization_settlement`. Maximum 150 characters. |

### Settlement modes

| Value | Destination behavior |
| --- | --- |
| `external_wallet` | You supply `postTransactionAddress` in the request. |
| `organization_settlement` | Relay uses the saved settlement address for the selected token and network. If it has not been configured, creation returns an actionable `400` error. |

The dashboard labels `organization_settlement` as **Settlement address**. Configure
that token and network under Settlement addresses before creating the intent.

```json
{
  "amount": 250,
  "txRef": "invoice-8091",
  "type": "crypto",
  "direction": "deposit",
  "cryptonetwork": "solana",
  "cryptotoken": "USDC",
  "metadata": {
    "invoiceId": "8091",
    "customerId": "cus_7a2"
  },
  "useremail": "finance@example.com",
  "postTransactionType": "organization_settlement"
}
```

```python
import os
import requests

response = requests.post(
    "https://bridge.relayfinance.io/payment/create-crypto-Payment-Intent",
    headers={"accesskey": os.environ["RELAY_ACCESS_KEY"]},
    json={
        "amount": 250,
        "txRef": "invoice-8091",
        "type": "crypto",
        "direction": "deposit",
        "cryptonetwork": "solana",
        "cryptotoken": "USDC",
        "metadata": {"invoiceId": "8091", "customerId": "cus_7a2"},
        "useremail": "finance@example.com",
        "postTransactionType": "organization_settlement",
    },
    timeout=20,
)
response.raise_for_status()
payment = response.json()["data"]
```

### Deposit instructions

For TRON, send `expectedAmount` of `cryptotoken` to `tempWallet[0].address` before `paymentWindowEndsAt` when that field is present.

For Solana SPL tokens, the response also provides:

- `chainIdentity`: the pinned Solana chain identity;
- `tokenContractAddress`: the token mint;
- `tokenStandard`: `SPL`;
- `tokenDecimals`: `6`; and
- `depositTokenAccount`: the associated token account that should receive the SPL transfer.

Intent creation derives the Solana token account but does not create it on-chain. A custom checkout should include idempotent associated-token-account creation when necessary, and should verify that the sending wallet or exchange supports that destination.

## Retrieve a payment intent

`GET /payment/get-payment-intent/{txId}`

| Path field | Type | Description |
| --- | --- | --- |
| `txId` | string | Relay transaction identifier returned when the intent was created. |

```bash
curl --request GET \
  --url https://bridge.relayfinance.io/payment/get-payment-intent/RLY-01J9Y7Y9F4M6 \
  --header 'accesskey: YOUR_ORGANIZATION_API_KEY'
```

A tenant-scoped miss returns HTTP `404` with code `PAYMENT_NOT_FOUND`. Retrieval does not change the payment or renew its collection window.

## List active assets

`GET /payment/get-active-payment-intents-currency`

Returns the payment-intent assets that are active in the current Relay deployment. Each item has:

| Field | Type | Description |
| --- | --- | --- |
| `name` | string | Display name configured by Relay. |
| `network` | string | Network identifier. |
| `token` | string | Asset symbol. |

Asset availability is operational configuration, not a permanent guarantee. Query this endpoint instead of treating the enums in this documentation as an allow-list.

## Funding and settlement

Incoming accounting and outgoing settlement are independent:

- `confirmedAmount` is the eligible confirmed total received;
- `outstandingAmount` is the remaining target;
- `status: successful` means the payment has been funded;
- `settlementStatus` describes the outgoing settlement separately; and
- `status: completed` is a later lifecycle state after Relay's completion workflow.

Use payment webhooks for timely transitions and retrieval for reconciliation. Never mark an order paid based only on HTTP `200` from the lookup endpoint.

## Common errors

| HTTP | Message or code | Cause |
| ---: | --- | --- |
| `400` | `Invalid Amount` or `INVALID_PAYMENT_AMOUNT` | Non-positive amount or invalid token precision |
| `400` | `Invalid Crypto Token` | Inactive or unsupported network/token pair |
| `400` | `External Wallet Address is Required` | Missing destination in external-wallet mode |
| `400` | `Invalid Post Transaction Type` | A destination was supplied for a non-external mode |
| `400` | `Organization wallet not found…` | No managed organization wallet exists for the network |
| `400` | `Solana payment configuration or destination is invalid or unavailable` | Chain, mint, or destination validation failed |
| `404` | `PAYMENT_NOT_FOUND` | The `txId` is absent or belongs to another organization |
