Table of Contents

Before Create Order Scripts

Cory M. Updated by Cory M.

"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).

See Scripting Basics to become more familiar with scripting in ShipStream in general and Before Create Order script Cookbook for solutions to common scripting needs.

How to Create a Before Create Order Script

  1. Navigate to System > Scripts.
  2. Click Create New Script at the top right.
  3. Select the Merchant to which the script will be applicable or "--All Merchants--" to have the script apply to all merchants.
  4. 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.
  5. Select Before Create Order as the Type.
  6. 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.
  7. 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.
  8. Click Save.
If the script is Active it will immediately take effect on incoming orders. Existing orders, even in New status, will not be affected by Before Create Order scripts.

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.

If any script throws an error, the subsequent scripts will be skipped as the order creation event has already failed.

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.

See System > Enumerations for the correct codes and IDs to use for various properties.

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.
See Before Create Order script Cookbook for solutions to common scripting requirements.

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
Use 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)
When checking for product properties be mindful that the "product" property will not exist if the SKU in the request does not match a SKU in the Merchant's catalog so you should use defensive techniques to avoid "Cannot read property '...' of undefined" type of errors.

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"
}
Some fields are optional or may be incorrectly missing from the request so it is best to write code defensively to avoid errors.

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
}
All of these fields are optional and may be missing from the request object so it is best to write code defensively to avoid errors.
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 noneanyadultindirect 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 the indirect signature required (If indirect is not supported by the carrier, this option will fall back to any). Currently only supported by FedEx.
  • default — May be used to defer to the default based on the carrier service type (If default is not supported by the carrier, this option will fall back to none).

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 soldnot_soldgiftsamplerepair_returnpersonal_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 defaultshipper (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 defaultall_or_nothingas_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

Sunday through Saturday

z

The day of the year (starting from 0)

0 through 365

F

A full textual representation of a month

January through December

G

24-hour format of an hour without leading zeros

0 through 23

i

Minutes with leading zeros

00 to 59

s

Seconds with leading zeros

00 to 59

c

ISO 8601 date

2004-02-12T15:19:21+00:00

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.

The custom field methods are invoked on an object with an upper-case "O" whereas the other fields above are accessed as properties of an object with a lower-case "o".
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"}

Email

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

Email

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

How did we do?

Scripting Basics

Preprocess Packing Solution Scripts

Contact