Errors
Every failure is a CallCashError:
TypeScript
import { isCallCashError } from "callcash";
try {
await cash.payments.create({ amount, reference });
} catch (e) {
if (isCallCashError(e)) {
e.code; // "amount_invalid"
e.status; // 422
e.message; // says what went wrong and what to do
e.retryable; // true when nothing was charged and trying again is safe
}
throw e;
}Retry only when retryable is true. Messages are written for developers; show your customers your own words.
Codes#
| Code | Status | Retry | When | What to do |
|---|---|---|---|---|
amount_invalid | 422 | No | amount is not rand above 0 with at most two decimals, or is over R9,999,999.99 | Send rand, like 250 or 99.50. If you store cents, divide by 100. |
reference_invalid | 422 | No | reference is empty or longer than 100 characters | Use your own order number. |
reference_used | 409 | No | The reference was already paid, or is open for a different amount | Use a new reference, or read the existing payment. |
gateway_down | 503 | Yes | A gateway did not answer: network error, a 15 second timeout, a 5xx or 429, or Netcash's status check failed | Retry. Routing already tried your backup gateway. In a webhook, the 503 makes the gateway retry. |
gateway_rejected | 502 | No | Yoco refused to open a checkout or a refund | Read the message, which includes Yoco's answer. The payment is left failed. |
signature_invalid | 400 | No | A Yoco event's signature did not match, it was over three minutes old, or it was not JSON | Check webhookSecret is the secret for this webhook. Check your server clock. |
not_found | 404 | No | There is no payment with that id | Check the id. |
refund_invalid | 400 | No | The payment is not paid, is fully refunded, or you asked for more than is left | Refund only what is left. |
refund_unsupported | 400 | No | Netcash payments, or Yoco payments made with test keys | Netcash: refund in the portal, then recordRefund(). |
config_invalid | 500 | No | The setup is wrong: see below | Fix the config. |
api_error | varies | When 5xx | The hosted API (planned) answered without a code; also the body of a webhook response when the request could not be read or the store failed | Retry when the status is 5xx. |
gateway_limit | 402 | No | Declared for a gateway's transaction limit. Not thrown by version 0.1.0. | Netcash's R100 limit shows as a missing card option, not an error. See Netcash. |
config_invalid, in detail#
- Real gateways without a
store. - Both
keyandgatewaysgiven. - A gateway named in
routesorgatewaythat is not ingateways. - An empty Yoco
secretKeyor NetcashserviceKey. - A Yoco payment with no
returnUrlorreturn_url. - A Yoco event arriving with no
webhookSecretconfigured. cash.test.pay()on a payment that is not on the test gateway.- A
cc_key that does not start withcc_test_orcc_live_. - Calling a hosted-only method (
webhooks.delete) without a key, or a direct-only method (webhooks.handle,recordRefund,events.deliver,test.*) with one.
handler_failed#
Not a thrown error. It is the code in the 500 response webhooks.handle gives the gateway when your handler throws. The event stays owed and is delivered again.