Transactions

Last updated: 2026-05-19

Transaction Model

The EPAS Client Library transaction APIs are terminal-roundtrip operations. A call such as Purchase, purchase, or purchase(_:) returns only when the terminal has completed the flow.

  • In .NET and Java, do not run transaction calls on the UI thread.
  • In Swift, use async APIs from a task and keep UI updates inside delegate callbacks or on the main actor.

ApiResult.OK means the request was sent and the response was parsed. It does not mean the payment was approved. Always inspect TransactionResponse.

Purchase

Use the tabs below to compare the same transaction flow across .NET, Java, and Swift.

.NET

csharp
TransactionResponse response;
ApiResult result = epas.Purchase(100.00m, out response);

if (result == ApiResult.OK)
{
    HandleTransactionResponse(response);
}

Java

java
ApiDefinitions.PurchaseTransactionAmounts amounts =
    definitions.new PurchaseTransactionAmounts(100.00);

Pair<ApiDefinitions.ApiResult, TransactionResponse> result = epas.purchase(amounts);
if (result.getKey() == ApiDefinitions.ApiResult.OK) {
    handleTransactionResponse(result.getValue());
}

Swift

swift
let response = try await client.purchase(100.00)
handleTransactionResponse(response)

Alternative Payment Method Purchase

The ECR can request a named alternative payment method for a purchase. If the terminal does not support the requested method, the transaction is aborted.

.NET

csharp
TransactionResponse response;
ApiResult result = epas.Purchase(100.00m, "Swish", out response);

Java

java
Pair<ApiDefinitions.ApiResult, TransactionResponse> result =
    epas.purchase(100.00, "Swish");

Swift

swift
let request = PurchaseRequest(
    amount: 100.00,
    paymentMethod: "Swish"
)

let response = try await client.purchase(request)

Purchase with Cashback

.NET

csharp
var amounts = new PurchaseTransactionAmounts(
    purchaseAmount: 100.00m,
    cashbackAmount: 20.00m);

ApiResult result = epas.Purchase(amounts, out TransactionResponse response);

Java

java
ApiDefinitions.PurchaseTransactionAmounts amounts =
    definitions.new PurchaseTransactionAmounts(100.00, 20.00);

Pair<ApiDefinitions.ApiResult, TransactionResponse> result = epas.purchase(amounts);

Swift

swift
let amounts = PurchaseTransactionAmounts(100.00, cashbackAmount: 20.00)
let response = try await client.purchase(amounts)

Purchase with Full Request Data

Use the full PurchaseRequest object when the ECR needs to specify terminal ID override, cashback, alternative payment method, or MCC.

.NET

csharp
var request = new PurchaseRequest
{
    Amount = 100.00m,
    CashbackAmount = 20.00m,
    PaymentMethod = null,
    TerminalId = null,
    MerchantCategoryCode = 5411
};

ApiResult result = epas.Purchase(request, out TransactionResponse response);

Java

java
PurchaseRequest request = new PurchaseRequest();
request.Amount = 100.00;
request.CashbackAmount = 20.00;
request.PaymentMethod = null;
request.TerminalId = null;
request.MerchantCategoryCode = 5411;

Pair<ApiDefinitions.ApiResult, TransactionResponse> result = epas.purchase(request);

Swift

swift
let request = PurchaseRequest(
    amount: 100.00,
    cashbackAmount: 20.00,
    paymentMethod: nil,
    terminalId: nil,
    merchantCategoryCode: 5411
)

let response = try await client.purchase(request)

Pre-Amount Purchase

Use pre-amount purchase when the customer may present a card before the final amount is known. Start the transaction first, then send PurchaseTransactionAmounts later.

.NET

csharp
Task.Run(() =>
{
    ApiResult result = epas.PurchaseBeforeAmount(out TransactionResponse response);
    HandleTransactionResponse(response);
});

var amounts = new PurchaseTransactionAmounts(100.00m, 0.00m);
ApiResult sendResult = epas.SendPurchaseAmounts(amounts);

Java

java
CompletableFuture.runAsync(() -> {
    Pair<ApiDefinitions.ApiResult, TransactionResponse> result =
        epas.purchaseBeforeAmount();
    handleTransactionResponse(result.getValue());
});

ApiDefinitions.PurchaseTransactionAmounts amounts =
    definitions.new PurchaseTransactionAmounts(100.00, 0.00);

ApiDefinitions.ApiResult sendResult = epas.sendPurchaseAmounts(amounts);

Swift

swift
Task {
    let response = try await client.purchaseBeforeAmount()
    handleTransactionResponse(response)
}

let amounts = PurchaseTransactionAmounts(100.00, cashbackAmount: 0.00)
let sendResult = try await client.sendPurchaseAmounts(amounts)

Refund

Refunds for card payments use the refund amount. Alternative payment method refunds must use the same payment method as the original purchase and normally include the original reference through RefundRequest or the equivalent wrapper call.

.NET

csharp
ApiResult result = epas.Refund(45.00m, out TransactionResponse response);
csharp
var original = new AltMethodTransaction(AltMethod.Swish)
{
    TransactionAmount = 45.00m,
    TransactionReference = originalReference
};

ApiResult result = epas.Refund(original, out TransactionResponse response);

Java

java
Pair<ApiDefinitions.ApiResult, TransactionResponse> result = epas.refund(45.00);
java
RefundRequest request = new RefundRequest();
request.Amount = 45.00;
request.PaymentMethod = "Swish";
request.Reference = originalReference;

Pair<ApiDefinitions.ApiResult, TransactionResponse> result = epas.refund(request);

Swift

swift
let response = try await client.refund(45.00)
swift
let request = RefundRequest(
    amount: 45.00,
    paymentMethod: "Swish",
    reference: originalReference
)

let response = try await client.refund(request)

Reversal

A reversal cancels the most recent approved transaction when the terminal or acquirer still allows it.

.NET

csharp
ApiResult result = epas.ReverseLastTransaction(
    transactionReference,
    out TransactionResponse response);

Java

java
Pair<ApiDefinitions.ApiResult, TransactionResponse> result =
    epas.reversal(transactionReference);

Swift

swift
let response = try await client.reverseLastTransaction(transactionReference)

Cash Advance

.NET

csharp
ApiResult result = epas.CashAdvance(200.00m, out TransactionResponse response);

Java

java
Pair<ApiDefinitions.ApiResult, TransactionResponse> result =
    epas.cashAdvance(200.00);

Swift

swift
let response = try await client.cashAdvance(200.00)

Last Transaction

Use last transaction when the ECR needs the latest terminal transaction outcome after recovery, reconciliation, or support workflows. The result is returned as LastTransactionResponse.

.NET

csharp
ApiResult result = epas.GetLastTransaction("80000082", out LastTransactionResponse response);
if (result == ApiResult.OK && response.mTransaction != null)
{
    Console.WriteLine(response.mTransaction.mReference);
}

Java

java
Pair<ApiDefinitions.ApiResult, LastTransactionResponse> result =
    epas.getLastTransaction("80000082");

if (result.getKey() == ApiDefinitions.ApiResult.OK &&
    result.getValue().mTransaction != null) {
    System.out.println(result.getValue().mTransaction.mReference);
}

Swift

swift
let response = try await client.getLastTransaction("80000082")
if let transaction = response.transaction {
    print(transaction.reference)
}

Enable or Disable Card Readers

Enable or disable payment or refund acceptance when the ECR needs to control terminal entry points outside an active transaction. Reader mode is controlled through EnableCardReaderOptions and ServiceEnableType.

.NET

csharp
var options = new EnableCardReaderOptions
{
    NotifyOnCancel = true,
    TransactionType = ServiceEnableType.Payment
};

ApiResult enableResult = epas.EnableCardReaders(true, options, out EnableReadersResponse enableResponse);
ApiResult disableResult = epas.EnableCardReaders(false, options, out EnableReadersResponse disableResponse);

Java

java
ApiDefinitions.EnableCardReaderOptions options = definitions.new EnableCardReaderOptions();
options.NotifyOnCancel = true;
options.TransactionType = ApiDefinitions.ServiceEnableType.Payment;

Pair<ApiDefinitions.ApiResult, EnableReadersResponse> enableResult =
    epas.enableCardReaders(true, options);

Pair<ApiDefinitions.ApiResult, EnableReadersResponse> disableResult =
    epas.enableCardReaders(false, options);

Swift

swift
let enableResponse = try await client.enableCardReaders(
    true,
    EnableCardReaderOptions(
        notifyOnCancel: true,
        transactionType: .payment
    )
)

let disableResponse = try await client.enableCardReaders(false)

Administrative Operations

Administrative operations are terminal management flows rather than payment transactions. The requested operation is represented by AdminOperation, and the result is returned as AdminResponse.

.NET

csharp
ApiResult hostLogin = epas.RequestAdministrativeOperation(AdminOperation.HostLogin, out AdminResponse hostLoginResponse);
ApiResult printConfiguration = epas.RequestAdministrativeOperation(AdminOperation.PrintConfiguration, out AdminResponse printConfigResponse);
ApiResult updateParameters = epas.RequestAdministrativeOperation(AdminOperation.UpdateParameters, out AdminResponse updateResponse);

Java

java
Pair<ApiDefinitions.ApiResult, AdminResponse> hostLogin =
    epas.requestAdministrativeOperation(ApiDefinitions.AdminOperation.HostLogin);

Pair<ApiDefinitions.ApiResult, AdminResponse> printConfiguration =
    epas.requestAdministrativeOperation(ApiDefinitions.AdminOperation.PrintConfiguration);

Pair<ApiDefinitions.ApiResult, AdminResponse> updateParameters =
    epas.requestAdministrativeOperation(ApiDefinitions.AdminOperation.UpdateParameters);

Swift

swift
let hostLogin = try await client.requestAdministrativeOperation(.hostLogin)
let printConfiguration = try await client.requestAdministrativeOperation(.printConfiguration)
let updateParameters = try await client.requestAdministrativeOperation(.updateParameters)

Raw XML Diagnostics

Use raw XML only for diagnostics, parity verification, or protocol-level troubleshooting.

.NET

csharp
string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<SaleToPOIRequest>
  ...
</SaleToPOIRequest>";

ApiResult result = epas.SendRawXml(xml);

Java

java
String xml = """
<?xml version="1.0" encoding="utf-8"?>
<SaleToPOIRequest>
  ...
</SaleToPOIRequest>
""";

ApiDefinitions.ApiResult result = epas.sendRawXml(xml);
java
Pair<ApiDefinitions.ApiResult, String> result = epas.sendRawXmlWithResult(xml);

Swift

swift
let xml = """
<?xml version="1.0" encoding="utf-8"?>
<SaleToPOIRequest>
  ...
</SaleToPOIRequest>
"""

let result = try await client.sendRawXml(xml)

Customer Inquiry

Use customer inquiry when the terminal needs the cardholder or cashier to answer a non-payment prompt during the flow. The result is returned as CustomerInquiryResponse.

.NET

csharp
var request = new CustomerInquiryRequest
{
    HeaderText = "Age check",
    InstructionMessage = "Are you over 18?"
};

ApiResult result = epas.SendCustomerInquiry(request, out CustomerInquiryResponse response);

Java

java
CustomerInquiryRequest request = new CustomerInquiryRequest();
request.HeaderText = "Age check";
request.InstructionMessage = "Are you over 18?";

Pair<ApiDefinitions.ApiResult, CustomerInquiryResponse> result =
    epas.sendCustomerInquiry(request);

Swift

swift
let request: CustomerInquiryRequest = buildCustomerInquiryRequest()
let response = try await client.sendCustomerInquiry(request)

Abort Customer Inquiry

Abort customer inquiry when the inquiry prompt should be withdrawn before the terminal has completed it.

.NET

csharp
ApiResult result = epas.AbortCustomerInquiry();

Java

java
ApiDefinitions.ApiResult result = epas.abortCustomerInquiry();

Swift

swift
try await client.abortCustomerInquiry()

Terminal-Side Print Request

Use a print request when the ECR needs the terminal printer to print arbitrary text or structured print data outside the normal receipt callback flow.

.NET

csharp
var request = new PrintRequest(data, PrintResponseMode.PrintEnd, printOutputFormat);
ApiResult result = epas.Print(request, out PrintResponse response);

Java

java
Pair<ApiDefinitions.ApiResult, PrintResponse> result =
    epas.requestPrint(data, outputFormat);

Swift

swift
let request: PrintRequest = buildPrintRequest()
let response = try await client.requestPrint(request)

Abort

Abort requests are best-effort. The terminal may already be at a stage where abort is impossible, so the ECR must still process the final response, receipts, and callbacks.

.NET

csharp
ApiResult result = epas.RequestTransactionAbort();

Java

java
ApiDefinitions.ApiResult result = epas.requestTransactionAbort();

Swift

swift
try await client.abort()

Transaction Response

FieldMeaning
ApprovedWhether the payment was approved.
Transaction referenceReference used for reporting, receipt matching, and reversals.
Final amountApproved final amount, including applicable tip, cashback, or charges.
Error conditionTerminal or library error condition when the transaction was not approved. See ErrorConditions / ErrorCondition.
Additional informationExtra terminal text about the outcome.

.NET

csharp
void HandleTransactionResponse(TransactionResponse response)
{
    if (response.Approved)
    {
        completeSale(response.TransactionReference, response.FinalAmount);
    }
    else
    {
        showDecline(response.ErrorCondition, response.AdditionalInformation);
    }
}

Java

java
void handleTransactionResponse(TransactionResponse response) {
    if (response.isApproved()) {
        completeSale(response.getTransactionReference(), response.getFinalAmount());
    } else {
        showDecline(response.toString());
    }
}

Swift

swift
func handleTransactionResponse(_ response: TransactionResponse) {
    if response.approved {
        completeSale(response.transactionReference, response.finalAmount)
    } else {
        showDecline(response.errorCondition, response.additionalInformation)
    }
}