Table of Contents
- How to Create a Before Create Order Script
- Order History
- Runtime Errors
- Return Statements
- Script Sort Order
- Transforming an Order
- order.merchant
- order.brand
- order.items
- order.items[*].product
- order.address
- order.options
- order.options.unique_id
- order.options.order_ref
- order.options.shipping_method
- order.options.custom_greeting
- order.options.note
- order.options.signature_required
- order.options.saturday_delivery
- order.options.declared_value_service
- order.options.declared_value
- order.options.declared_value_currency
- order.options.reason_for_export
- order.options.customs_value
- order.options.customs_value_currency
- order.options.duties_payor
- order.options.duties_tpb_group_id
- order.options.overbox
- order.options.backorder_policy
- order.options.priority
- order.options.requested_ship_date
- order.options.hold_until_time
- order.options.hold_indefinitely
- order.options.desired_delivery_date
- order.options.tpb_group_id
- order.options.generate_sscc
- order.options.allocation_options
- order.options.instructions
- order.options.other_shipping_options
- order.options.automation_data
- order.options.send_email
- order.options.source
- order.timestamp
- order.submitted_by
- order.submitted_by_id
- Custom Fields
Before Create Order Scripts
Updated by Cory M.
- How to Create a Before Create Order Script
- Order History
- Runtime Errors
- Return Statements
- Script Sort Order
- Transforming an Order
- order.merchant
- order.brand
- order.items
- order.items[*].product
- order.address
- order.options
- order.options.unique_id
- order.options.order_ref
- order.options.shipping_method
- order.options.custom_greeting
- order.options.note
- order.options.signature_required
- order.options.saturday_delivery
- order.options.declared_value_service
- order.options.declared_value
- order.options.declared_value_currency
- order.options.reason_for_export
- order.options.customs_value
- order.options.customs_value_currency
- order.options.duties_payor
- order.options.duties_tpb_group_id
- order.options.overbox
- order.options.backorder_policy
- order.options.priority
- order.options.requested_ship_date
- order.options.hold_until_time
- order.options.hold_indefinitely
- order.options.desired_delivery_date
- order.options.tpb_group_id
- order.options.generate_sscc
- order.options.allocation_options
- order.options.instructions
- order.options.other_shipping_options
- order.options.automation_data
- order.options.send_email
- order.options.source
- order.timestamp
- order.submitted_by
- order.submitted_by_id
- Custom Fields
"Scripts" in ShipStream are small snippets of computer programming code provided by a user which ShipStream uses to affect specific processes to accomplish the user's desired custom business logic. While ShipStream provides many "levers" to pull using the configuration and various other features, there are sometimes advanced or complex needs that cannot be handled by configuration alone.
The Before Create Order script type (commonly referred to as a "BCO script") covered in this article executes just before an order is created. This script allows you to transform the order items, address, and other options or reject the order entirely based on any piece of data in the order request. These scripts apply to all orders submitted for the given Merchant, regardless of the source (API, User Interface, Import, Integrations or EDI).
How to Create a Before Create Order Script
- Navigate to System > Scripts.
- Click Create New Script at the top right.
- Select the Merchant to which the script will be applicable or "--All Merchants--" to have the script apply to all merchants.
- Enter a brief description for the script so you can easily identify it. This description will also appear in the order's History tab if the script has an error or prints any output.
- Select Before Create Order as the Type.
- Change the Is Active field to Yes if you wish to use the script after it is saved, or leave it as No to disable it for now.
- Set a Sort Order if using multiple scripts to control the order in which the scripts are applied. Lower numbers will run before script with higher numbers.
- Click Save.
Order History
If the script contains and executes a print()
statement when it is executed for a given order, a comment will be recorded in the Order History along with the Script ID next to the Order Status. In the example below, a script with ID "3" and Description "Test Script" executed the statement print("Shipping Method Updated")
and so this text was added to the order history.
Runtime Errors
If any errors occur during the execution of the script and are not captured and handled within the script they will cause the order submission to fail with an error describing the script which threw the error, the line number and the error message. These will be logged and visible at the bottom of the Edit Script page. Once the script is saved these errors will be cleared so that you can easily determine if new errors are still occurring.
The editor is able to detect basic syntactical errors, but it is still possible to introduce runtime errors. For example, a common issue is setting or referencing a property of an "undefined" expression:
Return Statements
The return value of a script will have no effect so it is safe to call "return" at any time in the script. If there are additional scripts which have not yet run based on the Sort Order, those will still be executed regardless.
if (someCondition) {
return;
}
// this code will not execute if "someCondition" was truthy
doSomething()
Script Sort Order
You may create multiple scripts that will be active for any given Merchant and these will be run sequentially using the Sort Order of each script from lowest to highest.
For example, if you have two scripts:
- A: Place all orders with FedEx International Overnight shipping method on hold
- B: Change USPS Priority Mail Express to FedEx International Overnight if order contains SKU X
If script A executes first, it will not affect orders updated by script B, but if script B runs first, it would allow script A to affect those orders updated by B.
Transforming an Order
When the script executes, the data being submitted will be stored a variable containing a simple Javascript object called order
. You cannot replace this variable but you can modify its properties to suit your needs. You do not need to "return" anything from the script, you only need to modify the order object.
For example, to change the shipping method to be "UPS Ground" (code ups_03
) could be accomplished with this one line:
order.options.shipping_method = 'ups_03'
In English: The order
object has a property called options
which is itself an object with a property called shipping_method
which is being assigned to the string 'ups_03'
which is the correct code for UPS Ground.
The order object contains the following properties, each described in greater detail below:
merchant
- (string, read-only) - The "code" of the Merchant to which the order will belong.brand
- (null|string) - The "code" of the Brand to which the order will be assigned.items
- (array) - The line items to be added to the order.address
- (object) - The destination address for the order.options
- (object) - All other properties which affect the order request.timestamp
- (DateTime, read-only) - A timestamp representing the current time in the Merchant's timezone.submitted_by
- (string, read-only) - The source of the order request (one of: api, admin, client)submitted_by_id
- (null|string) - The ID of the admin user, client user or API key which is the source of the order request.
order.merchant
Changing this value in a script has no effect.
For scripts that apply to "--All Merchants--" this can be used to behave differently for different merchants or abort execution for some merchants but not others.
switch (order.merchant) {
case 'acme_inc':
// do something
break
case 'goodwin_group':
// do something else
break
default:
// everyone else
return
}
Similarly:
if (['acme_inc','goodwin_group'].includes(order.merchant)) {
// do something
}
Do something for all merchant codes ending in "_cn":
if (order.merchant.match(/_cn$/)) {
// do something
}
order.brand
If not specified in the request, this will default to the code of the Merchant's "Default Brand". Changing this value will change the brand the order is assigned to.
order.brand = 'acme_mexico'
order.items
The order.items property is an Array with each array element being an object containing order item data for one line item. You may add or remove elements of this array or modify individual elements as the order has not yet been created.
The minimum required proerties of an order item are the sku
and the qty
. However, the order item may have additional properties, see Order Items Data for a full list.
Minimum order item object properties:
{
sku: string,
qty: integer
}
Full order item object properties
{
sku: string,
qty: integer,
order_item_ref: string,
unit_declared_value: float|string,
unit_declared_value_currency: string,
unit_customs_value: float|string,
unit_customs_value_currency: string,
product: {
sku: string,
name: string,
...
}
}
Check if the order contains a given SKU
let itemX = order.items.find(item => item.sku === "X")
Get the quantity of a given item
parseInt
in case the input is not an integer.let xQuantity = parseInt((order.items.find(item => item.sku === "X")||{qty:0}).qty)
Add an order item if it doesn't already exist
if ( ! order.items.find(item => item.sku === "X")) {
order.items.push({sku: "X", qty: 1, product:{}})
}
Remove an order item
Use Array.prototype.filter
or other methods to remove item objects that are unwanted.
order.items = order.items.filter(item => item.sku === "X")
order.items[*].product
If the SKU is found in the Merchant's catalog before the script execution begins, the order item object will be populated with the product
property containing an object with all product information for the given product.
See Product Properties documentation for a full list of properties that are available.
In addition to the standard product attributes, weight and dimensions are augmented with additional fields which are already converted to common units for your convenience.
{
sku: "ABC",
name: "Cool Widget",
...,
weight_lb: 0.2,
weight_oz: 3.2,
weight_kg: 0.09071847400000001,
weight_g: 90.71847400000001,
length_in: 7.8,
length_cm: 19.812,
length_mm: 198.11999999999998,
width_in: 1.3,
width_cm: 3.302,
width_mm: 33.019999999999996,
height_in: 1,
height_cm: 2.54,
height_mm: 25.4
}
Check if every item is greater than 10 kg
let isAllHeavy = order.items.every(item => item.product && item.product.weight_kg >= 10.0)
Good:
let containsHazmat = order.items.some(item => item.product && item.product.goods_type === 'HAZMAT')
Bad:
let containsHazmat = order.items.some(item => item.product.goods_type === 'HAZMAT')
Get the total order item weight in pounds
let totalWeightLb = order.items.reduce((total, item) => total + (item.product||{weight_lb:0}).weight_lb, 0)
order.address
The order.address
object is also mutable but is typically used for "if.. then.. " logic. See Address Properties for a complete description of each field.
{
firstname: "Celina",
lastname: "Goalley",
company: "Thompson-Torp",
street: "Floor 14, 10400 NE 4th St",
city: "Bellevue",
region: "Washington",
region_code: "WA",
postcode: "98004",
country: "US",
email: "celina.goalley@thompson-torp.com",
telephone: "417.519.3773",
classification: "res"
}
Example checking for orders destined for specific countries using a regex:
let isUSMCA = (order.address.country||'').match(/^(US|MX|CA)$/)
Example checking for specific US states:
let isWestCoast = order.address.country === 'US' && ['CA','OR','WA'].contains(order.address.region_code)
order.options
The order.options
property is an Object contianing every other property that is mutable besides the brand, items and address. See Order Additonal Data for more details on the properies that can be used in this object.
{
unique_id: string,
order_ref: string,
shipping_method: string,
custom_greeting: string,
note: string,
signature_required: string,
saturday_delivery: bool,
declared_value_service: bool,
declared_value: string|float,
declared_value_currency: string,
customs_value: string|float,
customs_value_currency: string,
overbox: bool,
backorder_policy: string,
priority: int|string,
requested_ship_date: string,
delayed_ship_date: string,
desired_delivery_date: string,
allocation_options: object,
instructions: array,
generate_sscc: bool,
custom_fields: object,
other_shipping_options: object,
automation_data: object
}
order.options.unique_id
If specified will set the Order ID field. If not specified an order ID will be generated. The uniqueness of this value within the orders of a given Merchant is enforced by the system.
order.options.order_ref
If specified will set the Order Ref field. Will remain empty if not specified. Uniqueness is not checked or enforced.
order.options.shipping_method
If not specified after all scripts have run an error will be thrown so this is typically set already in the request. This is a code that should always match the format "{carrier}_{service}" where "{carrier}" is a code such as "fedex" and the "{service}" is a service code for that carrier such as "GROUND_HOME DELIVERY".
This can include both Virtual Shipping Methods as well as External Shipping Methods which are user-defined.
See System > Enumerations for a full list of shipping methods available in your environment.
order.options.custom_greeting
This appears on the Packing Slip. See Packign Slip Design.
order.options.note
This appears on the Order page in the Admin UI and Client UI but will not necessarily be presented to warehouse staff at any time. See Packing Instructions (order.options.instructions
) for messages that will be presented directly to packers.
order.options.signature_required
Values can be none
, any
, adult
, indirect
or default
.
none
— No signature requirement.any
— The package(s) will be shipped with the “Direct” signature required (recipient of any age).adult
— The package(s) will be shipped with the Adult Signature Required option (21 years or older).indirect
— The package(s) will be shipped with theindirect
signature required (Ifindirect
is not supported by the carrier, this option will fall back toany
). Currently only supported by FedEx.default
— May be used to defer to the default based on the carrier service type (Ifdefault
is not supported by the carrier, this option will fall back tonone
).
If the signature requirement is not specified it will fall back to default
for HazMat orders or none
for all others.
order.options.saturday_delivery
Defaults to false
.
order.options.declared_value_service
If true
then the order or the package(s) will be shipped with Declared Value Service requested (if supported by the carrier/service).
order.options.declared_value
The total declared value for the order.
Note, this should not be specified if the unit_declared_value
is present for any order items since this could be a potential conflict.
Get total declared value
let declaredValue = order.options.declared_value
? parseFloat(order.options.declared_value)
: order.items.reduce((total, item) => total + parseFloat((item.unit_declared_value||0)) * parseInt(item.qty), 0)
order.options.declared_value_currency
The currency of the order.options.declared_value
property. No currency conversion will take place so this currency must be supported by the carrier. Must be a valid ISO 4217 alphabetic code.
order.options.reason_for_export
Values can be sold
, not_sold
, gift
, sample
, repair_return
, personal_effects
. If not specified will default to sold
. Only applicable to international orders.
order.options.customs_value
The total customs value for the order.
Note, this should not be specified if the unit_customs_value
is present for any order items since this could be a potential conflict.
Get total customs value
let customsValue = order.options.customs_value
? parseFloat(order.options.customs_value)
: order.items.reduce((total, item) => total + parseFloat((item.unit_customs_value||0)) * parseInt(item.qty), 0)
order.options.customs_value_currency
The currency of the order.options.customs_value
property. No currency conversion will take place so this currency must be supported by the carrier. Must be a valid ISO 4217 alphabetic code.
order.options.duties_payor
Values can be default
, shipper
(example: DDP), recipient
(example: DDU) or third_party
. If not specified will default to default
. Only applicable to international orders.
order.options.duties_tpb_group_id
The ID number of a Third Party Billing Account Group which includes Duties and Taxes as an Eligible Payment Type.
order.options.overbox
Request overbox option. If not specified will default to ‘false’.
order.options.backorder_policy
If specified, the order will use specified policy instead of the Merchant's/Brand's default policy. Values can be default
, all_or_nothing
, as_available
, or up_to_X
. If not specified will default to default
.
all_or_nothing
- Accept order but do not ship anything until all items are in stock.as_available
- No limit to number or frequency of additional shipments.up_to_X
shipments - Same as "As Available", but changes to All or Nothing before shipping Xth shipment.
When using up_to_X
, “X” represent a positive integer number. Example: up_to_3
order.options.priority
If specified, sets this Order’s Priority. Default is "50" if unspecified. See Order Allocation for more information.
order.options.requested_ship_date
If specified, will determine if the Merchant wishes for the item to be shipped on the same day or not using the "Absolute Same-Day Cutoff" rather than the standard "Same-Day Cutoff".
Whether or not this date becomes the Target Ship Date depends on the Merchant’s Service Level and Ready to Ship Time.
Format: YYYY-MM-DD
order.options.hold_until_time
If specified, the order will be placed in “Scheduled Hold" status until this date and time. May be specified as a date or a date and time. The timezone is assumed to be the Merchant's default timezone if not specified. If a time is not specified it is assumed to be 00:00:00 (12:00 am) in the Merchant's timezone.
Format: YYYY-MM-DD
or YYYY-MM-DDThh:mm:ss
or YYYY-MM-DDThh:mm:ssZ
order.options.hold_indefinitely
If specified, the order will be placed in “On Hold” status indefinitely (cannot be used with hold_until_time
).
order.options.desired_delivery_date
This date is used only for Virtual Shipping Methods which have the Desired Delivery Date option enabled.
order.options.tpb_group_id
The ID number of a Third Party Billing Account Group. If unset or null
, and a default group is configured, the default group will be used. Set to 0
to override the default configuration and disable Third Party Billing for this order.
order.options.generate_sscc
Specify if the Serial Shipping Container Code should be generated for the order's shipments.
order.options.allocation_options
See Order Allocation for more information and info on how to set options by script.
order.options.instructions
An Array of objects containing details for Packing Instructions.
Each object must contain note
and presentation
fields at a minimum.
note
A string containing a message that will be displayed to the packer.
presentation
Either "once_per_order", "once_per_shipment" or "once_per_package".
// Add special handling instructions
order.options.instructions.push({
note: "Sign the gift card \"Yours truly, Bob\"",
presentation: "once_per_shipment"
})
file_request
A file can be attached by adding a file_request
option which must specify a url
from which the print job file will be downloaded. This url must accept an HTTP GET request and download a PDF file. A print_target
is also required when attaching a file.
// Add a special print job
order.options.instructions.push({
note: "Adhere the label to the side of the package.",
presentation: "once_per_order",
print_target: "LABEL",
file_request: {
url: "https://...."
}
})
For more advanced needs you can optionally specify a username/password using auth
for HTTP Basic Authentication or custom headers using headers
as an array of header names and values.
// Add a special print job with custom auth, headers and file_name
order.options.instructions.push({
note: "Place the flyer on top of the infill.",
presentation: "once_per_order",
print_target: "LASER",
file_request: {
url: "https://....",
auth: ["username...","password..."],
headers: {
"X-Custom-Header": "header value..."
}
},
file_name: "flyer.pdf"
})
print_target
Either "LABEL", "SMALL_LABEL" or "LASER". Required if a file is attached.
order.options.other_shipping_options
This is an object containing additional special-purpose fields that are documented on the Other Shipping Options page.
order.options.automation_data
This is an object that may contain your own structured data for various purposes. It must be an object that can be encoded with JSON. It is not visible or editable via any user-interface.
order.options.send_email
This may take one of three different types of values:
Set to true
to send a New Order email even if the order does not match the "Enabled for Source" configuration at System > Configuration > Shipping > Email Notifications.
Set to a string which is a comma-separated list of valid email addresses and/or the following values to send to the contact configured at System > Configuration > General > Email Addresses:
general
support
inbound
outbound
noreply
custom
order.options.source
This field should not be modified when used by integration plugins. It can also be used for custom API integrations to store a reference to an order in another system which is not visible to any users (unlike Order Ref which is visible).
order.timestamp
The order.timestamp
property is actually a PHP DateTime object. The value is set to the time that the order started being submitted in the Merchant's timezone.
Most commonly this will be to take action based on the day of week or time of day an order is submitted.
if (order.timestamp.format('l') === 'Sunday')) {
// do something only on Sundays
}
Formats which may be useful include:
Format | Description | Example |
l (lowecase 'L') | A full textual representation of the day of the week |
|
z | The day of the year (starting from 0) |
|
F | A full textual representation of a month |
|
G | 24-hour format of an hour without leading zeros |
|
i | Minutes with leading zeros |
|
s | Seconds with leading zeros |
|
c | ISO 8601 date |
|
order.submitted_by
This property contains a string that is either "api" for orders submitted through the API (including plugins like Shopify), or "admin" for orders submitted by organization users through the Admin UI or "client" for orders submitted by the merchant through the Client UI.
order.submitted_by_id
This property is the ID of the user who submitted the order if order.submitted_by
is "admin" or "client" or the ID of the API key used to submit the order if order.submitted_by
is "api".
Custom Fields
Order Custom Fields are accessed and updated using a number of methods on the Order
object rather than properties of the order
object.
Order.getCustomField(code)
This method returns either an object or an array depending on the type of the custom field.
Field Type | Empty Return Value | Non-Empty Return Value | Example |
Text | null | Object{value: string} | {"value":"Greetings!"} |
Multiline Text | null | Object{value: string} | {"value":"Hello\nworld!"} |
Number | null | Object{value: number} | {"value":42} |
Currency | null | Object{amount: number} | {"amount":1.29} |
Select | null | Object{id: number, label: string} | {"id":13,"label":"Damaged in shipping"} |
Multiselect | [] | Array{Object{id: number, label: string}} | [{"id":13,"label":"Label 1"},{"id":15,"label":"Label 2"}] |
Yes/No | null | boolean | {"value":true} |
Date | null | string | {"value":"2023-05-09"} |
Admin User | null | Object{id: number, label: string} | {"id":51,"label":"Bernard Greensmith"} |
Client User | null | Object{id: number, label: string} | {"id":51,"label":"Bernard Greensmith"} |
null | Object{value: string} | {"value":"user@example.com"} | |
URL | null | Object{value: string} | {"value":"https://example.com"} |
Get the custom field value for a custom field with code "my_custom_field":
let myValue = Order.getCustomField('my_custom_field') // null or {"value":"x"}
Order.getCustomFieldValue(code)
Like Order.getCustomField()
above, but returns the "value" or "amount" property instead of an object. This can still return null
so make sure you account for that to avoid errors from calling methods on null
. This method cannot be used for Select, Multiselect, Admin User or Client User types.
if ((Order.getCustomFieldValue('district')||'').match(/^pattern/)) {
// do something...
}
if (Order.getCustomFieldValue('customer_since') > "2020-01-01") {
// do something...
}
Order.getCustomFieldId(code)
Like above, but returns just the "id" property for single-select fields and an array of "id" for multi-select fields.
print(Order.getCustomFieldId('claim_reason')) // 13
print(Order.getCustomFieldId('claim_reasons')) // [15,16]
Order.getCustomFieldLabel(code)
Like above, but returns just the "label" property for single-select fields and an array of "label" for multi-select fields.
print(Order.getCustomFieldLabel('claim_reason')) // "Damaged in shipping"
print(Order.getCustomFieldLabel('claim_reasons')) // ["Damaged in shipping","Did not fit"]
order.setCustomField(code, value)
The first parameter is the custom field's code, the second parameter is the value or null to unset the field value.
// Select
Order.setCustomField('claim_reason', {label: 'Damaged in shipping'})
// Multiselect
Order.setCustomField('claim_reasons', [{label: "Damaged in shipping"},{label:"Did not fit"}])
The format of the value argument depends on the field type.
Field Type | Parameter Value | Example |
Text | Object{value: string} | {"value":"Greetings!"} |
Multiline Text | Object{value: string} | {"value":"Hello\nworld!"} |
Number | Object{value: number} | {"value":42} |
Currency | Object{amount: number} | {"amount":1.29} |
Select | Object{id: number} or Object{label: string} | {"id":13} or {"label":"Damaged in shipping"} |
Multiselect | Array{Object{id: number}} or Array{Object{label: string}} | [{"id":13},{"id":15}] or [{"label":"Label 1"},{"label":"Label 2"}] |
Yes/No | boolean | {"value":true} |
Date | string | {"value":"2023-05-09"} |
Admin User | Object{id: number} or Object{label: string} | {"id":51} or {"label":"Bernard Greensmith"} |
Client User | Object{id: number} or Object{label: string} | {"id":51} or {"label":"Bernard Greensmith"} |
Object{value: string} | {"value":"user@example.com"} | |
URL | Object{value: string} | {"value":"https://example.com"} |
Example Order Input
For complex scripts, it is recommended to use a tool like JSFiddle.net or CodePen to test your scripts in a sandbox before putting them into ShipStream for faster iterations of development.
const order = {
merchant: "acme_inc",
store: "keebler_group",
items: [
{
sku: "34-737-8757",
qty: 2,
order_item_ref: "B015UKRNGS",
unit_declared_value: "11.50",
unit_declared_value_currency: "USD",
unit_customs_value: "11.50",
unit_customs_value_currency: "USD",
product: {
sku: "34-737-8757",
name: "Protein - Strawberry",
barcode: "622218414-6",
external_id: "00-942-4257",
vendor_sku: null,
goods_type: "NORMAL",
regulation_id: null,
status: "1",
availability: "1",
visibility: "2",
weight: 5.8,
length: 6.7,
width: 6.7,
height: 9.7,
export_description: "Protein drink mix",
country_of_manufacture: "US",
customs_value_usd: "13.5000",
customs_value: "13.5000",
customs_value_currency: "USD",
hts_base_code: null,
hts_country_code: null,
requires_packaging: 1,
requires_infill: null,
require_weight_check: 1,
confirmation_per_item: 0,
allowed_container_styles: [ "rigid_box" ],
valid_containers: [],
disallowed_containers: [ "PB161616", "PB161624" ],
special_supplies: [ "TapeLid" ],
special_other: [ "KraftPaper" ],
unit_qty: 1,
bulk_qty: null,
max_per_package: "4.0000",
is_ship_separate: 0,
ship_separate_tag: null,
can_tip: 1,
can_contain_other_items: 0,
freight_class: null,
freight_category: null,
my_custom_text_field: null,
my_custom_yes_no: "Yes",
my_custom_price: null,
my_custom_text_area: null,
my_custom_date: null,
my_custom_multiple_select: "Is Required",
my_custom_dropdown: "Outer",
weight_lb: 5.8,
weight_oz: 92.8,
weight_kg: 2.6308357460000003,
weight_g: 2630.835746,
length_in: 6.7,
length_cm: 17.018,
length_mm: 170.18,
width_in: 6.7,
width_cm: 17.018,
width_mm: 170.18,
height_in: 9.7,
height_cm: 24.637999999999998,
height_mm: 246.37999999999997
}
},
{
sku: "19-177-1719",
qty: 1,
order_item_ref: "pc_13",
unit_declared_value: "3.50",
product: {
sku: "19-177-1719",
name: "Fruit and Vegetable Stainless Steel Corer",
barcode: "342398184-9",
external_id: "97-507-2551",
vendor_sku: null,
goods_type: "NORMAL",
regulation_id: null,
status: "1",
availability: "1",
visibility: "2",
weight: 0.2,
length: 7.8,
width: 1.3,
height: 1,
export_description: "Fruit and Vegetable Stainless Steel Corer",
country_of_manufacture: "TN",
customs_value_usd: "1.0000",
customs_value: "1.0000",
customs_value_currency: "USD",
hts_base_code: null,
hts_country_code: null,
requires_packaging: 1,
requires_infill: null,
require_weight_check: 1,
confirmation_per_item: 0,
allowed_container_styles: [],
valid_containers: [ "Box_12.5x24.5x1.25", "Box_4x5x3", "Box_8x4x3.25", "Box_8x4x4" ],
disallowed_containers: [],
special_supplies: [],
special_other: [],
unit_qty: 1,
bulk_qty: null,
max_per_package: null,
is_ship_separate: 0,
ship_separate_tag: null,
can_tip: 1,
can_contain_other_items: 0,
freight_class: null,
freight_category: null,
my_custom_text_field: "Custom Text Field",
my_custom_yes_no: "No",
my_custom_price: "10.5500",
my_custom_text_area: "Text area.\r\nAllows new lines.",
my_custom_date: "2023-04-14 00:00:00",
my_custom_multiple_select: [ "Is Required", "Not Required" ],
my_custom_dropdown: "Center",
weight_lb: 0.2,
weight_oz: 3.2,
weight_kg: 0.09071847400000001,
weight_g: 90.71847400000001,
length_in: 7.8,
length_cm: 19.812,
length_mm: 198.11999999999998,
width_in: 1.3,
width_cm: 3.302,
width_mm: 33.019999999999996,
height_in: 1,
height_cm: 2.54,
height_mm: 25.4
}
}
],
address: {
firstname: "Celina",
lastname: "Goalley",
company: "Thompson-Torp",
city: "Bellevue",
region: "Washington",
region_code: "WA",
postcode: "98004",
country: "US",
email: "celina.goalley@thompson-torp.com",
classification: "res",
street: "Floor 14, 10400 NE 4th St",
telephone: "417.519.3773"
},
options: {
unique_id: "1200009",
order_ref: "PO-44461",
shipping_method: "fedex_GROUND_HOME_DELIVERY",
custom_greeting: "Hello From the Walsh Group",
note: "a note to the warehouse Staff: Super fragile",
signature_required: "any",
saturday_delivery: false,
declared_value_service: true,
overbox: true,
requested_ship_date: "2023-04-15",
delayed_ship_date: null,
allocation_options: {
algorithms: [ "specific-locked" ],
allowed_stock_ids: [ 1 ]
},
instructions: [
{
note: "Follow these special instructions for packing.",
file_name: "special-instructions.pdf",
file_request: {
url: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
auth: [ "username", "password" ],
headers: { "X-Test": "foo" }
},
presentation: "once_per_shipment",
print_target: "LASER"
}
],
other_shipping_options: {
packaging: [
{
product_id: 62
},
{
sku: "BubbleWrap",
items: [ "34-737-8757" ]
},
{
sku: "ApprovalSticker",
items: [ "34-737-8757" ]
}
]
},
automation_data: {}
},
timestamp: {},
submitted_by: "api",
submitted_by_id: "6"
}