ResytechResytech Docs
Payments & Billing

Create an Invoice

Send a payment link to a customer so they can pay their booking balance online through Stripe.

Invoices in Resytech are payment links tied to a booking. When you create an invoice, the customer receives an email with a link to a payment page where they can enter their card details and pay. The payment is processed through Stripe and automatically updates the booking balance.

Prerequisites

  • A booking with an outstanding balance greater than $0.00.
  • The booking must not be canceled.
  • A connected Stripe account (see Set Up Stripe).
  • The customer must have a valid email address on file.

Create an Invoice

  1. Open the booking from Dashboard > Bookings.
  2. Click Send Invoice (or navigate to the invoice section of the booking).
  3. Configure the invoice:
FieldRequiredDescription
AmountYesThe amount to charge, in cents internally but displayed in dollars. This can be the full balance or a partial amount (e.g., a deposit).
Confirm on PayNoWhen enabled, the booking status automatically changes to Confirmed when the customer pays. Useful for draft or pending bookings where payment confirms the reservation.
Send To Email OverrideNoIf set, the invoice email is sent to this address instead of the customer's primary email. Useful when billing a different party.
Send TypeYesHow the invoice notification is delivered (email or SMS).
  1. Click Send.

The system creates the invoice with a status of Open and generates a unique token for the payment link. The customer receives a notification with the link.

Invoice Statuses

StatusMeaning
OpenInvoice has been sent and is awaiting payment
PaidCustomer has successfully paid the invoice
ClosedInvoice was manually closed without payment

How the Customer Pays

When the customer clicks the payment link:

  1. They see a summary of their booking and the amount due.
  2. They enter their card details using Stripe Elements (a secure, PCI-compliant payment form).
  3. If the card requires 3D Secure authentication, they are prompted to complete it.
  4. On success, they see a confirmation with their booking confirmation code.

The payment page validates several things before allowing payment:

  • The invoice is still open.
  • The booking is not canceled.
  • The booking still has an outstanding balance.
  • The booking's time slot is still available (for draft bookings).
  • Any required agreements/waivers have been acknowledged.

What Happens After Payment

When the invoice is paid:

  1. The invoice status changes to Paid.
  2. A CustomerPayment record is created with the Stripe PaymentIntent ID.
  3. The booking balance is reduced by the paid amount.
  4. If Confirm on Pay was enabled and the booking was in draft/pending status, the booking status changes to Confirmed and a confirmation email is sent.
  5. Calendar sync is triggered if Google Calendar integration is active.

Resend an Invoice

If the customer did not receive the invoice or needs a reminder:

  1. Open the booking.
  2. Navigate to the invoice section.
  3. Click Resend on the open invoice.

This sends a fresh notification with the same payment link.

Race Condition Protection

The invoice payment system includes safeguards against duplicate payments:

  • Row-level locking: When a customer submits payment, the invoice row is locked at the database level to prevent concurrent modifications.
  • Pending payment detection: If a payment is already in progress (e.g., the customer has a 3D Secure prompt open), a second payment attempt is blocked with the message "A payment is already being processed for this invoice."
  • Idempotency keys: Each payment attempt includes a unique idempotency key sent to Stripe, preventing duplicate charges on retries.
  • Stale payment cleanup: If a previous payment attempt failed or was canceled, the system automatically clears the stale reference and allows a new attempt.

3D Secure (3DS) Flow

Some cards require 3D Secure authentication. When this happens:

  1. The initial payment returns a requires_action status.
  2. The PaymentIntent ID is stored on the invoice to prevent concurrent attempts.
  3. The customer completes 3DS in their browser (e.g., entering a code from their bank's app).
  4. On success, the payment is retried with the authenticated PaymentIntent.
  5. The invoice is marked as paid and the balance is updated.

If the customer abandons the 3DS flow, the PaymentIntent eventually transitions to canceled or requires_payment_method. The next time the customer visits the payment link, the stale PaymentIntent is cleared and they can start a fresh payment.

Tips

  • Set the amount carefully. The invoice amount is fixed when created. If you need to change the amount, close the existing invoice and create a new one.
  • Use Confirm on Pay for pending bookings. This eliminates the need to manually confirm bookings after the customer pays their deposit or full balance.
  • The email override field is useful for group bookings where a corporate contact pays on behalf of the participants.
  • Invoice payments create the same payment records as dashboard card payments. They appear identically in reports and the booking's payment history.

What to Do Next

  • Process a Payment -- add a payment directly from the dashboard instead of sending an invoice.
  • Set Up Auto-Expire -- automatically cancel bookings if the invoice is not paid by a deadline.

On this page