diff --git a/README.md b/README.md index c21e01b7b..425e67a07 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,202 @@ System.setProperty("https.proxyUser", "squid"); System.setProperty("https.proxyPassword", "ward"); ~~~~ +## Using the Cloud Terminal API Integration +In order to submit In-Person requests with [Terminal API over Cloud](https://docs.adyen.com/point-of-sale/design-your-integration/choose-your-architecture/cloud/) you need to initialize the client in a similar way as the steps listed above for Ecommerce transactions, but make sure to include `TerminalCloudAPI`: +``` java +// Step 1: Import the required classes +import com.adyen.Client; +import com.adyen.enums.Environment; +import com.adyen.service.TerminalCloudAPI; +import com.adyen.model.nexo.*; +import com.adyen.model.terminal.*; + +// Step 2: Initialize the client object +Client client = new Client("Your YOUR_API_KEY", Environment.TEST); + +// Step 3: Initialize the API object +TerminalCloudAPI terminalCloudApi = new TerminalCloudAPI(client); + +// Step 4: Create the request object +String serviceID = "123456789"; +String saleID = "POS-SystemID12345"; +String POIID = "Your Device Name(eg V400m-123456789)"; + +// Use a unique transaction for every other transaction you perform +String transactionID = "TransactionID"; +TerminalAPIRequest terminalAPIRequest = new TerminalAPIRequest(); +SaleToPOIRequest saleToPOIRequest = new SaleToPOIRequest(); + +MessageHeader messageHeader = new MessageHeader(); +messageHeader.setMessageClass(MessageClassType.SERVICE); +messageHeader.setMessageCategory(MessageCategoryType.PAYMENT); +messageHeader.setMessageType(MessageType.REQUEST); +messageHeader.setProtocolVersion("3.0"); +messageHeader.setServiceID(serviceID); +messageHeader.setSaleID(saleID); +messageHeader.setPOIID(POIID); + +saleToPOIRequest.setMessageHeader(messageHeader); + +com.adyen.model.nexo.PaymentRequest paymentRequest = new com.adyen.model.nexo.PaymentRequest(); +SaleData saleData = new SaleData(); +TransactionIdentification transactionIdentification = new TransactionIdentification(); +transactionIdentification.setTransactionID("001"); +XMLGregorianCalendar timestamp = DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar()); +transactionIdentification.setTimeStamp(timestamp); +saleData.setSaleTransactionID(transactionIdentification); + +SaleToAcquirerData saleToAcquirerData = new SaleToAcquirerData(); +ApplicationInfo applicationInfo = new ApplicationInfo(); +CommonField merchantApplication = new CommonField(); +merchantApplication.setVersion("1"); +merchantApplication.setName("Test"); +applicationInfo.setMerchantApplication(merchantApplication); +saleToAcquirerData.setApplicationInfo(applicationInfo); +saleData.setSaleToAcquirerData(saleToAcquirerData); + +PaymentTransaction paymentTransaction = new PaymentTransaction(); +AmountsReq amountsReq = new AmountsReq(); +amountsReq.setCurrency("EUR"); +amountsReq.setRequestedAmount(BigDecimal.valueOf(1000)); +paymentTransaction.setAmountsReq(amountsReq); + +paymentRequest.setPaymentTransaction(paymentTransaction); +paymentRequest.setSaleData(saleData); + +saleToPOIRequest.setPaymentRequest(paymentRequest); + +terminalAPIRequest.setSaleToPOIRequest(saleToPOIRequest); + +// Step 5: Make the request +TerminalAPIResponse terminalAPIResponse = terminalCloudApi.sync(terminalAPIRequest); +``` + +### Optional: perform an abort request + +To perform an [abort request](https://docs.adyen.com/point-of-sale/basic-tapi-integration/cancel-a-transaction/) you can use the following example: +``` java +TerminalAPIRequest terminalAPIRequest = new TerminalAPIRequest(); +SaleToPOIRequest saleToPOIRequest = new SaleToPOIRequest(); + +MessageHeader messageHeader = new MessageHeader(); +messageHeader.setMessageClass(MessageClassType.SERVICE); +messageHeader.setMessageCategory(MessageCategoryType.ABORT); +messageHeader.setMessageType(MessageType.REQUEST); +messageHeader.setProtocolVersion("3.0"); +messageHeader.setServiceID("Different service ID"); +messageHeader.setSaleID(saleID); +messageHeader.setPOIID(POIID); + +AbortRequest abortRequest = new AbortRequest(); +abortRequest.setAbortReason("MerchantAbort"); +MessageReference messageReference = new MessageReference(); +messageReference.setMessageCategory(MessageCategoryType.PAYMENT); +messageReference.setSaleID(saleID); +messageReference.setPOIID(POIID); +// Service ID of the payment you're aborting +messageReference.setServiceID(serviceID); +abortRequest.setMessageReference(messageReference); + +saleToPOIRequest.setAbortRequest(abortRequest); +saleToPOIRequest.setMessageHeader(messageHeader); + +terminalAPIRequest.setSaleToPOIRequest(saleToPOIRequest); + +TerminalAPIResponse terminalAPIResponse = terminalCloudApi.sync(terminalAPIRequest); +``` + +### Optional: perform a status request + +To perform a [status request](https://docs.adyen.com/point-of-sale/basic-tapi-integration/verify-transaction-status/) you can use the following example: +```java +TerminalAPIRequest terminalAPIRequest = new TerminalAPIRequest(); +SaleToPOIRequest saleToPOIRequest = new SaleToPOIRequest(); + +MessageHeader messageHeader = new MessageHeader(); +messageHeader.setMessageClass(MessageClassType.SERVICE); +messageHeader.setMessageCategory(MessageCategoryType.TRANSACTION_STATUS); +messageHeader.setMessageType(MessageType.REQUEST); +messageHeader.setProtocolVersion("3.0"); +messageHeader.setServiceID("Different service ID"); +messageHeader.setSaleID(saleID); +messageHeader.setPOIID(POIID); + +TransactionStatusRequest transactionStatusRequest = new TransactionStatusRequest(); +transactionStatusRequest.setReceiptReprintFlag(true); +transactionStatusRequest.getDocumentQualifier().add(DocumentQualifierType.CASHIER_RECEIPT); +transactionStatusRequest.getDocumentQualifier().add(DocumentQualifierType.CUSTOMER_RECEIPT); +MessageReference messageReference = new MessageReference(); +messageReference.setMessageCategory(MessageCategoryType.PAYMENT); +messageReference.setSaleID(saleID); +// serviceID of the transaction you want the status update from +messageReference.setServiceID(serviceID); +transactionStatusRequest.setMessageReference(messageReference); + +saleToPOIRequest.setTransactionStatusRequest(transactionStatusRequest); +saleToPOIRequest.setMessageHeader(messageHeader); + +terminalAPIRequest.setSaleToPOIRequest(saleToPOIRequest); + +TerminalAPIResponse terminalAPIResponse = terminalCloudApi.sync(terminalAPIRequest); +``` + +## Using the Local Terminal API Integration +The request and response payloads are identical to the Cloud Terminal API, however, additional encryption details are required to perform the requests. +```java +// Step 1: Import the required classes +import com.adyen.service.TerminalLocalAPI; +import com.adyen.model.nexo.*; +import com.adyen.model.terminal.*; + +// Step 2: Add your Certificate Path and Local Endpoint to the config path. Install the certificate from [here](https://docs.adyen.com/point-of-sale/choose-your-architecture/local#protect-communications). +Client client = new Client(); +client.getConfig().setTerminalApiLocalEndpoint("The IP of your terminal (eg https://192.168.47.169)"); +client.getConfig().setEnvironment(Environment.TEST); +client.getConfig().setTerminalCertificate("YOUR_CERTIFICATE_PATH"); + +// Step 3: Setup a security password for you terminal in CA, and import the security key object: +SecurityKey securityKey = new SecurityKey(); +securityKey.setKeyVersion(1); +securityKey.setAdyenCryptoVersion(1); +securityKey.setKeyIdentifier("keyIdentifier"); +securityKey.setPassphrase("passphrase"); + +// Step 4 Initialize the API object +TerminalLocalAPI terminalLocalAPI = new TerminalLocalAPI(client, securityKey); + +// Step 5: Create the request object +TerminalAPIRequest terminalAPIRequest = ///....same as the one used for Cloud API ; + +// Step 6: Make the request +TerminalAPIResponse terminalAPIResponse = terminalLocalApi.request(terminalAPIRequest); +``` + +## Using the Local Terminal API Integration without Encryption (Only on TEST) +If you wish to develop the Local Terminal API integration parallel to your encryption implementation, you can opt for the unencrypted version. Be sure to remove any encryption details from the CA terminal config page. +```java +// Step 1: Import the required classes +import com.adyen.service.TerminalLocalAPIUnencrypted; +import com.adyen.model.nexo.*; +import com.adyen.model.terminal.*; + +// Step 2: Add your Certificate Path and Local Endpoint to the config path. +Client client = new Client(); +client.getConfig().setTerminalApiLocalEndpoint("The IP of your terminal (eg https://192.168.47.169)"); +client.getConfig().setEnvironment(Environment.TEST); +client.getConfig().setTerminalCertificate("YOUR_CERTIFICATE_PATH"); + +// Step 3 Initialize the client and the API objects; +TerminalLocalAPIUnencrypted terminalLocalAPIUnencrypted = new TerminalLocalAPIUnencrypted(client); + +// Step 4: Create the request object +TerminalAPIRequest terminalAPIPaymentRequest = ///....same as the one used in the other examples; + +// Step 5: Make the request +TerminalAPIResponse terminalAPIResponse = terminalLocalAPIUnencrypted.request(terminalAPIPaymentRequest); +``` + + ### Example integrations For a closer look at how our Java library works, you can clone one of our example integrations: diff --git a/src/main/java/com/adyen/service/TerminalLocalAPI.java b/src/main/java/com/adyen/service/TerminalLocalAPI.java index 243e27e1d..9a1ac6c08 100644 --- a/src/main/java/com/adyen/service/TerminalLocalAPI.java +++ b/src/main/java/com/adyen/service/TerminalLocalAPI.java @@ -20,8 +20,8 @@ */ package com.adyen.service; -import com.adyen.ApiKeyAuthenticatedService; import com.adyen.Client; +import com.adyen.Service; import com.adyen.model.terminal.TerminalAPIRequest; import com.adyen.model.terminal.TerminalAPIResponse; import com.adyen.model.terminal.TerminalAPISecuredRequest; @@ -35,7 +35,7 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -public class TerminalLocalAPI extends ApiKeyAuthenticatedService { +public class TerminalLocalAPI extends Service { private final LocalRequest localRequest; diff --git a/src/main/java/com/adyen/service/TerminalLocalAPIUnencrypted.java b/src/main/java/com/adyen/service/TerminalLocalAPIUnencrypted.java new file mode 100644 index 000000000..ca662000f --- /dev/null +++ b/src/main/java/com/adyen/service/TerminalLocalAPIUnencrypted.java @@ -0,0 +1,50 @@ +package com.adyen.service; + +import com.adyen.Client; +import com.adyen.Service; +import com.adyen.model.terminal.TerminalAPIRequest; +import com.adyen.model.terminal.TerminalAPIResponse; +import com.adyen.service.resource.terminal.local.LocalRequest; +import com.adyen.terminal.serialization.TerminalAPIGsonBuilder; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +/** + * [UNENCRYPTED] Local Terminal Api. + * Use this class (in TEST only) to experiment with the Local Terminal API separately + * from the encryption implementation required for live payments. + *
+ * Be sure to remove the encryption key details on the Customer Area as it will not work with encryption key details set up.
+ */
+public class TerminalLocalAPIUnencrypted extends Service {
+
+ private final LocalRequest localRequest;
+
+ private final Gson terminalApiGson;
+
+ public TerminalLocalAPIUnencrypted(Client client) {
+ super(client);
+ localRequest = new LocalRequest(this);
+ terminalApiGson = TerminalAPIGsonBuilder.create();
+ }
+
+ /**
+ * Local Terminal API call
+ *
+ * @param terminalAPIRequest TerminalAPIRequest
+ * @return TerminalAPIResponse
+ * @throws Exception exception
+ */
+ public TerminalAPIResponse request(TerminalAPIRequest terminalAPIRequest) throws Exception {
+ String jsonRequest = terminalApiGson.toJson(terminalAPIRequest);
+
+ String jsonResponse = localRequest.request(jsonRequest);
+
+ if (jsonResponse == null || jsonResponse.isEmpty() || "ok".equals(jsonResponse)) {
+ return null;
+ }
+
+ return terminalApiGson.fromJson(jsonResponse, new TypeToken