Lightweight ProcessWire module to handle Stripe Checkout Payment Links.
It takes care of:
- Handling the Stripe redirect (success URL)
- Creating or updating the user account
- Recording purchases in a repeater field
- Issuing access links for products that require login**
- Sending branded access mails
- Rendering Bootstrap modals for login, reset, and set-password flows
The module is designed for small e-commerce or membership scenarios where a full shop system would be overkill.
Features
Checkout processing
- Works with Stripe Checkout
session_id
- Records all purchased items in a single repeater item (
purchases
) - Stores session meta including
line_items
for debugging/audit
- Works with Stripe Checkout
User handling
- Auto-creates new users on first purchase
- Supports "must set password" flow with modal enforcement
- Automatic login after purchase
Access control
- Products with
requires_access=1
are protected - Delivery pages auto-gate users without purchase
- Access links with optional magic token for new users
- Products with
Mail & branding
- Branded HTML mail layout (logo, color, signature, tagline)
- Access summary mails (single/multi-product)
- Password reset mails
Modals (Bootstrap)
- Login
- Request password reset
- Set new password (via token)
- Force password set after purchase
- Notices (expired access, already purchased, reset expired)
Synchronization (Sync Helper)
- Admin helper to synchronize Stripe Checkout sessions into ProcessWire users
- Supports dry-run mode (no writes, for inspection only)
- Options for update existing purchases and create missing users
- Date range filters (
from
,to
) - Optional email filter to sync sessions for one user only
- Generates a plain-text report with all actions (LINKED, CREATE, UPDATE, SKIP) and line items
Internationalization (i18n)
- All strings are pulled from
defaultTexts()
using$this->_()
- No hardcoded UI strings in templates or services
- All strings are pulled from
Requirements
- ProcessWire 3.0.200+
- PHP 8.1+
- Stripe PHP SDK (installed in
StripePaymentLinks/vendor/stripe-php/
) - Repeater field
purchases
onuser
template (created automatically on install)
Installation
- Copy the module folder
StripePaymentLinks/
into your site’s/site/modules/
. - In the ProcessWire admin, go to Modules > Refresh.
- Install StripePaymentLinks.
- Enter your Stripe Secret API Key in the module config.
- Select which templates represent products.
Usage
In Stripe, create a Payment Link and set its success URL to your ProcessWire thank-you page, e.g.:
https://example.com/thank-you/?session_id={CHECKOUT_SESSION_ID}
On your product pages templates the module added two checkboxes:
- requires_access
- allow_multiple_purchases
Check/uncheck them on your product pages as needed.
In ProcessWire templates, call the module’s render method:
echo $modules->get('StripePaymentLinks')->render($page);
- On the thank-you page, the module will display an access buttons block if the checkout contained products that require access.
- On delivery/product pages marked with requires_access, users are gated: if they are not logged in or have not purchased, they are redirected to the sales page and prompted to log in.
- After first purchase, new users will see the set-password modal on the delivery page.
- Access summary emails are sent automatically according to the configured policy (never, newUsersOnly, or always).
Stripe Webhook & Subscription Handling
The module supports real-time synchronization between Stripe subscriptions and ProcessWire user access.
Webhook Endpoint
Add a webhook endpoint in your Stripe Dashboard under
Developers → Webhooks → + Add endpoint
Set the URL to:
https://yourdomain.com/stripepaymentlinks/api/stripe-webhook
This endpoint automatically processes the following events:
- Subscription cancellation, pause, resume, or renewal
- Invoice payment success/failure
Webhook Events to Enable
When adding the webhook in Stripe, either:
- Send all events (recommended for testing), or
- Select only the relevant subscription-related events:
customer.subscription.updated customer.subscription.deleted customer.subscription.paused customer.subscription.resumed invoice.payment_succeeded invoice.payment_failed
Note:
Some Stripe accounts don’t show explicitpaused
orresumed
events.
In those cases, Stripe sends them ascustomer.subscription.updated
events where thepause_collection
field changes.
The module automatically handles both forms.
Webhook Secret
After creating the webhook, copy the Webhook Signing Secret from Stripe and paste it into
Modules → Stripe Payment Links → Webhook Signing Secret.
Behavior
- Paused or canceled subscriptions immediately block access.
- Resumed subscriptions automatically restore access.
- Renewed subscriptions extend access based on the new billing period.
- Each purchase stores a per-product
period_end_map
(timestamp of subscription end).
The webhook updates this automatically when the subscription changes.
Synchronization / Sync Helper
For advanced scenarios (e.g. when purchases were made outside the normal flow, or to backfill history), the module provides a Sync Helper:
- Run via module config or CLI.
- Fetches Stripe Checkout Sessions via API and writes them into the
purchases
repeater. - Options:
- Dry Run → simulate sync, only produce a report (no writes).
- Update Existing → overwrite already linked purchases.
- Create Missing Users → auto-create new users if no account exists for the checkout email.
- Date Filters → limit sessions by
from
and/orto
date. - Email Filter → restrict sync to a single customer.
The sync produces a plain-text report with:
- Session ID, date, customer email
- Status:
LINKED
,MISSING
,CREATE
,UPDATE
,SKIP
- Line items with product ID, quantity, name, amount
This makes it easy to audit or re-import purchases safely.
Configuration
- Stripe Secret API Key
- Stripe Webhook Signing Secret (optional, needed only for handloing subscriptions)
- Product templates (to enable
requires_access
/allow_multiple_purchases
flags) - Access mail policy (
never
,newUsersOnly
,always
) - Magic link TTL in minutes
- Mail branding (logo, color, from name, signature, etc.)
- Sync options (dry-run, update existing, create missing users, date range, email filter)
Optional: Bootstrap via CDN
The module’s modal dialogs and access UI are styled with Bootstrap 5.
If your site does not already include Bootstrap, you have two options:
- Automatic inclusion (recommended for quick setup)
In the module configuration, enable “Load Bootstrap 5 from CDN”. The module will then insert css and js assets automatically into your frontend.
This ensures the module’s modals, buttons, and notices render correctly, even if your site does not already use Bootstrap.
- Manual inclusion
If your frontend already includes Bootstrap (from your theme or build pipeline), you can leave the config option disabled. No additional assets will be injected, avoiding duplicates.
Developer Notes
- Purchases are stored as one repeater item per checkout.
- All purchased product IDs are stored in
meta('product_ids')
. - Session meta (Stripe Checkout session) is stored in
meta('stripe_session')
. - Recurring products store per-product expiry timestamps in
meta('period_end_map')
. - The webhook endpoint keeps these timestamps and paused/resumed states in sync.
- Access control uses
hasActiveAccess($user, $product)
to evaluate current entitlement. - Modals are rendered via
ModalRenderer.php
with a clean Bootstrap view. - Texts are centralized in
defaultTexts()
and must be accessed withmt()
/t()
. - Sync Helper (
PLSyncHelper
) implements the same persistence logic as checkout.
It ensures that data structure inspl_purchases
is identical whether created live or via sync.
Roadmap
Sync helper for syncing older purchases or for controlling reasonssince v1.0.7Support for auto handling subscriptions of gated contentsince v1.0.8- Optional framework support (UIkit / Tailwind) via JSON view mappings
- Add more payment providers (Mollie, PayPal, …)
License
MIT License.
Copyright © 2025 frameless Media KG
More modules by Mikel
ProcessDataTables
Displays customizable backend tables for any ProcessWire template with flexible column selection, per-field output templates, and global formatting options.16Added 5 months ago by Mikel- Added 5 months ago by Mikel
Textformatter Smart Quotes
Replaces straight quotes "..." with typographic quotes („...“, “...”, or «...»), in visible text only.9Added 2 months ago by Mikel- Added 1 month ago by Mikel
- Added 4 weeks ago by Mikel
Install and use modules at your own risk. Always have a site and database backup before installing new modules.