Skip to content
English
  • There are no suggestions because the search field is empty.

Advanced Error Handling and Duplicate Prevention

Guidelines for managing transactions when an Approval, Declined, or Cancellation response is not received.

Due to potential factors like local Wi-Fi instability, network latency, or service disruptions, you might occasionally receive a response that isn't a standard approval, decline, or cancellation.

This page covers two methods for preventing duplicates and handling errors. 

Error Handling and Duplicate Prevention

Overview

When processing transactions, your integration should be prepared for rare scenarios where an expected Approved, Declined, or Cancelled response isn’t returned.
This can occur due to local Wi-Fi instability, network latency, or brief service interruptions.

Zift provides multiple mechanisms to help you safely determine the truth of a transaction and avoid duplicates.

How Zift Handles Transaction Errors

In most cases, your system receives a final Approved, Declined, or Cancelled response from the Zift API. If a network issue or timeout occurs, however, your integration may receive an error or no response at all. In these cases, never assume the transaction failed. Instead, verify whether Zift received and processed the original request.

You can do this by using the transactionCode field, which allows you to look up the status of the original transaction, even if your software never received the transactionId.

Transaction Lookup - Find the Truth

To facilitate transaction tracking—particularly in the event of a network error—your system should include external identifying fields in each API sale request. These identifiers enable you to query our servers, prevent duplicates, and reconcile transactions reliably within your system. 

The primary handle for a transaction is the transactionId, a unique value generated by Zift for each transaction. This ID can be used to retrieve transaction status and details. However, if an error occurs before the transactionId is returned, you will not be able to query using this value.

To address this, we strongly recommend including a unique external identifier from your system in the transactionCode field with each sale request. If you receive an error response you can then make a find request using your original transactionCode to look for the transaction in our system and confirm its status. 

Transaction Lookup Using  transactionCode

When your software includes a unique transactionCode with each sale request, you can use this value to search for the transaction in the Zift system.

Here's an example of a transaction find request using the transactionCode to lookup the transaction. See the full documentation for this request here

{
  "method": "POST",
  "url": "https://sandbox-portal.zift.io/gates/xurl",
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "body": {
    "requestType": "find",
    "userName": "{api-user}",
    "password": "{api-pass}",
    "accountId": "2222001",
    "transactionCode": "8a3T54333-12jat35t"
  }
}

What To Do If a Transaction is Found

You can verify the transaction status in the responseCode and/or responseMessage fields and treat it as if the response had been returned on the original request. To prevent duplicate transactions, if the response message is an Approval, you should treat the transaction as such and not run a subsequent transaction. We recommend implementing this business logic before presenting any results back to the user/customer.

What To Do If a Transaction is Not Found

Your software can treat the transaction request as incomplete. A new sale request can be attempted to complete the transaction with the cardholder.

Transaction-level Idempotency

A request is idempotent if sending it multiple times has the same effect as sending it once.
That means retries — whether intentional or caused by network issues — don’t change the end result or create duplicates.

The transactionCode identifies the transaction from your system and is stored on the Zift transaction record. By default, this field is not unique, but you can leverage transaction level idempotency by enabling uniqueness enforcement to automatically block duplicate requests.

Please contact support to set the transactionCode uniqueness policy on the account.

Zift implements transaction-level idempotency using the transactionCode field when uniqueness is enforced. The transactionCode is stored on the transaction record itself and can be searched or enforced as unique (via account configuration).

When idempotency is leveraged and uniqueness is enabled:

  • Zift accepts the first transaction and creates a record.
  • If another sale arrives with the same transactionCode + accountId, the system returns a V29 (“duplicate transaction”) or, for card-not-present transactions, returns the original result. 

This ensures that repeating the same request — for example, after a timeout — has the same outcome as the original attempt, preventing accidental duplicate charges.

For best practices, if you receive a V29 ("duplicate transaction") under any attempt to process a transaction use the Transaction Lookup process to find the truth of the original transaction. 

Summary

By leveraging the transactionCode field you can query the truth when needed.
You can enforce idempotency to prevent duplicates automatically.
And you can rely on a single field—transactionCode—to power both.

With idempotency leveraged through uniqeness on the transactionCode field any transaction is queryable and auditable and you can benefit from a permanent dedupe solution that lasts beyond 24h and across retries or even systems.

 


References

- Zift API Docs: https://api.zift.io/
- Cloud Sale Reference: https://api.zift.io/#cloudSale
- Find Transaction Reference: https://api.zift.io/#find
- HTTP Codes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status