Preauth

A preauthorization places a hold on the cardholder's funds without capturing. Use it when the final amount may change (e.g., tips, adjustments, custom surcharging).

Prerequisites

  • Authenticated merchant with login()
  • Active location set via setActiveLocationID()
  • Card reader prepared with prepare() (iOS) or device enrolled (Android)

Basic Preauth

iOS:

let breakdown = PaymentBreakdown(
    subtotal: 10000,
    taxRate: 0.0875,
    taxAmount: 875,
    tipType: .fixed
)

let currency = CurrencyCode(currencyCode: "USD", displayName: "US Dollar")

let response = try await KoardMerchantSDK.shared.preauth(
    amount: 10875,
    breakdown: breakdown,
    currency: currency,
    eventId: UUID().uuidString
)
let transactionId = response.transactionId!

Android:

val breakdown = PaymentBreakdown(
    subtotal = 10000,
    taxRate = 0.0875,
    taxAmount = 875,
    tipType = "fixed"
)

sdk.preauth(
    activity = this,
    amount = 10875,
    breakdown = breakdown,
    eventId = UUID.randomUUID().toString()
).collect { event ->
    when (event.actionStatus) {
        ActionStatus.OnComplete -> {
            val txn = event.response?.transaction
            println("Preauth hold placed: ${txn?.transactionId}")
        }
        ActionStatus.OnConfirmSurcharge -> {
            val txn = event.response?.transaction
            sdk.confirm(
                transactionId = txn?.transactionId ?: "",
                confirm = true
            )
        }
        ActionStatus.OnFailure -> {
            println("Preauth failed: ${event.response?.message}")
        }
        else -> { /* reader progress */ }
    }
}

Preauth with Surcharge Bypass

To calculate surcharges yourself (e.g., BIN-based logic), bypass the processor's automatic surcharge:

iOS:

let breakdown = PaymentBreakdown(
    subtotal: 10000,
    taxRate: 0.0875,
    taxAmount: 875,
    tipAmount: 2000,
    tipType: .fixed,
    surcharge: PaymentBreakdown.Surcharge(bypass: true)
)

let response = try await KoardMerchantSDK.shared.preauth(
    amount: 12875,       // subtotal + tax + tip (no surcharge yet)
    breakdown: breakdown,
    currency: currency,
    eventId: UUID().uuidString
)

Android:

val breakdown = PaymentBreakdown(
    subtotal = 10000,
    taxRate = 0.0875,
    taxAmount = 875,
    tipAmount = 2000,
    tipType = "fixed",
    surcharge = Surcharge(bypass = true)
)

sdk.preauth(
    activity = this,
    amount = 12875,
    breakdown = breakdown,
    eventId = UUID.randomUUID().toString()
).collect { /* handle response */ }

After the preauth completes, use the BIN from the response to calculate a custom surcharge, then apply it via incremental auth. See the BIN-based surcharging workflow for the full flow.

Parameters

Parameter Type Required Description
amount Int Yes Hold amount in minor units (cents)
breakdown PaymentBreakdown? No Itemized breakdown
currency CurrencyCode Yes (iOS) Currency for the transaction
eventId String? No Idempotency key (UUID recommended)
activity Activity Yes (Android) Android activity for NFC access

After Preauth

A preauth hold must be followed by one of:

Action Description
Capture Finalize at the same or lower amount
Incremental Auth Increase the hold (e.g., add surcharge)
Tip Adjust Update the tip before capture
Reverse Void the hold entirely

See Also

  • Sale — One-step authorize + capture
  • Capture — Finalize a preauth
  • Surcharging — Bypass and custom surcharge workflows