Migration (v1 to v2)
This page is for existing v1 customers. If you are new to Klub, start with Concepts and Setup.
Summary
- Multiple providers behind a shared interface.
- Provider configuration moved under
bnomei.klub.providers.{provider}. - Checkout and subscription data is normalized into DTOs.
- Webhooks use a generic
/klub/webhooks/{provider}endpoint.
Config changes
bnomei.klub.stripe.secret->bnomei.klub.providers.stripe.secretbnomei.klub.stripe.webhook->bnomei.klub.providers.stripe.webhookbnomei.klub.stripe.checkout->bnomei.klub.providers.stripe.checkoutbnomei.klub.stripe.metadata->bnomei.klub.providers.stripe.metadatabnomei.klub.manageUsers.role->bnomei.klub.members.rolesbnomei.klub.provider.current->bnomei.klub.provider.handler
Add or confirm:
bnomei.klub.provider.handler(provider class)bnomei.klub.providers.{provider}.field(user field for provider data, default: provider key)
Template and API changes
$user->subscriptions()now returnsSubscriptionDTOs, not arrays.- v1:
$subscription['items']['data'][0]['price']['id'] - v2:
$subscription->price_id
- v1:
- Use
klub()->provider()->subscriptionForPrice($priceId)to fetch the matching subscription. - One-time purchases are stored in the provider user data as
payments(for examplestripe.payments), notstripe['purchases'].
Webhooks
- Configure providers to send events to
POST /klub/webhooks/{provider}. - The legacy Stripe endpoint
POST /klub/webhooks/stripestill exists for backwards compatibility.
Defaults changed
- Rate limit defaults to 30 requests per minute per IP (
bnomei.klub.ratelimit.limit). - Trials are provider-managed and treated as active when gates are calculated.
- Provider selection is global and resolved via
bnomei.klub.provider.handler.
Checklist
- Update config keys and env vars for your provider.
- Add the provider data field to your member blueprint (hidden field).
- Update templates to use DTO properties.
- Configure provider webhooks.