Memberships
Selling a monthly pass or a block of sessions, scanning a member in, and how memberships expire, renew and get cancelled.
8 min read · Updated 10 Sep 2026
On this page
A membership is a thing a customer buys once and then uses over time: a monthly gym pass, ten massage sessions, a year of unlimited washes. Kassly sells it like any other item, then keeps count of what is left.
Memberships are on the Free plan. No add-on is needed. Attaching the membership to a customer does need the Customers feature, which comes with the Customer Memory & Promos add-on (₱300 per branch each month).
The Memberships menu only appears for service-type businesses. It sits under SERVICES in the sidebar, and that whole group is shown for business types that use partners, a queue, or settlements. A plain retail or convenience-store setup will not see it until one of those is switched on in Store Settings → Feature Toggles.
Two kinds of plan
| Plan Type | What runs out |
|---|---|
| Time-based (expires after a duration) | Days. The membership carries an end date |
| Session-based (limited visits) | Visits. The membership carries a session count |
You pick one per plan and it cannot be both. A time-based plan is measured in Days or Months; a session-based plan is measured in visits.
Creating a plan
Membership Plans → New Plan opens New Membership Plan:
| Field | Required | Notes |
|---|---|---|
| Name | Yes | e.g. Monthly Unlimited |
| Description | No | |
| Plan Type | Yes | Time-based or Session-based |
| Duration | Time-based only | A number plus Days or Months |
| Session Count | Session-based only | How many visits the plan grants |
| Price | Yes | VAT-exempt, and treated as VAT-inclusive |
| Active | — | "Allow new enrollments to this plan" |
Plans are archived rather than deleted, so history stays readable. Switch Active off to stop selling one.
A membership plan's price is recorded VAT-exempt. That is deliberate, and it is not a setting. If your accountant expects VAT on membership revenue, raise it with them before you sell — see Tax configuration.
Selling a membership
Ring the plan up at the POS like any other item and take payment normally. Two things are required:
- A customer must be attached to the sale. Without one, no membership is issued — you get a paid sale and nothing else.
- The sale must complete. The membership is created when the sale finishes, not when it is added to the cart.
On a time-based plan the membership starts today and ends on today plus the plan's duration. On a session-based plan it starts with the plan's full session count. The app then shows the member's QR code straight away so they can photograph it before they leave.
Voiding the sale cancels the membership. Any active membership issued by that receipt flips to Cancelled. It is not deleted — the record stays for the audit trail.
Enrolling without a sale
Memberships → Enroll Member issues one directly, for a member who paid some other way or whose record you are catching up on:
| Field | Required |
|---|---|
| Customer | Yes — search by name or phone |
| Membership Plan | Yes |
| Start Date | No — defaults to today |
| Notes | No |
Kassly refuses a duplicate here: "Customer already has an active membership for this plan." That guard exists to stop a double-tap on the dialog. It does not apply to sales — one receipt can legitimately issue several memberships.
The member card
Every customer gets one QR code, and it belongs to the customer, not to the membership. That matters: the same card keeps working through renewal after renewal. Print it once.
Membership Settings → Member QR Code Mode has two options:
| Mode | State |
|---|---|
| Static | Default. "Members get a permanent QR code. Print once, use forever. Reissue if a card is lost." |
| Rotating | "Coming soon — requires a customer app." Not selectable |
If a card is lost, reissue it from the customer's page — the old code stops working. Reissue All Member QRs on the settings page invalidates every card at once, which you would only do after a leak.
Checking a member in
Scan the card at the counter and tap Time In. The app confirms with "Welcome, Maria" using the member's first name.
On a session-based membership the visit takes one session off. When the last session is used the membership immediately becomes Expired — there is no "0 sessions left but still active" state.
Kassly refuses a check-in and tells you why:
| Message | Meaning |
|---|---|
| "Membership is not active." | Expired or cancelled |
| "No sessions remaining on this membership." | Session-based, count is 0 |
From the dashboard the same thing is Log Visit, with an optional note ("e.g. Attended yoga session, full body massage…"). Visits are listed per membership, and a customer's page shows their lifetime visits across every membership cycle they have had.
Owners, managers and cashiers can all record a visit. Creating, renewing, extending and cancelling is owner and manager only.
Renewing
Renew on a membership creates a new membership and marks the old one Expired. Nothing is lost in the handover:
- Time-based: if the current end date is still in the future, the new term starts from that date, not from today. Renew early and you keep the unused days.
- Session-based: leftover sessions roll forward. Five left plus a ten-session plan gives fifteen.
A renewal can also be rung up as a normal sale, which is the usual way — the POS carries the old membership through so the rollover still applies.
Extending
Extend is the correction tool, not the renewal tool: it adds to the current membership rather than starting a new term. It asks for Days to add or Sessions to add depending on the plan type, plus an optional reason.
| Rule | Behaviour |
|---|---|
| Time-based | Days only. Sessions are refused |
| Session-based | Sessions only. Days are refused |
| Already lapsed | Extending revives it: "This membership is expired. Extending will revive it to active." |
| Time-based already past its end date | The added days count from today, so they are not swallowed by the gap |
| Cancelled | Refused — "Cannot extend a cancelled membership." Cancellation is deliberate and is not undone by accident |
Cancelling, and how memberships end
There are three statuses and no others: Active, Expired, Cancelled.
| How it ends | What happens |
|---|---|
| Time runs out | A sweep at 00:10 Manila time each day marks time-based memberships past their end date as Expired |
| Sessions run out | The membership flips to Expired the moment the last session is used |
| Cancel | Immediate, and the confirmation says so: "This action cannot be undone." Refused if already cancelled, or if already expired |
| The sale is voided | Any active membership from that receipt is cancelled |
Cancel takes effect at once. There is no "cancel at the end of the period" button in the dashboard or the app — a cancellation ends the membership on the spot, including any days or sessions the member had left.
Even before the nightly sweep runs, a membership past its end date is treated as inactive everywhere — a check-in on it is refused. The sweep tidies the label, it does not decide the outcome. The Memberships list filters by All, Active, Expiring and Expired so you can see who is about to lapse.
Cancelling does not refund anything. Money is handled separately, through Returns and refunds.
Memberships when you are offline
Most of this works with no signal:
| Action | Offline |
|---|---|
| Selling a membership at the POS | Works. Issued on the device and synced later |
| Scanning a member card | Works. The device checks its own copy first |
| Recording a visit | Queued, and the app says "Welcome, Maria (offline — will sync)" |
| Creating a plan, renewing, extending, cancelling | Needs a connection |
A visit is only queued when the device gets no answer at all. If the server answers and refuses — no sessions left, membership not active, or you do not have permission — the app shows that refusal and does not queue anything. That is correct: a queued visit against an exhausted membership would just fail later, out of sight.
Do not create a new customer at the counter for someone already on file. A membership sale is held back from syncing until its customer exists on the server. If the offline customer duplicates an existing phone or email, that customer can never sync, so the sale sits on Pending Sync forever and the membership never reaches the dashboard. Search for the existing customer and attach them instead. See Customer profiles.
Prepaid packages of services
Sell a prepaid block — "ten haircuts", "five sessions" — as a session-based membership plan. That is the supported path, and everything above applies to it: it is sold at the POS, consumed by scanning the member in, rolls leftover sessions forward on renewal, and can be topped up with Extend.
There is no separate "service package" screen. Kassly's database carries a package structure that would let one package hold different services in different quantities, but nothing in the dashboard or the app sells, lists or redeems one. Session-based membership plans are what actually ships. If your packages need to mix services — two facials plus one massage — model them as separate plans for now.
What Kassly does not do here
- No recurring billing. A membership does not charge a card monthly. Renewal is a sale you ring up, or a button you press.
- No freeze or hold. There is no pause-my-membership. Use Extend to give the days back.
- No family or shared memberships. One membership belongs to one customer.
- No membership-only pricing. Being a member does not automatically discount other purchases; see Discounts.
- No expiry reminders to the member. Kassly does not text or email them.