Marketplaces / Very KornitX Technical Scope / Order Push API

Order Push API

Summary of Changes: (The purpose of this table is to keep traceability and Product team to highlight the things that were changed into the scope, based on comments or discussions)

Version Date Created / Updated Notes
v1.0 04.04.23 Bogomil Pavlov First publish
v1.1 18.05.23 Bogomil Pavlov Mapping Amendments
v1.2 05.06.23 Bogomil Pavlov Oder Payment Transaction id
v1.3 12.06.23 Bogomil Pavlov Mapping Amendments
v1.4 15.06.23 Bogomil Pavlov Mapping Amendments
Including removal of v1.3 in the scope below

The purpose of this document is to describe how Very will create orders in Hemi.

The flow of creating orders is in the opposite way and Very will be creating order directly into our system. Thus we have to build a listener which accept orders in specific format.

”The Order Push API” allows a supplier to configure a dropship URL that will receive order details for any new orders created by retailers.

Order details are sent to the URL via a simple JSON POST request.

Additionally, a X-CustomGateway-Hmac header is also sent as part of the request. This header can be used to verify that the request has originated from Kornit X.

Setup

To receive order pushes, a supplier must enable the "Generic API" supplier integration against the relevant dropshipping account in the Kornit X platform.

Once the integration has been enabled, a push URL defined and changes saved, a HMAC key will be automatically generated.

Verifying the HMAC Header

Whilst optional, this step is highly recommended for security.

For each push request, a HMAC message digest can be calculated using the SHA256 algorithm with the request body as the input and the HMAC key displayed in the Generic API settings page.

The calculated HMAC message digest should match the value of the requests's X-CustomGateway-Hmac header.

If the values do not match then you should reject the push request.

Sample way of doing this:

$hmac = hash_hmac('sha256', file_get_contents('php://stdin'), $key);

if(!hash_equals($hmac, getHeader('X-CustomGateway-Hmac')))
{
    throw new \Exception('HMAC mismatch');
}

Sample payload:

{
  "id": 48292893,
  "company_ref_id": 123456,
  "secondary_company_ref_id": "789012",
  "ref": "BA5081446450F3FE",
  "status": 1,
  "shipping_company": "",
  "shipping_address_1": "123 Test Street",
  "shipping_address_2": "",
  "shipping_address_3": "",
  "shipping_address_4": "Test",
  "shipping_address_5": "",
  "shipping_postcode": "SK10 2XR",
  "shipping_country": "United Kingdom",
  "shipping_country_code": "GB",
  "billing_company": "",
  "billing_address_1": "",
  "billing_address_2": "",
  "billing_address_3": "",
  "billing_address_4": "",
  "billing_address_5": "",
  "billing_postcode": "",
  "billing_country": "United Kingdom",
  "customer_name": "Paul Test",
  "customer_telephone": "",
  "customer_telephone_mobile": "",
  "sale_datetime": "2023-05-02 11:14:12",
  "external_ref": "L281223899999-L8-PH",
  "has_been_completed": false,
  "completion_datetime": "0000-00-00 00:00:00",
  "has_pdf_been_queued": false,
  "has_pdf_been_completed": false,
  "shipping_method": "Next Day",
  "customer_email": "paul.heseltine@kornit.com",
  "shipping_carrier": "DPD",
  "shipping_tracking": "",
  "shipping_note_url": "",
  "payment_trans_id": "",
  "payment_type": "",
  "has_initial_confirmation_email_been_sent": false,
  "has_shipping_confirmation_email_been_sent": false,
  "creation_datetime": "2023-05-02 11:29:02",
  "additional_info": "",
  "has_error": false,
  "error_message": "",
  "required_dispatch_date": "0000-00-00",
  "is_status_callback_pending": false,
  "stock_request_id": 0,
  "status_callback_attempts": 0,
  "status_callback_next_retry": "0000-00-00 00:00:00",
  "consolidate": false,
  "has_been_invoiced": false,
  "billing_customer_name": "",
  "billing_customer_email": "",
  "billing_customer_telephone": "",
  "shipping_price": 6,
  "shipping_price_inc_tax": 0,
  "shipping_tax_rate": 0,
  "is_urgent": false,
  "tag": "",
  "pos_user_id": null,
  "coupon_code": "",
  "currency_code": null,
  "is_free_of_charge": false,
  "status_name": "Received",
  "company_external_ref": "",
  "items": [
    {
      "id": 85632673,
      "sale_vat_rate": 0.2,
      "external_ref": "POS-EF8FE5",
      "ref": "8D2BD93C6450F3FE",
      "order_id": 48292893,
      "sku": "11508",
      "mapped_sku": "11508",
      "description": "Slim Fit White Shirt",
      "colour": "",
      "size": "",
      "quantity": 2,
      "type": 4,
      "print_job_id": 0,
      "print_job_promise_ref": "",
      "external_url": "",
      "external_thumbnail_url": "",
      "status": 1,
      "print_on_demand_ref": "",
      "plain_stock_item_ref": "",
      "license": "",
      "license_percentage": "",
      "unit_sale_price": 69.99,
      "unit_sale_price_inc_tax": 0,
      "unit_cost_price": 12.48,
      "shipping_price": 0,
      "shipping_price_inc_tax": 3,
      "bundle_ref": "",
      "textual_product_id": "11791111",
      "product_variant_id": null,
      "quantity_batched": 0,
      "quantity_dispatched": 0,
      "stock_request_id": null,
      "artwork_barcode": "",
      "quantity_consolidated": 0,
      "product_state_id": null,
      "status_name": "Received",
      "attributes": [],
      "assets": []
    },
    {
      "id": 85632674,
      "sale_vat_rate": 0.2,
      "external_ref": "POS-961B06",
      "ref": "46C958316450F3FE",
      "order_id": 48292893,
      "sku": "11655",
      "mapped_sku": "11655",
      "description": "Tailored Fit White Shirt",
      "colour": "",
      "size": "",
      "quantity": 1,
      "type": 4,
      "print_job_id": 0,
      "print_job_promise_ref": "",
      "external_url": "",
      "external_thumbnail_url": "",
      "status": 1,
      "print_on_demand_ref": "",
      "plain_stock_item_ref": "",
      "license": "",
      "license_percentage": "",
      "unit_sale_price": 59.99,
      "unit_sale_price_inc_tax": 0,
      "unit_cost_price": 10.99,
      "shipping_price": 0,
      "shipping_price_inc_tax": 0,
      "bundle_ref": "",
      "textual_product_id": "11792222",
      "product_variant_id": null,
      "quantity_batched": 0,
      "quantity_dispatched": 0,
      "stock_request_id": null,
      "artwork_barcode": "",
      "quantity_consolidated": 0,
      "product_state_id": null,
      "status_name": "Received",
      "attributes": [],
      "assets": []
    }
  ],
  "pdfs": [
    {
      "id": 32511879,
      "order_id": 48292893,
      "type": 1,
      "url": "https://s3-eu-west-1.amazonaws.com/xxx.pdf",
      "ref": "mjjkzj7fdf6trmwwx0jf",
      "is_outdated": false
    }
  ],
  "shipments": []
}

Mapping: N/A means we do not map this field anywhere in Hemi. Please note not all fields may be pushed from KornitX.

Very Field Hemi Field Comment
id Orders > Marketplace Order ID We want to include validation and return them an error if Orders > Marketplace Order ID already exist in our system.
company_ref_id N/A
secondary_company_ref_id N/A
ref N/A
status N/A
shipping_company Orders > Company Name Under Shipping Details tab
shipping_address_1 Orders > Shipping Street 1 (v1.1)If nothing is populated in shipping_address_1 but have data in shipping_address_2, we want to move it to Orders > Shipping Street 1
shipping_address_2 Orders > Shipping Street 2
shipping_address_3 Orders > Shipping Street 2 If this is populated we want to concatenate it with Orders > Shipping Street 2
shipping_address_4 Orders > Shipping City
shipping_address_5 Orders > Shipping State Province
shipping_postcode Orders > Shipping Postal Code
shipping_country_code Orders > Shipping Country Code ISO 3166-1 alpha-2 country code.
shipping_country Orders > Shipping Country Name
billing_company Orders > Company Name Under Billing Details tab
billing_address_1 Orders > Billing Street 1 (v1.1)If nothing is populated in billing_address_1but have data in billing_address_2, we want to move it to Orders > Billing Street 1
billing_address_2 Orders > Billing Street 2
billing_address_3 Orders > Billing Street 2 If this is populated we want to concatenate it with Orders > Billing Street 2
billing_address_4 Orders > Billing City Name
billing_address_5 Orders > Billing State Province
billing_postcode Orders > Billing Postal Code
billing_country Orders > Billing Country Name
billing_country_code Orders > Billing Country Code
customer_name Orders > Shipping Buyer Name
customer_telephone Orders > Shipping Phone This is used only if we are missing the customer_telephone_mobile
customer_telephone_mobile Orders > Shipping Phone This on is with priority and if we receive both we want to store only this
sale_datetime N/A
external_ref Orders > Selling Manager SalesRecordNumber
has_been_completed N/A
completion_datetime N/A
has_pdf_been_queued N/A
has_pdf_been_completed N/A
shipping_method Orders > Shipping Service
customer_email Orders > Buyer mail
shipping_carrier Orders > Shipping Carrier
shipping_tracking Orders > Shipping Track Number
shipping_note_url Orders > Shipping Tracking URL
payment_trans_id Orders > External Trans ID
payment_type Orders > Order Payment Method
has_initial_confirmation_email_been_sent N/A
has_shipping_confirmation_email_been_sent N/A
creation_datetime Orders > Order Created Time Please note we want to store unix. Format: 2023-05-02 11:29:02
additional_info Orders > Note
has_error N/A
error_message N/A
required_dispatch_date Orders > Ship By Date Please note we want to store unix. Format 2023-12-01
is_status_callback_pending N/A
stock_request_id N/A
status_callback_attempts N/A
status_callback_next_retry N/A
consolidate N/A
has_been_invoiced N/A
billing_customer_name Orders > Billing Name
billing_customer_email N/A
billing_customer_telephone Orders > Billing Phone
shipping_price Orders > Total Shipping Marketplace VAT We want to calculate shipping_price_inc_tax - shipping_price in order to get the correct Total VAT shipping price.
shipping_price_inc_tax Orders > Shipping Service Cost
shipping_tax_rate N/A
is_urgent N/A
tag N/A
pos_user_id N/A
coupon_code Orders > Discount Code
currency_code Orders > Order Currency If missing we want to get it from Account > Exchange Rate Calculator Currency
is_free_of_charge N/A
status_name Orders > Marketplace status
company_external_ref N/A
items
id Product In Order > Item Order Line ID Product In Order > Item Order Line ID
type N/A
sale_vat_rate Product In Order > Marketplace VAT Percent
external_ref N/A
ref Product In Order > Chanel Item ID
order_id N/A
colour Product In Order > Item Variations (v1.1)Fields here should be combined in the specific field type which is Table with two columns
size Product In Order > Item Variations
mapped_sku N/A
sku Product In Order > SKU
description N/A
quantity Product In Order > Quantity
print_job_id N/A
print_job_promise_ref N/A
external_url N/A
external_thumbnail_url N/A
status N/A
print_on_demand_ref N/A
plain_stock_item_ref N/A
license N/A
license_percentage N/A
unit_sale_price Product In Order >Item Price (v1.4) The only price we will receive will be unit_sale_price however we still may receive and orders without unit_sale_price and we want to treat them as completed and set the status as “Ready For Shipping“
unit_sale_price_inc_tax N/A
unit_cost_price Product In Order >Item Original Price
shipping_price Product In Order >Marketplace VAT Item Shipping Cost We want to calculate shipping_price_inc_tax - shipping_price in order to get the VAT for the shipping cost
shipping_price_inc_tax Product In Order >Item Shipping Cost
bundle_ref N/A
textual_product_id N/A
product_variant_id N/A
quantity_batched N/A
quantity_dispatched N/A
stock_request_id N/A
artwork_barcode N/A
quantity_consolidated N/A
product_state_id N/A
status_name Product In Order >Status
attributes N/A
assets N/A
pdfs
id N/A
order_id N/A
type N/A
url Orders Very > Dispatch Note New Field.
ref N/A
is_outdated N/A
shipments N/A

Since their payload is limited we have to make sure any missing information which is not provided by Very and is mandatory for Hemi to be filled.

Hemi Field Comment
Orders > Account Based on the url which we will provide we will know for which account is the actual order.
(v1.1)Orders > Status Every order they are pushing to Hemi will e paid and with status “Ready For Shipping“
Orders > Оrder Тotal Аmount Based on the item prices we need to calculate the total amount
Orders > Оrder Subtotal Аmount Based on the item prices we need to calculate the total amount - shipping cost
Product in Order > Account (v1.1)Based on the sku and the order account we have to map the correct correct Account Id from the order
Product in Order > Seller Based on the sku and the order account we have to map the correct Product Account and get the correct Seller Id
Product in Order > Item Title Based on the sku and the order account we have to map the correct Product Account and get the correct Title
Order Item Line >Line ID For each quantity we have to store additional row as per standard.
Order Payment > Transaction ID (v1.2)Same as Orders >External Trans ID (If empty use Orders > Marketplace Order ID)
Order Payment > Payment Date Same as Orders > Order Created Time
Order Payment > Total Amount Same as Orders > Оrder Тotal Аmount
Order Payment > Type “Payment“
Order Payment > Status “Completed“ all orders we are receiving will be paid

Also the same is the case with the validations and if we receive and order with missing or duplicate:

Hemi Field


Orders > Marketplace Order ID


Product In Order > Item Order Line ID


Orders > External Trans ID


We want to return and error and do not allow to create the order.

If any of the mandatory information as per abstraction is missing we want to set the Orders > Status = Incomplete

<v1.5> We also need to have a grace period of 30 minutes in which we keep the order on ‘Pending’ status

Is this article helpful?
0 0 0