Search

Are you looking for test card numbers?

Would you like to contact support?

Point-of-sale icon

Handle errors

Learn how to resolve Terminal API errors and handle declined payments.

To be able to resolve issues with your requests, you need to know how Terminal API informs you of the processing status of your request. This is communicated in the Response object of the API response, which has:

  • Result: One of the following values:

    • Success: The request succeeded / the transaction was approved.
    • Partial: The transaction amount has been partially approved.
    • Failure: The request or transaction didn't succeed. The remaining Response fields provide more information about the error, to enable you to determine how to handle it.

  • ErrorCondition: This field is included when the request or transaction fails, and indicates the cause of the failure.

  • AdditionalResponse: More information about the error condition. You'll receive either a string of form-encoded key-value pairs or a Base64 string that you need to decode to get a JSON object.

Now let's see what you can do when:

  • The request failed because it was invalid.
  • You made a payment request but didn't receive a result.
  • The result of your payment request indicates the transaction failed.

Invalid message format

A Response object with Result Failure and ErrorCondition MessageFormat indicates there was a mistake in the request you sent. Proceed as follows:

  1. Determine what caused the error, based on the message, warnings, or errors in the AdditionalResponse. For example, a missing required field or an unexpected field.

    The following example is for a response indicating that the Currency field is missing from the payment request:

    {
    ...
       "Response":{
          "Result":"Failure",
          "AdditionalResponse": "errors=At%20SaleToPOIRequest.PaymentRequest.PaymentTransaction.AmountsReq%2c%20field%20Currency%3a%20Missing",
          "ErrorCondition":"MessageFormat"
       }
    ...
    }
  2. Refer to the Terminal API reference if necessary, then manually fix your request and try again.

Invalid JSON format

If your API request does not contain a valid JSON object, you receive a Bad JSON HTTP reply that specifies the line number and a description of the issue:

["Bad JSON:LINE_NUMBER: DESCRIPTION"]
  • Manually fix the JSON error on the line mentioned in the HTTP reply and try again.

Unavailable service

A Response object with Result Failure and ErrorCondition UnavailableService indicates we were unable to implement your request. Proceed as follows:

  1. Determine what caused the error, based on the message, warnings, or errors in the AdditionalResponse. For example:

    • You tried to use functionality that the payment terminal doesn't support.
    • You tried to use a ProtocolVersion that the terminal can't manage.
    • You tried to use functionality that we don't support.

    The following example is for a response indicating that there's a mismatch between the protocol versions (2.0 in the request and 3.0 on the terminal):

    {
    ...
       "Response": {
          "Result": "Failure",
          "AdditionalResponse": "message=Sale%20Protocol%20Version%202.0%20mismatch%2c%20Version%20implemented%3a%203.0",
          "ErrorCondition": "UnavailableService"
       }
    ...
    }
  2. Depending on the cause of the error, manually fix your request and send it again. For example, after receiving the above failure response you'd specify the same protocol version that the terminal supports.

No result received

We recommend that your integration automatically requests the status of a transaction, any time it fails to receive a transaction response.
Payment requests time out after 120 seconds. If you do not receive a payment response (or you receive a response indicating a time-out) after 120 seconds, and the network connection hasn't dropped, your integration should automatically request the transaction status.

If you do not receive a transaction result, neither synchronously nor asynchronously, proceed as follows:

  1. Make a TransactionStatusRequest (see Verify transaction status for details).

  2. Determine your next action based on the TransactionStatusResponse.Response:

    Response Description Action
    Result Success The transaction was processed. Use the RepeatedResponseMessageBody to determine how to process the transaction.
    ErrorCondition InProgress The payment terminal is waiting for a response from the shopper, or there is a delay with the card issuer. Continue making a transaction status request for this transaction every five seconds until you receive a response indicating the transaction was processed.
    ErrorCondition NotFound Possible causes:
    • The details you specified in the transaction status request are incorrect.
    • We did not receive your request; maybe your connection dropped after sending the request.
    Possible actions:
    • Provide the details of the original transaction in the MessageReference of your transaction status request.
    • Retry the original transaction.

Terminal unavailable (cloud integration)

When you send a PaymentRequest to a payment terminal that is unavailable, the payment can't be processed. In a cloud integration, the Terminal API generates a Reject event notification.

Note that event notifications are always presented as a SaleToPOIRequest.

The EventNotification body contains:

  • RejectedMessage: A Base64 string containing the payment request that couldn't be processed. Decode this to get the original payment request as a JSON object.
  • EventToNotify: Reject
  • EventDetails: A message indicating why the payment terminal is unavailable.

Here's an example event notification for an unavailable payment terminal in a cloud integration:

{
   "SaleToPOIRequest": {
      "EventNotification": {
         "EventToNotify": "Reject",
         "EventDetails": "message=Did+not+receive+a+response+from+the+POI.",
         "RejectedMessage": "ewoi...0KfQo=",
         "TimeStamp": "2020-03-31T10:28:39.515Z"
      },
      "MessageHeader": {
         "DeviceID": "666568147",
         "MessageCategory": "Event",
         "MessageClass": "Event",
         "MessageType": "Notification",
         "POIID": "P400Plus-123456789",
         "ProtocolVersion": "3.0",
         "SaleID": "saleid-4c32759faaa7",
         "ServiceID": "31122609"
      }
   }
}

The steps that you can take, relate to the EventDetails message you receive:

Did not receive a response

"message=Did+not+receive+a+response+from+the+POI."

This message indicates that the request was sent but the payment terminal didn't respond, possibly because the websocket is down at the terminal.

Failed to send message

"message=Failed+to+send+message+to+POI.+There+may+be+a+network+issue+or+it+may+not+have+the+websocket+connected."

This message indicates that probably the websocket for the payment terminal is not available on the Terminal Cloud API router.

  • On the payment terminal, check the websocket connection:

    • On the display, there should be a cloud icon in the top row.
    • Open the Admin menu (press 9 and then the Confirm button and enter the Admin PIN or refer to the instructions for your payment terminal model) and select Network > Diagnostics > Terminal API. The websocket items should have a green check mark.

Unknown POIID

"message=Unknown+POIID+P400Plus-123456789"

This message indicates that the terminal ID (POIID) in the payment request is incorrect, or that the terminal is in the inventory of the Company account and hasn't been assigned to a merchant account or store that allows processing payments.

  1. On the payment terminal, open the terminal information (press 5 and then the Confirm button or refer to the instructions for your payment terminal model) and verify that the terminal ID in the format [device model]-[serial number] matches the POIID that you specified in the payment request. For example, P400Plus-123456789.
    If the POIID matches, go to the next step.
  2. Verify that the payment terminal is assigned to a merchant account or store. You can do this with the connectedTerminals API or in your Customer Area.

Declined payment

When a PaymentRequest results in a Response object with Result Failure and one of the error conditions listed below, the transaction was declined. The AdditionalResponse has more information about why the transaction was declined:

  • refusalReason: Our mapping of the raw response we receive from acquirers and issuers, to explain why the transaction failed.
  • message: Our mapping of the response code we receive from acquirers and issuers.

    Here's an example failure response for a declined payment:

    {
    ...
       "Response": {
          "Result": "Failure",
          "AdditionalResponse": "refusalReason=214%Declined%20online...&message=CANCELLED...",
          "ErrorCondition": "Refusal"
       }
    ...
    }

When your payment request is declined, you need to determine whether you can retry it:

  1. Check the ErrorCondition in the PaymentResponse.Response, because in many cases this already indicates whether you can retry the transaction.

    Error condition Retry?
    Aborted -white_check_mark-
    Busy See next step
    Cancel See next step
    DeviceOut -white_check_mark-
    InvalidCard See next step
    NotAllowed -x-
    Refusal See next step
    UnreachableHost -white_check_mark-
    WrongPIN -white_check_mark-
  2. For the error conditions Cancel, InvalidCard, and Refusal, check the AdditionalResponse for the refusalReason and message. For the error condition Busy, check the response for a serviceId.

    You can use the ErrorCondition to code your cash register software. The refusalReason and Message fields are included for additional insight, and should not be coded against.
    The serviceId can be used by the cash register to cancel a transaction.

    Select the tabs for details.

    ErrorCondition refusalReason message Retry?
    Cancel Approved APPROVED -x-
    Cancel (all other refusalReasons) (all other messages) -white_check_mark-
    ErrorCondition serviceId message Retry?
    Busy 1234567890 Forbidden Request, Service Dialogue PaymentRequest is in Progress -x-
    Busy ADMIN_MENU -x-
    Busy (all other messages) -x-

    Using the serviceId you can make an AbortRequest to cancel the in-progress transaction that the terminal is busy with.

    ErrorCondition refusalReason message Retry?
    InvalidCard Card data authentication failed DECLINED -x-
    InvalidCard No checking account available on Card NO_CHECKING_ACCOUNT_AVAILABLE_ON_CARD -white_check_mark-
    InvalidCard No savings account available on Card NO_SAVINGS_ACCOUNT_AVAILABLE_ON_CARD -white_check_mark-
    ErrorCondition refusalReason message Retry?
    Refusal CVC Declined CVC_DECLINED -white_check_mark-
    Refusal Refused DECLINED -white_check_mark-
    Refusal Declined Non Generic DECLINED -white_check_mark-
    Refusal Acquirer Error ERROR -white_check_mark-
    Refusal Expired Card CARD_EXPIRED -white_check_mark-
    Refusal Issuer Suspected Fraud ISSUER_SUSPECTED_FRAUD -x-
    Refusal Not enough balance NOT_ENOUGH_BALANCE -white_check_mark-
    Refusal Not Submitted NOT_SUBMITTED -white_check_mark-
    Refusal Not supported NOT_SUPPORTED -white_check_mark-
    Refusal Pin tries exceeded PIN_TRIES_EXCEEDED -white_check_mark-
    Refusal Pin validation not possible PIN_VALIDATION_NOT_POSSIBLE -x-
    Refusal Restricted Card RESTRICTED_CARD -x-
    Refusal Withdrawal count exceeded WITHDRAWAL_COUNT_EXCEEDED -white_check_mark-
    Refusal Withdrawal amount exceeded WITHDRAWAL_AMOUNT_EXCEEDED -white_check_mark-
    Refusal Transaction Not Permitted TRANSACTION_NOT_PERMITTED -white_check_mark-
    Refusal Always refused DECLINED -x-
    Refusal Amount too low to be accepted by Card Network DECLINED -x-
    Refusal Card is blocked BLOCK_CARD -x-
    Refusal declined DECLINED -white_check_mark-
    Refusal Timeout waiting for card after contactless fallback CONTACTLESS_FALLBACK -white_check_mark-
    Refusal Card requires online pin PIN_REQUIRED -white_check_mark-
    Refusal Mobile PIN required MOBILE_PIN_REQUIRED -white_check_mark-

    For more information, see our reference documentation for refusal reasons. If you enabled receiving the refusalReasonRaw field in the AdditionalResponse, also see our reference documentation for raw acquirer responses.

    The refusalReasonRaw provides additional information. But if you base your code on it, that might break your integration because acquirers and issuers sometimes change their raw responses without notification.

  3. If applicable, retry the transaction.

Error condition comparison

The table below compares error conditions and troubleshooting steps specific to making a PaymentRequest, TransactionStatusRequest, or ReversalRequest (a referenced refund).

Error condition PaymentRequest TransactionStatusRequest ReversalRequest
Aborted  See Declined payment not applicable Optionally retry
Cancel See Declined payment not applicable not applicable
DeviceOut See Declined payment Wait and retry Wait and retry
InProgress not applicable See No result received not applicable
InvalidCard See Declined payment not applicable not applicable
Invalid message format
NotAllowed See Declined payment Wait and retry Wait and retry or Retry different device
NotFound Manual recovery See No result received Manual recovery
Refusal See Declined payment not applicable Manual recovery
Unavailable service
UnreachableHost See Declined payment Retry Retry
WrongPIN See Declined payment not applicable not applicable

See also