# Crypto payments
Source: https://paylinky.vercel.app/docs/crypto

Accept USDT, BTC and more with a dedicated address and network.

# Crypto payments

## List active assets

```bash
curl https://paylinky.vercel.app/api/v1/crypto/assets -H "Authorization: Bearer $PAYLINKY_KEY"
```

```json
[
  { "asset_code": "USDT.TRC20", "name": "Tether (TRON)", "network": "TRC20", "symbol": "USDT" },
  { "asset_code": "BTC", "name": "Bitcoin", "network": "BTC", "symbol": "BTC" }
]
```

Use an `asset_code` from this list — never assume a network is active. Administrators can disable any asset (including Bitcoin) at any time.

## Create a crypto payment

```http
POST https://paylinky.vercel.app/api/v1/crypto/collect
```

| Field | Required | Description |
| - | - | - |
| `amount` | Yes | Amount in USDT (string or number) |
| `currency` | No | `USDT` (default) |
| `asset_code` | Yes | From `/crypto/assets` |
| `customer.email` | Yes | Payer email |
| `customer.firstName` | Yes | Payer first name |
| `customer.lastName` | Yes | Payer last name |
| `reference` | No | Your order reference (idempotent) |
| `country` | No | Payer country code |
| `notify_url` | No | Webhook URL for this payment |

:::warning
`customer.email`, `customer.firstName` and `customer.lastName` are **mandatory**. Never invent them — ask the payer.
:::

:::tabs
```bash cURL
curl -X POST https://paylinky.vercel.app/api/v1/crypto/collect \
  -H "Authorization: Bearer $PAYLINKY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "25",
    "currency": "USDT",
    "asset_code": "USDT.TRC20",
    "reference": "crypto_order_12345",
    "customer": { "email": "payer@example.com", "firstName": "Ada", "lastName": "Lovelace" }
  }'
```
```javascript Node.js
const payment = await plk.cryptoCollect({
  amount: "25", currency: "USDT", asset_code: "USDT.TRC20",
  reference: "crypto_order_12345",
  customer: { email: "payer@example.com", firstName: "Ada", lastName: "Lovelace" },
});
```
```python Python
payment = plk.crypto_collect(amount="25", currency="USDT", asset_code="USDT.TRC20",
    reference="crypto_order_12345",
    customer={"email": "payer@example.com", "firstName": "Ada", "lastName": "Lovelace"})
```
```php PHP
$payment = $plk->cryptoCollect(["amount" => "25", "currency" => "USDT", "asset_code" => "USDT.TRC20",
  "reference" => "crypto_order_12345",
  "customer" => ["email" => "payer@example.com", "firstName" => "Ada", "lastName" => "Lovelace"]]);
```
:::

### Response — `202 Accepted`

```json
{
  "transaction_id": "7a1f…",
  "reference": "PLK-3QW8N5ZK2D",
  "merchant_reference": "crypto_order_12345",
  "status": "pending",
  "payment_method": "crypto",
  "amount": 25,
  "fee_amount": 0.5,
  "credited_amount": 24.5,
  "currency": "USDT",
  "asset_code": "USDT.TRC20",
  "network": "TRC20",
  "address": "T…",
  "memo": null,
  "amount_usdt": 25,
  "credited_amount_usdt": 24.5,
  "fee_amount_usdt": 0.5,
  "customer": { "email": "payer@example.com", "firstName": "Ada", "lastName": "Lovelace" },
  "sandbox": false,
  "expires_at": "2026-01-01T10:15:00.000Z"
}
```

## Address, memo and QR code

Show the `address` (and `memo` when present) and render a QR code in your app. The payer must send on **exactly the returned `network`** — a wrong network can make funds unrecoverable.

## Expiry and confirmation

Addresses are temporary: a crypto payment still `pending` after **15 minutes** (`expires_at`) becomes `expired`. Never reuse an expired address. The payment is complete only after the `payment.completed` webhook (or `status: "success"`).
