Webhooks

Events

The payload of every order event, and when Pulse sends it.

Every event uses the event structure. This page shows the data object for each event type. See Event sequence for the order in which Pulse sends them.

order.awaiting_payment

The order is ready for payment. Use this event to recover from a timed-out create request. It also provides an offramp deposit address that was not ready in the create response.

{
  "id": "0198e2d1-0a44-7f19-8c33-b7e2409d5a18",
  "type": "order.awaiting_payment",
  "environment": "test",
  "created_at": "2026-07-28T10:02:11Z",
  "data": {
    "order_id": "0198e2d0-…",
    "reference": "partner-order-88213",
    "rate": "1538.46",
    "amount": "150000",
    "currency": "NGN",
    "funding_account": {
      "account_name": "Ada Obi",
      "account_number": "9901234567",
      "bank_code": "090175",
      "bank_name": "Rubies MFB",
      "amount": "150000"
    },
    "expires_at": "2026-07-28T10:32:11Z"
  }
}

Only this event contains rate. Pulse fixes it at quote acceptance.

For an offramp, funding_account is { "deposit_address": "0x…", "network": "POLYGON" }. The deposit_address format depends on the network. The currency value identifies the asset to send.

order.payment_received

Pulse received the customer's payment. For an onramp, naira reached the virtual account. For an offramp, crypto reached the deposit address.

{
  "id": "0198e3f8-4c11-7e63-9a07-2d5b81f4c920",
  "type": "order.payment_received",
  "environment": "test",
  "created_at": "2026-07-29T14:33:52Z",
  "data": {
    "order_id": "0198e3f7-…",
    "reference": "partner-order-88301",
    "amount": "200",
    "currency": "USDT",
    "network": "POLYGON"
  }
}

Use the amount received

amount reports the payment received and can differ from the quote. A payment of 190 USDT for a 200 USDT order produces amount: "190". Pulse uses this amount and the effective order rate to calculate the NGN payout.

network appears only for an on-chain payment. An onramp event contains amount and currency without network.

An offramp event also contains the deposit's transaction_hash and the sender's from_address.

From a collection deposit

A deposit to a collection carries the collection reference, not an order reference. It also carries a payout object with the naira amount Pulse pays and the rate it locked for this deposit.

{
  "id": "0199d2c4-5e18-7a90-b3c6-4f1e82d07a51",
  "type": "order.payment_received",
  "environment": "test",
  "created_at": "2026-10-15T10:36:05Z",
  "data": {
    "order_id": "0199d2c3-…",
    "reference": "user-48213",
    "amount": "250",
    "currency": "USDT",
    "network": "POLYGON",
    "transaction_hash": "0x5e1d3c7a9b2f4e6d8a0c1b3e5f7a9d2c4e6b8a0d1f3c5e7a9b2d4f6e8a0c1b3e",
    "from_address": "0x1F2e3D4c5B6a7F8e9D0c1B2a3F4e5D6c7B8a9F0e",
    "payout": { "amount": "391450", "currency": "NGN", "rate": "1565.80" }
  }
}

order.conversion_initiated

Pulse started the conversion. No action is required. Use this event to update the order's progress.

{
  "id": "0198e2f2-6e05-7a88-b410-93cd7e2f6045",
  "type": "order.conversion_initiated",
  "environment": "test",
  "created_at": "2026-07-28T10:05:30Z",
  "data": {
    "order_id": "0198e2d0-…",
    "reference": "partner-order-88213",
    "from": { "currency": "NGN", "amount": "150000" },
    "to": { "currency": "USDT", "network": "POLYGON" }
  }
}

The to object omits amount because conversion is not complete. order.completed reports the delivered amount.

order.payout_initiated

Pulse sent the payout. Settlement awaits confirmation. An onramp sends crypto to the customer's address. An offramp sends naira to the beneficiary's bank account.

{
  "id": "0198e2f3-11ba-7c47-9e82-40d6b5197ce3",
  "type": "order.payout_initiated",
  "environment": "test",
  "created_at": "2026-07-28T10:06:58Z",
  "data": {
    "order_id": "0198e2d0-…",
    "reference": "partner-order-88213",
    "amount": "97.50",
    "currency": "USDT",
    "network": "POLYGON",
    "transaction_hash": "0x7d4f1e83a6c2905b41fd7e3820ac95661b0d8f47e2c31a95604fb8d72e0a1c36"
  }
}

Store the payout identifier with your order. An onramp contains transaction_hash, which you can link to a block explorer. On SOLANA, it is the transaction signature. An offramp contains payout_reference for the bank transfer. Include this reference in a support request about a delayed payout. The two fields never appear together.

order.completed

The payout completed, and the order is final.

{
  "id": "0198e3fb-9d27-7b04-a165-6c80f213ae59",
  "type": "order.completed",
  "environment": "test",
  "created_at": "2026-07-29T14:41:07Z",
  "data": {
    "order_id": "0198e3f7-…",
    "reference": "partner-order-88301",
    "amount": "304600",
    "currency": "NGN",
    "payout_reference": "PLS-8f3a2c91"
  }
}

Use amount to reconcile the payout. It reports the amount delivered. For an offramp, Pulse calculates it from the crypto received and the effective order rate. An onramp event contains network and transaction_hash instead of payout_reference.

order.expired

The funding window closed without payment. No funds moved. Create a new quote and order if the customer wants to continue. You cannot reopen an expired order or reuse its rate.

{
  "id": "0198e30c-15b8-7d93-8e41-77a0c2f6b501",
  "type": "order.expired",
  "environment": "test",
  "created_at": "2026-07-28T10:32:11Z",
  "data": {
    "order_id": "0198e2ff-…",
    "reference": "partner-order-88240",
    "amount": "75000",
    "currency": "NGN"
  }
}

order.expired cannot follow order.payment_received. Pulse does not attribute a payment sent after expiry to this order.

order.failed

The order stopped before completion. Use reason to determine the next action and whether Pulse holds the customer's funds.

{
  "id": "0198e41a-2f66-7b15-9d80-8e37c05a1b44",
  "type": "order.failed",
  "environment": "test",
  "created_at": "2026-07-29T15:02:38Z",
  "data": {
    "order_id": "0198e414-…",
    "reference": "partner-order-88318",
    "reason": "payout_failed"
  }
}
ReasonMeaningWhat to do
payment_rejectedThe incoming payment could not be accepted.No funds are held. Start a new order.
payout_failedPulse received the payment but could not complete the payout.Pulse holds and reconciles the funds. Contact support with the reference. Do not retry.
internal_errorPulse could not complete the order.Contact support with the reference.

An order from a collection deposit fails only with payout_failed or internal_error, because Pulse received the deposit before the order existed.

order.held

A collection deposit arrived, but Pulse could not process it automatically. Pulse holds the funds for review. The order is not terminal.

This is the only event for a held order. Pulse holds the deposit before conversion, so no order.payment_received comes first.

{
  "id": "0199d2d1-7c40-7e25-a8f3-2b6d90e4c172",
  "type": "order.held",
  "environment": "test",
  "created_at": "2026-10-15T10:45:33Z",
  "data": {
    "order_id": "0199d2d0-…",
    "reference": "user-48213",
    "held_reason": "below_minimum",
    "amount": "2.5",
    "currency": "USDC",
    "network": "POLYGON",
    "transaction_hash": "0x2b4d6f8a0c2e4b6d8f0a2c4e6b8d0f2a4c6e8b0d2f4a6c8e0b2d4f6a8c0e2b4d",
    "from_address": "0x9E8d7C6b5A4f3E2d1C0b9A8f7E6d5C4b3A2f1E0d"
  }
}

network and transaction_hash are always present. Both can be empty strings when the deposit arrived on a network Pulse does not support. See Held deposits for each held_reason and what to do.

To trigger this event in the test environment, simulate a deposit below the minimum.

On this page