This chapter covers EFTLink Integration with Pay by Link Payment Systems. It should be read in conjunction with the Oracle Retail EFTLink Framework Installation and Configuration Guide.

EFTLink General

This document assumes static EFTLink configuration. When deploying with a POS that supports dynamic configuration, all property settings referred to below should be set on the POS, and not directly into local property files.

Minimum Version

The Pay by Link interface requires a minimum EFTLink version of 21.0.0 and a minimum version of Java11.

System Architecture

EFTLink utilizes the Pay by Link core in order to connect to either Adyen’s Checkout Service (using the Adyen Checkout API) for Customer Not Present transactions or Adyen’s Terminal for Customer Present transactions (using the Adyen Terminal API). Both connections are established using HTTPS / TLS from EFTLink to Endpoint.

Fileset

The following files are used in the EFTLink folder:

  • cores/paybylink/paybylink.jar

  • paybylink.properties –(optional, if not present defaults apply)

  • Lang<CC>_<Core>.properties – Language translation file, for further information see Language.

Language

The translation files for this core should not require alteration, but if necessary then this can be accomplished by amending the relevant Lang<CC>_<Core>.properties within the base eftlink folder.

The language used will follow the language set in the EFTLink framework; see the Oracle Retail EFTLink Framework Installation and Configuration Guide, EFTLink General Information, Translation section.

EftlinkConfig.properties

DisplayLanguage = EN

Supported country codes are CN, DE, EN, ES, FR, IT, JP, NL, PT, RU and SV.

Core Classname

The Pay by Link core is not a standalone primary core. This core should be configured in a multi-core environment. The following example needs to be set manually in the EftlinkConfig.properties file. In this example there are two cores. The primary one is the OPI Retail core and the secondary core is the Pay by Link core. The PayByLinkCore setting corresponds to the EPSCore for which you would like to use Pay by Link:

NumEPSCores = 2

EPSCore0 = oracle.eftlink.opiretail.OPIRetailCore

EPSCore1 = oracle.eftlink.paybylink.PayByLinkCore

PayByLinkCore = 1

Keystore

The encryption key must be generated and stored in a keystore. To achieve this, the following steps must be followed:

Open a terminal window and change directory to where the script file resides.

For Windows: Type encrypt-paybylink.bat –k [<keystore name> <properties file>].

For example, encrypt-paybylink.bat –k

For Linux: Type encrypt-paybylink.sh –k [<keystore name> <properties file>].

For Example, ./sudo encrypt-paybylink.sh –k

Keystore file will be generated and stored in the data directory. If the keystore name and the properties file names are not specified, then the default values (paybylink.keystore, paybylink.properties) will be used.

Encryption

The following settings within the paybylink.properties file needs to be encrypted.

  • adyen.paybylink.apikey

If using a terminal (customer present functionality), the following properties also need to be encrypted:

  • adyen.paybylink.cp.key.identifier

  • adyen.paybylink.cp.key.passphrase

  • adyen.paybylink.cp.key.version

To achieve this, the following steps must be followed:

To encrypt a value: Open a terminal window and change directory to where the script file resides.

For Windows: Type encrypt-paybylink.bat –e <keystore name> <properties file> <value>.

For example, encrypt-paybylink.bat –e

*For Linux: Type encrypt—paybylink.sh –e [<keystore name> <properties file> <value>].

For example, sudo ./ encrypt-paybylink.sh –e

The user will be presented with prompts to provide the value(s) which are to be encrypted. Once entered the corresponding properties keys will be automatically updated with the encrypted values.

Note:

If the keystore name, properties file and unencrypted text is included as arguments then the encrypted value and initialization vector will be outputted to the console which must be copied and pasted to relevant property key in paybylink.properties. This process then needs to be repeated for every value that is required to be encrypted.

To re-encrypt; Open a terminal window and change directory to where the script file resides.

For Windows: Type encrypt-paybylink.bat –r [<keystore name> <properties file> <keygen type> <cipher type> <key size> <iterations>].

For example, encrypt-paybylink.bat –r

*For Linux: Type encrypt-paybylink.sh –r [<keystore name> <properties file> <keygen type> <cipher type> <key size> <iterations>].

For example, sudo ./ encrypt-paybylink.sh -r

The key values to be re-encrypted will be taken from the properties file, re-encrypted and the properties file will be automatically updated.

* You may be required to give script file(s) execution rights for example, chmod +x <PathToFile>

Note:

When using AES algorithm with a keysize that is greater than 128, you may get java.security.InvalidKeyException: Illegal key size or default parameters. If so, Additional Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files will need to be downloaded and extracted to %JAVA_HOME%/jre/lib/security/.

Configuration Settings

The full set of configuration properties is defined and commented in poslynx.properties.

Key Settings

Settings that may be different for each POS.

Table 6-1 Pay by Link- Key Settings

Setting Description Default Example

keystore

Specifies the paybylink keystore name.

Mandatory setting.

paybylink.keystore

keystore = default.keystore

http.connect.timeout.seconds

Specifies how long to wait to establish a connection before timing out; in seconds.

30

http.connect.timeout.seconds = 180

adyen.merchant.account

Specifies the Adyen merchant account to associate transactions with.

Mandatory setting.

N/A

adyen.merchant.account = Oracle

adyen.paybylink.apikey

Specifies the (Encrypted) Adyen API Key to use to perform transactions.

Mandatory setting.

N/A

adyen.paybylink.apikey.iv

Specifies the (Encrypted) Adyen API Key’s initialization vector.

Mandatory setting.

N/A

adyen.paybylink.cnp.endpoint

Specifies the endpoint for customer not present transactions/communications.

Mandatory setting.

https://checkout-test.adyen.com/v67

https://checkout-test.adyen.com/v66

abort.timeout.seconds

Specifies how long to attempt to wait for a cancellable transaction to be available to be cancelled otherwise the AbortRequest will be ignored; in seconds.

30

abort.timeout.seconds = 180

Secondary Settings

These settings are normally correct at their default values but can be overridden if necessary.

Table 6-2 Pay By Link - Secondary Settings

Setting Description Default Example

maintenance.menu.timeout.seconds

Specifies the admin menu timeout; in seconds.

6000

maintenance.menu.timeout.seconds = 10000

adyen.paybylink.cnp.response.timeout.seconds

Specifies how long to wait for a response from the customer not present endpoint; in seconds.

600

adyen.paybylink.cnp.response.timeout.seconds = 500

adyen.paybylink.cnp.default.country.code

Specifies the default country code to use in customer not present transactions when the country code has not been specified in the original request. This is in ISO 3166-1 alpha-2 format.

N/A

adyen.paybylink.cnp.default.country.code = GB

adyen.paybylink.cnp.default.shopper.locale

Specifies the default shopper locale to use in customer not present transactions when the shopper locale has not been specified in the original request.

N/A

adyen.paybylink.cnp.default.shopper.locale = en-GB

adyen.paybylink.cnp.default.link.expiry.hours

Specifies the default link expiry of links created for customer not present transactions; in hours.

24

adyen.paybylink.cnp.default.expiry.hours = 72

adyen.paybylink.cp.endpoint

Specifies the endpoint for customer present transactions/communications.

N/A

adyen.paybylink.cp.endpoint = https://m400-123456789.test.terminal.adyen.com:8443/nexo

adyen.paybylink.cp.response.timeout.seconds

Specifies how long to wait for a response from the customer present endpoint; in seconds.

300

adyen.paybylink.cp.response.timeout.seconds = 600

adyen.paybylink.cp.sale.id

Specifies the sale id to send in customer present transactions. This is typically your unique cash register identifier.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.sale.id = TestPOS

adyen.paybylink.cp.POI.id

Specifies the poi id to send in customer present transactions. This is your unique identifier of the terminal, in the format [device model]-[serial number].

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.POI.id = M400-123456789

adyen.paybylink.cp.protocol.version

Specifies the version of Adyen’s Terminal API to send in customer present transactions.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

3.0

adyen.paybylink.cp.protocol.version = 3.0

adyen.paybylink.cp.adyen.crypto.version

Specifies the Adyen crypto version to send in customer present transactions.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.adyen.crypto.version = 1

adyen.paybylink.cp.key.identifier

Specifies the (Encrypted) Adyen Key Identifier to use to perform customer present transactions.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.key.identifier = 3212f4323c917fbdf52c5a2436ed3c16

adyen.paybylink.cp.key.identifier.iv

Specifies the (Encrypted) Adyen Key Identifier’s initialization vector.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.key.identifier.iv = a62a76826f81dcaf3d9a55c534ea94ef

adyen.paybylink.cp.key.passphrase

Specifies the (Encrypted) Adyen Key Passphrase to use to perform customer present transactions.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.key.passphrase = be9ff6c0cf49e436db59e7b395ae9862

adyen.paybylink.cp.key.passphrase.iv

Specifies the (Encrypted) Adyen Key Passphrase’s initialization vector.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.key.passphrase.iv = 273f3ee5fecc001dfe52ea69e0d19b2f

adyen.paybylink.cp.key.version

Specifies the (Encrypted) Adyen Key Version to use to perform customer present transactions.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.key.version = d9d8a033dd2ab3495953fff3d599a073

adyen.paybylink.cp.key.version.iv

Specifies the (Encrypted) Adyen Key Version’s initialization vector.

Mandatory setting if adyen.paybylink.cp.endpoint has been set.

N/A

adyen.paybylink.cp.key.version.iv = 9cc3564f43bcfa0ae4d9c456f66b217a

crypto.keygenType

Specifies the keygen type to use for the internal encryption processing.

AES

crypto.keygenType = AES

crypto.cipherType

Specifies the cipher type to use for the internal encryption processing.

AES/GCM/PKCS5Padding

crypto.cipherType = AES/GCM/PKCS5Padding

crypto.keySize

Specifies the key size to use for the internal encryption processing.

128

crypto.keySize = 256

crypto.iterations

Specifies the number of iterations to use for the internal encryption processing.

100000

crypto.iterations = 100000

crypto.factoryinstance

Sets crypto factory instance for keystore password encryption.

PBKDF2WithHmacSHA512

crypto.factoryinstance = PBKDF2WithHmacSHA512

crypto.secretkeyspec

Sets crypto secret key spec for keystore password encryption.

AES

crypto.secretkeyspec = AES

crypto.keystoretype

Sets keystore type

JKS

crypto.keystoretype = JKS

crypto.digest

Sets digest for keystore password.

SHA-512

crypto.digest = SHA-512

crypto.hashbyteSize

Sets hash byte size for keystore password.

384

crypto.hashbyteSize = 384

merchant.reference

Specifies the unique merchant reference.

N/A

merchant.reference = Merchant A

Merchant.reference.format

Specify the format of the merchant reference - replaces static value with a dynamically generated value using several substitutions.

See Merchant Reference Formats.

R (use existing static merchant ref)

merchant.reference.format=R-dddddddddd-SSSSSS.WWWWWW.YYYYMMDD.hhmmss.TTTTTT.qq

merchant.reference.special.characters

Specifies a character that is to be passed through 'as is' in addition to the ones already mentioned.

N/A

merchant.reference.special.characters = K

Merchant Reference Formats

For the merchant reference format, the following substitutions are available:

Table 6-3 Merchant Reference Formats

Component Description Example Format

R

Use existing Merchant Reference

R

S

StoreID

SSSSSS

min 3, max 10 chars, left 0 filled

W

WorkStation id

WWWWWW

min 3, max 20 chars, left 0 filled

YY

Year

YY or YYYY

extracted from POSTimeStamp

MM

Month

MM

extracted from POSTimeStamp

DD

Day

DD

extracted from POSTimeStamp

hh

Hour

hh

extracted from POSTimeStamp

mm

Minute

mm

extracted from POSTimeStamp

ss

Second

ss

extracted from POSTimeStamp

T

Transaction number

TTTTTT

min 3, max 20 chars, left 0 filled

d

Transaction date

dddddddddd

must be 10 chars

The following special characters are also allowed:

  • minus -
  • underscore _
  • period .

Example format:

R-dddddddddd-SSSSSS_WWWWWW.YYYYMMDD.hhmmss.TTTTTT.qq

Supported Functions

Below is a list of supported functionalities of the interface to Pay by Link.

Table 6-4 Pay By Link - Supported Functions

Function Description

Customer not present - Payment/Payment with Loyalty

The POS initiates a customer not present pay by link tender. EFTLink sends the request to the Adyen Online Payments (Checkout API) endpoint. The Adyen Online Payments endpoint will create a payment link which EFTLink will send back to the POS. The customer will be referred to pay via the link generated by the Adyen Online Payments system.

In the event of a communication failure between EFTLink and the Adyen Online Payments endpoint; the POS operator will be prompted by EFTLink as to whether they would like to Retry or Decline the transaction. Due to API Idempotency, if the operator chooses to Retry the transaction, an exact duplicate of the previous request is sent once again to the Adyen Online Payments endpoint. Should the connection timeout continue to occur, the POS operator will be continually asked whether they would like to Retry or Decline until they press the Decline button. If the operator presses the Decline button, EFTLink will simply return a failure result to the POS and the POS will return back to the tender screen.

Customer present – Payment/Payment with Loyalty

The POS initiates a customer present pay by link tender. EFTLink sends the request to the Adyen In-Store (Terminal API) Payment Entry Device (PED). The PED will display a QR code which the customer will scan and enter their card details on the secure form generated by the Adyen payment gateway. Once the customer has completed the form and the payment has been processed, EFTLink will return a response including formatted merchant/customer receipts as required.

In the event of a communication failure between EFTLink and the PED an initial Transaction Status request is sent from EFTLink to determine the status of the request.

  1. If the initial Transaction Status check succeeds, the original response details will be sent from EFTLink to the POS.

  2. If the initial Transaction Status check returns as in-progress, EFTLink will continue to query the status of the transaction until a valid response is returned. Once the final response has returned, EFTLink will send the original response details back to the POS.

  3. If the initial Transaction Status check times out, the POS operator will be prompted by EFTLink as to whether they would like to Retry or Decline the transaction. If the operator chooses to Retry the transaction, EFTLink will attempt to re-send the previous Transaction Status check until a valid response is returned or until the cashier presses the Decline button when prompted after every check. If an in-progress response is returned, the in-progress scenario outlined above occurs. If a valid final response is returned, EFTLink will send the final response back to the POS and complete the transaction as usual.

Customer not present – Link Query

The POS initiates a customer not present link query request with the link Id to check the status of a link. EFTLink sends the link query request to the Adyen Online Payments (Checkout API) endpoint. The Adyen Online Payments endpoint will respond with the status of the link. EFTLink will set the status of the link in the final response to the POS. The status of the link will be one of the following:

  • active

  • expired

  • completed

  • paid

Customer not present – Link Expiry

The POS initiates a customer not present link expiry request with the link Id to expire. EFTLink sends the link expiry request to the Adyen Online Payments (Checkout API) endpoint. The Adyen Online Payments endpoint will set the status of the link to expired in the response to EFTLink. EFTLink will send the final response to the POS with the new status set.

Reversal

Customer not present reversal is possible if the POS initiates a Post Void request to EFTLink following a customer not present pay by link tender. This will simply expire the link which was generated during the initial customer not present pay by link tender.

Customer present reversals behave in the same way as a reversal for any standard transaction. EFTLink converts the reversal request into a Verified Refund request using the original transaction reference and sends this request to the Adyen In-Store (Terminal API) endpoint.

Verified Refund

All verified refund requests are handled by the Adyen Online Payments (Checkout API) endpoint.

The POS initiates a Verified Refund request. EFTLink sends the refund request to the Adyen Online Payments endpoint. The Adyen Online Payments endpoint responds with a valid response. EFTLink sends the final response to the POS.

Time out handling

All transactions processed by the Pay by Link core are available for the timeout scenarios described under the “Customer not present - Payment/Payment with Loyalty” and “Customer present – Payment/Payment with Loyalty” sections of this “Pay by Link – Supported Functions” table, refer to these sections for further information.