# Create an Invoice (/how-to/payments/create-an-invoice)



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 [#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](/how-to/payments/set-up-stripe)).
* The customer must have a valid email address on file.

Create an Invoice [#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:

| Field                      | Required | Description                                                                                                                                                                  |
| -------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Amount**                 | Yes      | The 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 Pay**         | No       | When 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 Override** | No       | If set, the invoice email is sent to this address instead of the customer's primary email. Useful when billing a different party.                                            |
| **Send Type**              | Yes      | How the invoice notification is delivered (email or SMS).                                                                                                                    |

4. 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 [#invoice-statuses]

| Status     | Meaning                                       |
| ---------- | --------------------------------------------- |
| **Open**   | Invoice has been sent and is awaiting payment |
| **Paid**   | Customer has successfully paid the invoice    |
| **Closed** | Invoice was manually closed without payment   |

How the Customer Pays [#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 [#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 [#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 [#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 [#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 [#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 [#what-to-do-next]

* [Process a Payment](/how-to/payments/process-a-payment) -- add a payment directly from the dashboard instead of sending an invoice.
* [Set Up Auto-Expire](/how-to/payments/set-up-auto-expire) -- automatically cancel bookings if the invoice is not paid by a deadline.
