Transactions

SPI empowers your POS with the ability to make several types of transactions.

Introductions

An example of a transaction is when a customer uses their card to pay for a meal. They present their card to the EFTPOS terminal which communicates with the POS (via SPI). If the transaction succeeds, money is transferred from the customer to the merchant.

See the code

Take a tour of the code below, and copy it into your project to get started.

Generate posRefIds

Each transaction is identified by a posRefId. This is a unique string that can be in any format, and a UUID is often used.

Note that when retrying a transaction (i.e. after an 'invalid PIN' or 'signature declined'), a new unique posRefId must be used.

Purchase transaction

An example of a purchase is when a customer buys a candle from a candle shop and pays for it using their card.

In the code, for the spi.InitiatePurchaseTxV2(...) function, take note of the following parameters.

  • posRefId — this must be a unique string.
  • purchaseAmount — this amount is specified in cents, so 1000 means $10.

The other fields are used for additional features such as surcharges.

As with all transactions, spi.AckFlowEndedAndBackToIdle() should be called first to return the terminal to the 'Idle' state.

Sequence diagram of a purchase transaction.

When using Gecko Bank for testing, it will ask you to select the method of card entry: Tap, Insert, or Swipe. Then, enter a PIN if necessary, and it will approve the transaction. It doesn't ask you to present a card since it is a virtual terminal, and this makes testing easier since no test card is needed.

📘

Learn how to create a UI for transactions.

Refund transaction

An example of a refund is when a customer purchases a candle but then decides to return it to the candle shop a week later. The candle shop returns the money to the customer's card.

In the code, for the spi.InitiateRefundTx(...) function, take note of the following parameters.

  • posRefId — this should be a unique string to initiate the Refund transaction.
  • refundAmount — for a full refund, use the same amount as that of the purchase, or for a partial refund, use a lesser amount. It is also possible to use a greater amount.
  • suppressMerchantPassword — we recommend for this value to be false. This will require the merchant to enter their password to approve the refund, thereby protecting against theft.

Sequence diagram of a refund transaction.

When using Gecko Bank for testing, if suppressMerchantPassword is false, it will first ask you to authenticate by entering the Manager passcode. After this, select the card entry method (as with a purchase transaction), then enter a PIN and the refund will be approved.

Additional transaction types

You can also add support for the following transaction types.

  • MOTO transactions
  • Cashout-only transactions
  • Settlement and settlement enquiry
  • Pre-authorisation transactions

Handling the 'TxFlowStateChanged' event

When processing transactions, it is important to add the TxFlowStateChanged event listener. This feature allows the library to send important updates regarding the transactions, such as when they start, finish, and when signatures are required. By doing so, you can provide targeted feedback to your users on the UI.

For an example of how to handle transactions, see the events code sample.

Your integration logic can be different to the example, but it should still be similar to the following.

  1. If a signature is required, handle the signature transaction.
  2. Else, if MOTO phone authentication is required, handle a MOTO transaction.
  3. Else, if the transaction is finished ...
    1. If the merchant receipt hasn't already been printed ...
      1. Print and/or store the merchant receipt.
    2. If the customer receipt hasn't already been printed ...
      1. Print and/or store the customer receipt.
    3. Display a UI for if the transaction was successful, if it failed, or if manual transaction recovery is needed.
    4. If the transaction was successful, close the sale on the POS.
    5. Perform any other actions needed, even for specific transaction types.

📘

We recommend always storing the receipts, even if the receipt is printed.

Handling the 'TxFlowStateChanged' response

In the case of a successful transaction, you can access the 'host_response_text' property in the event data. Typically, this property contains a string indicating that the transaction has been “Approved”.

If the transaction fails, you should check the 'host_response_text' again. If it's empty, you can check the 'error_reason' and 'error_detail' properties to determine the reason for the failure. Note that 'host_response_text' can be empty if the transaction is cancelled before it reaches the terminal.

We suggest using a conditional statement to determine the appropriate text to display based on the transaction status. You can find examples of this in our "Events" Recipe.

'TxFlowStateChanged' event data

The 'TxFlowStateChanged' event contains detailed information about the transaction which you can use in your integration logic. In its detail object, it contains the following.

Transaction request and response The Request sent to SPI and Response received from it.
Display message A message that you can display in the UI — e.g. DisplayMessage: "Purchase Transaction Ended."
Success state The Success state can be either Success, Failed, or Unknown
These states are defined in the SuccessState object:
import { SuccessState } from "@mx51/spi-client-js";
Transaction type The Type can be either AccountVerify, CashoutOnly, GetLastTransaction, GetTransaction, MOTO, Preauth, Purchase, Refund, Reversal, Settle, SettlementEnquiry These types are defined in the TransactionType object: import { TransactionType } from "@mx51/spi-client-js";
Various boolean statuses There are several statuses that are boolean (true/false) values: AttemptingToCancel, AwaitingGtResponse, AwaitingPhoneForAuth, AwaitingSignatureCheck, Finished, RequestSent

Additionally, you can find this data in spi.CurrentTxFlowState when a new update is available for the current transaction. This information can help you determine whether the transaction has finished txState.Finished and whether it was successful txState.Success.

📘

Learn how to listen for events and handle signature transactions.