Kornit X Platform APIs
Overview
This document describes some of the APIs that the Kornit X platform exposes.
Which APIs you might be interested in depend on whether you are a Sales Channel or a Fulfiller.
Please select from the left hand side.
Our IP Range
We no longer publish our IP range and are unable to offer static IP addresses for incoming (from you to the platform) requests.
However in certain circumstances we may be able to ensure that outgoing (from the platform to you) are sent from static IPs.
For Sales Channels
Introduction
This guide covers how to integrate your website into the Kornit X platform.
The guide is split into two key sections.
Smartlink
The Smartlink guide covers how to integrate personalisation apps into your website.
You might not need to follow this part depending on your requirements.
Order-iT
The Order-iT guide covers how you can send orders to Kornit X's Sales Module, from where the orders will be routed to the correct fulfiller.
You will definitely need to follow this part.
Virtual Product Creator
The Virtual Product Creator (VPC) guide shows how you can embed Kornit X's VPC tool into your website. The VPC allows your end users to create their own sellable product designs within the platform without ever leaving your site.
You might not need to follow this part depending on your requirements.
Before Starting
Before starting either section, you will need the following information:
- A unique company reference ID.
- An alphanumeric API key.
Both will be provided to you by Kornit X. Please contact us for more details.
The VPC tool has additional requirements that are documented in the VPC section.
Note on Code Samples
The shell code samples to the right assume that you have access to the curl
command line tool.
Smartlink
Kornit X's smartlink apps are provided in the form of a URL which can be embedded via an iframe into your website.
Different apps layouts exist and you may require different URL parameters depending on your use case.
The below URL is a bare bones example of our standard offering:
https://g3d-app.com/s/app/acp3_2/en_GB/default.html#p=1007644&r=2d-canvas&d=COMPANYREFID
The URL can be broken down into a few key parts:
Part | Description |
---|---|
acp3_2 |
The app that you would like to use |
en_GB |
The app locale |
default |
The app configuration |
p=1007644 |
The ID of the product to load |
r=2d-canvas |
The renderer to use. Typically this would either be 2d-canvas for 2D products or webgl for 3D products. multi can be used to load both renderers however doing so may slightly reduce loading speeds |
d |
Your unique company reference ID |
Adding to Cart
<!DOCTYPE html>
<html>
<body>
<iframe style="border: 1px solid red; width: 100%; height: 50px;" src="" id="app"></iframe>
<script>
let iframeOrigin = "https://g3d-app.com";
let iframeUrl = iframeOrigin + "/s/app/acp3_2/en_GB/default.html#p=1007644&r=2d-canvas&d=COMPANYREFID&a2c=postMessage";
let meo = location.origin;
let mei = Math.random().toString(16).substr(2);
window.addEventListener("message", e => {
if(e.origin == iframeOrigin && e.data.id == mei) {
switch(e.data.name) {
case 'ADD_TO_CART_CALLBACK':
var printJobRef = e.data.body.items[0].ref;
console.log(printJobRef);
break;
}
}
});
let iframe = document.getElementById('app');
iframe.src = iframeUrl + "&meo=" + meo + "&mei=" + mei;
</script>
</body>
</html>
When a user clicks on an "Add to Cart" button within a personalisation app, the app will create a "print job" which represents the user's design.
Subsequently, the app will then use the postMessage API to send an ADD_TO_CART_CALLBACK
event to the parent window.
You will need to add a JavaScript message handler to the parent window that listens for the ADD_TO_CART_CALLBACK
event. The handler should add the item to the user's shopping cart and store the value of the printJobRef
field.
For the postMessage
API to function, 3 Smartlink iframe URL parameters are required.
Name | Description |
---|---|
meo |
The origin of the parent window (i.e https://myshop.com ) |
mei |
A random string. |
a2c |
Should always be set to postMessage |
The meo
and mei
URL parameters are used to ensure that the parent window
only acts on messages from the correct iframe instance. The app
will not send messages if either meo
and mei
are not specified. For security
reasons it is also important to ensure that the message is from the g3d-app.com
origin.
The event's data contains a separate item for each print job that was created. Usually, each item would be added to the cart separately however you may wish to consolidate them depending on your exact use case.
Each item
element of the data
property contains the below fields.
Name | Type | Description |
---|---|---|
ref |
string | The unique reference code for the created print job. |
sku |
string | The product's SKU. This should only be needed if the smartlink contains a product selector. In single product mode, your event handler should already know which product to add to cart. |
thumbnails |
array | A collection of thumbnails for different views of the product (including the user's design) |
Restoring a User's Design
If you wish to allow the user to edit their design later on, it can be loaded
again by passing the value of printJobRef
back to the personalisation app
via the pj
(print job) URL parameter.
For example:
https://g3d-app.com/s/app/acp3_2/en_GB/default.html#p=1007644&r=2d-canvas&d=COMPANYREFID&a2c=postMessage&meo=...&mei=...&pj=CF921CF10F59B3A258
When the user clicks "Add to Cart" again in the app, the ADD_TO_CART_CALLBACK
event will be called
as normal but with a new value for printJobRef
.
Saving
A user can save their design, allowing them to reload it at a later date. You need to provide a callback URL which the user is redirected to after saving. The callback URL allows you to record the information needed to reload the user's design.
The following URL enables the save button:
https://g3d-app.com/s/app/acp3_2/en_GB/mt217h0kr51b1wh.html#p=1007644&r=2d-canvas&d=COMPANYREFID&save=https://example.com/save-callback
Handling The Callback
Once the user has clicked save, the app will make a application/x-www-form-urlencoded
form POST to your callback URL.
The POST will include a data
field, the value of which is a JSON encoded object.
{
...,
"created_from": "https://g3d-app.com/s/app/acp3_2/en_GB/mt217h0kr51b1wh.html#p=1007644&r=2d-canvas&d=COMPANYREFID&save=https://example.com/save-callback",
"ref": "44EEEA752F59C3A3B1",
"thumbnails": [
{
"name": "thumbnail",
"url": "https://g3d-app.com/u/product-state/44/EE/EA/75/2F/59/C3/A3/B1/thumbnails/thumbnail.png",
"description": ""
},
{
"name": "thumbnail_60",
"url": "https://g3d-app.com/u/product-state/44/EE/EA/75/2F/59/C3/A3/B1/thumbnails/thumbnail_60.png",
"description": ""
}
],
}
The object will contain many fields, the most important of which are:
Name | Type | Description |
---|---|---|
created_from |
string | The original app URL |
ref |
string | A unique reference code needed to reload the user's design |
thumbnails |
array | A collection of thumbnails for the user's design which you might like to display somewhere |
Reloading The Saved Design
The user's design can subsequently be loaded by taking the value of the created_from
field and appending &ps=
and the value of the ref
field. For example:
https://g3d-app.com/s/app/acp3_2/en_GB/mt217h0kr51b1wh.html#p=1007644&r=2d-canvas&d=COMPANYREFID&save=https://example.com/save-callback&ps=44EEEA752F59C3A3B1
Pricing
postMessage API
In addition to the ADD_TO_CART_CALLBACK
event, Smartlinks also emit other events.
IFRAME_RESIZE
window.addEventListener("message", e => {
if(e.origin == iframeOrigin && e.data.id == mei) {
switch(e.data.name) {
case 'IFRAME_RESIZE':
iframe.style.height = e.data.body.height + "px";
break;
}
}
});
The IFRAME_RESIZE
event can be used to automatically resize the iframe on your
site so that all content fits within it without the need for scroll bars within
the iframe.
Order-iT
The Order-iT API has a single endpoint:
https://api-sl-2-2.custom-gateway.net/order
Rate Limiting
Requests to the API are rate limited to 1000 requests per hour and 10000 requests per day.
A 400
HTTP status code will be returned in the event of the limit being exceeded,
please check the error code table for more details.
If you need this limit to be increased on a per account basis, please contact us.
IP Restrictions
For additional security, an IP white list can be enabled for your company reference ID.
Any requests made using your company reference ID and API key from an IP address that isn't white listed will be rejected.
Please contact us to set up IP restrictions, quoting the IP addresses that you will be sending requests from.
Migrating from 2.1
This document refers to the 2.2 version of the API.
The endpoints for version 2.1 are https://api-sl-2-1.custom-gateway.net/order/
or https://my.gateway3d.com/acp/api/sl/2.1
.
Version 2.2 is mostly backwards compatible with 2.1 however there are some key differences:
The authentication method is different, your API key and company reference ID must now be supplied via a HTTP header.
You no longer need to split orders yourself if a multi line order uses different suppliers, the API will split it for you.
Automatic order splitting means that a POST request to the order creation end point will result in an array of orders rather than a single individual order.
Automatic order splitting also requires that your account and available products have been correctly configured in the Catalog module. Please contact us to ensure that this is the case.
Data validation is now much more rigorous.
Authentication
curl "https://api-sl-2-2.custom-gateway.net/order"
-H "Authorization: Basic COMPANYREFID:APIKEY"
Make sure to replace
COMPANYREFID
andAPIKEY
with your company reference ID and API key respectively.If authentication fails, the following JSON response body will be returned, along with a 400 HTTP status code:
{
"error": {
"message": "Authentication failed",
"code": 50000
}
}
To authenticate against the API, include the Authorization
HTTP header
with every request.
For example,
Authorization: Basic COMPANYREFID:APIKEY
Submitting an Order
curl https://api-sl-2-2.custom-gateway.net/order\
-H "Content-Type: application/json"\
-H "Authorization: Basic COMPANYREFID:APIKEY"\
-d'{
"external_ref": "TEST001",
"sale_datetime": "2017-01-01 12:00:43",
"shipping_company": "Kornit X."
"shipping_address_1": "Pinewood Court",
"shipping_postcode": "SK10 2XR",
"shipping_country_code": "GB",
"items": [
{
"external_ref": "ITEM001",
"quantity": 1,
"type": 2,
"print_job_ref": "CF921CF10F59B3A258"
}
]
}'
A successful request will result in an array of orders being returned:
[
{
"id": "...",
"ref": "...",
"external_ref": "TEST001",
...
"has_error": false,
"error_message": "",
"items": [
{
"id": "...",
"ref": "...",
"external_ref": "ITEM001"
}
]
}
]
Please see the errors section for more information on the
has_error
anderror_message
fields.An example request body for submitting an order is below, this contains multiple different item types.
[
{
"external_ref": "TEST-0001",
"company_ref_id": 99999,
"sale_datetime": "2021-09-26 15:20:01",
"customer_name": "Kornit X",
"customer_email": "test@example.com",
"shipping_address_1": "Shipping Address 1",
"shipping_address_2": "Shipping Address 2",
"shipping_address_3": "Shipping Address 3",
"shipping_address_4": "Shipping Address 4",
"shipping_address_5": "Shipping Address 5",
"shipping_postcode": "Shipping Postcode",
"shipping_country": "Shipping Country",
"shipping_country_code": "GB",
"shipping_method": "Shipping Method",
"shipping_carrier": "Shipping Carrier",
"shipping_tracking": "Shipping Tracking",
"billing_address_1": "Billing Address 1",
"billing_address_2": "Billing Address 2",
"billing_address_3": "Billing Address 3",
"billing_address_4": "Billing Address 4",
"billing_address_5": "Billing Address 5",
"billing_postcode": "Billing Postcode",
"billing_country": "Billing Country",
"payment_trans_id": "0123456789ABC",
"status_callback_url": "https://mydomain.com/order/status/orderid",
"items": [
{
"sku": "IP4",
"external_ref": "TEST-0001-01",
"description": "iPhone 4",
"quantity": 1,
"type": 1,
"external_url": "http://my.gateway3d.com/ep/output/output_viewer/0/49020//49020_final.png",
"external_thumbnail_url": "http://my.gateway3d.com/ep/output/output_viewer/0/49020/49020_thumbnail.png"
},
{
"sku": "IP4",
"external_ref": "TEST-0001-02",
"description": "iPhone 4",
"quantity": 1,
"type": 2,
"print_job_ref": "ABCDEFGHIJKLM"
},
{
"sku": "IP4",
"external_ref": "TEST-0001-03",
"description": "iPhone 4",
"quantity": 1,
"type": 3,
"print_on_demand_ref": "hjldskhfj"
},
{
"sku": "IP4",
"external_ref": "TEST-0001-05",
"description": "iPhone 4",
"quantity": 1,
"type": 5,
"attributes": [
{ "name": "Date_of_birth", "value": "11/11/1988" },
{ "name": "First_Name", "value": "James" }
]
},
{
"sku": "IP4",
"external_ref": "TEST-0001-07",
"description": "iPhone 4",
"quantity": 1,
"type": 7,
"external_urls": [
{
"name": "front",
"fullsize": "http://www.gateway3d.com/wp-content/uploads/2016/10/Custom-Gateway-250-x-56.png",
"thumbnail": "http://www.gateway3d.com/wp-content/uploads/2016/10/Custom-Gateway-250-x-56.png"
},
{
"name": "back",
"fullsize": "http://www.gateway3d.com/wp-content/uploads/2016/10/Custom-Gateway-250-x-56.png",
"thumbnail": "http://www.gateway3d.com/wp-content/uploads/2016/10/Custom-Gateway-250-x-56.png"
}
]
}
]
}
]
An order can be created by sending a JSON encoded order object via a POST request to the API.
HTTP Request
POST https://api-sl-2-2.custom-gateway.net/order
Order Object
- Bold text denotes a required field
- † denotes a field which the API will try to auto populate if left blank
Name | Type | Description |
---|---|---|
external_ref | string | A unique reference code that can be used to identify the order in your system. |
company_ref_id | integer | A unique company ID (supplied by Kornit X). Must correspond to the API key provided via the URL. |
sale_datetime | string | The date and time (must be UTC) of when the order was placed in the format YYYY-MM-DD HH:MM:SS (i.e. 2013-08-07 10:54:23) |
required_dispatch_date | string | The required dispatch date for the order in the format YYYY-MM-DD (i.e. 2013-08-07) |
customer_name | string | Customer's full name. |
customer_email | string | Customer's contact email. |
customer_telephone | string | Customer's contact telephone number. |
shipping_company | string | Shipping address company. |
shipping_address_1 | string | Shipping address 1. |
shipping_address_2 | string | Shipping address 2. |
shipping_address_3 | string | Shipping address 3. |
shipping_address_4 | string | Shipping town or city. |
shipping_address_5 | string | Shipping region. |
shipping_postcode | string | Shipping post or ZIP code. |
shipping_country_code | string | ISO 3166-1 alpha-2 country code. |
shipping_method | string | Shipping method. |
shipping_carrier | string | Shipping carrier. |
shipping_note_url | string | An optional URL for a specifying an external shipping note. If no value is provided then a basic shipping note will be generated. The URL must begin with either http:// or https:// . |
billing_customer_name | string | Billing name. |
billing_company | string | Billing address company. |
billing_address_1 | string | Billing address 1. |
billing_address_2 | string | Billing address 2. |
billing_address_3 | string | Billing address 3. |
billing_address_4 | string | Billing town or city. |
billing_address_5 | string | Billing region. |
billing_postcode | string | Billing post or ZIP code. |
coupon_code | string | Coupon code. |
payment_trans_id | string | Payment transaction identifier. |
status_callback_url | string | Order status callback URL. |
items | array | An array of order items |
Item Object
- Bold text denotes a required field
- † denotes a field which the API will try to auto populate if left blank
Name | Type | Description |
---|---|---|
external_ref | string | A reference code that can be used to identify the order item in your system. |
sku† | string | Product SKU. |
description† | string | Product description. |
quantity | integer | Item quantity. |
colour† | string | Item colour. |
size† | string | Item size. |
textual_product_id | integer | Determines which Catalog product the order item is for (can be used for either textual items or external URL items). |
type | integer | Item type code |
external_url | string | Required for external items (type 1). URL to an image which will be used for this item. This URL must be available until the order has been processed. |
external_thumbnail_url | string | Required for external items (type 1). URL to a thumbnail of an image which will be used for this item. This URL must be available until the order has been processed. |
print_job_ref | string | Required for print job items (type 2). A unique identifier linking this item to an already existing print job (created by a Kornit X Smartlink). The specified print job must have been created using a company ID which the current API key (URL parameter k) is permitted access to. |
print_on_demand_ref | string | Required for print on demand items (type 3). A unique identifier linking this item to a pre-created Print-on-Demand sample (created from within the Kornit X Catalog Module). |
external_urls | array of ExternalUrl | Required for external URL (multi) items (type 7). An array of ExternalUrl objects. |
ExternalUrl Object
- Bold text denotes a required field
Name | Type | Description |
---|---|---|
fullsize | string | A public URL to fullsized print ready artwork. |
thumbnail | string | A public URL to a thumbnail of the artwork. |
name | string | Position name, i.e. Front or Back. The give name must correlate a print area name set in the Catalog module |
Item Type Codes
Type Code | Name | Description |
---|---|---|
1 | External URL | an item for which the artwork is specified as an external URL (not hosted by Kornit X). |
2 | Print Job | An item that can be associated with a print job created by a Kornit X Smartlink. Once an order has been created, any referenced print jobs will be set to "Paid" in the "Print Manager". |
3 | Print-on-Demand | An item that can be associated to a precreated Print-on-Demand sample. |
4 | Stock Item | A item that does not have any generated artwork. |
5 | Textual Item | An item that does not have artwork generated by Kornit X but does have textual personalisation. |
7 | External URL [Multi] | Identical to the External URL type but allows for multiple images to be provided. |
Status Callbacks
Example callback URL request body
{
"id": "...",
"external_ref": "...",
"ref": "...",
"status": "...",
"status_name": "...",
"shipping_tracking": "...",
"shipping_method": "...",
"shipping_carrier": "..."
}
Every time an order's status changes in the Kornit X platform, the URL that you specified in the
status_callback_url
field will be sent a PUT
request with a JSON encoded
request body.
Your status callback should return a 200
HTTP response code if successful.
In the event of a 4XX
or 5XX
error response code, Kornit X will keep retrying the
request up to a maximum of 5 times at 2 hour intervals. For statuses that you
are not interested in, please be sure to still reply with a 200
response code
to prevent unnecessary retries.
Request Fields
Name | Type | Description |
---|---|---|
id | integer | The unique sequential ID for the order |
external_ref | string | The order reference number provided when creating the order |
ref | string | The unique alphanumeric reference code for the order |
status | int | The order's current status |
status_name | string | The name of the order's current status |
shipping_tracking | string | A shipment tracking ID. This field may be blank and its population is dependent on the product supplier. |
shipping_method | string | The shipping method that will be used for shipping the order |
shipping_carrier | string | The shipping carrier that will be used for shipping the order |
The shipping_carrier
and shipping_method
values may
be different to what was specified during order creation. It is common for the
values of both fields to mapped to different but equivalent values that the supplier is able to accept.
For example, if Standard Delivery Next Day
is specified as the shipping_method
during order creation, it may be mapped to Royal Mail
and RM1
for shipping_carrier
and shipping_method
by the supplier.
Statuses
Generally your status callback would not need to handle all possible order statuses.
- † denotes a status that you should handle at a minimum.
Status Code | Status Name | Description |
---|---|---|
0 | Unknown | The status of the order is unknown. |
1† | Received | The order has been received by Kornit X. |
2 | Unused | Unused |
4 | In Production | (Only when batching is enabled) At least a part of the order has been downloaded by a fulfilment operative. |
8† | Dispatched | The order has been fully dispatched. |
32 | QC Query | The order has a QC query against it. |
64 | Dispatched (Retailer Notified) | Dispatch confirmation has been explicitly pushed to the Sales Channel by Kornit X. |
128 | Cancelled | The order has been cancelled. |
256 | On Hold | The order is on hold. |
512 | Sent to Supplier | The order has been routed to an appropriate supplier. |
513 | Received by Supplier | The order has been confirmed as received by an appropriate supplier. |
515 | Sent to Shipper | The order details have been sent to a shipment courier (such as UPS or DPD). |
516† | Received by Shipper | The order details have been confirmed by a shipment courier. |
Errors
API Errors
An example HTTP 400 error response body
{
"error": {
"code": 12345,
"message": "A brief description of the problem"
}
}
An example HTTP 500 error response body
{
"error": {
"code": null,
"message": "An unexpected error occured 84C1E94BAF83D9C2A43CFCCBC04FE937"
}
}
When the API encounters an error, it will return either a 400
or 500
HTTP status code along with a JSON encoded error response.
The 500
HTTP status code indicates an internal error that should be reported to us. Please quote the full error message, including the long alphanumeric identifier.
The JSON encoded error response will contain both an error code and a message.
Error Code | Meaning | Solution |
---|---|---|
0 | Please check the error message for more details | |
100 | Invalid JSON | Please check the error message for details on syntax errors etc. |
8000 | No items | At least one order item must be specified |
8001 | An order already exists with the specified value for external_ref |
Ensure that external_ref is unique for each order |
8011 | Invalid sale_datetime |
sale_datetime must be in the correct format and not in the future. |
8012 | Invalid status_callback_url |
status_callback_url must be a valid URL and have a public DNS entry |
8013 | Invalid country code | shipping_country_code must be valid 2 character ISO 3166-1 alpha-2 country codes |
8014 | Invalid required_dispatch_date |
required_dispatch_date must be in the correct format and not in the past. |
8030 | Order company_ref_id not specified |
|
8031 | Order external_ref not specified |
|
8032 | Order shipping_address_1 not specified |
|
8033 | Order shipping_postcode not specified |
|
8034 | Order shipping_country_code not specified |
|
8040 | Invalid item type |
|
8041 | Invalid item quantity |
quantity must be greater than 0 |
8042 | Invalid item attribute for a textual item | The attribute must exist as an image or text area on the specified product |
8043 | Invalid item print job | The print_job_ref field must be valid and be a print job that is owned by your account |
8050 | Item external_ref not specified |
|
8051 | Item print_job_ref not specified |
|
8052 | Item textual_product_id not specified |
|
8053 | Item external_url not specified |
|
8054 | Item external_thumbnail_url not specified |
|
50000 | Either your company reference ID or API key are incorrect | Please make sure your details are correct |
50001 | Your company type does not allow receiving orders | Please contact support |
50002 | Your company has been deactivated | |
50003 | The IP address used to send the request does not appear in the IP white list | |
50004 | The rate limit has been exceeded |
Administrative Errors
An example response for when an order is created in an error state
[
{
"id": "...",
"external_ref": "TEST001",
...,
"has_error": true,
"error_message": "Failed to split order due to invalid supplier information",
"items": [
{
"id": "...",
...
}
]
}
]
In certain circumstances, the API might return a success response code but create an order that is in an error state.
Such error states can be dealt with by non-technical staff and do not represent issues with how the API has been used.
One example scenario could be if the API is unable to correctly determine the supplier of an order line due to a misconfigured product in the Catalog module.
When an administrative error occurs, the order fields has_error
and error_message
will be populated with true
and an error message respectively. The order status will also be set to QC Query
.
Virtual Product Creator
Before embedding the VPC tool into your website, you need the following pieces of information:
- A unique company reference ID.
- An alphanumeric API key.
Additionally, it is also necessary to specify two product category IDs:
- The ID of a category which is used to determine the available blank products.
- The ID of a category into which all end user created content is saved.
Please contact us for more details.
Embedding the VPC
<?php
$params = [
'company_ref_id' => 99999,
'approved_pc' => 1,
'blanks_pc' => 2,
'time' => time(),
'nonce' => bin2hex(random_bytes(8)),
'origin' => "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}",
];
$query = http_build_query($params);
$apiKey = 'AAAAAAAAAAAAAAAAAAAAAAAAAAA';
$params += [
'hmac' => hash_hmac('sha512', $query, $apiKey)
];
$query = http_build_query($params);
$iframeUrl = "https://whitelabel.custom-gateway.net/artists/vpc?{$query}";
The VPC tool can be embedded into your site using an iframe set to the following URL:
https://whitelabel.custom-gateway.net/artists/vpc
Several query parameters are also required:
Name | Description | Required? |
---|---|---|
company_ref_id |
Your unique company reference ID | Yes |
approved_pc |
The ID of the Catalog product category into which all created content is inserted | Yes |
blanks_pc |
The ID of the Catalog product category containing available product blanks | Yes |
time |
The number of seconds since the UNIX epoch | Yes |
nonce |
A random alphanumeric string that should be different each time you load the VPC | Yes |
origin |
The origin of the page loading the VPC | Yes |
hmac |
A HMAC message digest | Yes |
Calculating the HMAC Message Digest
Due to the nature of the VPC tool, it is necessary for the personalisation platform to be able to verify that your site is who it says it is. This is accomplished via the use of the HMAC algorithm.
The input to the HMAC algorithm should be the query part of your iframe URL (minus the hmac
parameter itself) whilst the HMAC secret key is your API key. sha512
should be selected as the hashing algorithm.
The time
query parameter is used to ensure that any HMAC value older than 15 seconds is rejected. This means that it is important that your server has the correct date and time set.
For example, given the following query parameters:
Name | Value |
---|---|
company_ref_id |
99999 |
approved_pc |
1 |
blanks_pc |
2 |
time |
1543581543 |
nonce |
randomstring |
origin |
https://myshop.com |
the HMAC input data would be:
company_ref_id=99999&approved_pc=1&blanks_pc=2&time=1543581543&none=randomstring&origin=https%3A%2F%2Fmyshop.com
which gives the below message digest when using AAAAAAAAAAAAAAAAAAAAAAAAAAA
as the HMAC secret key:
faf1b78c10bab271ba3a37933a642cfa371ce6bd4c82575d5180b2a1af904cb9ab8379dd997a2bfb90c3213a92928fe54187a75cc085b24a811747b4955f9f89
resulting in the final iframe URL:
https://whitelabel.custom-gateway.net/artists/vpc?company_ref_id=99999&approved_pc=1&blanks_pc=2&time=1543581543&none=randomstring&origin=https%3A%2F%2Fmyshop.com&hmac=faf1b78c10bab271ba3a37933a642cfa371ce6bd4c82575d5180b2a1af904cb9ab8379dd997a2bfb90c3213a92928fe54187a75cc085b24a811747b4955f9f89
Product Creation Callback
<!DOCTYPE html>
<html>
<head>
<style>
html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; }
iframe { width: 100%; height: 100%; border: 0; }
</style>
<script>
window.addEventListener('message', function(e) {
if(e.data.name == 'PRODUCTS_CREATED' && e.source == document.getElementById('iframe').contentWindow) {
let products = e.data.body;
// Do something to create the products within your own eCommerce
// platform
}
});
</script>
</head>
<body>
<iframe id="iframe" src="https://whitelabel.custom-gateway.net/artists/vpc?..."></iframe>
</body>
</html>
Once the end user has created their products using the VPC tool, a PRODUCTS_CREATED
message will
be passed back to the parent site using the postMessage
API.
Your site can listen for such messages using Javascript.
When the message is received, your site should use the data provided within the message to create relevant products in the most appropriate way for your particular eCommerce package.
After creating the products, the VPC iframe should be closed and the user redirected to an appropriate landing page.
The body
field of the message will be an array containing an element for each
product that the user selected.
Each element has the following fields:
Name | Description |
---|---|
id |
The Catalog module product ID that can be used in a Smartlink to reload the user's design |
description |
The design description entered by the user. |
name |
The design name entered by the user. |
retail_sku |
A unique SKU generated by the VPC tool using the product's supplier SKU as a base |
snapshots.small |
A 600x600 preview of the user's product |
base_product.productCode |
The SKU to use when sending future order lines for the product. |
For Fulfillers
Introduction
This guide covers only some of the various ways in which suppliers who don't wish to use our Production and/or Floor Modules can still integrate with the platform. Kornit X have created a knowledgebase conataining articles on the various integrations we have created which can be accessed here. A breif summary on a small number of these which are most commonly used is below.
Generic FileSystem Integration
The Generic FileSystem integration is a simple way of receiving order details from the platform.
Typically order details are represented by an XML file however we can support other formats on request.
Files can be transferred to a supplier use several different protocols such as FTP, SFTP, FTPS and S3.
Order API
The order API allows suppliers to programmatically retrieve new orders from the platform via an API.
Order Shipping API
The order shipping API allows suppliers to make use of the platform's various shipping integrations to create shipments with providers such as Hermes and Royal Mail.
When a shipment is created, a shipping label will be returned.
Before Starting
For both APIs, you will need the following information:
- A unique company reference ID.
- An alphanumeric API key.
Both will be provided to you by Kornit X. Please contact us for more details.
Note on Code Samples
The shell code samples to the right assume that you have access to the curl
command line tool.
Order Push API
Introduction
{
"id": 0,
"ref": "unique Kornit X reference"
"external_ref": "Sales Channel order reference",
"customer_name": "",
"shipping_address_1": "",
"shipping_address_2": "",
"shipping_address_3": "",
"shipping_address_4": "",
"shipping_address_5": "",
"shipping_postcode": "",
"shipping_country_code": "",
"shipping_carrier": "",
"shipping_method": "",
"items": [
{
"id": 0,
"type": 1,
"mapped_sku": "supplier SKU",
"sku": "retail SKU",
"description": "Product description",
"quantity": 1,
"assets": [
{
"name": "output-1.png",
"url": "http://example.com/output-1.png",
"description": "Front"
}
]
}
]
}
The Order Push API allows a supplier to configure a per 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.
Verifying the HMAC header
$hmac = hash_hmac('sha256', file_get_contents('php://stdin'), $key);
if(!hash_equals($hmac, getHeader('X-CustomGateway-Hmac')))
{
throw new \Exception('HMAC mismatch');
}
Order Shipping API
Before Starting
Using the order shipping API requires a shipping integration to have been enabled on your relevant dropshipping accounts within the personalisation platform.
Please contact us for more details.
Shipping an Order
curl https://api-sl-2-2.custom-gateway.net/order/:id/shipment\
-H "Authorization: Basic COMPANYREFID:APIKEY" -X POST
A successful request will result in an array of shipments being returned:
[
{
"id": 1234567890,
"carrier": "hermes",
"tracking": "ABCDEFGHIJKL",
"label_url": "http://example.com/label.pdf",
"items": [
{
"id": 1234,
"order_id": 1234,
"quantity": 10,
"quantity_shipped": 10
}
]
}
]
A order can be shipped by making a simple POST
request to the order shipment endpoint.
POST https://api-sl-2-2.custom-gateway.net/order/:id/shipment
The shipping service used is automatically determined based on how your account (and possibly the retailers account) have been configured.
A successful request will result in one or more shipment entities being created and returned.
If an order has been split into multiple shipments, then the items
collection on each shipment can be used to identify which items are included in that particular shipment.
Stock API
Introduction
The stock API allows a supplier to update available stock levels for their products.
Updating Stock Levels
<?php
$guzzle = new \GuzzleHttp\Client;
$guzzle->request("PUT", "https://api-sl-2-2.custom-gateway.net/stock/availability", [
'headers' => [
'Authorization' => "Basic COMPANYREFID:APIKEY"
],
'json' => [
[
"sku" => "ABC",
"data" => [
"quantity_available" => 10
]
],
[
"sku" => "DEF",
"data" => [
"quantity_available" => 12
]
]
]
]);
curl https://api-sl-2-2.custom-gateway.net/stock/availability\
-H "Authorization: Basic COMPANYREFID:APIKEY" -X PUT\
-d'[ { "sku": "ABC", "data": { "quantity_available": 10 } }, { "sku": "DEF", "data": { "quantity_available": 12 } } ]'
Updates to stock levels can be made by issuing a PUT
request to the availability endpoint:
PUT https://api-sl-2-2.custom-gateway.net/stock/availability
The body of the PUT
request should be a JSON encoded array, with a single element for each stock product to be updated.
GraphQL
This section assumes a basic understanding of GraphQL and that the reader understands how to consume GraphQL APIs from their language of choice.
More info on GraphQL can be found here
Authorization
<?php
$client = new \GuzzleHttp\Client;
$clientId = ...;
$clientSecret = ...;
$scopes = [ ... ];
$response = $client->post("https://oauth.custom-gateway.net/token", [
"form_params" => [
"client_id" => $clientId,
"client_secret" => $clientSecret,
"grant_type" => "client_credentials"
"scope" => implode(' ', $scopes)
]
]);
$json = (string)$response->getBody();
$accessToken = json_decode($json, true)['access_token'];
curl "https://oauth.custom-gateway.net/token"\
-F "client_id=CLIENTID"\
-F "client_secret=CLIENTSECRET"\
-F "grant_type=client_credentials"\
-F "scope=SCOPES"
A successful request will return an access token.
{"token_type":"Bearer","expires_in":3600,"access_token":"..."}
To use the GraphQL API, it is first necessary to obtain OAuth access tokens using your client ID and client secret.
This can be done by making a POST
request to the OAuth access token endpoint:
https://oauth.custom-gateway.net/token
On success, the request will result in a JSON encoded object that contains an access_token
field.
The access token is valid for 3600 seconds and must be provided via the Authorization
header in subsequent API calls.
Product Manager
The product manager GraphQL API is located at:
https://cpp.custom-gateway.net/v2/product-manager/products-graphql
createVirtualProductsFromArtwork
Example mutation
mutation($baseProducts: [ID]!, $categoryId: ID!, $artwork: [CreateVirtualProductsFromArtworkArtwork]!) {
createVirtualProductsFromArtwork(baseProducts: $baseProducts, categoryId: $categoryId, artwork: $artwork) {
id
}
}
<?php
$client = new \GuzzleHttp\Client;
$response = $client->post("https://cpp.custom-gateway.net/v2/product-manager/products-graphql", [
"headers" => [
"Authorization" => "Bearer {$accessToken}"
],
"json" => [
"query" => 'mutation($baseProducts: [ID]!, $categoryId: ID!, $artwork: [CreateVirtualProductsFromArtworkArtwork]!) {
createVirtualProductsFromArtwork(baseProducts: $baseProducts, categoryId: $categoryId, artwork: $artwork) {
id
}
}',
"variables" => [
"baseProducts" => [ $productId1, $productId2, ... ],
"categoryId" => $categoryId,
"artwork" => [
[
"design_name": "Design #001",
"urls" => [
[
"preview" => "https://example.com/fairly-smal-live-preview-image.png",
"original" => "https://example.com/full-size-artwork-image.png"
]
]
]
]
]
]
]);
$json = (string)$response->getBody();
$virtualProductIds = json_decode($json)['data']['createVirtualProductsFromArtwork'];
Virtual products can be created via the createVirtualProductsFromArtwork
GraphQL mutation, which accepts three mandatory variables.
Required scopes:
products.customisable.create
Variable | Type | Description |
---|---|---|
baseProducts |
[ID]! |
A collection of base product IDs. |
categoryId |
ID! |
The ID of the target product category into which the new virtuals will be created. |
artwork |
CreateVirtualProductsFromArtworkArtwork |
A collection of artwork objects. Each artwork object has a:
|
A new virtual product is created for each product specified via the baseProducts
variable.
Storing Images
curl -X POST "https://legacy.custom-gateway.net/acp/api-3/user-image/?url=https://www.google.co.uk/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"
<?php
$client = new \GuzzleHttp\Client;
$response = $client->post("https://legacy.custom-gateway.net/acp/api-3/user-image", [
'query' => [
'url' => 'https://www.google.co.uk/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png'
]
]);
On success, a simple JSON response will be returned:
{
"urls": {
"original": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/9931/b09d/27b7/b284/6eaf/902c/a919/6049/2243/9a78/af03/19e6/e335/bd76/abe2/2780-original.png",
"preview": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/9931/b09d/27b7/b284/6eaf/902c/a919/6049/2243/9a78/af03/19e6/e335/bd76/abe2/2780-preview.png",
"processed": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/9931/b09d/27b7/b284/6eaf/902c/a919/6049/2243/9a78/af03/19e6/e335/bd76/abe2/2780-original.png"
},
}
It is possible to use Kornit X to host your images using the User Image API.
https://legacy.custom-gateway.net/acp/api-3/user-image
The API is able to download an image from a URL, generate a live preview image automatically and store both.
The URLs can then be used in the createVirtualProductsFromArtwork
API call.