Skip to content

Latest commit

 

History

History
245 lines (202 loc) · 10.9 KB

File metadata and controls

245 lines (202 loc) · 10.9 KB

Using the Terminal API

For In-Person Payments integrations with the Cloud Terminal API, you must initialise the Client setting the closest Region:

// 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.*;
import java.math.BigDecimal;
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

// Step 2: Initialize the client object
Client client = new Client(new Config().apiKey("test").environment(Environment.TEST));

// for LIVE environment set the region
// Config config = new Config();
// config.setEnvironment(Environment.LIVE);
// config.setTerminalApiRegion(Region.EU);
// Client client = new Client(config);

// 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);
      
// Optional: set SaleToAcquirerData with merchant application info
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");
// RequestedAmount is in major currency units (e.g. 10.00 EUR)
amountsReq.setRequestedAmount(BigDecimal.valueOf(10));
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 you can use the following example:

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 you can use the following example:

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);

Helper classes

Use PredefinedContentHelper to parse Display notification types which you find in PredefinedContent->ReferenceID

PredefinedContentHelper helper = new PredefinedContentHelper(predefinedContent.getReferenceID());

// Safely extract and use the event type with Optional
helper.getEvent().ifPresent(event -> {
        System.out.println("Received event: " + event);
    if (event == PredefinedContentHelper.DisplayNotificationEvent.PIN_ENTERED) {
        // Handle PIN entry event
        System.out.println("The user has entered their PIN.");
    }
});

Using the Local Terminal API Integration

The procedure to send In-Person requests using Terminal API over Local Connection is similar to the Cloud Terminal API one, however, additional encryption details are required to perform the requests. Make sure to install the certificate as described here

Local terminal API Using Keystore

// Import the required classes
import com.adyen.Client;
import com.adyen.Config;
import com.adyen.enums.Environment;
import com.adyen.httpclient.TerminalLocalAPIHostnameVerifier;
import com.adyen.service.TerminalLocalAPI;
import com.adyen.model.terminal.security.*;
import com.adyen.model.terminal.*;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.security.KeyStore;
import java.security.SecureRandom;

// Create a KeyStore for the terminal certificate
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("adyenRootCertificate", adyenRootCertificate);

// Create a TrustManagerFactory that trusts the CAs in our KeyStore
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

// Create an SSLContext with the desired protocol that uses our TrustManagers
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

// Configure a client for TerminalLocalAPI
Config config = new Config();
config.setEnvironment(Environment.TEST);
config.setTerminalApiLocalEndpoint("https://" + terminalIpAddress); // IP address of your terminal
config.setSSLContext(sslContext);
config.setHostnameVerifier(new TerminalLocalAPIHostnameVerifier(Environment.TEST));
Client client = new Client(config);

// Create your SecurityKey object used for encrypting the payload (keyIdentifier/passphrase you set up beforehand in CA)
SecurityKey securityKey = new SecurityKey();
securityKey.setKeyVersion(1);
securityKey.setAdyenCryptoVersion(1);
securityKey.setKeyIdentifier("keyIdentifier");
securityKey.setPassphrase("passphrase");

// Use TerminalLocalAPI
TerminalLocalAPI terminalLocalAPI = new TerminalLocalAPI(client, securityKey);
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. Consider this ONLY for development and testing on localhost.

// Step 1: Import the required classes
import com.adyen.Client;
import com.adyen.Config;
import com.adyen.enums.Environment;
import com.adyen.service.TerminalLocalAPIUnencrypted;
import com.adyen.model.nexo.*;
import com.adyen.model.terminal.*;

// Step 2: Configure the client with the terminal endpoint
Config config = new Config();
config.setEnvironment(Environment.TEST);
config.setTerminalApiLocalEndpoint("https://192.168.47.169"); // IP address of your terminal
Client client = new Client(config);

// Step 3: Initialize the unencrypted local API (handles SSL context internally)
TerminalLocalAPIUnencrypted terminalLocalAPI = new TerminalLocalAPIUnencrypted(client);

// Step 4: Construct a TerminalAPIRequest object
TerminalAPIRequest terminalAPIRequest = new TerminalAPIRequest();
// ... build your SaleToPOIRequest as shown above ...

// Step 5: Make the request
TerminalAPIResponse terminalAPIResponse = terminalLocalAPI.request(terminalAPIRequest);