# Payment API

> Erstellen und verwalten Sie Kryptowährungs-Zahlungssitzungen mit der 2328.io Payment API.

Mit der Payment API können Sie Zahlungssitzungen erstellen, Kunden auf eine gehostete Checkout-Seite weiterleiten und den Zahlungsstatus verfolgen.

## Zahlung erstellen

Erstellt eine Zahlungssitzung und gibt eine URL zurück, unter der der Kunde bezahlen kann.

### Anfrageparameter

| Feld | Typ | Pflicht | Beschreibung | Werte |
|------|-----|---------|--------------|-------|
| `amount` | decimal | ja | Zahlungsbetrag in der Währung, z. B. `100.00` |  |
| `currency` | string | ja | Fiat-Währung (USD, EUR, RUB, …) oder Kryptowährung (USDT, TRX, BTC, …) | `USD`, `EUR`, `RUB`, `KZT`, `UAH`, `UZS`, `USDT`, `USDC`, `BTC`, `ETH`, `GRAM`, `SOL`, `TRX`, `BNB`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `order_id` | string | ja | Ihre Bestell-ID, z. B. `ORDER-12345` (max. 128 Zeichen) |  |
| `to_currency` | string | nein | Vorausgewählte Kryptowährung | `USDT`, `USDC`, `BTC`, `ETH`, `GRAM`, `SOL`, `TRX`, `BNB`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `network` | string | nein\* | Netzwerkcode (erforderlich, wenn `to_currency` gesetzt ist oder `currency` eine Kryptowährung ist) | `TRX-TRC20`, `ETH-ERC20`, `BASE`, `BSC-BEP20`, `AVAX-C`, `POL-MATIC`, `TON`, `SOL`, `BTC`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `url_return` | string | nein | Weiterleitungs-URL nach der Zahlung, z. B. `https://your-site.com/return` |  |
| `url_success` | string | nein | Alternative zu `url_return` |  |
| `url_callback` | string | ja | URL für Webhook-Benachrichtigungen, z. B. `https://your-site.com/webhook` |  |
| `invite_code` | string | nein | Empfehlungscode |  |
| `fee_split` | decimal | nein | Anteil der Händlergebühr, der an den Zahler weitergegeben wird, 0–100 (%). 0 = der Händler trägt sie vollständig, 100 = der Zahler trägt sie vollständig. Überschreibt die Projekteinstellung. **Beispiel: `30`** (der Zahler übernimmt 30 % der Gebühr). |  |
| `price_markup` | decimal | nein | Aufschlag oder Rabatt auf den Rechnungsbetrag, −99 bis 100 (%). Überschreibt die Projekteinstellung. **Beispiel: `5`** (+5 %) oder `-10` (10 % Rabatt). |  |
| `description` | string | nein | Optionale Rechnungsbeschreibung (max. 200 Zeichen). Wird dem Zahler auf der Zahlungsseite angezeigt. **Beispiel: `Premium plan — Order #12345`**. |  |
| `ttl_seconds` | int | nein | Gültigkeitsdauer der Rechnung in Sekunden, von `300` (5 Minuten) bis `86400` (24 Stunden). Nach Ablauf dieser Zeit verfällt die Rechnung und kann nicht mehr bezahlt werden. Standard: `3600` (1 Stunde). **Beispiel: `3600`**. |  |

### Antwort

```json
{
  "state": 0,
  "result": {
    "uuid": "abc123-def456-...",
    "order_id": "ORDER-12345",
    "amount": "100.00",
    "currency": "USD",
    "amount_usd": "100.00",
    "exchange_rate": null,
    "url": "https://2328.io/pay/abc123-def456-...",
    "tg_deeplink": "https://t.me/my2328bot?start=pay_abc123-def456-...",
    "expires_at": "2026-01-11T21:00:00Z",
    "created_at": "2026-01-11T20:00:00Z",
    "payer_currency": "USDT",
    "payer_amount": "100.50",
    "network": "TRX-TRC20",
    "address": "TXYZabc123...",
    "payment_status": "check",
    "txid": null,
    "payment_amount": null,
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
```

- Leiten Sie den Kunden zu `result.url` weiter, um die Zahlung abzuschließen.
- `tg_deeplink` — Telegram-Bot-Deeplink für die Zahlung über die Telegram MiniApp.
- `qr` — Base64-codierter QR-Code (Data-URI) der Einzahlungsadresse. Vorhanden, wenn bereits eine Adresse zugewiesen wurde (wenn `network` zusammen mit `to_currency` gesetzt ist oder wenn `currency` eine Kryptowährung ist); andernfalls `null`.
- `txid`, `payment_amount` — `null`, bis der Kunde bezahlt. Werden ausgefüllt, sobald die Transaktion on-chain erkannt wird. Lauschen Sie auf den Webhook `payment_status: paid`, um den Zeitpunkt zu erfahren.
- `exchange_rate` — `null`, falls eine Umrechnung noch nicht relevant ist (z. B. wenn der Fiat-zu-Krypto-Kurs noch nicht festgesetzt wurde). Wird gefüllt, sobald eine Zahler-Währung gewählt ist.

> Use your project UUID and the endpoint-appropriate API key from the merchant dashboard.

#### Interactive request: `POST /v1/payment`
  - `amount` (decimal, required)
  - `currency` (enum, required): USD,EUR,RUB,KZT,UAH,UZS,USDT,USDC,BTC,ETH,GRAM,SOL,TRX,BNB,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `order_id` (string, required)
  - `to_currency` (enum): USDT,USDC,BTC,ETH,GRAM,SOL,TRX,BNB,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `network` (enum): TRX-TRC20,ETH-ERC20,BASE,BSC-BEP20,AVAX-C,POL-MATIC,TON,SOL,BTC,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `url_return` (string)
  - `url_success` (string)
  - `url_callback` (string, required)
  - `invite_code` (string)
  - `fee_split` (decimal)
  - `price_markup` (decimal)
  - `description` (string)
  - `ttl_seconds` (integer)

## Hosted checkout, H2H und genaue Krypto-Beträge

Dasselbe Endpunkt unterstützt drei verschiedene invoice-Formen. Wählen Sie eine bewusst; mischen Sie nicht deren Mengenbedeutungen.

### Hosted checkout mit Zahlerwahl

Senden Sie `amount`, `currency`, `order_id` und `url_callback`, aber lassen Sie `to_currency` und `network` weg. Die Antwort enthält `result.url`; `address`, `qr` und manchmal Zahlerfelder bleiben `null`, bis der Zahler auf der gehosteten Seite eine Richtung auswählt.

```json
{
  "amount": "125.00",
  "currency": "EUR",
  "order_id": "ORDER-2026-1042",
  "url_callback": "https://merchant.example/webhooks/2328",
  "url_return": "https://merchant.example/orders/ORDER-2026-1042"
}
```

### Direktadresse H2H invoice

Senden Sie sowohl `to_currency` als auch `network`. 2328.io erstellt die Blockchain invoice während API call, sodass eine erfolgreiche Antwort innerhalb Ihres Checkouts gerendert werden kann, ohne den Kunden umzuleiten.

```json
{
  "amount": "100.00",
  "currency": "USD",
  "to_currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "ORDER-2026-1043",
  "url_callback": "https://merchant.example/webhooks/2328"
}
```

Geben Sie diese Werte genau so wieder, wie sie zurückgegeben werden:

- `payer_amount` und `payer_currency` — die Zahlungsanweisung;
- `network` und `address` — das einzige Ziel für dieses invoice;
- `qr` — eine Daten-URI für dieselbe Adresse;
- `expires_at` — die invoice-Frist;
- `url` — ein nützliches gehostetes fallback, wenn der benutzerdefinierte Checkout nicht abgeschlossen werden kann.

> **DANGER:** Generieren oder substituieren Sie niemals eine Adresse, verwenden Sie keine Adresse von einem anderen invoice erneut oder berechnen Sie `payer_amount` aus einem öffentlichen Spotpreis. Die API-Antwort ist maßgeblich.

### Invoice für einen genauen Krypto-Betrag

Setzen Sie die Kryptowährung in `currency`, wenn das invoice selbst in Krypto denominiert ist:

```json
{
  "amount": "25.000000",
  "currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "ORDER-2026-1044",
  "url_callback": "https://merchant.example/webhooks/2328"
}
```

Der angeforderte Krypto-Wert wird in `payer_currency` / `payer_amount` beibehalten. Der Service kann auch eine USD-Bewertung intern für Buchhaltungs- und Kursfelder verwalten; ersetzen Sie die genaue Krypto-Anweisung nicht durch diese Bewertung. Bewahren Sie zurückgegebene Dezimalzeichenfolgen einschließlich nachgestellter Genauigkeit.

Bei einer Kryptowährung mit nur einem unterstützten Netzwerk kann das Netzwerk automatisch ausgewählt werden. Es wird trotzdem empfohlen, `network` explizit anzugeben, um eine deterministische Integration zu gewährleisten. Für Multi-Netzwerk-Assets wie Stablecoins senden Sie sie immer.

## Idempotency und retries

`order_id` ist auf das authentifizierte merchant-Projekt beschränkt und fungiert als Erstellungs-idempotency-Schlüssel. Wenn eine Zahlung bereits existiert, gibt die API diese Sitzung mit `state: 0` zurück.

> **WARNING:** Ein retry mit dem gleichen `order_id` bedeutet **nicht**, „diese invoice aktualisieren“. Geänderte Beträge, Währung, Callback, Aufschlag, TTL oder Richtungsfelder können ignoriert werden, da die bestehende Sitzung zurückgegeben wird. Bewahren Sie die erste Anfrage persistent auf und lehnen Sie widersprüchliche retries in Ihrer eigenen Anwendung ab.

Empfohlener Erstellungsalgorithmus:

1. Fügen Sie Ihren lokalen Zahlungsversuch und eindeutiges `order_id` in einer Datenbanktransaktion ein.
2. Senden Sie die unterzeichnete API-Anfrage.
3. Speichern Sie die zurückgegebene `uuid` und die vollständige Antwort.
4. Wenn das HTTP-Ergebnis verloren geht, retry die identische Anfrage oder fragen Sie `/v1/payment/info` über `order_id` ab.
5. Erstellen Sie niemals eine zweite lokale Bestellung nur weil die Upstream-Anfrage abgelaufen ist.

## Zahlungs-Sonderfälle

| Situation | Korrekte Handhabung |
|-----------|------------------|
| `address` / `qr` ist `null` | Die Zahler-Richtung wurde nicht initialisiert. Leiten Sie zu `url` weiter oder erstellen Sie ein neues korrekt spezifiziertes H2H invoice mit einem neuen `order_id`. |
| HTTP `400` Validierungsfehler | Lesen Sie das Feld-Level-`errors`; ändern Sie die Eingabe nicht retry. |
| HTTP `429` | Retry mit gestaffeltem exponentiellem Backoff und behalten Sie dasselbe `order_id`. |
| HTTP `503` / `direction_disabled` | Aktualisieren Sie `/v1/directions`; verstecken Sie die Richtung vorübergehend oder retry später. |
| Client-Anfrage timeout | Behandeln Sie das Ergebnis als unbekannt. Fragen Sie über `order_id` bevor Sie etwas anderes erstellen. |
| `underpaid_check` | Speichern Sie das partielle Ereignis und warten Sie auf eine Aufladung oder einen späteren Status. Buchen Sie nicht doppelt, wenn weitere txids eintreffen. |
| `underpaid` | Endzustand Unterzahlung. Wenden Sie Ihre konfigurierte Fulfillment-/Manuell-Prüfungs-Policy auf den tatsächlich gutgeschriebenen Betrag an. |
| `overpaid` | Erfolgreiche Zahlung mit überschüssigen Mitteln. Erfüllen Sie idempotent und behalten Sie die tatsächlichen Beträge für reconciliation/Rückerstattungsrichtlinie. |
| `aml_lock` | Erfüllen oder leisten Sie keine Gelder automatisch; leiten Sie sie an den Compliance-/Support-Workflow weiter. |
| `cancel` | Invoice ist abgelaufen oder wurde storniert. Ziehen Sie nicht den Schluss, dass eine verspätete On-Chain-Überweisung unmöglich ist; gleichen Sie jedes spätere Ereignis mit dem Support ab. |

Die Rückkehr-URL des Browsers dient nur der Navigation. Ein Kunde kann sie ohne Zahlung öffnen, nach der Zahlung schließen oder später erneut aufrufen. Nur ein verifizierter API-/webhook-Status kann die merchant-Bestellung abschließen.

## Zahlungsinformationen

Aktuellen Zahlungsstatus per `uuid` oder `order_id` abrufen.

### Anfrageparameter

| Feld | Typ | Pflicht | Beschreibung | Werte |
|------|-----|---------|--------------|-------|
| `uuid` | string | ja\* | Zahlungs-UUID (aus `result.uuid` bei der Erstellung) |  |
| `order_id` | string | ja\* | Ihre Bestell-ID |  |

> **INFO:** Mindestens eines der Felder `uuid` oder `order_id` ist erforderlich.

#### Interactive request: `POST /v1/payment/info`
  - `uuid` (string)
  - `order_id` (string)

## Zahlungsliste

Liste aller Zahlungen mit Filterung und Paginierung abrufen.

### Anfrageparameter

| Feld | Typ | Pflicht | Beschreibung | Werte |
|------|-----|---------|--------------|-------|
| `status` | string | nein | Nach Zahlungsstatus filtern (siehe [References](/docs/references)) | `pending`, `check`, `paid`, `underpaid_check`, `underpaid`, `overpaid`, `cancel` |
| `date_from` | date | nein | Startdatum (YYYY-MM-DD), z. B. `2026-01-01` |  |
| `date_to` | date | nein | Enddatum (YYYY-MM-DD), z. B. `2026-01-31` |  |
| `page` | int | nein | Seitennummer, Standard `1` |  |
| `per_page` | int | nein | Einträge pro Seite, Standard `15`, max. `5000` |  |

#### Interactive request: `POST /v1/payment/list`
  - `status` (enum): pending,check,paid,underpaid_check,underpaid,overpaid,cancel
  - `date_from` (string)
  - `date_to` (string)
  - `page` (integer)
  - `per_page` (integer)