Skip to content

Receive orders from a shop

Turn the orders of a shop into orders in BIRP, once each, then confirm or cancel them.

Version v1.1, updated

On this page

You will create in BIRP the orders your shop receives, with their customer, lines, prices and addresses. Each order keeps the id the shop gave it, so importing it twice is refused.

Before you start

  • A key with orders:write and orders:read, and customers:write if you create customers with the order.

  • The products of the order in BIRP, as finished products, linked to your ids or with their SKU.

Note. Orders accept finished products. A line with resale goods answers 422 validation_failed, naming the line.

Steps

Name the customer

Name a customer BIRP already knows in customer, as a reference. Or create it with the order in customer_upsert, which works like the customer upsert of Match and update customers.

customer_upsertJSON
{
  "source": "woocommerce",
  "external_id": "cust-77",
  "match_by": [
    "email"
  ],
  "data": {
    "country_code": "FR",
    "customer_type": "b2b",
    "email": "achats@example.com",
    "name": "Epicerie Exemple SARL"
  }
}

Send the order

POST /v1/orders creates the order as a draft. Send source and external_id, the id the shop gave the order. A second import of the same order then answers 409 external_id_conflict, so it is never created twice.

POST /v1/orders
curl -X POST "https://api.birp.io/v1/orders" \
  -H "Authorization: Bearer $BIRP_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"currency":"EUR","customer":{"external_id":"cust-77","source":"woocommerce"},"expected_at":"2026-09-29T06:00:00Z","external_id":"order-5512","lines":[{"product":{"sku":"FP-BREAD-500"},"quantity":"20","unit_price":"3.20"}],"notes":"Deliver before 7:00","ordered_at":"2026-09-27T08:00:00Z","shipping_address":{"city":"Paris","company":"Epicerie Exemple SARL","country_code":"FR","email":null,"line1":"12 rue des Exemples","line2":null,"name":"Claire Exemple","phone":"+33 0 00 00 00 00","postal_code":"00000","region":null},"source":"woocommerce"}'
  • Each line names a product, a quantity and a unit_price, as decimal strings.

  • Without currency, the base currency of the company applies.

  • shipping_address and billing_address are kept with the order as you send them.

  • Without expected_at, the expected date is the order date.

Change it while it is a draft

PATCH /v1/orders/{id} changes the lines, the currency, the addresses, the expected date and the notes while the order is a draft. The customer and the order date stay as created.

Confirm or cancel

POST /v1/orders/{id}/confirm confirms a draft. POST /v1/orders/{id}/cancel cancels a draft or a confirmed order and needs a reason.

Once BIRP starts producing an order, the API refuses to cancel it: cancel it in BIRP, where the people who produce it decide.

Check the result

GET /v1/orders?source=woocommerce&external_id=order-5512 returns the order with its status and lines. Confirmed orders keep confirmed_at.

What can go wrong

Answer

Cause

Fix

409 external_id_conflict

The order was already imported.

Read it by its external id instead of creating it again.

422 reference_not_found

A product or the customer is not found in the company.

Sync the product or the customer first.

403 insufficient_scope

customer_upsert without customers:write.

Use a key with both scopes, or name an existing customer.

409 invalid_status_transition

The status does not allow the action or the change.

Read current_status, then decide.

  • orders
  • customers
  • references-and-external-ids
  • idempotency