This repository contains an end-to-end configuration for building a full X12 EDI system using Stedi products. This implementation demonstrates one way to build an integration for the common read and write EDI use cases. Your solution may differ, depending on your systems and requirements.
We'd like to set up and customize the bootstrap repository with you. Working together helps us understand what Stedi customers need and helps get your solution into production as quickly as possible. We offer free hands-on support that includes:
- Help deploying the bootstrap workflows and customizing them for your use cases
- Best practices for designing a scalable Stedi integration
- EDI experts to answer your questions
- Live troubleshooting over Slack or video call
Contact us to get started.
The bootstrap workflow uses the following process to handle incoming EDI:
- You upload EDI documents to a Stedi bucket. A trading partner could also do this using Stedi SFTP.
- New documents automatically invoke a Stedi Function that contains custom code for the workflow.
- The function calls Stedi EDI Translate to transform the EDI data into JSON. This process uses a Stedi Guide to map EDI fields to JSON fields.
- The function sends the JSON document to an internal webhook that you configure.
The bootstrap uses a similar process in reverse to handle outgoing EDI. It translates JSON documents to EDI and publishes them to a Stedi bucket.
-
Install Node.js (minimum version: 15)
-
Clone the bootstrap repository and install the necessary dependencies:
git clone https://github.com/Stedi-Demos/bootstrap.git cd bootstrap npm ci -
Create a Stedi account.
-
Rename the bootstrap's
.env.examplefile to.envand update the following environment variables:STEDI_API_KEY: A Stedi API key is required for authentication. You can generate an API key in your Stedi account.DESTINATION_WEBHOOK_URL: Go to webhook.site and copy the unique URL. The bootstrap workflow sends output to this webhook.
Example
.envfileSTEDI_API_KEY=<YOUR_STEDI_API_KEY> DESTINATION_WEBHOOK_URL=<YOUR_WEBHOOK_URL>
Run the following command in the bootstrap directory:
npm run bootstrapNew files in the SFTP bucket automatically invoke the inbound-edi function.
-
Go to the Buckets UI and navigate to the
inbounddirectory for your trading partner:<SFTP_BUCKET_NAME>/trading_partners/ANOTHERMERCH/inbound -
Upload the input X12 5010 855 EDI document to this directory. (note: if you upload the document to any directory not named
inbound, it will be intentionally ignored by theinbound-edi). -
Look for the output of the function wherever you created your test webhook! The function sends the JSON received from EDI Translate to the endpoint you have configured.
Example webhook output (click to expand):
{
"delimiters": {
"composite": ">",
"element": "*",
"repetition": "U",
"segment": "~"
},
"envelope": {
"interchangeHeader": {
"authorizationInformationQualifier": "00",
"authorizationInformation": " ",
"securityQualifier": "00",
"securityInformation": " ",
"senderQualifier": "02",
"senderId": "THISISME ",
"receiverQualifier": "ZZ",
"receiverId": "ANOTHERMERCH ",
"date": "2004-08-05",
"time": "06:24",
"repetitionSeparator": "U",
"controlVersionNumber": "00400",
"controlNumber": "000000001",
"acknowledgementRequestedCode": "0",
"usageIndicatorCode": "P",
"componentSeparator": ">"
},
"groupHeader": {
"functionalIdentifierCode": "IM",
"applicationSenderCode": "CNWY",
"applicationReceiverCode": "GSRECEIVERID",
"date": "2004-08-05",
"time": "06:24",
"controlNumber": "000000001",
"agencyCode": "X",
"release": "004010"
},
"groupTrailer": {
"numberOfTransactions": "1",
"controlNumber": "000000001"
},
"interchangeTrailer": {
"numberOfFunctionalGroups": "1",
"controlNumber": "000000001"
}
},
"transactionSets": [
{
"heading": {
"transaction_set_header_ST": {
"transaction_set_identifier_code_01": "210",
"transaction_set_control_number_02": 1
},
"beginning_segment_for_carriers_invoice_B3": {
"invoice_number_02": "PRONUMBER",
"shipment_identification_number_03": "Shipment ID Number",
"shipment_method_of_payment_04": "PP",
"date_06": "2004-08-05",
"net_amount_due_07": 274.09,
"delivery_date_09": "2004-08-09",
"date_time_qualifier_10": "017",
"standard_carrier_alpha_code_11": "CNWY"
},
"reference_identification_N9": [
{
"reference_identification_qualifier_01": "PO",
"reference_identification_02": "Reference Identification"
}
],
"name_N1_loop_Shipper": [
{
"name_N1": {
"entity_identifier_code_01": "SH",
"name_02": "Name"
},
"additional_name_information_N2": {
"name_01": "Name"
},
"address_information_N3": [
{
"address_information_01": "Address Information"
}
],
"geographic_location_N4": {
"city_name_01": "City Name",
"state_or_province_code_02": "St",
"postal_code_03": "Postal Code",
"country_code_04": "USA"
}
}
],
"name_N1_loop_consignee": [
{
"name_N1": {
"entity_identifier_code_01": "CN",
"name_02": "Name"
},
"additional_name_information_N2": {
"name_01": "Name"
},
"address_information_N3": [
{
"address_information_01": "Address Information"
}
],
"geographic_location_N4": {
"city_name_01": "City Name",
"state_or_province_code_02": "St",
"postal_code_03": "Postal Code",
"country_code_04": "USA"
}
}
],
"name_N1_loop_bill_to": [
{
"name_N1": {
"entity_identifier_code_01": "BT",
"name_02": "Name"
},
"additional_name_information_N2": {
"name_01": "Name"
},
"address_information_N3": [
{
"address_information_01": "Address Information"
}
],
"geographic_location_N4": {
"city_name_01": "City Name",
"state_or_province_code_02": "St",
"postal_code_03": "Postal Code",
"country_code_04": "USA"
}
}
]
},
"detail": {
"assigned_number_LX_loop": [
{
"assigned_number_LX": {
"assigned_number_01": 1
},
"description_marks_and_numbers_L5": [
{
"lading_line_item_number_01": 1,
"lading_description_02": "Lading Description"
},
{
"lading_line_item_number_01": 1,
"lading_description_02": "Lading Description continued"
}
],
"line_item_quantity_and_weight_L0": [
{
"lading_line_item_number_01": 1,
"weight_04": 2442,
"weight_qualifier_05": "G",
"lading_quantity_08": 509,
"packaging_form_code_09": "BDL",
"weight_unit_code_11": "L"
}
],
"rate_and_charges_L1": [
{
"lading_line_item_number_01": 1,
"freight_rate_02": 325.41,
"rate_value_qualifier_03": "FR",
"charge_04": 325.41
}
],
"tariff_reference_L7": [
{
"lading_line_item_number_01": 1,
"tariff_agency_code_02": "CNWY",
"tariff_number_03": "5350",
"freight_class_code_07": "55"
}
]
},
{
"assigned_number_LX": {
"assigned_number_01": 2
},
"description_marks_and_numbers_L5": [
{
"lading_line_item_number_01": 2,
"lading_description_02": "XPO DISCOUNT SAVES YOU"
}
],
"rate_and_charges_L1": [
{
"lading_line_item_number_01": 2,
"charge_04": -40.23,
"special_charge_or_allowance_code_08": "DSC"
}
],
"tariff_reference_L7": [
{
"lading_line_item_number_01": 2,
"tariff_agency_code_02": "CNWY",
"tariff_number_03": "5350"
}
]
},
{
"assigned_number_LX": {
"assigned_number_01": 3
},
"description_marks_and_numbers_L5": [
{
"lading_line_item_number_01": 3,
"lading_description_02": "FSC FUEL SURCHARGE 8.30% ...."
}
],
"rate_and_charges_L1": [
{
"lading_line_item_number_01": 3,
"freight_rate_02": 30.82,
"rate_value_qualifier_03": "FR",
"charge_04": 30.82,
"special_charge_or_allowance_code_08": "FUE"
}
],
"tariff_reference_L7": [
{
"lading_line_item_number_01": 3,
"tariff_agency_code_02": "CNWY",
"tariff_number_03": "110"
}
]
}
]
},
"summary": {
"total_weight_and_charges_L3": {
"weight_01": 2442,
"weight_qualifier_02": "G",
"freight_rate_03": 10484,
"rate_value_qualifier_04": "MN",
"charge_05": 274.09,
"lading_quantity_11": 509,
"weight_unit_code_12": "L"
},
"transaction_set_trailer_SE": {
"number_of_included_segments_01": 13,
"transaction_set_control_number_02": 1
}
}
}
]
}You can invoke the outbound-edi function through the UI for testing.
-
Navigate to the
outbound-edifunction in the [Functions UI]https://www.stedi.com/app/functions/edi-outbound/edit. -
Click the
Edit execution payloadlink, paste the contents of src/resources/X12/5010/850/outbound.json into the payload modal, and click save. -
Hit the
Executebutton, if successful theOutputshould look similar to the following:
Example function output (click to expand):
{
"statusCode": 200,
"deliveryResults": [
{
"type": "bucket",
"payload": {
"bucketName": "4c22f54a-9ecf-41c8-b404-6a1f20674953-sftp",
"key": "trading_partners/ANOTHERMERCH/outbound/000000005-850.edi",
"body": "ISA*00* *00* *ZZ*THISISME *14*ANOTHERMERCH *230113*2027*U*00501*000000005*0*T*>~GS*PO*MYAPPID*ANOTAPPID*20230113*202727*000000005*X*005010~ST*850*0001~BEG*00*DS*365465413**20220830~REF*CO*ACME-4567~REF*ZZ*Thank you for your business~PER*OC*Marvin Acme*TE*973-555-1212*EM*marvin@acme.com~TD5****ZZ*FHD~N1*ST*Wile E Coyote*92*123~N3*111 Canyon Court~N4*Phoenix*AZ*85001*US~PO1*item-1*0008*EA*400**VC*VND1234567*SK*ACM/8900-400~PID*F****400 pound anvil~PO1*item-2*0004*EA*125**VC*VND000111222*SK*ACM/1100-001~PID*F****Detonator~CTT*2~AMT*TT*3700~SE*16*0001~GE*1*000000005~IEA*1*000000005~"
}
}
]
}- You can view the file using the Buckets UI. As shown above, the output of the
function includes the
bucketNameandkey(path within the bucket) of where the generated EDI was saved.
The bootstrap workflow uses a sample trading partner to set up and test the read and write EDI workflows. You can customize the bootstrap workflow by doing one or all of the following:
- Edit the partner profile to replace the test trading partner with your real trading partners' details and requirements.
- Create Stedi mappings. The base bootstrap repository ingests and generates JSON with a schema that closely matches EDI documents. You may need to create a mapping to transform EDI documents into a custom JSON shape for your internal system. You can also create a mapping that transforms JSON data from your system into the JSON schema required for outgoing EDI documents.
- Create SFTP users for your trading partners, so they can send and retrieve EDI documents from Stedi Buckets.
You may want to use additional Stedi products to further optimize your EDI workflows. We can help you customize the bootstrap workflow and determine which products and approaches are right for your use cases. Contact us to set up a meeting with our technical team.
You can poll remote FTP and SFTP servers to download files from your trading partners. Visit the External FTP / SFTP poller README for details.
To delete all the resources created by the bootstrap, run the following command:
npm run destroy