What is AppFlow?
AppFlow is a solution designed to facilitate standardised integration between applications in a point of sale environment in order to manage the 'checkout' experience.
This is made possible via two different APIs that allows applications to initiate flows and for other applications to be called at any point in those flows to read and augment relevant data.
The overview goes into more detail how AppFlow works.
Who built AppFlow?
AppFlow was created by AEVI.
AEVI works with merchant acquirers to provide merchants with maximum flexibility with regards to payment devices, value added services and payment solutions.
One of AEVI's solutions offers a Marketplace that allows acquirers and merchants to browse and install third party applications onto their Android payment devices that are managed via AEVI's Device Management System. The apps will have been sourced from third party developers.. As part of the Marketplace solution, AEVI provides tools for app developers to help them develop applications which will work seamlessly across any 'AEVI enabled devices'.
Typically the Android payment devices will have one or more payment applications to facilitate transaction processing. These applications are generally developed by the device manufacturers, AEVI, or by the acquirers themselves.
Below are some terms and acronyms that will be used throughout the documentation.
- POS : Point of Sale
- POS application : The POS/ECR application the merchant interacts with to input purchases, orders, etc
- Flow Service : Any application that integrates with
Payment Flow Service APIand can be called to read and augment flow data
- VAA / Value Added Application - a third party application that provides some function for the merchant and/or customer on a device. When called through AppFlow, this will be a type of flow service.
- Payment App : Processes payments, traditionally via a bank host/gateway - another type of flow service.
The purpose of the AppFlow solution is to provide acquirers and merchants with flexible and powerful options for shaping their point of sale offering. This includes choices of standalone or integrated environments, a choice of numerous value added services that integrate seamlessly into the point of sale experience where a customer can pay via a range of supported payment methods.
AppFlow enables applications (referred to as flow services) to be called at different stages of the point of sale flow. What these stages are and what applications are called is down to the flow applied to that particular request. The flow applied is determined by the type of the request, such as sale or reversal, which is one of the parameters an initiating application will set in the request used to initiate the flow.
Below is a simplified view of this solution.
As you can see from this diagram, the Flow Processing Service (FPS) is the core component that handles all requests and moves them through a flow. FPS is developed and maintained by AEVI; it can be installed onto any Android (API level 21+) device to facilitate AppFlow functionality. Once installed onto a device, developers will be able to use the AppFlow APIs in their applications to interact with it. FPS itself is agnostic of point of sale or payments and can be used for any scenario where a flow of applications is useful.
Most flows will be customised for the particular function they provide. For instance, a
sale flow may be sent through a split stage (to split the bill) but that would not make sense for a
refund flow. The production flows will usually be defined by the bank, acquirer or payment processor distributing AEVI enabled devices.
- Requests from a client app are processed through a flow
- Each flow consists of a number of stages.
- Acquirers, banks and payment processors can define any number of flows. These may be generic, or specific to an acquirer and/or a particular AEVI enabled device.
- Each stage in the flow can optionally execute a number of flow services. These are either statically defined in the flow or dynamically chosen at runtime based on their eligibility for that flow.
- Each flow service will process the data that has been sent to it and pass back a response. The type of data sent between FPS and the flow service for any given stage is determined by the data models for that stage.
There are two main types of AppFlow applications;
- Flow initiators
- Flow services
Flow initiating applications is what the merchant/operator uses to enter details for a particular function. A classic example would be to scan customer goods into a basket in order to take a payment. AppFlow is however not restricted to transaction style flows and allows for any form of function to be initiated, such as updating inventory or registering a customer for loyalty purposes.
These applications are often referred to as a POS or ECR app. They make use of the
Payment Initiation API to query AppFlow for information, and to initiate flows with request data tailored for that flow.
Flow services are applications that adhere to the
Payment Flow Service API and get called in a flow to perform some function, such as loyalty or processing payments.
There is no limit on the number of flow services that can be called for any given flow or stage, but in practise it is rarely more than a few to a handful of applications.
The flow services can be divided into two main groups;
- Payment applications, which processes the actual payments
- Value added applications, such as loyalty or split bill
The payment applications are in this context defined as flow services that execute in the
TRANSACTION_PROCESSING stage. They may optionally also support the
PAYMENT_CARD_READING stage where a card may be presented separately to the processing of the payment, to allow for other flow services to react on the given card data, such as token or scheme. These form of applications are typically developed by or on behalf of the acquirer/bank, but can also be independent payment solutions where a customer pays via cash, vouchers, QR codes, etc.
Value added applications
Value added applications typically offer a function or service that will benefit the merchant and/or customer. For most scenarios, they will augment a flow in some way by applying a discount, adding costs such as tax or fees, or splitting a flow into multiple per-customer flows. Some examples are
- loyalty programs
- charity donations
- split bill
- advertising and promos
- currency conversion
- receipt printing/emailing
The flow stages determine what applications are called and how they are called.
There are three main types of flows that will impact what stages are available;
Paymentflows, which involve the transfer of money from one party to another, such as sale/purchase or refund.
Genericflows, which are designed to support any custom/bespoke scenario where the request/response models can hold any arbitrary data. Examples of AEVI defined types are tokenisation and batch closure.
Status updateflows, which allow an application to inform other applications of some status/state change, such as basket or customer updates.
The most common payment flow is the sale flow, which is used for all standard transactions where a customer is charged for some goods or services.
Below is a diagram illustrating a sale flow with all supported stages. The only mandatory stage is
TRANSACTION_PROCESSING- all others are optional.
In the diagram you can see the distinction between payment applications and value added applications based on the stage of the flow.
An application can be defined to be called at multiple stages of the same flow. An example could be a loyalty points app, where you may want to offer a customer the option to redeem their points for a purchase before the payment application processes the payment (
pre-transaction), and you may want to reward the customer with points after a successful purchase (
Below is a short summary for each stage relevant for payment flows.
This stage is executed immediately after the source
Payment has been received and validated. It is executed only once per flow, regardless of whether the flow is split or not.
Pre-flow is designed to handle the fairly rare use cases where an application other than the POS application initiates a flow. As an example, a loyalty app might be the first point of interaction with a customer where they identify themselves. In order to pass this information onto a payment flow (without using bespoke integrations), the loyalty app can initiate a zero based amounts payment with associated customer data. The POS application will then be called in the pre-flow stage where it can perform its normal function and update the
Payment model with relevant data before the flow continues.
Note; By default, pre-flow is only called for cases where the payment amounts are zero. This is configurable via
A pre-flow app can via the
PreFlowModel set data in a
Payment model similar to what an initiation app can do. It may also cancel the flow.
If a split application is installed and the request has enabled split, the split stage will be executed where the application can split the flow into one or more individual transactions. The most common use case of this is to allow a group of customers to split the bill, either based on amount or via basket items.
A split app can via the
SplitModel update the base amount and/or basket for the next transaction. It may also cancel the flow.
This stage allows an application to modify request data before any potential payment card is read, assuming that there is a payment application that reads cards and supports the optional payment-card-reading stage.
For most applications, post-card-reading will be a more appropriate stage as card details may then also be available, allowing an informed choice of how to identify a customer. This is explored in further depth in the API documentation.
A pre-transaction app can via the
PreTransactionModel do things like;
- Add amounts (like charity donation or a fee)
- Add baskets
- Pay off a portion or all of the requested amounts
- Apply discounts to baskets / basket items
- Add or update customer details
Payment card reading
This is an optional stage that a payment app may or may not support. Note that there is no guarantee that payment applications even use payment cards as a payment method - it could be cash, QR codes, etc.
If the stage is supported and the card reading is successful, card data will be available for the remaining stages.
A payment app can via the
CardReadingModel set card details or decline the transaction.
This stage is executed after the optional payment card reading step, meaning there may or may not be valid card data available.
Post-card-reading is using the same model as pre-transaction,
PreTransactionModel, and can perform the same actions.
At this stage, the payment app will process the payment based on the data provided (which may or may not have been augmented in previous stages).
At the end of this stage, a
TransactionResponse will be sent back via a
TransactionProcessingModel dictating the outcome of the transaction.
TransactionSummary model will be passed to applications in this stage, which contains a breakdown of the input transaction data and a list of transaction responses for that transaction. It will also contain the card data if any was set by the payment application at either payment app stage.
Note that the only thing an application can augment at this point is adding transaction references, via the
This stage is executed after the flow is completed and a final
PaymentResponse object has been created which is made available for applications at this stage.
There are no options to augment any data as the flow has completed.
A post-flow app may however choose to keep executing in the background in parallel to the flow.
The generic flows are a lot simpler than the payment flows and consists of only two possible stages.
The generic stage is where the request is processed. As an example, for a request of type
tokenisation, this is where a payment app would read a card and generate token.
There can only be one service handling a generic request and passing back a response via the
This is the generic equivalent of Post-flow, where an app gets called with the final response and can review that data.
It can also add references to that response via the
Status update flows
Status update flows are similar to generic flows in terms of how they are initiated and what models are used, but the execution of
the flows are different. For status updates, there is just a single stage,
STATUS_UPDATE, that may contain one to many applications that
get called in sequence for the purpose of getting access to the request data. The flow is executed entirely in the background from a special request queue and can process in parallel to payment and generic foreground flows.
Applications can fetch the data and optionally add references via the
A flow configuration is a JSON structure that defines the flow meta-data, what stages it consists of and what applications to call for each stage, if any. See Example Flows for what a fully fledged
sale flow and a standard generic flow might look like.
These flow configurations are created by AEVI and/or the acquirers and are bundled inside a Flow Configuration Provider (FCP), which is an application responsible for providing FPS and other components with runtime configuration details.
How AppFlow behaves is defined via these flow configurations, such as
- What types of requests are supported (sale, refund, tokenisation, etc)
- What flow services get called for any particular flow/type, in any given stage
- What the rules of application selection are if there is more than one flow service for a stage
What flows are created and what they look like for any given environment is generally down to the acquirer and enabled device requirements. It is common for acquirers to offer app bundles via their various merchant offerings, in which case there is a set of flows associated with each bundle.
For development and testing purposes, we offer a special type of flow config provider as part of this SDK that allows developers to configure the flows dynamically via a user interface.
Flow name vs type
A flow has both a name and a type associated with it. This is due to the fact that AppFlow supports multiple flows per type, to allow for scenarios where different stages and/or applications can be used with the same type. As an example, there may be two different sale flows each with a different loyalty scheme and the merchant initiates the relevant one based on what scheme the customer is signed up with.
Initiating apps must provide the flow type at a minimum, and optionally a flow name to explicitly specify what flow to use. If no name is provided and there are multiple flows available for the given type, a dialog will be presented allowing the merchant to select the desired flow.
If flow name is required, there are two ways to determine what flow name to use:
- The available flows are known up front
- The possible flows are looked up programmatically from desired type
The first case is fairly standard for initiating apps where they are customised for a particular acquirer. In these cases, that acquirer project will define specifications that outline the available flows and the initiating app can technically hard code the flow names to represent the function they want to initiate.
The second case would allow for dynamic choices of flows, but as FPS already supports this natively, it may not be as useful.
In addition to the pre-defined flows, FPS will also create ad-hoc flows dynamically based on the custom request types reported by the flow services. These are generic flows which typically only call a single application. It is however possible for more than one application to support a custom type, in which case the app selection will be done according to
SINGLE_SELECT rules, described below.
If a flow service that has defined a custom request type is uninstalled or no longer defines it, the associated flow will also be removed.
App execution types
The flow configuration defines a field called
appExecutionType that is associated with each stage. This determines how FPS will execute the applications in that stage.
SINGLE- Only a single application can be defined
SINGLE_SELECT- Multiple applications can be defined and runtime filtering and/or selection will determine one
MULTIPLE- Multiple applications can be defined and they will be called one by one in order of definition
DYNAMIC_SELECT- This is a special dev/test type (not allowed in prod) that can have an empty list of apps for full runtime selection of eligible apps
AppFlow consists of two separate APIs, each with one or many associated sample apps;
Payment Initiation API- Provides general flow and system information and allows apps to initiate flows
Payment Flow Service API- Provides an integration point for flow services to be called throughout the flow
Payment Initiation API
Payment Initiation API allows an application to initiate flows. It also provides various functions to query the system for information about the defined flows and installed flow services.
Payment Flow Service API
Payment Flow Service API allows for applications to be called throughout the flows and provide capabilities.
This is the API you should be looking at if you are building
- a value added application, such as loyalty, charity, currency conversion, receipt generation, printing, etc
- a payment application that can process payments via any form of payment method
AppFlow has been designed to be as flexible as possible. This is achieved via the generic
Response models, configurable flows, support for additional/custom/bespoke data for basically any scenario and so on. Bounded types such as
enum are also avoided wherever possible.
This is to avoid limitations and restrictions and to support cases where third party applications define a private/internal API/contract for proprietary data. In the documentation you will find definitions for the various types of requests, what data can be passed for various requests and use cases, and what format this data is in. This is to ensure applications can set and read data in a compatible way.
Although AEVI does not enforce the use of this common set of definitions, developers should always look to the documentation to ensure consistency with other applications.
It should be noted that although the APIs define POJOs for client apps to use, all data is represented as JSON. The POJOs are serialised to JSON whenever it is passed between applications and the system itself is mainly concerned with JSON structures.
The APIs are primarily Java based, but as the underlying representation is JSON there is no real language restriction from a system point of view.
Kotlin (and some other JVM-based languages) are implicitly supported due to interoperability with Java.
These APIs make extensive use of reactive (Rx) based principles. Therefore in the case of the Java API it makes heavy use of the RxJava library.
To read more about Rx principles and the RxJava library itself see the documentation here. For the remainder of this documentation it is assumed that the reader is familiar with asynchronous and event-based programming using observable streams.