> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flexwash.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Prepaid Members & Loyalty Points

> Carry every prepaid membership and loyalty balance into FlexWash so day-one customers feel no disruption at the gate.

Prepaid membership bases and loyalty programs are some of the stickiest parts
of a car wash business, and they are also the parts customers notice fastest
when a migration goes wrong. FlexWash imports both, per car wash, before your
first day live, so existing members keep the time they paid for and every
loyalty point follows them into the new system.

<Note>
  Recurring card-on-file memberships move through a different path. See
  [Member Token Migration](/data-import/member-token-migration)
  for the processor-to-processor flow, and
  [Interim Imports](/data-import/interim-import) for the
  daily bridge that keeps members recognized while tokens migrate.
</Note>

## Before You Start

Build the prepaid wash package at every car wash that needs it first. The
importer resolves each row to a live membership or prepaid membership package
at that row's car wash, and a row whose package is missing or deleted stops
the import. See
[Prepaid Memberships](/memberships/prepaid-memberships) for how to create one.

## How It Works

This is a hands-on, support-led import. You produce the data per car wash, and
a FlexWash onboarding specialist runs the importer for you after a joint
validation pass.

<Steps>
  <Step title="Export one CSV per car wash">
    Pull active and expired prepaid memberships and loyalty balances from your
    current POS into a separate CSV file for each car wash.
  </Step>

  <Step title="Share the files with your onboarding specialist">
    Email the CSVs to
    [onboarding@flexwashtech.com](mailto:onboarding@flexwashtech.com). We treat
    them as the source of truth for prepaid coverage and point balances at
    go-live.
  </Step>

  <Step title="We validate and map plans">
    Our support staff verifies every row, flags any data issues back to you,
    and maps each legacy plan name to a FlexWash package template. We do this
    mapping once per organization and reuse it on every subsequent file.
  </Step>

  <Step title="We run the import">
    Once the file is clean and every plan is mapped, we run the importer.
    Customers, vehicles, prepaid subscriptions, memberships, and loyalty
    balances land in FlexWash together. Supplying the optional
    `customerInsertedAt`, `vehicleInsertedAt`, and `membershipInsertedAt`
    columns preserves each record's original start date.
  </Step>
</Steps>

## File Format

One CSV per car wash. The header row must contain the exact field names shown
in the tables below, and empty cells are allowed for any optional field.

Every row carries the car wash it belongs to. The importer rejects the whole
file if the `carWashId` column is missing, if any cell in it is blank, or if
any row names a different car wash than the one selected in the importer. This
catches the wrong site's file before it writes anything.

### Required Fields

| Field                       | Description                                                                                                                                                                                            |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `carWashId`                 | The FlexWash car wash ID for the site this file covers. Every row repeats it.                                                                                                                          |
| `customerMigrationId`       | The customer's unique ID in your existing POS. We use this to keep your historical records linked.                                                                                                     |
| `name`                      | Customer's full name. The column must be present. Individual cells can be blank, though we strongly recommend filling them.                                                                            |
| `licensePlate`              | Vehicle license plate. The plate is uppercased, every letter `O` becomes digit `0`, and all whitespace is removed. Verify your records do not rely on a literal `O`.                                   |
| `packageTemplateId`         | The FlexWash package template ID for the prepaid plan, as a UUID. The importer resolves it to that template's package at the row's car wash.                                                           |
| `vehicleSubscriptionStatus` | Use `prepaid_active` for coverage that still has time on it and `prepaid_expired` for coverage that has run out.                                                                                       |
| `billDateInMonth`           | Day of the month for billing, as an integer from 1 to 31. Stored on the membership record. For prepaid rows, `validUntil` is what governs coverage.                                                    |
| `integrationPlatform`       | The car wash's payment platform: `adyen`, `clover`, or `pax`.                                                                                                                                          |
| `validUntil`                | The last day prepaid coverage is good for, written as `YYYY-MM-DD`. For example, `2026-06-30` covers the customer all day on June 30 in the car wash's local time. Required for both prepaid statuses. |

### Conditionally Required Fields

| Field          | Description                                                                                                                                                                    |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `customerUuid` | The customer's FlexWash UUID. Required on every row when `integrationPlatform` is `adyen`. Also supply it to group several vehicles under one customer, whatever the platform. |

### Optional Fields

| Field                  | Description                                                                                                                        |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `phoneNumber`          | Phone number. Non-digit characters are removed and the trailing 10 digits are kept.                                                |
| `email`                | Customer email address. Stored lowercased.                                                                                         |
| `make`                 | Vehicle make.                                                                                                                      |
| `model`                | Vehicle model.                                                                                                                     |
| `year`                 | Vehicle year.                                                                                                                      |
| `rfidTag`              | Vehicle RFID tag. Whitespace is removed, the tag is uppercased, known vendor prefixes are stripped, and leading zeros are dropped. |
| `statusUpdatedAt`      | When the subscription last changed status. Defaults to the import time.                                                            |
| `customerInsertedAt`   | Original customer creation timestamp. Preserves the customer's true start date in FlexWash.                                        |
| `vehicleInsertedAt`    | Original vehicle creation timestamp.                                                                                               |
| `membershipInsertedAt` | Original membership creation timestamp.                                                                                            |
| `ccZipcode`            | Billing zip code on file.                                                                                                          |
| `promotionId`          | FlexWash promotion ID to attach to the subscription. It must already exist in your FlexWash organization.                          |
| `loyaltyPointsBalance` | Current loyalty point balance for the customer, as an integer.                                                                     |

<Note>
  Card columns such as `ccIntegrationToken`, `ccLastFour`, and `ccBrand` are
  not part of a prepaid file. Prepaid members have no card on file, and those
  columns are only required for the `active` and `active_external` statuses
  used by [Member Token Migration](/data-import/member-token-migration).
</Note>

## Prepaid Coverage Dates

`validUntil` is the whole point of a prepaid row, so the importer refuses to
guess it. A `prepaid_active` or `prepaid_expired` row without a `validUntil`
stops the import rather than falling back to a computed date.

Set `validUntil` to the last day the customer is entitled to wash. FlexWash
stores it as the end of that day in the car wash's local timezone, so a member
paid through June 30 washes freely all day on June 30.

Send expired prepaid members too, with their real past `validUntil` and their
loyalty balance. They arrive as `prepaid_expired`, which keeps their history
and points intact and gives your team a warm list to re-sell on day one.

## Several Vehicles on One Membership

The importer groups rows into customers by `customerUuid`. Give every vehicle
its own row, repeat the same `customerUuid` on each, and those rows land as one
customer with one membership and one subscription per vehicle.

Each vehicle keeps its own coverage dates. `validUntil`,
`vehicleSubscriptionStatus`, `packageTemplateId`, and `promotionId` all sit on
the vehicle's own subscription, so one customer can hold a vehicle prepaid
through June 30 next to a second vehicle whose prepaid time ran out last year.
Send one row per vehicle, keep `customerUuid` identical across them, and vary
`licensePlate` and `validUntil` between them. Giving the second vehicle its own
`customerUuid` creates a second customer in FlexWash, which this never needs.

Rows that share a `customerUuid` must agree on `billDateInMonth`. If they
disagree, the import stops and reports the conflict.

<Warning>
  Leave `customerUuid` blank and each row becomes its own customer, because
  FlexWash generates a fresh UUID per row. Always supply it for any customer
  with more than one vehicle.
</Warning>

## Verify the Import

Check a handful of records yourself as soon as the import finishes:

1. Open **Customers** in the admin app and search for one of the imported
   customers by name, phone number, or plate.
2. On the customer's profile, confirm the loyalty point balance matches your
   source data.
3. Open the vehicle and confirm the normalized license plate, the prepaid
   package, and the valid-until date match the CSV row.
4. Repeat for a `prepaid_expired` member and confirm the subscription reads as
   expired rather than active.

## Tips for a Clean File

* If you use Excel, export the file as a CSV, then open it in a plain-text
  editor to confirm Excel has not stripped leading zeros from RFID tags or
  rewritten long numeric codes in scientific notation.
* Keep `customerMigrationId` stable. If your ex-POS has a separate "customer
  number" that changes when a record is edited, use the immutable internal ID
  instead.
* Deduplicate plates and RFID tags before you send the file. One repeat of
  either stops the whole import.
* Normalize legacy plan names to one casing before exporting. `Premium Prepaid`
  and `premium prepaid` map as two separate plans.
* Send one file per car wash even if a single customer appears at more than one
  location. We reconcile shared identities during the verification pass.
* Send any correction to your onboarding specialist before we import the file.
  Fixing a row afterwards is a manual change in FlexWash, not a second upload.
