Docs
← cabintale.com EN · CZ Email support
Products · Tutorial

Vouchers

Sell printable / digital voucher codes from your account. Every unit purchased generates one unique redeemable code.

By the end of this guide, you'll know how to create a voucher product, how codes are generated and emailed, how to issue codes manually without taking online payment, how to send payment links for unpaid voucher orders, how the voucher-disposition dialog works when you refund / cancel / delete a voucher order, and how guests and admins can redeem voucher codes.

Before you start

What you'll need

  • A configured payment gateway in Settings → Payments (Stripe) — only required for guest-facing voucher checkout. Manual voucher issuance works without a gateway.
  • Optionally: a short brand-friendly code prefix (e.g. SUNNY) if you want voucher codes to be visually owned by your business.
  • ~10 minutes for the first voucher product.
What you'll achieve
  • A voucher product live on your website with embedded Checkout
  • An admin Vouchers tab showing every issued code
  • Manual voucher issuance for gift codes and comps
  • Refund / cancel flow that lets you decide what happens to outstanding codes

What's a voucher?

A voucher is a row in the vouchers table created when a customer pays for a voucher product. Each row stores:

  • A unique code in the format [PREFIX-]XXXX-XXXX (8 random Crockford Base32 chars; alphabet excludes I L O U to avoid phone-dictation ambiguity)
  • The value + currency snapshotted from the product at issuance
  • A status: paid (active, redeemable), redeemed, expired, or cancelled
  • An optional expires_at date
  • A link back to the ProductOrder that created it (one order → N vouchers, one per quantity)

Codes are surfaced to the customer in the confirmation email and on the payment success step.

Step 1: Create a voucher product

Sidebar → Products+ → fill the new-product form:

FieldVoucher value
NameCustomer-facing label (e.g. Cellar Voucher, Spa Day Voucher).
TypeVoucher.
Country / CurrencyAuto-pairs; must match what your gateway supports.
Pricing modeSingle price (one voucher value) or Options (multiple voucher values sold from one button).
Price (single mode)Per-voucher value in major units (e.g. 500 for a 500 CZK voucher). Every code issued from this product carries this value.
Options (options mode)Add one line per voucher denomination, e.g. 500 CZK voucher — 500, 1 000 CZK voucher — 1000. Each option line's price becomes the value of every voucher generated from that line. Title and description are optional; price is required.
Code prefix (optional)1–8 letters/digits, e.g. SUNNY. Codes will look like SUNNY-RDX9-RPMS. Leave empty for code-only (RDX9-RPMS).
Validity (days) (optional)How many days from issuance before the voucher expires. Empty = unlimited validity.

Click Save. The product detail page opens. The sidebar now shows a Vouchers child route under this product (only voucher-type products get it).

Options mode + vouchers. Each option line acts like its own voucher tier. If a guest buys 2× 500 CZK voucher + 1× 1 000 CZK voucher, that's three voucher rows: two with value 500 and one with value 1000. Each gets its own unique code and its own dashed-border chip in the confirmation email.

Step 2: Configure the Checkout button

Set up a Checkout button exactly as for a regular product (see Products overview Step 2). The button label can advertise the voucher value: Buy a 500 CZK voucher.

Quantity bounds set on the product apply: e.g. min=1, default=1, max=10 lets a customer buy up to 10 vouchers in a single checkout, each generating its own code.

Step 3: How a guest buys a voucher

Identical 4-step dialog to any product:

  1. Quantity
    • Single-price voucher products: one stepper for how many vouchers.
    • Options voucher products: one stepper per voucher tier (e.g. 500 CZK ×2, 1 000 CZK ×1). Total = Σ (option price × line quantity).
  2. Custom fields — name + email (required); add gift-message / recipient-name fields via the dialog-fields editor.
  3. Review — running total. For options mode the breakdown lists each tier with its quantity.
  4. Pay — Stripe Checkout.

When payment succeeds:

  • One voucher row is inserted per ordered unit — in options mode, the row's value is snapshotted from the option line that produced it. Codes are unique, currency is snapshotted, expires_at follows the product's validity setting.
  • The guest's confirmation email lists every issued code as a dashed-border chip with code, value, and (if set) expiry date.
  • The host gets the standard new-order notification.

If voucher issuance fails for any reason, the webhook handler returns 5xx so Stripe retries. The order's status stays out of paid until ALL expected codes have been generated, so partial state self-heals on retry.

Step 4: View + manage issued vouchers

Sidebar → Products → {voucher product} → Vouchers.

Two tabs at the top:

  • Activestatus = paid. Vouchers still redeemable.
  • Expiredstatus IN (expired, redeemed, cancelled). Archived buckets.

Each row shows: customer name + email, issued date (relative), expires (or "No expiry"), linked order code, voucher code chip, status badge, actions dropdown (Cancel / View) + arrow to detail.

Click into a voucher to see its Detail page:

  • Code as the page title
  • Value / Issued / Expires info row
  • Linked order card with public reference code
  • Redeemed against card — once redeemed, shows which booking/order and the date
  • Danger zone — manual cancel (only available while status = paid)

Step 5: Issue vouchers manually

For gift codes, in-person sales, or comps where no online payment is involved.

Path: Sidebar → Products → {voucher product} → Vouchers → click Add voucher in the header.

Form fields:

FieldWhat it does
Value per voucherOverride the product's default price; empty = product price.
QuantityHow many codes to generate in this batch (1–100).
Validity (days)Same as on the product. Empty = unlimited.

Submit. cabintale creates a synthetic ProductOrder with payment_status='manual', named "Voucher order", and inserts N voucher rows. You're redirected to the Active tab with a success flash showing how many were created.

The synthetic order shows up in the Orders list (so accounting is honest), but no gateway transaction is recorded — there's no Stripe charge to refund. To deactivate a manual voucher, use per-row Cancel from either the Vouchers list dropdown or the order's Issued Vouchers panel.

Step 6: Send a payment link for an unpaid voucher order

If a customer started a voucher checkout but didn't complete payment, you can send them a link to retry without re-entering details:

  1. Open the order detail in Orders.
  2. In the Payments section, click Send payment link.
  3. cabintale creates a pending Stripe Checkout session and copies the URL to your clipboard. Paste into chat / email.
  4. The customer pays via /pay/{token}. Vouchers are generated as usual on success.

The button is hidden if the product has no gateway configured or the order is already paid.

Step 7: Cancel / Refund / Delete — voucher disposition dialog

When you take a destructive action on a voucher order, cabintale asks what to do with the paid vouchers tied to it. The dialog appears in three places:

  • After refunding a transaction in the order's Payments table
  • When changing order status to Cancelled and saving
  • When deleting the order from the Danger Zone

Two buttons:

  • Cancel all vouchers — every paid voucher on the order flips to cancelled (holder can no longer redeem).
  • Keep vouchers — vouchers stay paid + redeemable. Only the order's state changes.

On Delete + Keep, the order is hard-deleted; the vouchers' product_order_id becomes NULL but each voucher row stays valid — codes still work, value + expiry unchanged.

Step 8: Cancel an individual voucher

From either of two places:

  • Vouchers list → row dropdown → Cancel voucher
  • Order detail → Issued Vouchers panel → per-row trash icon

Either path opens a confirmation modal. On confirm, status flips to cancelled (no gateway call). To return the customer's money instead, refund the underlying transaction from the order's Payments table — the voucher-disposition dialog will then ask if you want to cancel the vouchers too.

Step 9: Redeem a voucher

Voucher codes (Phase C) can be applied as a payment method against place bookings, service bookings, and non-voucher product orders. Codes are case-insensitive and dash-tolerant — SUNNY-RDX9-RPMS, sunnyrDx9rPms, and SUNNY RDX9 RPMS all resolve to the same voucher.

Currency + account must match. A CZK voucher cannot pay a EUR booking. A voucher from one host account cannot be applied to another.

Guest path (BookingDialog)

  1. On the Summary step, a "Use voucher code" link appears below the price breakdown.
  2. Click it, enter the code, and press Use. cabintale checks the code and returns the voucher value.
  3. If the voucher covers the full amount: the submit button changes to Confirm booking and no card is charged.
  4. If the voucher covers part of the amount: the breakdown shows the voucher discount and a "Due now" line for the remainder. The guest proceeds through Stripe and pays only the remainder.

The voucher is fully consumed in both cases — there is no partial-value bank-back.

Admin path (Add Payment → Voucher)

  1. Open the booking / order detail in the admin.
  2. In the Payments section, click Add Payment.
  3. Set Type to Voucher, enter the code, and submit.
  4. cabintale validates the code, applies it, and marks the voucher as redeemed. No Stripe charge is triggered.

Voucher status flow

  • paid → voucher is active and redeemable.
  • pending_use → a customer is mid-checkout with the voucher locked (partial-coverage only; full-coverage commits immediately). Lock auto-releases when the checkout finishes or expires.
  • redeemed → voucher has been used. The Voucher Detail page shows which booking/order it was applied to, and the date.

If a gateway session expires without payment, the voucher reverts to paid automatically. Admins can also clear a stuck pending_use lock manually via the Release hold button on the Voucher Detail page.

Limitations (current)

  • One denomination per option line. Single-price voucher products issue codes at one value. To sell multiple denominations from one button, switch the product to Options mode and add one option line per denomination.
  • No bulk export. Codes are visible in the admin and in the customer email; if you need a CSV, file a request.
  • Multi-voucher stacking not supported. Only one voucher code can be applied per booking or order.
  • Partial-value retention not supported. Vouchers are always consumed in full — there is no remaining balance.
  • No voucher transfer. Codes are tied to the issuing account; there is no mechanism to reassign a code to a different holder.

Related guides

Still stuck?

We reply to every email within one business day.

Email support →