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:
Download Software requirements
Download Java 1.8 or laterDownload 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 yourapp/build.gradle
file: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 byfind()
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 URL | Environment |
---|---|
https://stage-api.wepay.com | STAGE |
https://api.wepay.com | PRODUCTION |
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 undercom.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:
GET /accounts
AccountsApi.find()
POST /accounts
AccountsApi.create()
GET /accounts/{id}
AccountsApi.lookup()
POST /accounts/{id}
AccountsApi.update()
DELETE /accounts/{id}
AccountsApi.delete()
GET /accounts/{id}/capabilities
AccountsApi.getCapabilities()
POST /accounts/{id}/capabilities
AccountsApi.capabilities()
Handle Errors
All API request methods can throw these exceptions within the SDK:
SDK Error | Description |
---|---|
IOException | The SDK failed to establish valid connection to our servers. |
JSONException | The SDK failed to get a valid JSON response. |
WePayException | WePay returned an error response. |
UnknownWePayException | An unknown exception occurred. This is a generic exception which means the SDK received an error response which was not expected for this endpoint. |
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.
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.
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.
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, theautoPagingIterable
makes this simpler by fetching large lists of resources: 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 theUnique-Key
header is provided in the original request.Configure retry policy
Partners can disable retry by configuring theWePayHttpClient
with the NO_RETRY
policy:WePayRequest.setHttpClient(
WePayHttpClient.builder().retryPolicy(PredefinedRetryPolicies.NO_RETRY)
.build()
);
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:
Payment payment = PaymentsApi.create( paymentsCreateData, paymentsCreateAdditionalParams);
// waiting for line above to finish executing before moving on
Asynchronous Example:
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 itsretryContext
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
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
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
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
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());
}