Guides and reports

Adyen for Java developers

By Beppe Catanese, Developer Advocate, Adyen

May 16, 2023
 ·  6 minutes
Screen with API text and other logos

In today's digital age, the ability to connect to different applications through APIs (Application Programming Interfaces) is essential for any modern platform. APIs allow the design of sophisticated workflows, enabling communication between systems that need to exchange data and provide services.

While developers can use different languages and frameworks to directly consume the REST APIs, the adoption of libraries is the most effective path to create friction-less integrations that boost both productivity and developer experience.

In a previousblogwe explained the benefits of using an Adyen API Library. Let’s now explore more specifically the choices and advantages available to Java developers.

In this article..

…discover the Adyen Java Library, what’s new in the latest release, and how to bootstrap a new application or upgrade an existing one.


Adyen Java Library

The Adyen Java library is the toolkit provided to Java developers who work or will work with Adyen’s APIs. It enables them to focus on the use cases and its functional aspects while the library takes care of the necessary groundwork such as connection setup, security features (authentication, encryption and tokenization), validation, exception handling, etc…

The library includes a wrapper for each of our public APIs, complete with documentation. Whether you are implementing a payment flow, platform integration, issuing, capital or API managementyou only need to use this library. As you expand the scope of your integration and access new products or services, the library is already set up and the additional code is minimal.

Benefits

The Java library brings the following advantages typical of the Java ecosystem:

  • Easy access, available on Maven central
  • Usage of packages to ensure encapsulation and avoid name clashing
  • Built-in JSON support with Gson
  • Custom exception class (ApiException) to provide a consistent exception handling
  • Dependency management: use Dependabot or Renovate to be notified when a new Adyen Java Library version is released
  • Comprehensive unit testing coverage: check unit tests to see an example of how services are invoked and models are defined
  • Built-in HTTP client (with additional proxy support) with the option to override and use your own implementation

Supported APIs

All Adyen products are supported in the latest version of the Java library.

APIDescription
Online PaymentsEverything you need to process payments and any advanced use case: Checkout, Payouts, Recurring Payments
Point of SaleManagement of point-of-sale (POS) payment terminals
ManagementConfiguration of company and merchant accounts, stores, payment terminals
Platforms and Financial ProductsWork with Adyen for Platforms: account structure, onboarding, payment flows, embedded financial services

What’s new in the Java library

The Java Library v20 upgrade delivers a lot of new features as well as several significant improvements.

Asubstantial redesignis perhaps the most noteworthy change, as it brings the library in line with Adyen API catalog and naming conventions. This update enables you to quickly locate the relevant Java service that corresponds to an API (i.e. CheckoutService when using the Checkout API). By maintaining consistency across Adyen documentation, the API Explorer, and code samples, you can easily find the information you need.

Another significant change is the adoption of OpenAPI-driven code generation. Java classes that map the request and response payloads are now generated usingOpenAPI Generator, ensuring that the code complies with the contract (i.e. the specification), thus avoiding errors and inconsistencies.

There are other valuable improvements to make sure the library iscomprehensive(all API versions are updated to the latest release, there is support for Adyen for Platforms and Embedded Financial Services),fast(providing built-in methods for JSON processing) andeasy(adding adapter classes mapping each payment method).

Getting started

The Adyen Java library requires minimum setup. Make sure you match the pre-requisites (Java 11, a valid API Key), then add the dependency with your favorite build tool.

Language: xml
1
2
3
4
5
6
7
8
    <!-- Maven dependency -->
<dependency>
  <groupId>com.adyen</groupId>
  <artifactId>adyen-java-api-library</artifactId>
  <version>20.0.0</version>
</dependency>


  
Language: plaintext
1
2
3
4
    # Gradle dependency
dependencies {
  implementation 'com.adyen:adyen-java-api-library:20.0.0'
}
  

Setup the client that will access the Adyen service:

Language: java
1
2
3
4
5
6
    // Setup Client and Service
Client client = new Client(
 "Your X-API-KEY", Environment.TEST);

// PaymentsApi service
PaymentsApi api = new PaymentsApi(client);

  

Use the relevant service and models to access the functionality, for example when using Checkout you can get the list available payment methods:

Language: java
1
2
3
4
5
6
    PaymentMethodsRequest pm = new PaymentMethodsRequest();
pm.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
PaymentMethodsResponse resp = api.paymentMethods(pm);

// print available payment methods
resp.getPaymentMethods().stream().forEach(log::info);

  

When using the Management API (i.e. generate client Key) the approach is similar:

Language: java
1
2
3
4
5
6
7
    // Management ClientKeyMerchantLevel service
ClientKeyMerchantLevel merchantLevel = new ClientKeyMerchantLevel(client);

// generate Client Key
GenerateClientKeyResponse resp = merchantLevel.generateNewClientKey("YOUR_MERCHANT_ACCOUNT", "YOUR_API_CREDENTIAL_ID");

System.out.println(resp.getClientKey());

  

Working with webhooks

Language: java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    // YOUR_HMAC_KEY from the Customer Area
String hmacKey = "YOUR_HMAC_KEY";
String json = "NOTIFICATION_REQUEST_JSON";
HMACValidator hmacValidator = new HMACValidator();

NotificationHandler handler = new NotificationHandler();
NotificationRequest notification = 
 handler.handleNotificationJson(json);

// fetch first (and only) NotificationRequestItem
var item = 
 notification.getNotificationItems().stream().findFirst();

if (item.isPresent()) {
 // Handle the notification
 if ( hmacValidator.validateHMAC(item, hmacKey) ) {
  // Process the notification based on the eventCode
  // …
 } else {
 // Non valid NotificationRequest
  throw new RuntimeError("Invalid HMAC signature");
 }
}

  
Team working together

Is your application already using the Adyen Java library? Do you want to use this latest version? Then this section is for you.

The Adyen Java Library v20 brings lots of new features but, at the same time, introduces several breaking changes. Although affecting existing working code is never good news,“breaking by design”is sometimes necessary. The redesign of the library, the code generation and many other improvements are addressing inconsistencies and removing legacy code.

The new version can better assist you in the implementation of your workflows and use cases, and allow you to easily integrate new products and features as they become available on the Adyen platform.

Migrating your code

All Java models are created based on theOpenAPI specifications, which results in various modifications such as the relocation and renaming of packages, classes, and fields.

Generic models (i.e. Address, Name, BankAccount, etc..) are no longer shared. Each package defines the models it needs. While this results in some duplication of the Java classes, it ensures a good encapsulation of the services.

Notifications have been renamed to webhooks, for example class GenericNotification is now GenericWebhook (watch out, this class includes constants that might be used by your application) and NotificationHandler has become WebhookHandler.

If you work with theCheckout APIyou need to consider the following changes:

  • The single Checkout class has been removed in favor of providing a different service class for each Checkout functionality: PaymentsApi, RecurringApi, ModificationsApi, etc.. Each service corresponds to a functionality (sub-folder) of the Checkout API ensuring consistency between the library and the API.
  • `com.adyen.model.Amount` is now `com.adyen.model.checkout.Amount`
  • `com.adyen.model.checkout.details.StorePaymentMethodDetails` is now `com.adyen.model.checkout.StorePaymentMethodDetails`
  • `PaymentsRequest` has been renamed `PaymentRequest`
  • `PaymentsResponse` has been renamed `PaymentResponse`
  • Several helper methods (setAmountData, setCardData, isAuthorised, getCardHolderName) have been removed to let Java models provide getter/setter methods only, consistently with the OpenAPI specification and the API Explorer documentation.

Gson

Another major change is the introduction ofGsonas the preferred JSON processing framework. This should be transparent to the application as the library takes care of providing the serialization and deserialization logic that converts JSON payloads into Java objects.

You can find within each model (ie CardDetailsRequest) the methods to process JSON:

Language: java
1
2
3
4
5
6
7
8
9
10
11
    public static CardDetailsRequest fromJson(String jsonString) 
 throws IOException {
   return JSON.getGson()
    .fromJson(jsonString, CardDetailsRequest.class);
 }

public String toJson() {
   return JSON.getGson().toJson(this);
 }
}

  

In the case of handling the webhooks you can take advantage of the built-in methods, for example:

Language: java
1
2
3
4
5
6
7
8
    @PostMapping("/webhooks/notifications")
public ResponseEntity<String> webhooks(@RequestBody) 
 throws Exception {
  // from JSON string to object
  var req = NotificationRequest.fromJson(json);

  // consume event 
  // ...    
  

Upgrade the Recurring Payment sample

Let’s look at a use case and what should be done when upgrading an existing application to the Adyen Java library v20.

OnGitHubyou can find a Java sample application that demonstrates how to implement payment subscriptions. It is a simplified version of a website that offers a music subscription service. 

There are 2 flows basically:

  • the shopper can purchase a subscription, saving the card details for the recurring payment (aka Tokenization)
  • the site administrator can make payments on behalf of the shopper (for example monthly when the subscription is renewed) and optionally expire the token
Subscription sample application screenshot

The first step is to update the dependency version in the application. It uses Gradle therefore we need to change the`adyen-java-library` version in `build.gradle`

Language: plaintext
1
2
3
4
    # Gradle dependency
dependencies {
  implementation 'com.adyen:adyen-java-api-library:20.0.0'
}
  

The new version (as outlined above) has refactored packages and classes, so we need to update several imports and replace the Checkout class with PaymentsApi:

Language: java
1
2
3
4
5
6
7
8
9
10
11
12
    import com.adyen.model.checkout.Amount;
import com.adyen.model.checkout.CreateCheckoutSessionRequest;
import com.adyen.model.checkout.CreateCheckoutSessionResponse;
import com.adyen.service.checkout.PaymentsApi;

@RestController
@RequestMapping("/api")
public class SubscriptionResource {

 // PaymentsApi service class	
 private final PaymentsApi paymentsApi;
 // …

  

Other classes and references to update:

  • PaymentsRequest and PaymentsResponse have been renamed to PaymentRequest and PaymentResponse: the imports and the class names must be updated
  • The class that defines the payment method is now called CheckoutPaymentMethod

The revised code snippet to perform a payment using a token looks like:

Language: java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    PaymentRequest paymentRequest = new PaymentRequest();

paymentRequest.setMerchantAccount(“YOUR_MERCHANT_ACCOUNT”);
paymentRequest.setAmount
  (new Amount().currency("EUR").value(1199L));
paymentRequest.setReference(orderRef);
paymentRequest.setShopperInteraction(
  PaymentRequest.ShopperInteractionEnum.CONTAUTH);
paymentRequest.setShopperReference(
  Storage.SHOPPER_REFERENCE);
paymentRequest.setRecurringProcessingModel(
  PaymentRequest.RecurringProcessingModelEnum.SUBSCRIPTION);
paymentRequest.setPaymentMethod(
  new CheckoutPaymentMethod(
   new StoredPaymentMethodDetails().storedPaymentMethodId(“abc123”)));

PaymentResponse response = this.paymentsApi.payments(paymentRequest);
  

Finally we need to update the webhook handler to take advantage of the built-in methods for deserializing the JSON payload into a Java object.

Language: java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    // processing incoming webhooks
@PostMapping("/webhooks/notifications")
public ResponseEntity<String> webhooks(@RequestBody String json) 
 throws Exception {

  // from JSON string to object
  NotificationRequest request = 
    NotificationRequest.fromJson(json);

  // fetch first (and only) NotificationRequestItem
  Optional<NotificationRequestItem> item = 
   request.getNotificationItems().stream().findFirst();

  if (item.isPresent()) {
    // consume webhooks
    // ...

  

Next steps

It is time to get coding.

For new starters the simplest way to see the Adyen Java library in action is to look at theJava Spring sample application. The sample uses theWeb Drop-inand the Java library to demonstrate the Checkout use case.

Run the application withone click using Gitpodand browse through the source code to learn how to obtain the available payment methods, perform the transaction and process the asynchronous event delivered by webhooks.

If you are upgrading an existing application the Upgrade section above will guide you through the changes and how to deal with them. We are of course ready to help you in case something is not clear or requires additional details.

We are looking forward to hearing your feedback about our libraries, what is missing or can be improved. Join oursurveyand let us know how we can improve them and make your developer experience better.




Fresh insights, straight to your inbox

By submitting your information you confirm that you have read Adyen's Privacy Policy and agree to the use of your data in all Adyen communications.