Checkouts
Checkouts redirect your customer to Vatly's hosted payment page. After payment, the customer is redirected back to your application.
Creating a checkout
$checkout = $user->checkout()->create(
items: [['id' => 'product_abc123', 'quantity' => 1]],
redirectUrlSuccess: 'https://your-app.com/success',
redirectUrlCanceled: 'https://your-app.com/canceled',
);
return redirect($checkout->links->checkoutUrl->href);
$checkout is a Vatly\API\Resources\Checkout — see vatly-api-php for the full resource shape.
Subscription checkouts
For subscriptions, use the subscribe() builder. Redirect URLs default to those in config/vatly.php so the call can be just one line:
$checkout = $user->subscribe()
->toPlan('subscription_plan_monthly')
->create();
return redirect($checkout->links->checkoutUrl->href);
Checkout with metadata
$checkout = $user->checkout()
->withMetadata(['campaign' => 'summer-2025'])
->create(
items: [['id' => 'product_abc123', 'quantity' => 1]],
redirectUrlSuccess: 'https://your-app.com/success',
redirectUrlCanceled: 'https://your-app.com/canceled',
);
Checkout language (locale)
Set locale to present the hosted checkout — including its validation and error messages — in the customer's language. Do this when you already know their language: it is a better signal than their browser's, and it carries through to the payment provider's own hosted page.
create() takes a fourth argument, payloadOverrides, that is merged into the checkout payload, so pass locale there:
$checkout = $user->checkout()->create(
items: [['id' => 'product_abc123', 'quantity' => 1]],
redirectUrlSuccess: 'https://your-app.com/success',
redirectUrlCanceled: 'https://your-app.com/canceled',
payloadOverrides: ['locale' => 'de'],
);
For the subscription flow, subscribe()->create() takes the same overrides:
$checkout = $user->subscribe()
->toPlan('subscription_plan_monthly')
->create(['locale' => 'de']);
Send a bare language code (de), a BCP 47 tag (de-AT), or a POSIX / ISO 15897 locale (de_DE) — whichever your stack already stores. All three fold to the language, so de, de-AT and de_DE are the same request; there are no region-specific variants. Leave locale unset to let Vatly fall back to the customer's browser language.
How it works
The checkout flow:
- Your app creates a checkout session via the Vatly API (customer is created automatically if needed)
- The customer is redirected to Vatly's hosted payment page
- After payment, the customer returns to your
redirectUrlSuccess - Vatly sends a webhook to confirm the payment (see Webhooks)
- If this was a new customer, the customer ID is synced to your local database via webhook
The redirect URLs default to the values in your vatly.php config but can be overridden per checkout.