@@ -10,14 +10,14 @@ Webhooks deliver real-time notifications when payment and request events occur.
10
10
## Webhook Configuration
11
11
12
12
### Setup in Portal
13
- 1 . Navigate to ** Settings → Webhooks** in Request Portal
14
- 2 . Add your HTTPS endpoint URL
15
- 3 . Copy your ** Signing Secret ** for signature verification
16
- 4 . Select event types to receive
17
- 5 . Test with ** Send test webhooks** feature
13
+ 1 . Navigate to ** Platform Settings → Webhooks** in Request Portal
14
+ 2 . Click ** Add webhook **
15
+ 3 . Enter URL and click ** Create webhook **
16
+ 4 . Click copy button to copy ** Signing Secret ** to clipboard
17
+ 5 . Enable/disable or delete webhooks as needed
18
18
19
19
### Local Development
20
- Use ngrok to receive webhooks locally:
20
+ Use [ ngrok] ( https://ngrok.com/docs/traffic-policy/getting-started/agent-endpoints/cli ) to receive webhooks locally:
21
21
``` bash
22
22
ngrok http 3000
23
23
# Use the HTTPS URL (e.g., https://abc123.ngrok.io/webhook) in Portal
@@ -27,7 +27,7 @@ ngrok http 3000
27
27
28
28
### Payment Events
29
29
<CardGroup cols = { 2 } >
30
- <Card title = " payment.confirmed" icon = " check- circle" >
30
+ <Card title = " payment.confirmed" icon = " circle-check " >
31
31
Payment fully completed and settled
32
32
33
33
** Timing:** After blockchain confirmation
@@ -41,14 +41,14 @@ ngrok http 3000
41
41
** Use:** Update balance, allow additional payments
42
42
</Card >
43
43
44
- <Card title = " payment.failed" icon = " x- circle" >
44
+ <Card title = " payment.failed" icon = " circle-x " >
45
45
Payment transaction failed or reverted
46
46
47
47
** Triggers:** Failed TX, insufficient funds
48
48
** Use:** Notify failure, reset order status
49
49
</Card >
50
50
51
- <Card title = " payment.refunded" icon = " undo " >
51
+ <Card title = " payment.refunded" icon = " arrow-uturn-left " >
52
52
Payment has been refunded to payer
53
53
54
54
** Context:** Crypto-to-fiat transactions
@@ -162,6 +162,7 @@ res.status(200).json({ success: true });
162
162
res .status (201 ).json ({ created: true });
163
163
164
164
// ❌ Error - triggers retry
165
+ res .status (401 ).json ({ error: " Unauthorized" });
165
166
res .status (404 ).json ({ error: " Resource not found" });
166
167
res .status (500 ).json ({ error: " Internal server error" });
167
168
```
@@ -179,51 +180,104 @@ Request API logs all webhook delivery failures with:
179
180
``` json
180
181
{
181
182
"event" : " payment.confirmed" ,
182
- "requestId" : " 01ARZ3NDEKTSV4RRFFQ69G5FAV" ,
183
- "paymentNetwork" : " erc20-fee-proxy-contract" ,
184
- "currency" : " USDC" ,
185
- "amount" : " 100.00" ,
186
- "txHash" : " 0x1234567890abcdef..." ,
183
+ "requestId" : " req_test123456789abcdef" ,
184
+ "requestID" : " req_test123456789abcdef" ,
185
+ "paymentReference" : " 0x1234567890abcdef1234567890abcdef12345678" ,
186
+ "explorer" : " https://scan.request.network/request/req_test123456789abcdef" ,
187
+ "amount" : " 100.0" ,
188
+ "totalAmountPaid" : " 100.0" ,
189
+ "expectedAmount" : " 100.0" ,
187
190
"timestamp" : " 2025-10-03T14:30:00Z" ,
188
- "metadata" : {
189
- "orderId" : " ORDER-123" ,
190
- "customField" : " value"
191
- }
191
+ "txHash" : " 0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" ,
192
+ "network" : " ethereum" ,
193
+ "currency" : " USDC" ,
194
+ "paymentCurrency" : " USDC" ,
195
+ "isCryptoToFiat" : false ,
196
+ "subStatus" : " " ,
197
+ "paymentProcessor" : " request_network" ,
198
+ "fees" : [
199
+ {
200
+ "type" : " network" ,
201
+ "amount" : " 0.02" ,
202
+ "currency" : " ETH"
203
+ }
204
+ ]
192
205
}
193
206
```
194
207
195
208
### Payment Processing
196
209
``` json
197
210
{
198
211
"event" : " payment.processing" ,
199
- "requestId" : " 01ARZ3NDEKTSV4RRFFQ69G5FAV" ,
200
- "subStatus" : " sending_fiat" ,
212
+ "requestId" : " req_test123456789abcdef" ,
213
+ "requestID" : " req_test123456789abcdef" ,
214
+ "paymentReference" : " 0x1234567890abcdef1234567890abcdef12345678" ,
215
+ "offrampId" : " offramp_test123456789" ,
216
+ "timestamp" : " 2025-10-03T14:35:00Z" ,
217
+ "subStatus" : " processing" ,
218
+ "paymentProcessor" : " request_tech" ,
219
+ "rawPayload" : {
220
+ "status" : " processing" ,
221
+ "providerId" : " provider_test123"
222
+ }
223
+ }
224
+ ```
225
+
226
+ ### Payment Partial
227
+ ``` json
228
+ {
229
+ "event" : " payment.partial" ,
230
+ "requestId" : " req_test123456789abcdef" ,
231
+ "requestID" : " req_test123456789abcdef" ,
232
+ "paymentReference" : " 0x1234567890abcdef1234567890abcdef12345678" ,
233
+ "explorer" : " https://scan.request.network/request/req_test123456789abcdef" ,
234
+ "amount" : " 50.0" ,
235
+ "totalAmountPaid" : " 50.0" ,
236
+ "expectedAmount" : " 100.0" ,
237
+ "timestamp" : " 2025-10-03T14:30:00Z" ,
238
+ "txHash" : " 0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" ,
239
+ "network" : " ethereum" ,
201
240
"currency" : " USDC" ,
202
- "amount" : " 100.00" ,
203
- "fiatCurrency" : " USD" ,
204
- "fiatAmount" : " 99.50" ,
205
- "timestamp" : " 2025-10-03T14:35:00Z"
241
+ "paymentCurrency" : " USDC" ,
242
+ "isCryptoToFiat" : false ,
243
+ "subStatus" : " " ,
244
+ "paymentProcessor" : " request_network" ,
245
+ "fees" : []
246
+ }
247
+ ```
248
+
249
+ ### Payment Failed
250
+ ``` json
251
+ {
252
+ "event" : " payment.failed" ,
253
+ "requestId" : " req_test123456789abcdef" ,
254
+ "requestID" : " req_test123456789abcdef" ,
255
+ "paymentReference" : " 0x1234567890abcdef1234567890abcdef12345678" ,
256
+ "subStatus" : " insufficient_funds" ,
257
+ "paymentProcessor" : " request_network"
206
258
}
207
259
```
208
260
209
261
### Compliance Updated
210
262
``` json
211
263
{
212
264
"event" : " compliance.updated" ,
213
- "userId " : " user_abc123 " ,
265
+ "clientUserId " : " user_test123456789 " ,
214
266
"kycStatus" : " approved" ,
215
- "agreementStatus" : " completed" ,
267
+ "agreementStatus" : " signed" ,
268
+ "isCompliant" : true ,
216
269
"timestamp" : " 2025-10-03T14:30:00Z" ,
217
- "metadata " : {
218
- "level " : " tier2 " ,
219
- "documents" : [ " passport " , " proof_of_address " ]
270
+ "rawPayload " : {
271
+ "verificationLevel " : " full " ,
272
+ "documents" : " verified "
220
273
}
221
274
}
222
275
```
223
276
224
277
## Implementation Examples
225
278
226
- ### Express.js Handler
279
+ <Tabs >
280
+ <Tab title = " Express.js" >
227
281
``` javascript
228
282
import express from " express" ;
229
283
import crypto from " node:crypto" ;
@@ -274,8 +328,9 @@ app.post("/webhook/payment", async (req, res) => {
274
328
}
275
329
});
276
330
```
331
+ </Tab >
277
332
278
- ### Next.js API Route
333
+ < Tab title = " Next.js" >
279
334
``` javascript
280
335
// app/api/webhook/route.ts
281
336
import crypto from " node:crypto" ;
@@ -318,13 +373,15 @@ export async function POST(request: Request) {
318
373
}
319
374
}
320
375
```
376
+ </Tab >
377
+ </Tabs >
321
378
322
379
## Testing
323
380
324
381
### Portal Testing
325
- 1 . Go to ** Settings → Webhooks** in Request Portal
326
- 2 . Click ** Send test webhooks **
327
- 3 . Select event types to test
382
+ 1 . Go to ** Platform Settings → Webhooks** in Request Portal
383
+ 2 . Create a webhook if you haven't already
384
+ 3 . Select the webhook event type and click ** Send test event **
328
385
4 . Monitor your endpoint logs for test requests
329
386
330
387
### Test Webhook Identification
0 commit comments