diff --git a/api-features/create-requests-query-status.mdx b/api-features/create-requests-query-status.mdx
deleted file mode 100644
index 393239c..0000000
--- a/api-features/create-requests-query-status.mdx
+++ /dev/null
@@ -1,83 +0,0 @@
----
-title: "Create Requests & Query Status"
-description: "Request creation, management, and real-time status monitoring"
----
-
-## Overview
-
-Request creation and status querying form the foundation of Request Network operations, enabling invoice generation and payment tracking throughout the lifecycle.
-
-## Request Creation
-
-
-
- Traditional invoicing workflows
-
-
-
- Direct payment collection
-
-
-
-## How It Works
-
-```mermaid
-graph TD
- A[Create Request] --> B[Generate ID]
- B --> C[Store on IPFS]
- C --> D[Index on Blockchain]
- D --> E[Return Request]
-```
-
-**Process:**
-1. **Create:** Submit request with payee, payer, and amount details
-2. **Store:** Decentralized storage on IPFS
-3. **Index:** Blockchain indexing for discovery
-4. **Track:** Real-time status monitoring
-
-## Request Properties
-
-### Core Information
-- **Payee:** Request creator/recipient
-- **Payer:** Payment sender (optional)
-- **Amount:** Payment amount and currency
-- **Due Date:** Payment deadline
-
-### Payment Configuration
-- **Payment Network:** ERC20, ETH, or custom
-- **Accepted Tokens:** Supported payment currencies
-- **Conversion:** Fiat-denominated crypto payments
-
-## Status Lifecycle
-
-### Request States
-- `created` - Request initialized
-- `pending` - Awaiting payment
-- `paid` - Payment completed
-- `cancelled` - Request cancelled
-
-### Payment States
-- `no_payment` - No payment detected
-- `partially_paid` - Partial payment received
-- `paid` - Full payment completed
-- `overpaid` - Payment exceeds requested amount
-
-## Query Methods
-
-
-
- Get specific request by ID
-
-
-
- Multiple requests in one call
-
-
-
-## Real-time Updates
-
-Combine with [Webhooks & Events](/api-features/webhooks-events) for instant status notifications.
-
-## Implementation Details
-
-See [API Reference - Requests](/api-reference/requests) for complete technical documentation.
\ No newline at end of file
diff --git a/api-features/create-requests.mdx b/api-features/create-requests.mdx
new file mode 100644
index 0000000..8fa54dd
--- /dev/null
+++ b/api-features/create-requests.mdx
@@ -0,0 +1,91 @@
+---
+title: "Create Requests"
+description: "Request creation workflows and configuration for invoices and payment collection"
+---
+
+## Overview
+
+Request creation forms the foundation of Request Network operations, enabling structured payment collection through invoice generation and payment request workflows.
+
+## Request Types
+
+
+
+ Traditional invoicing with payee details
+
+
+
+ Direct payment collection workflows
+
+
+
+## How It Works
+
+```mermaid
+graph TD
+ A[Define Request] --> B[Select Payment Network]
+ B --> C[Configure Properties]
+ C --> D[Store on IPFS]
+ D --> E[Index on Blockchain]
+ E --> F[Generate Request ID]
+```
+
+**Creation Process:**
+1. **Define:** Set payee, payer, amount, and currency details
+2. **Configure:** Choose payment network and accepted tokens
+3. **Store:** Decentralized storage on IPFS
+4. **Index:** Blockchain indexing for discovery
+5. **Track:** Real-time status monitoring
+
+## Request Properties
+
+### Core Information
+- **Payee:** Request creator/recipient address
+- **Payer:** Payment sender address (optional)
+- **Amount:** Payment amount and currency
+- **Due Date:** Payment deadline (optional)
+
+### Payment Configuration
+- **Payment Network:** ERC20, ETH, or specialized networks
+- **Accepted Tokens:** Supported payment currencies
+- **Conversion Settings:** Fiat-denominated crypto payments
+
+## Payment Network Selection
+
+
+
+ USDC, USDT, DAI token payments
+
+
+
+ ETH, MATIC, BNB direct payments
+
+
+
+### Supported Networks
+- **Mainnet:** Ethereum, Polygon, Arbitrum, Optimism
+- **Sidechains:** BSC, Gnosis, Fantom, Avalanche
+- **Testnets:** Sepolia, Mumbai for development
+
+## Content Data
+
+Attach additional information to requests:
+- **Invoice Details:** Line items, tax information
+- **Business Information:** Company details, terms
+- **Custom Metadata:** Application-specific data
+
+## Used In
+
+
+
+ Business invoice generation
+
+
+
+ Employee payment requests
+
+
+
+## Implementation Details
+
+See [API Reference - Create Requests](/api-reference/endpoints/create-request) for complete technical documentation.
\ No newline at end of file
diff --git a/api-features/query-requests.mdx b/api-features/query-requests.mdx
new file mode 100644
index 0000000..8068890
--- /dev/null
+++ b/api-features/query-requests.mdx
@@ -0,0 +1,101 @@
+---
+title: "Query Requests"
+description: "Request status monitoring, lifecycle management, and information retrieval"
+---
+
+## Overview
+
+Query requests provides comprehensive request status monitoring and information retrieval, enabling real-time tracking of payment requests throughout their lifecycle.
+
+## Request Status Lifecycle
+
+
+
+ Created, pending, partially paid
+
+
+
+ Paid, cancelled, expired
+
+
+
+## How It Works
+
+```mermaid
+graph LR
+ A[Request ID] --> B[Query Status]
+ B --> C[Retrieve Info]
+ C --> D[Check Payments]
+ D --> E[Update Status]
+```
+
+**Query Process:**
+1. **Identify:** Use request ID for lookup
+2. **Retrieve:** Get current request information
+3. **Analyze:** Check payment status and history
+4. **Update:** Reflect latest blockchain state
+
+## Status Types
+
+### Request States
+- `created` - Request initialized and stored
+- `pending` - Awaiting payment completion
+- `paid` - Full payment received and confirmed
+- `cancelled` - Request cancelled by creator
+- `expired` - Past due date without payment
+
+### Payment States
+- `no_payment` - No payment transactions detected
+- `partially_paid` - Partial payment received
+- `paid` - Full payment amount received
+- `overpaid` - Payment exceeds requested amount
+
+## Query Methods
+
+
+
+ Detailed status for specific request
+
+
+
+ Multiple request status in one call
+
+
+
+### Information Retrieved
+- **Basic Details:** Amount, currency, participants
+- **Payment History:** Transaction details and confirmations
+- **Status Timeline:** Creation, updates, completion dates
+- **Network Data:** Blockchain and transaction information
+
+## Real-time Monitoring
+
+### Automatic Updates
+Combine with [Payment Detection](/api-features/payment-detection) for automatic status updates
+
+### Event Integration
+Use [Webhooks & Events](/api-features/webhooks-events) for instant notifications
+
+## Advanced Filtering
+
+Filter requests by:
+- **Date Range:** Creation or due date periods
+- **Status:** Current request or payment state
+- **Participants:** Payee or payer addresses
+- **Amount Range:** Minimum and maximum values
+
+## Used In
+
+
+
+ Real-time payment tracking
+
+
+
+ Invoice status reconciliation
+
+
+
+## Implementation Details
+
+See [API Reference - Query Requests](/api-reference/endpoints/get-request) for complete technical documentation.
\ No newline at end of file
diff --git a/api-features/webhooks-events.mdx b/api-features/webhooks-events.mdx
index 7d518b8..af86100 100644
--- a/api-features/webhooks-events.mdx
+++ b/api-features/webhooks-events.mdx
@@ -5,17 +5,33 @@ description: "Real-time notifications for payment lifecycle events and request s
## Overview
-Webhooks provide real-time notifications when payment and request events occur, enabling immediate response to status changes without polling.
+Webhooks provide real-time notifications when payment and request events occur, enabling immediate response to status changes without constant polling.
-## Supported Events
+## Event Categories
- Payment detected, confirmed, failed
+ **Core events:** confirmed, partial, failed, refunded
+
+ Immediate notification when payments are processed or fail
+
+
+
+ **Crypto-to-fiat:** payment.processing with detailed subStatus
+
+ Track multi-step fiat conversion progress
-
+
- Request created, updated, cancelled
+ **Recurring:** request.recurring
+
+ Automatic subscription renewal generation
+
+
+
+ **KYC & verification:** compliance.updated, payment_detail.updated
+
+ User verification and bank account status changes
@@ -23,58 +39,58 @@ Webhooks provide real-time notifications when payment and request events occur,
```mermaid
graph LR
- A[Event Occurs] --> B[Webhook Triggered]
- B --> C[HTTP POST]
- C --> D[Your Endpoint]
- D --> E[Process Event]
+ A[Event Occurs] --> B[HMAC Signed POST]
+ B --> C[Your Endpoint]
+ C --> D[Verify & Process]
+ D --> E[Return 200 OK]
```
-**Flow:**
-1. **Event:** Payment or request status changes
-2. **Trigger:** Automatic webhook activation
-3. **Delivery:** HTTP POST to your endpoint
-4. **Process:** Handle event in your application
+**Process:**
+1. **Event occurs:** Payment confirmed, request created, compliance updated
+2. **Secure delivery:** HMAC SHA-256 signed POST to your configured endpoint
+3. **Your processing:** Verify `x-request-network-signature`, update application state
+4. **Reliable delivery:** 3 retries (1s, 5s, 15s delays) with 5-second timeout
-## Event Types
+## Key Features
-### Payment Events
-- `payment.detected` - Payment transaction found
-- `payment.confirmed` - Payment confirmed on blockchain
-- `payment.failed` - Payment transaction failed
+### Reliability
+- **Idempotency support:** Use `x-request-network-delivery` header for duplicate detection
+- **Delivery confirmation:** Monitor `x-request-network-retry-count` header to track attempts
-### Request Events
-- `request.created` - New request created
-- `request.updated` - Request information changed
-- `request.cancelled` - Request cancelled by creator
+### Security
+- **HMAC SHA-256 signatures:** Every webhook includes `x-request-network-signature` header
+- **HTTPS required:** Production endpoints must use secure connections
+- **Test webhook identification:** `x-request-network-test` header for development
-## Webhook Configuration
+### Development Tools
+- **Portal testing:** Send test webhooks from [Request Portal](https://portal.request.network)
+- **ngrok integration:** Receive webhooks locally during development
+- **Comprehensive logging:** Request API logs all delivery failures with attempt details
-### Endpoint Requirements
-- **HTTPS Only:** Secure webhook endpoints required
-- **Response Codes:** Return 200-299 for successful processing
-- **Timeout:** Respond within 30 seconds
+## Common Use Cases
-### Retry Logic
-- **Automatic Retries:** Failed deliveries retried with backoff
-- **Maximum Attempts:** Up to 5 retry attempts
-- **Retry Schedule:** 1min, 5min, 25min, 2hr, 12hr
+- **Invoice systems:** Automatically mark invoices as paid when `payment.confirmed` received
+- **Order fulfillment:** Release goods or services immediately after payment confirmation
+- **Subscription management:** Handle `request.recurring` for automatic billing renewals
+- **Compliance workflows:** Update user permissions when `compliance.updated` shows KYC approval
+- **Real-time dashboards:** Display live payment status using `payment.processing` subStatus values
-## Security Features
+## Implementation
-
- HMAC signatures for authenticity
-
-
-
- Restrict webhook sources
+
+ Complete technical documentation with setup, payloads, and code examples
-
-
-## Implementation Examples
-See EasyInvoice webhook handling for real-world integration patterns.
+
+ Working webhook implementation example with Express.js
+
-## Implementation Details
+
+ Configure webhooks and test delivery
+
-See [API Reference - Webhooks](/api-reference/webhooks) for complete technical documentation.
\ No newline at end of file
+
+ Explore payment transactions and request details
+
+
\ No newline at end of file
diff --git a/api-reference/webhooks.mdx b/api-reference/webhooks.mdx
index 35c5c68..428edca 100644
--- a/api-reference/webhooks.mdx
+++ b/api-reference/webhooks.mdx
@@ -1,521 +1,424 @@
---
title: "Webhooks"
-description: "Real-time event notifications and webhook configuration guide"
+description: "Complete webhook implementation guide with event types, security, and retry configuration"
---
-## Webhook Overview
+## Overview
-Webhooks provide real-time notifications when events occur in your Request Network integration. Instead of polling for updates, webhooks push event data to your application immediately when payments are detected, requests are created, or other significant events happen.
+Webhooks deliver real-time notifications when payment and request events occur. Configure your endpoints to receive HMAC-signed POST requests with automatic retry logic and comprehensive event data.
-## Webhook Events
+## Webhook Configuration
+
+### Setup in Portal
+1. Navigate to **Platform Settings → Webhooks** in [Request Portal](https://portal.request.network)
+2. Click **Add webhook**
+3. In the dialog that opens, enter URL and click **Create webhook**
+4. Click copy button to copy **Signing Secret** to clipboard (see [Authentication](/api-reference/authentication) for API key setup)
+5. Enable/disable or delete webhooks as needed
+
+### Local Development
+Use [ngrok](https://ngrok.com/docs/traffic-policy/getting-started/agent-endpoints/cli) to receive webhooks locally:
+```bash
+ngrok http 3000
+# Use the HTTPS URL (e.g., https://abc123.ngrok.io/webhook) in Portal
+```
+
+## Event Types
+
+
+See [Payload Examples](#payload-examples) below for detailed webhook structures.
+
### Payment Events
-
-
- **When:** Payment transaction is detected on blockchain
-
- **Use Cases:**
- - Show "Payment Pending" status to users
- - Start order preparation
- - Send confirmation emails
-
- **Typical Timing:** Within 1-5 seconds of transaction
-
-
-
- **When:** Payment is confirmed on blockchain (sufficient confirmations)
-
- **Use Cases:**
- - Complete order fulfillment
- - Update accounting systems
- - Release digital goods
-
- **Typical Timing:** 1-15 minutes after payment
-
-
+| Event | Description | Context | Primary Use |
+|-------|-------------|---------|-------------|
+| `payment.confirmed` | Payment fully completed and settled | After blockchain confirmation | Complete fulfillment, release goods |
+| `payment.partial` | Partial payment received for request | Installments, partial orders | Update balance, allow additional payments |
+| `payment.failed` | Payment execution failed | Recurring payments, cross-chain transfers | Notify failure, retry logic, pause subscriptions |
+| `payment.refunded` | Payment has been refunded to payer | Cross-chain payment failures, refund scenarios | Update order status, notify customer |
-
-
- **When:** Payment transaction fails or is reverted
-
- **Use Cases:**
- - Notify customer of payment failure
- - Reset order status
- - Trigger retry workflows
-
- **Triggers:** Failed transactions, insufficient gas, reverted smart contract calls
-
-
-
- **When:** Partial payment is received for a request
-
- **Use Cases:**
- - Update outstanding balance
- - Notify of partial payment
- - Allow additional payments
-
- **Common Scenarios:** Installment payments, partial order fulfillment
-
-
+### Processing Events
+
+| Event | Description | Context | Primary Use |
+|-------|-------------|---------|-------------|
+| `payment.processing` | Crypto-to-fiat payment in progress | **subStatus values:** initiated, pending_internal_assessment, ongoing_checks, sending_fiat, fiat_sent, bounced | Track crypto-to-fiat payment status, update UI |
### Request Events
-
-
- **When:** New payment request is created
-
- **Payload Includes:**
- - Request ID and details
- - Payment information
- - Custom metadata
-
- **Use Cases:** CRM integration, analytics tracking
-
-
-
- **When:** Request metadata or status is modified
-
- **Payload Includes:**
- - Updated fields
- - Previous values
- - Change timestamp
-
- **Use Cases:** Audit trails, status synchronization
-
-
+| Event | Description | Context | Primary Use |
+|-------|-------------|---------|-------------|
+| `request.recurring` | New recurring request generated | Subscription renewals, scheduled payments | Send renewal notifications, update billing |
-### Subscription Events
+### Compliance Events
-
-
- **When:** Recurring payment is successfully processed
-
- **Use Cases:**
- - Extend subscription period
- - Send renewal confirmation
- - Update billing systems
-
- **For:** [Subscription](/use-cases/subscriptions) use cases
-
-
-
- **When:** Recurring payment fails
-
- **Use Cases:**
- - Notify customer of failed payment
- - Initiate payment retry
- - Manage subscription status
-
- **Common Causes:** Insufficient funds, expired payment methods
-
-
+| Event | Description | Context | Primary Use |
+|-------|-------------|---------|-------------|
+| `compliance.updated` | KYC or agreement status changed | **kycStatus values:** not_started, pending, approved, rejected, retry_required
**agreementStatus values:** not_started, pending, completed, rejected, failed | Update user permissions, notify status |
+| `payment_detail.updated` | Bank account verification status updated | States: approved, failed, pending | Enable fiat payments, update profiles |
-## Webhook Configuration
+## Security Implementation
-### Setting Up Webhooks
-
-
-
- Set up a webhook endpoint URL in the [Request Portal](https://portal.request.network)
-
-
- Choose which event types you want to receive
-
-
- Use the test webhook feature to verify your endpoint
-
-
- Enable webhooks for production traffic
-
-
-
-### Webhook Endpoint Requirements
+### Signature Verification
+Every webhook includes an HMAC SHA-256 signature in the `x-request-network-signature` header:
-
-
- **Endpoint Specifications:**
- - Must be publicly accessible HTTPS URL
- - Should return 2xx status code for successful processing
- - Timeout limit: 30 seconds
- - Must handle duplicate events (idempotency)
+```javascript
+import crypto from "node:crypto";
+
+function verifyWebhookSignature(payload, signature, secret) {
+ const expectedSignature = crypto
+ .createHmac("sha256", secret)
+ .update(JSON.stringify(payload))
+ .digest("hex");
- ```javascript
- app.post('/webhooks/request-network', (req, res) => {
- try {
- // Process webhook event
- const { eventType, data } = req.body;
-
- // Your business logic here
- processEvent(eventType, data);
-
- // Return success status
- res.status(200).send('OK');
-
- } catch (error) {
- // Return error status for retry
- console.error('Webhook processing error:', error);
- res.status(500).send('Error processing webhook');
- }
- });
- ```
-
+ return signature === expectedSignature;
+}
+
+// Usage in your webhook handler
+app.post("/webhook", (req, res) => {
+ const signature = req.headers["x-request-network-signature"];
-
- **Webhook Security:**
- - Verify webhook signatures
- - Use HTTPS only
- - Implement request validation
- - Rate limit webhook endpoints
-
- ```javascript
- const crypto = require('crypto');
-
- function verifyWebhookSignature(req) {
- const signature = req.headers['x-request-signature'];
- const timestamp = req.headers['x-request-timestamp'];
- const payload = JSON.stringify(req.body);
-
- // Verify timestamp (prevent replay attacks)
- const currentTime = Math.floor(Date.now() / 1000);
- if (Math.abs(currentTime - timestamp) > 300) { // 5 minute tolerance
- return false;
- }
-
- // Verify signature
- const expectedSignature = crypto
- .createHmac('sha256', process.env.WEBHOOK_SECRET)
- .update(timestamp + payload)
- .digest('hex');
-
- return crypto.timingSafeEqual(
- Buffer.from(signature, 'hex'),
- Buffer.from(expectedSignature, 'hex')
- );
- }
- ```
-
+ if (!verifyWebhookSignature(req.body, signature, WEBHOOK_SECRET)) {
+ return res.status(401).json({ error: "Invalid signature" });
+ }
-
- **Automatic Retries:**
- - Retry schedule: 1s, 5s, 25s, 125s, 625s
- - Maximum 5 retry attempts
- - Exponential backoff with jitter
- - Dead letter queue for failed webhooks
-
- **Error Handling:**
- ```javascript
- app.post('/webhooks/request-network', async (req, res) => {
- try {
- const { eventType, data } = req.body;
-
- // Process event
- await processEvent(eventType, data);
-
- res.status(200).send('OK');
-
- } catch (error) {
- if (error.permanent) {
- // Don't retry permanent errors
- res.status(400).send('Permanent error');
- } else {
- // Retry temporary errors
- res.status(500).send('Temporary error');
- }
- }
- });
- ```
-
-
+ // Process webhook...
+ res.status(200).json({ success: true });
+});
+```
+
+### Security Requirements
+- **HTTPS only:** Production webhooks require HTTPS endpoints
+- **Always verify signatures:** Never process unverified webhook requests
+- **Keep secrets secure:** Store signing secrets as environment variables
+- **Return 2xx for success:** Any 2xx status code confirms successful processing
+
+## Request Headers
+
+Each webhook request includes these headers:
+
+| Header | Description | Example |
+|--------|-------------|---------|
+| `x-request-network-signature` | HMAC SHA-256 signature | `a1b2c3d4e5f6...` |
+| `x-request-network-delivery` | Unique delivery ID (ULID) | `01ARZ3NDEKTSV4RRFFQ69G5FAV` |
+| `x-request-network-retry-count` | Current retry attempt (0-3) | `0` |
+| `x-request-network-test` | Present for test webhooks | `true` |
+| `content-type` | Always JSON | `application/json` |
+
+## Retry Logic
+
+### Automatic Retries
+- **Max attempts:** 3 retries (4 total attempts)
+- **Retry delays:** 1s, 5s, 15s
+- **Trigger conditions:** Non-2xx response codes, timeouts, connection errors
+- **Timeout:** 5 seconds per request
+
+### Response Handling
+```javascript
+// ✅ Success - no retry
+res.status(200).json({ success: true });
+res.status(201).json({ created: true });
+
+// ❌ Error - triggers retry
+res.status(401).json({ error: "Unauthorized" });
+res.status(404).json({ error: "Resource not found" });
+res.status(500).json({ error: "Internal server error" });
+```
+
+### Error Logging
+Request API logs all webhook delivery failures with:
+- Endpoint URL
+- Attempt number
+- Error details
+- Final failure after all retries
-## Webhook Payloads
+## Payload Examples
-### Payment Confirmed Event
+All payment events include an `explorer` field linking to [Request Scan](https://scan.request.network) for transaction details.
-
-```json Payment Confirmed
+**Common Fields:**
+- `requestId` / `requestID`: Unique identifier for the payment request
+- `paymentReference`: Short reference, also unique to a request, used to link payments to the request
+- `timestamp`: ISO 8601 formatted event timestamp
+- `paymentProcessor`: Either `request-network` (crypto) or `request-tech` (fiat)
+
+### Payment Confirmed
+```json
{
- "eventType": "payment_confirmed",
- "timestamp": "2025-09-12T10:30:00Z",
- "data": {
- "requestId": "req_1234567890abcdef",
- "paymentReference": "pay_abcdef1234567890",
- "transactionHash": "0x742d35cc6cf8a8cbeff61cf82c6b8b3b42a67f1d6c1e8a7b9e2f8d5c3a1b0e9f",
- "blockNumber": 18523456,
- "networkName": "matic",
- "amount": "1000000000000000000000", // 1000 USDC (18 decimals)
- "currency": "USDC-matic",
- "payerAddress": "0x1234567890123456789012345678901234567890",
- "payeeAddress": "0x0987654321098765432109876543210987654321",
- "fees": {
- "platformFee": "25000000000000000000", // 25 USDC
- "gasFee": "0.02"
- },
- "metadata": {
- "reason": "Invoice #INV-001",
- "invoiceNumber": "INV-001",
- "customerEmail": "customer@example.com",
- "orderId": "ORD-2025-001"
+ "event": "payment.confirmed",
+ "requestId": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "requestID": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "paymentReference": "0x2c3366941274c34c",
+ "explorer": "https://scan.request.network/request/0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "amount": "100.0",
+ "totalAmountPaid": "100.0",
+ "expectedAmount": "100.0",
+ "timestamp": "2025-10-03T14:30:00Z",
+ "txHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
+ "network": "ethereum",
+ "currency": "USDC",
+ "paymentCurrency": "USDC",
+ "isCryptoToFiat": false,
+ "subStatus": "",
+ "paymentProcessor": "request-network",
+ "fees": [
+ {
+ "type": "network",
+ "amount": "0.02",
+ "currency": "ETH"
}
- }
+ ]
}
```
-```json Request Created
+### Payment Processing
+```json
{
- "eventType": "request_created",
- "timestamp": "2025-09-12T10:00:00Z",
- "data": {
- "requestId": "req_1234567890abcdef",
- "expectedAmount": "1000000000000000000000",
- "currency": "USDC-matic",
- "payeeAddress": "0x0987654321098765432109876543210987654321",
- "payerAddress": "0x1234567890123456789012345678901234567890",
- "status": "pending",
- "createdAt": "2025-09-12T10:00:00Z",
- "dueDate": "2025-10-12T10:00:00Z",
- "metadata": {
- "reason": "Professional Services Q3 2025",
- "invoiceNumber": "INV-001",
- "customerInfo": {
- "name": "Acme Corporation",
- "email": "billing@acme.com"
- }
- }
+ "event": "payment.processing",
+ "requestId": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "requestID": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "paymentReference": "0x2c3366941274c34c",
+ "offrampId": "offramp_test123456789",
+ "timestamp": "2025-10-03T14:35:00Z",
+ "subStatus": "ongoing_checks",
+ "paymentProcessor": "request-tech",
+ "rawPayload": {
+ "status": "ongoing_checks",
+ "providerId": "provider_test123"
}
}
```
-```json Subscription Renewed
+### Payment Partial
+```json
{
- "eventType": "subscription_renewed",
- "timestamp": "2025-09-12T10:30:00Z",
- "data": {
- "subscriptionId": "sub_1234567890abcdef",
- "requestId": "req_abcdef1234567890",
- "paymentReference": "pay_1234567890abcdef",
- "transactionHash": "0x742d35cc6cf8a8cbeff61cf82c6b8b3b42a67f1d6c1e8a7b9e2f8d5c3a1b0e9f",
- "amount": "2999000000000000000000", // $29.99
- "currency": "USD",
- "renewalPeriod": "monthly",
- "nextRenewalDate": "2025-10-12T10:30:00Z",
- "customerId": "cust_1234567890",
- "subscriptionPlan": {
- "name": "Pro Plan",
- "features": ["feature1", "feature2"],
- "billingCycle": "monthly"
- }
+ "event": "payment.partial",
+ "requestId": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "requestID": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "paymentReference": "0x2c3366941274c34c",
+ "explorer": "https://scan.request.network/request/0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "amount": "50.0",
+ "totalAmountPaid": "50.0",
+ "expectedAmount": "100.0",
+ "timestamp": "2025-10-03T14:30:00Z",
+ "txHash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
+ "network": "ethereum",
+ "currency": "USDC",
+ "paymentCurrency": "USDC",
+ "isCryptoToFiat": false,
+ "subStatus": "",
+ "paymentProcessor": "request-network",
+ "fees": []
+}
+```
+
+### Payment Failed
+```json
+{
+ "event": "payment.failed",
+ "requestId": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "requestID": "0151b394e3c482c5aebaa04eb04508a8db70595470760293f1b258ed96d1fafa93",
+ "paymentReference": "0x2c3366941274c34c",
+ "subStatus": "insufficient_funds",
+ "paymentProcessor": "request-network"
+}
+```
+
+### Compliance Updated
+```json
+{
+ "event": "compliance.updated",
+ "clientUserId": "user_test123456789",
+ "kycStatus": "approved",
+ "agreementStatus": "completed",
+ "isCompliant": true,
+ "timestamp": "2025-10-03T14:30:00Z",
+ "rawPayload": {
+ "verificationLevel": "full",
+ "documents": "verified"
}
}
```
-
-## Integration Examples
+## Implementation Examples
+
+For a complete working example, see the [EasyInvoice demo](/use-cases/invoicing) which implements webhook handling for payment notifications.
+
+
+
+```javascript
+import express from "express";
+import crypto from "node:crypto";
+
+const app = express();
+const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
-### E-commerce Order Processing
+app.use(express.json());
-
-```javascript Express.js Handler
-app.post('/webhooks/payment-confirmed', async (req, res) => {
+app.post("/webhook/payment", async (req, res) => {
try {
- // Verify webhook signature
- if (!verifyWebhookSignature(req)) {
- return res.status(401).send('Unauthorized');
+ // Verify signature
+ const signature = req.headers["x-request-network-signature"];
+ const expectedSignature = crypto
+ .createHmac("sha256", WEBHOOK_SECRET)
+ .update(JSON.stringify(req.body))
+ .digest("hex");
+
+ if (signature !== expectedSignature) {
+ return res.status(401).json({ error: "Invalid signature" });
}
+
+ // Check for test webhook
+ const isTest = req.headers["x-request-network-test"] === "true";
- const { eventType, data } = req.body;
+ // Process webhook based on event type
+ const { event, requestId } = req.body;
- if (eventType === 'payment_confirmed') {
- const orderId = data.metadata.orderId;
-
- // Update order status
- await updateOrder(orderId, {
- status: 'paid',
- paymentHash: data.transactionHash,
- paidAt: data.timestamp,
- paymentMethod: 'crypto'
- });
-
- // Send confirmation email
- await sendOrderConfirmation(orderId);
-
- // Trigger fulfillment
- await triggerOrderFulfillment(orderId);
-
- console.log(`Order ${orderId} marked as paid`);
+ switch (event) {
+ case "payment.confirmed":
+ await handlePaymentConfirmed(req.body);
+ break;
+ case "payment.processing":
+ await handlePaymentProcessing(req.body);
+ break;
+ case "compliance.updated":
+ await handleComplianceUpdate(req.body);
+ break;
+ default:
+ console.log(`Unhandled event: ${event}`);
}
-
- res.status(200).send('OK');
+
+ return res.status(200).json({ success: true });
} catch (error) {
- console.error('Webhook error:', error);
- res.status(500).send('Error processing webhook');
+ console.error("Webhook processing error:", error);
+ return res.status(500).json({ error: "Processing failed" });
}
});
```
+
+
+
+```javascript
+// app/api/webhook/route.ts
+import crypto from "node:crypto";
+import { NextResponse } from "next/server";
-```javascript SaaS Subscription Handler
-app.post('/webhooks/subscription-events', async (req, res) => {
+export async function POST(request: Request) {
try {
- const { eventType, data } = req.body;
+ const body = await request.json();
- switch (eventType) {
- case 'subscription_renewed':
- // Extend subscription period
- await extendSubscription(data.customerId, data.renewalPeriod);
-
- // Send renewal confirmation
- await sendRenewalConfirmation(data.customerId);
- break;
-
- case 'subscription_failed':
- // Handle failed payment
- await handleFailedSubscriptionPayment(data.customerId);
-
- // Send payment failure notification
- await sendPaymentFailureNotification(data.customerId);
- break;
-
- case 'subscription_cancelled':
- // Deactivate subscription
- await deactivateSubscription(data.customerId);
- break;
+ // Verify signature
+ const signature = request.headers.get("x-request-network-signature");
+ const expectedSignature = crypto
+ .createHmac("sha256", process.env.WEBHOOK_SECRET!)
+ .update(JSON.stringify(body))
+ .digest("hex");
+
+ if (signature !== expectedSignature) {
+ return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
}
+
+ // Process webhook
+ const { event, requestId } = body;
- res.status(200).send('OK');
+ // Your business logic here
+ await processWebhookEvent(event, body);
+
+ return NextResponse.json({ success: true }, { status: 200 });
} catch (error) {
- console.error('Subscription webhook error:', error);
- res.status(500).send('Error processing subscription webhook');
+ console.error("Webhook error:", error);
+
+ if (error instanceof ResourceNotFoundError) {
+ return NextResponse.json({ error: error.message }, { status: 404 });
+ }
+
+ return NextResponse.json(
+ { error: "Internal server error" },
+ { status: 500 }
+ );
}
-});
-```
-
-
-### Database Integration
-
-
-```sql Payment Tracking
--- Create table for payment tracking
-CREATE TABLE payment_events (
- id SERIAL PRIMARY KEY,
- request_id VARCHAR(255) NOT NULL,
- event_type VARCHAR(50) NOT NULL,
- transaction_hash VARCHAR(66),
- block_number INTEGER,
- amount DECIMAL(36, 18),
- currency VARCHAR(20),
- payer_address VARCHAR(42),
- payee_address VARCHAR(42),
- metadata JSONB,
- created_at TIMESTAMP DEFAULT NOW(),
- processed_at TIMESTAMP,
- INDEX idx_request_id (request_id),
- INDEX idx_event_type (event_type),
- INDEX idx_created_at (created_at)
-);
+}
```
+
+
+
+## Testing
+
+### Portal Testing
+1. Go to **Platform Settings → Webhooks** in Request Portal
+2. Create a webhook if you haven't already
+3. Select the webhook event type and click **Send test event**
+4. Monitor your endpoint logs for test requests
+
+### Test Webhook Identification
+Test webhooks include the `x-request-network-test: true` header:
-```javascript Database Handler
-async function savePaymentEvent(eventData) {
- const {
- requestId,
- eventType,
- transactionHash,
- blockNumber,
- amount,
- currency,
- payerAddress,
- payeeAddress,
- metadata
- } = eventData;
+```javascript
+app.post("/webhook", (req, res) => {
+ const isTest = req.headers["x-request-network-test"] === "true";
- // Insert payment event
- const result = await db.query(`
- INSERT INTO payment_events (
- request_id, event_type, transaction_hash, block_number,
- amount, currency, payer_address, payee_address, metadata
- ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
- RETURNING id
- `, [
- requestId, eventType, transactionHash, blockNumber,
- amount, currency, payerAddress, payeeAddress, JSON.stringify(metadata)
- ]);
+ if (isTest) {
+ console.log("Received test webhook");
+ // Handle test scenario
+ }
- return result.rows[0].id;
-}
+ // Process normally...
+});
```
-
-## Testing Webhooks
+## Best Practices
-### Webhook Testing Tools
+### Error Handling
+- **Implement idempotency:** Use delivery IDs to prevent duplicate processing
+- **Graceful degradation:** Handle unknown event types without errors
-
-
- **Local Development:**
- - Expose local server to internet
- - Test webhooks during development
- - Secure tunnels with authentication
-
- ```bash
- # Install ngrok
- npm install -g ngrok
-
- # Expose local server
- ngrok http 3000
-
- # Use ngrok URL as webhook endpoint
- # https://abc123.ngrok.io/webhooks/request-network
- ```
-
-
-
- **Quick Testing:**
- - Temporary webhook endpoints
- - Inspect webhook payloads
- - No setup required
-
- **Process:**
- 1. Go to webhook.site
- 2. Copy the unique URL
- 3. Use as webhook endpoint
- 4. View received webhooks in browser
-
-
+### Performance
+- **Timeout management:** Complete processing within 5 seconds
-### Test Event Simulation
+## Troubleshooting
-
-**Test Webhooks in Request Portal**
+### Common Issues
-Use the Request Portal to send test webhook events to your endpoint for development and testing.
-
+**Signature verification fails:**
+- Check your signing secret matches Portal configuration
+- Ensure you're using the raw request body for signature calculation
+- Verify HMAC SHA-256 implementation
+
+**Webhooks not received:**
+- Confirm endpoint URL is accessible via HTTPS
+- Verify endpoint returns 2xx status codes
+
+### Debugging Tips
+- Use ngrok request inspector to see raw webhook data
+- Monitor retry counts in headers to identify issues
+- Test with Portal's "Send test webhooks" feature
-## What's Next?
+## Related Documentation
-
-
- Secure your API and webhook endpoints
+
+
+ High-level webhook concepts and workflow
-
-
- Learn more about webhook event types and handling
+
+
+ Complete webhook implementation example
-
-
- Common webhook integration patterns and best practices
+
+
+ API key setup and webhook security
+
+
+
+ Understanding payment lifecycle events
+
+
+
+ Configure webhooks and manage API keys
+
+
+
+ Explore transactions and request details
diff --git a/docs.json b/docs.json
index 91467f0..a375a7a 100644
--- a/docs.json
+++ b/docs.json
@@ -71,11 +71,11 @@
{
"group": "Requests",
"pages": [
- "api-features/create-requests-query-status"
+ "api-features/create-requests"
]
},
{
- "group": "Payment Types",
+ "group": "Payments",
"pages": [
"api-features/payment-types-overview",
"api-features/standard-payments",
@@ -91,6 +91,7 @@
"group": "Reconciliation",
"pages": [
"api-features/payment-detection",
+ "api-features/query-requests",
"api-features/query-payments",
"api-features/webhooks-events"
]