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:
| Callback | Purpose |
|---|---|
Display | Show cashier-facing terminal messages. |
PrintReceipt | Handle merchant and cardholder receipts delivered as ReceiptData. |
PrintReport | Handle textual terminal reports. |
Log | Store or display library log entries, typically using OperatingParameters and local diagnostics settings together. |
ParameterDownloadAvailable | Allow 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 dependentSwift: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
csharppublic 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
swiftfunc 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
csharppublic 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
swiftfunc 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
csharppublic 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
swiftfunc 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.
| Notification | Meaning |
|---|---|
| Link status | The connection between ECR and terminal changed. |
| Busy status | The terminal is performing a long-running operation. |
| Card action | A card was inserted or removed. |
| Card accepted | The terminal accepted a card and supplies masked card details through CardAcceptedEventArgs. |
| Raw message | A 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
csharpepas.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
swiftfunc 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
csharppublic 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
swiftfunc log(level: LogLevel, text: String) { ecrLogger.write(level: level, text: text) }