This guide explains how to use QuickBooks Commerce API to integrate with a fulfillment service - a third party warehouse that prepares and ships orders on behalf of a merchant on QuickBooks Commerce. You can use these resources to receive and create fulfillments.
In this guide:Before you start working on a fulfillment integration with QuickBooks Commerce, it's helpful to understand some of the different fulfillment-related resources.
draft
, active
, finalized
, fulfilled
, void
or deleted
.fulfilled
.shipping_address
), ship from address (stock_location_id
), tracking information and an array of fulfillment line items.packed
, fulfilled
, void
or deleted
.packed
by default. After the fulfillment is shipped, its status should be updated to fulfilled
.Each order includes an array of order line items that needs to be fulfilled. Each order line item can be packed and fulfilled separately, depending on how the inventory is packed and managed.
fulfillment.create
webhook to be notified of any new fulfillments to be shipped.order.create
webhook to be notified when a new order is created.POST /orders/[:order_id]/actions/pack
. This will create a fulfillment for all order line items with status packed
.fulfilled
through an API call to: POST /orders/[:order_id]/actions/fulfill
.fulfillment.create
webhook.fulfilled
.fulfillment.create
webhook.To get started, subscribe to the fulfillment.create
webhook to be notified when a fulfillment is created for an order.
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
webhook = gecko.Webhook.build({:address=>"https://mywebsite.com/webhooks", :event=>"fulfillment.create"})
webhook.save
{
"webhook": {
"id": 1,
"created_at": "2018-09-24T11:12:49.244Z",
"updated_at": "2018-09-24T11:12:49.244Z",
"event": "fulfillment.create",
"address": "https://mywebsite.com/webhooks",
"oauth_application_id": 1
}
}
curl -X POST -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/webhooks/ -d '{"webhook":{"address":"https://mywebsite.com/webhooks","event":"fulfillment.create"}'}
{
"webhook": {
"id": 1,
"created_at": "2018-09-24T11:12:49.244Z",
"updated_at": "2018-09-24T11:12:49.244Z",
"event": "fulfillment.create",
"address": "https://mywebsite.com/webhooks",
"oauth_application_id": 1
}
}
If your fulfillment service only handles fulfillment in certain stock locations, you can check the stock_location_id
of the fulfillment to determine if you should ship any variants. You can also refer to the quantity
and variant_id
or variant_sku
fields on the fulfillment line items to determine which and how many items to ship.
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
gecko.Fulfillment.find(1)
{
"fulfillment": {
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-12-02T01:11:25.524Z",
"stock_location_id": 1,
"fulfillment_line_item_ids": [1, 2, 3]
// more fields
}
}
curl -X GET -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/fulfillments/1?include=fulfillment_line_items
{
"fulfillment_line_items": [
{
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-12-02T01:11:25.524Z",
"variant_id": 1,
"variant_sku": "SKU123",
"quantity": 1
// more fields
},
],
"fulfillment": {
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-12-02T01:11:25.524Z",
"stock_location_id": 1,
"fulfillment_line_item_ids": [1],
// more fields
}
}
fulfilled
.After shipping a fulfillment, you can update the status
of the fulfillment to fulfilled
and include information like tracking_company
, tracking_number
and tracking_url
.
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
fulfillment = gecko.Fulfillment.find(1)
fulfillment.attributes = {
status: "fulfilled",
tracking_company: "GeckoShip",
tracking_number: "123TrackMe",
}
fulfillment.save
{
"fulfillment": {
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-12-02T01:11:25.524Z",
"status": "fulfilled",
"tracking_company": "GeckoShip",
"tracking_number": "123TrackMe",
// more fields
}
}
curl -X PUT -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/fulfillments/1 -d '{"fulfillment":{"status":"fulfilled","tracking_company":"GeckoShip","tracking_number":"123TrackMe"}}'
{
"fulfillment_line_items": [
{
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-12-02T01:11:25.524Z",
// more fields
},
],
"fulfillment": {
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-12-02T01:11:25.524Z",
"tracking_company": "GeckoShip",
"tracking_number": "123TrackMe",
"status": "fulfilled",
"stock_location_id": 1,
"fulfillment_line_item_ids": [1],
// more fields
}
}
As a result, a fulfillment service may need to query for order line items and determine the outstanding items to be shipped in upcoming fulfillments.
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
gecko.Order.find(1)
{
"order": {
"id": 1,
"created_at": "2015-11-12T08:06:01.561Z",
"updated_at": "2015-11-12T08:06:01.561Z",
"order_line_item_ids": [
1,
2
]
// more fields
}
curl -X POST -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/orders/1?include=order_line_items
{
"order_line_items": [
// order line item attributes
],
"order": {
"id": 1,
"created_at": "2015-11-12T08:06:01.561Z",
"updated_at": "2015-11-12T08:06:01.561Z",
"order_line_item_ids": [
1,
2
]
// more fields
}
order.create
webhook.order.create
webhook.To get started, subscribe to the order.create
webhook to be notified when a new order comes in.
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
webhook = gecko.Webhook.build({:address=>"https://mywebsite.com/webhooks", :event=>"order.create"})
webhook.save
{
"webhook": {
"id": 1,
"created_at": "2018-09-24T11:12:49.244Z",
"updated_at": "2018-09-24T11:12:49.244Z",
"event": "order.create",
"address": "https://mywebsite.com/webhooks",
"oauth_application_id": 1
}
}
curl -X POST -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/webhooks/ -d '{"webhook":{"address":"https://mywebsite.com/webhooks","event":"order.create"}'}
{
"webhook": {
"id": 1,
"created_at": "2018-09-24T11:12:49.244Z",
"updated_at": "2018-09-24T11:12:49.244Z",
"event": "order.create",
"address": "https://mywebsite.com/webhooks",
"oauth_application_id": 1
}
}
Note: If your fulfillment service only handles fulfillments in certain stock locations, you can check the order's stock_location_id
to determine if you should fulfill it.
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
gecko.Order.find(1)
{
"order": {
"id": 1,
"created_at": "2015-11-12T08:06:01.561Z",
"updated_at": "2015-11-12T08:06:01.561Z",
"stock_location_id": 1,
"order_line_item_ids": [
1,
2
]
// more fields
}
curl -X POST -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/orders/1?include=order_line_items
{
"order_line_items": [
{
"id": 1,
"created_at": "2015-11-12T08:06:01.561Z",
"updated_at": "2015-11-12T08:06:01.561Z",
// more fields
}
],
"order": {
"id": 1,
"created_at": "2015-11-12T08:06:01.561Z",
"updated_at": "2015-11-12T08:06:01.561Z",
"stock_location_id": 1,
"order_line_item_ids": [
1
]
// more fields
}
A fulfillment service can either partially or completely fulfill an order.
To completely fulfill an order, create a fulfillment using POST /orders/[:order_id]/actions/fulfil
. Do note that this will create a fulfillment with status fulfilled
for all unpacked order line items and also update the status of all existing packed
fulfillments to fulfilled
.
To partially fulfill an order, pass in the order_line_item_ids
and quantities to be fulfilled. Do note that this will create a fulfillment with status packed
. After shipping the fulfillment, you can update the status to fulfilled
as seen in Scenario 1 - Step 3.
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
fulfillment = gecko.Fulfillment.build({:order_id=>1, :packed_at=>"Time.now", :billing_address_id=>1, :shipping_address_id=>1, :fulfillment_line_items=>[{:order_line_item_id=>1}, {:order_line_item_id=>2}]})
fulfillment.save
{
"fulfillment": {
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-11-02T01:22:25.524Z",
"order_id": 2,
"shipping_address_id": 1,
"billing_address_id": 1,
"stock_location_id": 1,
"fulfillment_line_item_ids": [
1,
2
]
// more fields
}
}
curl -X POST -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/fulfillments/ -d '{"fulfillment":{"order_id":1,"packed_at":"Time.now","billing_address_id":1,"shipping_address_id":1,"fulfillment_line_items":[{"order_line_item_id":1},{"order_line_item_id":2}]}'}
{
"fulfillment": {
"id": 1,
"created_at": "2015-11-02T01:22:25.524Z",
"updated_at": "2015-11-02T01:22:25.524Z",
"order_id": 2,
"shipping_address_id": 1,
"billing_address_id": 1,
"stock_location_id": 1,
"fulfillment_line_item_ids": [
1,
2
]
// more fields
}
}
stock_location_id
will default to the order stock_location id
unless a stock_location_id
is specified on fulfillment creation.Depending on a merchant's return policy, there may be a need to create a fulfillment return or void an order. You can return an entire order or part of an order.
In the event that your company is handling the return through QuickBooks Commerce API, you can create a fulfillment_return
as shown below:
require 'gecko-ruby'
gecko = Gecko::Client.new(<OAUTH_ID>, <OAUTH_SECRET>)
access_token = OAuth2::AccessToken.new(gecko.oauth_client, <ACCESS_TOKEN>)
gecko.access_token = access_token
fulfillment_return = gecko.FulfillmentReturn.build({:order_id=>1, :fulfillment_return_line_items=>[{:order_line_item_id=>1, :quantity=>1}, {:order_line_item_id=>2, :quantity=>1}]})
fulfillment_return.save
{
"fulfillment_return": {
"id": 1,
"created_at": "2015-11-02T01:22:25.535Z",
"updated_at": "2015-11-02T01:22:25.535Z",
"order_id": 1,
"location_id": 1,
"delivery_type": null,
"exchange_rate": "1.0",
"notes": null,
"received_at": null,
"tracking_company": null,
"tracking_number": null,
"tracking_url": null,
"status": "returning",
"credit_note_number": "CN0001",
"order_number": "SO0001",
"company_id": 1
}
}
curl -X POST -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.tradegecko.com/fulfillment_returns/ -d '{"fulfillment_return":{"order_id":1,"fulfillment_return_line_items":[{"order_line_item_id":1,"quantity":1},{"order_line_item_id":2,"quantity":1}]}'}
{
"fulfillment_return": {
"id": 1,
"created_at": "2015-11-02T01:22:25.535Z",
"updated_at": "2015-11-02T01:22:25.535Z",
"order_id": 1,
"location_id": 1,
"delivery_type": null,
"exchange_rate": "1.0",
"notes": null,
"received_at": null,
"tracking_company": null,
"tracking_number": null,
"tracking_url": null,
"status": "returning",
"credit_note_number": "CN0001",
"order_number": "SO0001",
"company_id": 1
}
}
fulfillment_return.create
webhook to receive notifications.See these additional resources for more information about authorization, webhooks and order actions.
For API feature requests, bug reports and other questions related to API guides, contact support@tradegecko.com.