Security//4 min

Make Sure Paid Features Open Only for Paying Customers

Hiding a paid button is not enough. Your app must check a trusted customer record before it creates a report, opens a lesson, sends a download, or performs another paid action.

before you start

The final decision about paid access must come from a protected customer record, not from a setting on the visitor’s device.

What the paid-access rule really means

in plain words

A hidden button can guide a visitor, but it cannot prove that the person has paid.

Your app may hide a button, show a Pro badge, or replace a paid page with an upgrade message. Those screen changes are useful, but they are not the final protection. The files that draw the screen are sent to the visitor’s device. A program called a browser opens those files and displays the app. Because the visitor controls that device, information stored there should not decide whether the app creates a paid report, opens a course, sends a customer download, or performs another paid action.

The final yes or no must come from a separate protected part of the app that visitors cannot directly edit. Developers call this protected part the server. When a signed-in person requests a paid result, the server should identify the account, read its current payment status, and decide whether that exact action is allowed. The technical name for this decision is authorization. It means checking what a known account is permitted to do, not merely checking whether a paid-looking button is visible.

  • ▸Protect the result itself, not only the button that starts it.
  • ▸Include downloads, saved work, automatic tasks, reports, and members-only content.

common risk

An unpaid visitor cannot see the export button, but the app still creates an export when the hidden action is requested because no protected account check happens.

what to do now

Write down every result included with payment and mark the exact moment when the app creates, sends, saves, or reveals it.

ask your AI

Review my entire app for paid access. List every paid page, lesson, report, download, saved item, background task, and action. For each item, identify where the protected server must confirm that the signed-in account currently has access before creating, sending, saving, or revealing the result. Do not treat a hidden button or a value from the visitor’s device as proof of payment.

Why one trusted customer record matters

in plain words

The app needs one protected account record that gives a clear and current answer about paid access.

Choose one record connected to each customer account that answers a simple question: can this account use paid features now? It may also contain the customer’s plan, the paid-through date, remaining usage, or a short grace period after a failed charge. Keep this information in the protected part of the app. Make it the main answer used by every paid feature so that different pages do not invent conflicting rules.

Do not let a field such as isPro, paid, premium, or planName on the visitor’s device make the final decision. The screen may receive a copy of payment information so it can show the correct plan or upgrade message, but that copy is only for display. Developers call information kept by the protected part of an app server-side state. This technical name means the trusted record is stored and checked away from files the visitor can change. The screen can suggest what should happen; the protected record must decide what actually happens.

  • ▸Connect the trusted access record to the customer’s signed-in account.
  • ▸Use the same record for every paid feature and every device.

common risk

A saved setting named premium says yes, so the screen opens a subscriber feature even though the trusted customer record says the subscription expired yesterday.

what to do now

Find every field currently used to decide paid access and make the protected customer record the only final source of the answer.

ask your AI

Change my app so one protected customer account record is the only source used to decide paid access. Include the current plan, access status, paid-through date, and any usage allowance my plans require. Values sent to or returned by the visitor’s device may control what the screen displays, but they must never grant access. Show me every place where the old decision was replaced.

Why the app must check at the moment of use

in plain words

A payment answer from an earlier sign-in or page visit may no longer be correct.

A customer can leave a page open for hours, use several devices, change plans, cancel, receive a refund, or have a renewal fail. If the app checks only when the person signs in, an old page may continue acting as though access is active. The protected part of the app should read the current customer record again immediately before it creates or reveals each paid result.

This does not mean every screen must feel slow. The screen can remember plan details to respond quickly and can explain how to upgrade. It simply cannot be the final gatekeeper. Developers call the current right to use a feature an entitlement. The technical phrase entitlement check means confirming that right at the time of the action. For example, the check may confirm that an account can open a members-only lesson, create another report this month, or download a file while its paid period remains active.

  • ▸Check immediately before creating, changing, sending, or revealing a paid result.
  • ▸Apply the rule to actions started from old tabs, other devices, and automatic processes.

common risk

A customer cancels, but a page opened before the cancellation continues producing paid reports because the app trusted an answer saved at sign-in.

what to do now

Trace every paid action from the visitor’s request to the final result and place the current account check directly before completion.

ask your AI

For every paid feature in my app, add a fresh check of the protected customer record immediately before the result is created, changed, sent, downloaded, or revealed. Cover old open tabs, multiple devices, and automatic jobs. If access is inactive or the usage allowance is exhausted, stop the action, create no paid result, and show a clear message explaining the next step.

Keep access current when payments change

in plain words

The customer record must follow successful payments, failures, cancellations, expirations, refunds, and disputes.

Your payment company normally sends the app a notice when something important changes. The app should receive that notice, connect it to the correct customer, and update the protected account record. Decide the intended result for a new purchase, trial start, successful renewal, failed renewal, cancellation at the end of a paid period, immediate cancellation, refund, and payment dispute. Save enough information to explain when and why the status changed without storing more customer information than you need.

Developers call an automatic notice from one service to another a webhook. Before changing access, the app must confirm that the notice genuinely came from the payment company and has not already been applied. Keep the payment key, password, or access code used for that confirmation in the protected server environment. Never place it in files sent to visitors. Also plan for notices that arrive late or out of order: compare event times or payment periods so an older failure does not incorrectly replace a newer successful payment.

  • ▸Write down the expected access result for every payment change.
  • ▸Confirm each payment notice before updating a customer record.

common risk

A refund is completed, but the customer remains marked as paid because the app handles new purchases and ignores later payment changes.

what to do now

Create a payment-event table, connect each event to an exact account status, and test every path with the payment company’s safe testing mode.

ask your AI

Build a protected payment-update process for my app. Verify that every notice truly comes from my payment provider, match it to the correct customer, prevent the same notice from being applied twice, and handle notices that arrive late or out of order. Update access for purchases, renewals, failed payments, trial endings, cancellations, expirations, refunds, and disputes. Keep all payment keys, passwords, and access codes out of files sent to visitors.

What to test now and keep watching

in plain words

Real account scenarios show whether paid access begins, continues, and ends according to your rules.

Create safe test accounts for an active customer, an unpaid person, a trial user, a cancelled customer who still has paid time remaining, an expired customer, and a refunded customer. Use each account to try every paid page and action on your list. Check the final outcome, not only the appearance of the screen. If a download button is hidden, confirm that no file is sent. If a report button is disabled, confirm that no report is created and no usage is deducted.

Keep a short test record and repeat it whenever you change sign-in, prices, plans, payment handling, customer data, or a paid feature. After the app is public, VibeCodeWall can check the public app from the outside and watch for important changes over time. It does not need access to code that is not public. This outside view helps you notice what visitors can reach, while your account tests confirm that the protected payment decision still works correctly. Use both kinds of checking because they answer different questions.

  • ▸Test both allowed and blocked outcomes for every paid feature.
  • ▸Repeat the checks after changes and continue watching the public app over time.

common risk

Only an active subscriber is tested, so nobody notices that an expired account can still download an older paid file.

what to do now

Run the complete checklist with at least one active and one inactive account before publishing, then repeat it after every payment or plan change.

ask your AI

Create a complete paid-access test plan for my app. Include active, unpaid, trial, cancelled-but-still-active, expired, refunded, and disputed accounts. List every paid page, lesson, report, download, saved item, and automatic action. For each combination, state the expected screen message, whether the final result must be allowed or blocked, and what customer record should be checked. Include repeat tests after changes to sign-in, plans, payments, or customer data.

Quick checklist

  1. 01List every paid page, lesson, report, download, and action.
  2. 02Choose one protected customer record that states whether access is active.
  3. 03Check that record immediately before every paid result is created or revealed.
  4. 04Do not let a setting on the visitor’s device make the final decision.
  5. 05Define what happens after cancellation, failed payment, expiration, refund, or payment dispute.
  6. 06Test active, unpaid, trial, cancelled, expired, and refunded accounts.
  7. 07Keep payment keys, passwords, and access codes away from files sent to visitors.
  8. 08After publishing, have VibeCodeWall check the public app from the outside and watch for important changes over time.

FAQ

Is hiding a paid button enough?

No. Hide it to make the screen clear, but also check the protected customer record before creating or revealing the paid result.

Where should payment status be stored?

Store it in protected account data connected to the customer. A copy on the visitor’s device may help display the screen, but it must not grant access.

Should access end immediately after cancellation?

Follow the policy promised to customers. A cancellation may leave access active until the paid period ends, while a refund or payment dispute may follow a different rule.

Why test again after a small change?

A small change can affect when the customer record updates or which paid actions check it. Repeating the tests catches those gaps.