Sales Channel Guide

    Use TradeGecko APIs and webhooks to build sales channel integrations, allowing merchants to import orders and products from online stores or marketplaces and to sell anywhere and everywhere.

    In this guide:

    Sales Channel Resources

    Before you start working on a sales channel integration with TradeGecko, it’s helpful to understand some of the different sales channel related resources.

    • Sales Order: Contains information about a sales order, its associated order line items and fulfillments. Order line items contain information such as variants and tax types
      • An order in TradeGecko can have 1 of 6 statuses: draft, active, finalized, fulfilled, void or deleted.
    • Fulfillment: Represents a shipment of one or more items in a sales order. It includes the line item that the fulfillment applies to, its tracking information and the location of the fulfillment
      • A fulfillment object in TradeGecko can have 1 of 4 statuses: packed, fulfilled, void or deleted.
    • Company: Represents a merchant's supplier or customer created and stored in the TradeGecko Relationships section
    • Address: Represents a physical address associated with a merchant's company

    Authorising Your Sales Channel Integration

    TradeGecko uses OAuth to authorize third party integrations. As part of the OAuth flow, TradeGecko obtains the user’s authorization and issues an access token that your sales channel can use to interact with the API. To find out more, refer to our OAuth docs.

    Publishing Products from TradeGecko to a Sales Channel

    • Step 1: Get a product, its variants and their inventory levels.
    • Step 2 (optional): Receive an alert whenever a merchant creates a new product or variant in TradeGecko
    • Step 3: Receive an alert whenever the stock level for a variant is updated in TradeGecko

    Step 1: Get a product, its variants and their inventory levels.

      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.Product.find(1)
    
      {
        "product": {
          "id": 1,
          "created_at": "2015-11-02T01:22:24.817Z",
          "updated_at": "2015-11-02T01:22:24.817Z",
          "variant_ids": [
            1,
            2
          ],
          // more fields
        }
      }
    
      curl -X GET -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
      https://api.tradegecko.com/products/1?include=variants
    
      {
        "variants": [
          {
            "id": 1,
            "created_at": "2015-11-02T01:22:24.817Z",
            "updated_at": "2015-11-02T01:22:24.817Z",
            "locations": [
              {
                "location_id": 1,
                "stock_on_hand": "10",
                "committed": "3",
                "incoming": null,
                "bin_location": null,
                "reorder_point": null
              }
            ]
            // more fields
          }
        ],
        "product": {
          "id": 1,
          "created_at": "2015-11-02T01:22:24.817Z",
          "updated_at": "2015-11-02T01:22:24.817Z",
          "variant_ids": [
            1
          ],
          // more fields
        }
      }
    

    Tips:

    • As TradeGecko does not enforce variant SKU uniqueness, you are advised to use the TradeGecko variant id instead of SKU to create any mapping between TradeGecko and sales channel variants. This will ensure that incoming sales orders are linked to the correct TradeGecko variants.

    Notes:

    • For each variant, we return locations, an array of per-warehouse inventory data about the current variant.
    • When a variant's manage_stock attribute is set to false, the variant's stock level will not be tracked by TradeGecko.
    • When a variant's keep_selling attribute is set to true, the variant can continue to be sold even when the stock level is zero or negative.
    • If the variant has a max_online value defined, the sales channel should not display stock levels higher than this value.
    • In TradeGecko, images belong to products. Each image can be assigned to multiple variants of the product. Use the image endpoint to retrieve variant images.
    • Variants may have different prices across price lists. To determine the variant prices to be displayed on the sales channel, you may need to retrieve the merchant's price lists by making a GET request to the price lists endpoint (GET /price_lists). Some relevant price lists include: 

    Step 2 (optional): Receive an alert whenever a merchant creates a new product or variant in TradeGecko

    Subscribe to the product.create and variant.create webhooks to be notified when a new product or variant is created by the merchant.

    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=>"product.create")
    webhook.save

    { "webhook": { "id": 1, "created_at": "2018-09-24T11:12:49.244Z", "updated_at": "2018-09-24T11:12:49.244Z", "event": "product.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":"product.create"}}'

    { "webhook": { "id": 1, "created_at": "2018-09-24T11:12:49.244Z", "updated_at": "2018-09-24T11:12:49.244Z", "event": "product.create", "address": "https://mywebsite.com/webhooks", "oauth_application_id": 1 } }

    Step 3: Receive an alert whenever the stock level for a variant is updated in TradeGecko

    Subscribe to the variant.stock_level_update webhook to be notified when the stock level for a variant is updated in TradeGecko.

    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=>"variant.stock_level_update")
    webhook.save

    { "webhook": { "id": 1, "created_at": "2018-09-24T11:12:49.244Z", "updated_at": "2018-09-24T11:12:49.244Z", "event": "variant.stock_level_update", "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":"variant.stock_level_update"}}'

    { "webhook": { "id": 1, "created_at": "2018-09-24T11:12:49.244Z", "updated_at": "2018-09-24T11:12:49.244Z", "event": "variant.stock_level_update", "address": "https://mywebsite.com/webhooks", "oauth_application_id": 1 } }

    Importing Orders from a Sales Channel to TradeGecko

    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.

    • Step 1: Create a sales order.
    • Step 2 (optional): Invoice and mark the sales order as paid.
    • Step 3 (optional): Fulfill a sales order.
    • Step 4 (optional): Cancel a sales order.

    Step 1: Create a sales order.

    For an existing customer with existing addresses, populate the company_id attribute with the customer's TradeGecko id, and the shipping_address_id and billing_address_id attributes with appropriate TradeGecko address ids. Do note that the billing_address_id defaults to the shipping_address_id if it is not provided.

      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
      order = gecko.Order.build({:company_id=>1, :issued_at=>"Time.now", :billing_address_id=>1, :shipping_address_id=>1, :order_line_items=>[{:variant_id=>123, :quantity=>2}, {:variant_id=>456, :quantity=>5}]})
      order.save
    
      {
        "order": {
          "id": 1,
          "created_at": "2015-11-02T01:22:25.524Z",
          "updated_at": "2015-11-02T01:22:25.524Z",
          "shipping_address_id": 1,
          "billing_address_id": 1,
          "company_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/ -d '{"order":{"company_id":1,"issued_at":"Time.now","billing_address_id":1,"shipping_address_id":1,"order_line_items":[{"variant_id":123,"quantity":2},{"variant_id":456,"quantity":5}]}'}
    
      {
        "order": {
          "id": 1,
          "created_at": "2015-11-02T01:22:25.524Z",
          "updated_at": "2015-11-02T01:22:25.524Z",
          "shipping_address_id": 1,
          "billing_address_id": 1,
          "company_id": 1,
          "order_line_item_ids": [
            1,
            2
          ]
          // more fields
        }
      }
    

    For an existing customer with a new address, you can embed the address when creating a sales order as seen below. Alternatively, you can manually create a new address using the address endpoint.

      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
      order = gecko.Order.build({:company_id=>1, :issued_at=>"Time.now", :shipping_address_id=>1, :order_line_items=>[{:variant_id=>123, :quantity=>2}, {:variant_id=>456, :quantity=>5}]})
      order.shipping_address.build({address1=>"121 Street", :label=>"my company label", :company_id=>1})
      order.save
    
      {
        "order": {
          "id": 1,
          "created_at": "2015-11-02T01:22:25.524Z",
          "updated_at": "2015-11-02T01:22:25.524Z",
          "shipping_address_id": 2,
          "billing_address_id": 1,
          "company_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/ -d '{"order":{"company_id":1,"issued_at":"Time.now","shipping_address_id":1,"order_line_items":[{"variant_id":123,"quantity":2},{"variant_id":456,"quantity":5}],"billing_address":{"address1":"121 Street","label":"my company label","company_id":1}}'}
    
      {
        "order": {
          "id": 1,
          "created_at": "2015-11-02T01:22:25.524Z",
          "updated_at": "2015-11-02T01:22:25.524Z",
          "shipping_address_id": 1,
          "billing_address_id": 1,
          "company_id": 1,
          "order_line_item_ids": [
            1,
            2
          ]
          // more fields
        }
      }
    

    For a new customer, you can embed the the company and shipping address when creating a sales order as seen below. Alternatively, you can manually create a new company and a new address.

      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
      order = gecko.Order.build({:issued_at=>"Time.now", :order_line_items=>[{:variant_id=>123, :quantity=>2}, {:variant_id=>456, :quantity=>5}]})
      order.company.build({:name=>"121 Street", :company_type=>"consumer"})
      order.shipping_address.build({address1=>"121 Street", :label=>"my company label"})
      order.save
    
      {
        "order": {
          "id": 1,
          "created_at": "2015-11-02T01:22:25.524Z",
          "updated_at": "2015-11-02T01:22:25.524Z",
          "shipping_address_id": 2,
          "billing_address_id": 1,
          "company_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 -d '{"order":{"issued_at":"2018-06-01","order_line_items":[{"variant_id":2,"quantity":2},{"variant_id":1,"quantity":5}],"shipping_address":{"label":"Office","address1":"123 TG Street"},"company":{"name":"TG Company","company_type":"consumer"}}}'
    
      {
        "order": {
          "id": 1,
          "created_at": "2015-11-02T01:22:25.524Z",
          "updated_at": "2015-11-02T01:22:25.524Z",
          "shipping_address_id": 1,
          "billing_address_id": 1,
          "company_id": 1,
          "order_line_item_ids": [
            1,
            2
          ]
          // more fields
        }
      }
    

    Step 2 (optional): Invoice and mark the sales order as paid.

    Create an invoice for a sales order by sending an API call to POST /orders/[:order_id]/actions/invoice. This will create an invoice for the sales order. Once the customer has paid for the sales order, mark the sales order as paid by sending an API call to POST /orders/[:order_id]/actions/pay.

    For orders which are paid by credit card, you can send an API call to POST /orders/[:order_id]/actions/pay to both invoice and mark the sales order as paid in one step.

    Step 3 (optional): Fulfill a sales order.

    Fulfill a sales order by sending an API call to POST /orders/[:order_id]/actions/pack. This creates a fulfillment object with status packed and fires a fulfillment.create webhook. Once the fulfillment has been shipped, send an API call to POST /orders/[:order_id]/actions/fulfil which updates the fulfillment object to status fulfilled.

    Learn more about managing the fulfillment process in TradeGecko here.

    Step 4 (optional): Cancel a sales order.

    To cancel a sales order, send an API call to POST /orders/[:order_id]/actions/void.

    Notes

    • If you want to add additional information to a sales order such as special requests for customers or shipping information, you can set the freeform attribute to true and create or update an order line item with these information.
    • When you create a sales order with a variant that cannot be matched to an existing variant in TradeGecko, either by TradeGecko id or SKU, you will need to create the variant in TradeGecko before re-importing the sales order.
    • If you want to specify a currency when creating a sales order, pass in the currency_iso when creating or updating a sales order and TradeGecko would find a matching currency. However, if the currency matching fails, you will need to create the currency first. You can also cache the currencies and check if a particular currency exists before creating a new sales order.

    Handling Returns

    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 TradeGecko 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
        }
      }
    

    Tips:

    • If fulfillment return creation is handled by the merchant, you can subscribe to the fulfillment_return.create webhook to receive notifications.

    Notes:

    • You cannot delete a fulfillment if there are any associated fulfillment returns.
    • If a merchant is integrated with an accounting platform on TradeGecko, creating a fulfillment return would create a credit note on the accounting platform.
    • Refunds are currently not supported. If you need an endpoint for the refund process, let us know here.
    • You can void an order via the order's void endpoint.

    Additional Resources

    See these additional resources for more information about authorization, webhooks and order actions.

    Support

    For API feature requests, bug reports and other questions related to API guides, contact support@tradegecko.com.

    Got Feedback? We want to hear from you!

    Give Feedback