Skip to main content

Errors and testing

Two things on this page:

  • How Payment Platform reports errors back to you, and
  • The test cards you use in your sandbox envoronment to exercise every payment outcome.

For the complete error reference (every code, every message, with cause and fix) see the API error reference. For symptom-cause-fix breakdowns of common failures, see the troubleshooting page.

info

Remember that there are no common URLs in our Sandbox test, the URLs will vary depending on your environment lifecycle.

Errors

When Payment Platform rejects a request, the synchronous response carries:

ParameterDescription
resultERROR
error_codeNumeric code identifying the error class
error_messageHuman-readable explanation of what went wrong
errorsArray of per-field validation errors (present when error_code is 100000)

Most common error codes on S2S CARD

This list covers the codes you are most likely to hit during integration. The API error reference carries the full catalogue; the troubleshooting page has symptom-cause-fix breakdowns for the most common ones.

CodeWhere it firesMeaning
100000Request validationGeneric validation failure. The errors array carries the per-field reasons. Also used for Hash is not valid and several not-found cases (see below).
101000Status lookup, CAPTURE (post 6.7.0)Specific not-found code introduced by Changelog for transaction and order entities. Messages include Transaction does not exist. and Order does not exist.
204002RoutingEnabled merchant mappings or MIDs not found.
204005RoutingPayment action not supported by the MID.
204006RoutingPayment system / brand not supported.
204007RoutingDay MID limit not set or exceeded.
204014RoutingMonth MID limit exceeded.
204015RoutingWeek merchant mapping limit exceeded.
205005Card tokenCard token is invalid or not found.
205006Card tokenCard token is expired.
205007Card tokenCard token is not accessible.
208003Payment flowCapture requested on a payment not in pending status.
208005Payment flowRefund requested on a payment not in settled status.
220002CredentialsLive merchant key used against the sandbox. Use the test key.

For the per-entity rule that decides between 100000 and 101000 on not-found responses (it depends on which action you called), see the troubleshooting page's not-found section.

Example validation failure

A typical 100000 response with the errors array filled in:

Sample error response
{
"result": "ERROR",
"error_code": 100000,
"error_message": "Request data is invalid.",
"errors": [
{ "error_code": 100000, "error_message": "card_number: This value should not be blank." },
{ "error_code": 100000, "error_message": "card_exp_month: This value should not be blank." },
{ "error_code": 100000, "error_message": "card_exp_year: This value should not be blank." },
{ "error_code": 100000, "error_message": "card_cvv2: This value should not be blank." },
{ "error_code": 100000, "error_message": "order_id: This value should not be blank." },
{ "error_code": 100000, "error_message": "order_amount: This value should not be blank." },
{ "error_code": 100000, "error_message": "order_currency: This value should not be blank." },
{ "error_code": 100000, "error_message": "order_description: This value should not be blank." },
{ "error_code": 100000, "error_message": "term_url_3ds: This value should not be blank." }
]
}
Payer fields are configurable since 6.7.0

payer_address, payer_country, payer_city, payer_zip are no longer required at the API layer by default. They are enforced only when the Protocol Mapping setting is set to Required. See Changelog.

Testing

The sandbox accepts the test cards below. Every transaction runs through a Test engine, so no real money moves and no real acquirer call is made.

Card numberCard expiration date (MM / YYYY)Result
411111111111111101/2038Successful sale. Also the card you use for recurring payments to get a recurring token on the initial sale; other test cards do not support recurring.
SALE: {action: SALE, result: SUCCESS, status: SETTLED}
AUTH: {action: SALE, result: SUCCESS, status: PENDING}
411111111111111102/2038Declined sale.
SALE: {action: SALE, result: DECLINED, status: DECLINED}
AUTH: {action: SALE, result: DECLINED, status: DECLINED}
411111111111111103/2038Successful AUTH then declined CAPTURE.
AUTH: {action: SALE, result: SUCCESS, status: PENDING}
CAPTURE: {action: CAPTURE, result: DECLINED, status: PENDING}
411111111111111105/2038Successful sale after 3DS verification.
Initial: {action: SALE, result: REDIRECT, status: 3DS}
After ACS return: {action: SALE, result: SUCCESS, status: SETTLED}
411111111111111106/2038Declined sale after 3DS verification.
Initial: {action: SALE, result: REDIRECT, status: 3DS}
After ACS return: {action: SALE, result: DECLINED, status: DECLINED}
411111111111111112/2038Successful sale after redirect.
Initial: {action: SALE, result: REDIRECT, status: REDIRECT}
After return: {action: SALE, result: SUCCESS, status: SETTLED}
411111111111111112/2039Declined sale after redirect.
Initial: {action: SALE, result: REDIRECT, status: REDIRECT}
After return: {action: SALE, result: DECLINED, status: DECLINED}
4601541833776519not applicableSuccessful CREDIT2CARD.
Response: {action: CREDIT2CARD, result: SUCCESS, status: SETTLED}

A minimal credential-verification call

The fastest sanity check that your credentials and hash recipe are wired up correctly is a GET_TRANS_STATUS call against a deliberately bogus trans_id. If everything is right you get back the structured not-found error code, which confirms Payment Platform accepted your signature.

TRANS_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')

CONCAT="${TRANS_ID}${password}"
UPPER=$(printf "%s" "$CONCAT" | tr '[:lower:]' '[:upper:]')
MD5=$(printf "%s" "$UPPER" | md5) # use "md5sum | awk '{print $1}'" on Linux
HASH=$(printf "%s" "$MD5" | shasum -a 1 | awk '{print $1}')

curl -ksS -X POST "$PAYMENT_URL/post" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "action=GET_TRANS_STATUS&client_key=$MERCHANT_TEST_KEY&trans_id=$TRANS_ID&hash=$HASH"

Expected response on a correctly-configured account:

{ "result": "ERROR", "error_code": 101000, "error_message": "Transaction does not exist." }

If you get 100000 + Hash is not valid instead, double-check the password and the hash inputs. See the troubleshooting page for the five most common hash-recipe mistakes.

What's next