Skip to content

Collect deposits

The Quickstart walks the happy path once. This guide is the same flow with the decisions and the failure modes: how to organise wallets, what each status does to your balance, and how to reconcile so a missed webhook never becomes a missed credit.

A wallet is a dedicated deposit address on one chain, derived for your workspace and watched permanently. Your end-user sends funds to it; CowriePay detects the transaction, tracks its confirmations, credits your workspace, then consolidates the funds to custody. You never handle keys or gas; you consume webhooks and read the API.

Deposit lifecycle: funds sent, DEPOSIT_DETECTED, DEPOSIT_CONFIRMED, then DEPOSIT_SWEPT to custody

Wallet strategy: per order, per user, or both

Section titled “Wallet strategy: per order, per user, or both”
  • A wallet per order is the safest attribution: whatever arrives on the address belongs to that order, and external_ref carries your own opaque id for it.
  • A wallet per end-user suits balance-style products (the user tops up whenever they like). Attach wallets to a customer (customer_id at creation) to group them: attribution is first-class and queryable, while balances stay at the workspace level. Catalogue on the Customers reference.
  • Never put personal data in external_ref; it is your opaque id, nothing else.

Addresses are watched for as long as they exist, so a late payment to an old order’s address is still detected and credited; your external_ref mapping is what tells you what it was for.

Every status, its webhook, and what it does to your balance

Section titled “Every status, its webhook, and what it does to your balance”
Status Meaning Webhook Balance effect
DETECTED Seen on-chain, below the confirmation threshold DEPOSIT_DETECTED pending increases
CONFIRMING Accumulating confirmations (none per confirmation) none
CONFIRMED Threshold reached; credit your customer now DEPOSIT_CONFIRMED none yet
SWEPT Consolidated to custody; fee settled DEPOSIT_SWEPT (with the fee breakdown) pending decreases, available increases by the net
FLAGGED Held for compliance review; do not credit DEPOSIT_FLAGGED stays in pending, never credited while held
REJECTED Review concluded against the deposit; funds stay frozen (no event; terminal) removed from pending

Two decisions fall out of this table:

  • Credit your end-customer at CONFIRMED, never at DETECTED (a detected transaction can still disappear in a reorganisation, see On-chain concepts). Read the threshold off the deposit’s required_confirmations.
  • Your spendable balance moves at SWEPT, when the net lands in available and the fee object in the payload gives you gross_amount, fee_amount and net_amount for reconciliation. Between CONFIRMED and SWEPT the funds are safe but sit in pending; if your product pays out immediately after crediting, account for that window.

A FLAGGED deposit is not an error in your integration: hold the credit, surface “under review” to your user if relevant, and contact support if it persists. It resolves either to the normal flow (released) or to REJECTED.

Reconcile with webhooks first, polling second

Section titled “Reconcile with webhooks first, polling second”

Webhooks are the primary feed and they are delivery-guaranteed with retries; the Webhooks guide covers signature verification and the deduplication contract (the delivery id is stable across retries; the deposit id is your business key).

Polling is the safety net, not the integration: GET /v2/transactions/deposits filters by status and pages through history, and each item carries its fee_record (null until swept). A sane reconciliation habit:

nightly (or hourly), per open order:
deposits = GET /v2/transactions/deposits?status=CONFIRMED
for each deposit not yet processed in your system:
process it exactly as the webhook handler would (same code path)

Make the webhook handler and the reconciler share one idempotent processing function, keyed on deposit_id. Processing a deposit twice must be a no-op; that single property absorbs crashes, replays and reconciliation overlaps at once.

  • Small deposits wait. Below the per-asset consolidation minimum, a deposit stays CONFIRMED (credited to pending, your customer creditable) but is not yet swept; it consolidates once the address’s accumulated balance crosses the floor. The floors are in On-chain concepts.
  • The fee is settled at consolidation, not at confirmation. fee_record on the deposit is null until SWEPT; do not reconcile fees before then.
  • One deposit can arrive in several transactions. Each on-chain transaction is its own deposit record with its own lifecycle. If your product expects an exact amount, sum the confirmed deposits on the wallet rather than expecting one record.