# Payment SPI Specification
Payment SPI (Service Provider Interface) provides an integration framework for hardware vendors to integrate their card reader modules with Poynt.
Payment SPI implementation has to be provided as an android service connecting variosu components of the card reader - entry point, L1/L2 kernels, secure module for Pin Pad, EMV configuration/parameters, etc. - with the Poynt Payment flows and commerce platform. This enables all Poynt Core Applications including apps built by 3rd party developers and cloud service provides to work seamless with any POS hardware.
Payment SPI interface defines functional APIs that are designed to enable quick and easy integration of underlying Card Reader functionality into Payment experience and Applications built for Android OS. The SPI Implementation must be an Android AIDL service implementing the functionality as defined in the Payment SPI and Payment Security SPI AIDL interfaces, which are defined as part of the Poynt Vendor SDK.
At a high level these functional APIs fall into 3 categories:
- Transactional APIs - to support various aspects of processing card based transactions
- Security APIs - to support loading encryption/MAC keys into the pin pad and encryption/decryption of sensitive data
- Direct Card APIs - to support interactions with non-payment card using generic APDUs
Once implemented, the SPI Service will be used by Poynt Payment Application (Payment Fragment) to process card transactions. Poynt’s Configuration Service, bundled as part of the Poynt system services, provides a repository of EMV Configuration for card reader that the SPI Service would need to use to retrieve the configuration as necessary.
Note: Transactional and Direct Card APIs are defined in the IPoyntPaymentSPI.aidl and must be implemented in the Payment SPI Service. Security APIs are defined in the IPoyntPaymentSecuritySPI.aidl and must be implemented as a different Payment Security SPI Service.
# Transactional APIs
Transactional APIs provide high level functionality to process a card transaction for any interface (CT, CL, MSR). The API model abstracts the card interface and EMV process to provide a generic interface to support any card type.
The APIs consist of a sequence of calls and callback functions to process a complete card based transaction.
API Method | Description |
---|---|
startTransaction() | Starts a new Transaction - input contains various parameters like amount, currency, card interfaces, etc., - card reader must begin polling for the provided interfaces (CT/CL/MSR) and initiate the transaction based on the card entry. If an MSR swipe was detected, it should process as a MSR transaction and return track data as onComplete callback. If an EMV card (CT or CL) is detected, it should start the EMV transaction. The callback functions must be used to give the caller necessary control on various aspects of the card interactions including App Selection, stop after read records, etc. |
cancelTransaction() | Cancels the current card transaction in progress and terminates all the interfaces gracefully. |
continueTransaction() | Continue processing the transaction after App selection or Acquirer selection or checkCard callbacks depending on the card. |
completeTransaction() | Complete the transaction after receiving the Host response. This method is typically called for EMV transactions that require online authorization from Host. |
The Transaction Callback Interface consists of various specific actions that need to be taken care of by the Payment application based on processor requirements, and merchant/customer preferences. These callbacks need to be invoked by the SPI Service to ensure that a transaction is processed successfully. Please refer to the Poynt Vendor SDK for API reference.
Callback | Description |
---|---|
onCardEntryTimeoout() | When no card is detected within the read timeout specified in the startTransaction() request. |
onAppSelectionRequired() | When the presented card has multiple applications and require merchant or customer to select the EMV application to use. |
onAcquirerSelectionRequired() | When the presented card can be processed by more than one configured acquirer. |
onTrackSelectionRequired() | When the presented card has track3 that can be used to process as a different card type than track2. (Eg. bancomat) |
onCheckCard() | Callback right after read records to allow the payment application to present acquirer specific options like DCC (Dynamic Currency Conversion), requested operation allowed for card, etc. |
onOnlineAuthorizationRequired() | When the card requires the transaction to be authorized by the host. Callers must send the appropriate host message to authorize the transaction with the necessary data from the card reader response. |
onComplete() | Callback to indicate the end of a transaction. In case of EMV transactions, the status could indicate whether the transaction is approved or declined or reversal required. |
onError() | Callback to indicate a transaction failure - the returned error contains details about the failure. |
onEvent() | Callback to send various card reader events that could be used to display customer/merchant friendly messages/instructions. Eg. PRESENT_CARD, CARD_FOUND, CARD_REMOVED, PIN_REQUIRED, APPROVED, DECLINED, etc. |
# Card Reader Events
SPI Service must send the following events at various phases of a transaction being processed. These events are used both to control the UX flows and also to display messages to the merchants and the card holder.
Each card reader event consists of:
- Type - type of the event - UI event, Security event, Misc event, etc.
- Name - name of the event - PRESENT_CARD, CARD_FOUND, etc.
- Data - a byte[] containing additional information as applicable for a given event
Please refer to the javadoc for a complete list of events that must be supported by the SPI Service.
# CVM Handling
Card holder verification methods (CVM) like Offline/Online PIN must be handled by the Payment SPI Service using it’s own PIN PAD functionality. Poynt provides necessary android fragments that can be invoked by the SPI Service to display the pin pad UI while secure card reader pin pad still handling the secure touch. Please refer to Poynt Second Screen Service APIs for launching the Poynt Secure PIN fragment.
CVMs that require customers to handle on their mobile phones should be handled by using the events callback to instruct the customer on what they need to do.
For Signature CVM, Poynt Payment flow would take care of collecting the signature at the end of the transaction either on receipt or on screen.
# Card Reader Request & Response
Card Reader Request object is used to pass the necessary parameters to the card reader through Payment SPI methods. It contains the commonly used fields to send the necessary parameters to process a transaction with a card. Card Reader Response object must be used by the SPI Service to communicate the results of the card transaction by setting the available card data as applicable.
Custom/Additional TLVs fields can be used to send and receive any additional fields that are not defined as member variables of the Request and Response classes.
Please refer to the javadoc for complete definition of the Card Reader Request & Response classes.
# Security APIs
Poynt Payment Security SPI interface defines the method that need to be implemented as a Security SPI Service to support the following functionality:
- Poynt Remote Key Injection process, and
- Provide generic encryption service for processor/acquirer host integration.
Hardware vendors must implement the Poynt Payment Security SPI as an Android service (similar to Payment SPI Service). The Payment Security SPI includes the following category of APIs - which could be internally integrated with Card Readers security service.
# Remote Key Injection
Poynt Remote Key Injection is built on PKI - an open industry security standard that has been proven to deliver exchange of sensitive information in a very secure way. Every Poynt enabled POS terminal requires a public/private RSA key pair to securely communicate with Poynt Cloud RKMS and fetch the corresponding terminal encryption keys for a given merchant account. This provides the flexibility of injecting the encryption keys anywhere in the world through a very secure process, while reducing the overhead of both personnel costs and physical location (secure room) associated with direct key injection process at factories and distribution centers.
Poynt Remote Key Injection involves a two step process:
- Step One - Object Sign POS Terminal
- Every terminal must generate an RSA key pair, and the public key is signed by 'Poynt CA' (Certificate Authority) at the manufactoring facility. Poynt provides the necessary cloud services and tools required for this.
- API Methods necessary for this are:
- getDeviceCSR() -- which requires generation of RSA key pair internally and return a certificate signing request (CSR) with device serial as CNAME. This CSR is sent to 'Poynt CA' for signing.
- setDeviceSigningCertificate() -- which loads the signed certificate from 'Poynt CA' into the card reader.
- loadTrustedSourceCertificate() -- which loads the trusted CA chain that is used to validate and verify both Device Signing Certificate and also communication with Poynt Cloud RKMS during Remote Key Load process below.
- Step Two - Remote Key Load
- At the POS activation time - either at distribution partner's warehouse or at the merchant's location, terminal establishes a secure mutual authentication connection with Poynt Cloud RKMS to download the encryption keys that are necessary to process payment transactions.
- API Methods necessary for this are:
- initiateRemoteKeyLoading() -- initiates the RKL process by loading RKMS signing and encryption certificates. Card reader at this point is expected to verify the RKMS certificates using the trusted CA chain that was loaded in step one at manufactury facility.
- generateDeviceKeyRequest() -- which must generate a session encryption key that is used for key exchange, and encrypt with RKMS encryption certificate so it can be sent to RKMS securely.
- loadDeviceKeyResponse() -- which loads terminal encryption keys (a sequence of keys encoded in TR-31 format) from RKMS server, encrypted with the session key generated in the above method.
- generateDeviceKeyValidationRequest() -- which must generate a report of the keys loaded in ASN.1 structure
- validateDeviceKeyValidationResponse() -- which must validate the response from RKMS due a two-way confirmation of the loaded keys before completing the RKL process.
Please refer to Poynt Object Signing and Remote Key load specification for more details about these APIs, and Poynt Payment Security SPI javadoc for complete reference of the methods and classes.
# Direct Card APIs
Direct Card APIs defined in the Payment API Service allow applications to use the card reader to read non-payment card data by sending/receiving APDUs directly via the Payment SPI. Third party application built on Poynt platform use these APIs for various non-payment related functionality - Eg. Transit cards, Hotel Key cards, SIM cards, Meal Voucher cards, etc.
Method | Description |
---|---|
connectToCard() | Initiates the card reader to connect over the specific interface (CT or CL or Both). If a card is found on any of the specified interfaces, the reader establishes an L1 connection to the card. If a card is not found for the specified duration of time, the command returns an appropriate error code. |
disconnectFromCard() | Disconnects from the card (CT or CL or both) and powers off corresponding interface. |
checkIfCardInserted() | Checks whether a card is present in the card reader slot or not. This command does not check whether a connection to the card has been established or not. It only checks if a card is physically inserted in the slot such that the card inserted switch is asserted. It does not apply to contactless interface |
exchangeAPDU() | Send an APDU command to the card and receive the response APDU. |
exchangeAPDUList() | Send a list of APDU commands to the card and receive the response APDU. |
abort() | Abort any pending connect or wait for card removal operations. |
Please refer to the javadoc for full definition of the API methods and the class definitions.
# EMV Configuration
Poynt manages all the EMV Configuration parameters for acquirers/processors in Poynt Cloud and provides a secure way to push the configuration updates to all terminals. On the terminal Poynt Configuration Service (IPoyntConfigurationService) provides the necessary interfaces for the SPI implementers to fetch the EMV parameters dynamically during a transaction or fetch all parameters every time Poynt pushes the configuration updates to the terminal.
Poynt Configuration Service provides the parameters organized in the following structure:
- Terminal Configuration for each card interface (CT, CL, MSR) -- consists of terminal level configuration paramters like track data format, encryption key scheme, terminal type, capabilities, etc.
- EMV AID Configuration for CT and CL interfaces -- consists of AID specific configuration parameters as defined by the corresponding card scheme
- EMV CA Public keys for CT and CL interfaces
- EMV Recovation and Exception lists
When Poynt cloud pushes new updates or loads configuration into a terminal, Poynt Configuration service sends an event broadcast (poynt.intent.action.EMV_CONFIGS_UPDATED), which could be subscribed by the Payment SPI service to fetch and load updated configuration parameters into it's local memory. Payment SPI service could also use the Poynt Configuration Service to only fetch the configuration parameters it needs at run time during a transaction.
All Poynt EMV Configuration tags are defined in Poynt EMV Configuration Specification.
Please refer to IPoyntConfigurationService.aidl for the list of methods available.