Initiating physical fulfillments

Learn how to use the Fulfillment Orders API to manage the physical fulfillment of an order's products.

When Digital River coordinates the physical fulfillment of an order, you can use the Fulfillment Orders API to manage the process. It allows you to create and retrieve fulfillment orders.

Prior to initiating a fulfillment order, your integration should properly sequences calls in the upstream APIs. You should also keep in mind that most of the data you specify in a create fulfillment order request should be carried over from upstream resources. This ensures that accurate and consistent data is maintained throughout the entire order flow.

Additionally, when important events occur during the lifecycle of a fulfillment order, such as when a shipment takes place or an item is backordered, you can can be notified of them. We also provide you the ability track each shipment in an order.

Sequencing a fulfillment order

Although every integration is unique, you'll typically use a fulfillment order as part of a fairly standard flow.

The following "happy path" assumes that customers have finalized a checkout with an attached payment source, the customer has picked a shipping quote, the selected inventory items either have sufficient inventory or are configured to allow overselling and all the inventory items are reserved. In these cases, you should:

  1. Use the Orders API to submit a POST/orders request that includes the checkout identifier. This prompts Digital River to conduct a fraud review and, depending on the results, create a charge on the payment source.

  2. Wait until you've received an order.accepted event and then pass the relevant upstream data to a POST/fulfillment-orders request. This instructs Digital River to initiate the actual physical delivery of the products.

  3. Wait until you receive a fulfillment_order.shippedevent. The payload of this event informs you which items, and in what quantity, have been shipped to the customer.

  4. Use the data in this event to submit a POST/fulfillments request. This instructs Digital River to capture the appropriate amount of the payment charge.

Creating a fulfillment order

To create a fulfillment order, your integration should first receive an order accepted event. Once you consume this event, you can then define and submit a fulfillment order.

Receiving the order accepted event

Before defining and submitting a fulfillment order, your integration should first receive the order.accepted event. The data.object of this event provides you the upstream order in an accepted state. More specifically, it means that the order has passed fraud review and contains a charge in a capturable state.

Defining and submitting a fulfillment order

When creating a fulfillment order, submit a POST/fulfillment-orders request that provides us currency, customer, shipping address, shipping method, and product data. You can also provide optional data on the locale, and any holds you placed on inventory items. Nearly all of this data should be retrieved from upstream resources.

Currency

The currency in the request should be the same as the value in the upstream Order. This avoids creating downstream invoicing errors, issues with customs, and incorrect tax computations.

Customer information

You have the option of providing the customer's name, email, and phone at the fulfillment order level and within the shipTo hash table.

Attaching a reservation

The reservationId references the hold you may have placed on inventory items included in the order.

When you don't include a reservation identifier in a POST/fulfillment-orders request, Digital River still attempts to allocate the specified inventory items. If we determine inventory levels are too low, what happens at that point depends on whether you allow overselling of the item and whether your channel is set up to accept backorders.

Ship to address

The shipping address values you specify in the shipTo hash table should map exactly to those in the corresponding data structure of the upstream Order.

Shipping choices

When setting the id and signatureRequiredType parameters in the shippingChoice hash table, you should retrieve the unique identifier of the shipping quote your customer selected, along with the signature type enumeration the shipping quote may have returned.

If the upstream Order triggered the landed cost feature, you should set dutiesPaid to true. This notifies the shipping carrier that the customer has already paid the full landed cost and they should invoice you for any duties paid.

Product information

You use the items array to specify your product information. The data you provide comes primarily from upstream resources.

The giftMessage andgiftWrap parameters allow customers to provide the downstream fulfiller a message they want included with the package, and to indicate whether the package should be wrapped, respectively.

Upstream data sent in a POST fulfillment order request

The following table shows how most of the required and optional data sent in a POST/fulfillment-orders request should be retrieved from the upstream Order, Reservation, Shipping Quote, and Inventory Item resources.

Upstream API

Attribute

Global Fulfillment Orders API

Orders

currency

currency

Orders

locale

locale

Orders

createdTime

upstreamOrderTime

Reservations

id

reservationId

Orders

id

upstreamId

Orders

shipTo

shipTo

Shipping Quotes

id

shippingChoice.id

Shipping Quotes

signatureRequiredType

shippingChoice.signatureRequiredType

Orders

items[].id

items[].upstreamId

Inventory Items

id

items[].inventoryItemId

Orders

items[].amount

items[].total

SKUs

name

items[].name

Orders

items[].quantity

items[].quantity

Orders

items[].tax.amount

items[].tax.amount

A fulfillment order

After you submit a POST/fulfillment-orders request, we return a fulfillment order that contains the same data you provided in the request. The object also contains unique identifiers that are needed for downstream processing of the fulfillment order. Additionally, the object returns attributes that inform you of a fulfillment order's state and categorize the status of its line items.

Unique identifiers

We assign a unique identifier to a fulfillment order and each of its line items. You'll need to use the fulfillment order identifier when retrieving the object. You must also supply this identifier, along with the relevant line item identifiers, when both cancelling and returning physical fulfillments.

The fulfillment order life cycle

A fulfillment order has a defined lifecycle at both the order level and line item level. Each stage of that lifecycle is represented by the state attribute.

Order level

The state attribute at the order level indicates where a fulfillment order is in its lifecycle. The values for a successful fulfillment order (i.e., the happy path) are pending > shipped.

(1) When the fulfillment order...

(2) the state transitions to...

is created but not yet partially or fully shipped

pending

partially or fully ships

shipped

is cancelled by you or the customer

cancelled

Line item level

The state attribute at the item level indicates where a line item is in its fulfillment lifecycle. The values for a successfully fulfilled line item (i.e., the happy path) are pending > shipped.

(1) When the line item...

(2) the state transitions to...

has not yet partially or fully shipped

pending

is configured to allow oversell and is awaiting restocking

backordered

partially or fully ships

shipped

is cancelled by you or the customer

cancelled

Product status by category

When you get back a fulfillment order, each object in the items array indicates how many products are pending, backordered, shipped, cancelled, and returned. In aggregate, these values equal the total quantity of the item, which represents the amount originally ordered.

Monitoring and responding to a fulfillment order

Once you have successfully submitted a POST/fulfillment-orders request, you can determine its status by either calling the API directly or listening for webhook events.

Retrieving a fulfillment order

There are two methods in the Fulfillment Orders API that can be used to retrieve fulfillment orders. You can either get a list of fulfillment orders filtered by optional query parameters. Or you can get an individual fulfillment order by sending its unique identifier as a path parameter.

Listening and responding to fulfillment order events

You can also respond to a fulfillment order by listening for the pending, backordered, shipped, and cancelled events it broadcasts. These events are emitted in response to changes in the fulfillment order lifecycle.

For all these events, the data.object contains the identifiers of the associated fulfillment order, upstream order, line items, inventory items, and SKUs.

These events can be subscribed to either programmatically or via Dashboard. By doing so, the event is sent directly to an endpoint on your sever.

Pending events

When Digital River queues a fulfillment order for creation, we create and send a fulfillment_order.pending event. The data.object of this event consists of a fulfillment order in a pending state at the order level.

A fulfillment order in a pending state doesn't necessarily mean that the state of all its line items is also pending. A line item can be in a shipped, backordered or cancelled state while the order is still pending.

Backordered events

Upon receiving a backordered notification from the channel's designated fulfiller, Digital River sends you a fulfillment_order.backordered event. The data.object of this event provides you an array of backordered items.

For each product in the items array, we provide an estimated availableTime (when we can obtain this information from the fulfiller). We also specify how many of this item were ordered in the fulfillment and how many werebackOrdered in this event.

The totalBackordered is the aggregated backOrdered quantity from all the events. When processing duplicate events, you can use this value as a checksum, thereby ensuring your system does not exceed the total ordered amount.

The data we provide in a fulfillment_order.backordered event can be used to notify customers that a product has been backordered. It also allows you to potentially build your integration so customers have the option to either cancel these items or wait for them to be restocked in sufficient quantity.

Fulfillment order backordered event
Fulfillment order backordered event
{
"id": "evt_e381g2ff-7d42-3b05-91d5-e711443r3521",
...
"data": {
"object": {
...
"items": [
{
...
"ordered": 6,
"backordered": 2,
"totalBackordered": 3,
"availableTime": 2020-11-25T20:36:00Z,
...
}
],
...
},
"previousAttributes": {}
},
...
"type": "fulfillment_order.backordered"
}

Shipped events

Once we receive a shipped notification from the channel's designated fulfiller, we send you a fulfillment_order.shipped event. The data.object of this event consists of a shipment that contains a unique identifier. You should persist this identifier so that you can use it later to track shipped items.

Fulfillment order shipped event
Fulfillment order shipped event
{
"id": "evt_d290f1ee-6c54-4b01-90e6-d701748f0851",
...
"data": {
"object": {
"id": "29016544906",
...
"fulfillmentOrderId": "5774321009",
"fulfillmentOrderUpstreamId": "9292981838",
...
"items": [
{
"id": "8760948870",
"fulfillmentOrderItemId": "650398674428",
"fulfillmentOrderItemUpstreamId": "650398674428",
...
"quantity": 1,
...
}
],
...
},
"previousAttributes": {}
},
...
"type": "fulfillment_order.shipped"
}

Every time you receive a fulfillment_order.shipped event, your integration should pass its relevant data in a create fulfillment request. By submitting this request, you're instructing Digital River to capture the relevant part of the payment charge.

Specifically, you'll need to send the shipment identifier and the identifier of each shipment item. You're also required to pass the upstream fulfillment order identifier, and, for each of the shipped items identified in the event, you should send an upstream fulfillment order item identifier and its shipped quantity.

fulfillment_order.shipped event

POST/fulfillments

data.object.id

shipmentId

items[].id

items[].shipmentItemId

fulfillmentOrderUpstreamId

orderId

items[].fulfillmentOrderItemUpstreamId

items[].itemId

items[].quantity

items[].quantity

Cancelled events

Whenever any part of a fulfillment order is cancelled, we create and send a fulfillment_order.cancelled event. The data.object of this event consists of a fulfillment order in a cancelled state at both the order level and the item level.

A fulfillment order in a cancelled state means that all of its line items are also cancelled.

When you receive this fulfillment_order.cancelled event, you should pass its upstreamId and, for each of the cancelled items, theitems[].upstreamId and items[].cancelled quantity to aPOST/fulfillments request in the Fulfillments API.

By submitting this request, you're telling Digital River to cancel the relevant parts of the payment charge.

fulfillment_order.cancelled event

POST/fulfillments

upstreamId

orderId

items[].upstreamId

items[].itemId

items[].cancelled

items[].cancelQuantity

Tracking a shipment

The products in a fulfillment order can be delivered to the end customer in one or more shipments. Each of these shipments is represented by the Shipment resource.

You can use the unique shipment identifier you receive in a shipped event to submit queries that return a shipment's contents and track its progress.

Querying the Shipments API

There are two methods for querying the Shipments API. You can either retrieve an individual shipment by sending its unique identifier as a path parameter in a GET/shipments/{id} request. Or you can submit a GET/shipments request to retrieve a list of shipments and use optional query parameters to filter the results.

Determining the contents of a shipment

The items array returns each uniquely identified shipment item and the quantity shipped. All the relevant upstream identifiers of the item are also included.

Additionally, when the shipped item is a smartphone or cellphone, the downstream fulfiller may pass back to you unitAttributesthat help identify and track the device. These attributes consist of a serial, IMEI, or SIM card number

Monitoring the progress of a shipment

A shipment provides you numerous data points that you can use to track its progress. For the entire shipment, we provide you a trackingUrl where the customer can enter the trackingNumber provided by the trackingCompany. At the shipment item level, we also give you a trackingNumber and trackingUrl to monitor the progress of specific products within the fulfillment order.