# Statische Wallets

> Permanente Einzahlungsadressen, die an eine bestimmte Bestellung oder einen Nutzer gebunden sind — ideal für wiederkehrende und langfristige Zahlungen.

Statische Wallets sind permanente Adressen für den Empfang von Kryptowährungs-Zahlungen. Sie sind mit einer bestimmten `order_id` verknüpft und eindeutig durch die Kombination aus `project_id + order_id + currency + network`.

Verwenden Sie statische Wallets für:

- Wiederkehrende Einzahlungen desselben Nutzers
- Langfristige Zahlungsadressen, die im Nutzerprofil angezeigt werden
- Einzahlungs-Workflows mit hohem Volumen, in denen Sie eine stabile Adresse pro Nutzer wünschen

## Statische Wallet erstellen

`POST /v1/static-wallet`

### Anfrageparameter

| Feld | Typ | Pflicht | Beschreibung |
|------|-----|---------|--------------|
| `currency` | string | ja | Kryptowährung (USDT, BTC, ETH usw.) |
| `network` | string | ja | Netzwerkcode |
| `order_id` | string | ja | Ihre Bestell-/Nutzer-ID (max. 255 Zeichen) |
| `label` | string | nein | Wallet-Bezeichnung (max. 255 Zeichen) |
| `url_callback` | string | ja | URL für Webhook-Benachrichtigungen |
| `invite_code` | string | nein | Empfehlungscode |

### Anfragebeispiel

```json
{
  "currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "USER-123",
  "label": "User deposit #123",
  "url_callback": "https://your-site.com/webhook/static"
}
```

### Antwortbeispiel

```json
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "address": "TXYZabc123...",
    "currency": "USDT",
    "network": "TRX-TRC20",
    "label": "User deposit #123",
    "order_id": "USER-123",
    "status": "active",
    "url": "https://go.2328.io/static/019b2265-34d8-7001-a230-8f97de90d481",
    "created_at": "2026-01-20T12:00:00Z",
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
```

## Wallet-Informationen

Statische Wallet anhand von `uuid` oder `address` abrufen.

`POST /v1/static-wallet/info`

### Anfrageparameter

| Feld | Typ | Pflicht | Beschreibung |
|------|-----|---------|--------------|
| `uuid` | string | ja* | UUID der statischen Wallet |
| `address` | string | ja* | Blockchain-Wallet-Adresse |

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

### Antwortbeispiel

```json
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "address": "TXYZabc123...",
    "currency": "USDT",
    "network": "TRX-TRC20",
    "status": "active",
    "total_received": "1250.50",
    "transactions_count": 3,
    "created_at": "2026-01-20T12:00:00Z",
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
```

- `total_received` — Summe aller von dieser Wallet empfangenen Einzahlungen, in `currency`.
- `transactions_count` — Anzahl der bisher empfangenen Einzahlungen.
- `qr` — Base64-codierter QR-Data-URI der Einzahlungsadresse (für statische Wallets stets vorhanden, da die Adresse bei der Erstellung zugewiesen wird).

## Wallet-Liste

`POST /v1/static-wallet/list`

### Anfrageparameter

| Feld | Typ | Pflicht | Beschreibung |
|------|-----|---------|--------------|
| `status` | string | nein | Nach Status filtern (`active`, `inactive`) |
| `currency` | string | nein | Nach Währung filtern |
| `network` | string | nein | Nach Netzwerk filtern |
| `order_id` | string | nein | Nach order_id filtern |
| `page` | int | nein | Seitennummer (Standard: 1) |
| `per_page` | int | nein | Einträge pro Seite (Standard: 20, max.: 100) |

### Antwortbeispiel

```json
{
  "state": 0,
  "result": {
    "items": [
      {
        "uuid": "019b2265-...",
        "address": "TXYZabc123...",
        "currency": "USDT",
        "network": "TRX-TRC20",
        "status": "active",
        "total_received": "1250.50",
        "transactions_count": 3
      }
    ],
    "paginate": {
      "count": 1,
      "current_page": 1,
      "per_page": 20,
      "total": 1,
      "total_pages": 1,
      "has_more": false
    }
  }
}
```

## Wallet aktivieren / deaktivieren

Schalten Sie um, ob eine statische Wallet neue Zahlungen entgegennimmt.

`POST /v1/static-wallet/disable`

`POST /v1/static-wallet/enable`

### Anfrage

Beide Endpoints nehmen einen einzelnen Parameter entgegen:

```json
{
  "uuid": "019b2265-34d8-7001-a230-8f97de90d481"
}
```

### Antwortbeispiel

```json
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "status": "inactive",
    "message": "Static wallet disabled successfully"
  }
}
```

Bei `enable` lautet `status` `"active"` und `message` `"Static wallet enabled successfully"`.

## Wallet-Transaktionen

Liste aller von einer statischen Wallet empfangenen Einzahlungen abrufen.

`POST /v1/static-wallet/transactions`

### Anfrageparameter

| Feld | Typ | Pflicht | Beschreibung |
|------|-----|---------|--------------|
| `uuid` | string | ja | UUID der statischen Wallet |
| `date_from` | date | nein | Startdatum (YYYY-MM-DD) |
| `date_to` | date | nein | Enddatum (YYYY-MM-DD) |
| `page` | int | nein | Seitennummer (Standard: 1) |
| `per_page` | int | nein | Einträge pro Seite (Standard: 15, max.: 5000) |

### Antwortbeispiel

```json
{
  "state": 0,
  "result": {
    "items": [
      {
        "uuid": "abc123-def456-...",
        "order_id": "USER-123",
        "amount": "100.00",
        "currency": "USDT",
        "payment_status": "paid",
        "txid": "0xabc123def456...",
        "fee_amount": "3.00",
        "net_amount": "97.00",
        "created_at": "2026-01-20T15:30:00Z"
      }
    ],
    "paginate": {
      "count": 1,
      "hasPages": true,
      "perPage": 15,
      "page": 1
    }
  }
}
```

- `fee_amount` — Plattformgebühr, die von dieser Einzahlung abgezogen wird, in `currency`.
- `net_amount` — Betrag, der nach Abzug der Gebühr dem Händlerguthaben gutgeschrieben wird.

## Webhooks für statische Wallets

Wenn eine Zahlung auf einer statischen Wallet eingeht, sendet das System einen Webhook an `url_callback`.

> **WARNING:** Das Webhook-Format für statische Wallets unterscheidet sich vom Format regulärer Zahlungs-Webhooks. Insbesondere enthalten Static-Wallet-Webhooks ein Feld `merchant_amount`, das Sie für die Gutschrift verwenden sollten.

### Webhook-payload

```json
{
  "uuid": "a28b293f-5c76-4053-8062-ae9ca4ab784b",
  "order_id": "USER-7666308594",
  "amount": "10.00000000",
  "currency": "USDT",
  "amount_usd": "10.00000000",
  "exchange_rate": "1.00000000",
  "payer_currency": "USDT",
  "payer_amount": "10.00000000",
  "network": "TRX-TRC20",
  "address": "TMU9Tgpchvgbywkbj5SdC8KJS73t5m3M7G",
  "payment_status": "paid",
  "txid": "8369ede26a0da05b1bae154b4bb4072eb2453db30ba86b21831902670929454f",
  "tx_explorer_url": "https://tronscan.org/#/transaction/8369ede26a0da05b1bae154b4bb4072eb2453db30ba86b21831902670929454f",
  "payment_amount": "10.00000000",
  "merchant_amount": "9.920000000000000000",
  "created_at": "2026-05-09T16:13:04+03:00",
  "sign": "dd958d1405febce670a9a196e9141784b9f2a5f39cd6d1832d6f3f68d0de1e10"
}
```

> **INFO:** Static-Wallet-Webhooks enthalten **kein** `url` und kein `expires_at` (da die Adresse permanent ist und keine Sitzung). Sie enthalten jedoch `exchange_rate` und `created_at`.

### Feldreferenz

| Feld | Typ | Beschreibung |
|------|-----|--------------|
| `uuid` | string | Transaktions-(Rechnungs-)UUID dieser Einzahlung |
| `order_id` | string | Die `order_id` Ihrer statischen Wallet |
| `amount` | decimal (8 dp) | Empfangener Krypto-Betrag |
| `currency` | string | Empfangene Krypto (entspricht der `currency` der Wallet) |
| `amount_usd` | decimal (8 dp) | USD-Wert zum Zeitpunkt des Eingangs |
| `exchange_rate` | decimal | Verwendeter Krypto-/USD-Kurs |
| `payer_currency` | string | Bei statischen Wallets identisch mit `currency` |
| `payer_amount` | decimal (8 dp) | Bei statischen Wallets identisch mit `amount` |
| `network` | string | Blockchain-Netzwerk |
| `address` | string | Adresse der statischen Wallet |
| `payment_status` | string | Aktueller Einzahlungsstatus; normalerweise `paid`, AML kann jedoch `aml_lock` erzeugen, das nicht automatisch gutgeschrieben werden darf |
| `txid` | string | Hash der Blockchain-Transaktion |
| `tx_explorer_url` | string \| null | URL der Transaktion im Blockchain-Explorer. `null`, wenn keine `txid` vorhanden ist oder es sich um einen internen P2P-Transfer handelt. |
| `payment_amount` | decimal (8 dp) | Identisch mit `amount` |
| `merchant_amount` | decimal (18 dp) | **Betrag nach Gebührenabzug** — verwenden Sie diesen für die Gutschrift |
| `created_at` | string (ISO 8601) | Zeitpunkt des Eingangs der Einzahlung |
| `sign` | string (hex) | HMAC-SHA256-Signatur des payload |

## Best Practices

- **Eindeutige `order_id`** — Verwenden Sie für jeden Nutzer oder jede Bestellung eine eindeutige `order_id`
- **Idempotenz** — Prüfen Sie `txid` vor der Verarbeitung, um doppelte Gutschriften zu vermeiden
- **Signaturen verifizieren** — Verifizieren Sie IMMER die `sign`-Signatur, bevor Sie Mittel gutschreiben
- **`merchant_amount` verwenden** — Schreiben Sie Nutzern auf Basis von `merchant_amount` gut, nicht auf Basis von `payment_amount`

## Lebenszyklus und idempotency

Ein static wallet ist eine wiederverwendbare Einzahlungsidentität, kein invoice. Er hat keinen erwarteten Betrag und kein Ablaufdatum. Eine Adresse kann im Laufe ihrer Existenz beliebig viele Einzahlungstransaktionen erzeugen.

Die Erstellung ist idempotent für dasselbe merchant Projekt, `order_id`, `currency` und `network`: das vorhandene Wallet wird zurückgegeben. Halten Sie dieses Tupel stabil und bewahren Sie das zurückgegebene Wallet `uuid`; verwenden Sie nicht jedes Mal ein neues `order_id`, wenn derselbe Kunde den Einzahlungsbildschirm öffnet.

Einzahlungs-idempotency ist anders als Wallet-idempotency:

- `order_id` identifiziert die wiederverwendbare Wallet/Kunden-Zuordnung;
- Wallet-`uuid` identifiziert den permanenten Wallet-Eintrag;
- webhook `uuid` identifiziert eine erkannte Einzahlungstransaktion;
- `txid` identifiziert die On-Chain-Übertragung und ist der primäre Deduplication-Schlüssel für die Gutschrift.

Verwenden Sie eine Datenbank-Eindeutigkeitsbeschränkung für die verarbeitete Kette/Netzwerk/txid-Identität und beanspruchen Sie diese in derselben Transaktion, die das interne Kontoguthaben des Kunden gutschreibt.

## Semantik von Aktivieren und Deaktivieren

Das Deaktivieren eines Wallets verhindert, dass die Anwendung es als aktives Einzahlungziel verarbeitet; es löscht jedoch die Adresse oder deren Historie nicht und kann eine vom Benutzer bereits gesendete Blockchain-Übertragung nicht stoppen.

> **DANGER:** Teilen Sie den Nutzern niemals mit, dass an eine inaktive Adresse gesendete Gelder automatisch zurücküberwiesen werden. Blockchain-Übertragungen sind unwiderruflich. Deaktivieren Sie nur, nachdem die Adresse aus Ihrer Benutzeroberfläche entfernt wurde, und halten Sie ein operatives Wiederherstellungsverfahren für verspätete Einzahlungen bereit.

Das erneute Aktivieren bewahrt dieselbe Wallet-Identität und Adresse. Erstellen Sie keinen Ersatz lediglich, um das Label zu ändern; Labels sind keine settlement-Identifikatoren.

## Edge-Cases von Static wallet

| Situation | Korrekte Handhabung |
|-----------|------------------|
| Doppelte Erstellung Anfrage | Akzeptieren Sie das zurückgegebene vorhandene Wallet und prüfen Sie dessen gespeichertes Tupel, anstatt eine neue Adresse zu erwarten. |
| Mehrere Einzahlungen auf eine Adresse | Erstellen Sie für jede Transaktion eine separate lokale Einzahlungszeile `uuid`/`txid`; markieren Sie niemals das Wallet selbst als „bezahlt“. |
| Doppelte webhook | HTTP 200 zurückgeben, nachdem die bereits bestätigte txid gefunden wurde; nie erneut gutschreiben. |
| Bestätigungsverzögerung oder erneute Beobachtung der Chain | Weiterverarbeitung von idempotent und Abgleich von `/v1/static-wallet/transactions`. |
| Einzahlung unter einem auto-convert Mindestbetrag | Erwarten Sie Gutschrift der Quellwährung ohne abgeschlossenen `convert` Block. |
| Auto-convert erfolgreich | Zahlungswerte der Quelle und das Ziel `convert` Ergebnis getrennt speichern. |
| Falsches Token oder falsches Netzwerk | Keine Gutschrift erzeugen. Beweise aufzeichnen und an Support/Recovery eskalieren, da die Wiederherstellbarkeit kette-spezifisch ist. |
| Memo-/Tag-basierte Chain | Alle vom System zurückgegebenen Ziel-Felder anzeigen und validieren; eine Adresse allein kann unzureichend sein, wenn ein Memo erforderlich ist. |
| AML-Sperre | Dem Endnutzer keine Gutschrift erteilen, bis der autoritative Status durch den Compliance-Prozess freigegeben wird. |
| Wallet nach Adressanzeige deaktiviert | Sofort aus der UI entfernen, aber weiterhin operative Warnungen für nachträgliche Transfers überwachen. |

## Reconciliation Modell

Führen Sie regelmäßig einen Job aus, der durch `/v1/static-wallet/transactions` blättert, Einzahlungen nach txid upsertet und deren `merchant_amount`, Status und optionales Konversionsergebnis mit Ihrem internen Hauptbuch vergleicht. Die Webhook Lieferung sollte reconciliation schnell machen, aber reconciliation muss sie vollständig machen.