Suppose a workspace owner pays for a month of private search in Team Index, then cancels halfway through the month. When a teammate runs a search after the cancellation, the app's Node.js API has to decide whether the team can still use the feature. Set that policy before you build the cancel button so the team knows what the plan buys.
Use billing events to apply the policy, then store the result in Postgres so the API can check it on each search. If a payment notice never arrives, the app needs another way to bring the stored access record up to date.
Turn the promise into dates and actions
In this hypothetical example, Team Index enables search after payment and keeps it available through the paid period if the owner cancels. If a renewal fails, the app allows a grace period so the team can keep working while the owner fixes their card. Decide how long that period lasts and show the rule to buyers.
Store the workspace ID, provider customer ID, subscription ID, access state, and date through which search is allowed. Record why access last changed. Support can then explain a disabled search by following its payment or cancellation reference.
Keep a trial separate from a paid period if you offer one. A customer who has saved a card for a future charge may have trial access without having paid yet. Mixing those states makes it harder to explain when access should end.
Give each billing case one rule
Write the first plan's rules in a table before mapping them to provider events.
| What happened | Team Index's example rule |
|---|---|
| First payment is pending | Show setup status and keep paid search blocked |
| First payment succeeds | Allow the purchased search plan |
| A renewal succeeds | Set access through the new paid period |
| A renewal fails | Follow the stated grace period |
| Cancellation is scheduled | Keep access through the period already paid for |
| The subscription ends | Stop paid search and preserve data under the data policy |
These are choices for the example app. Refunds, disputes, plan changes, and free access granted by support need their own rules if you offer them. Decide those cases before someone has to resolve one during a support call.
Stripe documents invoice and subscription events that can feed this policy. Keep the final access decision in one place so handlers for different events don't drift into different rules. Stripe subscription events
Check access where the paid work runs
When access ends, the browser can hide the search button. Since a caller can still send a request directly, the API has to check the workspace and its access date before running each search.
Use the stored access record for this check. Calling the payment provider on every search adds another network dependency to the customer's work. Keep the record current through billing events and regular repair checks instead. If you cache it, limit how long a cached value lives and clear it when access changes.
When a renewal is paid, take the new end date from the trusted billing record. Setting that date gives the same result each time the notice arrives. If the handler adds a month on every delivery, a retry would grant another month for the same payment.
Take care with old events too. A late notice about a past payment should not quietly restore a plan that has since ended. Read current trusted subscription state when the event's order or meaning is unclear, then apply the same policy used elsewhere.
Find the event that never arrived
An event handler can fail for longer than a provider keeps retrying. Team Index therefore needs a scheduled check that compares its stored access with trusted billing records.
Give each subscription that can still change, including pending subscriptions, a time for its next check. Index that field so the job can find due rows in small pages. After comparing each record with the provider, set its next check time.
A filter for recently changed rows can miss the case you most need to find. If a renewal event was lost, the local row may still look active and may have no recent change at all. Scheduling each relevant row for review lets the job find that stale access.
Record the source and reason for each repair so support can explain why access changed. Give support a way to run the same check safely for one workspace.
Check that the job can both extend access and end it. Skip a synthetic paid renewal event and see whether the job extends access to the correct date. Then skip a notice that the subscription ended and check that the job stops paid search. Leave both checks open until you run them against the deployed job.
Use Forte states as inputs to the same policy
Forte exposes INCOMPLETE, ACTIVE, PAST_DUE, and CANCELLED subscription states. PAYMENT_COMPLETED covers the first successful charge, renewals, and recovery charges. SUBSCRIPTION_STATUS_CHANGED reports entry to past due or cancelled states. Your Service turns these inputs into Team Index's search rule. Forte subscription lifecycle
For a future-dated plan, the first paid event comes when that charge succeeds. If you use Checkout to collect a new card for a trial, follow the documented setup confirmation steps and grant trial access separately so the customer can start before the first charge. Forte future starts and trials
On Forte, a repair job can use Actions beta to call the Service. The work must finish inside that request, within 120 seconds. Services get no CPU between requests, so an in-process timer is unsuitable. Keep each page of repair work small and save progress. Forte Actions
Build the policy in a Sandbox Project before using live payments, which need approved compliance registration. Use the subscription guide to map each event to one explicit rule, then keep the table beside the handler for future changes.