Skip to content
payrocdevelopers

Cancel a sale

Cancel an in-progress sale with the Tap to Pay on iPhone SDK, and handle the cancellation status that the SDK returns.

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

  1. Cancel the sale.
  2. Handle the cancellation status.

Step 1. Cancel the sale

  • Call cancelTransaction while the sale is in progress.

Swift

swift
terminal.cancelTransaction()

Objective-C

objectivec
[[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:

ValueDescription
TRANSACTION_CANCELLATION_STATUS_CANCELLINGThe SDK is canceling the transaction. Wait for the SDK to confirm the outcome.
TRANSACTION_CANCELLATION_STATUS_CANCELLEDThe SDK canceled the transaction.
TRANSACTION_CANCELLATION_STATUS_NOT_ALLOWEDThe SDK can't cancel the transaction, for example, because our gateway is authorizing the sale.
TRANSACTION_CANCELLATION_STATUS_NOTHING_TO_CANCELThere 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

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

objectivec
- (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:

PropertyDescription
typeType 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.
valueValue 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:

ValueDescription
CANCELLATION_NOT_ALLOWED_TRANSACTION_STARTINGThe sale is starting.
CANCELLATION_NOT_ALLOWED_TRANSACTION_GOING_ONLINEThe sale is going to our gateway.

The following example reads the error from the wrapper:

Swift

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

objectivec
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];
    }
}

Browse guides

Search documentation

API reference169
Guides118
Knowledge38
legal1
Solutions32
Workflows74
↑↓highlight↵openView all search results

Menu

Theme

Sign out

Your saved plans remain in your organization. This browser’s private draft and account view will be cleared.

Talk to an engineer