Saltar al contenido principal

Ejemplo de integración con FedEx

En este tutorial verás cómo integrar FedEx.

1. Preparación previa​

1.1. Crea una cuenta en FedEx

Crea una cuenta en el portal para desarrolladores.

1.2. Crea los proyectos y obtén los tokens

Crea 2 proyectos en la sección Mis proyectos y guarda el client id y el client secret.

El primer proyecto sirve para gestionar los envíos.

El segundo, para rastrearlos.

1.3. Crea los estados de entrega

En la pestaña de estados del almacenamiento de pedidos, crea los estados (se abre en una pestaña nueva):

  • order_delivery
  • order_delivery_started
  • ready_for_pickup

1.4. Crea un evento para rastrear los estados

En el módulo Events (se abre en una pestaña nueva), crea un evento que rastree el cambio del pedido al estado order_delivery.

Evento order delivery con el marcador order_delivery: módulo orders, almacenamiento test_order_storage, estado order_delivery, "Integrations" marcado.

1.5. Crea una colección para las entregas

En el módulo Integration Collections (se abre en una pestaña nueva), crea una colección para las entregas con estos atributos:

  • name (string)
  • address (string)
  • phone_number (string)
  • city (string)
  • state_code (string)
  • postal_code (string)
  • country_code (string)
  • tracking_number (string)
  • transaction_id (string)
  • ship_datestamp (string)
  • delivery_datestamp (string)

Sección "Integration collections": en la lista aparece la colección delivery con el marcador delivery.

1.6. Crea un pedido de prueba

Crea un pedido y un registro de la colección para ese pedido.

Solicitud POST a /api/content/orders-storage/marker/order_storage/orders con el cuerpo JSON de un pedido de prueba: formulario order_form, pago paypal, producto 1 × 2.

Solicitud POST a /api/content/integration-collections/marker/delivery/rows: registro del pedido 1 con el formulario delivery_form y los datos del destinatario.

2. Creación del envío​

2.1. Seguimiento del evento de entrega

  • Arrastra el nodo events (se abre en una pestaña nueva) al espacio de trabajo.
  • Ingresa un nombre para el nodo.
  • Cambia el valor del campo "Set" a "orderEvent".
  • El evento se guardará en el objeto "msg.orderEvent" y podrás usarlo en otros nodos.
  • Selecciona en la lista el evento que creaste, "order delivery", y haz clic en "submit".

Nodo de eventos order delivery event: "Set" es msg.orderEvent y en "Events" está seleccionado order delivery.


2.2. Obtención del token

  • Arrastra el nodo function (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Pega el código del ejemplo en el campo "Function".
  • Reemplaza YOUR_CLIENT_ID y YOUR_CLIENT_SECRET por tus propios valores.

Nodo auth body: el código del campo "Function" define msg.payload con client_credentials, YOUR_CLIENT_ID y YOUR_CLIENT_SECRET, y el encabezado Content-Type.

msg.payload = {
'grant_type': 'client_credentials',
'client_id': 'YOUR_CLIENT_ID',
'client_secret': 'YOUR_CLIENT_SECRET'
}
msg.headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}

return msg;

Los parámetros se describen en la documentación de FedEx.


  • Arrastra el nodo http request (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • En el campo Method, selecciona "POST".
  • En el campo Data, selecciona "Send as request body".
  • En el campo Link, pega https://apis-sandbox.fedex.com/oauth/token.
  • En el campo Return, selecciona "Object JSON".

Nodo auth request: "Method" es POST, "Data" es Send as request body, "Link" es https://apis-sandbox.fedex.com/oauth/token y "Return" es Object JSON.


Nodo set access token: el código del campo "Function" copia access_token de msg.payload a msg.access_token.

msg.access_token = msg.payload.access_token;

return msg;

2.3. Creación del envío

  • Arrastra el nodo admin-api (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Selecciona el método "Receiving all records belonging to the collection" y pega el siguiente código en el campo "Data".
{
"entityType": "orders",
"entityId": "{{orderEvent.order.id}}",
"langCode": "en_US",
"offset": 0,
"limit": 1,
"marker": "delivery"
}

Nodo find collection rows: "Type" es Receiving all records belonging to the collection; en "Query parameters", un JSON con marker delivery, entityType orders y entityId orderEvent.order.id.


Nodo shipment data: el código del campo "Function" arma los encabezados con el token Bearer y los datos del destinatario a partir del registro de la colección.

// obtenemos el token guardado anteriormente
const token = msg.access_token;

// definimos los encabezados
msg.headers = {
'Content-Type': 'application/json',
'authorization': `Bearer ${token}`
};

// obtenemos la colección del paso anterior
const collection = msg.payload.items[0];
// convertimos el array en un objeto
const formData = collection.formData.reduce((acc, item) => {
acc[item.marker] = item.value;
return acc;
}, {});
// definimos los datos del destinatario a partir del formulario
const recipient = {
"address": {
"streetLines": [
formData.address
],
"city": formData.city,
"stateOrProvinceCode": formData.state_code,
"postalCode": formData.postal_code,
"countryCode": formData.country_code
},
"contact": {
"personName": formData.name,
"phoneNumber": formData.phone_number
}
}
// guardamos los datos de la colección en msg para usarlos más adelante
msg.collection = collection;
// definimos los parámetros de la solicitud a FedEx
msg.payload = {
"labelResponseOptions": "URL_ONLY",
"accountNumber": {
"value": "510087020"
},
"requestedShipment": {
"shipper": {
"contact": {
"personName": "SENDER NAME",
"phoneNumber": "9018328595"
},
"address": {
"streetLines": [
"SENDER ADDRESS 1"
],
"city": "MEMPHIS",
"stateOrProvinceCode": "TN",
"postalCode": "38116",
"countryCode": "US"
}
},
"recipients": [
recipient
],
"serviceType": "STANDARD_OVERNIGHT",
"packagingType": "YOUR_PACKAGING",
"pickupType": "DROPOFF_AT_FEDEX_LOCATION",
"shippingChargesPayment": {
"paymentType": "SENDER",
"payor": {
"responsibleParty": {
"accountNumber": {
"value": "510087020",
"key": ""
}
},
"address": {
"streetLines": [
"SENDER ADDRESS 1"
],
"city": "MEMPHIS",
"stateOrProvinceCode": "TN",
"postalCode": "38116",
"countryCode": "US"
}
}
},
"labelSpecification": {},
"requestedPackageLineItems": [
{
"customerReferences": [
{
"customerReferenceType": "CUSTOMER_REFERENCE",
"value": `Collection${collection.id}`
}
],
"weight": {
"units": "LB",
"value": "20"
}
}
]
}
};

return msg;

Los parámetros se describen en la documentación de FedEx.


  • Arrastra el nodo http request (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • En el campo Method, selecciona "POST".
  • En el campo Data, selecciona "Send as request body".
  • En el campo Link, pega https://apis-sandbox.fedex.com/ship/v1/shipments.
  • En el campo Return, selecciona "Object JSON".

Nodo shipment request: "Method" es POST, "Data" es Send as request body, "Link" es https://apis-sandbox.fedex.com/ship/v1/shipments y "Return" es Object JSON.


Nodo debug debug fedex shipment: "Output" es msg.payload.


Nodo update row data: el código del campo "Function" arma el nuevo formData del registro de la colección con los campos transaction_id y ship_datestamp de la respuesta de FedEx.

// obtenemos los datos del envío
const shipment = msg.payload.output.transactionShipments[0];
// obtenemos los datos de la colección guardados anteriormente
const collection = msg.collection;

// escribimos los datos del envío en los atributos del formulario
const newFormData = [
...collection.formData
.filter(item => !['transaction_id', 'ship_datestamp', 'delivery_datestamp', 'tracking_number'].includes(item.marker)),
{
marker: 'transaction_id',
value: msg.payload.transactionId,
type: 'string'
},
{
marker: 'ship_datestamp',
value: shipment.shipDatestamp,
type: 'string'
},
{
marker: 'delivery_datestamp',
value: shipment.pieceResponses[0].deliveryDatestamp,
type: 'string'
},
{
marker: 'tracking_number',
value: shipment.masterTrackingNumber,
type: 'string'
}
]

// definimos los parámetros para actualizar la colección
msg.params = {
langCode: 'en_US',
id: collection.id,
marker: 'delivery'
}

msg.data = {
formIdentifier: 'delivery_form',
formData: {
en_US: newFormData
},
entityId: collection.entityId,
entityType: collection.entityType
}

// guardamos los datos de la colección para usarlos más adelante
msg.collection = collection;

return msg;

Nodo update collection row: en "Type" está seleccionado el método "Changing a record in the collection" y el campo "Query parameters" está vacío.


2.4. Actualización del estado del pedido

  • Arrastra el nodo admin-api (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Selecciona el método "Updating the status of an order belonging to the order storage object".
  • Pega el siguiente código en el campo "Query parameters".
{
"id": 1,
"orderId": "{{collection.entityId}}"
}
  • Pega el siguiente código en el campo "Request body".
{
"statusIdentifier": "order_delivery_started"
}

Nodo order delivery started: el tipo es la actualización del estado de un pedido del almacenamiento; parámetros id y orderId, y statusIdentifier en el cuerpo.


Nodo debug debug status update 1: "Output" es msg.payload.


3. Seguimiento del estado del envío​

3.1. Obtención de los pedidos que se van a rastrear

Nodo set interval: el campo "interval" tiene el valor 60.


  • Arrastra el nodo admin-api (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Selecciona el método "Receiving all orders belonging to the order storage object".
  • Pega el siguiente código en el campo "Query parameters".
{
"statusIdentifier": "order_delivery_started",
"langCode": "en_US",
"offset": 0,
"limit": 100,
"id": 1
}

Nodo find orders by status: "Type" es Receiving all orders belonging to the order storage object; en "Query parameters", un JSON con statusIdentifier order_delivery_started, limit 100 e id 1.


Nodo set orders: el código del campo "Function" asigna msg.payload.items a msg.payload.

msg.payload = msg.payload.items;

return msg;

Nodo split: "Property" es payload y "Length" es 1.


  • Arrastra el nodo admin-api (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Selecciona el método "Receiving all records belonging to the collection".
  • Pega el siguiente código en el campo "Query parameters".
{
"marker": "delivery",
"entityId": "{{payload.id}}",
"entityType": "orders",
"langCode": "en_US",
"limit": 1,
"offset": 0
}

Nodo find collection rows: "Type" es Receiving all records belonging to the collection; en "Query parameters", un JSON con marker delivery, entityId payload.id y entityType orders.


Ventana "Node Information" del nodo function "set row": el código del campo "Function" asigna a msg.payload el primer elemento de msg.payload.items

msg.payload = msg.payload.items[0]

return msg;

  • Arrastra el nodo switch (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Agrega una regla de comprobación y selecciona la condición "not empty".

Ventana "Node Information" del nodo "switch": propiedad "payload", modo "check all rules" y la condición "not empty" seleccionada en la regla


Ventana "Node Information" del nodo function "set trackingNummber": el código del campo "Function" toma de formData el valor del campo con el marcador tracking_number y lo guarda en msg.trackingNumber

msg.trackingNumber = msg.payload
.formData
.find(item => item.marker === 'tracking_number')
.value;

msg.collection = msg.payload;

return msg;

3.2. Obtención del token

  • Arrastra el nodo function (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Pega el código del ejemplo en el campo "Function".
  • Reemplaza YOUR_CLIENT_ID y YOUR_CLIENT_SECRET por tus propios valores.

Ventana "Node Information" del nodo function "auth body": el código del campo "Function" arma el cuerpo de la solicitud del token con grant_type, client_id y client_secret, con los valores de ejemplo YOUR_CLIENT_ID y YOUR_CLIENT_SECRET

msg.payload = {
'grant_type': 'client_credentials',
'client_id': 'YOUR_CLIENT_ID',
'client_secret': 'YOUR_CLIENT_SECRET'
}
msg.headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}

return msg;

Los parámetros se describen en la documentación de FedEx.


  • Arrastra el nodo http request (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • En el campo Method, selecciona "POST".
  • En el campo Data, selecciona "Send as request body".
  • En el campo Link, pega https://apis-sandbox.fedex.com/oauth/token.
  • En el campo Return, selecciona "Object JSON".

Ventana "Node Information" del nodo http request "auth request": método "POST", "Send as request body", dirección apis-sandbox.fedex.com/oauth/token y "Return" en "Object JSON"


3.3. Obtención del estado del envío

Ventana "Node Information" del nodo function "tracking data": el código del campo "Function" define el encabezado de autorización Bearer con el token y un cuerpo de solicitud con trackingNumber

const token = msg.payload.access_token;

msg.headers = {
'content-type': 'application/json',
'authorization': `Bearer ${token}`
};

msg.payload = {
"trackingInfo": [
{
"trackingNumberInfo": {
"trackingNumber": msg.trackingNumber
}
}
],
"includeDetailedScans": true
}

return msg;

Los parámetros se describen en la documentación de FedEx.


  • Arrastra el nodo http request (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • En el campo Method, selecciona "POST".
  • En el campo Data, selecciona "Send as request body".
  • En el campo Link, pega https://apis-sandbox.fedex.com/track/v1/trackingnumbers.
  • En el campo Return, selecciona "Object JSON".

Ventana "Node Information" del nodo http request "tracking request": método "POST", "Send as request body", dirección apis-sandbox.fedex.com/track/v1/trackingnumbers y "Return" en "Object JSON"


Ventana "Node Information" del nodo function "set tracking result": el código del campo "Function" asigna a msg.payload el resultado del seguimiento tomado de msg.payload.output

msg.payload = msg.payload.output.completeTrackResults[0].trackResults[0].latestStatusDetail.statusByLocale;

return msg;

3.4. Actualización del estado del pedido

  • Arrastra el nodo switch (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Agrega una regla de comprobación: selecciona la condición "==" e ingresa el valor "Ready for pickup".

Ventana "Node Information" del nodo switch "check ship status": propiedad "payload", condición "==" y valor "Ready for pickup"


  • Arrastra el nodo admin-api (se abre en una pestaña nueva) al espacio de trabajo y conéctalo al nodo del paso anterior.
  • Selecciona el método "Updating the status of an order belonging to the order storage object".
  • Pega el siguiente código en el campo "Query parameters".
{
"id": 1,
"orderId": "{{collection.entityId}}"
}
  • Pega el siguiente código en el campo "Request body".
{
"statusIdentifier": "ready_for_pickup"
}

Ventana "Node Information" del nodo "update status": el tipo es la actualización del estado del pedido; en "Query parameters", id y orderId; en "Request body", statusIdentifier ready_for_pickup


Ventana "Node Information" del nodo debug "debug status update 2": en el campo "Output" está seleccionado msg.payload