fedex-cross-border-api

0.0.6 • Public • Published

WARNING: DEV PRE-RELEASE

This module is not released or complete and should not be used until this message isn't here. It will be available via GitHub and NPM when it reaches v1.0.0 release status.

FedEx Cross Border API

This node module acts as a wrapper for the FedEx Cross Border API, allowing your node applications to consume v4.4 of the SOAP API and perform tasks for fulfilling international shipping for FedEx Cross Border customers.

It features client that functions with traditional node style callbacks, and client that uses ECMA 6 style promises. All of the Connect API methods are supported as of release v1.0.0, and details (as well as where objects differ in structure from official FECB docs) are listed below.

Purpose

Traditionally, FECB is integrated entirely on the ecommerce platform it is supporting as a fulfillment method. If your cart platform is running on node already, great! This software will provide a quick integration for you.

However, most common ecommerce platforms run on PHP, .net, or Java. Leaving aside the issues with these languages, of these three, only .net provides a suitably performant XML parser, and all three languages have their own issues about sharing server resources with external SOAP APIs. To avoid adding overhead that can nick your server response times or scalability, you may wish to use an external application to handle the majority of the FECB API work, and node is pretty performant in handling an XML workflow, and even *shudder* SOAP.

This wrapper will allow you to build an application to do all the FECB dirty work and interact with your ecommerce platform in a native, hopefully more performant manner than acting as a SOAP client on your server.

Installation

v.1.0.0 is available as an NPM package:

npm install fedex-cross-border-api

Basic Usage

Once installed locally or globally, require the module:

var FedExCrossBorder = require('fedex-cross-border-api');

To instantiate a client, you'll need a minimum of two arguments passed to the args object of either clients' constructor: a two letter language code (only english and spanish are currently supported by FECB API v4.4) and the merchant key for your FECB account:

var language = 'en';
var merchantKey = 'yourMerchantKeyForFECB';
var args = {
    "language": language,
    "merchantKey": merchantKey
};

Then you may create either a callback-based client:

var fecbClientCallbacks = new FedExCrossBorder.client(args);

Or a promise-based client:

var fecbClientPromises = new FedExCrossBorder.clientPromise(args);

Calling a method on the client is pretty straightforward; client methods match the method names in the FECB docs and WSDL file, and your request data is passed in an object as the first argument for each (details for each method/object below). Callback client methods return values via node 'standard' two argument callbacks, and Promise client methods, when assigned to a variable, are promises that return data from the API on success. Here's an example of each using the 'ConnectProductInfo':

// lets assume we've already created objects for each product here...
var productInfoArray = [
    productObject1,
    productObject2
];
 
// call to method using callback client
// we'll log the results to console
fecbClientCallbacks.productInfo(productInfoArray, function(error, result) {
 
    if (error) {
        console.log("Oh no! \n" + error.message);
    }
    
    else {
        console.log("Yay, we got stuff! \n" + JSON.stringify(result));
    }
 
});
 
// call to method using promise client
// we'll log results to console when promise is resolved or rejected
var sendProductInfo = fecbClientPromises.productInfo(productInfoArray);
sendProductInfo.then(function(result) {
 
    console.log("Yay, we got stuff! \n" + JSON.stringify(result));
 
}).catch((error) => {
 
    console.log("Oh no! \n" + error.message);
 
});

Client Constructors

Each constructor's first argument is an object containing properties that define the behavior of the client during method calls. The synchronous client also requires a second argument, the callback function. The 'args' object, as mentioned in the previous section, always requires a 'merchantKey' and a 'language' property. Both are ECMA 6 compliant 'classes' (basically prototypes with class-like syntax), so they are instantiated using the 'new' keyword, with constructor arguments after the class name. Full explanation of the usage for each constructor:

Client Constructor - Callbacks

Usage

new FedExCrossBorder.client(args(object))

Returns

FedExCBClientCallback Object

Valid Properties for 'args'
property valueType notes
language string(2) v4.4 supports 'en' or 'es'
merchantKey string(45) value provided by FECB
stripWrapper boolean default false
returnRaw boolean default false; only acknowledged if stripWrapper is false
returnSoapHeader boolean default false; only acknowledged if stripWrapper is false
returnFullResponse boolean default false; only acknowledged if stripWrapper is false

Client Constructor - Promises

Usage

new FedExCrossBorder.clientPromise(args(object))

Returns

FedExCBClientPromise Object

Valid Properties for 'args'
property valueType notes
language string(2) required, v4.4 supports 'en' or 'es'
merchantKey string(45) required, value provided by FECB
stripWrapper boolean default false
returnRaw boolean default false; only acknowledged if stripWrapper is false
returnSoapHeader boolean default false; only acknowledged if stripWrapper is false
returnFullResponse boolean default false; only acknowledged if stripWrapper is false

Optional Arguments of 'args' for both Constructors

In addition to the the required 'language' and 'merchantKey' properties, the argument object for the client constructors also accepts some optional properties, noted above. These affect how the client's methods return the successful response.

By default, methods return a result object that contain three properties: body, request, and statusCode. This body is an object parsed from the server's response body to the API call, statusCode is the http status for the response, and request echoes the request JS object sent to the API server.

For debugging or other logical purposes, the soapHeader (as JSON), the raw response string, and/or the full response JS object can be added to the result object of all methods by setting the 'returnSoapHeader', 'returnRaw' and/or 'returnFullResponse arguments to true, respctively. Setting 'returnSoapHeader' to true adds the 'soapHeader' property to the result object, which contains a JSON encoded soapHeader of the API response. Setting 'returnRaw' to true adds the 'raw' property to the result object, which contains the raw XML string of the API response body. Setting 'returnFullResponse' adds the 'response' property, a JS object containing the full response from the server as a Node.js http.IncomingMessage. Each of these are IN ADDITION to the 'body', 'statusCode', and 'request' properties, which are always returned if 'stripWrapper' is false.

But, if you'd like to go in the opposite direction and return ONLY the body object, without a wrapper, setting the 'stripWrapper' property of 'args' to true will return the 'body' object without another object wrapping it, and WILL NOT return statusCode or request. This option also disables the effects of 'returnFullResponse', 'returnRaw' and 'returnSoapHeader'.

Examples focus on the callback based client, but the same rules apply for the promise client as well... except the result is an argument of your promise success handler rather than of the callback.

Examples
var FedExCrossBorder = require('fedex-cross-border-api');
var args1 = {
    "language": "en",
    "merchantKey": "***myMerchantKeyValue***"
};
var args2 = {
    "language": "en",
    "merchantKey": "***myMerchantKeyValue***",
    "stripWrapper": true
    // if returnRaw, returnSoapHeader, and/or returnFullResponse 
    // are set to true here,
    // they will be ignored
};
var args3 = {
    "language": "en",
    "merchantKey": "***myMerchantKeyValue***",
    // stripWrapper defaults to false
    "returnRaw": true
};
var args4 = {
    "language": "en",
    "merchantKey": "***myMerchantKeyValue***",
    // stripWrapper defaults to false
    "returnSoapHeader": true
};
var args5 = {
    "language": "en",
    "merchantKey": "***myMerchantKeyValue***",
    // stripWrapper defaults to false
    "returnFullResponse": true
}
 
var fecbClientDefault = new FedExCrossBorder.client(args1);
// methods for this client will return a result object like this:
// {
//     body: {
// property1: 'result1',
// etc: etc...
//     },
// request: {
// requestprop1: 'prop1',
// etc: etc...
// },
// statusCode: 200
// }
 
var fecbClientLean = new FedExCrossBorder.client(args2);
// methods for this client will only return the body object AS the result:
// {
// property1: 'result1',
// etc: etc...
// }
 
var fecbClientRaw = new FedExCrossBorder.client(args3);
// methods for this client will return a result object with both raw and response values:
// {
//     body: {
// property1: 'result1',
// etc: etc...
//     },
// request: {
// requestprop1: 'prop1',
// etc: etc...
// },
// statusCode: 200,
// raw: '<ns1:ConnectProductInfoResponse><return xsi:type="ns1:ConnectProductInfoResponse">
// <error xsi:type="xsd:int">0</error><errorMessage xsi:type="xsd:string"></errorMessage>
// <errorMessageDetail xsi:type="xsd:string"></errorMessageDetail></return</ns1:ConnectProductInfoResponse>'
// }
 
var fecbClientHeaders = new FedExCrossBorder.client(args4);
// methods for this client will return a result object with both soapHeader and response values:
// {
//     body: {
// property1: 'result1',
// etc: etc...
//     },
// request: {
// requestprop1: 'prop1',
// etc: etc...
// },
// statusCode: 200,
// soapHeader: '{"xmlns:SOAP-ENV": "http://schemas.xmlsoap.org/soap/envelope/", 
// "xmlns:ns1": "https://api.crossborder.fedex.com/services/v44", 
// "xmlns:xsd": "http://www.w3.org/2001/XMLSchema",
// "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
// "xmlns:SOAP-ENC": "http://schemas.xmlsoap.org/soap/encoding/",
// "SOAP-ENV:encodingStyle": "http://schemas.xmlsoap.org/soap/encoding/"}'
// }
 
// IN CASE IT WASN'T OBVIOUS... these are not the actual values the API returns...
// Just illustrating the effects of the constructor args...
 

BOILERPLATE FOR EACH METHOD

Arguments Passed to Callback
argument valueType notes
error object(JS Error or subclass thereof) false if no error occurs
result object by default contains 'body'(JS Object), 'request'(JS Object), and 'statusCode'(number)
Arguments Passed to Promise resolution function
argument valueType notes
result object by default contains 'body'(JS Object), 'request'(JS Object), and 'statusCode'(number)
Arguments Passed to Promise rejection function
argument valueType notes
error object(JS Error or subclass thereof)

Methods

Methods for each client are 1:1 matches for the SOAP API methods documented by FECB, but the function names and arguments have changed from the SOAP equivalents. Operations for both clients are identical, but there's an extra argument for the callback client (for the callback, of course!).

ConnectProductInfo

Purpose

Sends product data to FECB to create or update product details in their database.

Usage

Callback - client.productInfo(request, callback)

Promise - client.productInfo(request)

Request Object Parameters

The 'request' argument for this method is an array of objects, one per product:

[
    {
        "id": "string(255)",
        "description": "string(250)",
        "price": "float",
        "currency": "string(3)",
        "exportHub": "string(3)",
        "origin": "string(2)",
        "itemInformation": {
            "w": "float",
            "h": "float",
            "l": "float",
            "wt": "float"
        },
        "optionalArgs": {
            "productName": "string(255)",
            "url": "string(255)",
            "imageUrl": "string(255)",
            "hsCode": "string(15)",
            "eccn": "string(15)",
            "hazFlag": "boolean",
            "licenseFlag": "array -OR- comma-separated string (limited to ~84 country codes)",
            "importFlag": "array -OR- comma-separated string (limited to ~84 country codes)",
            "productType": "string(255)"
        } 
    },
    {
    (additional objects, if any)
    }
]

The array must contain at least ONE product object. All object parameters are required except 'optionalArgs', which can, as the name suggests, contain any number of the optional parameters or be omitted entirely. Also, if w, l, and h are defined in the 'itemInformation' object, wt is optional, and vice versa.

Arguments Passed to Callback
argument valueType notes
error object(JS Error or subclass thereof) false if no error occurs
result object by default contains 'body'(JS Object), 'request'(JS Object), and 'statusCode'(number)
Arguments Passed to Promise resolution function
argument valueType notes
result object by default contains 'body'(JS Object), 'request'(JS Object), and 'statusCode'(number)
Arguments Passed to Promise rejection function
argument valueType notes
error object(JS Error or subclass thereof)

ConnectLandedCost

ConnectOrder

ConnectOrderTrackingUpdate

ConnectOrderRemove

ConnectSkuStatus

Objects

Several classes are available to use, with built in validation and some santization as part of the constructor. These are used by the client methods internally, but are exposed for your use as well, if you need them.

cartonsDat

Purpose

Contains dimensions and/or weight for a carton or item

Constructor Usage

new FedExCrossBorder.cartonsDat(lengthIn, widthIn, heightIn, weightLb);

Constructor Arguments
arguments valueType notes
lengthIn float(4) item length in inches
widthIn float(4) item width in inches
heightIn float(4) item height in inches
weightLb float(4) item weight in pounds
Methods

getXmlString() - no arguments, returns SOAP formatted XML string of object

productInfoDat

Purpose

Contains product details for updating FECB product database

Constructor Usage

new FedExCrossBorder.productInfoDat(id, description, price, currency, exportHub, origin, itemInformation, optionalArgs)

Constructor Arguments
arguments valueType notes
id string unique product identifier
description string human readable product description
price float(13,4) sales price for item
currency string(3) three letter identifier for item price currency
exportHub string(3) three letter identifier for FECB distribution hub
origin string(2) two letter identifier for product country of origin
iteminformation object cartonsDat physical data for item
optionalArgs object optional; may contain properties matching any of the optionalArgs in the below table.
optionalArgs Properties

All properties, like the optionalArgs argument itself, are optional.

property valueType notes
productName string human readable identifier for product
url string URL that points to product on ecommerce site
imageUrl string URL that points to product image
hsCode string(10) code that allows the calculation of tax payable in the destination country of the shipment
eccn string(15) eccn code for product
hazFlag boolean whether product is flagged as hazardous; default false, set to true if product is flagged as hazardous
importFlag string -OR- array comma separated string or array of two letter strings indicating countries product is forbidden to enter
licenseFlag string -OR- array comma separated string or array of two letter strings indicating countries product requires license to enter
productType string merchant category associated with this item
Methods

getXmlString() - no arguments, returns SOAP formatted XML string of object

productInfo

Purpose

Contains basic product details for landedCost interface

Constructor Usage

new FedExCrossBorder.productInfo(id, quantity, price, exportHub);

Constructor Arguments
arguments valueType notes
id string unique product identifier
quantity int quantity of items in shipment
price float(13,4) sales price for item
exportHub string(3) three letter identifier for FECB distribution hub
Methods

getXmlString() - no arguments, returns SOAP formatted XML string of object

orderInformation

Purpose

Contains line item detail for an FECB order

Constructor Usage

new FedExCrossBorder.orderInformation(id, quantity, price, currency, optionalArgs);

Constructor Arguments
arguments valueType notes
id string unique product identifier
quantity int quantity of items in shipment
price float(13,4) sales price for item
currency string(2) two letter identifier for currency of line item's price
optionalArgs object optional; may contain properties matching any of the optionalArgs in the below table.
optionalArgs Properties

All properties, like the optionalArgs argument itself, are optional.

property valueType notes
exportHub string(3) three letter identifier for FECB distribution hub
carrier string -OR- int identifier for shipping agent; integers 1-6 or a valid carrier value are accepted (assigns to 6, 'other', by default or if invalid value passed)
trackingNumber string(100) carrier tracking code for order
Methods

getXmlString() - no arguments, returns SOAP formatted XML string of object

trackingList

Purpose

Contains tracking details for orderTrackingUpdate interface

Constructor Usage

new FedExCrossBorder.trackingList(id, quantity, trackingNumber, carrier);

Constructor Arguments
arguments valueType notes
id string unique product identifier
quantity int quantity of items in shipment
trackingNumber string(100) carrier tracking code for order
carrier string -OR- int identifier for shipping agent; integers 1-6 or a valid carrier value are accepted (assigns to 6, 'other', by default or if invalid value passed)
Methods

getXmlString() - no arguments, returns SOAP formatted XML string of object

productsIdDat

Purpose

Contains product id for skuStatus interface

Constructor Usage

new FedExCrossBorder.productsIdDat(id);

Constructor Arguments
arguments valueType notes
id string unique product identifier
Methods

getXmlString() - no arguments, returns SOAP formatted XML string of object

Functions

Utility functions used by the clients are also exposed for your use, should you need them.

validateLanguage

Purpose

Determine whether a string is a valid FECB supported language identifier

Usage

FedExCrossBorder.validateLanguage(languageCode);

Arguments
arguments valueType notes
languageCode string(2) language identifier
Returns

(boolean)

true = valid language code false = invalid language code

validateCountry

Purpose

Determine whether a string is a valid FECB supported country identifier

Usage

FedExCrossBorder.validateCountry(countryCode);

Arguments
arguments valueType notes
countryCode string(2) country identifier
Returns

(boolean)

true = valid country code false = invalid country code

validateCurrency

Purpose

Determine whether a string is a valid FECB supported currency identifier

Usage

FedExCrossBorder.validateCurrency(currencyCode);

Arguments
arguments valueType notes
currencyCode string(3) currency identifier
Returns

(boolean)

true = valid currency code false = invalid currency code

getCountryForHub

Purpose

Given a valid three character facility code string, returns the two character country code the hub facility is located in.

Usage

FedExCrossBorder.getCountryForHub(facilityCode);

Arguments
arguments valueType notes
facilityCode string(3) FECB hub facility identifier
Returns

(string(2))

Two letter country code for the given FECB hub facility

getCarrierCode

Purpose

Given a valid three character facility code string, returns the two character country code the hub facility is located in.

Usage

FedExCrossBorder.getCarrierCode(carrierString);

Arguments
arguments valueType notes
carrierString string String identifying FECB carrier; one of ['UPS', 'FedEx', 'DHL', 'USPS', 'EMS']; case-sensitive
Returns

(int(1))

integer between 1-6 inclusive that is related to the given carrierString; returns 6 if string is not matched (for 'Other')

Constants

If the objects and functions aren't enough, the constants containing various FECB provided tables, as of API v4.4, (also listed in CSV format in the /csv directory of this package) are exposed for direct access, should you need them.

exportHubs

Purpose

Array of objects, each containing a FECB hub facility code and the related country code

Structure

[ { facility: string(3), country: string(2) }, ... ]

countryCodes

Purpose

Array of objects, each containing a country name, the related country code, and the related currency code

Structure

[ { name: string, code: string(2), currency: string(3) }, ... ]

languages

Purpose

Array of strings, each containing a FECB supported language identifier

Structure

[ 'languageCode', ... ]

carriers

Purpose

Object containing a carrier string property that contains the integer identifier for it

Structure

{ carrier: id, ... }

Package Sidebar

Install

npm i fedex-cross-border-api

Weekly Downloads

3

Version

0.0.6

License

MIT

Last publish

Collaborators

  • bangerkuwranger