Java SDK

Looking for the Card Present SDK?

Get started seamlessly integrating our payment solution with the WePay V3 Java Software Development Kit (SDK).

This guide will outline how to install, configure, and initialize the WePay V3 Java SDK with code demos of how to execute our most common API Requests.

For more information on our available methods, objects, and errors, see the Javadoc which is available in the SDK package.

Note

Required fields will be the same as indicated in the v3.0 API reference. For any updates, see our Release Notes and ensure you're on the latest SDK version.


Get Started

Getting started with the Java SDK requires two steps:

  1. Download Software requirements
  2. Download and Install the SDK

Download Software requirements

Download Java 1.8 or later

Download and Install the SDK

There are two ways to access our SDK:

1. Maven Repository

To access our Java SDK from Maven, add wepay-v3-java-sdk to your app/build.gradle file:
Copy
Copied
repositories {
    mavenCentral()
}

dependencies {
    implementation group: 'com.wepay', name: 'wepay-v3-java-sdk', version: '0.0.1'
}

2. Download the JAR fields

This method would require you to download the .JAR files and manually upload them to your Java Project.


SDK Organization

The Java SDK contains several packages:

  • com.wepay.exception: Defines exceptions that could be thrown by the APIs. See Handle Errors.
  • com.wepay.endpoints: Functions that are the entry points for making API calls.
  • com.wepay.model.*: These packages contains POJO classes that represent objects used in the WePay API.
    • com.wepay.model.resource: Represent a WePay resource (which is what's returned by most API requests).
    • com.wepay.model.collection: Represent a collection of WePay resources (returned by find() requests).
    • com.wepay.model.request_params: The body of an API request.
    • com.wepay.model.additional_params: Additional data for an API request, such as headers.
    • com.wepay.model.data: Nested objects in the request or response.
    • com.wepay.model.enums: Enumeration values.
  • com.wepay.network: Used internally by the SDK.

Configure the SDK

The SDK must be configured with your app's credentials before it can be used. You can find these in the Partner Center under the Development tab.

Use the table below to determine which testing environment your app will use. The environment inputs are case-sensitive.

Base URLEnvironment
https://stage-api.wepay.comSTAGE
https://api.wepay.comPRODUCTION
Copy
Copied
import com.wepay.network.Configuration;
import com.wepay.network.WePayRequest;

    Configuration configuration = new Configuration();
    configuration.setAppId("<YOUR APP ID>");
    configuration.setAppToken("<YOUR APP TOKEN>");
    configuration.setEnvironment(Configuration.Environment.STAGE);
    WePayRequest.initializeRequest();

Make API Requests

API requests can be made to WePay using the classes under com.wepay.endpoints.*. Each class corresponds to an API resource, and each function corresponds to an operation on that resource.
The mapping between SDK methods and API calls is useful for referencing the API Reference and Guides and understanding the structure of the SDK.

The SDK methods are grouped under each top-level API resource. For example, this is the mapping for Accounts:

The input parameters are derived from our API Reference. Each field in the schema has a corresponding field in the SDK. In addition, the Javadoc for the SDK methods will also point out what the corresponding API call is.

Handle Errors

All API request methods can throw these exceptions within the SDK:

SDK ErrorDescription
IOExceptionThe SDK failed to establish valid connection to our servers.
JSONExceptionThe SDK failed to get a valid JSON response.
WePayExceptionWePay returned an error response.
UnknownWePayExceptionAn unknown exception occurred. This is a generic exception which means the SDK received an error response which was not expected for this endpoint.
The API request methods have a long list of exceptions in the function signature. All of them (besides IOException and JSONException) are subclasses of WePayException. The exceptions here correspond to the errors described in our Errors Guide. For a few exceptions without details, empty values are provided instead of null.

You have several options for handling API errors.

Handle the relevant WePay errors

This option allows your application to have special handling for any errors it cares about, while handling the rest as generic errors.

Copy
Copied
try {
    AccountsRequestParamData accountsRequestParamData = new AccountsRequestParamData();
    AccountsCollection findResult = AccountsApi.find(accountsRequestParamData);
}
catch (InvalidParams e) {
    LOGGER.info("handling invalid params error");
    LOGGER.info(e.getMessage());
}
catch (WePayException e) {
    LOGGER.info("handling any other WePay errors");
}
catch (IOException | JSONException e) {
    LOGGER.info("failed to send the request");
}

Handle every type of error

This option is the most tedious, but it has the benefit of having a strict compile-time check that all exceptions have been caught.

Copy
Copied
try {
    AccountsRequestParamData accountsRequestParamData = new AccountsRequestParamData();
    AccountsCollection findResult = AccountsApi.find(accountsRequestParamData);
}
catch (InvalidParams | NotAuthorized e) {
    LOGGER.info("handling some known WePay errors");
}
catch (ThrottleExceeded e) {
    LOGGER.info("handling throttle exceeded");
}
catch (UnknownWePayException | UnexpectedError | ServiceTemporarilyUnavailable | JSONException | IOException e) {
    LOGGER.info("handling non-actionable errors");
}

Handle errors based on the error code

The type of error can also be determined by the exception's error code.

Copy
Copied
try {
    AccountsRequestParamData accountsRequestParamData = new AccountsRequestParamData();
    AccountsFindRespData findResult = AccountsApi.find(accountsRequestParamData);
}
catch (WePayException e) {
    switch (e.getErrorCode() {
        case InvalidParams.ERROR_CODE: break;
        case NotAuthorized.ERROR_CODE: break;
    }
}
catch (IOException | JSONException e) {
    LOGGER.info("failed to send the request");
}

Use Auto Pagination

The find() method request returns a fixed-size page, which may not fetch all results in your query. Instead of manually asking for the next page to get all results, the autoPagingIterable makes this simpler by fetching large lists of resources:
Copy
Copied
    AccountsRequestParamData requestParamData = new AccountsRequestParamData();
    requestParamData.setPageSize(50);
    AccountsCollection accounts = AccountsApi.find(new AccountsRequestParamData());
    for (Account account: accounts.autoPagingIterable()) {
        // Do something with `account`
    }

Implement Idempotency

By default, the SDK requests are configured to retry on retry-able error responses as described in detail in our Design a Retry Strategy cookbook. The default retry policy comes with exponential backoff, a deadline of 24 hours and 30 retry attempts maximum. Retries will be attempted only if the Unique-Key header is provided in the original request.

Configure retry policy

Partners can disable retry by configuring the WePayHttpClient with the NO_RETRY policy:
Copy
Copied
WePayRequest.setHttpClient(
    WePayHttpClient.builder().retryPolicy(PredefinedRetryPolicies.NO_RETRY)
    .build()
);
Create your own retry policy with customized BackoffStrategy and RetryCondition.

The default retry condition checks multiple conditions in the following order:

  • If the Unique-Key header is not present;
  • If the retry deadline is past;
  • If the max number of retries is reached;
  • If the error is one of the retry-able errors.

Make async requests

If you are implementing a retry strategy that takes longer than 30 seconds to terminate, use the asynchronous version of methods to make requests. This helps to avoid prolonged and hanging API requests.
Synchronous Example:
Copy
Copied
Payment payment = PaymentsApi.create( paymentsCreateData, paymentsCreateAdditionalParams);
// waiting for line above to finish executing before moving on
Asynchronous Example:
Copy
Copied
Payment payment = = PaymentsApi.createAsync(paymentsCreateData, paymentsCreateAdditionalParams);
// do some other stuff
Payment paymentCreateResult = payment.join();

Persistence

The SDK currently does not provide any persistence support, so partners need to implement a strategy to retrieve and continue in-retry requests in the case of an application restart.

The solution will possibly include persisting the request body and headers with its retryContext which contains the initial request time, number of attempts, etc. The restarted application can load these data and re-attempt the requests.

Clear Usage Demos

Creating a Legal Entity

Copy
Copied
try {
    LegalEntitiesCreateData legalEntitiesCreateData = new LegalEntitiesCreateData();
    legalEntitiesCreateData.setCountry(CountriesEnum.US); // Country is a required parameter for the Create Legal Entities call
    LegalEntity legalEntity = LegalEntitiesApi.create(legalEntitiesCreateData);
    LOGGER.info(String.format("Successfully created a legal entity, id = %s", legalEntity.getId()));
}
catch (WePayException e) {
    LOGGER.warning(String.format("WePay error: %s", e.getMessage()));
}
catch (Exception e) {
    LOGGER.warning(e.getMessage());
}

Creating an Account

Copy
Copied
try {
    AccountsCreateData accountsCreateData = new AccountsCreateData();
    accountsCreateData.setLegalEntityId("<Legal Entity ID>"); // A Legal Entity ID is a required parameter for the Create Account call
    Account createResult = AccountsApi.create(accountsCreateData);
    LOGGER.log(Level.INFO, String.format("Successfully create an account %s", createResult.getId()));
}
catch (Exception e) {
    LOGGER.log(Level.WARNING, e.getMessage());
}

Updating Capabilities

Copy
Copied
try {
    AccountsCapabilitiesData accountsCapabilitiesData = new AccountsCapabilitiesData();
    AccountsIdCapabilitiesPaymentsRequest paymentCapability = new AccountsIdCapabilitiesPaymentsRequest();
    AccountsIdCapabilitiesApplicationBlockRequest applicationBlock = new AccountsIdCapabilitiesApplicationBlockRequest();
    applicationBlock.setIsBlocked(true); // is_blocked a required parameter for the Update Capabilities call
    applicationBlock.setReason("<REASON>"); // Reason is a required parameter for the Update Capabilities call
    paymentCapability.setApplicationBlock(applicationBlock);
    accountsCapabilitiesData.setPayments(paymentCapability);
    CapabilitiesResp capabilities = AccountsApi.capabilities(accountId, accountsCapabilitiesData);
}
catch (Exception e) {
    LOGGER.log(Level.WARNING, e.getMessage());
}

Making a Payment

Copy
Copied
try {
    PaymentsPaymentMethodRequest paymentMethod = new PaymentsPaymentMethodRequest();
    paymentMethod.setPaymentMethodId("<PAYMENT-METHOD-ID>"); 

    PaymentsCreateData paymentsCreateData = new PaymentsCreateData();
    paymentsCreateData.setAccountId("<ACCOUNT-ID>"); // Account ID is a required parameter for the Create Payment call
    paymentsCreateData.setAmount(AMOUNT); // Amount is a required parameter for the Create Payment call
    paymentsCreateData.setFeeAmount(30);
    paymentsCreateData.setCurrency(CurrencyEnum.USD); // Currency is a required parameter for the Create Payment call
    paymentsCreateData.setPaymentMethod(paymentMethod); // Payment Method is a required parameter for the Create Payment call
    paymentsCreateData.setAutoCapture(false);
    paymentsCreateData.setReferenceId(REFERENCE_ID);


    PaymentsCreateAdditionalParams paymentsCreateAdditionalParams = new PaymentsCreateAdditionalParams();
    paymentsCreateAdditionalParams.setUniqueKey("1"); // Unique Key is a required parameter for the Create Payment call

    Payment payment = PaymentsApi.create(paymentsCreateData, paymentsCreateAdditionalParams);
        LOGGER.log(Level.INFO, String.format("Successfully create a payment %s", payment.getId()));
    }
catch (Exception e) {
    LOGGER.log(Level.WARNING, e.getMessage());
}