Shipping
shipping : object
Add custom carrier and rates, and adjust markup.
Kind: global namespace
- shipping :
object- .Address
- .Package
- .getZIPCode(zipcode, country) ⇒
Object - .getPackagingByID(id) ⇒
Promise.<Object> - .getRetailPriceWithMarkup(cost, retail, carrier, service, weightOz, packaging) ⇒
Promise.<number> - .convertMeteredToRetail(rate_price) ⇒
number - .getLabelDate([carrier]) ⇒
Promise.<Date> - .getCarrierName(carrierId) ⇒
string - .getServiceName(serviceId, [carrier], [stripInternational]) ⇒
string - .defineCarrierName(id, name, dropoff, regions, hide)
- .defineServiceName(id, name, carrierName, nameTM)
- .getCustomsFormImages(parcel, incoterm, trackingNumber, invoiceNumber, date) ⇒
Promise.<Array.<Jimp>> - .registerRateEndpoint(getRates, purchase, idPrefix, [extraOptions])
- .registerStampEndpoint(id, name, getRates, purchase, purchaseCorrection)
- .addRateWarning(message)
- .registerAddressVerificationProvider(id, name, verifyFn)
- .registerCarrierPickupMenu(carrierName, displayName, onPickup) ⇒
undefined - .registerMarkupCalculator(markupFn)
- .registerInsuranceProvider(id, name, cardText, maxValue, getQuote, insure)
- .getRecentShipments(plugin_sourceid, sinceDate, includeVoided, onlyNotShipped) ⇒
Promise.<Array> - .addShipmentToDatabase(plugin_sourceid, prepaid, tracking, carrier, service, to_address, from_address, create_date, metadata) ⇒
Promise - .markShipmentVoid(shipmentid, voided) ⇒
Promise - .markShipmentPickedUp(shipmentid, timestamp) ⇒
Promise - .getParcel() ⇒
Package - .setParcel(newParcel, parcelChangeEventSource)
- .isOfficeMode() ⇒
boolean - .getAddressFieldInfo(country) ⇒
Object
shipping.Address
Kind: static class of shipping
new Address()
A class representing an address.
shipping.Package
Kind: static class of shipping
new Package()
A class representing a package/parcel. See docs.
shipping.getZIPCode(zipcode, country) ⇒ Object
Get data for a ZIP Code.
Kind: static method of shipping
Returns: Object - Data about the ZIP code. See example. Fields may be empty if not available. Type may be "STANDARD", "UNIQUE", "PO BOX", or "MILITARY".
| Param | Type | Default | Description |
|---|---|---|---|
| zipcode | string |
ZIP or postal code. | |
| country | string |
"US" |
Two-letter ISO country code. |
Example
shipping.getPackagingByID(id) ⇒ Promise.<Object>
Get a parcel's packaging type from PostalPoint's internal ID for it.
Kind: static method of shipping
Returns: Promise.<Object> - See examples.
| Param | Type |
|---|---|
| id | number |
Example
{
id: 100,
type: "Parcel",
img: "box.png",
name: "Box",
service: "",
l: -1,
w: -1,
h: -1,
weight: true,
hazmat: true,
source: "Customer"
}
{
id: 1,
type: "FlatRateEnvelope",
img: "pm-fres.png",
name: "Flat Rate Envelope",
service: "Priority",
l: -2,
w: -2,
h: -2,
weight: false,
hazmat: true,
usps_supplied: true,
envelope: true,
source: "USPS",
skus: ["PS00001000014", "PS00001000012", "PS00001000027", "PS00001000064", "PS00001001921", "PS00001035000", "PS00001036014", "PS00001128600", "https://qr.usps.com/epsspu?p=30", "https://qr.usps.com/epsspu?p=8"]
}
{
id: 201,
type: "UPSLetter",
img: "ups-env.png",
name: "Envelope",
carrier: "UPS",
l: -2,
w: -2,
h: -2,
weight: true,
hazmat: true,
source: "OtherCarrier"
}
shipping.getRetailPriceWithMarkup(cost, retail, carrier, service, weightOz, packaging) ⇒ Promise.<number>
Calculate the retail price for a shipment rate based on the configured margin settings.
Kind: static method of shipping
Returns: Promise.<number> - The amount to charge the customer
| Param | Type | Description |
|---|---|---|
| cost | number |
Cost of shipment to business |
| retail | number |
Default retail price from label provider |
| carrier | string |
Shipment carrier |
| service | string |
Shipment service |
| weightOz | number |
The weight of the shipment in ounces, or null if not available. |
| packaging | string |
An empty string if not available, or "Letter", "FlatRateEnvelope", etc. |
shipping.convertMeteredToRetail(rate_price) ⇒ number
Convert a USPS metered/PC postage letter rate to the retail stamp price by adding the difference based on the current USPS Notice 123 rate chart.
Kind: static method of shipping
Returns: number - the retail price for the given metered rate (for example, 0.78)
| Param | Type | Description |
|---|---|---|
| rate_price | number |
Metered price (for example, 0.74) |
shipping.getLabelDate([carrier]) ⇒ Promise.<Date>
Get the date to use for a label's ship date, based on the next carrier pickup. If no date is found for the next pickup, defaults to the current date and time.
Kind: static method of shipping
| Param | Type | Default | Description |
|---|---|---|---|
| [carrier] | string |
"\"\"" |
Carrier ID or name. |
shipping.getCarrierName(carrierId) ⇒ string
Converts the carrier ID string into a consistent and human-readable name.
Kind: static method of shipping
| Param | Type |
|---|---|
| carrierId | string |
shipping.getServiceName(serviceId, [carrier], [stripInternational]) ⇒ string
Converts the service ID string into a consistent and human-readable name. Set the carrier ID for better results.
Kind: static method of shipping
| Param | Type | Default | Description |
|---|---|---|---|
| serviceId | string |
||
| [carrier] | string |
"\"USPS\"" |
Carrier ID or name (i.e. the string sent to or received from getCarrierName()) |
| [stripInternational] | boolean |
false |
If true, remove "International" from the service name. For example, "Priority Mail International" becomes "Priority Mail", to allow matching a domestic USPS service with the international version of that service. |
shipping.defineCarrierName(id, name, dropoff, regions, hide)
Add a new carrier ID-name pair for use by getCarrierName.
Adding multiple IDs for the same carrier name is permitted.
Adding new IDs for a pre-existing carrier name is also permitted.
id and name must be non-empty strings or this function will log a warning and do nothing.
Kind: static method of shipping
| Param | Type | Default | Description |
|---|---|---|---|
| id | string |
An internal ID code that might be passed to getCarrierName. | |
| name | string |
The human-readable carrier name for display. | |
| dropoff | boolean |
false |
True if drop-off scans for this carrier can be handled (i.e. there's a handler set with global.apis.barcode.onPrepaidScan for it) |
| regions | array |
Array of two-letter ISO country codes where this carrier is available. Carriers are hidden from list UIs if the user's country isn't on this list. An empty array or undefined means global availability. | |
| hide | boolean |
false |
If true, the carrier name won't be shown to the user in some UIs, but will still be available for all other purposes. |
shipping.defineServiceName(id, name, carrierName, nameTM)
Add a new shipping service ID-name pair for use by getServiceName.
Adding multiple IDs for the same service name is permitted.
Adding new IDs for a pre-existing service name is also permitted.
carrierName must match the name or an ID of an already-defined carrier or this function will log a warning and do nothing.
id, name, and carrierName must be non-empty strings or this function will log a warning and do nothing.
Kind: static method of shipping
| Param | Type | Description |
|---|---|---|
| id | string |
An internal ID code that might be passed to getServiceName. |
| name | string |
The human-readable service name for display. |
| carrierName | string |
The human-readable carrier name for display. |
| nameTM | string | null |
An alternate version of the service name to display, including trademark symbols. Will be used instead of name in some places such as shipping rate cards, but not on receipts or other places that might not support non-ASCII symbols. |
shipping.getCustomsFormImages(parcel, incoterm, trackingNumber, invoiceNumber, date) ⇒ Promise.<Array.<Jimp>>
Generate a 4x6 inch customs form/commercial invoice for printing on a label printer.
Kind: static method of shipping
Returns: Promise.<Array.<Jimp>> - an array of Jimp image objects.
Can be sent as-is to the label printer functions. Each array element is a page of the form.
Normally one page is returned, but additional "overflow" pages are added if there isn't room to list
all the package contents on one page.
| Param | Type | Default | Description |
|---|---|---|---|
| parcel | Object |
A Package object to pull customs data from. | |
| incoterm | string |
"\"DDU\"" |
Incoterm. |
| trackingNumber | string |
"\"\"" |
The tracking number for the shipment. |
| invoiceNumber | string |
"\"\"" |
The commercial invoice number for the shipment. |
| date | Date |
Invoice/form date. If undefined, the current date is assumed. |
shipping.registerRateEndpoint(getRates, purchase, idPrefix, [extraOptions])
Register the plugin as a shipping rate and label provider. See the Shipping example plugin.
Kind: static method of shipping
| Param | Type | Default | Description |
|---|---|---|---|
| getRates | function |
A function passed a Parcel object to get rates for. Returns a Promise that resolves to an array of rate objects. | |
| purchase | function |
A function passed a rate ID to purchase. Returns a Promise that resolves to the label information. | |
| idPrefix | string |
A unique string that will be prefixing all rate IDs from this plugin. | |
| [extraOptions] | Object |
{} |
Extra optional functions/options that can be implemented. See example. |
Example
// getRates sample return value:
[{
rateid: `${idPrefix}_${global.apis.util.uuid.v4()}`,
carrier: "CarrierID",
carrierName: "Carrier Name",
service: "CARRIER_SERVICE_ID",
cost_rate: 10,
retail_rate: 15,
delivery_days: 3,
delivery_date: null,
guaranteed: true,
serviceName: "Service Name",
color: "green" // Rate card color
}]
// purchase sample return value:
{
label: labelImageToPrint,
labeltype: "PNG",
receiptItem: ReceiptItem, // Data to add to the transaction receipt.
tracking: "12345678901234567890",
cost: 10.0,
price: 15.0,
carrier: "Carrier Name",
service: "Service Name",
delivery_days: 3,
delivery_date: 1234567890, // UNIX timestamp
to_address: new global.apis.shipping.Address(),
from_address: new global.apis.shipping.Address(),
plugin_sourceid: "", // Unique string for your plugin; saved alongside shipment in store database to allow queries to filter shipments by source.
metadata: {} // Object containing extra data to be stored in the database. Serialized to JSON.
}
extraOptions = {
getRecentLabels: async function () {
// Return a list of recently purchased/printed labels for reprinting and/or voiding/refund purposes.
// Your plugin must also implement voidLabel() (below) or it won't be queried for recent labels.
return [
{
id: `${idPrefix}_${yourShipmentID}`,
created: Date, // Date object of the label/shipment date. Used for ordering the list.
refund_status: false, // false to show a refund/void button, otherwise a short string to show such as "Refunded" or "Refund processing" or "Refund rejected"
tracking: "", // Shipment tracking number or an empty string if it has no tracking.
label_urls: [], // Array of URLs to download the label image(s) from if the user requests a reprint.
// If empty or not an array, the reprint button is disabled.
// May also be a function that returns a Promise that resolves to the described array.
// If this is a function, it's passed this label object as an argument.
to: new global.apis.shipping.Address(), // Destination/to address.
from: new global.apis.shipping.Address(), // Return/from address.
carrier: global.apis.shipping.getCarrierName(""), // Carrier name
service: global.apis.shipping.getServiceName("") // Shipping service
}
]
},
voidLabel: async function (id) {
// Try to void a label with the ID provided (an `id` returned in getRecentLabels)
// Returns a status string that's displayed to the user in a dialog box, such as "Label refunded." or "Refund request submitted." or "Refund request rejected."
return "Void request status message goes here";
}
}
shipping.registerStampEndpoint(id, name, getRates, purchase, purchaseCorrection)
Register the plugin as a USPS postage indicia provider for First Class Mail.
Kind: static method of shipping
| Param | Type | Description |
|---|---|---|
| id | string |
Unique alphanumeric ID for this provider. |
| name | string |
Human-readable name for this provider. |
| getRates | function |
see registerRateEndpoint. Any returned rates that aren't for USPS First-Class Mail are ignored. |
| purchase | function |
see registerRateEndpoint. Returned data must also include a imageSettings object, see example. |
| purchaseCorrection | function | null |
Same as purchase but instead of a rate ID the argument is a string number of cents to print on the postage. If null, postage correction stamps will be disabled. |
Example
// imageSettings object returned by purchase:
{
includeFIM: true, // If true, a FIM D (Facing Identification Mark, variant D) is printed to the left of the indicia. Required for letter-size postage.
indiciaX: px, // Leftmost pixel in label image to print (pixels to the left will be cropped out). If negative, counts from the right side of the label instead.
indiciaY: px, // Topmost pixel in label image (pixels above will be cropped out). If negative, counts from the right side of the label instead.
indiciaWidth: px, // Width in pixels to crop to, starting from indiciaX on the left side and moving right
indiciaHeight: px, // Height in pixels to crop to, starting from indiciaY on the top side and moving down
dpi: 300, // Native DPI (pixels per inch) of your label. PostalPoint scales your image to 300 DPI after cropping.
rotate: 0 // If not zero, image is rotated this many degrees (90, 180, 270, etc) before any processing.
}
// Note: Depending on indicia width, FIM presence, and label width, the indicia may be
// scaled slightly smaller after cropping to the dimensions provided in order to fit on
// the label media size in use. In our testing with the widest indicia (PDF417),
// the barcode in the indicia is still scannable (and the human-readable text still legible)
// after this adjustment, but you might wish to test the worst case scenario:
// `includeFIM: true` on a 1.1x3.5 "standard address" label printed at 200dpi.
shipping.addRateWarning(message)
If an error or warning is encountered while getting shipping rates (such as an invalid/unsupported combination of shipment options/packaging for a particular service) send a message string to this function and it will be available for the user to read when the rate cards are displayed on screen.
Kind: static method of shipping
| Param | Type | Description |
|---|---|---|
| message | string | Array.<string> |
A string message or an array of messages. |
shipping.registerAddressVerificationProvider(id, name, verifyFn)
Add an address validation/sanitization/verification provider. The user's preferred provider will be called with a shipment's to and from addresses, and will return the validated addresses. The verified addresses will be passed on to rate provider plugins.
Kind: static method of shipping
| Param | Type | Description |
|---|---|---|
| id | string |
Unique alphanumeric ID for this provider. |
| name | string |
Human-readable display name for this provider. |
| verifyFn | function |
See example. |
Example
registerAddressVerificationProvider("example", "Example", async function (addressData) {
// This function is passed the data structure shown below, and must return the same structure but updated with the validated addresses.
return {
to: new global.apis.shipping.Address(),
from: new global.apis.shipping.Address(),
toVerified: true, // If the to address was verified
fromVerified: true, // If the from/return address was verified
toErrors: [], // String messages to display on the to address verification checkmark/warning icon
fromErrors: [] // String messages to display on the from/return address verification checkmark/warning icon
}
});
shipping.registerCarrierPickupMenu(carrierName, displayName, onPickup) ⇒ undefined
Add an entry to the Carrier Pickup tool for setting the next pickup date
for your specific carrier/plugin. Used with getLabelDate.
Kind: static method of shipping
| Param | Type | Description |
|---|---|---|
| carrierName | string |
Carrier name. Pass to getLabelDate to get the next pickup date as selected by the user (or auto-incremented). |
| displayName | string | null |
Optional different name to show in the tool. |
| onPickup | function | null |
Optional function to run when the user marks all packages for the carrier as picked up. |
shipping.registerMarkupCalculator(markupFn)
Register the plugin to modify PostalPoint's shipping markup calculation during shipment rating.
Kind: static method of shipping
Throws:
ErrorOnly one plugin may register with this function; any subsequent attempts to register will throw an Error.
| Param | Type | Description |
|---|---|---|
| markupFn | function |
A function that must return either the retail price to charge for this rate, or false to opt-out of setting this particular rate. |
Example
global.apis.shipping.registerMarkupCalculator(
// Parameters:
// cost: Cost to shipper
// retail: Carrier-suggested retail price
// suggested: PostalPoint-suggested retail (default margin calc)
// carrier: Shipping carrier name
// service: Shipping service code
// weightOz: The weight of the shipment in ounces, or null if not available.
// packaging: An empty string if not available, or "Letter", "FlatRateEnvelope", etc. See https://docs.easypost.com/docs/parcels#predefined-package
// parcel: The Parcel object for this shipment. May be null for some rate-only requests without a shipment, such as USPS price calculations.
function (cost, retail, suggested, carrier, service, weightOz, packaging, parcel) {
if (carrier == "USPS") {
if (service == "First-Class Mail") {
// Handle First-Class Mail differently if it's a 1oz letter (i.e. Forever stamp)
if (weightOz <= 1 && packaging == "Letter") {
return retail + 0.05;
} else {
return retail + 0.25;
}
}
// Handle flat rate envelopes differently
if (global.apis.shipping.getServiceName(service, carrier) == "Priority Mail" && packaging == "FlatRateEnvelope") {
return retail + 1.0;
}
return suggested + 2.0; // Charge the PostalPoint-calculated amount plus $2
} else {
return cost * 2; // Charges the customer double the shipment's cost.
}
}
);
shipping.registerInsuranceProvider(id, name, cardText, maxValue, getQuote, insure)
Add a shipping insurance provider.
Kind: static method of shipping
| Param | Type | Description |
|---|---|---|
| id | string | null |
Unique ID for the provider. Will be autogenerated if null. |
| name | string |
Human-readable name for the provider. Shown as the card heading on the Insurance section of the Ship screen. |
| cardText | string |
Text or HTML to display on the Ship screen card for this provider. |
| maxValue | number |
The largest number that will be accepted for the "Insured for" value. |
| getQuote | function |
Returns the cost and retail price for insuring the parcel, or a Promise that resolves into the same. See the example for details. |
| insure | function |
Insure the parcel and add the insurance details to the receipt. See example. |
Example
async function getQuote(value, parcel, carrier, service, rateObject) {
// See shipping rate provider documentation for rateObject structure.
// Do math, etc
var cost = value / 100;
return {
cost: cost,
retail: cost * 2
};
// Or, to remove this shipping rate from the list,
// because the shipment/carrier/service combination
// is not eligible for insurance:
return false;
}
async function insure(value, parcel, carrier = "USPS", service = "Priority", trackingNumber = "94055...") {
// Purchase the insurance
var cost = value / 100;
var retailPrice = cost * 2;
var costPrice = cost;
var receiptitem = new global.apis.pos.ReceiptItem(`sampleinsurance_${trackingNumber}`,
"Sample Insurance",
"Insured for " + global.apis.i18n.moneyString(value),
retailPrice, 1, costPrice, 0
);
receiptitem.merch = true;
receiptitem.category = "Shipping Insurance";
receiptitem.barcode = trackingNumber;
global.apis.pos.addReceiptItem(receiptitem);
}
global.apis.shipping.registerInsuranceProvider(
"sampleproviderid", "Sample Insurance",
"Insurance coverage from Sample Insurance. $1 per $100 of value.",
5000, getQuote, insure);
shipping.getRecentShipments(plugin_sourceid, sinceDate, includeVoided, onlyNotShipped) ⇒ Promise.<Array>
Get recent shipments for a plugin_sourceid.
Kind: static method of shipping
Returns: Promise.<Array> - List of shipments. See example.
| Param | Type | Default | Description |
|---|---|---|---|
| plugin_sourceid | string |
See data returned from the purchase function of registerRateEndpoint |
|
| sinceDate | Date | null |
|
Get shipments created after this Date object. If not set, returns all shipments from the past 7 days. |
| includeVoided | Boolean |
false |
If true, response includes voided shipments. |
| onlyNotShipped | Boolean |
false |
If true, response only includes shipments without a recorded carrier pickup timestamp. |
Example
// Sample result from this function:
// All fields except `id` and `created` might be null.
{
id: 123, // Internal database ID for shipment
shipmentid: "xxx", // The `shipmentid` returned from a label purchase, or null if not provided
customeruuid: "string", // Customer UUID string
prepaid: false, // True if a prepaid drop-off
voided: false, // True if label marked as voided
tracking: "string", // Tracking number
carrier: "string",
service: "string",
created: Date,
shipped: Date, // Date and time the package was marked as picked up by the carrier.
metadata: {}, // Whatever was returned by the purchase function that created the shipment. Stored internally as a JSON string and parsed before returning. If JSON can't be parsed, is set to null.
to_address: Address,
from_address: Address
}
shipping.addShipmentToDatabase(plugin_sourceid, prepaid, tracking, carrier, service, to_address, from_address, create_date, metadata) ⇒ Promise
Manually add a shipment record to the store database. This is done automatically when a label is purchased, and only needs to be done with this function if a shipment is created outside a normal PostalPoint workflow (such as, for example, when a shipment is created by a dropoff QR code handler that doesn't return prepaid drop-off shipment data)
Kind: static method of shipping
Returns: Promise - Result of the database query.
| Param | Type | Description |
|---|---|---|
| plugin_sourceid | string |
Shipment plugin source ID. See getRecentShipments and registerRateEndpoint |
| prepaid | boolean |
If the shipment is a prepaid drop-off. Default is false. |
| tracking | string | null |
Tracking number. |
| carrier | string | null |
Carrier ID or name. |
| service | string | null |
Service ID or name. |
| to_address | Address | null |
An Address object for the destination address. |
| from_address | Address | null |
An Address object for the return/origin/customer address. |
| create_date | Date | number | null |
Date or UNIX timestamp when the shipment was created. Defaults to now if not set. |
| metadata | Object | null |
An object for holding other data about a shipment. Will be serialized to JSON. If not an Object, will be saved as {}. |
shipping.markShipmentVoid(shipmentid, voided) ⇒ Promise
Mark a shipment as voided in the database.
Kind: static method of shipping
| Param | Type | Default | Description |
|---|---|---|---|
| shipmentid | Integer |
The internal database ID for the shipment, returned in getRecentShipments | |
| voided | Boolean |
true |
Set to false to un-void a previously voided shipment. |
shipping.markShipmentPickedUp(shipmentid, timestamp) ⇒ Promise
Mark an outgoing shipment in the database as picked up by the carrier.
Kind: static method of shipping
| Param | Type | Default | Description |
|---|---|---|---|
| shipmentid | Integer |
The internal database ID for the shipment, returned in getRecentShipments | |
| timestamp | Date | Integer | null |
|
The Date or UNIX timestamp (in seconds) of the pickup. Defaults to the current date and time if not a Date or number. |
shipping.getParcel() ⇒ Package
Get the current in-progress shipment's data.
Kind: static method of shipping
Returns: Package - See Parcel/Package docs
shipping.setParcel(newParcel, parcelChangeEventSource)
Set/overwrite the current in-progress shipment's data.
Kind: static method of shipping
| Param | Type | Description |
|---|---|---|
| newParcel | Package |
|
| parcelChangeEventSource | string | null |
An optional string sent as the data for the parcelUpdated event. |
shipping.isOfficeMode() ⇒ boolean
Check if PostalPoint is running the shipment in "office mode", i.e. the customer should be charged the cost price.
Kind: static method of shipping
Returns: boolean - true if office mode enabled, otherwise false.
shipping.getAddressFieldInfo(country) ⇒ Object
Get info on address fields for a given country.
Kind: static method of shipping
Returns: Object - See example.
| Param | Type | Description |
|---|---|---|
| country | string |
two-letter ISO country code. |
Example
{
fields: { // False if field not applicable for addresses in this country.
name: true,
company: true,
street1: true,
street2: true,
city: true,
state: true,
zip: true
},
labels: { // Human-readable form field labels, localized, and country-dependent
name: "Name",
company: "Company",
street1: "Address",
street2: "Address Line 2",
city: "City/Suburb/District/Locality",
state: "State/Province",
zip: "Postal Code"
},
placeholders: {
name: "John Doe",
company: "ABC Inc",
street1: "123 Example St",
street2: "Apt 2",
city: "(Not Required)",
state: "",
zip: "12345"
}
}