# General Information

> Technical specification for cryptocurrency payment processing and withdrawal integration with 2328.io.

Welcome to the 2328.io API documentation. This reference describes how to integrate cryptocurrency payment processing and withdrawals into your application.

## Getting started

To begin integrating:

1. Create a merchant account and project at [2328.io](https://2328.io)
2. Obtain your **project UUID** and **API key** from project settings
3. Generate a separate **Payout API key** if you plan to use withdrawals
4. Read the [Authentication](/docs/authentication) section to learn how to sign requests
5. Make your first [Create Payment](/docs/payments) call

## Base URL

All production API requests use the following base URL:

```
https://api.2328.io/api
```

> **WARNING:** All requests must be made over **HTTPS**. Requests without HTTPS are blocked.

## What you can do

With the 2328.io API you can:

- **Accept crypto payments** — create payment sessions and redirect customers to a hosted checkout or Telegram MiniApp
- **Withdraw funds** — programmatically send payouts from your merchant balance to any blockchain address
- **Check balances** — see merchant account balances per currency, USD equivalents, and AML-locked amounts
- **Use static wallets** — generate permanent deposit addresses tied to a user or order
- **Fetch exchange rates** — get real-time rates for fiat and crypto pairs
- **Receive webhooks** — get notified instantly when a payment status changes

## Rate limits

The API allows up to **10 requests per second per project**. Requests above the limit get an HTTP `429 Too Many Requests` response — back off and retry.

## Choose the right integration pattern

| Requirement | Recommended pattern | Why |
|-------------|---------------------|-----|
| Let the customer choose how to pay | Hosted checkout | Create a payment and redirect to `result.url`; 2328.io presents currently available directions. |
| Keep the customer inside your own checkout | Direct-address **H2H** invoice | Send `to_currency` and `network` when creating the payment; render the returned `address`, `payer_amount`, and `qr`. |
| Charge exactly `25 USDT` or `0.001 BTC` | Crypto-denominated invoice | Put the cryptocurrency in `currency` and the exact decimal amount in `amount`. |
| Give each user a reusable deposit address | Static wallet | The address is permanent and can receive many independent deposits. |
| Normalize incoming assets into one balance currency | Auto-convert | Configure project rules in the dashboard and consume the `convert` result when conversion completes. |
| Exchange an existing merchant balance | Manual convert | Preview with `/v1/convert/price`, then execute with `/v1/convert`. |
| Send funds to a blockchain address | Payout | Use the separate Payout API key, calculate first, and reconcile the payout status. |

> **INFO:** Hosted checkout and H2H are two presentations of the same Payment API. H2H does not create a weaker or unsigned payment: the backend still creates the invoice, 2328.io still owns the address and status, and signed webhooks remain authoritative for settlement.

## Integration invariants

These rules apply to every production integration:

- **Backend only** — keep API keys out of browsers, mobile applications, logs, analytics, and support screenshots.
- **Decimal strings** — send and store money as strings. Never round cryptocurrency or exchange rates with binary floating-point arithmetic.
- **Immutable idempotency keys** — generate `order_id` before the first request and persist the complete request with it. A retry with the same `order_id` can return the original object rather than applying changed fields.
- **Webhook-first settlement** — redirects, client polling, transaction hashes supplied by users, and HTTP timeouts are not proof of payment.
- **Verify, deduplicate, then mutate** — verify the HMAC, claim an idempotency record atomically, update the order/balance once, and return HTTP 200 quickly.
- **Reconciliation** — periodically query payment, static-wallet, and payout status so a lost webhook cannot leave permanent disagreement.
- **Dynamic availability** — validate currency/network pairs with `/v1/directions`; a supported asset can still have one deposit or withdrawal direction temporarily disabled.
- **Explicit status policy** — decide how your product handles partial payment, overpayment, expiry, AML lock, conversion fallback, and ambiguous upstream timeouts before going live.

## Recommended data to persist

For payments, store at minimum `uuid`, `order_id`, the original request body, `amount`, `currency`, `payer_currency`, `payer_amount`, `network`, `address`, `expires_at`, latest `payment_status`, `txid`, `payment_amount`, `merchant_amount`, the optional `convert` block, and the raw verified webhook payload.

For static wallets, keep the wallet `uuid`, address, currency, network, customer/account reference, status, and callback URL separately from deposit records. Each deposit needs its own transaction `uuid`, `txid`, status, received amount, merchant amount, and conversion result.