Fulfillment providers

Ship the orders a store assigns to your app and report tracking back.

A fulfillment provider ships orders for a store, for example as a warehouse or a shipping aggregator. The merchant assigns your app to one or more locations; each order those locations fulfil reaches your app as a fulfillment order. Your app ships it, then creates the fulfillment, records tracking events and cancels through the Store API. Tringify doesn't call your app directly for fulfillment.

Declare it#

json
"store_scopes": ["read_orders", "write_orders"],
"data_subscribed_events": ["fulfillment_orders/create"],
"webhook_url": "https://example.app/webhooks",
"providers": [
  {
    "service_type": "fulfillment",
    "protocol_version": "1",
    "operations": ["list_assigned_orders", "create_fulfillment", "record_fulfillment_event", "cancel_fulfillment"],
    "endpoints": {},
    "supports_test_mode": false
  }
]

All four operations are required, with no endpoints. Merchants can assign your app only when the release they installed has this declaration, both scopes, a webhook URL, and a subscription to fulfillment_orders/create.

How a store uses it#

In Store Admin, under Settings → Fulfillment, the merchant chooses a provider for each location. New fulfillment orders at that location go to your app; existing ones keep the provider they had.

Ship an order#

  1. fulfillment_orders/create arrives for each new fulfillment order assigned to your app. You can also list them with GET /fulfillment-orders, filtered by location and status.

  2. Read the order for its items, address and packages with GET /orders/{id}.

  3. When you ship, create a fulfillment under that fulfillment order with the items, carrier, tracking number and tracking URL. Once the order has been edited, send order_version so you never ship contents you haven't seen.

  4. As the carrier reports progress, record fulfillment events with a stable source_event_id.

  5. If a shipment won't go ahead, cancel the fulfillment.

Your app can see and act on only the fulfillment orders assigned to it. Use display_id, such as #1042-1, on labels and in your dashboard.

Tracking events#

event_type is one of: shipment_created, label_created, pickup_scheduled, pickup_rescheduled, pickup_attempted, pickup_failed, picked_up, in_transit, arrived_at_destination, out_for_delivery, delivery_attempted, delivery_failed, delivered, return_started, return_in_transit, return_arrived, return_out_for_delivery, returned, shipment_cancelled, shipment_failed, shipment_lost, shipment_damaged, shipment_destroyed, shipment_misrouted, shipment_untraceable or exception. Events such as picked_up, delivered and returned move the fulfillment's status; the shopper sees them on their order's tracking page.

Recording the same event again with the same source_event_id is accepted as a duplicate. Reusing a source_event_id with different content is refused with 409, so derive it from everything in the event that can change.

Personalized items#

If an item has files attached by another app, such as print artwork, fetch them with GET …/items/{itemId}/artifacts. Download links last five minutes.

Test#

Orders on development stores are test orders and are never sent to fulfillment providers. To test end to end, use a live store you control and cancel the test order afterwards.