One Time Payment Products

One-time payments use POST /klub/payment and grant a gate for the purchased price ID. Use this page when you want a single purchase to unlock content.

Start a payment checkout

<form method="post" action="<?= site()->url() ?>/klub/payment">
  <input type="hidden" name="token" value="<?= csrf() ?>">
  <input type="hidden" name="product" value="basic_one_time">
  <input type="hidden" name="redirect" value="<?= url('thanks') ?>">
  <button type="submit">Buy now</button>
</form>

The provider returns the user to GET /klub/payment/{token} which confirms payment and updates gates.

For providers with asynchronous captures, webhooks are also used to persist one-time purchases and refunds even if the buyer never returns to your site.

Listing products

<?php foreach (klub()->products('one_time') as $product): ?>
  <div>
    <strong><?= $product['name'] ?? 'Product' ?></strong>
    <span><?= $product['price'] ?? '' ?></span>
  </div>
<?php endforeach ?>

Checking access

<?php if (kirby()->user()?->hasGate('basic_one_time')): ?>
  <p>Thanks for your purchase.</p>
<?php endif ?>

Or use the generic helper:

<?php if (klub()->allows('basic_one_time')): ?>
  <p>Unlocked content</p>
<?php endif ?>

Hooks

One-time payments trigger klub.payment:before and klub.payment:after hooks with the checkout session DTO.

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.