From 09291ab1d8c421cbebe6e52fb945948f3ff277c1 Mon Sep 17 00:00:00 2001 From: gcatanese Date: Mon, 15 Sep 2025 11:28:09 +0200 Subject: [PATCH 01/11] Add agents.md (draft) --- agents.md | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 agents.md diff --git a/agents.md b/agents.md new file mode 100644 index 000000000..2b8f246bf --- /dev/null +++ b/agents.md @@ -0,0 +1,242 @@ +# Adyen Java API Library for AI Assistants + +This file gives guidance to AI-based coding assistants (like Copilot or ChatGPT) to help developers use the **Adyen Java API Library**. + +The goal is to provide **simple, working examples** that help developers quickly get started with setup, making requests, and handling responses. + +--- + +## General Rules + +- Always use classes from the `com.adyen` package (not internal or test code). +- Show **minimal, copy-pasteable examples**. +- Use `Environment.TEST` in all examples. +- Get credentials (API key, merchant account) from **environment variables** — never hardcode secrets. +- Generate snippets only looking at this file, the README.md or the unit test source code at https://github.com/Adyen/adyen-java-api-library/tree/main/src/test/java/com/adyen +- If developers need more details, link to: + - [Adyen Java API Library](https://github.com/Adyen/adyen-java-api-library) + - [Adyen API Explorer](https://docs.adyen.com/api-explorer/) + - [Adyen Java Sample Application](https://github.com/adyen-examples/adyen-java-spring-online-payments) + +## What is the Adyen Java API Library? + +The Adyen Java API Library is a client SDK that allows developers to integrate with Adyen from Java applications. It provides: + +- Simplified access to Adyen APIs (Checkout, Terminal API, Plaforms and Financial Services). +- Request and response models for all API endpoints, so you don’t have to manually construct JSON. +- Helpers for security and HTTP calls, including setting API keys, idempotency keys, and headers. +- Error handling utilities to manage API exceptions in a structured way. + +It supports the following Adyen APIs: + +- **Checkout** https://docs.adyen.com/api-explorer/Checkout/latest/overview +- **Terminal API** https://docs.adyen.com/api-explorer/terminal-api/1/overview +- **Management API** https://docs.adyen.com/api-explorer/Management/ +- **Legal Entity Management API** https://docs.adyen.com/api-explorer/legalentity/ +- **Balance Platform Configuration API** https://docs.adyen.com/api-explorer/balanceplatform/ +- **Tranfers API** https://docs.adyen.com/api-explorer/transfers/ +- **Webhooks** https://docs.adyen.com/api-explorer/Webhooks/1/overview +- **Balance Platform Configuration webhooks** https://docs.adyen.com/api-explorer/balanceplatform-webhooks/ +- **Transfers Webhooks** https://docs.adyen.com/api-explorer/transfer-webhooks/ + + +## Installation + +Show developers how to add the library: + +**Maven** + +```xml + + + com.adyen + adyen-java-api-library + LATEST_VERSION + +``` + +```groovy +implementation 'com.adyen:adyen-java-api-library:LATEST_VERSION' + +``` + +## Setup + +Show developers how to setup the client: + +```java + +import com.adyen.Client; +import com.adyen.enums.Environment; +import com.adyen.service.checkout.PaymentsApi; +import com.adyen.model.checkout.*; + +// Setup Client +Client client = new Client( + new Config( + .environment(Environment.TEST) + .liveEndpointUrlPrefix("myCompany") + .apiKey(System.getenv().get("Your X-API-KEY")) + ) +); + +// Setup Service +PaymentsApi paymentsApi = new PaymentsApi(client); +``` + +## Make a payment with Checkout + +Show developers how to make a payment with the Checkout API: + +```java + +import com.adyen.Client; +import com.adyen.Config; +import com.adyen.enums.Environment; +import com.adyen.service.checkout.PaymentsApi; +import com.adyen.model.checkout.*; + +// Setup Client +Client client = new Client( + new Config( + .environment(Environment.TEST) + .liveEndpointUrlPrefix("myCompany") + .apiKey(System.getenv().get("Your X-API-KEY")) + ) +); + +// Setup Service +PaymentsApi paymentsApi = new PaymentsApi(client); + +// Create PaymentRequest +CardDetails cardDetails = + new CardDetails() + .type(CardDetails.TypeEnum.SCHEME) + .encryptedCardNumber("5136333333333335") + .holderName("John Doe") + .cvc("737") + .encryptedExpiryMonth("08") + .encryptedExpiryYear("2018"); +PaymentRequest paymentRequest = + new PaymentRequest() + .merchantAccount("YOUR_MERCHANT_ACCOUNT") + .reference("YOUR_REFERENCE") + .amount(new Amount() + .currency("EUR") + .value(1000L)) + .returnUrl("https://your-company.example.org/checkout?shopperOrder=12xy..") + .paymentMethod(new CheckoutPaymentMethod(cardDetails)); + +// Make a call to the /payments endpoint +PaymentResponse paymentResponse = paymentsApi.payments(paymentRequest); +``` + +## Error handling + +Show developers how to handle errors: use a try-catch block to handle API errors. +Catch the `ApiException` to inspect the response and handle specific cases: + + +```java +// Setup Client +Client client = new Client( + new Config( + .environment(Environment.TEST) + .liveEndpointUrlPrefix("myCompany") + .apiKey(System.getenv().get("Your X-API-KEY")) + ) +); + + +// Setup Service +PaymentLinksApi paymentLinksApi = new PaymentLinksApi(client); + +// Get Payment link +try { + paymentLinksApi.getPaymentLink("1234"); +} catch (ApiException e) { + // Obtain response + int statusCode = e.getStatusCode(); + String responseBody = e.getResponseBody(); + // Check ApiError object + ApiError apiError = e.getError(); + String errorCode = apiError.getErrorCode(); + List invalidFields = apiError.getInvalidFields(); +} + +``` + +## Webhook processing + +Show developers how to handle webhooks: + +```java +import java.util.List; +import com.adyen.util.HMACValidator; +import com.adyen.notification.WebhookHandler; +import com.adyen.model.notification.NotificationRequest; +import com.adyen.model.notification.NotificationRequestItem; + +String hmacKey = System.getenv().get("Your X-API-KEY"); +// The webhook payload +String notificationRequestJson = "NOTIFICATION_REQUEST_JSON"; + +HMACValidator hmacValidator = new HMACValidator(); + +WebhookHandler webhookHandler = new WebhookHandler(); +NotificationRequest notificationRequest = webhookHandler.handleNotificationJson(notificationRequestJson); + +// fetch first (and only) NotificationRequestItem +var notificationRequestItem = notificationRequest.getNotificationItems().stream().findFirst(); + +if (notificationRequestItem.isPresent()) { + // validate the HMAC signature + if ( hmacValidator.validateHMAC(notificationRequestItem, hmacKey) ) { + // Process the notification based on the eventCode + log.info("Received webhook with event {} : \n" + + "Merchant Reference: {}\n" + + "Alias : {}\n" + + "PSP reference : {}", + notificationRequestItem.getEventCode(), + notificationRequestItem.getMerchantReference(), + notificationRequestItem.getAdditionalData().get("alias"), + notificationRequestItem.getPspReference()); + } else { + // Non valid NotificationRequest + throw new RuntimeException("Invalid HMAC signature"); + } +} + +``` + +## Idempotency key + +Show developers how to use an idempotency key: + +```java + +import java.util.UUID; +import com.adyen.model.checkout.PaymentRequest; +import com.adyen.model.checkout.PaymentResponse; +import com.adyen.RequestOptions; + +// Create a PaymentRequest +PaymentRequest paymentRequest = new PaymentRequest(); +// ... set amount, merchant account, payment method, etc. + +// Generate a random idempotency key +RequestOptions requestOptions = new RequestOptions() + .idempotencyKey(UUID.randomUUID().toString()); + +// Make the payment request with idempotency +PaymentResponse paymentResponse = checkout.payments(paymentRequest, requestOptions); + +System.out.println("Payment response: " + paymentResponse); + +``` +Notes for developers: + +- UUID.randomUUID() generates a random UUID (version 4), suitable for idempotency keys. +- Always use a new key for each logically unique request. +- This is important to prevent duplicate payments if the request is retried due to network issues or timeouts. + From aa3534abbb32e04a5da7dd668736f0dcaea52e12 Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:10:48 +0200 Subject: [PATCH 02/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents.md b/agents.md index 2b8f246bf..5d7614c6b 100644 --- a/agents.md +++ b/agents.md @@ -161,7 +161,7 @@ try { // Check ApiError object ApiError apiError = e.getError(); String errorCode = apiError.getErrorCode(); - List invalidFields = apiError.getInvalidFields(); + List invalidFields = apiError.getInvalidFields(); } ``` From 101ac661eefaec05bf59925a74c9924e53527b20 Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:10:56 +0200 Subject: [PATCH 03/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents.md b/agents.md index 5d7614c6b..68c24e640 100644 --- a/agents.md +++ b/agents.md @@ -177,7 +177,7 @@ import com.adyen.notification.WebhookHandler; import com.adyen.model.notification.NotificationRequest; import com.adyen.model.notification.NotificationRequestItem; -String hmacKey = System.getenv().get("Your X-API-KEY"); +String hmacKey = System.getenv("ADYEN_HMAC_KEY"); // The webhook payload String notificationRequestJson = "NOTIFICATION_REQUEST_JSON"; From b330823994793516a802c5e5d32aa642847f5163 Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:12:33 +0200 Subject: [PATCH 04/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/agents.md b/agents.md index 68c24e640..27bf09c93 100644 --- a/agents.md +++ b/agents.md @@ -187,16 +187,17 @@ WebhookHandler webhookHandler = new WebhookHandler(); NotificationRequest notificationRequest = webhookHandler.handleNotificationJson(notificationRequestJson); // fetch first (and only) NotificationRequestItem -var notificationRequestItem = notificationRequest.getNotificationItems().stream().findFirst(); +var notificationRequestItemOptional = notificationRequest.getNotificationItems().stream().findFirst(); -if (notificationRequestItem.isPresent()) { +if (notificationRequestItemOptional.isPresent()) { + NotificationRequestItem notificationRequestItem = notificationRequestItemOptional.get(); // validate the HMAC signature if ( hmacValidator.validateHMAC(notificationRequestItem, hmacKey) ) { // Process the notification based on the eventCode - log.info("Received webhook with event {} : \n" + - "Merchant Reference: {}\n" + - "Alias : {}\n" + - "PSP reference : {}", + System.out.printf("Received webhook with event %s : %n" + + "Merchant Reference: %s%n" + + "Alias : %s%n" + + "PSP reference : %s%n", notificationRequestItem.getEventCode(), notificationRequestItem.getMerchantReference(), notificationRequestItem.getAdditionalData().get("alias"), From 531ea563030b341ee592da5fe163f0601e9d800c Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:13:16 +0200 Subject: [PATCH 05/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents.md b/agents.md index 27bf09c93..84dd47607 100644 --- a/agents.md +++ b/agents.md @@ -55,7 +55,7 @@ Show developers how to add the library: ``` -```groovy +```gradle implementation 'com.adyen:adyen-java-api-library:LATEST_VERSION' ``` From b2423e7b17eebddeb9902f242de6e710bf9bc256 Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:14:16 +0200 Subject: [PATCH 06/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents.md b/agents.md index 84dd47607..63668343d 100644 --- a/agents.md +++ b/agents.md @@ -230,7 +230,7 @@ RequestOptions requestOptions = new RequestOptions() .idempotencyKey(UUID.randomUUID().toString()); // Make the payment request with idempotency -PaymentResponse paymentResponse = checkout.payments(paymentRequest, requestOptions); +PaymentResponse paymentResponse = paymentsApi.payments(paymentRequest, requestOptions); System.out.println("Payment response: " + paymentResponse); From add0b90d669039eb9202988ad5b492d851799f4c Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:14:52 +0200 Subject: [PATCH 07/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents.md b/agents.md index 63668343d..5439ae1f2 100644 --- a/agents.md +++ b/agents.md @@ -22,7 +22,7 @@ The goal is to provide **simple, working examples** that help developers quickly The Adyen Java API Library is a client SDK that allows developers to integrate with Adyen from Java applications. It provides: -- Simplified access to Adyen APIs (Checkout, Terminal API, Plaforms and Financial Services). +- Simplified access to Adyen APIs (Checkout, Terminal API, Platforms and Financial Services). - Request and response models for all API endpoints, so you don’t have to manually construct JSON. - Helpers for security and HTTP calls, including setting API keys, idempotency keys, and headers. - Error handling utilities to manage API exceptions in a structured way. From ba53d90c8e2f3d18f5fc3f3b45176322ebf9e4ef Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:15:35 +0200 Subject: [PATCH 08/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents.md b/agents.md index 5439ae1f2..fb17e9f2d 100644 --- a/agents.md +++ b/agents.md @@ -34,7 +34,7 @@ It supports the following Adyen APIs: - **Management API** https://docs.adyen.com/api-explorer/Management/ - **Legal Entity Management API** https://docs.adyen.com/api-explorer/legalentity/ - **Balance Platform Configuration API** https://docs.adyen.com/api-explorer/balanceplatform/ -- **Tranfers API** https://docs.adyen.com/api-explorer/transfers/ +- **Transfers API** https://docs.adyen.com/api-explorer/transfers/ - **Webhooks** https://docs.adyen.com/api-explorer/Webhooks/1/overview - **Balance Platform Configuration webhooks** https://docs.adyen.com/api-explorer/balanceplatform-webhooks/ - **Transfers Webhooks** https://docs.adyen.com/api-explorer/transfer-webhooks/ From 9beb659b11ca7b3c027b2d2557f7991a5d89e21a Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:24:36 +0200 Subject: [PATCH 09/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/agents.md b/agents.md index fb17e9f2d..023244543 100644 --- a/agents.md +++ b/agents.md @@ -72,12 +72,9 @@ import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.*; // Setup Client -Client client = new Client( - new Config( - .environment(Environment.TEST) - .liveEndpointUrlPrefix("myCompany") - .apiKey(System.getenv().get("Your X-API-KEY")) - ) +Client client = new Client(new Config() + .environment(Environment.TEST) + .apiKey(System.getenv("ADYEN_API_KEY")) ); // Setup Service From 113844a4120f7d2f2513acdcdf48c5f9349ed0ba Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:24:49 +0200 Subject: [PATCH 10/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/agents.md b/agents.md index 023244543..3d5ab0c48 100644 --- a/agents.md +++ b/agents.md @@ -94,12 +94,9 @@ import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.*; // Setup Client -Client client = new Client( - new Config( - .environment(Environment.TEST) - .liveEndpointUrlPrefix("myCompany") - .apiKey(System.getenv().get("Your X-API-KEY")) - ) +Client client = new Client(new Config() + .environment(Environment.TEST) + .apiKey(System.getenv("ADYEN_API_KEY")) ); // Setup Service From 5be58ea874caaf3bf15fb9aeefa845007dc6896b Mon Sep 17 00:00:00 2001 From: Beppe Catanese <1771700+gcatanese@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:24:59 +0200 Subject: [PATCH 11/11] Update agents.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- agents.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/agents.md b/agents.md index 3d5ab0c48..b26a2971e 100644 --- a/agents.md +++ b/agents.md @@ -133,12 +133,9 @@ Catch the `ApiException` to inspect the response and handle specific cases: ```java // Setup Client -Client client = new Client( - new Config( - .environment(Environment.TEST) - .liveEndpointUrlPrefix("myCompany") - .apiKey(System.getenv().get("Your X-API-KEY")) - ) +Client client = new Client(new Config() + .environment(Environment.TEST) + .apiKey(System.getenv("ADYEN_API_KEY")) );