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:
-
Determine what caused the error, based on the
message
,warnings
, orerrors
in theAdditionalResponse
. 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" } ... }
- 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:
-
Determine what caused the error, based on the
message
,warnings
, orerrors
in theAdditionalResponse
. 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" } ... }
- 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:
-
Make a
TransactionStatusRequest
(see Verify transaction status for details). -
Determine your next action based on the
TransactionStatusResponse.Response
:Response Description Action Result
SuccessThe transaction was processed. Use the RepeatedResponseMessageBody
to determine how to process the transaction.ErrorCondition
InProgressThe 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
NotFoundPossible 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
: RejectEventDetails
: 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.
- Make a
TransactionStatusRequest
to verify whether the websocket connection was reestablished and the payment is now processed.
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 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.
- 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. - 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 in the refusalReason
and message
fields. These fields are our mapping of the response 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:
-
Check the
ErrorCondition
in thePaymentResponse.Response
, because in many cases this already indicates whether you can retry the transaction.Error condition Retry? Aborted Busy See next step Cancel See next step DeviceOut InvalidCard See next step NotAllowed Refusal See next step UnreachableHost WrongPIN -
For the error conditions Cancel, InvalidCard, and Refusal, check the
AdditionalResponse
for therefusalReason
andmessage
. For the error condition Busy, check the response for aserviceId
.You can use the
ErrorCondition
to code your cash register software. TherefusalReason
andMessage
fields are included for additional insight, and should not be coded against.
TheserviceId
can be used by the cash register to cancel a transaction.Select the tabs for details.
ErrorCondition refusalReason message Retry? Cancel Approved APPROVED Cancel (all other refusalReasons) (all other messages) ErrorCondition serviceId message Retry? Busy 1234567890 Forbidden Request, Service Dialogue PaymentRequest is in Progress Busy ADMIN_MENU Busy (all other messages) Using the
serviceId
you can make anAbortRequest
to cancel the in-progress transaction that the terminal is busy with.ErrorCondition refusalReason message Retry? InvalidCard Card data authentication failed DECLINED InvalidCard No checking account available on Card NO_CHECKING_ACCOUNT_AVAILABLE_ON_CARD InvalidCard No savings account available on Card NO_SAVINGS_ACCOUNT_AVAILABLE_ON_CARD ErrorCondition refusalReason message Retry? Refusal CVC Declined CVC_DECLINED Refusal Refused DECLINED Refusal Declined Non Generic DECLINED Refusal Acquirer Error ERROR Refusal Expired Card CARD_EXPIRED Refusal Issuer Suspected Fraud ISSUER_SUSPECTED_FRAUD Refusal Not enough balance NOT_ENOUGH_BALANCE Refusal Not Submitted NOT_SUBMITTED Refusal Not supported NOT_SUPPORTED Refusal Pin tries exceeded PIN_TRIES_EXCEEDED Refusal Pin validation not possible PIN_VALIDATION_NOT_POSSIBLE Refusal Restricted Card RESTRICTED_CARD Refusal Withdrawal count exceeded WITHDRAWAL_COUNT_EXCEEDED Refusal Withdrawal amount exceeded WITHDRAWAL_AMOUNT_EXCEEDED Refusal Transaction Not Permitted TRANSACTION_NOT_PERMITTED Refusal Always refused DECLINED Refusal Amount too low to be accepted by Card Network DECLINED Refusal Card is blocked BLOCK_CARD Refusal declined DECLINED Refusal Timeout waiting for card after contactless fallback CONTACTLESS_FALLBACK Refusal Card requires online pin PIN_REQUIRED Refusal Mobile PIN required MOBILE_PIN_REQUIRED For more information, see our reference documentation for refusal reasons. If you enabled receiving the
refusalReasonRaw
field in theAdditionalResponse
, 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. - 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 |