Get Order Data from FBPI Webhooks
This guide walks you through handling an FBPI order webhook event and retrieving full order and customer data from the FBPI APIs. By the end, your integration will parse the order_nr from the webhook payload, fetch the complete order details, and store the data your system needs to process the order.
How It Works
Key points about this flow:
- Return HTTP 200 immediately. noon's Event Notifications system is push-based and at-least-once. Return 2xx before any processing — delaying the response risks retries and duplicate events.
- The webhook payload contains only
order_nr. All order details, item statuses, and customer data come from subsequent API calls, not the webhook body. order_nris your primary key. Use it for all downstream processing and API retrieval.- Use exponential backoff on API calls. If
GetFbpiOrderreturns a transient error, the order may not yet be available. Retry with backoff.
Prerequisites
- An active FBPI integration warehouse with a configured webhook URL — see Warehouse Setup
- Your webhook destination registered in Event Notifications — see Event Notifications
- An authenticated API session — see Authenticating Your Requests
Step 1 — Receive the Webhook Event
noon sends an FBPI::ORDER_SYNC event to your webhook endpoint when an order is placed. Parse the order_nr from the payload, return HTTP 200 immediately, and enqueue the order_nr for background processing.
Webhook payload:
{
"event_schema_version": 1,
"event_type": "FBPI::ORDER_SYNC",
"metadata": {
"message_id": "msg-abc123",
"destination_id": "dest-xyz456",
"published_at": "2026-04-09T08:42:15Z",
"project_code": "your-project-code"
},
"payload": {
"order_nr": "NFBO123456789"
}
}
Validation checklist before processing:
event_typeequalsFBPI::ORDER_SYNCpayload.order_nris present and non-emptyevent_schema_versionequals1
If any of these checks fail, return HTTP 200 anyway (to prevent retries) and log the raw payload for investigation. Do not return non-2xx on validation failure.
You'll know this worked when your endpoint returns HTTP 200 and you can see the event in the Event Notifications log.
Step 2 — Retrieve Full Order Details
Call GetFbpiOrder (GET /fbpi/v1/fbpi-order/{fbpi_order_nr}/get) with the order_nr from the webhook to fetch the complete order.
- Python
- Node.js
- Go
import requests
session = get_authenticated_session()
order_nr = "NFBO123456789" # from webhook payload
response = session.get(
f"https://noon-api-gateway.noon.partners/fbpi/v1/fbpi-order/{order_nr}/get",
headers={"User-Agent": "MyApp/1.0.0"},
timeout=30,
)
response.raise_for_status()
order = response.json()
const client = await getAuthenticatedClient();
const orderNr = "NFBO123456789"; // from webhook payload
const response = await client.get(
`https://noon-api-gateway.noon.partners/fbpi/v1/fbpi-order/${orderNr}/get`,
{ headers: { "User-Agent": "MyApp/1.0.0" } }
);
const order = response.data;
orderNr := "NFBO123456789" // from webhook payload
client := getAuthenticatedClient()
url := fmt.Sprintf("https://noon-api-gateway.noon.partners/fbpi/v1/fbpi-order/%s/get", orderNr)
req, _ := http.NewRequest(http.MethodGet, url, nil)
req.Header.Set("User-Agent", "MyApp/1.0.0")
client.Timeout = 30 * time.Second
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var order map[string]any
json.NewDecoder(resp.Body).Decode(&order)
Response:
<!-- from: v1GetFbpiOrderResponse -->
{
"fbpi_order_nr": "NFBO123456789",
"mp_code": "noon",
"mp_order_nr": "NF123456789",
"mp_country_code": "ae",
"customer_country_code": "ae",
"merchant_code": "STR-12345",
"currency_code": "AED",
"warehouse_code": "WH-NOON-001",
"order_created_at": "2026-04-09T08:42:15Z",
"items": [
{
"mp_item_nr": "NFBO123456789-1",
"partner_sku": "MY-SKU-001",
"mp_status": "MP_ITEM_STATUS_CONFIRMED",
"integration_status": "INTEGRATION_ITEM_STATUS_ACKNOWLEDGED",
"delivered_invoice_price": 149.99,
"cancellation_reason_code": null
}
]
}
Key response fields:
| Field | Description |
|---|---|
fbpi_order_nr | Primary key for all downstream API calls |
mp_code | Marketplace source: "noon" or "namshi" |
customer_country_code | Country from which the customer placed the order |
merchant_code | Your merchant identifier, prefixed with STR |
warehouse_code | Integration warehouse assigned to fulfil this order |
mp_status values — the marketplace's view of each item:
| Value | Meaning |
|---|---|
MP_ITEM_STATUS_CONFIRMED | Item is active and confirmed by the marketplace |
MP_ITEM_STATUS_CANCELLED | Item has been cancelled by the marketplace |
MP_ITEM_STATUS_UNSPECIFIED | Default — treat as unresolved |
integration_status values — your integration's view of each item:
| Value | Meaning |
|---|---|
INTEGRATION_ITEM_STATUS_ACKNOWLEDGED | Order received and acknowledged by your webhook |
INTEGRATION_ITEM_STATUS_OUT_OF_STOCK | Item marked out of stock by your integration |
INTEGRATION_ITEM_STATUS_SHIPPED | Shipment created for this item |
INTEGRATION_ITEM_STATUS_UNSPECIFIED | Default — treat as unresolved |
You'll know this worked when you receive a response with items populated and integration_status set to INTEGRATION_ITEM_STATUS_ACKNOWLEDGED.
| Error | What it means | What to do |
|---|---|---|
| HTTP 404 | Order not yet available | Retry with exponential backoff — the order may not be queryable immediately |
| HTTP 401 | Session expired | Re-authenticate and retry |
For the full schema, see GetFbpiOrder API Reference.
Step 3 — Retrieve Customer Details
Call GetFbpiOrderCustomerData (GET /fbpi/v1/fbpi-order/{fbpi_order_nr}/customer-details/get) to fetch the customer's name and delivery location. Use the same order_nr.
- Python
- Node.js
- Go
import requests
session = get_authenticated_session()
order_nr = "NFBO123456789"
response = session.get(
f"https://noon-api-gateway.noon.partners/fbpi/v1/fbpi-order/{order_nr}/customer-details/get",
headers={"User-Agent": "MyApp/1.0.0"},
timeout=30,
)
response.raise_for_status()
customer = response.json()
const client = await getAuthenticatedClient();
const orderNr = "NFBO123456789";
const response = await client.get(
`https://noon-api-gateway.noon.partners/fbpi/v1/fbpi-order/${orderNr}/customer-details/get`,
{ headers: { "User-Agent": "MyApp/1.0.0" } }
);
const customer = response.data;
orderNr := "NFBO123456789"
client := getAuthenticatedClient()
url := fmt.Sprintf("https://noon-api-gateway.noon.partners/fbpi/v1/fbpi-order/%s/customer-details/get", orderNr)
req, _ := http.NewRequest(http.MethodGet, url, nil)
req.Header.Set("User-Agent", "MyApp/1.0.0")
client.Timeout = 30 * time.Second
resp, _ := client.Do(req)
defer resp.Body.Close()
var customer map[string]any
json.NewDecoder(resp.Body).Decode(&customer)
Response:
<!-- from: v1GetFbpiOrderCustomerDataResponse -->
{
"first_name": "Ahmed",
"last_name": "Al Rashid",
"city": "Dubai",
"administrative_division": "Dubai"
}
All fields are returned in Latin characters.
You'll know this worked when you receive a response with first_name and city populated for the order.
For the full schema, see GetFbpiOrderCustomerData API Reference.
Recommended Processing Flow
Use this sequence in your webhook worker:
- Receive the webhook event → return HTTP 200 immediately.
- Extract
order_nrfrompayload.order_nr. - Call
GetFbpiOrderwithorder_nr. - Call
GetFbpiOrderCustomerDatawithorder_nr. - Merge the order and customer data and persist them in your system.
- Record processing status and outcome for monitoring and replay.
Testing
Use CreateSandboxOrder (POST /fbpi/v1/sandbox-order/create) to trigger a test webhook event against your warehouse.
- Python
- Node.js
session = get_authenticated_session()
response = session.post(
"https://noon-api-gateway.noon.partners/fbpi/v1/sandbox-order/create",
json={
"warehouse_code": "WH-NOON-001",
"idempotency_key": "wh-test-1",
"items": [
{
"status": "MP_ITEM_STATUS_CONFIRMED"
}
],
"country_code": "ae"
},
headers={"User-Agent": "MyApp/1.0.0"},
timeout=30,
)
response.raise_for_status()
result = response.json()
# result["fbpi_order_nr"] — verify this arrives at your webhook
const client = await getAuthenticatedClient();
const response = await client.post(
"https://noon-api-gateway.noon.partners/fbpi/v1/sandbox-order/create",
{
warehouse_code: "WH-NOON-001",
idempotency_key: "wh-test-1",
items: [{ status: "MP_ITEM_STATUS_CONFIRMED" }],
country_code: "ae"
},
{ headers: { "Content-Type": "application/json", "User-Agent": "MyApp/1.0.0" } }
);
// response.data.fbpi_order_nr — verify this arrives at your webhook
What to observe:
- Your webhook endpoint receives an
FBPI::ORDER_SYNCevent within a few seconds. - The event's
payload.order_nrmatches thefbpi_order_nrreturned byCreateSandboxOrder. GetFbpiOrderreturns a populated response for thatorder_nr.GetFbpiOrderCustomerDatareturns a response withfirst_nameandcity.- The FBPI Orders Dashboard shows a successful webhook delivery and acknowledgment for the sandbox order.
Common failures:
| Symptom | Likely cause | What to do |
|---|---|---|
| Webhook never fires | Warehouse not active or webhook URL misconfigured | Check warehouse status in Seller Lab — see Warehouse Setup |
GetFbpiOrder returns 404 | Order not yet queryable | Retry with exponential backoff |
| Dashboard shows failed delivery | Webhook returned non-2xx or timed out | Check your endpoint logs; ensure it responds within the timeout window |
Next Steps
- Managing Your Orders — process the order after you've retrieved its data
- FBPI Orders Dashboard — monitor webhook delivery attempts and acknowledgment status
- GetFbpiOrder API Reference — full response schema
- GetFbpiOrderCustomerData API Reference — full customer data schema
- CreateSandboxOrder API Reference — full sandbox order schema