Deposit webhooks

Notifications for a payin, from the moment the transfer is seen on-chain until the amount is available in your balance.

Partial payments

A deposit is marked completed, and payment_detected / payment_confirmed are sent, once received_amount reaches minimum_payment percent of crypto_amount. minimum_payment is set per account; below 100 the customer may have paid less than the invoice. Before delivering, compare data.received_amount with data.crypto_amount (both in data.crypto_currency) and decide what to do with the difference.

payment_detectedPayment detected

The transaction appeared on the network and the payin is completed, but this is not the final status. funds_available is false and finality_status is pending_finality while the block can still be reorganised. If you need to move faster, you may release the product on this notice. The amount is held and is not part of the spendable balance until the network reaches the confirmations required.

Releasing the product at this stage is your decision. A payout of that amount is refused until payment_confirmed.

json
{
  "data": {
    "status": "success",
    "wallet": "0xDeaD0000000000000000000000000000000000a1",
    "network": "BinanceSmartChain",
    "paid_with": [
      {
        "amount": "25.000000000000000000",
        "currency": "USDT"
      }
    ],
    "created_at": "2026-03-01 12:00:00",
    "cross_token": false,
    "fiat_amount": "25.00",
    "network_fee": "0.00000500",
    "confirmed_at": null,
    "percent_rate": "0.50",
    "reference_id": "11111111-1111-4111-8111-111111111111",
    "transactions": "[\"0xabc0000000000000000000000000000000000000000000000000000000000def\"]",
    "confirmations": null,
    "crypto_amount": "25.00000000",
    "customer_info": "customer@example.com",
    "fiat_currency": "USD",
    "is_duplicated": false,
    "crypto_currency": "USDT",
    "finality_status": "pending_finality",
    "funds_available": false,
    "is_wallet_fixed": false,
    "received_amount": "25.00000000",
    "reversal_reason": null,
    "internal_reference": "22222222-2222-4222-8222-222222222222",
    "received_amount_fiat": "25.00",
    "estimated_release_seconds": null,
    "received_amount_fiat_current": "25.00"
  },
  "event": "payment_detected",
  "timestamp": "2026-03-01 12:02:00"
}

payment_confirmedPayment confirmed

The block is final. funds_available is true and the amount is available in your balance. Credit the customer for good on this event.

json
{
  "data": {
    "status": "success",
    "wallet": "0xDeaD0000000000000000000000000000000000a1",
    "network": "BinanceSmartChain",
    "paid_with": [
      {
        "amount": "25.000000000000000000",
        "currency": "USDT"
      }
    ],
    "created_at": "2026-03-01 12:00:00",
    "cross_token": false,
    "fiat_amount": "25.00",
    "network_fee": "0.00000500",
    "confirmed_at": null,
    "percent_rate": "0.50",
    "reference_id": "11111111-1111-4111-8111-111111111111",
    "transactions": "[\"0xabc0000000000000000000000000000000000000000000000000000000000def\"]",
    "confirmations": null,
    "crypto_amount": "25.00000000",
    "customer_info": "customer@example.com",
    "fiat_currency": "USD",
    "is_duplicated": false,
    "crypto_currency": "USDT",
    "finality_status": "final",
    "funds_available": true,
    "is_wallet_fixed": false,
    "received_amount": "25.00000000",
    "reversal_reason": null,
    "internal_reference": "22222222-2222-4222-8222-222222222222",
    "received_amount_fiat": "25.00",
    "estimated_release_seconds": null,
    "received_amount_fiat_current": "25.00"
  },
  "event": "payment_confirmed",
  "timestamp": "2026-03-01 12:03:00"
}

payment_reversedPayment reversed

A reorganisation undid the deposit and the credit was removed. data.status is reversed and reversal_reason says why. From this point check-payin and list-payin also return status reversed, so an integration that polls sees it too. If you already released the product on payment_detected, reconcile that delivery against this notice.

json
{
  "data": {
    "status": "reversed",
    "wallet": "0xDeaD0000000000000000000000000000000000a1",
    "network": "BinanceSmartChain",
    "paid_with": [
      {
        "amount": "25.000000000000000000",
        "currency": "USDT"
      }
    ],
    "created_at": "2026-03-01 12:00:00",
    "cross_token": false,
    "fiat_amount": "25.00",
    "network_fee": "0.00000500",
    "confirmed_at": null,
    "percent_rate": "0.50",
    "reference_id": "11111111-1111-4111-8111-111111111111",
    "transactions": "[\"0xabc0000000000000000000000000000000000000000000000000000000000def\"]",
    "confirmations": null,
    "crypto_amount": "25.00000000",
    "customer_info": "customer@example.com",
    "fiat_currency": "USD",
    "is_duplicated": false,
    "crypto_currency": "USDT",
    "finality_status": "reorged",
    "funds_available": false,
    "is_wallet_fixed": false,
    "received_amount": "25.00000000",
    "reversal_reason": "reorg",
    "internal_reference": "22222222-2222-4222-8222-222222222222",
    "received_amount_fiat": "25.00",
    "estimated_release_seconds": null,
    "received_amount_fiat_current": "25.00"
  },
  "event": "payment_reversed",
  "timestamp": "2026-03-01 12:04:00"
}

When detection is already final

On some networks the payment is final as soon as it is detected. payment_confirmed is then sent right after payment_detected; payment_detected already carries finality_status final, and payment_confirmed may carry finality_status null. Decide from event and funds_available: not every payment_detected holds the amount.

Receipt fields

FieldTypeDescription
funds_availablebooleanfalse while the amount is held. true when it can be withdrawn.
finality_statusstring | nullpending_finality while confirmations are still running, final when the block is settled, reorged when the deposit was undone. Can be null on a payment_confirmed for a payment that was final on detection.
confirmationsnumber | nullReserved for the confirmation count. Currently always null; do not rely on it.
estimated_release_secondsnumber | nullReserved for an estimate of the wait until release. Currently always null; do not rely on it.
reversal_reasonstring | nullWhy the credit was removed. Null on payment_detected and payment_confirmed.
received_amountstringCrypto amount credited on the receipt.
received_amount_fiatstringFiat value of the received amount at the invoice rate.
received_amount_fiat_currentstringFiat value at the rate when the webhook was built. Falls back to the invoice rate if the live price is unavailable.
cross_tokenbooleantrue when the customer paid in a token other than the invoice token.
paid_witharrayTokens actually received on-chain. Each item has currency and amount.
is_wallet_fixedbooleantrue when the deposit landed on a fixed address.
is_duplicatedPayin Only

true when Bifrost created this payin itself, for a payment that did not match an open payin: an extra payment to an address whose payin was already completed, or a payment on a different network from the invoice. It is a new payin with its own internal_reference and a reference_id generated by Bifrost. The amount is credited to your balance, and the notice goes to the webhook_url of the original payin.

When is_duplicated is true, reference_id is not one of yours. Link the payment to your order with customer_info or wallet. The payin is also returned by List Payins and Check Specific Payin.

customer_info

Your own identifier for the customer, such as a user ID, e-mail or order ID. It is returned in webhooks and lists, so you can tell whose transaction it is, including payins Bifrost creates on its own (additional payments and fixed-address deposits), whose reference_id is generated by Bifrost.