Read webhook-overview.mdfirst for signature verification, retry policy, and the state machine common to all events.
| Trigger condition | Notes |
|---|---|
toAddress ∈ order address pool | Address was issued for a specific payment link |
fromAddress ∉ PIK master addresses and ∉ PIK order pool | External payer |
| Field | Value |
|---|---|
eventType | CUSTOMER_PAYMENT |
businessRefType | PAYMENT |
direction | IN |
PENDING ──── on-chain confirmed ────► CONFIRMED (balance credited)
│
└──────── reverted ─────────────► FAILED| Status | When | Side effects |
|---|---|---|
PENDING | First on-chain detection of the inbound transfer | Payment link order marked as "transfer detected" |
CONFIRMED | Sufficient confirmations reached | Order matched, balance becomes available after subsequent COLLECT |
FAILED | Transaction reverted or invalidated | No balance change |
status = PENDING{
"event": "transaction.created",
"timestamp": 1738800000000,
"data": {
"fundEventCode": "FE20260206120000001",
"paymentLinkName": "Premium Plan — Monthly",
"businessRefType": "PAYMENT",
"chain": "Ethereum",
"tokenSymbol": "USDC",
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"txHash": "0xabc123def4567890abc123def4567890abc123def4567890abc123def4567890",
"fromAddress": "0x1234567890abcdef1234567890abcdef12345678",
"toAddress": "0xfedcba0987654321fedcba0987654321fedcba09",
"amount": 99.00,
"direction": "IN",
"eventType": "CUSTOMER_PAYMENT",
"status": "PENDING",
"createTimeUtc": "2026-02-06 12:00:00"
}
}status = CONFIRMEDfundEventCode — the order is now fully paid; you may release goods/services.{
"event": "transaction.created",
"timestamp": 1738800180000,
"data": {
"fundEventCode": "FE20260206120000001",
"paymentLinkName": "Premium Plan — Monthly",
"businessRefType": "PAYMENT",
"chain": "Ethereum",
"tokenSymbol": "USDC",
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"txHash": "0xabc123def4567890abc123def4567890abc123def4567890abc123def4567890",
"fromAddress": "0x1234567890abcdef1234567890abcdef12345678",
"toAddress": "0xfedcba0987654321fedcba0987654321fedcba09",
"amount": 99.00,
"direction": "IN",
"eventType": "CUSTOMER_PAYMENT",
"status": "CONFIRMED",
"createTimeUtc": "2026-02-06 12:00:00"
}
}status = FAILED{
"event": "transaction.created",
"timestamp": 1738800240000,
"data": {
"fundEventCode": "FE20260206120000001",
"paymentLinkName": "Premium Plan — Monthly",
"businessRefType": "PAYMENT",
"chain": "Ethereum",
"tokenSymbol": "USDC",
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"txHash": "0xabc123def4567890abc123def4567890abc123def4567890abc123def4567890",
"fromAddress": "0x1234567890abcdef1234567890abcdef12345678",
"toAddress": "0xfedcba0987654321fedcba0987654321fedcba09",
"amount": 99.00,
"direction": "IN",
"eventType": "CUSTOMER_PAYMENT",
"status": "FAILED",
"createTimeUtc": "2026-02-06 12:00:00"
}
}| Field | Notes |
|---|---|
paymentLinkName | Always populated — identifies which payment link the payment belongs to |
toAddress | The per-link order address generated by PIK |
fromAddress | The customer's wallet — useful for KYC/AML records |
amount | Actual amount received on-chain. May differ slightly from the expected price due to network behavior. Verify against the link's expected amount before fulfilling the order |
1. Verify signature (see webhook-overview.md §2).
2. Look up local order by fundEventCode (idempotency key).
3. Switch on status:
PENDING → mark order as "Payment Detected", show "awaiting confirmation"
to the customer, do NOT fulfill yet.
CONFIRMED → fulfill order, send receipt, release goods.
FAILED → mark order as failed, notify customer to retry.
4. Always respond 200 within 5 seconds.CUSTOMER_PAYMENT → CONFIRMED, a separate ORDER_COLLECT_OUT event is fired later when PIK sweeps the order address funds into the merchant's master address. That sweep is when the funds become available for withdrawal.