const result = await afriex.webhooks.triggerTestWebhook({
event: "TRANSACTION.UPDATED",
entityId: "6952826eba52c13b669fb263",
});
console.log(result);
// { queued: true, event: "TRANSACTION.UPDATED", entityId: "6952826eba52c13b669fb263", deliveryUrl: "https://merchant.example.com/webhooks" }
curl --request POST \
--url https://sandbox.api.afriex.com/api/v1/webhooks/trigger \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"event": "TRANSACTION.UPDATED",
"entityId": "6952826eba52c13b669fb263"
}
'import requests
url = "https://sandbox.api.afriex.com/api/v1/webhooks/trigger"
payload = {
"event": "TRANSACTION.UPDATED",
"entityId": "6952826eba52c13b669fb263"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({event: 'TRANSACTION.UPDATED', entityId: '6952826eba52c13b669fb263'})
};
fetch('https://sandbox.api.afriex.com/api/v1/webhooks/trigger', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.api.afriex.com/api/v1/webhooks/trigger",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'event' => 'TRANSACTION.UPDATED',
'entityId' => '6952826eba52c13b669fb263'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.api.afriex.com/api/v1/webhooks/trigger"
payload := strings.NewReader("{\n \"event\": \"TRANSACTION.UPDATED\",\n \"entityId\": \"6952826eba52c13b669fb263\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.api.afriex.com/api/v1/webhooks/trigger")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"event\": \"TRANSACTION.UPDATED\",\n \"entityId\": \"6952826eba52c13b669fb263\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.api.afriex.com/api/v1/webhooks/trigger")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"event\": \"TRANSACTION.UPDATED\",\n \"entityId\": \"6952826eba52c13b669fb263\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"queued": true,
"event": "TRANSACTION.UPDATED",
"entityId": "6952826eba52c13b669fb263",
"deliveryUrl": "https://merchant.example.com/webhooks"
}
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"message": "Not allowed"
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"code": "EXTERNAL_REQUEST_ERROR",
"error": "External request error",
"details": {}
}Trigger Test Webhook
Fires a real signed webhook to the business’s configured callback URL using a real entity (customer, payment method, transaction, or checkout session) as the payload. Useful for testing webhook handlers in sandbox without manufacturing the underlying activity. This endpoint is only available in the sandbox environment and will return a 403 Forbidden response in production. The business must have a webhook callback URL configured, or the request is rejected with 400.
const result = await afriex.webhooks.triggerTestWebhook({
event: "TRANSACTION.UPDATED",
entityId: "6952826eba52c13b669fb263",
});
console.log(result);
// { queued: true, event: "TRANSACTION.UPDATED", entityId: "6952826eba52c13b669fb263", deliveryUrl: "https://merchant.example.com/webhooks" }
curl --request POST \
--url https://sandbox.api.afriex.com/api/v1/webhooks/trigger \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"event": "TRANSACTION.UPDATED",
"entityId": "6952826eba52c13b669fb263"
}
'import requests
url = "https://sandbox.api.afriex.com/api/v1/webhooks/trigger"
payload = {
"event": "TRANSACTION.UPDATED",
"entityId": "6952826eba52c13b669fb263"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({event: 'TRANSACTION.UPDATED', entityId: '6952826eba52c13b669fb263'})
};
fetch('https://sandbox.api.afriex.com/api/v1/webhooks/trigger', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.api.afriex.com/api/v1/webhooks/trigger",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'event' => 'TRANSACTION.UPDATED',
'entityId' => '6952826eba52c13b669fb263'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.api.afriex.com/api/v1/webhooks/trigger"
payload := strings.NewReader("{\n \"event\": \"TRANSACTION.UPDATED\",\n \"entityId\": \"6952826eba52c13b669fb263\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.api.afriex.com/api/v1/webhooks/trigger")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"event\": \"TRANSACTION.UPDATED\",\n \"entityId\": \"6952826eba52c13b669fb263\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.api.afriex.com/api/v1/webhooks/trigger")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"event\": \"TRANSACTION.UPDATED\",\n \"entityId\": \"6952826eba52c13b669fb263\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"queued": true,
"event": "TRANSACTION.UPDATED",
"entityId": "6952826eba52c13b669fb263",
"deliveryUrl": "https://merchant.example.com/webhooks"
}
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"message": "Not allowed"
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"code": "<string>",
"error": "<string>",
"details": {
"errorMessage": "<string>",
"friendlyMessage": "<string>",
"data": {
"customerId": "<string>"
}
}
}{
"code": "EXTERNAL_REQUEST_ERROR",
"error": "External request error",
"details": {}
}403 Forbidden response in production.TRANSACTION.UPDATED. Pick the outcome with the payment method’s last four digits (0001 fails, 0003 stays pending until you call /simulate), or add SIMULATE_INSTANT anywhere in meta.reference to speed things up to about 30 seconds. Full reference: Testing in Sandbox.How it works
- Create or look up an existing entity in sandbox.
- Call this endpoint with the matching
eventname and the entity’s ID. - Afriex delivers a real, signed webhook to your configured callback URL using that entity as the payload.
What to pass as entityId
| Event family | entityId |
|---|---|
CUSTOMER.* | The customer ID, 24 hexadecimal characters |
PAYMENT_METHOD.* | The payment method ID, 24 hexadecimal characters |
TRANSACTION.* | The transaction ID, 24 hexadecimal characters |
CHECKOUT_SESSION.* | The checkoutId returned when you created the checkout. It must belong to your business. |
Authorizations
Static business API key issued from the dashboard. A business can provision multiple API keys, each scoped to a configurable set of permissions (e.g. read transactions, create deposits, etc). Permissions are chosen per key at creation time in the dashboard and may be revoked by deleting the key. Manage your keys and their permissions under Developer → API keys in the dashboard.
A request whose key does not carry the permission the target
endpoint requires is rejected with 401 Unauthorized, the same
response an unrecognised, malformed, revoked or disabled key
returns. The API does not distinguish the two cases on the wire.
See the Permissions reference for the permission each endpoint requires.
Headers
API version in ISO 8601 format. The only supported version is 2026-05-18, which is also the default when the header is omitted. Any other value is rejected with a 400 Bad Request.
Body
The event to fire. POOL_DEPOSIT_REQUEST.REJECTED is delivered by the pool-account flow but cannot be fired from this test endpoint; sending it returns 400.
CUSTOMER.CREATED, CUSTOMER.UPDATED, CUSTOMER.DELETED, PAYMENT_METHOD.CREATED, PAYMENT_METHOD.UPDATED, PAYMENT_METHOD.DELETED, TRANSACTION.CREATED, TRANSACTION.UPDATED, CHECKOUT_SESSION.CREATED, POOL_DEPOSIT_REQUEST.REJECTED The identifier of the entity to send in the webhook payload. When event is CHECKOUT_SESSION.CREATED, send the checkoutId returned when you created the session; otherwise must be the 24-character hexadecimal id of the relevant customer, payment method, or transaction (the id returned when it was created).
"69528240ba52c13b669fb239"
Response
Webhook triggered successfully.
Details of the queued webhook delivery.
Show child attributes
Show child attributes
