Client Callbacks

Last updated: 2026-05-19

Callback Model

The EPAS Client Library is callback-driven. Your ECR calls the library to connect, log in, and start transactions. The library calls your ECR when it needs a cashier prompt, receipt handling, logging, or a terminal status update.

Callbacks should return quickly. If a callback needs UI interaction, marshal to your UI framework and return the result as soon as it is available.

In Swift, callbacks are exposed through EpasClientDelegate and can use async return values for cashier decisions such as BooleanCallbackResult, TextCallbackResult, and DecimalCallbackResult.

Required Operational Callbacks

Start by implementing these baseline callbacks:

CallbackPurpose
DisplayShow cashier-facing terminal messages.
PrintReceiptHandle merchant and cardholder receipts delivered as ReceiptData.
PrintReportHandle textual terminal reports.
LogStore or display library log entries, typically using OperatingParameters and local diagnostics settings together.
ParameterDownloadAvailableAllow or defer terminal parameter download.

The summary above is for fast scanning. The sections below show the callback shape and concrete implementation examples.

Baseline Callback Signatures

Display

  • .NET: void Display(string text)
  • Java: void Display(String text)
  • Swift: func display(text: String)

PrintReceipt

  • .NET: void PrintReceipt(ReceiptData receipt)
  • Java: void PrintReceipt(ReceiptData receipt)
  • Swift: func printReceipt(receipt: ReceiptData)

PrintReport

  • .NET: void PrintReport(string report)
  • Java: void PrintReport(String report)
  • Swift: func printReport(report: String)

Log

  • .NET: void Log(LogLevel level, string text)
  • Java: void Log(ApiDefinitions.LogLevel level, String text)
  • Swift: func log(level: LogLevel, text: String)

ParameterDownloadAvailable

  • .NET: void ParameterDownloadAvailable(string text, out bool permit)
  • Java: boolean ParameterDownloadAvailable(String text)
  • Swift: func parameterDownloadAvailable(displayText: String) async -> Bool

Cashier Decision Callbacks

These callbacks are triggered only when the terminal flow needs operator input.

Signature Verification

Ask the cashier whether the cardholder signature is accepted.

  • .NET: bool VerifySignature(string text, out bool ok)
  • Java: Pair<Boolean, Boolean> VerifySignature(String text)
  • Swift: func verifySignature(displayText: String) async -> BooleanCallbackResult?

Force Fallback

Confirm magnetic-stripe fallback when chip handling requires cashier consent. Related outcome handling is typically driven by ErrorConditions / ErrorCondition.

  • .NET: bool ForceFallback(string text, out bool useFallback)
  • Java: wrapper-version dependent
  • Swift: func forceFallback(displayText: String) async -> BooleanCallbackResult?

Voice Referral

Collect a voice referral approval code.

  • .NET: bool HandleVoiceReferral(string text, out string code)
  • Java: Pair<Boolean, String> HandleVoiceReferral(String text)
  • Swift: func handleVoiceReferral(displayText: String) async -> TextCallbackResult?

Payment Code

Collect a payment code for cards that require one.

  • .NET: bool PaymentCodeRequired(string text, out string code)
  • Java: Pair<Boolean, String> PaymentCodeRequired(String text)
  • Swift: func paymentCodeRequired(displayText: String) async -> TextCallbackResult?

VAT Amount

Collect VAT or sales tax amount when required.

  • .NET: bool VatAmountRequired(string text, out decimal amount)
  • Java: Pair<Boolean, Double> VatAmountRequired(String text)
  • Swift: func vatAmountRequired(displayText: String) async -> DecimalCallbackResult?

Loyalty Card

Decide how to handle a loyalty card.

  • .NET: bool LoyaltyCardPresented(string card, out bool useForPayment)
  • Java: Pair<Boolean, Boolean> LoyaltyCardPresented(String card)
  • Swift: func loyaltyCardPresented(cardNumber: String) async -> BooleanCallbackResult?

DCC Refund Check

Confirm whether DCC was used on the original purchase.

  • .NET: bool CheckDccOnOriginalTransaction(string text, out bool used)
  • Java: Pair<Boolean, Boolean> CheckDccOnOriginalTransaction(String text)
  • Swift: func checkDccOnOriginalTransaction(displayText: String) async -> BooleanCallbackResult?

Display Callback

The display callback contains text intended for the cashier. It may differ from the terminal's cardholder display text and may include line breaks. Use the tabs below to compare the same callback implementation across wrappers.

.NET

csharp
public void Display(string text)
{
    cashierDisplay.Text = text.Replace("\n", Environment.NewLine);
}

Java

java
@Override
public void Display(String text) {
    cashierDisplay.setText(text.replace("\n", System.lineSeparator()));
}

Swift

swift
func display(text: String) {
    cashierDisplay.text = text
}

Receipt Callback

The terminal can call PrintReceipt more than once during a transaction, normally once for the merchant receipt and once for the cardholder receipt. Store the ReceiptData even if printing immediately. Use the tabs below to compare the same receipt handling pattern across wrappers.

.NET

csharp
public void PrintReceipt(ReceiptData receipt)
{
    receiptRepository.Save(receipt);
    receiptPrinter.Print(receipt.GenerateSimpleReceipt(32));
}

Java

java
@Override
public void PrintReceipt(ReceiptData receipt) {
    receiptRepository.save(receipt);
    receiptPrinter.print(receipt.generateSimpleReceipt(32));
}

Swift

swift
func printReceipt(receipt: ReceiptData) {
    receiptRepository.save(receipt)
    receiptPrinter.print(receipt.generateSimpleReceipt(width: 32))
}

Cashier Decision Callbacks

For callbacks that return a decision, the return value tells the library whether the transaction should continue. The output value, Pair, or Swift callback result carries the cashier answer.

Signature Verification - .NET

csharp
public bool VerifySignature(string displayText, out bool signatureOk)
{
    Display(displayText);
    signatureOk = cashierPrompts.Confirm("Signature OK?");
    return true;
}

Signature Verification - Java

java
@Override
public Pair<Boolean, Boolean> VerifySignature(String displayText) {
    Display(displayText);
    boolean signatureOk = cashierPrompts.confirm("Signature OK?");
    return new Pair<>(true, signatureOk);
}

Signature Verification - Swift

swift
func verifySignature(displayText: String) async -> BooleanCallbackResult? {
    display(text: displayText)
    let accepted = await cashierPrompts.confirm("Signature OK?")
    return BooleanCallbackResult(handled: true, value: accepted)
}

Optional Status Notifications

Status notifications help your ECR update UI state and recover from terminal events.

NotificationMeaning
Link statusThe connection between ECR and terminal changed.
Busy statusThe terminal is performing a long-running operation.
Card actionA card was inserted or removed.
Card acceptedThe terminal accepted a card and supplies masked card details through CardAcceptedEventArgs.
Raw messageA raw EPAS message was received. Use only when you need protocol-level diagnostics.

Use the tabs below to compare the notification hookup in each wrapper.

.NET

csharp
epas.LinkStatus = linkUp =>
{
    if (!linkUp)
    {
        reconnectWorkflow.Schedule();
    }
};

epas.BusyStatus = busy => ui.SetTerminalBusy(busy);
epas.CardStatus = inserted => ui.SetCardInserted(inserted);
epas.CardAccepted = args => audit.RecordCard(args);

Java

java
@Override
public boolean IsBusyStatusNotificationEnabled() {
    return true;
}

@Override
public boolean IsCardActionNotificationEnabled() {
    return true;
}

@Override
public void BusyStatusNotification(boolean state) {
    ui.setTerminalBusy(state);
}

@Override
public void CardActionNotification(boolean cardInserted) {
    ui.setCardInserted(cardInserted);
}

Swift

swift
func linkStatusChanged(isConnected: Bool) {
    ui.setTerminalConnected(isConnected)
}

func busyStatusChanged(isBusy: Bool) {
    ui.setTerminalBusy(isBusy)
}

func cardStatusChanged(isInserted: Bool) {
    ui.setCardInserted(isInserted)
}

func epasMessageReceived(message: String) {
    diagnosticsStore.append(message)
}

Logging

The library also stores terminal trace information or exposes it through callbacks. The Log callback is useful because it lets your ECR correlate terminal activity with cashier actions and transaction IDs. Use the tabs below for wrapper-specific logging examples.

.NET

csharp
public void Log(LogLevel level, string text)
{
    ecrLogger.Write(level.ToString(), text);
}

Java

java
@Override
public void Log(ApiDefinitions.LogLevel level, String text) {
    ecrLogger.write(level.name(), text);
}

Swift

swift
func log(level: LogLevel, text: String) {
    ecrLogger.write(level: level, text: text)
}