# crypt.pe Gateway API — Plain-Text Reference

> Machine-readable API documentation for crypt.pe, the non-custodial crypto
> payment gateway with a 0% transaction fee. Full interactive docs:
> https://crypt.pe/docs · Product summary: https://crypt.pe/llms.txt

## Overview

- Base URL: `https://crypt.pe/api`
- Auth: secret API key (`sk_live_…` or `sk_test_…`) as a Bearer token.
- Non-custodial: every payment settles on-chain from the payer's wallet
  directly to the merchant's own wallet. crypt.pe never holds funds.
- Coins: BTC, ETH, SOL, USDT (TRC-20/ERC-20/BSC), USDC (Base/Polygon/Solana),
  BNB, TRX, XRP, LTC, DOGE and more — 24+ assets across 13 chains.
- Fees: 0% per transaction on all plans. Plans are flat subscriptions
  (Free $0, Pro $9/mo, Business $29/mo, Scale $99/mo).

## Create a payment order

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

{
  "amount_usd": 25.00,
  "webhook_url": "https://your-site.com/hooks/cryptpe",   // optional
  "return_url": "https://your-site.com/thanks",           // optional
  "metadata": { "order_ref": "1234" }                     // optional
}
```

Response (201):

```
{
  "order_id": "cp_XXXXXXXXXXXXXXXXXXXXXX",
  "status": "pending",
  "amount_usd": 25.0,
  "accepted_coins": ["btc", "usdt-trc20", "eth", "sol"],
  "checkout_url": "https://crypt.pe/checkout/cp_XXXXXXXXXXXXXXXXXXXXXX",
  "expires_at": "2026-09-02T12:34:56Z"
}
```

Send the payer to `checkout_url`. They pick a coin, get an exact-amount
quote and address/QR, and pay from any wallet. Detection is server-side —
the payer may close the tab; webhooks still fire.

Idempotency: pass an `Idempotency-Key` header to make retries safe.

## Retrieve an order

```
GET /api/v1/payments/{order_id}
Authorization: Bearer sk_live_...
```

Statuses: `pending` → `paid_unconfirmed` → `confirmed` (or `expired`,
`cancelled`, `refunded`, `overpaid`, `underpaid`).

## Verify a transaction hash (rescue path)

If a payer says "I paid" but the order shows pending/expired:

```
POST /api/v1/payments/{order_id}/verify-tx
Authorization: Bearer sk_live_...
{ "tx_hash": "0x… or txid" }
```

Checks the chain directly (any of the order's accepted coins), binds the
payment, updates the order and fires the webhook.

## Sandbox / test mode

Use an `sk_test_…` key. Test orders quote on Sepolia ETH / BTC testnet, or
simulate instantly:

```
POST /api/v1/payments/{order_id}/test-pay
Authorization: Bearer sk_test_...
```

Fires the full webhook + confirmation lifecycle with a simulated tx.

## Webhooks

Events: `payment.detected`, `payment.confirmed`, `payment.expired`,
`refund.created` (JSON POST to your `webhook_url`; 24h retry with backoff).

Every delivery is signed:

```
X-Cryptpe-Signature: t=<unix-ts>,v1=<hex hmac-sha256>
```

Verify by computing HMAC-SHA256 of `"<t>.<raw-body>"` with your webhook
secret (`whsec_…`) and comparing constant-time to `v1`. Always sign the raw
request body, not re-serialized JSON.

Node example:

```js
const crypto = require("crypto");
function verify(rawBody, sigHeader, whsec) {
  const { t, v1 } = Object.fromEntries(sigHeader.split(",").map(p => p.split("=")));
  const expected = crypto.createHmac("sha256", whsec).update(`${t}.${rawBody}`).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
```

## SDKs and plugins

- Node.js SDK, Python SDK
- WooCommerce plugin, Magento plugin, Shopify integration guide
- Drop-in JS payment button: one `<script>` tag for any HTML site
- No-code: payment links (`crypt.pe/yourname`), exact-amount tracked
  invoices with on-chain receipts, printable QR standee

## Refunds

Non-custodial refunds are merchant-initiated: you send funds back from your
wallet; the dashboard refund flow records it against the original payment so
both sides keep a linked on-chain record. `POST /api/v1/payments/{id}/refunds`.

---
Get a free API key: https://crypt.pe/signup · Support: hello@crypt.pe
