Payments

Public payment page

The /pay/[handle] page clients use to pay you — branding, links, and behavior.

What it is

Every RemixCRM organization has a public-facing payment page at:

https://app.remixcrm.com/pay/<your-org-slug>

(or if you have a custom domain configured, https://yourdomain.com/pay.)

It shows your logo, business address, and a payment form. Clients use it to pay deposits or balances without needing a RemixCRM account.

You can find yours under Settings → Slug — set a memorable slug like galaxy and your URL becomes /pay/galaxy. UUIDs work as fallbacks but look ugly in a shareable link.

Pre-filling the form

You can pre-fill the amount, event date, and email via query string:

https://app.remixcrm.com/pay/your-slug
  ?amount=500
  &event=2026-08-15
  &email=client@example.com

This is what RemixCRM uses for "Pay" links in contract emails, balance-due reminders, and the event detail page. You can use it anywhere — email signatures, your website, deposit-request texts.

Payment methods shown

The page shows tabs for every method configured on your org:

  • Card — visible when Square or Stripe is configured (and Card Processor isn't None)
  • Venmo — visible when a Venmo username is saved
  • Zelle — visible when a Zelle handle is saved

If no method is configured, the page shows a "preview mode" banner. The form still renders so the layout looks right, but nothing can submit.

Branding

The page uses your org's:

  • Logo (uploaded under Settings)
  • Business name (header)
  • Address, phone, email (sub-header)
  • Theme colors (light/dark mode aware)
  • Footer text — "Payments processed securely by Square / Stripe" + a badge in sandbox/test mode so test charges aren't mistaken for live

Matching payments to events

The form requires:

  • Client name (free text — used to look like a polite receipt)
  • Email (matched against your clients' primary or secondary email)
  • Event date (matched against your events table)
  • Amount

If RemixCRM finds an event in your org with the same date AND a client whose email matches, the payment is auto-attached to that event. If not, the payment is recorded as unattached — visible in Reports → Payments and you can manually attach it from the event later.

This means: the public pay page works even if the client isn't in your database. You can hand the link to a brand-new prospect and they can pay a hold deposit before you've created their event.

Bot protection

RemixCRM uses Cloudflare Turnstile (the privacy-friendly alternative to reCAPTCHA) to prevent bots from spamming the payment endpoint. The widget appears on the form when NEXT_PUBLIC_TURNSTILE_SITE_KEY is set in the deployment environment; otherwise it's skipped (dev mode).

You don't need to configure anything per-org.

What gets stored

Field Source
org_id The slug/UUID in the URL
event_id Auto-matched by email + date (nullable if no match)
client_name / client_email Form input
event_date Form input
amount Form input
payment_type Square / Stripe / Venmo / Zelle
square_payment_id + square_receipt_url From Square (card path)
stripe_session_id + stripe_payment_intent_id + stripe_receipt_url From Stripe (card path)
status completed (card) or pending (Venmo/Zelle)
entered_by 'public-payment-page'

Customizing the success message

The success thank-you uses the Square/Stripe receipt URL when available. You can add a custom thank-you message under Settings → Sign Thank-You Message — this appears at the bottom of the contract-signing flow but not yet on the payment page. (Filed for a future release.)