Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
# CHANGELOG

## v8.5.0 (2025-12-09)

- Adds the following functions:
- `fedexRegistration.registerAddress`
- `fedexRegistration.requestPin`
- `fedexRegistration.validatePin`
- `fedexRegistration.submitInvoice`
- Adds `details` property of a `Rate` objec

## v8.4.1 (2025-12-01)

- Adds missing `apiKeys` field to `BaseUser`
- Removes unecessary `SerializedName` entries in `StatelessRate`

## v8.4.0 (2025-11-24)

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Add this to your project's POM:
<dependency>
<groupId>com.easypost</groupId>
<artifactId>easypost-api-client</artifactId>
<version>8.4.1</version>
<version>8.5.0</version>
</dependency>
```

Expand All @@ -25,7 +25,7 @@ Add this to your project's POM:
Add this to your project's build file:

```groovy
implementation "com.easypost:easypost-api-client:8.4.1"
implementation "com.easypost:easypost-api-client:8.5.0"
```

**NOTE:** [Google Gson](http://code.google.com/p/google-gson/) is required.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.4.1
8.5.0
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>com.easypost</groupId>
<artifactId>easypost-api-client</artifactId>

<version>8.4.1</version>
<version>8.5.0</version>
<packaging>jar</packaging>

<name>com.easypost:easypost-api-client</name>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.easypost.model;

import java.util.List;
import java.util.Map;
import lombok.Getter;

@Getter
public final class FedExAccountValidationResponse {
// If the response contains the following, one must complete pin or invoice validation next
private String emailAddress;
private List<String> options;
private String phoneNumber;

// If the response contains the following, pre-validation has been completed
private String id;
private String object;
private String type;
private Map<String, String> credentials;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.easypost.model;

import lombok.Getter;

@Getter
public class FedExRequestPinResponse {
private String message;
}
21 changes: 13 additions & 8 deletions src/main/java/com/easypost/service/EasyPostClient.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.easypost.service;

import lombok.Getter;
import java.util.function.Function;

import com.easypost.Constants;
import com.easypost.exception.General.MissingParameterError;
import com.easypost.hooks.ResponseHook;
import com.easypost.hooks.ResponseHookResponses;
import com.easypost.hooks.RequestHook;
import com.easypost.hooks.RequestHookResponses;
import com.easypost.hooks.ResponseHook;
import com.easypost.hooks.ResponseHookResponses;

import java.util.function.Function;
import lombok.Getter;

public class EasyPostClient {
private final int connectTimeoutMilliseconds;
Expand All @@ -26,6 +26,7 @@ public class EasyPostClient {
public final BillingService billing = new BillingService(this);
public final CarrierAccountService carrierAccount = new CarrierAccountService(this);
public final CarrierMetadataService carrierMetadata = new CarrierMetadataService(this);
public final FedExRegistrationService fedexRegistration = new FedExRegistrationService(this);
public final CarrierTypeService carrierType = new CarrierTypeService(this);
public final ClaimService claim = new ClaimService(this);
public final CustomerPortalService customerPortal = new CustomerPortalService(this);
Expand Down Expand Up @@ -82,7 +83,7 @@ public EasyPostClient(String apiKey, String apiBase) throws MissingParameterErro
*
* @param apiKey API key for API calls.
* @param connectTimeoutMilliseconds Timeout for connection.
* @throws MissingParameterError When the request fails.
* @throws MissingParameterError When the request fails.
*/
public EasyPostClient(String apiKey, int connectTimeoutMilliseconds) throws MissingParameterError {
this(apiKey, connectTimeoutMilliseconds, Constants.Http.API_BASE);
Expand All @@ -94,7 +95,7 @@ public EasyPostClient(String apiKey, int connectTimeoutMilliseconds) throws Miss
* @param apiKey API key for API calls.
* @param connectTimeoutMilliseconds Timeout for connection.
* @param apiBase API base for API calls.
* @throws MissingParameterError When the request fails.
* @throws MissingParameterError When the request fails.
*/
public EasyPostClient(String apiKey, int connectTimeoutMilliseconds, String apiBase) throws MissingParameterError {
this(apiKey, connectTimeoutMilliseconds, Constants.Http.DEFAULT_READ_TIMEOUT_MILLISECONDS, apiBase);
Expand All @@ -106,7 +107,7 @@ public EasyPostClient(String apiKey, int connectTimeoutMilliseconds, String apiB
* @param apiKey API key for API calls.
* @param connectTimeoutMilliseconds Timeout for connection.
* @param readTimeoutMilliseconds Timeout for read.
* @throws MissingParameterError When the request fails.
* @throws MissingParameterError When the request fails.
*/
public EasyPostClient(String apiKey, int connectTimeoutMilliseconds, int readTimeoutMilliseconds)
throws MissingParameterError {
Expand All @@ -120,7 +121,7 @@ public EasyPostClient(String apiKey, int connectTimeoutMilliseconds, int readTim
* @param connectTimeoutMilliseconds Timeout for connection.
* @param readTimeoutMilliseconds Timeout for read.
* @param apiBase API base for API calls.
* @throws MissingParameterError When the request fails.
* @throws MissingParameterError When the request fails.
*/
public EasyPostClient(String apiKey, int connectTimeoutMilliseconds, int readTimeoutMilliseconds, String apiBase)
throws MissingParameterError {
Expand All @@ -136,6 +137,7 @@ public EasyPostClient(String apiKey, int connectTimeoutMilliseconds, int readTim

/**
* Subscribes to a request hook from the given function.
*
* @param function The function to be subscribed to the request hook
*/
public void subscribeToRequestHook(Function<RequestHookResponses, Object> function) {
Expand All @@ -144,6 +146,7 @@ public void subscribeToRequestHook(Function<RequestHookResponses, Object> functi

/**
* Unsubscribes to a request hook from the given function.
*
* @param function The function to be unsubscribed from the request hook
*/
public void unsubscribeFromRequestHook(Function<RequestHookResponses, Object> function) {
Expand All @@ -152,6 +155,7 @@ public void unsubscribeFromRequestHook(Function<RequestHookResponses, Object> fu

/**
* Subscribes to a response hook from the given function.
*
* @param function The function to be subscribed to the response hook
*/
public void subscribeToResponseHook(Function<ResponseHookResponses, Object> function) {
Expand All @@ -160,6 +164,7 @@ public void subscribeToResponseHook(Function<ResponseHookResponses, Object> func

/**
* Unubscribes to a response hook from the given function.
*
* @param function The function to be unsubscribed from the response hook
*/
public void unsubscribeFromResponseHook(Function<ResponseHookResponses, Object> function) {
Expand Down
188 changes: 188 additions & 0 deletions src/main/java/com/easypost/service/FedExRegistrationService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package com.easypost.service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.easypost.exception.EasyPostException;
import com.easypost.http.Requestor;
import com.easypost.http.Requestor.RequestMethod;
import com.easypost.model.FedExAccountValidationResponse;
import com.easypost.model.FedExRequestPinResponse;

public class FedExRegistrationService {
private final EasyPostClient client;

/**
* FedExRegistrationService constructor.
*
* @param client The client object.
*/
FedExRegistrationService(EasyPostClient client) {
this.client = client;
}

/**
* Register the billing address for a FedEx account.
* Advanced method for custom parameter structures.
*
* @param fedexAccountNumber The FedEx account number.
* @param params Map of parameters.
* @return FedExAccountValidationResponse object with next steps (PIN or invoice
* validation).
* @throws EasyPostException when the request fails.
*/
public FedExAccountValidationResponse registerAddress(final String fedexAccountNumber,
final Map<String, Object> params) throws EasyPostException {
Map<String, Object> wrappedParams = wrapAddressValidation(params);
String endpoint = String.format("fedex_registrations/%s/address", fedexAccountNumber);

return Requestor.request(RequestMethod.POST, endpoint, wrappedParams, FedExAccountValidationResponse.class,
client);
}

/**
* Request a PIN for FedEx account verification.
*
* @param fedexAccountNumber The FedEx account number.
* @param pinMethodOption The PIN delivery method: "SMS", "CALL", or "EMAIL".
* @return FedExRequestPinResponse object confirming PIN was sent.
* @throws EasyPostException when the request fails.
*/
public FedExRequestPinResponse requestPin(final String fedexAccountNumber, final String pinMethodOption)
throws EasyPostException {
Map<String, Object> wrappedParams = new HashMap<>();
Map<String, Object> pinMethodMap = new HashMap<>();
pinMethodMap.put("option", pinMethodOption);
wrappedParams.put("pin_method", pinMethodMap);
String endpoint = String.format("fedex_registrations/%s/pin", fedexAccountNumber);

return Requestor.request(RequestMethod.POST, endpoint, wrappedParams, FedExRequestPinResponse.class, client);
}

/**
* Validate the PIN entered by the user for FedEx account verification.
*
* @param fedexAccountNumber The FedEx account number.
* @param params Map of parameters.
* @return FedExAccountValidationResponse object.
* @throws EasyPostException when the request fails.
*/
public FedExAccountValidationResponse validatePin(final String fedexAccountNumber, final Map<String, Object> params)
throws EasyPostException {
Map<String, Object> wrappedParams = wrapPinValidation(params);
String endpoint = String.format("fedex_registrations/%s/pin/validate", fedexAccountNumber);

return Requestor.request(RequestMethod.POST, endpoint, wrappedParams, FedExAccountValidationResponse.class,
client);
}

/**
* Submit invoice information to complete FedEx account registration.
*
* @param fedexAccountNumber The FedEx account number.
* @param params Map of parameters.
* @return FedExAccountValidationResponse object.
* @throws EasyPostException when the request fails.
*/
public FedExAccountValidationResponse submitInvoice(final String fedexAccountNumber,
final Map<String, Object> params)
throws EasyPostException {
Map<String, Object> wrappedParams = wrapInvoiceValidation(params);
String endpoint = String.format("fedex_registrations/%s/invoice", fedexAccountNumber);

return Requestor.request(RequestMethod.POST, endpoint, wrappedParams, FedExAccountValidationResponse.class,
client);
}

/**
* Wraps address validation parameters and ensures the "name" field exists.
* If not present, generates a UUID (with hyphens removed) as the name.
*
* @param params The original parameters map.
* @return A new map with properly wrapped address_validation and
* easypost_details.
*/
@SuppressWarnings("unchecked")
private Map<String, Object> wrapAddressValidation(final Map<String, Object> params) {
Map<String, Object> wrappedParams = new HashMap<>();

if (params.containsKey("address_validation")) {
Map<String, Object> addressValidation = new HashMap<>(
(Map<String, Object>) params.get("address_validation"));
ensureNameField(addressValidation);
wrappedParams.put("address_validation", addressValidation);
}

if (params.containsKey("easypost_details")) {
wrappedParams.put("easypost_details", params.get("easypost_details"));
}

return wrappedParams;
}

/**
* Wraps PIN validation parameters and ensures the "name" field exists.
* If not present, generates a UUID (with hyphens removed) as the name.
*
* @param params The original parameters map.
* @return A new map with properly wrapped pin_validation and easypost_details.
*/
@SuppressWarnings("unchecked")
private Map<String, Object> wrapPinValidation(final Map<String, Object> params) {
Map<String, Object> wrappedParams = new HashMap<>();

if (params.containsKey("pin_validation")) {
Map<String, Object> pinValidation = new HashMap<>(
(Map<String, Object>) params.get("pin_validation"));
ensureNameField(pinValidation);
wrappedParams.put("pin_validation", pinValidation);
}

if (params.containsKey("easypost_details")) {
wrappedParams.put("easypost_details", params.get("easypost_details"));
}

return wrappedParams;
}

/**
* Wraps invoice validation parameters and ensures the "name" field exists.
* If not present, generates a UUID (with hyphens removed) as the name.
*
* @param params The original parameters map.
* @return A new map with properly wrapped invoice_validation and
* easypost_details.
*/
@SuppressWarnings("unchecked")
private Map<String, Object> wrapInvoiceValidation(final Map<String, Object> params) {
Map<String, Object> wrappedParams = new HashMap<>();

if (params.containsKey("invoice_validation")) {
Map<String, Object> invoiceValidation = new HashMap<>(
(Map<String, Object>) params.get("invoice_validation"));
ensureNameField(invoiceValidation);
wrappedParams.put("invoice_validation", invoiceValidation);
}

if (params.containsKey("easypost_details")) {
wrappedParams.put("easypost_details", params.get("easypost_details"));
}

return wrappedParams;
}

/**
* Ensures the "name" field exists in the provided map.
* If not present, generates a UUID (with hyphens removed) as the name.
* This follows the pattern used in the web UI implementation.
*
* @param map The map to ensure the "name" field in.
*/
private void ensureNameField(final Map<String, Object> map) {
if (!map.containsKey("name") || map.get("name") == null) {
String uuid = UUID.randomUUID().toString().replace("-", "");
map.put("name", uuid);
}
}
}
Loading
Loading