Do not let a browser decide who has paid
A page can look locked while still trusting a setting that visitors can change. Use a protected payment record to decide who receives paid features.
before you start
A hidden button does not protect a paid feature. The app must confirm the customer’s payment record before delivering it.
What the payment decision really means
in plain words
The page a customer sees can show payment information, but it should not make the final decision about paid features.
When someone visits your app, their browser receives files that build the page on their device. Those files can hide a button, show an upgrade message, or remember that checkout appeared to finish. However, anything used only inside the visitor’s browser is a poor source of proof. A curious person may change a saved setting, reuse an old page, or open a paid action through another path. The app should therefore treat the page as a display, not as the keeper of the real payment answer.
The dependable answer should live in a protected part of the app that visitors cannot download or alter. Developers call that protected part the server. Before the app sends a paid report, opens a lesson, creates a booking, or performs another paid task, the server should inspect the customer’s account and decide whether the current payment record allows it. When browser files make that final decision, the technical name is client-side authorization. It may make the screen look correct, but it does not reliably protect the result behind the screen.
- ▸Treat hidden buttons and upgrade messages as helpful signs, not proof of payment.
- ▸Protect the result itself, including files, information, and actions that cost money to provide.
common risk
An unpaid visitor changes a saved browser setting from unpaid to paid. The page then shows a members-only report because nothing checks the account’s real payment record.
what to do now
Write down every paid result in your app, including pages, downloads, reports, lessons, bookings, generated items, and actions that continue after the page closes.
ask your AI
Review my entire app for paid features. List every place where browser files, page state, saved browser data, or a hidden button decides whether someone has paid. For each place, move the final decision to protected server code that reads the current customer account and payment record before returning paid information or completing paid work. Do not change the intended design or pricing. Show me the files changed and explain each decision in plain language.
Why one trusted payment record matters
in plain words
Each customer account needs one protected record that clearly says which paid features are available now.
Without one reliable answer, different parts of an app can disagree. The main page may say a subscription is active while a download page uses an older list. A customer who cancelled may lose one feature but keep another by using a saved page. A paying customer may also be blocked because one screen never received the newest information. These problems become more likely when page clicks, checkout messages, and scattered settings each hold their own version of the customer’s payment situation.
Create one protected record connected to the customer’s account. It can describe states such as active, trial, unpaid, overdue, refunded, or cancelled, along with an end date when needed. The technical name for the allowed products or features in this record is an entitlement. Connect it with a stable account identifier rather than a displayed name or email address alone, because those can change. Decide in advance what each state means, including any grace period after a failed renewal, so every paid feature follows the same written rule.
- ▸Use one account record as the main answer for paid use.
- ▸Define what active, trial, overdue, refunded, and cancelled accounts may do.
common risk
Checkout marks one page as paid, but cancellation updates a different record. The customer loses the dashboard while an old download page still treats the account as active.
what to do now
Make a small table of account states and the features allowed in each state. Include when access begins, when it ends, and whether an overdue customer receives a grace period.
ask your AI
Create one protected payment-permission record for every customer account. Include active, trial, unpaid, overdue, refunded, and cancelled states, plus the date access ends when relevant. Connect the record to the app’s stable account identifier. Replace scattered payment flags with this record as the single source of truth. Preserve my existing payment policy, list any unclear policy choices for me, and add safe database changes without storing card numbers or card security codes.
A common way paid features stay open
in plain words
Checking the menu is not enough because customers can reach the same paid result through another path.
A common mistake is to check payment only when the customer opens a page. The app hides the export button for unpaid accounts, so everything appears protected during a normal visit. Yet the work that creates the export may accept a request without looking at the current payment record. Someone using an old bookmark, an open tab, or another screen can then reach the valuable result without passing through the menu that contained the check.
Place the decision beside every valuable operation. Immediately before sending a file, returning customer information, creating a paid item, starting paid processing, or changing something reserved for subscribers, the server should identify the signed-in account and read its current entitlement. Developers call this server-side authorization: the protected part of the app decides whether this particular account may perform this particular action. If the answer is no, return a calm message explaining that payment or account status needs attention, and do not produce part of the paid result.
- ▸Check again when each paid result is requested, even if the page checked earlier.
- ▸Cover work started by buttons, saved pages, automatic jobs, and long-running actions.
common risk
The app hides its export button from unpaid customers, but the separate operation that creates the file never checks payment and still produces the report.
what to do now
Test every paid feature through normal navigation, a saved page, an old open tab, and any other place that can start the same work.
ask your AI
Trace every path that can send a paid file, reveal paid customer information, create a paid item, start paid processing, or change subscriber-only data. Add a server-side authorization check immediately beside each operation. The check must identify the signed-in account, read its current entitlement, allow only the states defined by my policy, and return a clear account-status message without returning partial paid content. Include tests for direct requests and old sessions.
What to change now
in plain words
Confirmed messages from the payment company should update the trusted record whenever a customer’s payment situation changes.
The page shown after checkout should not be the only thing that grants paid use. A customer can close that page, lose their connection, or complete payment on another device. Renewals, failed charges, refunds, and cancellations also happen later, when no checkout page is open. The payment company can send the app a protected message about each event. The app should confirm that the message genuinely came from that company before changing the customer’s record.
Developers call this incoming payment message a webhook. The app should use the payment company’s documented verification method, match the event to the correct stable account identifier, and then update the entitlement. Repeated delivery of the same confirmed event should leave the same correct result rather than creating duplicate access. Keep a limited history containing the event identifier, account identifier, event type, time, and outcome, but do not store card numbers or card security codes. Keep payment keys in the server so visitors cannot download or change them.
- ▸Handle purchases, renewals, failed payments, refunds, disputes, and cancellations according to your written policy.
- ▸Make repeated confirmed messages safe and keep a small history for support and repair.
common risk
A customer completes payment but closes the confirmation page. Access never begins because that page, rather than the payment company’s confirmed message, was responsible for updating the account.
what to do now
Open your payment company’s settings and confirm that every important subscription and payment event is sent to the protected part of your app and recorded successfully.
ask your AI
Implement verified incoming payment messages using my payment company’s official method. Handle confirmed purchase, trial start, renewal, failed payment, refund, dispute, and cancellation events. Match each event to a stable customer account, update its entitlement according to my existing policy, and make repeated delivery produce the same result. Store only a small event history and never store card numbers or card security codes. Keep all payment keys in protected server settings and add tests for valid, invalid, repeated, and out-of-order messages.
How to confirm the fix keeps working
in plain words
Test several account situations now, then repeat the checks whenever payment or paid-feature behavior changes.
Create safe test accounts for an active customer, a trial customer, an unpaid visitor, an overdue customer, and a cancelled customer. Before testing, write down what each account should receive. Then try normal navigation, saved pages, direct visits, downloads, old open tabs, and actions that take time to finish. Confirm both sides of the rule: eligible customers should receive what they bought, while other accounts should receive a clear message without paid information or completed paid work.
Repeat these checks after changes to checkout, sign-in, prices, account records, or paid features. Also review unexpected payment events and failed checks so ordinary mistakes do not quietly leave customers with the wrong result. VibeCodeWall checks the public app from the outside and watches for important changes over time. It does not need to see private code to help identify public behavior worth reviewing. This outside view complements account tests; it does not replace the protected payment decision inside the app.
- ▸Record the account type, feature, expected result, and actual result for every test.
- ▸Repeat the checks after important changes and investigate unexpected differences.
common risk
A cancelled customer is blocked on the main page but can still create paid reports from a bookmark saved before cancellation.
what to do now
Run the full account test today. Save the results, assign an owner for failures, and schedule the same test after the next change involving payments, sign-in, or paid features.
ask your AI
Create and run an automated test plan for every paid feature in my app. Use active, trial, unpaid, overdue, refunded, and cancelled accounts. Test normal navigation, direct visits, saved pages, downloads, old sessions, repeated requests, and long-running work. For each case, record the expected and actual result. Confirm that allowed accounts receive the complete result and blocked accounts receive no paid information or completed work. Also give me a short manual checklist to repeat after future changes.
Quick checklist
- 01List every page, file, report, lesson, booking, and action that requires payment.
- 02Find every place where the app decides whether a customer has paid.
- 03Keep one trusted payment record for each customer account.
- 04Make the protected part of the app decide whether to deliver each paid result.
- 05Update the record after confirmed purchases, renewals, failed payments, refunds, and cancellations.
- 06Keep payment keys where visitors cannot download or change them.
- 07Test paid, trial, unpaid, overdue, and cancelled accounts.
- 08Check the public app from the outside after important changes and continue watching it over time.
FAQ
Is hiding a paid button enough?
No. It improves the page experience, but the protected part of the app must still check the customer’s current payment record before delivering the result.
Where should payment keys be kept?
Keep payment keys in protected server settings that visitors cannot download or change. Never place a key that can charge money or read payment information in browser-delivered files.
What should happen after a failed payment?
Follow the policy you told customers, such as a grace period or reduced use. Update the trusted account record so every paid feature applies that policy consistently.
Must every page check payment?
The essential check belongs wherever a paid result is delivered or paid work begins. A page may also show the current status, but its display is not the final decision.