Configuration
This page covers the core configuration surface after installation. The core configuration lives under bnomei.klub.* in site/config/config.php. Provider-specific settings are namespaced under bnomei.klub.providers.{provider}.
Minimal configuration
You need a license key, an active provider handler, and the config block for that provider.
<?php
$provider = 'paddle'; // change to your provider key (stripe, mollie, lemonsqueezy, chargebee, polar, paypal, paddle)
$providerClass = \Bnomei\Klub\Provider\PaddleProvider::class;
return [
'bnomei.klub.license.key' => fn() => env('KLUB_LICENSE_KEY'),
'bnomei.klub.provider.handler' => $providerClass,
// Copy the required keys from the matching provider doc page:
// docs/providers/{provider}.md
'bnomei.klub.providers.' . $provider => [
// ...
],
];
Provider selection
bnomei.klub.provider.handlersets the active provider class (global).- Stripe is the default handler, but you should set
bnomei.klub.provider.handlerexplicitly to the provider you use. - Provider classes expose a static
$name; custom providers should set it to the provider key used inbnomei.klub.providers.{provider}. bnomei.klub.providers.{provider}.fieldsets the user field used to store provider data (defaults to the provider key).bnomei.klub.providers.{provider}.handlerregisters custom providers.
Provider credentials and setup details live in the Providers section.
Provider option keys
Use bnomei.klub.providers.{provider} with the keys below.
| Provider | Required keys | Common optional keys |
|---|---|---|
| Stripe |
secret, webhook
|
checkout, metadata, webhook_tolerance, field
|
| Chargebee |
api_key, site
|
webhook_auth or webhook_secret, checkout, plans, field
|
| Lemon Squeezy |
secret, store_id, webhook_secret
|
checkout, plans, test_mode, field
|
| Paddle |
secret, webhook_secret
|
client_token, environment, webhook_tolerance, proration_billing_mode, checkout, plans, field
|
| Polar |
secret, webhook_secret
|
server, organization/org_slug/org, webhook_tolerance, checkout, plans, field
|
| PayPal |
client_id, secret, webhook_id
|
environment, cancel_behavior, checkout, plans, field
|
| Mollie | secret |
webhook_secret, checkout, plans, field
|
Plans and products
Plan and product sources depend on the provider:
- Stripe: plans/products are fetched from the Stripe API (cached).
- Other built-in providers: plans come from
bnomei.klub.providers.{provider}.plansorsite()->content()->plansYAML. Products are derived from those plans and grouped byproduct_id,product, orproductname.
Checkout metadata
You can attach metadata to checkout sessions with bnomei.klub.providers.{provider}.metadata. In the built-in checkout routes, this callback receives sanitized request data from the checkout POST.
<?php
$provider = 'paddle'; // change to your provider key
return [
'bnomei.klub.providers.' . $provider . '.metadata' => function (array $requestData = []) {
return [
'kirby_user_id' => kirby()->user()?->id(),
'campaign' => $requestData['campaign'] ?? null,
];
},
];
Checkout option callbacks
bnomei.klub.providers.{provider}.checkout can be an array or closure. The closure receives (array $options, array $data).
$optionsis always present.$datais only present when checkout data is passed asoptions['data'].- Built-in checkout routes do not pass
datato checkout callbacks by default.
See Customizing checkout for provider-specific examples.
Core options
| Option | Default | Purpose |
|---|---|---|
cache.* |
true |
Toggle internal caches (actions, gates, gravatar, magiclink, notifications, ratelimit, stats). |
caching |
15 |
Cache provider calls and derived gates (minutes). |
csrf |
true |
Enforce CSRF on state-changing routes. |
captcha.current |
callback |
Read captcha input from the request. |
captcha.get |
callback |
Read captcha phrase from storage. |
captcha.set |
callback |
Generate captcha image + phrase. |
captcha.remove |
callback |
Clear stored captcha phrase after validation. |
crypto.encrypt |
false |
Encrypt provider data on the user. |
crypto.password |
callback |
string |
gates.handler |
Bnomei\Klub\ProviderGates |
Gates handler implementation. Field name is defined in ProviderGates::$field. |
license.key |
callback |
string |
license.domain |
string |
null |
members.create |
true |
Auto-create users on checkout return. |
members.roles |
['member'] |
Roles allowed for members (first is default). |
progress.handler |
Bnomei\Klub\Provider\UserFieldProgress |
Progress handler implementation. Field name is defined in UserFieldProgress::$field. |
provider.handler |
Bnomei\Klub\Provider\StripeProvider |
Provider class used to resolve the active provider. |
ratelimit.enabled |
true |
Enable rate limiting on public routes. |
ratelimit.limit |
30 |
Requests per minute per IP. |
turnstile.endpoint |
... |
Verification endpoint override. |
turnstile.sitekey |
callback |
string |
turnstile.secretkey |
callback |
string |