Skip to content

Shipping

shipping : object

Add custom carrier and rates, and adjust markup.

Kind: global namespace

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

{city: "NEW YORK", state: "NY", type: "STANDARD"}

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"
}
Example
{
    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"]
}
Example
{
    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.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
}]
Example
// 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.
}
Example
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:

  • Error Only 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
    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"
    }
}