> Documentation index: https://docs.sellhidden.com/llms.txt

# Payments

Source: https://docs.sellhidden.com/reference/payments

Take crypto payments for any amount on your own site. Create a payment, send the buyer to its `url` (a payment page Hidden hosts) and deliver when `payment.paid` arrives. The API never returns a deposit address, a coin amount or a QR code. Turn payments on in Developers, Payments first; test payments work before that.

## Endpoints

5 endpoints · [payments:write](https://docs.sellhidden.com/start?scope=payments%3Awrite#scopes) · [payments:read](https://docs.sellhidden.com/start?scope=payments%3Aread#scopes)

Base URL https://api.sellhidden.com/v1 · Authorization: Bearer · 120/min per key · cursor pagination · Idempotency-Key on POST · No test mode

### POST /payments — Create a payment

Call it from your server when the buyer clicks Pay. The answer carries `url`: send the buyer there to pay. Calls from a web page are refused (403 server_only), except with a temporary key from Try it, which always creates test payments. A `reference` that matches an open payment with the same amount returns that payment instead (200, `existing: true`). Scope `payments:write`. Accepts `Idempotency-Key`. Returns 201.

**Body**

| Body | Type | Description |
| --- | --- | --- |
| `amountUsd` (required) | number | At least 1.00 and at most your per-payment limit (never more than 10,000). Rounded to cents. |
| `reference` | string | Your own id, such as an order number: 1 to 64 letters, digits and _ . : @ + / = -. While a payment with it is open, the same amount returns that payment. |
| `description` | string | Up to 120 characters of plain text, shown to the buyer. |
| `returnUrl` | string | Where the page sends the buyer after paying: https, up to 2,048 characters, on one of your payment websites. Test payments may also return to localhost. |
| `cancelUrl` | string | Linked on the page until the buyer pays. The same rules as returnUrl. |
| `buyerEmail` | string | The buyer's email, up to 254 characters. Hidden emails them a receipt once the payment is paid. |
| `expiresInMinutes` | 15..1440 | The time the buyer has to start paying. Default 60. |
| `metadata` | object | Up to 20 keys of letters, digits, _ . or - (40 characters each), with string, number or true/false values of up to 200 characters, and 2 KB of JSON in all. Returned to you, never shown to the buyer. |
| `test` | boolean | Set to true for a test payment: no money moves, and its page offers Mark as paid and Mark as expired. |

```bash
curl -X POST https://api.sellhidden.com/v1/payments \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "amountUsd": 49,
    "reference": "order-1042",
    "description": "Pro plan, 1 month",
    "metadata": {
      "plan": "pro"
    }
  }'
```

Response (201):

```json
{
  "ok": true,
  "payment": {
    "id": "NOVA-7K2Q-9XHD",
    "url": "https://sellhidden.com/order/NOVA-7K2Q-9XHD",
    "status": "pending",
    "test": false,
    "amountUsd": 49,
    "paidUsd": null,
    "shortUsd": 0,
    "overpaidUsd": 0,
    "creditedUsd": null,
    "feeUsd": 0,
    "networkFeeUsd": 0,
    "reference": "order-1042",
    "description": "Pro plan, 1 month",
    "metadata": {
      "plan": "pro"
    },
    "buyerEmail": null,
    "returnUrl": null,
    "cancelUrl": null,
    "coin": null,
    "network": null,
    "underpaid": null,
    "availableAt": null,
    "createdAt": "2026-09-26T09:58:40.000Z",
    "expiresAt": "2026-09-26T10:58:40.000Z",
    "paidAt": null
  }
}
```

### GET /payments — List payments

Newest first. Scope `payments:read`.

**Query parameters**

| Query parameters | Type | Description |
| --- | --- | --- |
| `status` | pending \| underpaid \| paid \| expired \| cancelled | Only this status. pending includes confirming; expired also matches a pending or underpaid payment past its expiresAt. |
| `reference` | string | Only payments with this reference. |
| `test` | true \| false | Only test payments, or only live ones. |
| `since` | ISO date | Created at or after. |
| `until` | ISO date | Created before. |
| `limit` | 1..100 | Page size. Default 25. |
| `cursor` | string | nextCursor from the previous page. |

```bash
curl https://api.sellhidden.com/v1/payments \
  -H "Authorization: Bearer hsk_live_…"
```

Response (200):

```json
{ "ok": true, "payments": [ { "id": "NOVA-7K2Q-9XHD", "url": "https://sellhidden.com/order/NOVA-7K2Q-9XHD", "status": "paid", "test": false, "amountUsd": 49, "paidUsd": 49, "creditedUsd": 49, "reference": "order-1042", … } ], "nextCursor": null, "hasMore": false }
```

### GET /payments/{id} — Get a payment

{id} is the payment's `id` (any case, hyphen optional). If a webhook did not arrive, read the payment here. Scope `payments:read`.

```bash
curl https://api.sellhidden.com/v1/payments/ID \
  -H "Authorization: Bearer hsk_live_…"
```

Response (200):

```json
{ "ok": true, "payment": { "id": "NOVA-7K2Q-9XHD", "status": "paid", "amountUsd": 49, "paidUsd": 49, "creditedUsd": 49, "coin": "USDT", "network": "Tron (TRC20)", "availableAt": "2026-09-28T10:01:12.000Z", "paidAt": "2026-09-26T10:01:12.000Z", … } }
```

### POST /payments/{id}/cancel — Cancel a payment

Cancels a pending payment and sends payment.cancelled. Once the buyer has started paying, it cannot be cancelled while their transfer can still arrive, or after money arrived: 409 payment_started, with `retryAfter` (an ISO time). Accept what arrived instead. Any other state answers 409 not_cancellable. Scope `payments:write`. Accepts `Idempotency-Key`.

**Body**

| Body | Type | Description |
| --- | --- | --- |
| `reason` | string | Private, up to 500 characters. |

```bash
curl -X POST \
  https://api.sellhidden.com/v1/payments/ID/cancel \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
```

Response (200):

```json
{ "ok": true, "payment": { "id": "NOVA-7K2Q-9XHD", "status": "cancelled", … } }
```

### POST /payments/{id}/accept — Accept what arrived

Settles an underpaid or expired payment on the money that arrived: you are credited it, minus any network fee you pay, and payment.paid is sent. Refused with 409 nothing_received, payment_in_flight (a transfer is still confirming; `until` says until when), payment_busy (another action on it is running: retry shortly) or not_underpaid. Scope `payments:write`. Accepts `Idempotency-Key`.

```bash
curl -X POST \
  https://api.sellhidden.com/v1/payments/ID/accept \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Idempotency-Key: $(uuidgen)"
```

Response (200):

```json
{ "ok": true, "creditedUsd": 30, "payment": { "id": "NOVA-7K2Q-9XHD", "status": "paid", "amountUsd": 49, "paidUsd": 30, "shortUsd": 19, "creditedUsd": 30, … } }
```
