Receipt Considerations - AEVI-AppFlow/pos-android-sdk GitHub Wiki

Receipts should usually be printed by a flow service application that is executed in the POST_TRANSACTION or POST_GENERIC stage. Therefore, a receipt printing application implement a service extending BasePaymentFlowService and override the two methods onPostTransaction and onGeneric. Within onPostTransaction the service will retrieve the TransactionSummary and use this to construct a receipt. Within the onGeneric method the receipt app must obtain the correct data from the request data and use the information to print the receipt. See receipts for more details on the type of data you can expect.

Receipts for payments

The TransactionSummary object contains information about who the receipt is for and details of the Transaction that has just occurred in the previous stages. The Transaction object can contain lots of data that may or may not need to be printed on the receipt which has been added by any number of flow apps in the flow so far. It is likely that as well as the different data acquirers will have there own requirements as to what needs to be printed on the receipt.

However, there are certain data structures that will always be present which are described below.

Baskets

Both POS applications and flow services can add baskets to the transaction. It is most likely that these all simply need to be printed onto the receipt. This can be done by simply finding all the baskets in the TransactionSummary and adding to the receipt e.g.

String currency = transactionSummary.getRequestedAmounts().getCurrency();
for (Basket basket : transactionSummary.getBaskets()) {
    addBasketDetails(printPayload, basket, currency);
}

Where the addBasketDetails method above does the work of adding all the basket lines items to the receipt.

Basket objects can themselves contain other additional data items that may require specific handling in certain use cases.

Different amounts

The TransactionSummary object also contains all TransactionResponses that may have occurred during a flow. Each TransactionResponse contains information about an amount that has been paid. The TransactionResponse contains at least a amount processed, which should always be added to the receipt, and can optionally include any number of additional amounts. Usually these amounts indicate sub totals such as tax, cashback, tip etc. These additional amounts can simply be iterated and added to the receipt.


for (TransactionResponse transactionResponse : transactions) {
    Amounts amounts = transactionResponse.getAmountsProcessed();
    String paymentMethod = transactionResponse.getPaymentMethod();
    Map<String, Long> addAmounts = amounts.getAdditionalAmounts();
    for (String type : new TreeSet<>(addAmounts.keySet())) {
        append(printPayload, type.toUpperCase(), formatAmount(new Amount(addAmounts.get(type), amounts.getCurrency())));
    }

    append(printPayload, getPaidByMessage(paymentMethod), formatAmount(amounts.getTotalAmount()));
}

Note that of course amounts in the API are always longs and should be converted sensibly to the correct currency and unit display, shown above as formatAmount method. Care should be taken to ensure the units are displayed correctly.

The getPaidByMessage method referenced above will convert the payment method string supplied into a user friendly string to display on the receipt. Usually this would indicate how the payment was fulfilled e.g. by card, cash or loyalty points etc.

Customer details

Depending on the use-case it may be a requirement to display customer data on a receipt. For Payment requests a specific Customer object is made available if it has been added during the flow. The Customer object contains some basic standard fields as well as a number of additional data fields described here. Customer information can be added before the Payment is initiated or at any time in the flow by a flow service that is able to identify the customer in some way e.g. card token.

Ads/promotions

It is possible that an advertising flow service might add data to augment a flow. This may need to be displayed on the receipt. This could include adding images and/or a QR code that can be scanned by a customer to access further content from the advert. See here for more details of the kind of data an advert service may add to the transaction

Card details

If a response was paid for by card then the TransactionResponse object will contain a Card object containing the details. This can be extracted and added to a receipt like so.

Card card = transactionResponse.getCard();
if (card != null) {
    if (card.getCardholderName() != null) {
        appendToReceipt(card.getCardholderName());
    }
    if (card.getMaskedPan() != null) {
        appendToReceipt(card.getMaskedPan());
    }
    if (card.getExpiryDate() != null) {
        appendToReceipt(card.getExpiryDate());
    }

    AdditionalData cardData = card.getAdditionalData();
    appendIfPresent(cardData, "network");
    appendIfPresent(cardData, "entryMethod");
}

As well as the standard card fields other data may also be available in the additionalData stored with the Card. As above you can see the code is extracting the "network" and "entryMethod". The complete list of additional data for card can be found here

Transaction references

Each TransactionResponse can also contain any number of bespoke references these can be found in the AdditionalData returned from the getReferences() method. These references are usually added by a payment flow service and acquirers may mandate that certain ones are shown on the receipt. e.g. transaction ID and certain EMV values.

The references may also contain other bespoke data that does not fit into any of the objects above e.g loyalty data. This may also need to be printed on the receipt. For example these references may contain loyalty data which can be extracted as below.

AdditionalData references = transactionResponse.getReferences();
appendIfPresent(references, "earnPoints");
appendIfPresent(references, "redeemPoints");
appendIfPresent(references, "totalPoints");

For more information about specific loyalty data attributes