Place a click-and-collect order
The COLLECTION variant of order ingestion. Instead of a delivery address, the order carries a customer collection address, the store or pickup point where the customer will collect the parcel. Carriyo's allocation engine uses that address as the reference point and allocates the fulfillment order to a fulfillment location whose coverage includes it. When the collection point is itself a fulfillment location, as in this recipe, Carriyo allocates the order to the store and no shipment is needed.
This is a single-endpoint recipe. The downstream Customer collection entity tracks the in-store handover and OTP verification. The Fulfillment App creates it at fulfillment time, not at order create.
Scenario
A customer in London is buying a single pair of wireless earbuds
for £79.99 and wants to collect them from the Acme Marylebone
store the same evening. You send the order to Carriyo with
delivery_method set to COLLECTION and a
customer_collection_address pointing to the store. The store is
set up as both a collection point and a fulfillment location, so
Carriyo produces a single fulfillment order allocated to it.
Prerequisites
- API credentials: see Getting started for the one-time setup.
- A collection point configured for the merchant: a location with the customer collection flag. For local collection, as here, the same location is also a fulfillment location whose coverage includes its own address.
- Automatic allocation enabled in the tenant's order management
settings (
enable_automatic_order_allocation). It is off until those settings are created. Without it, the order is created inopenand its fulfillment order carries afulfillment_location_missingerror until you allocate it.
Create the order
curl -X POST 'https://api.carriyo.com/orders' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'tenant-id: YOUR_TENANT_ID' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"merchant": "ACME",
"partner_order_reference": "YOUR_ORDER_REF",
"delivery_method": "COLLECTION",
"order_date": "2026-05-10T13:42:00.000Z",
"sales_channel": "web",
"payment": {
"currency": "GBP",
"order_total": 79.99
},
"customer": {
"contact_name": "Oliver Bennett",
"contact_email": "oliver.bennett@example.co.uk",
"contact_phone": "+44 7700 900123"
},
"billing_address": {
"contact_name": "Oliver Bennett",
"contact_email": "oliver.bennett@example.co.uk",
"contact_phone": "+44 7700 900123",
"address1": "45 Gloucester Place",
"address2": "Marylebone",
"city": "London",
"country": "GB",
"postcode": "W1U 8HU"
},
"customer_collection_address": {
"partner_location_code": "STORE-UK-LON-MARYLEBONE"
},
"line_items": [
{
"sku": "SKU-EAR-003",
"description": "Wireless Earbuds",
"quantity": 1,
"unit_price": 79.99
}
]
}'
The response is the created order, abridged here, with a single fulfillment order allocated to the store:
{
"tenant": "your-tenant",
"order_id": "OMP1B9C8D3EAYZ",
"merchant": "ACME",
"partner_order_reference": "YOUR_ORDER_REF",
"order_date": "2026-05-10T13:42:00.000Z",
"sales_channel": "web",
"status": "allocated",
"payment": {
"currency": "GBP",
"order_total": 79.99
},
"customer": {
"contact_name": "Oliver Bennett",
"contact_email": "oliver.bennett@example.co.uk",
"contact_phone": "+44 7700 900123"
},
"line_items": [
{
"id": "Q3R7T",
"sku": "SKU-EAR-003",
"product_ref": "SKU-EAR-003",
"product_id": "PDTHDMCY4YN4Z7L0Q",
"quantity": 1,
"unit_price": 79.99
}
],
"fulfillment_orders": [
{
"fulfillment_order_id": "FOMP1B9C8VKGNHY",
"fulfillment_location": {
"partner_location_id": "ACCOUNT_a1b2c3d4-store-marylebone",
"partner_location_code": "STORE-UK-LON-MARYLEBONE",
"partner_location_name": "Acme Marylebone Store"
},
"status": "allocated",
"delivery_method": "COLLECTION",
"customer_collection_address": {
"partner_location_id": "ACCOUNT_a1b2c3d4-store-marylebone",
"partner_location_code": "STORE-UK-LON-MARYLEBONE",
"partner_location_name": "Acme Marylebone Store",
"contact_name": "Acme Marylebone Store",
"address1": "120 Marylebone High Street",
"city": "London",
"postcode": "W1U 4SD",
"country": "GB"
},
"line_items": [
{ "id": "Q3R7T", "quantity": 1, "status": "allocated" }
],
"creation_date": "2026-05-10T13:42:01.205Z"
}
],
"creation_date": "2026-05-10T13:42:01.000Z"
}
What just happened
- The order was accepted and immediately moved to
allocated. - Carriyo resolved the line item to the catalog product (
product_idis Carriyo's own id,product_refyour reference). It allocated the item to the Marylebone store because the store is a fulfillment location whose coverage includes the collection address. With inventory management enabled the store also needs stock for the SKU. - The FO carries the
customer_collection_addressyou submitted, enriched with the store's full address andpartner_location_id; downstream events (notifications, OTP send) use it. - No shipment is created in this scenario: the fulfillment location is the collection point, so the parcel is already there. This is local collection.
For the remote collection variant, where stock is held at a warehouse and a shipment carries it to the collection point, see Fulfillment orders → what a fulfillment order produces.
After this call
The customer collection entity (which tracks the in-store
handover, OTP verification, and expiry) isn't created
synchronously. The Fulfillment App creates it when packing completes,
and it appears in open status. From that point the lifecycle is:
- The collection is created in
openwhen the FO is fulfilled. - Staff confirms the parcel is at the collection counter and the
collection moves to
ready_to_collect. - Carriyo sends the OTP to the customer's email.
- The customer presents the OTP; staff verifies; the collection moves to
collected. - The line item closes, the FO closes, and the order auto-closes.
The full lifecycle, OTP rules, and auto-expiry behavior are in Customer collection.
Pitfalls
customer_collection_addressshould be provided for COLLECTION orders. If omitted, the order is still created but no customer collection entity is created downstream. Sendingdelivery_addresson a COLLECTION order is ignored.- Allocation follows fulfillment coverage, not the collection flag. If the collection point is not a fulfillment location, the engine allocates to another location whose zone or radius covers the collection address, and that location ships the parcel to the store (remote collection).
- Identify products by
skuorproduct_ref.product_idis Carriyo's own product id; the response fills it in from the catalog. Your SKU inproduct_idmatches nothing. - Pass the location by
partner_location_code(orpartner_location_id) rather than by full address. Carriyo resolves the code to a location, enriches the response with the full address, and populatespartner_location_idfor you. partner_order_referenceis the dedupe key. Re-sending the same value returns an error rather than upserting.- The collection point must be a collection-capable location.
Each location carries a
collection_locationflag (set in the Dashboard); only locations with this flag enabled can be used as a customer collection point.