The Worldline Payment Interface (WPI) is an Android intent-based interface that enables easy and fast integration with payment apps. It is designed to allow additional business applications to execute payments on any Worldline offered SmartPOS device. A SmartPOS device is a payment device that runs Android And also smartphones using Tap On Mobile..

All Worldline Payment Solutions support WPI, which means that business applications that use this interface can run everywhere without any change of code. This makes it easy for developers to build payment apps that are compatible with a wide range of payment devices and payment protocols.

The WPI interface is built on top of the Android Intent mechanism, which allows different parts of an app to communicate with each other in a structured way. By using intents to trigger payment-related actions, the WPI interface simplifies the payment integration process and makes it easier for developers to build business applications on top of Payment Solutions.

What You'll Learn

Get the code

Click the following link to download all the code for this codelab:

Download Zip

Check out the sample app

For this codelab we will use Android studio Giraffe, SDK 33 and Gradle 7.5

The code you just downloaded contains code for all codelabs available. To complete this codelab, open the samplecode project inside Android Studio.

The codelabs repo contains starter code for all codelabs in the pathway. For this codelab, use the wpiCodelab project.

The project is built with two app folders:

We recommend that you start with the code in the start folder and follow the codelab step-by-step at your own pace.

During the codelab, you'll be presented with snippets of code that you'll need to add to the project. In some places, you'll also need to remove code that is explicitly mentioned in comments on the code snippets.

Getting familiar with the code and running the sample app

Take a moment to explore the project structure and run the app.

Project structure

When you run the app from the ‘start' folder , you'll see that this is a very simple application with only a text field to enter an amount and a button to proceed to the payment.

Project structure

For this codelab we will see how to implement a payment but the WPI provides a set of intents that developers can use to build apps that work with the interface. The following table lists each intent, along with its purpose:

Type

Intent

Purpose

Financial

com.worldline.payment.action.PROCESS_TRANSACTION

Process a financial transaction

Management

com.worldline.payment.action.PROCESS_MANAGEMENT

Trigger payment solution managed actions

Extras

An extra in Android intents is a way to pass additional data or parameters to another component in order to provide more context or information for the requested action. In WPI we have extras for request and response. The request extras needs to be provided by the Business Application that is using the interface and the response extra is provided by the Payment Solution.

Request:

Extra

Description

Type

Condition

WPI_SERVICE_TYPE

Specify the subtype of action to be executed

String

Mandatory

WPI_REQUEST

The request contains JSON structured data mandatory for given service type, in some specific cases this field is not given or empty

String

Mandatory for Financial, Optional for Management

WPI_VERSION

Used WPI version

float

Mandatory

Response:

Extra

Description

Type

Purpose

WPI_RESPONSE

The response contains JSON structured data processed for the requested service type

String

Mandatory

Service type

Purpose

WPI_SVC_PAYMENT

Used to perform a simple sale transaction also known as purchase

WPI_SVC_CANCEL_PAYMENT

Used to reverse a previous transaction

WPI_SVC_REFUND

Used to refund a previous transaction

WPI_SVC_PRE_AUTHORIZATION

Used to perform a reservation

WPI_SVC_CANCEL_PRE_AUTHORIZATION

Used to cancel a previous reservation

WPI_SVC_UPDATE_PRE_AUTHORIZATION

Used to increment a previous reservation

WPI_SVC_CANCEL_UPDATE_PRE_AUTHORIZATION

Used to cancel the previous incrementation of a reservation

WPI_SVC_PAYMENT_COMPLETION

Used to purchase a reservation / incremented reservation

WPI_SVC_CANCEL_PAYMENT_COMPLETION

Used to cancel the purchased reservation

WPI_SVC_DEFERRED_PAYMENT_AUTHORIZATION

Used to execute a deferred payment authorization (energy solution use-case)

WPI_SVC_DEFERRED_PAYMENT_COMPLETION

Used to execute a deferred payment completion of a previous authorization(energy solution use-case)

WPI_SVC_PAYMENT_WITH_PRODUCT_DELIVERY

Used to execute a transaction with product delivery (vending use-case)

WPI_SVC_PRODUCT_DELIVERY

Used to inform the payment solution that the product was delivered (vending use-case)

WPI_SVC_PAYMENT_INSTRUMENT_RECOGNITION

Used to do a payment card of non payment card recognition request without performing a real transaction (token)

Service type

Purpose

WPI_SVC_PAYMENT_MENU

Used to open the payment solution menu

WPI_SVC_DAY_END

Used to upload the transactions (online and offline) to perform the final settlement.

WPI_SVC_PAYMENT_PARAMETERIZATION

Used to fetch the latest payment solution configuration from the payment solution related configuration system.

WPI_SVC_ACQUIRER_PARAMETERIZATION

Used to fetch the latest acquirer parameters from the acquirer

WPI_SVC_REPEAT_RECEIPT

Used to repeat the receipt printing

WPI_SVC_ABORT

Used to abort an ongoing transaction

WPI_SVC_LAST_TRANSACTION

Used to return the last transaction result

WPI_SVC_PAYMENT_INFORMATION

Used to retrieve the payment solution information especially which service types are supported.

Data Dictionary

Request Data:

Field Name

Description

Type

currency

Currency of the amount. Alpha code value defined in ISO 4217 (e.g. EUR)

String

requestedAmount

Total payment amount as minor unit. The fractional digits are evaluated based in the currency. For example, 11.91€ must be sent as 1191 and the currency as EUR

Integer

cashbackAmount

paymentSolutionReference

A previous transaction reference used for subsequent transactions like a Reversal. This value is defined by the payment application and contains all necessary data to perform subsequent transactions. This value can differ based on the payment application and can only be used on the same device.

String

reference

Reference to be send to the payment solution for reconciliation

String

productRecords

Product catalogue for energy solution based use-cases. This records needs the format that the issuer can understand. Most often used for petrol use-cases.

Array

receiptFormat

To override the default receipt format

Array

recognitionTimeout

Defines the timeout before an error will be returned in milliseconds

Integer

recognitionOptions

Card recognition options

Array

Response Data:

Field Name

Description

Type

result

Result of the transaction (success or failure)

String

errorCondition

Specific error reason (see table below)

String

actionCode

Specific action to be performed by the business application

String

remark

Terminal / transaction specific message for detailed error descriptions. Text provided by payment app in English

String

timestamp

Date and time of the transaction, indicated by the acquirer.
Format according to ISO 8601(extended format) => yyyy-mm-hhThh:mm:ss±hh:mm

String

currency

Currency code of the transaction. Alpha code value defined in ISO 4217 e.g. EUR

String

authorizedAmount

Amount of the transaction. The fraction is taken from the currency code. Example:
Currency = EUR
requestedAmount = 3190
=> 31,90 €

Integer

brandName

Brand name of used payment card, like MasterCard, VISA, AMEX and so on.

String

customerLanguage

Language used on all screens towards the cardholder and when formatting the receipt. Language code will be returned for english > en
Format according to ISO 630-1 (alpha-2 code)

String

applicationIdentifier

Payment card application identifier dependent on the used card e.g. for MasterCard A00000041010

String

applicationLabel

Payment card application label, depending on the used card e.g. MasterCard DEBIT

String

formattedReceipt

Merchant and cardholder receipt are contained in this field. Both receipts are available as text preformatted. Check the subsequent chapter below for an example. The receipt wide is defined by the payment application (often 32 characters) and depends on the printer capabilities or configuration.
The receipt language is the same as it is for the payment app.

Object

paymentSolutionReference

Transaction specific and unique identification. This value is defined by the payment application and contains all necessary data to perform subsequent transactions. This value can differ based on the payment application and can only be used on the same device.

String

dccUsed

Whether DCC was used or not for the transaction. This field is present as soon as DCC is activated for this payment solution.

Boolean

tipAmount

The tip amount that was entered by the cardholder during the transaction with the payment solution. This field is present as soon as TIP is activated for this payment solution.

Integer

reference

Reference to be send to the payment app for reconciliation. The reference will be the same value as in the response.

String

softwareVersion

Payment Solution software version

String

terminalIdentifier

The terminal identifier configured for the payment solution

String

supportedLanguages

List of language that are supported
Format according to ISO 630-1 (alpha-2 code)

String

cardholderDefaultLanguage

The configured cardholder default language
Format according to ISO 630-1 (alpha-2 code)

String

merchantLanguage

The configured merchant default language
Format according to ISO 630-1 (alpha-2 code)

String

countryCode

The country code of the terminal ISO 3166-1 (alpha-2 code)

String

defaultCurrency

The default currency that is configured for the payment solution.
Alpha code value defined in ISO 4217 e.g. EUR

String

supportedCurrency

All currencies that are supported by the payment solution.
Alpha code value defined in ISO 4217 e.g. EUR

String

shopInfo

The shop information of the terminal. Usually these are the first three lines of each receipt.
Shop Name
Street + No
Location
The information are provided as array. First item shop name, second one address and third one location.

Array

acquirerProtocol

The used acquirer protocol by the payment solution, usually this is the official acronym like CTAP.

String

supportedTicketFormats

The supported ticket formats by the payment solution

String

paymentInformation

Detailed payment solution information per brand & acquirer

Array

paymentSolutionSupportedServiceTypes

Payment Solution supported service types. This includes all service types of WPI.

Array

entryMode

The technology that was used to read the card

String

isoTrack1

ISO track 1 data

String

isoTrack2

ISO track 2 data (due to PCI regulatory payment card PAN data are always masked)

String

isoTrack3

ISO track 3 data

String

token

The token of the card PAN / UID (in case of NFC non payment related card) that was read. The token should be an unique value, generated by the payment solution and can be reproduced on the same device. This token is used to identify the customer.

String

pan

PAN of the card (due to PCI regulatory payment card PAN data are always masked)

String

mediaType

Media type of NFC non payment card. e.g. MIFARE Ultralight

String

mediaUniqueIdentifier

UID of NFC based non payment card

String

waitForNextAction

Whether the payment solution keeps the card in read mode for a subsequent transaction or not

Boolean

nextActionWaitTime

The time how long the card is kept in read mode, in milliseconds

Integer

Creation of the request

Create a new data class SaleTransactionRequest in the package com.worldline.wpi_codelab.model.request. This class takes 2 parameters: the currency and the amount.

@Serializable
public data class SaleTransactionRequest(
    val currency: String,
    val requestedAmount: Long,
)

To use the Serialization you need to add the following code in your gradle.app:

plugins {
    id 'kotlinx-serialization'
}

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0'
}

To finish sync your project with Gradle files.

Creation of the response

Create a second data class SaleTransactionResponse in the package com.worldline.wpi_codelab.model.response. This class takes 3 parameters: the result the currency and the amount.

@Serializable
public data class SaleTransactionResponse(
    val result: String?,
    val authorizedAmount: Long? = null,
    val currency: String? = null,
)

We can now create the SaleActivity in the package com.worldline.wpi_codelab, this activity will execute the transaction and handle the response. To do so we will use a registerForActivityResult.

To have more information about how to get a result from an activity you can click here.

executeSaleTransaction

The SaleActivity first method will be executeSaleTransaction and it will execute the registerForActivityResult:

private fun executeSaleTransaction(amount: Long) {
    val saleTransaction = SaleTransactionRequest("eur", amount)
    val saleTransactionJson: String = Json.encodeToString(saleTransaction)

    val intent = Intent("com.worldline.payment.action.PROCESS_TRANSACTION")
    // These extras are mandatory whether the intent comes from the payment
    // application or a 3rd party application.
    intent.putExtra("WPI_SERVICE_TYPE", "WPI_SVC_PAYMENT")
    intent.putExtra("WPI_REQUEST", saleTransactionJson)
    intent.putExtra("WPI_VERSION", 1)

    launcher.launch(intent)
}

handleTransactionResponse

The SaleActivity second method will be handleTransactionResponse:

//allows ignoring fields we don't need in the response
private val json = Json { ignoreUnknownKeys = true }

private fun handleTransactionResponse(intent: Intent) {
    val rawJsonResponse = intent.getStringExtra("WPI_RESPONSE")
    if (rawJsonResponse != null) {
        Log.d("Transaction response", rawJsonResponse)
        val transactionResponse = json.decodeFromString<SaleTransactionResponse>(rawJsonResponse)
        val paymentMessage = "${transactionResponse.result}: ${(transactionResponse.authorizedAmount?.toDouble()?.div(100))} ${transactionResponse.currency}"
        Toast.makeText(this, paymentMessage, Toast.LENGTH_SHORT).show()
    }
    // Handle response
}

launcher

To finish this step, just add to your main activity the laucher that will handle the result of the activity when you perform a payment:

private val launcher = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { result ->
    result.data?.let { handleTransactionResponse(it) }
}

Now that everything is set up, we will make the payment start by pressing the button.

As the amount formating is not the subjectof this codelab, we use a simple solution with radio buttons and pre-defined amount.

To finish on this codelab, just add the executeSaleTransaction function in the button listener:

if(radioOne.isChecked){
    executeSaleTransaction(1999)
}
if(radioTwo.isChecked){
    executeSaleTransaction(12000)
}
if(radioThree.isChecked){
    executeSaleTransaction(5000)
}

Here we check which radio is checked and we lauch executeSaleTransaction with the selected amount.

You can now run the app on a terminal and proceed to your first payment.

Congratulations, you've successfully completed this codelab and learned how to proceed to a payment with the WPI!

You learned about how to create a request, a response, and how to use the Worldline Payment Interface.

What's next? Check out the others possible transactions in the documentation and try to handle them.