Skip to content
jovvie.com

Handle Jovvie PHP SDK errors

This page lists the exceptions the Jovvie SDKs throw and what your integration should do when it catches each one. Both SDKs use the same error classes. Only the namespace is different.

Class When it is thrown
BadRequestError Jovvie rejected the request as invalid (HTTP 400)
UnauthorizedError Jovvie did not accept your keys (HTTP 401)
ForbiddenError Your keys are valid but cannot do this (HTTP 403)
NotFoundError The payment, device, or other item was not found (HTTP 404)
ResponseError Any other error response from Jovvie. BadRequestError, UnauthorizedError, ForbiddenError, and NotFoundError extend it
WebhookError A webhook could not be verified or read
InvalidArgumentException The Stripe client was created with a mode other than 'live' or 'test', or in live mode with a platform provider ID that works in test mode only
Exception The request could not be completed, for example because of a network problem or a timeout

The namespaces are:

Stripe NMI
Request errors JovviePayments\Http\Error\ JovviePaymentsGateway\Http\Error\
Webhook errors JovviePayments\WebhookEvents\Error\ JovviePaymentsGateway\WebhookEvents\Error\

InvalidArgumentException and Exception are PHP’s built-in classes.

Catch the most specific classes first. Every request method can throw ResponseError or one of its subclasses, and also a plain Exception when the request does not complete.

use JovviePayments\Http\Error\BadRequestError;
use JovviePayments\Http\Error\NotFoundError;
use JovviePayments\Http\Error\ResponseError;
use JovviePayments\Http\Error\UnauthorizedError;
try {
$payment = $jovvie->payments()->get($jovviePaymentId);
} catch (NotFoundError $e) {
// The payment does not exist in this mode for this account.
} catch (UnauthorizedError $e) {
// Check the keys and platform provider ID. Alert an administrator.
} catch (BadRequestError $e) {
// Check the values you sent. Do not retry unchanged.
} catch (ResponseError $e) {
// Another error from Jovvie. See the "Read the error details" section.
} catch (\Exception $e) {
// Network problem or timeout. See the "When to try again" section.
}

ResponseError and its subclasses have two methods that help you find the cause:

  • $e->getCode() returns the HTTP status code, such as 400.
  • $e->getResponse()->getBody() returns the response body as an object. It usually has a code property with an error code, and an error or message property with a short description. The body can be null, so check it before you read it.
} catch (ResponseError $e) {
$body = $e->getResponse()->getBody();
$errorCode = is_object($body) && isset($body->code) ? $body->code : null;
yourApp_log('Jovvie request failed', [
'status' => $e->getCode(),
'code' => $errorCode,
]);
}

Exception messages can include technical details about the request. Log them on your server, but show staff a plain message instead, such as “We could not confirm whether the payment started. Check the reader and the payment processor before trying again, or contact your administrator.” Never show exception messages to customers.

Something in the request is not valid, or the merchant’s account is not ready. Do not retry the same request without changing it.

Error code What it means What to do
ERR_BAD_REQUEST A value is missing or not valid. For example, the amount is not a positive whole number, a URL is not a full URL, or the description is empty Check the values you send. If the message is Invalid platform provider, check your platform provider ID
ERR_INVALID_STRIPE_CONFIGURATION The merchant’s Stripe account is not connected Ask the merchant to connect Stripe in the Payments Dashboard
ERR_STRIPE_UNSUPPORTED_CURRENCY The currency is not supported for in-person payments on this Stripe account Use the currency of the merchant’s Stripe account
ERR_MISSING_NMI_ACCOUNT The merchant has no NMI account set up (NMI only) Ask the merchant to finish setting up NMI
ERR_DEVICE_NOT_FOUND The device ID you sent is not one of the merchant’s terminals (NMI only) List the merchant’s devices again and use a current device ID

Jovvie did not accept the request’s credentials. Check that:

  • The public key and secret key come from the same application, and you copied them in full.
  • The keys were not regenerated since you saved them.
  • The application is not disabled.
  • With Stripe, the platform provider ID is the one Jovvie support gave you, and the application is not already used by another integration.
  • Your server’s clock is set correctly.

Do not retry until you fix the cause. Alert an administrator instead of showing the error to staff.

Your keys work, but they cannot do what you asked. Common causes:

  • The keys belong to an application that is not a server application. Create one on the Applications page. See Get started.
  • You asked for a payment that belongs to a different merchant account.

The item does not exist for this account and mode. Check that:

  • You saved the correct payment ID when you created the payment.
  • You are using a client in the same mode as the payment. A test payment cannot be fetched with a live client, and a live payment cannot be fetched with a test client.

These include:

  • 429: too many requests.
  • 500 and higher: an error on Jovvie’s side.
  • Card errors, such as a declined card. Staff usually see these on the payment page instead. See Card declined and payment error messages.

Whether you can try again depends on the request. See When to try again.

The SDK throws WebhookError from WebhookEvent::constructEvent() when a webhook cannot be trusted or read. For example, the signature does not match your webhook key, the request is too old, or the body is not valid.

When you catch it:

  1. Respond with an HTTP error status, such as 400.
  2. Do not change any order.
  3. Log that it happened, without the request headers or your webhook key.

The SDK also throws WebhookError for an event type it does not know, and from an event’s getter methods when a field is missing from the event. See Handle webhooks.

The Stripe client throws InvalidArgumentException when you create it in two cases:

  • The mode is not valid. The client only accepts 'live' or 'test'. Check the mode setting in your integration.
  • The platform provider ID only works in test mode. This is why an integration can work in test mode and then fail as soon as you switch to live mode. Pass the platform provider ID that Jovvie support gave you. If you do not have one, contact Jovvie support to get it. Do not switch back to test mode to get around the error, because test mode does not take real payments.

See Install the SDK.

Only retry read-only requests automatically, such as payments()->get(), or devices()->list() and devices()->get() with NMI. Retry them after a 429, a status of 500 or higher, or a plain Exception. Wait before each attempt, wait longer after each one, and stop after a few attempts.

Never retry creating a payment automatically. If creating a payment fails with any error, including a status of 500 or higher or a plain Exception, a payment may still have started. Before anyone tries again:

  1. Check the card reader or terminal to see whether a payment is in progress or went through.
  2. Check the payment in the Stripe Dashboard or the NMI portal.
  3. If you are still not sure, contact Jovvie support.

Create a new payment only after you have confirmed that no payment for the order went through and none is still processing. With Stripe, only send staff to the checkout link of the payment you saved for the order.

Never retry a payment in a loop.

Errors that staff see on the Jovvie payment page are not thrown by the SDK. For those, see:

When you contact support, include the class name, the HTTP status, and the error code. Never send your keys.

Contact Jovvie support.