Prerequisites: Authentication · Run a sale
If a merchant starts a sale by mistake, or a customer changes their mind before they tap their card, you can cancel the sale while it's still in progress. To cancel a sale, call cancelTransaction on WTPSTerminal.
You can't cancel a sale after our gateway starts to authorize the sale. To return funds after a sale, go to Run a refund.
Integration steps
Step 1. Cancel the sale
- Call
cancelTransactionwhile the sale is in progress.
Swift
terminal.cancelTransaction()
Objective-C
[[WTPSTerminal singleton] cancelTransaction];
The SDK returns the outcome to onCancelTransactionAttempt:withError: on your CoreAPISaleListener. You registered this listener in Run a sale, so you don't need to register another listener.
Step 2. Handle the cancellation status
The SDK sends a TransactionCancellationStatus value to onCancelTransactionAttempt:withError:. The value indicates whether the SDK canceled the sale:
| Value | Description |
|---|---|
TRANSACTION_CANCELLATION_STATUS_CANCELLING | The SDK is canceling the transaction. Wait for the SDK to confirm the outcome. |
TRANSACTION_CANCELLATION_STATUS_CANCELLED | The SDK canceled the transaction. |
TRANSACTION_CANCELLATION_STATUS_NOT_ALLOWED | The SDK can't cancel the transaction, for example, because our gateway is authorizing the sale. |
TRANSACTION_CANCELLATION_STATUS_NOTHING_TO_CANCEL | There was no transaction to cancel. |
Important: TRANSACTION_CANCELLATION_STATUS_CANCELLING means that the SDK accepted your request, not that it canceled the sale. Wait for TRANSACTION_CANCELLATION_STATUS_CANCELLED before your app tells the merchant that the SDK canceled the sale.
The following example handles each cancellation status and enables or disables a payment button:
Swift
func onCancelTransactionAttempt(_ cancellationStatus: TransactionCancellationStatus,
withError sdkError: CoreSdkErrorWrapper?) {
switch cancellationStatus {
case TRANSACTION_CANCELLATION_STATUS_CANCELLING:
// The SDK is canceling the transaction. Wait for the outcome.
confirmButton.isEnabled = false
case TRANSACTION_CANCELLATION_STATUS_CANCELLED:
// The SDK canceled the transaction. You can start another sale.
confirmButton.isEnabled = true
case TRANSACTION_CANCELLATION_STATUS_NOT_ALLOWED:
// It's too late to cancel. Wait for onSaleResponse:.
confirmButton.isEnabled = true
case TRANSACTION_CANCELLATION_STATUS_NOTHING_TO_CANCEL:
// No transaction was in progress.
confirmButton.isEnabled = true
default:
confirmButton.isEnabled = true
}
}
Objective-C
- (void)onCancelTransactionAttempt:(TransactionCancellationStatus)cancellationStatus
withError:(CoreSdkErrorWrapper *)sdkError {
switch (cancellationStatus) {
case TRANSACTION_CANCELLATION_STATUS_CANCELLING:
// The SDK is canceling the transaction. Wait for the outcome.
_confirmButton.enabled = NO;
break;
case TRANSACTION_CANCELLATION_STATUS_CANCELLED:
// The SDK canceled the transaction. You can start another sale.
_confirmButton.enabled = YES;
break;
case TRANSACTION_CANCELLATION_STATUS_NOT_ALLOWED:
// It's too late to cancel. Wait for onSaleResponse:.
_confirmButton.enabled = YES;
break;
case TRANSACTION_CANCELLATION_STATUS_NOTHING_TO_CANCEL:
// No transaction was in progress.
_confirmButton.enabled = YES;
break;
}
}
Find out why the SDK didn't cancel the sale
If the SDK returns TRANSACTION_CANCELLATION_STATUS_NOT_ALLOWED, it also sends a CoreSdkErrorWrapper that explains why. The wrapper has the following properties:
| Property | Description |
|---|---|
type | Type of error that the wrapper holds. The SDK returns one of the following error types: - SDK_CORE_DEVICE_ERROR indicates a CoreDeviceError value. - SDK_CORE_ERROR indicates a CoreError value. |
value | Value of the error as an NSNumber. Cast the value to the type that type indicates. |
If the SDK returns a CoreDeviceError, the value can be one of the following:
| Value | Description |
|---|---|
CANCELLATION_NOT_ALLOWED_TRANSACTION_STARTING | The sale is starting. |
CANCELLATION_NOT_ALLOWED_TRANSACTION_GOING_ONLINE | The sale is going to our gateway. |
The following example reads the error from the wrapper:
Swift
if let sdkError = sdkError {
switch sdkError.type {
case .SDK_CORE_DEVICE_ERROR:
let deviceError = CoreDeviceError(rawValue: sdkError.value.uint32Value)
// For example, CANCELLATION_NOT_ALLOWED_TRANSACTION_GOING_ONLINE
case .SDK_CORE_ERROR:
let coreError = CoreError(rawValue: sdkError.value.uint32Value)
}
}
Objective-C
if (sdkError != nil) {
if ([sdkError type] == SDK_CORE_DEVICE_ERROR) {
CoreDeviceError deviceError = (CoreDeviceError)[[sdkError value] integerValue];
// For example, CANCELLATION_NOT_ALLOWED_TRANSACTION_GOING_ONLINE
} else {
CoreError coreError = (CoreError)[[sdkError value] integerValue];
}
}