diff --git a/CHANGELOG.md b/CHANGELOG.md index 882708daa..718e7f1a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Removes the deprecated, unusable `addCreditCardToUser` function - Stripe has disabled the ability to pass plain credit card details over the wire and now requires using [Stripe.js/Elements/Checkout](https://support.stripe.com/questions/card-tokenization-restrictions-using-publishable-keys). Follow the [Decentralized (EasyPost-Manage Billing) Guide](https://docs.easypost.com/guides/get-started-with-forge/easypost-managed-billing-guide#referralcustomer-billing-management) for more details on the new flow to use. - Makes `referralCustomer.retrieveEasypostStripeApiKey` public to help facilitate adding credit cards using Stripe.js +- Adds support for `FedexDefaultAccount`, `GofoWalletAccount`, `UpsDapAccount`, `UniUniWalletAccount`, and `VehoWalletAccount` by properly routing carrier-account create requests to the `/carrier_accounts/open` endpoint. ## v8.8.0 (2026-06-25) diff --git a/src/main/java/com/easypost/Constants.java b/src/main/java/com/easypost/Constants.java index cbd00f208..d9f3dc2d7 100644 --- a/src/main/java/com/easypost/Constants.java +++ b/src/main/java/com/easypost/Constants.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.List; +import java.util.Map; import com.easypost.exception.APIException; import com.easypost.http.HashMapSerializer; @@ -15,6 +16,7 @@ import com.easypost.model.Webhook; import com.easypost.model.WebhookDeserializer; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -61,12 +63,14 @@ public abstract static class ErrorCodes { } public abstract static class CarrierAccountTypes { - public static final List CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_WORKFLOW = ImmutableList.of( - "FedexAccount", "FedexSmartpostAccount"); - - public static final List CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH = ImmutableList.of( - "AmazonShippingAccount", "UpsAccount", "UpsMailInnovationsAccount", "UpsSurepostAccount", - "UspsShipAccount"); + public static final Map> CARRIER_ACCOUNT_CREATE_ENDPOINT_TYPES = ImmutableMap.of( + "carrier_accounts/open", ImmutableList.of( + "FedexDefaultAccount", "GofoWalletAccount", "UpsDapAccount", "UniUniWalletAccount", + "VehoWalletAccount"), + "carrier_accounts/register", ImmutableList.of("FedexAccount", "FedexSmartpostAccount"), + "carrier_accounts/register_oauth", ImmutableList.of( + "AmazonShippingAccount", "UpsAccount", "UpsMailInnovationsAccount", "UpsSurepostAccount", + "UspsShipAccount")); } public abstract static class Http { diff --git a/src/main/java/com/easypost/service/CarrierAccountService.java b/src/main/java/com/easypost/service/CarrierAccountService.java index 9c4329188..e9aaad094 100644 --- a/src/main/java/com/easypost/service/CarrierAccountService.java +++ b/src/main/java/com/easypost/service/CarrierAccountService.java @@ -33,9 +33,14 @@ public class CarrierAccountService { */ public CarrierAccount create(final Map params) throws EasyPostException { String type = (String) params.get("type"); - Map wrappedParams = new HashMap(); - wrappedParams.put(selectTopLayerKey(type), params); + if (type == null) { + throw new MissingParameterError( + String.format(Constants.ErrorMessages.MISSING_REQUIRED_PARAMETER, "carrier account type")); + } + String endpoint = selectCarrierAccountCreationEndpoint(type); + Map wrappedParams = new HashMap(); + wrappedParams.put(selectTopLayerKey(endpoint), params); return Requestor.request(RequestMethod.POST, endpoint, wrappedParams, CarrierAccount.class, client); } @@ -116,30 +121,25 @@ public void delete(String id) throws EasyPostException { * @return The endpoint for the carrier account creation request. */ private static String selectCarrierAccountCreationEndpoint(final String carrierAccountType) { - if (Constants.CarrierAccountTypes.CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_WORKFLOW.contains(carrierAccountType)) { - return "carrier_accounts/register"; - } else if (Constants.CarrierAccountTypes.CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH.contains(carrierAccountType)) { - return "carrier_accounts/register_oauth"; - } else { - return "carrier_accounts"; + for (Map.Entry> entry : Constants.CarrierAccountTypes.CARRIER_ACCOUNT_CREATE_ENDPOINT_TYPES + .entrySet()) { + if (entry.getValue().contains(carrierAccountType)) { + return entry.getKey(); + } } + + return "carrier_accounts"; } /** * Select the top-layer key for the carrier account creation/update request based on the * carrier type. * - * @param carrierAccountType The type of carrier account to create. + * @param carrierAccountEndpoint The endpoint of carrier account to create. * @return The top-layer key for the carrier account creation/update request. - * @throws MissingParameterError when the request fails. */ - private static String selectTopLayerKey(final String carrierAccountType) throws MissingParameterError { - if (carrierAccountType == null) { - throw new MissingParameterError( - String.format(Constants.ErrorMessages.MISSING_REQUIRED_PARAMETER, "carrier account type")); - } - - if (Constants.CarrierAccountTypes.CARRIER_ACCOUNT_TYPES_WITH_CUSTOM_OAUTH.contains(carrierAccountType)) { + private static String selectTopLayerKey(final String carrierAccountEndpoint) { + if ("carrier_accounts/register_oauth".equals(carrierAccountEndpoint)) { return "carrier_account_oauth_registrations"; } else { return "carrier_account"; diff --git a/src/test/cassettes/carrier_account/create_url_routing_AmazonShippingAccount.json b/src/test/cassettes/carrier_account/create_url_routing_AmazonShippingAccount.json new file mode 100644 index 000000000..15e9af55e --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_AmazonShippingAccount.json @@ -0,0 +1,189 @@ +[ + { + "recordedAt": 1792096187, + "request": { + "body": "{\n \"carrier_account_oauth_registrations\": {\n \"type\": \"AmazonShippingAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "response": { + "body": "{\n \"readable\": \"Amazon Shipping\",\n \"credentials\": {},\n \"created_at\": \"2026-10-15T20:29:47Z\",\n \"description\": null,\n \"type\": \"AmazonShippingAccount\",\n \"reference\": null,\n \"updated_at\": \"2026-10-15T20:29:47Z\",\n \"clone\": false,\n \"billing_type\": \"carrier\",\n \"logo\": null,\n \"id\": \"ca_2425aaad5a4e46ccb59d084ac2e89707\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 201 Created" + ], + "content-length": [ + "1713" + ], + "expires": [ + "0" + ], + "x-node": [ + "web115azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "ef2f756f6ad137bbe2bc52590008bce0" + ], + "x-proxied": [ + "intlb4azw f29267e751", + "extlb1azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.099722" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 201, + "message": "Created" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "duration": 190 + }, + { + "recordedAt": 1792096187, + "request": { + "body": "", + "method": "DELETE", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_2425aaad5a4e46ccb59d084ac2e89707" + }, + "response": { + "body": "{}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 200 OK" + ], + "content-length": [ + "2" + ], + "expires": [ + "0" + ], + "x-node": [ + "web122azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "2cb8c6466ad137bbe2bc525a0008cdfe" + ], + "x-proxied": [ + "intlb2azw f29267e751", + "extlb2azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.071734" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 200, + "message": "OK" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_2425aaad5a4e46ccb59d084ac2e89707" + }, + "duration": 160 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_FedexAccount.json b/src/test/cassettes/carrier_account/create_url_routing_FedexAccount.json new file mode 100644 index 000000000..ec75c0bfd --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_FedexAccount.json @@ -0,0 +1,97 @@ +[ + { + "recordedAt": 1792096187, + "request": { + "body": "{\n \"carrier_account\": {\n \"registration_data\": {},\n \"type\": \"FedexAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"GONE\",\n \"message\": \"The requested resource is no longer available at the server and no forwarding address is known.\",\n \"errors\": [\n {\n \"message\": \"FedEx account registrations must use the multi-factor authentication (MFA) registration workflow. See: https://support.easypost.com/hc/en-us/articles/35262738410253-FedEx-Multi-Factor-Authentication\"\n }\n ]\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 410 Gone" + ], + "content-length": [ + "357" + ], + "expires": [ + "0" + ], + "x-node": [ + "web115azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "add87ec46ad137bbe2bc523e006262d7" + ], + "x-proxied": [ + "intlb3azw f29267e751", + "extlb3azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.089783" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 410, + "message": "Gone" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register" + }, + "duration": 178 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_FedexDefaultAccount.json b/src/test/cassettes/carrier_account/create_url_routing_FedexDefaultAccount.json new file mode 100644 index 000000000..1f472cdba --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_FedexDefaultAccount.json @@ -0,0 +1,189 @@ +[ + { + "recordedAt": 1792096139, + "request": { + "body": "{\n \"carrier_account\": {\n \"registration_data\": {},\n \"type\": \"FedexDefaultAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"UNPROCESSABLE_ENTITY\",\n \"message\": \"The request was understood, but cannot be processed.\",\n \"errors\": [\n {\n \"field\": \"name\",\n \"message\": \"is missing\"\n },\n {\n \"field\": \"street1\",\n \"message\": \"is missing\"\n },\n {\n \"field\": \"city\",\n \"message\": \"is missing\"\n },\n {\n \"field\": \"state\",\n \"message\": \"is missing\"\n },\n {\n \"field\": \"postal_code\",\n \"message\": \"is missing\"\n },\n {\n \"field\": \"country\",\n \"message\": \"is missing\"\n },\n {\n \"field\": \"phone\",\n \"message\": \"is missing\"\n },\n {\n \"field\": \"email\",\n \"message\": \"is missing\"\n }\n ]\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 422 Unprocessable Entity" + ], + "content-length": [ + "453" + ], + "expires": [ + "0" + ], + "x-node": [ + "web107azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "2cb8c6456ad1378be2bc41a000088881" + ], + "x-proxied": [ + "intlb4azw f29267e751", + "extlb2azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.023869" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 422, + "message": "Unprocessable Entity" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "duration": 112 + }, + { + "recordedAt": 1792096139, + "request": { + "body": "", + "method": "GET", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_720352f88fce4ebbb7e8fb4306826bbf" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"NOT_FOUND\",\n \"message\": \"The requested resource could not be found.\",\n \"errors\": []\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 404 Not Found" + ], + "content-length": [ + "97" + ], + "expires": [ + "0" + ], + "x-node": [ + "web107azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "aebfacae6ad1378be2bc41b80062190d" + ], + "x-proxied": [ + "intlb2azw f29267e751", + "extlb3azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.038834" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 404, + "message": "Not Found" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_720352f88fce4ebbb7e8fb4306826bbf" + }, + "duration": 130 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_FedexSmartpostAccount.json b/src/test/cassettes/carrier_account/create_url_routing_FedexSmartpostAccount.json new file mode 100644 index 000000000..5f2237d87 --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_FedexSmartpostAccount.json @@ -0,0 +1,97 @@ +[ + { + "recordedAt": 1792096187, + "request": { + "body": "{\n \"carrier_account\": {\n \"registration_data\": {},\n \"type\": \"FedexSmartpostAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"GONE\",\n \"message\": \"The requested resource is no longer available at the server and no forwarding address is known.\",\n \"errors\": [\n {\n \"message\": \"FedEx account registrations must use the multi-factor authentication (MFA) registration workflow. See: https://support.easypost.com/hc/en-us/articles/35262738410253-FedEx-Multi-Factor-Authentication\"\n }\n ]\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 410 Gone" + ], + "content-length": [ + "357" + ], + "expires": [ + "0" + ], + "x-node": [ + "web103azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "2cb8c6436ad137bbe2bc52400008cd3f" + ], + "x-proxied": [ + "intlb3azw f29267e751", + "extlb2azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.045289" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 410, + "message": "Gone" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register" + }, + "duration": 131 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_GofoWalletAccount.json b/src/test/cassettes/carrier_account/create_url_routing_GofoWalletAccount.json new file mode 100644 index 000000000..7148679ca --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_GofoWalletAccount.json @@ -0,0 +1,189 @@ +[ + { + "recordedAt": 1792096185, + "request": { + "body": "{\n \"carrier_account\": {\n \"registration_data\": {},\n \"type\": \"GofoWalletAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "response": { + "body": "{\n \"readable\": \"GOFO Wallet\",\n \"credentials\": {},\n \"created_at\": \"2026-10-15T20:29:45Z\",\n \"description\": \"GOFO Wallet Account\",\n \"type\": \"GofoWalletAccount\",\n \"reference\": null,\n \"updated_at\": \"2026-10-15T20:29:45Z\",\n \"clone\": false,\n \"billing_type\": \"easypost\",\n \"logo\": null,\n \"id\": \"ca_4f79588ef6fd43b38624a958c7907fe7\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 201 Created" + ], + "content-length": [ + "460" + ], + "expires": [ + "0" + ], + "x-node": [ + "web126azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "ef2f756d6ad137b9e2bc4ec50008b902" + ], + "x-proxied": [ + "intlb4azw f29267e751", + "extlb1azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.090634" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 201, + "message": "Created" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "duration": 179 + }, + { + "recordedAt": 1792096185, + "request": { + "body": "", + "method": "DELETE", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_4f79588ef6fd43b38624a958c7907fe7" + }, + "response": { + "body": "{}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 200 OK" + ], + "content-length": [ + "2" + ], + "expires": [ + "0" + ], + "x-node": [ + "web119azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "2cb8c6446ad137b9e2bc4ec60008ca62" + ], + "x-proxied": [ + "intlb1azw f29267e751", + "extlb2azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.062628" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 200, + "message": "OK" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_4f79588ef6fd43b38624a958c7907fe7" + }, + "duration": 148 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_UniUniWalletAccount.json b/src/test/cassettes/carrier_account/create_url_routing_UniUniWalletAccount.json new file mode 100644 index 000000000..bbbd4fbdc --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_UniUniWalletAccount.json @@ -0,0 +1,192 @@ +[ + { + "recordedAt": 1792096186, + "request": { + "body": "{\n \"carrier_account\": {\n \"registration_data\": {},\n \"type\": \"UniUniWalletAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "response": { + "body": "{\n \"readable\": \"UniUni Wallet\",\n \"credentials\": {},\n \"created_at\": \"2026-10-15T20:29:46Z\",\n \"description\": \"UniUni Wallet Account\",\n \"type\": \"UniUniWalletAccount\",\n \"reference\": null,\n \"updated_at\": \"2026-10-15T20:29:46Z\",\n \"clone\": false,\n \"billing_type\": \"easypost\",\n \"logo\": null,\n \"id\": \"ca_94a1d1d09f3a437791e106b0cfc0749a\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 201 Created" + ], + "content-length": [ + "600" + ], + "expires": [ + "0" + ], + "x-node": [ + "web101azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-canary": [ + "direct" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "aebfacb16ad137bae2bc4ee10062612a" + ], + "x-proxied": [ + "intlb2azw f29267e751", + "extlb3azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.089194" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 201, + "message": "Created" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "duration": 177 + }, + { + "recordedAt": 1792096186, + "request": { + "body": "", + "method": "DELETE", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_94a1d1d09f3a437791e106b0cfc0749a" + }, + "response": { + "body": "{}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 200 OK" + ], + "content-length": [ + "2" + ], + "expires": [ + "0" + ], + "x-node": [ + "web106azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "cdd5852e6ad137bae2bc4ee60008cbb0" + ], + "x-proxied": [ + "intlb2azw f29267e751", + "extlb2azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.081239" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 200, + "message": "OK" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_94a1d1d09f3a437791e106b0cfc0749a" + }, + "duration": 173 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_UpsAccount.json b/src/test/cassettes/carrier_account/create_url_routing_UpsAccount.json new file mode 100644 index 000000000..d79b6539a --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_UpsAccount.json @@ -0,0 +1,100 @@ +[ + { + "recordedAt": 1792096188, + "request": { + "body": "{\n \"carrier_account_oauth_registrations\": {\n \"type\": \"UpsAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"UNPROCESSABLE_ENTITY\",\n \"message\": \"The request was understood, but cannot be processed.\",\n \"errors\": [\n {\n \"field\": \"account_number\",\n \"message\": \"The provided Carrier Account\\u0027s Account Number is required but missing.\"\n }\n ]\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 422 Unprocessable Entity" + ], + "content-length": [ + "227" + ], + "expires": [ + "0" + ], + "x-node": [ + "web101azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-canary": [ + "direct" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "5218e5896ad137bce2bc525c0008bde3" + ], + "x-proxied": [ + "intlb4azw f29267e751", + "extlb1azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.021612" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 422, + "message": "Unprocessable Entity" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "duration": 109 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_UpsDapAccount.json b/src/test/cassettes/carrier_account/create_url_routing_UpsDapAccount.json new file mode 100644 index 000000000..4fb6067df --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_UpsDapAccount.json @@ -0,0 +1,97 @@ +[ + { + "recordedAt": 1792096186, + "request": { + "body": "{\n \"carrier_account\": {\n \"registration_data\": {},\n \"type\": \"UpsDapAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"PARAMETER.REQUIRED\",\n \"message\": \"Missing required parameter.\",\n \"errors\": [\n {\n \"field\": \"postal_code\",\n \"message\": \"is required but missing\"\n }\n ]\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 422 Unprocessable Entity" + ], + "content-length": [ + "150" + ], + "expires": [ + "0" + ], + "x-node": [ + "web107azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "5218e5886ad137bae2bc4edf0008ba02" + ], + "x-proxied": [ + "intlb1azw f29267e751", + "extlb1azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.058223" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 422, + "message": "Unprocessable Entity" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "duration": 168 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_UpsMailInnovationsAccount.json b/src/test/cassettes/carrier_account/create_url_routing_UpsMailInnovationsAccount.json new file mode 100644 index 000000000..60e4ec7b5 --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_UpsMailInnovationsAccount.json @@ -0,0 +1,97 @@ +[ + { + "recordedAt": 1792096188, + "request": { + "body": "{\n \"carrier_account_oauth_registrations\": {\n \"type\": \"UpsMailInnovationsAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"UNPROCESSABLE_ENTITY\",\n \"message\": \"The request was understood, but cannot be processed.\",\n \"errors\": [\n {\n \"field\": \"account_number\",\n \"message\": \"The provided Carrier Account\\u0027s Account Number is required but missing.\"\n }\n ]\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 422 Unprocessable Entity" + ], + "content-length": [ + "227" + ], + "expires": [ + "0" + ], + "x-node": [ + "web119azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "aebfacb36ad137bce2bc525e00626521" + ], + "x-proxied": [ + "intlb4azw f29267e751", + "extlb3azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.028725" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 422, + "message": "Unprocessable Entity" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "duration": 124 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_UpsSurepostAccount.json b/src/test/cassettes/carrier_account/create_url_routing_UpsSurepostAccount.json new file mode 100644 index 000000000..21c620ed6 --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_UpsSurepostAccount.json @@ -0,0 +1,100 @@ +[ + { + "recordedAt": 1792096188, + "request": { + "body": "{\n \"carrier_account_oauth_registrations\": {\n \"type\": \"UpsSurepostAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "response": { + "body": "{\n \"error\": {\n \"code\": \"UNPROCESSABLE_ENTITY\",\n \"message\": \"The request was understood, but cannot be processed.\",\n \"errors\": [\n {\n \"field\": \"account_number\",\n \"message\": \"The provided Carrier Account\\u0027s Account Number is required but missing.\"\n }\n ]\n }\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 422 Unprocessable Entity" + ], + "content-length": [ + "227" + ], + "expires": [ + "0" + ], + "x-node": [ + "web101azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-canary": [ + "direct" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "2cb8c6456ad137bce2bc52600008cf76" + ], + "x-proxied": [ + "intlb1azw f29267e751", + "extlb2azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.021904" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 422, + "message": "Unprocessable Entity" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" + }, + "duration": 112 + } +] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/update_ups.json b/src/test/cassettes/carrier_account/create_url_routing_UspsShipAccount.json similarity index 50% rename from src/test/cassettes/carrier_account/update_ups.json rename to src/test/cassettes/carrier_account/create_url_routing_UspsShipAccount.json index 52977e65b..a588ec542 100644 --- a/src/test/cassettes/carrier_account/update_ups.json +++ b/src/test/cassettes/carrier_account/create_url_routing_UspsShipAccount.json @@ -1,8 +1,8 @@ [ { - "recordedAt": 1748029861, + "recordedAt": 1792096188, "request": { - "body": "{\n \"carrier_account_oauth_registrations\": {\n \"account_number\": \"123456789\",\n \"type\": \"UpsAccount\"\n }\n}", + "body": "{\n \"carrier_account_oauth_registrations\": {\n \"type\": \"UspsShipAccount\"\n }\n}", "method": "POST", "headers": { "Accept-Charset": [ @@ -18,20 +18,23 @@ "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" }, "response": { - "body": "{\n \"readable\": \"UPS\",\n \"credentials\": {},\n \"created_at\": \"2025-05-23T19:51:01Z\",\n \"description\": null,\n \"type\": \"UpsAccount\",\n \"reference\": null,\n \"updated_at\": \"2025-05-23T19:51:01Z\",\n \"clone\": false,\n \"billing_type\": \"carrier\",\n \"logo\": null,\n \"id\": \"ca_ee686a5ce36748d7b8af5f15097d13d4\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", + "body": "{\n \"readable\": \"Usps Ship\",\n \"credentials\": {},\n \"created_at\": \"2026-10-15T20:29:48Z\",\n \"description\": null,\n \"type\": \"UspsShipAccount\",\n \"reference\": null,\n \"updated_at\": \"2026-10-15T20:29:48Z\",\n \"clone\": false,\n \"billing_type\": \"carrier\",\n \"logo\": null,\n \"id\": \"ca_b1209bc1f68b41bb9d9b196ef7784dc0\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", "httpVersion": null, "headers": { "null": [ "HTTP/1.1 201 Created" ], "content-length": [ - "1404" + "2553" ], "expires": [ "0" ], "x-node": [ - "bigweb54nuq" + "web109azw" + ], + "vary": [ + "EasyPost-Api-Version" ], "x-frame-options": [ "SAMEORIGIN" @@ -57,24 +60,27 @@ "x-content-type-options": [ "nosniff" ], + "easypost-api-version": [ + "2015-01-01" + ], "x-ep-request-uuid": [ - "6be4a8f36830d1a5e787bc610049cfde" + "ef2f756c6ad137bce2bc52620008bf1b" ], "x-proxied": [ - "intlb3nuq 668d3fc830", - "extlb1nuq 99aac35317" + "intlb1azw f29267e751", + "extlb1azw ff4cfe6eb5" ], "referrer-policy": [ "strict-origin-when-cross-origin" ], "x-runtime": [ - "0.083741" + "0.108157" ], "content-type": [ "application/json; charset\u003dutf-8" ], "x-version-label": [ - "easypost-202505231841-d89645a184-master" + "easypost-202610151955-b13716d895-main" ], "cache-control": [ "private, no-cache, no-store" @@ -86,41 +92,41 @@ }, "uri": "https://api.easypost.com/v2/carrier_accounts/register_oauth" }, - "duration": 297 + "duration": 197 }, { - "recordedAt": 1748029862, + "recordedAt": 1792096188, "request": { - "body": "{\n \"carrier_account\": {\n \"account_number\": \"987654321\"\n }\n}", - "method": "PUT", + "body": "", + "method": "DELETE", "headers": { "Accept-Charset": [ "UTF-8" ], "User-Agent": [ "REDACTED" - ], - "Content-Type": [ - "application/json" ] }, - "uri": "https://api.easypost.com/v2/carrier_accounts/ca_ee686a5ce36748d7b8af5f15097d13d4" + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_b1209bc1f68b41bb9d9b196ef7784dc0" }, "response": { - "body": "{\n \"readable\": \"UPS\",\n \"credentials\": {},\n \"created_at\": \"2025-05-23T19:51:01Z\",\n \"description\": null,\n \"type\": \"UpsAccount\",\n \"reference\": null,\n \"updated_at\": \"2025-05-23T19:51:02Z\",\n \"clone\": false,\n \"billing_type\": \"carrier\",\n \"logo\": null,\n \"id\": \"ca_ee686a5ce36748d7b8af5f15097d13d4\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", + "body": "{}", "httpVersion": null, "headers": { "null": [ "HTTP/1.1 200 OK" ], "content-length": [ - "1404" + "2" ], "expires": [ "0" ], "x-node": [ - "bigweb42nuq" + "web106azw" + ], + "vary": [ + "EasyPost-Api-Version" ], "x-frame-options": [ "SAMEORIGIN" @@ -146,24 +152,27 @@ "x-content-type-options": [ "nosniff" ], + "easypost-api-version": [ + "2015-01-01" + ], "x-ep-request-uuid": [ - "6be4a8f16830d1a5e787bc630049d05b" + "2cb8c6456ad137bce2bc527a0008d014" ], "x-proxied": [ - "intlb4nuq 668d3fc830", - "extlb1nuq 99aac35317" + "intlb1azw f29267e751", + "extlb2azw ff4cfe6eb5" ], "referrer-policy": [ "strict-origin-when-cross-origin" ], "x-runtime": [ - "0.076048" + "0.092643" ], "content-type": [ "application/json; charset\u003dutf-8" ], "x-version-label": [ - "easypost-202505231841-d89645a184-master" + "easypost-202610151955-b13716d895-main" ], "cache-control": [ "private, no-cache, no-store" @@ -173,12 +182,12 @@ "code": 200, "message": "OK" }, - "uri": "https://api.easypost.com/v2/carrier_accounts/ca_ee686a5ce36748d7b8af5f15097d13d4" + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_b1209bc1f68b41bb9d9b196ef7784dc0" }, - "duration": 292 + "duration": 189 }, { - "recordedAt": 1748029862, + "recordedAt": 1792096189, "request": { "body": "", "method": "GET", @@ -190,109 +199,26 @@ "REDACTED" ] }, - "uri": "https://api.easypost.com/v2/carrier_accounts/ca_ee686a5ce36748d7b8af5f15097d13d4" + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_720352f88fce4ebbb7e8fb4306826bbf" }, "response": { - "body": "{\n \"readable\": \"UPS\",\n \"credentials\": {},\n \"created_at\": \"2025-05-23T19:51:01Z\",\n \"description\": null,\n \"type\": \"UpsAccount\",\n \"reference\": null,\n \"updated_at\": \"2025-05-23T19:51:02Z\",\n \"clone\": false,\n \"billing_type\": \"carrier\",\n \"logo\": null,\n \"id\": \"ca_ee686a5ce36748d7b8af5f15097d13d4\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", + "body": "{\n \"error\": {\n \"code\": \"NOT_FOUND\",\n \"message\": \"The requested resource could not be found.\",\n \"errors\": []\n }\n}", "httpVersion": null, "headers": { "null": [ - "HTTP/1.1 200 OK" + "HTTP/1.1 404 Not Found" ], "content-length": [ - "1404" + "97" ], "expires": [ "0" ], "x-node": [ - "bigweb34nuq" - ], - "x-frame-options": [ - "SAMEORIGIN" - ], - "x-download-options": [ - "noopen" - ], - "x-permitted-cross-domain-policies": [ - "none" - ], - "x-backend": [ - "easypost" - ], - "pragma": [ - "no-cache" - ], - "strict-transport-security": [ - "max-age\u003d31536000; includeSubDomains; preload" - ], - "x-xss-protection": [ - "1; mode\u003dblock" - ], - "x-content-type-options": [ - "nosniff" - ], - "x-ep-request-uuid": [ - "6be4a8f26830d1a6e787bc640049d0af" - ], - "x-proxied": [ - "intlb4nuq 668d3fc830", - "extlb1nuq 99aac35317" - ], - "referrer-policy": [ - "strict-origin-when-cross-origin" - ], - "x-runtime": [ - "0.029771" + "web110azw" ], - "content-type": [ - "application/json; charset\u003dutf-8" - ], - "x-version-label": [ - "easypost-202505231841-d89645a184-master" - ], - "cache-control": [ - "private, no-cache, no-store" - ] - }, - "status": { - "code": 200, - "message": "OK" - }, - "uri": "https://api.easypost.com/v2/carrier_accounts/ca_ee686a5ce36748d7b8af5f15097d13d4" - }, - "duration": 245 - }, - { - "recordedAt": 1748029862, - "request": { - "body": "", - "method": "DELETE", - "headers": { - "Accept-Charset": [ - "UTF-8" - ], - "User-Agent": [ - "REDACTED" - ] - }, - "uri": "https://api.easypost.com/v2/carrier_accounts/ca_ee686a5ce36748d7b8af5f15097d13d4" - }, - "response": { - "body": "{}", - "httpVersion": null, - "headers": { - "null": [ - "HTTP/1.1 200 OK" - ], - "content-length": [ - "2" - ], - "expires": [ - "0" - ], - "x-node": [ - "bigweb53nuq" + "vary": [ + "EasyPost-Api-Version" ], "x-frame-options": [ "SAMEORIGIN" @@ -318,35 +244,38 @@ "x-content-type-options": [ "nosniff" ], + "easypost-api-version": [ + "2015-01-01" + ], "x-ep-request-uuid": [ - "6be4a8f46830d1a6e787bc650049d0eb" + "add87ec56ad137bce2bc527b006266a6" ], "x-proxied": [ - "intlb4nuq 668d3fc830", - "extlb1nuq 99aac35317" + "intlb2azw f29267e751", + "extlb3azw ff4cfe6eb5" ], "referrer-policy": [ "strict-origin-when-cross-origin" ], "x-runtime": [ - "0.193067" + "0.039288" ], "content-type": [ "application/json; charset\u003dutf-8" ], "x-version-label": [ - "easypost-202505231841-d89645a184-master" + "easypost-202610151955-b13716d895-main" ], "cache-control": [ "private, no-cache, no-store" ] }, "status": { - "code": 200, - "message": "OK" + "code": 404, + "message": "Not Found" }, - "uri": "https://api.easypost.com/v2/carrier_accounts/ca_ee686a5ce36748d7b8af5f15097d13d4" + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_720352f88fce4ebbb7e8fb4306826bbf" }, - "duration": 408 + "duration": 138 } ] \ No newline at end of file diff --git a/src/test/cassettes/carrier_account/create_url_routing_VehoWalletAccount.json b/src/test/cassettes/carrier_account/create_url_routing_VehoWalletAccount.json new file mode 100644 index 000000000..05a1b6970 --- /dev/null +++ b/src/test/cassettes/carrier_account/create_url_routing_VehoWalletAccount.json @@ -0,0 +1,189 @@ +[ + { + "recordedAt": 1792096186, + "request": { + "body": "{\n \"carrier_account\": {\n \"registration_data\": {},\n \"type\": \"VehoWalletAccount\"\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "response": { + "body": "{\n \"readable\": \"Veho\",\n \"credentials\": {},\n \"created_at\": \"2026-10-15T20:29:46Z\",\n \"description\": \"Veho Account\",\n \"type\": \"VehoWalletAccount\",\n \"reference\": null,\n \"updated_at\": \"2026-10-15T20:29:46Z\",\n \"clone\": false,\n \"billing_type\": \"easypost\",\n \"logo\": null,\n \"id\": \"ca_b8511323c78a4129b82efb7d8b7e6d2b\",\n \"fields\": {\n \"credentials\": {}\n },\n \"object\": \"CarrierAccount\"\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 201 Created" + ], + "content-length": [ + "583" + ], + "expires": [ + "0" + ], + "x-node": [ + "web113azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "ef2f756e6ad137bae2bc52190008bb47" + ], + "x-proxied": [ + "intlb1azw f29267e751", + "extlb1azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.084168" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 201, + "message": "Created" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/open" + }, + "duration": 183 + }, + { + "recordedAt": 1792096187, + "request": { + "body": "", + "method": "DELETE", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ] + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_b8511323c78a4129b82efb7d8b7e6d2b" + }, + "response": { + "body": "{}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 200 OK" + ], + "content-length": [ + "2" + ], + "expires": [ + "0" + ], + "x-node": [ + "web108azw" + ], + "vary": [ + "EasyPost-Api-Version" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-download-options": [ + "noopen" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-backend": [ + "easypost" + ], + "pragma": [ + "no-cache" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-content-type-options": [ + "nosniff" + ], + "easypost-api-version": [ + "2015-01-01" + ], + "x-ep-request-uuid": [ + "cdd585326ad137bae2bc521d0008cc7a" + ], + "x-proxied": [ + "intlb2azw f29267e751", + "extlb2azw ff4cfe6eb5" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.079723" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202610151955-b13716d895-main" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 200, + "message": "OK" + }, + "uri": "https://api.easypost.com/v2/carrier_accounts/ca_b8511323c78a4129b82efb7d8b7e6d2b" + }, + "duration": 188 + } +] \ No newline at end of file diff --git a/src/test/java/com/easypost/CarrierAccountTest.java b/src/test/java/com/easypost/CarrierAccountTest.java index 18b672912..b20f5cf06 100644 --- a/src/test/java/com/easypost/CarrierAccountTest.java +++ b/src/test/java/com/easypost/CarrierAccountTest.java @@ -1,20 +1,24 @@ package com.easypost; -import com.easypost.exception.API.InvalidRequestError; +import com.easypost.exception.APIException; import com.easypost.exception.EasyPostException; import com.easypost.http.Requestor; import com.easypost.model.CarrierAccount; import com.easypost.model.CarrierType; -import com.easypost.model.FieldError; import com.easypost.model.Pickup; import com.easypost.model.Shipment; -import com.google.common.collect.ImmutableMap; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.charset.StandardCharsets; +import java.util.AbstractMap; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -35,14 +39,29 @@ private static CarrierAccount createBasicCarrierAccount() throws EasyPostExcepti return carrierAccount; } - private static CarrierAccount createUpsCarrierAccount() throws EasyPostException { - Map data = new HashMap<>(); - data.put("type", "UpsAccount"); - data.put("account_number", "123456789"); + private static List> flattenCustomCarrierRouteMapping() { + List> routes = new ArrayList<>(); + for (Map.Entry> endpointEntry : Constants.CarrierAccountTypes + .CARRIER_ACCOUNT_CREATE_ENDPOINT_TYPES.entrySet()) { + for (String carrierAccountType : endpointEntry.getValue()) { + routes.add(new AbstractMap.SimpleEntry<>(carrierAccountType, endpointEntry.getKey())); + } + } + return routes; + } - CarrierAccount carrierAccount = vcr.client.carrierAccount.create(data); - testCarrierAccountId = carrierAccount.getId(); // trigger deletion after test - return carrierAccount; + private static Map carrierCreatePayloadForEndpoint(String endpoint) { + Map payload = new HashMap<>(); + if ("carrier_accounts/open".equals(endpoint) || "carrier_accounts/register".equals(endpoint)) { + payload.put("registration_data", new HashMap<>()); + } + return payload; + } + + private static String loadCarrierAccountCassette(String cassetteName) throws Exception { + Path cassettePath = Paths.get(TestUtils.getSourceFileDirectory(), "src/test/cassettes/carrier_account", + cassetteName + ".json"); + return new String(Files.readAllBytes(cassettePath), StandardCharsets.UTF_8); } /** @@ -88,66 +107,41 @@ public void testCreate() throws EasyPostException { } /** - * Test creating a carrier account with a custom workflow. + * Test routing carrier account create calls to the proper endpoint. * - * @throws EasyPostException when the request fails. + * @throws Exception when the request fails. */ @Test - public void testCreateWithCustomWorkflow() throws EasyPostException { - vcr.setUpTest("create_with_custom_workflow"); - - Map data = new HashMap<>(); - data.put("type", "FedexAccount"); - data.put("registration_data", ImmutableMap.of("some", "data")); - - try { - CarrierAccount carrierAccount = vcr.client.carrierAccount.create(data); - testCarrierAccountId = carrierAccount.getId(); // clean up after test, should never get here - } catch (InvalidRequestError e) { - // We're sending bad data to the API, so we expect an error - assertEquals(422, e.getStatusCode()); - // We expect one of the sub-errors to be regarding a missing field - FieldError fieldError = (FieldError) e.getErrors().get(0); - assertEquals("shipping_streets", fieldError.getField()); - assertEquals("must be present and a string", fieldError.getMessage()); - } - } + public void testCreateUrlRouting() throws Exception { + for (Map.Entry route : flattenCustomCarrierRouteMapping()) { + String carrierAccountType = route.getKey(); + String expectedEndpoint = route.getValue(); + String cassetteName = "create_url_routing_" + carrierAccountType; + vcr.setUpTest(cassetteName); - /** - * Test creating a UPS carrier account. - * - * @throws EasyPostException when the request fails. - */ - @Test - public void testCreateWithUPS() throws EasyPostException { - vcr.setUpTest("create_with_ups"); - - CarrierAccount carrierAccount = createUpsCarrierAccount(); - - assertInstanceOf(CarrierAccount.class, carrierAccount); - assertTrue(carrierAccount.getId().startsWith("ca_")); - assertEquals("UpsAccount", carrierAccount.getType()); - } + Map payload = new HashMap<>(); + payload.put("type", carrierAccountType); + payload.putAll(carrierCreatePayloadForEndpoint(expectedEndpoint)); - /** - * Test creating an Amazon carrier account. - * - * @throws EasyPostException when the request fails. - */ - @Test - public void testCreateWithAmazon() throws EasyPostException { - vcr.setUpTest("create_with_amazon"); - - Map data = new HashMap<>(); - data.put("type", "AmazonShippingAccount"); - - CarrierAccount carrierAccount = vcr.client.carrierAccount.create(data); - testCarrierAccountId = carrierAccount.getId(); // trigger deletion after test + try { + CarrierAccount carrierAccount = vcr.client.carrierAccount.create(payload); + assertInstanceOf(CarrierAccount.class, carrierAccount); + assertTrue(carrierAccount.getId().startsWith("ca_")); + vcr.client.carrierAccount.delete(carrierAccount.getId()); + } catch (APIException e) { + Integer statusCode = e.getStatusCode(); + assertTrue(statusCode == null || (statusCode != 404 && statusCode != 500)); + } - assertInstanceOf(CarrierAccount.class, carrierAccount); - assertTrue(carrierAccount.getId().startsWith("ca_")); - assertEquals("AmazonShippingAccount", carrierAccount.getType()); + String cassette = loadCarrierAccountCassette(cassetteName); + assertTrue(cassette.contains("/v2/" + expectedEndpoint)); + if ("carrier_accounts/register_oauth".equals(expectedEndpoint)) { + assertTrue(cassette.contains("carrier_account_oauth_registrations")); + } else { + assertTrue(cassette.contains("carrier_account")); + } + } } /** @@ -205,26 +199,6 @@ public void testUpdate() throws EasyPostException { assertEquals(testDescription, updatedCarrierAccount.getDescription()); } - /** - * Test updating an UPS account. - * - * @throws EasyPostException when the request fails. - */ - @Test - public void testUpdateUpsAccount() throws EasyPostException { - vcr.setUpTest("update_ups"); - - CarrierAccount carrierAccount = createUpsCarrierAccount(); - Map updateParams = new HashMap<>(); - updateParams.put("account_number", "987654321"); - - CarrierAccount updatedCarrierAccount = vcr.client.carrierAccount.update(carrierAccount.getId(), updateParams); - - assertInstanceOf(CarrierAccount.class, updatedCarrierAccount); - assertTrue(updatedCarrierAccount.getId().startsWith("ca_")); - assertEquals("UpsAccount", updatedCarrierAccount.getType()); - } - /** * Test deleting a carrier account. *