npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fedex-cross-border-api

v0.0.6

Published

Node wrapper for FedEx CrossBorder API client calls.

Downloads

1

Readme

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, ... }