1. Payment Links
PIK
  • Start
    • Getting Started
  • Authentication
    • Authentication Token
      POST
  • Global Account
    • Contacts
      • Create Contact
      • List Contacts
      • Get Contact
      • Count Contacts
    • Virtual Accounts
      • Create Virtual Account
      • List Virtual Accounts
      • Get Virtual Account
    • Transactions
      • List Transactions
      • Get Transaction
    • Account Balance
      • List Account Balances
      • Get Balance by Currency
    • Payout
      • Create Payout
    • Webhooks
      • Unified Webhook Entry
      • Virtual Account Webhook
      • Deposit Webhook
      • Payout Status Webhook
  • Payment Links
    • Payment Links
      • Create Payment Link
      • Update Payment Link
      • Get Payment Link Detail
      • Get Payment Link List
    • Transactions
      • Get Transaction List
  • Webhook
    • Global Account
      • Deposit Webhook
      • Payout Webhook
      • Virtual Account Webhook
    • Payment Links
      • Overview
      • Order Collect Out Webhook
      • Customer Payment Webhook
      • Customer Refund Webhook
      • Master Recharge Webhook
      • Web3 Direct Payment Webhook
      • Withdraw Out Webhook
  1. Payment Links

Web3 Direct Payment Webhook

Customer pays a payment link by connecting a Web3 wallet in the checkout UI. Funds are transferred directly to the merchant's master address rather than to a per-link order address.
Read webhook-overview.md first for signature verification, retry policy, and the state machine common to all events.

When it fires#

PIK detects an incoming on-chain transfer to a master address, AND the transaction hash matches a pre-recorded payment_transaction row created when the customer initiated checkout. The pre-recorded row is what distinguishes this from a MASTER_RECHARGE.
Trigger conditionNotes
toAddress ∈ PIK master addressesNot an order pool address
fromAddress ∉ PIK order poolExternal payer wallet
txHash matches an open payment-link transactionThis is what classifies the event as a payment vs. a raw recharge

Event identifiers#

FieldValue
eventTypeWEB3_DIRECT_PAYMENT
businessRefTypePAYMENT
directionIN

State machine#

  PENDING ──── on-chain confirmed ────► CONFIRMED  (balance credited)
     │
     └──────── reverted ─────────────► FAILED
StatusWhenSide effects
PENDINGFirst on-chain detection of the inbound transferPayment link order matched; merchant + customer notified by email
CONFIRMEDSufficient confirmations reachedFunds become available in the master balance immediately (no separate collect step required)
FAILEDTransaction reverted or invalidatedNo balance change; order should be marked unpaid

Payload examples#

status = PENDING#

Funds detected on-chain. The system has already cross-referenced the txHash with an open payment link order.
{
  "event": "transaction.created",
  "timestamp": 1738800000000,
  "data": {
    "fundEventCode": "FE20260206120000002",
    "paymentLinkName": "Annual License",
    "businessRefType": "PAYMENT",
    "chain": "Ethereum",
    "tokenSymbol": "USDT",
    "tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "txHash": "0x9988776655443322110099887766554433221100998877665544332211009988",
    "fromAddress": "0xC0ffee1234567890C0ffee1234567890C0ffee12",
    "toAddress": "0xMasterAddressAAAAMasterAddressAAAAMasterAA",
    "amount": 1200.00,
    "direction": "IN",
    "eventType": "WEB3_DIRECT_PAYMENT",
    "status": "PENDING",
    "createTimeUtc": "2026-02-06 12:00:00"
  }
}

status = CONFIRMED#

Same fundEventCode. Funds are now part of the merchant's available master balance.
{
  "event": "transaction.created",
  "timestamp": 1738800180000,
  "data": {
    "fundEventCode": "FE20260206120000002",
    "paymentLinkName": "Annual License",
    "businessRefType": "PAYMENT",
    "chain": "Ethereum",
    "tokenSymbol": "USDT",
    "tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "txHash": "0x9988776655443322110099887766554433221100998877665544332211009988",
    "fromAddress": "0xC0ffee1234567890C0ffee1234567890C0ffee12",
    "toAddress": "0xMasterAddressAAAAMasterAddressAAAAMasterAA",
    "amount": 1200.00,
    "direction": "IN",
    "eventType": "WEB3_DIRECT_PAYMENT",
    "status": "CONFIRMED",
    "createTimeUtc": "2026-02-06 12:00:00"
  }
}

status = FAILED#

{
  "event": "transaction.created",
  "timestamp": 1738800240000,
  "data": {
    "fundEventCode": "FE20260206120000002",
    "paymentLinkName": "Annual License",
    "businessRefType": "PAYMENT",
    "chain": "Ethereum",
    "tokenSymbol": "USDT",
    "tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "txHash": "0x9988776655443322110099887766554433221100998877665544332211009988",
    "fromAddress": "0xC0ffee1234567890C0ffee1234567890C0ffee12",
    "toAddress": "0xMasterAddressAAAAMasterAddressAAAAMasterAA",
    "amount": 1200.00,
    "direction": "IN",
    "eventType": "WEB3_DIRECT_PAYMENT",
    "status": "FAILED",
    "createTimeUtc": "2026-02-06 12:00:00"
  }
}

Field notes specific to this event#

FieldNotes
paymentLinkNameAlways populated — comes from the matched payment link
toAddressThe merchant master address — same address as used for the rest of master-balance operations
amountThe amount recorded against the matched payment link, not necessarily the raw on-chain value if there is a discrepancy worth flagging

How this differs from CUSTOMER_PAYMENT#

CUSTOMER_PAYMENTWEB3_DIRECT_PAYMENT
Destination addressPer-link order addressMerchant master address
Requires a sweep (ORDER_COLLECT_OUT) afterward?YesNo — funds land in master immediately
Typical customer flowManual transfer from any walletWeb3 wallet connect in checkout
For Web3 direct payments you will not receive a follow-up ORDER_COLLECT_OUT event.

Recommended handler logic#

1. Verify signature.
2. Look up local order by fundEventCode (idempotency).
3. Switch on status:
     PENDING   → mark order "Payment Detected" but DO NOT fulfill yet.
     CONFIRMED → fulfill order, send receipt.
     FAILED    → mark order failed.
4. Respond 200 within 5 seconds.
Modified at 2026-05-25 08:36:47
Previous
Master Recharge Webhook
Next
Withdraw Out Webhook
Built with