Customizing the Checkout UI

Checkout UI options are provider-specific. Use this page when you want to pass provider options for branding, tax, or discounts. Klub forwards provider options from bnomei.klub.providers.{provider}.checkout when creating sessions.

Metadata callbacks

All providers can receive metadata. Use bnomei.klub.providers.{provider}.metadata to attach IDs or campaign data to the checkout.

<?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 options callbacks

bnomei.klub.providers.{provider}.checkout accepts an array or a closure. The closure always receives the current checkout options as the first argument. The second argument is only populated when checkout data is passed as options['data'].

<?php

return [
  'bnomei.klub.providers.paypal.checkout' => function (array $options = [], array $data = []): array {
    $brand = $data['brand'] ?? 'My Site';

    if (($options['mode'] ?? null) === 'payment') {
      return [
        'payment_source' => [
          'paypal' => [
            'experience_context' => [
              'brand_name' => $brand,
              'user_action' => 'PAY_NOW',
            ],
          ],
        ],
      ];
    }

    return [
      'application_context' => [
        'brand_name' => $brand,
      ],
    ];
  },
];

Klub controls the price, product, and return URLs. Avoid overriding those values in checkout options.

Passing request data to checkout callbacks (optional)

The built-in checkout routes sanitize request data and pass it to metadata callbacks. They do not pass request data to checkout callbacks by default. If you need it there, pass it explicitly:

$data = \Bnomei\Klub\Data::sanitize(kirby()->request()->data());

$session = klub()->provider($user)->checkout($priceId, [
  'success_url' => site()->url().'/klub/payment/{CHECKOUT_SESSION_ID}',
  'cancel_url' => site()->url(),
  'mode' => 'payment',
  'data' => $data,
]);

Stripe checkout options

Stripe supports extensive Checkout Session options via bnomei.klub.providers.stripe.checkout.

<?php

return [
  'bnomei.klub.providers.stripe.checkout' => [
    'automatic_tax' => ['enabled' => true],
    'allow_promotion_codes' => true,
    'customer_update' => ['address' => 'auto'],
  ],
];

Docs: https://docs.stripe.com/api/checkout/sessions/create

Chargebee hosted pages options

Useful options:

  • customer[email], customer[first_name]
  • coupon_ids
  • subscription[meta_data][key]

Docs: https://apidocs.chargebee.com/docs/api/hosted_pages#checkout_new_for_items

Lemon Squeezy checkout options

Useful options:

  • checkout_data.email, checkout_data.name
  • checkout_options.discount, checkout_options.embed
  • product_options.name, product_options.description

Docs: https://docs.lemonsqueezy.com/api/checkouts/create-checkout

Paddle transaction checkout options

Useful options:

  • discount_id
  • custom_data
  • currency_code

Docs: https://developer.paddle.com/api-reference/transactions/create-transaction

Polar checkout session options

Useful options:

  • allow_discount_codes, require_billing_address
  • customer_email, customer_name
  • external_customer_id

Docs: https://polar.sh/docs/api-reference/checkouts/create-session

PayPal checkout options

Useful options:

  • Subscriptions: application_context.brand_name, application_context.locale, application_context.user_action
  • Orders: payment_source.paypal.experience_context.user_action, payment_source.paypal.experience_context.landing_page

Docs: https://developer.paypal.com/docs/api/subscriptions/v1/ and https://developer.paypal.com/docs/api/orders/v2/

Mollie payment options

Useful options:

  • method
  • locale
  • billingAddress

Docs: https://docs.mollie.com/reference/v2/payments-api/create-payment

Kirby Klub is not affiliated with the developers of Kirby CMS. We are merely standing on the shoulder of giants.
© 2026 Bruno Meilick All rights reserved.