From 8bdcf8ec252173cdaf1a713ca6d813a0303e7f42 Mon Sep 17 00:00:00 2001 From: Holly Abrams Date: Tue, 4 Aug 2026 15:59:24 -0400 Subject: [PATCH 1/7] Adding and updating DHL eCommerce carrier curls for Wallet and BYOCA --- .../create-carrier-curls/dhlecs-wallet.sh | 9 +++ .../guides/create-carrier-curls/dhlecs.sh | 8 +-- .../build_curls.py | 62 +++++++++++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 official/guides/create-carrier-curls/dhlecs-wallet.sh diff --git a/official/guides/create-carrier-curls/dhlecs-wallet.sh b/official/guides/create-carrier-curls/dhlecs-wallet.sh new file mode 100644 index 00000000..5ba53bd7 --- /dev/null +++ b/official/guides/create-carrier-curls/dhlecs-wallet.sh @@ -0,0 +1,9 @@ +curl -X POST https://api.easypost.com/v2/carrier_accounts \ + -u "$EASYPOST_API_KEY": \ + -H 'Content-Type: application/json' \ + -d '{ + "carrier_account": { + "type": "DhlEcsAccount", + "payment_mode": "aggregation" + } +}' diff --git a/official/guides/create-carrier-curls/dhlecs.sh b/official/guides/create-carrier-curls/dhlecs.sh index 3aac9c5f..7cfed961 100644 --- a/official/guides/create-carrier-curls/dhlecs.sh +++ b/official/guides/create-carrier-curls/dhlecs.sh @@ -1,21 +1,19 @@ curl -X POST https://api.easypost.com/v2/carrier_accounts \ -u "$EASYPOST_API_KEY": \ -H 'Content-Type: application/json' \ - -d '{ + -d '{ "carrier_account": { "type": "DhlEcsAccount", "description": "DhlEcsAccount", "credentials": { "client_id": "VALUE", "client_secret": "VALUE", - "distribution_center": "VALUE", - "pickup_id": "VALUE" + "distribution_center": "VALUE" }, "test_credentials": { "client_id": "VALUE", "client_secret": "VALUE", - "distribution_center": "VALUE", - "pickup_id": "VALUE" + "distribution_center": "VALUE" } } }' diff --git a/tools/build_create_carrier_curl_requests/build_curls.py b/tools/build_create_carrier_curl_requests/build_curls.py index b65225b9..40a3186b 100644 --- a/tools/build_create_carrier_curl_requests/build_curls.py +++ b/tools/build_create_carrier_curl_requests/build_curls.py @@ -23,6 +23,9 @@ CANADAPOST_CUSTOM_WORKFLOW_CARRIERS = [ "CanadaPostAccount", ] +DHLECOMMERCE_CUSTOM_WORKFLOW_CARRIERS = [ + "DhlEcsAccount", +] OAUTH_CUSTOM_WORKFLOW_CARRIERS = [ "AmazonShippingAccount", "UpsAccount" @@ -151,6 +154,65 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st ) as default_file: default_file.write(re.sub(r"^.*?\n", "", default_output)) + return carrier_output + # DHL eCommerce + elif carrier["type"] in DHLECOMMERCE_CUSTOM_WORKFLOW_CARRIERS: + # BYOCA cURL + end = END_CHARS + for top_level in carrier_fields: + if top_level == "custom_workflow": + end += CUSTOM_WORKFLOW_CHARS + else: + top_level_carrier_fields = carrier_fields[top_level] + for item in top_level_carrier_fields: + if item == "pickup_id": + continue + if carrier_account_json["carrier_account"].get(top_level) is None: + carrier_account_json["carrier_account"][top_level] = {} + carrier_account_json["carrier_account"][top_level][item] = "VALUE" + + carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" + carrier_output += end + carrier_output = carrier_output.replace( + f"{LINE_BREAK_CHARS}{END_CHARS}", + END_CHARS, + ) + + # Wallet cURL + wallet_output = f'# {carrier.get("type")} (EasyPost Aggregation)\n' + wallet_output = add_curl_line(wallet_output, carrier) + wallet_output = add_headers(wallet_output, carrier) + + wallet_json = { + "carrier_account": { + "type": carrier["type"], + "payment_mode": "aggregation", + } + } + + wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" + wallet_output += END_CHARS + wallet_output = wallet_output.replace( + f"{LINE_BREAK_CHARS}{END_CHARS}", + END_CHARS, + ) + + output_destination = os.path.join( + "../", + "../", + "official", + "guides", + "create-carrier-curls", + ) + if not os.path.exists(output_destination): + os.makedirs(output_destination) + + with open( + os.path.join(output_destination, "dhlecs-wallet.sh"), + "w", + ) as wallet_file: + wallet_file.write(re.sub(r"^.*?\n", "", wallet_output)) + return carrier_output # Maersk Parcel — custom static credential structure elif carrier["type"] in MAERSK_CUSTOM_WORKFLOW_CARRIERS: From 76f9b7bcc5ed130ea9c40d173eeba9e397920d32 Mon Sep 17 00:00:00 2001 From: Holly Abrams Date: Tue, 4 Aug 2026 16:05:55 -0400 Subject: [PATCH 2/7] Fix: Indentation error --- tools/build_create_carrier_curl_requests/build_curls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/build_create_carrier_curl_requests/build_curls.py b/tools/build_create_carrier_curl_requests/build_curls.py index 40a3186b..39907331 100644 --- a/tools/build_create_carrier_curl_requests/build_curls.py +++ b/tools/build_create_carrier_curl_requests/build_curls.py @@ -171,7 +171,7 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st carrier_account_json["carrier_account"][top_level] = {} carrier_account_json["carrier_account"][top_level][item] = "VALUE" - carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" + carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" carrier_output += end carrier_output = carrier_output.replace( f"{LINE_BREAK_CHARS}{END_CHARS}", @@ -190,7 +190,7 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st } } - wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" + wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" wallet_output += END_CHARS wallet_output = wallet_output.replace( f"{LINE_BREAK_CHARS}{END_CHARS}", From bd25a56eb97360d97d37eed97cc6121653d3465c Mon Sep 17 00:00:00 2001 From: Holly Abrams Date: Tue, 4 Aug 2026 16:08:15 -0400 Subject: [PATCH 3/7] Fix: Indentation error...again --- official/guides/create-carrier-curls/dhlecs-wallet.sh | 2 +- official/guides/create-carrier-curls/dhlecs.sh | 2 +- tools/build_create_carrier_curl_requests/build_curls.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/official/guides/create-carrier-curls/dhlecs-wallet.sh b/official/guides/create-carrier-curls/dhlecs-wallet.sh index 5ba53bd7..2941be81 100644 --- a/official/guides/create-carrier-curls/dhlecs-wallet.sh +++ b/official/guides/create-carrier-curls/dhlecs-wallet.sh @@ -1,7 +1,7 @@ curl -X POST https://api.easypost.com/v2/carrier_accounts \ -u "$EASYPOST_API_KEY": \ -H 'Content-Type: application/json' \ - -d '{ + -d '{ "carrier_account": { "type": "DhlEcsAccount", "payment_mode": "aggregation" diff --git a/official/guides/create-carrier-curls/dhlecs.sh b/official/guides/create-carrier-curls/dhlecs.sh index 7cfed961..fe4e0a5d 100644 --- a/official/guides/create-carrier-curls/dhlecs.sh +++ b/official/guides/create-carrier-curls/dhlecs.sh @@ -1,7 +1,7 @@ curl -X POST https://api.easypost.com/v2/carrier_accounts \ -u "$EASYPOST_API_KEY": \ -H 'Content-Type: application/json' \ - -d '{ + -d '{ "carrier_account": { "type": "DhlEcsAccount", "description": "DhlEcsAccount", diff --git a/tools/build_create_carrier_curl_requests/build_curls.py b/tools/build_create_carrier_curl_requests/build_curls.py index 39907331..40a3186b 100644 --- a/tools/build_create_carrier_curl_requests/build_curls.py +++ b/tools/build_create_carrier_curl_requests/build_curls.py @@ -171,7 +171,7 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st carrier_account_json["carrier_account"][top_level] = {} carrier_account_json["carrier_account"][top_level][item] = "VALUE" - carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" + carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" carrier_output += end carrier_output = carrier_output.replace( f"{LINE_BREAK_CHARS}{END_CHARS}", @@ -190,7 +190,7 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st } } - wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" + wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" wallet_output += END_CHARS wallet_output = wallet_output.replace( f"{LINE_BREAK_CHARS}{END_CHARS}", From 115f5ae2b773f638165dbfb839427b48988bc6de Mon Sep 17 00:00:00 2001 From: Holly Abrams Date: Wed, 5 Aug 2026 15:08:03 -0400 Subject: [PATCH 4/7] Add Wallet carrier cURL generation --- .../create-carrier-curls/dhlecs-wallet.sh | 3 +- .../build_curls.py | 190 +++++++----------- 2 files changed, 72 insertions(+), 121 deletions(-) diff --git a/official/guides/create-carrier-curls/dhlecs-wallet.sh b/official/guides/create-carrier-curls/dhlecs-wallet.sh index 2941be81..b1af6ead 100644 --- a/official/guides/create-carrier-curls/dhlecs-wallet.sh +++ b/official/guides/create-carrier-curls/dhlecs-wallet.sh @@ -1,9 +1,10 @@ curl -X POST https://api.easypost.com/v2/carrier_accounts \ -u "$EASYPOST_API_KEY": \ -H 'Content-Type: application/json' \ - -d '{ + -d '{ "carrier_account": { "type": "DhlEcsAccount", + "description": "DhlEcsAccount", "payment_mode": "aggregation" } }' diff --git a/tools/build_create_carrier_curl_requests/build_curls.py b/tools/build_create_carrier_curl_requests/build_curls.py index 40a3186b..c0d53ebe 100644 --- a/tools/build_create_carrier_curl_requests/build_curls.py +++ b/tools/build_create_carrier_curl_requests/build_curls.py @@ -1,3 +1,4 @@ +import copy import json import os import re @@ -20,12 +21,6 @@ UPS_CUSTOM_WORKFLOW_CARRIERS = [ "UpsDapAccount", ] -CANADAPOST_CUSTOM_WORKFLOW_CARRIERS = [ - "CanadaPostAccount", -] -DHLECOMMERCE_CUSTOM_WORKFLOW_CARRIERS = [ - "DhlEcsAccount", -] OAUTH_CUSTOM_WORKFLOW_CARRIERS = [ "AmazonShippingAccount", "UpsAccount" @@ -36,6 +31,10 @@ DOORDASH_CUSTOM_WORKFLOW_CARRIERS = [ "DoorDashAccount" ] +WALLET_CARRIERS = [ + "CanadaPostAccount", + "DhlEcsAccount", +] def main(): carrier_types = get_carrier_types() @@ -90,6 +89,39 @@ def add_headers(carrier_output: str, carrier: dict[str, str]) -> str: return carrier_output +def write_wallet_curl(carrier: dict[str, str], carrier_account_json: dict) -> None: + """Create a Wallet cURL for carriers that support EasyPost aggregation.""" + wallet_json = copy.deepcopy(carrier_account_json) + wallet_account = wallet_json["carrier_account"] + wallet_account.pop("credentials", None) + wallet_account.pop("test_credentials", None) + wallet_account["payment_mode"] = "aggregation" + wallet_output = f'# {carrier.get("type")} (EasyPost Wallet)\n' + wallet_output = add_curl_line(wallet_output, carrier) + wallet_output = add_headers(wallet_output, carrier) + wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" + wallet_output += END_CHARS + wallet_output = wallet_output.replace( + f"{LINE_BREAK_CHARS}{END_CHARS}", + END_CHARS, + ) + output_destination = os.path.join( + "..", + "..", + "official", + "guides", + "create-carrier-curls", + ) + if not os.path.exists(output_destination): + os.makedirs(output_destination) + carrier_filename = carrier["type"].lower().replace("account", "") + with open( + os.path.join(output_destination, f"{carrier_filename}-wallet.sh"), + "w", + ) as wallet_file: + wallet_file.write(re.sub(r"^.*?\n", "", wallet_output)) + + def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> str: """Iterate over the carrier fields and print the credential structure.""" carrier_account_json = { @@ -110,110 +142,6 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" carrier_output += END_CHARS carrier_output = carrier_output.replace(f"{LINE_BREAK_CHARS}{END_CHARS}", f"{END_CHARS}") - # CanadaPost - elif carrier["type"] in CANADAPOST_CUSTOM_WORKFLOW_CARRIERS: - # BYOA cURL - end = END_CHARS - for top_level in carrier_fields: - if top_level == "custom_workflow": - end += CUSTOM_WORKFLOW_CHARS - else: - top_level_carrier_fields = carrier_fields[top_level] - for item in top_level_carrier_fields: - if carrier_account_json["carrier_account"].get(top_level) is None: - carrier_account_json["carrier_account"][top_level] = {} - carrier_account_json["carrier_account"][top_level][item] = "VALUE" - - carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" - carrier_output += end - carrier_output = carrier_output.replace(f"{LINE_BREAK_CHARS}{END_CHARS}", f"{END_CHARS}") - - # Default (aggregation) cURL - default_output = f'# {carrier.get("type")} (EasyPost Aggregation)\n' - default_output = add_curl_line(default_output, carrier) - default_output = add_headers(default_output, carrier) - - default_json = { - "carrier_account": { - "type": carrier["type"], - "payment_mode": "aggregation" - } - } - - default_output += f" -d '{json.dumps(default_json, indent=2)}'" - default_output += END_CHARS - default_output = default_output.replace(f"{LINE_BREAK_CHARS}{END_CHARS}", f"{END_CHARS}") - - output_destination = os.path.join("../", "../", "official", "guides", "create-carrier-curls") - if not os.path.exists(output_destination): - os.makedirs(output_destination) - - with open( - os.path.join(output_destination, "canadapost-default.sh"), - "w", - ) as default_file: - default_file.write(re.sub(r"^.*?\n", "", default_output)) - - return carrier_output - # DHL eCommerce - elif carrier["type"] in DHLECOMMERCE_CUSTOM_WORKFLOW_CARRIERS: - # BYOCA cURL - end = END_CHARS - for top_level in carrier_fields: - if top_level == "custom_workflow": - end += CUSTOM_WORKFLOW_CHARS - else: - top_level_carrier_fields = carrier_fields[top_level] - for item in top_level_carrier_fields: - if item == "pickup_id": - continue - if carrier_account_json["carrier_account"].get(top_level) is None: - carrier_account_json["carrier_account"][top_level] = {} - carrier_account_json["carrier_account"][top_level][item] = "VALUE" - - carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" - carrier_output += end - carrier_output = carrier_output.replace( - f"{LINE_BREAK_CHARS}{END_CHARS}", - END_CHARS, - ) - - # Wallet cURL - wallet_output = f'# {carrier.get("type")} (EasyPost Aggregation)\n' - wallet_output = add_curl_line(wallet_output, carrier) - wallet_output = add_headers(wallet_output, carrier) - - wallet_json = { - "carrier_account": { - "type": carrier["type"], - "payment_mode": "aggregation", - } - } - - wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" - wallet_output += END_CHARS - wallet_output = wallet_output.replace( - f"{LINE_BREAK_CHARS}{END_CHARS}", - END_CHARS, - ) - - output_destination = os.path.join( - "../", - "../", - "official", - "guides", - "create-carrier-curls", - ) - if not os.path.exists(output_destination): - os.makedirs(output_destination) - - with open( - os.path.join(output_destination, "dhlecs-wallet.sh"), - "w", - ) as wallet_file: - wallet_file.write(re.sub(r"^.*?\n", "", wallet_output)) - - return carrier_output # Maersk Parcel — custom static credential structure elif carrier["type"] in MAERSK_CUSTOM_WORKFLOW_CARRIERS: carrier_account_json = { @@ -310,23 +238,45 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st # Normal carriers else: end = END_CHARS - # top_level here means `credentials` or `test_credentials` or `custom_workflow` + + # top_level here means `credentials`, `test_credentials`, + # or `custom_workflow` for top_level in carrier_fields: - # TODO: If there is a custom_workflow such as 3rd party auth or a similar flow - # we should warn about that here. The credential structure will differ from - # a normal carrier account and is currently not automated + # TODO: If there is a custom_workflow such as 3rd party auth + # or a similar flow, warn about that here. The credential + # structure will differ from a normal carrier account and is + # currently not automated. if top_level == "custom_workflow": end += CUSTOM_WORKFLOW_CHARS else: top_level_carrier_fields = carrier_fields[top_level] - for item in top_level_carrier_fields: - if carrier_account_json["carrier_account"].get(top_level) is None: - carrier_account_json["carrier_account"][top_level] = {} - carrier_account_json["carrier_account"][top_level][item] = "VALUE" - carrier_output += f" -d '{json.dumps(carrier_account_json, indent=2)}'" + for item in top_level_carrier_fields: + if ( + carrier_account_json["carrier_account"].get( + top_level + ) + is None + ): + carrier_account_json["carrier_account"][ + top_level + ] = {} + + carrier_account_json["carrier_account"][ + top_level + ][item] = "VALUE" + + carrier_output += ( + f" -d '{json.dumps(carrier_account_json, indent=2)}'" + ) carrier_output += end - carrier_output = carrier_output.replace(f"{LINE_BREAK_CHARS}{END_CHARS}", f"{END_CHARS}") + carrier_output = carrier_output.replace( + f"{LINE_BREAK_CHARS}{END_CHARS}", + END_CHARS, + ) + + if carrier["type"] in WALLET_CARRIERS: + write_wallet_curl(carrier, carrier_account_json) return carrier_output From d26c39b1138cef4ce3571efc5cc23401d512234a Mon Sep 17 00:00:00 2001 From: Holly Abrams Date: Wed, 5 Aug 2026 15:12:05 -0400 Subject: [PATCH 5/7] Fix: Indention error --- official/guides/create-carrier-curls/dhlecs-wallet.sh | 2 +- tools/build_create_carrier_curl_requests/build_curls.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/official/guides/create-carrier-curls/dhlecs-wallet.sh b/official/guides/create-carrier-curls/dhlecs-wallet.sh index b1af6ead..3a281b61 100644 --- a/official/guides/create-carrier-curls/dhlecs-wallet.sh +++ b/official/guides/create-carrier-curls/dhlecs-wallet.sh @@ -1,7 +1,7 @@ curl -X POST https://api.easypost.com/v2/carrier_accounts \ -u "$EASYPOST_API_KEY": \ -H 'Content-Type: application/json' \ - -d '{ + -d '{ "carrier_account": { "type": "DhlEcsAccount", "description": "DhlEcsAccount", diff --git a/tools/build_create_carrier_curl_requests/build_curls.py b/tools/build_create_carrier_curl_requests/build_curls.py index c0d53ebe..12545a98 100644 --- a/tools/build_create_carrier_curl_requests/build_curls.py +++ b/tools/build_create_carrier_curl_requests/build_curls.py @@ -99,7 +99,7 @@ def write_wallet_curl(carrier: dict[str, str], carrier_account_json: dict) -> No wallet_output = f'# {carrier.get("type")} (EasyPost Wallet)\n' wallet_output = add_curl_line(wallet_output, carrier) wallet_output = add_headers(wallet_output, carrier) - wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" + wallet_output += f" -d '{json.dumps(wallet_json, indent=2)}'" wallet_output += END_CHARS wallet_output = wallet_output.replace( f"{LINE_BREAK_CHARS}{END_CHARS}", From e45567ca588066e2db508f0f510d09fd572cdc69 Mon Sep 17 00:00:00 2001 From: Holly Abrams <99987524+hollyabrams@users.noreply.github.com> Date: Wed, 5 Aug 2026 15:32:27 -0400 Subject: [PATCH 6/7] Update tools/build_create_carrier_curl_requests/build_curls.py Co-authored-by: Justin Hammond --- tools/build_create_carrier_curl_requests/build_curls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_create_carrier_curl_requests/build_curls.py b/tools/build_create_carrier_curl_requests/build_curls.py index 12545a98..dfcb7118 100644 --- a/tools/build_create_carrier_curl_requests/build_curls.py +++ b/tools/build_create_carrier_curl_requests/build_curls.py @@ -107,7 +107,7 @@ def write_wallet_curl(carrier: dict[str, str], carrier_account_json: dict) -> No ) output_destination = os.path.join( "..", - "..", + "..", "official", "guides", "create-carrier-curls", From db523ac66672cb060c2e5d34b9dceb0136c1b071 Mon Sep 17 00:00:00 2001 From: Holly Abrams Date: Wed, 5 Aug 2026 15:41:59 -0400 Subject: [PATCH 7/7] Applied review formatting suggestions (flattened for 120 char length) --- .../build_curls.py | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/tools/build_create_carrier_curl_requests/build_curls.py b/tools/build_create_carrier_curl_requests/build_curls.py index dfcb7118..be03d670 100644 --- a/tools/build_create_carrier_curl_requests/build_curls.py +++ b/tools/build_create_carrier_curl_requests/build_curls.py @@ -252,23 +252,12 @@ def add_credential_structure(carrier_output: str, carrier: dict[str, str]) -> st top_level_carrier_fields = carrier_fields[top_level] for item in top_level_carrier_fields: - if ( - carrier_account_json["carrier_account"].get( - top_level - ) - is None - ): - carrier_account_json["carrier_account"][ - top_level - ] = {} - - carrier_account_json["carrier_account"][ - top_level - ][item] = "VALUE" - - carrier_output += ( - f" -d '{json.dumps(carrier_account_json, indent=2)}'" - ) + if (carrier_account_json["carrier_account"].get(top_level)is None): + carrier_account_json["carrier_account"][top_level] = {} + + carrier_account_json["carrier_account"][top_level][item] = "VALUE" + + carrier_output += (f" -d '{json.dumps(carrier_account_json, indent=2)}'") carrier_output += end carrier_output = carrier_output.replace( f"{LINE_BREAK_CHARS}{END_CHARS}",