Overview
If your store doesn't run on Shopify or WooCommerce β for example, a custom-built website, an in-house order system, or any other platform β you can still integrate with FraudHawkAI using our custom order endpoint.
Unlike the Shopify and WooCommerce integrations, this endpoint does not mirror a third-party payload shape. A custom site has no standard order format for us to map from, so this endpoint defines its own simple JSON contract. You send your order data in this format, and FraudHawkAI handles the rest β risk analysis, customer matching, and order tracking β the same as it does for Shopify and WooCommerce orders.
How it works
- An order is created on your platform
- You format the order data to match the FraudHawkAI custom order schema
- You send it to the FraudHawkAI custom order endpoint with your API token
- FraudHawkAI matches or creates the customer record, saves the order, and analyzes it for risk
- If you send the same
externalOrderIdagain (e.g. when order status changes), the existing order is updated instead of duplicated
Prerequisites
Before you begin, make sure you have:
- A FraudHawkAI account β sign up here
- Your API token β found in Dashboard β API Key
- The ability to send an HTTP
POSTrequest from your platform or backend (server-side, not client-side)
Endpoint
POST /api/webhooks/custom?token={your_api_token}
Query parameters
| Parameter | Required | Description |
|---|---|---|
token | Yes | Your FraudHawkAI API token. Requests without a valid token are rejected with 401 Unauthorized |
Note: Unlike the Shopify and WooCommerce integrations, this endpoint does not take a
platformquery parameter. There's only one payload format for custom integrations β described below β so there's nothing to select between.
Request body
Send a JSON body matching the schema below.
{
"externalOrderId": "ORD-1023",
"orderNumber": "1023",
"customer": {
"name": "Ali Raza",
"email": "ali@example.com",
"phone": "03001234567"
},
"amount": 4500,
"currency": "PKR",
"paymentType": "cod",
"status": "pending",
"items": [
{ "name": "Product A", "sku": "SKU1", "quantity": 1, "price": 4500 }
],
"shippingAddress": {
"city": "Lahore",
"address1": "House #123, Street 5",
"phone": "03001234567"
},
"courier": "Leopards"
}
Field reference
| Field | Type | Required | Description |
|---|---|---|---|
externalOrderId | string | Yes | A unique identifier for this order in your system. Used to detect repeat requests for the same order β sending the same externalOrderId again updates the existing order instead of creating a duplicate |
orderNumber | string | No | A human-readable order number, shown in your FraudHawkAI dashboard. Defaults to externalOrderId if omitted |
customer | object | Yes | The customer object β see below |
customer.name | string | Recommended | Customer's full name |
customer.email | string | Conditional | Customer's email address. At least one of customer.email or customer.phone must be provided |
customer.phone | string | Conditional | Customer's phone number. At least one of customer.email or customer.phone must be provided. Stored as a hash β never in plain text |
amount | number | Yes | The total order value as a number (not a string). Example: 4500, not "4500.00" |
currency | string | No | Three-letter currency code. Defaults to PKR if omitted |
paymentType | string | Yes | Must be exactly cod or prepaid. Any other value is rejected |
status | string | No | Order status. Defaults to pending if omitted or not one of the valid values listed below |
items | array | No | List of products in the order. Optional, but recommended for more accurate risk analysis |
items[].name | string | Yes, if items is sent | Product name |
items[].sku | string | No | Product SKU |
items[].quantity | number | No | Quantity ordered. Defaults to 1 if omitted |
items[].price | number | No | Price per unit. Defaults to 0 if omitted |
shippingAddress | object | No | Shipping address details. Structure is flexible (e.g. city, address1, phone) |
courier | string | No | Name of the courier handling delivery (e.g. Leopards, TCS). Defaults to unknown if omitted |
Important:
customer.emailandcustomer.phoneare not individually mandatory, but at least one of the two is required β a request with neither is rejected. Providingcustomer.namealongside one of them is strongly recommended, since FraudHawkAI uses these fields to match and track customer order history across your store.
Valid status values
| Value | Meaning |
|---|---|
pending | Order placed, not yet processed |
processing | Order is being prepared |
shipped | Order has been dispatched to the courier |
delivered | Order was successfully delivered |
cancelled | Order was cancelled before dispatch |
returned | Order was delivered but later returned |
rejected | Order was refused at the doorstep (RTO) |
Any value outside this list is ignored, and the order is saved with a status of pending.
How duplicate requests are handled
FraudHawkAI treats externalOrderId as the unique identifier for an order from your store. If you send a request with an externalOrderId that already exists:
- The existing order is updated with the new data you sent (not duplicated)
- If the
statushas changed since the last request, your customer's order counters (e.g. delivered count, returned count) are adjusted automatically - The response returns
200 OKwith the message"Order updated"
If the externalOrderId is new, a new order is created and the response returns 201 Created with the message "Order saved".
This means it's safe β and expected β to call this endpoint again for the same order when its status changes, for example when it moves from pending to shipped, or from shipped to delivered.
Example request
curl -X POST "https://www.fraudhawkai.com/api/webhooks/custom?token=your_api_token" \
-H "Content-Type: application/json" \
-d '{
"externalOrderId": "ORD-1023",
"orderNumber": "1023",
"customer": {
"name": "Ali Raza",
"email": "ali@example.com",
"phone": "03001234567"
},
"amount": 4500,
"currency": "PKR",
"paymentType": "cod",
"status": "pending",
"items": [
{ "name": "Product A", "sku": "SKU1", "quantity": 1, "price": 4500 }
],
"shippingAddress": {
"city": "Lahore",
"address1": "House #123, Street 5",
"phone": "03001234567"
},
"courier": "Leopards"
}'
Response format
Success β new order
{
"success": true,
"message": "Order saved",
"orderId": "665f1c2e9b1f2a0012a3b456"
}
Status code: 201 Created
Success β existing order updated
{
"success": true,
"message": "Order updated",
"orderId": "665f1c2e9b1f2a0012a3b456"
}
Status code: 200 OK
Error responses
| Status | Message | Cause |
|---|---|---|
401 | Unauthorized. Please provide a token. | The token query parameter is missing |
401 | Invalid or expired token | The token doesn't match any account |
400 | externalOrderId is required | The externalOrderId field is missing from the request body |
400 | amount (number) is required | The amount field is missing or not a number |
400 | paymentType must be 'cod' or 'prepaid' | The paymentType field is missing or has an invalid value |
400 | customer.email or customer.phone is required | Neither customer.email nor customer.phone was provided |
500 | Internal Server Error | An unexpected error occurred while processing the request |
Testing your integration
- Send a test request using the
curlexample above with your own API token - Confirm you receive a
201response with"message": "Order saved" - Log in to your FraudHawkAI dashboard to see the test order appear
- Send the same request again with the same
externalOrderIdand confirm you now get a200response with"message": "Order updated" - Once confirmed, connect your live order flow to send real orders as they're created and updated