Payments, safely
How TrustBnB Pro will take payments through Dodo Payments without putting money, keys or users' data at risk. This is the plan for the Pro tier; none of it is live yet.
The rules
- The extension never holds a secret. Anyone can unzip an extension and read it, so
nothing in it may be private. It only uses Dodo's public license endpoints (
activate,validate,deactivate), which need no API key. - Pro is decided on a server, never in the extension. Someone can edit their own copy of the extension to show a "Pro" badge, and that's fine: what Pro pays for (city data, fresh data, the breakdown) comes from a server that checks the license key on every request.
- Card details never touch TrustBnB. Buyers pay on Dodo's hosted checkout. Dodo is the merchant of record, so it handles card data, VAT and sales tax, receipts, refunds and chargebacks.
- Secrets live in one place: Vercel's environment variables. Never in the repository, the extension, the website's pages, a GitHub issue or a chat.
- Test mode first, live mode last. Everything is built and tried against Dodo's test mode, with test keys and test cards, before a single live key exists.
What's secret and what isn't
| Thing | Secret? | Where it lives |
|---|---|---|
| Checkout link (from the Dodo dashboard) | No | Extension popup (Pro tab) |
| Product id | No | Website and API code |
| A customer's license key | Theirs | The customer's browser (storage.local), our API requests |
| Dodo API key | Yes | Vercel environment variable DODO_PAYMENTS_API_KEY, for automatic activation |
Dodo webhook secret (whsec_…) |
Yes | Vercel environment variable DODO_PAYMENTS_WEBHOOK_SECRET, only if needed |
Pasting a key needs no secret at all. Static checkout links come from the dashboard, Dodo issues license keys automatically, and checking a key uses public endpoints. Dodo also revokes a key on its own when a subscription is cancelled or refunded, so there's nothing to sync.
Turning Pro on automatically after checkout, without copying the key, needs one secret: the Dodo API key, used by one server function to look up the key for a payment. It stays in Vercel and never reaches the extension. The webhook secret is only needed if we later react to payment events.
How a purchase works
Everything starts and ends in the extension. The popup gets four tabs: Page (status and on/off), Check (check a rating), Settings and Pro.
- Get Pro. The Pro tab shows what Pro adds and the price. "Get Pro" opens Dodo's hosted checkout in a new browser tab. The payment can't happen inside the popup itself: the popup closes as soon as you click anywhere else, and the stores expect payments to happen on the payment provider's own page.
- Back to TrustBnB. After paying, Dodo sends the buyer to a short "Welcome to Pro" page on our website, with the payment's id in the address.
- Pro turns on by itself. The extension recognizes that page (its content script also
runs on our own site's
/pro/pages) and asks/api/claimfor the license key. The server looks the payment up with Dodo, checks that it's paid, recent and not already claimed too often, and returns the key. The extension stores the key, calls Dodo's publicactivate, and the Pro tab shows "Pro is active". The welcome page also shows the key, and Dodo emails it, for using Pro on another browser. - Pasting still works. On another computer, or if anything goes wrong, "Already have a license key?" in the Pro tab takes a pasted key and activates it the same way.
- Pro data. The extension sends the key and its activation id to
/api/data. The server calls Dodo'svalidate(cached for a few minutes) and only then returns the data. Requests carry no information about the pages the user visits. - Staying valid. Once a day the extension re-validates. When a key stops being valid (cancelled, refunded, expired), Pro switches off after a short grace period for travellers who are offline, and the Pro tab says why.
The key and activation id are stored in storage.local, which doesn't sync across devices,
so each browser counts as one activation.
Managing Pro in the extension
When Pro is active, the Pro tab shows:
- the plan (Yearly with its renewal date, or Lifetime), the masked license key (with a copy button), and how many of the key's activations are in use,
- the date of the city data,
- Manage subscription: opens Dodo's customer portal in a new tab, to cancel, change card or download invoices,
- Remove Pro from this browser: calls Dodo's public
deactivate, freeing the activation for another device.
Setting it up
Do everything in test mode first. Test and live mode are separate in Dodo: products, keys and checkout links made in test mode don't exist in live mode, so the last step recreates them.
1. Before anything else
- Email Inside Airbnb (data@insideairbnb.com) about paid use of their data. Pro depends on it.
- Pick the website address for good (the Vercel domain or your own). Checkout links and the extension both point to it.
2. Dodo account
- Sign up at dodopayments.com and stay in test mode (the switch in the dashboard).
- Turn on two-factor authentication.
- Fill in the business details: name TrustBnB, a support email, the website address, and links to the privacy policy, terms of sale and refund policy. Dodo verifies your identity and business before it pays out real money, so start this early.
3. Products
Create two products. Turn on tax-inclusive pricing for each (the price shown is the price paid), set the US price with localized pricing by currency so Dodo doesn't convert it, and turn on license keys with an activation limit of 3.
| Product | Type | EUR | USD | License key expires |
|---|---|---|---|---|
| TrustBnB Pro · Yearly | Subscription, yearly | €9.99 | $9.99 | Never while the subscription is active |
| TrustBnB Pro · Lifetime | One-time | €19.99 | $19.99 | Never |
4. Checkout links and customer portal
- Create a checkout link for each product, returning buyers to
https://<website>/pro/welcomeafter they pay. - Turn on the customer portal (cancel, change card, invoices). The Pro tab links to it.
- Set the payout threshold well above the minimum, so small payouts don't each pay a payout fee.
Checkout links and product ids aren't secret: they go into the extension.
5. Try it, still in test mode
Buy each product with Dodo's test cards and check:
- the key arrives by email and on the welcome page, and activates in the extension,
- cancelling Yearly keeps Pro until the end of the paid year, then switches it off,
- a refund switches the key off, and a fourth browser is refused (activation limit).
6. Vercel
Before launch, make sure the hosting allows commercial use. Vercel's free Hobby plan doesn't, and its Pro plan ($20 a month) would cost about three Yearly sales a month. Cloudflare's free plan can host both the website and the small Pro API; check its terms and pick one before launch. The steps below are for Vercel; Cloudflare has the same encrypted variables ("secrets").
Settings → Environment Variables. Add each with Sensitive ticked:
Variable Preview and Development Production DODO_PAYMENTS_API_KEYthe test API key the live API key DODO_PAYMENTS_ENVIRONMENTtest_modelive_modeDODO_PAYMENTS_WEBHOOK_SECRETonly if webhooks are added later Redeploy. The values are available to the server code as
process.env.…and nowhere else: never to pages, never to the extension.
The API key is created in Dodo under the developer settings. Copy it straight into Vercel, and nowhere else: not a file, not a chat, not an email.
7. Store listings and policies
- Add "Free, with optional Pro from €9.99 a year" to the Chrome Web Store, Firefox Add-ons and Edge listings.
- Publish terms of sale (with "Lifetime means for as long as TrustBnB Pro is offered"), a refund policy, and the updated privacy policy on the website.
8. Go live
- Switch Dodo to live mode and recreate the two products and checkout links there.
- Create the live API key and put it in Vercel's Production variables.
- Put the live checkout links and product ids into the extension and release it.
- Make one real purchase yourself, check it end to end, then refund it.
In GitHub
.envfiles are ignored by git (see.gitignore), so local test keys can't be committed by accident.- CI runs gitleaks on every push and pull request, and fails if anything that looks like a key or token appears in the code or its history.
- Turn on two-factor authentication on GitHub and Vercel too: whoever controls them controls the deployments.
Server code rules
For the Vercel functions that will serve Pro data and, later, receive webhooks:
- Check every request. Validate the license key with Dodo (with a short cache) before returning anything paid. Treat everything the extension sends as untrusted input: check the length and characters of the key before using it.
- Verify webhooks before reading them. Dodo signs webhooks following the Standard
Webhooks spec (
webhook-id,webhook-timestamp,webhook-signature). Verify the signature over the raw request body with the webhook secret, reject old timestamps, and skipwebhook-ids already handled, since deliveries can repeat. - Hand out keys carefully.
/api/claimonly returns a key for a payment that is paid, recent (under an hour old) and claimed fewer than a few times. The payment id is unguessable, but it sits in the welcome page's address, so that page sends no referrer and loads nothing from other sites. - Never log a license key, API key or webhook body. Log ids, not secrets.
- Rate-limit
/api/dataper key and per IP, so a leaked key can't be used to scrape. - Don't rely on CORS or origins. Any program can call the API, and Firefox gives every install its own extension id. The license key check is the only gate that counts.
If something leaks
| What leaked | Do this |
|---|---|
| Dodo API key or webhook secret | Create a new one in the Dodo dashboard, put it in the Vercel variable, redeploy, then delete the old one so it stops working. |
| A customer's license key (shared publicly) | Disable that key in the Dodo dashboard and issue the customer a new one. Activation limits keep the damage small meanwhile. |
| Anything committed to git | Treat it as public even after deleting the commit: replace it first, then clean up. |
Before going live
- Inside Airbnb has agreed to the commercial use of its data (see the roadmap).
- The full flow works in test mode: purchase, activation, Pro data, cancellation, refund, activation limit, offline grace period.
- Privacy policy updated: license key, data download, and Dodo as payment processor.
- Terms of sale and refund policy published on the website.
- Store listings declare the paid features.
- Dodo's fees and payout fee checked in the live dashboard.
- Live products, live checkout links and live keys created; live keys set for Production only.
- Hosting on a plan that allows commercial use (Vercel's free Hobby plan doesn't; see step 6).