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.