Your plan
Your tokens
Try it free for 3 days
Plans
Paid out of the balance above. Nothing here asks for a card — add tokens first, then buy the plan with them.
Add tokens
How would you like to pay?
Transfer in pesos
Without it an operator is looking at a name that may not be yours, and the tokens cannot be matched to you. Copy it exactly.
Checking with the provider…
Payment methods
Set up in .env at the project root — never in this app and
never in the repository. .env.example names every variable.
Restart the server after editing it: the environment is read once,
when the process starts.
Setting them up
The money lands wherever these keys belong and nowhere else — no email address anywhere in this app sends it anywhere. Both provider accounts must be the ones under the operator's own address.
PayPal
- A PayPal Business account. A personal one cannot take card payments through the Orders API.
- developer.paypal.com → Apps & Credentials → Sandbox → Create App. Copy the Client ID and Secret.
- Put them in
.envasPAYPAL_CLIENT_IDandPAYPAL_SECRET, leavePAYPAL_ENV=sandbox, restart, and press Test the connections above. - Buy the monthly plan with a sandbox buyer account. The whole path — order, approve, return, capture, plan — has to work once.
- Only then: switch to the Live tab in the same dashboard, take
the live Client ID and Secret, and set
PAYPAL_ENV=live.
Nothing but the exact string live switches environment, so
a half-finished edit stays in the sandbox rather than taking real money.
Binance Pay
- A Binance account with completed KYC, then apply for a merchant account — this needs business verification and is the slow step.
- Merchant dashboard → API keys. Copy the API key and the secret.
BINANCE_PAY_KEYandBINANCE_PAY_SECRETin.env, restart, and press Test the connections.- If the dashboard asks for allowed domains or a webhook URL, this app
is served on
127.0.0.1— there is no public address to give it yet, and no webhook is used. See below.
Settles in USDT, priced at parity with the dollar price. The signature is the whole integration and a wrong one is refused with a message that names nothing — which is what the test button is for.
What is still missing, and why
Webhooks. The normal backstop for "the customer paid and closed
the tab" is a webhook from the provider. A webhook needs a public URL,
and this app is served on 127.0.0.1 — a provider cannot
reach it, so a webhook route here would be dead code that looks like a
safety net.
What stands in for it: this page asks about every unfinished order each
time it loads, so a customer who closed the tab gets their plan the next
time they open it. When there is a real hostname, add the webhook — and
register it before the sign-in gate in
web/serve.js, because a payment provider cannot sign in.
No live call has ever been made from this project. The requests
are built to both providers' documentation and the whole purchase is
tested against a scripted provider
(node CRBuilderApp/test-billing.js), which proves this app
does the right thing with the answers it is given — not that these are
the answers it will get. The first sandbox purchase is the test that
matters.
Orders
Every checkout this app has opened. A claimed row is somebody saying they have transferred pesos — open Mercado Pago, find the reference in the transfer note, and grant it here. That is the only way a peso transfer becomes a plan.