Webhook Payloads
Complete payload structure for webhook events.
Payload Structure
All webhook payloads follow this structure:
interface WebhookPayload {
/** Unique event ID */
id: string;
/** Event type */
type: WebhookEventType;
/** ISO 8601 timestamp */
timestamp: string;
/** Event-specific data */
data: {
session: CheckoutSession;
order?: Order | null;
txHash?: string | null;
error?: {
code: string;
message: string;
} | null;
};
}
Session Object
Included in all webhook payloads:
interface CheckoutSession {
/** Unique session ID */
id: string;
/** Your merchant ID */
merchantId: string;
/** Payment amount in USDC */
amountUsdc: string;
/** Target blockchain (8453 for Base) */
destinationChainId: number;
/** USDC token address */
destinationToken: string;
/** Wallet receiving the funds */
recipientAddress: string;
/** Session status */
status: 'CREATED' | 'ACTIVE' | 'COMPLETED' | 'EXPIRED' | 'CANCELLED';
/** User's selected payment platform */
selectedPaymentPlatform?: 'venmo' | 'cashapp' | 'revolut' | ... | null;
/** User's selected fiat currency */
selectedFiatCurrency?: string | null;
/** Redirect URL after success */
successUrl?: string | null;
/** Redirect URL on cancel */
cancelUrl?: string | null;
/** Your custom metadata */
metadata?: Record<string, string> | null;
/** Currently active order ID */
activeOrderId?: string | null;
/** Timestamps */
createdAt: string;
updatedAt: string;
/** Merchant details (if included) */
merchant?: {
id: string;
name: string;
displayName?: string | null;
logoUrl?: string | null;
} | null;
}
Order Object
Included when an order exists:
interface Order {
/** Unique order ID */
id: string;
/** Parent session ID */
sessionId: string;
/** Merchant ID */
merchantId: string;
/** Order status */
status: OrderStatus;
/** On-chain intent hash */
intentHash?: string | null;
/** Intent signal transaction */
signalTx?: string | null;
/** Fulfillment transaction */
fulfillTx?: string | null;
/** Payment platform used */
paymentPlatform?: PaymentPlatform | null;
/** Fiat currency */
fiatCurrency?: string | null;
/** USDC amount */
amountUsdc?: string | null;
/** Fiat to USDC conversion rate */
conversionRate?: string | null;
/** Payment recipient (username/email) */
recipient?: string | null;
/** Quote details */
quote?: Quote | null;
/** Order expiration time */
expiresAt?: string | null;
/** Cancellation info */
cancelTx?: string | null;
cancelledAt?: string | null;
cancelReason?: string | null;
/** Error info (for failed orders) */
errorCode?: string | null;
errorMessage?: string | null;
errorDetails?: Record<string, unknown> | null;
failedAt?: string | null;
/** Timestamps */
createdAt: string;
updatedAt: string;
}
Order Status Values
type OrderStatus =
| 'SESSION_CREATED' // Initial state
| 'SIGNAL_SENT' // Intent transaction submitted
| 'SIGNAL_MINED' // Intent confirmed on-chain
| 'PAYMENT_SENT' // User sent fiat payment
| 'PROOF_VERIFIED' // ZK proof verified
| 'PROOF_SUBMITTED' // Proof submitted to chain
| 'FULFILL_SUBMITTED' // Fulfillment tx submitted
| 'FULFILLED' // Payment complete
| 'CANCELLED' // Order cancelled
| 'EXPIRED' // Order expired
| 'FAILED'; // Order failed
Example Complete Payload
{
"id": "evt_1a2b3c4d5e6f",
"type": "order.fulfilled",
"timestamp": "2024-01-15T14:30:00.000Z",
"data": {
"session": {
"id": "sess_abc123def456",
"merchantId": "merch_xyz789",
"amountUsdc": "100.00",
"destinationChainId": 8453,
"destinationToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"recipientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE71",
"status": "COMPLETED",
"selectedPaymentPlatform": "venmo",
"selectedFiatCurrency": "USD",
"successUrl": "https://mystore.com/success",
"cancelUrl": "https://mystore.com/cart",
"metadata": {
"orderId": "order_12345",
"customerId": "cust_67890"
},
"activeOrderId": "ord_qrs456",
"createdAt": "2024-01-15T14:25:00.000Z",
"updatedAt": "2024-01-15T14:30:00.000Z",
"merchant": {
"id": "merch_xyz789",
"name": "my-store",
"displayName": "My Store",
"logoUrl": "https://mystore.com/logo.png"
}
},
"order": {
"id": "ord_qrs456",
"sessionId": "sess_abc123def456",
"merchantId": "merch_xyz789",
"status": "FULFILLED",
"intentHash": "0x1234567890abcdef...",
"signalTx": "0xabcdef1234567890...",
"fulfillTx": "0x0987654321fedcba...",
"paymentPlatform": "venmo",
"fiatCurrency": "USD",
"amountUsdc": "100.00",
"conversionRate": "1.00",
"recipient": "@merchant-venmo",
"expiresAt": "2024-01-15T15:25:00.000Z",
"createdAt": "2024-01-15T14:26:00.000Z",
"updatedAt": "2024-01-15T14:30:00.000Z"
},
"txHash": "0x0987654321fedcba...",
"error": null
}
}
TypeScript Types
Import types from the shared package:
import type {
WebhookPayload,
WebhookEventType,
CheckoutSession,
Order,
OrderStatus,
PaymentPlatform,
} from '@zkp2p-pay/shared';