Test playground (dev only)
Test playground (dev only)
A team-only page on the dev environment that runs Checkout Sessions and Payment Links with a merchant test key.
Status: internal, dev only.
https://checkout-test.devfluveo.com/checkout-testexists only on thedevenvironment and accepts only test keys (sk_test_…/rk_test_…). It is not part of the public API, it is not promoted to production, and it may change or disappear without notice.
The playground is the fastest way for the team to see the real hosted checkout
end to end: paste a merchant test key, type an amount, pay on the hosted page,
and read back what the API says about the resulting session. Nothing here
bypasses the public /v1 API — the page is a thin, host-gated relay inside the
dashboard app that makes the same calls you would make from your own server.
How the team uses it
- Open
https://checkout-test.devfluveo.com/checkout-test. A red banner reads TEST MODE ONLY — dev environment. - Paste a merchant test secret key into the password field. Live keys
(
sk_live_…,rk_live_…) and processor credentials are refused with400 live_key_not_allowedbefore any upstream call. - Enter an amount (decimal, e.g.
42.42), pick the currency (usd,brl,eur,gbp), optionally add a description and a customer e-mail. - Pay on checkout creates
POST /v1/checkout/sessions(mode=payment, oneline_items[0]from your amount) and redirects the browser to the returned hosted checkout URL onpay.devfluveo.com. Pay there with a test card. - Fluveo sends you back to
/checkout-test/return?session_id=cs_…. The return page re-reads the session (GET /v1/checkout/sessions/{id}) and shows thecs_id, thepi_id (and ach_id when an event exposes one),amount_total,currency,statusandpayment_status, followed byGET /v1/events?object=pi_…for that payment. - Generate Payment Link posts the same amount/currency/description to
POST /v1/payment_linksand shows the returned shareableurlwith a copy chip. - Press Forget key when you are done. Closing the tab has the same effect.
Where the key goes — and where it never goes
- The key travels once per action from the browser to a route inside the
dashboard app on this hostname, which forwards it as
Authorization: Bearertoapi.devfluveo.comand then drops it. The server does not store it: no cookie, no session, no database, no log line, no URL. Upstream error bodies are redacted before they are logged or shown. - Between the checkout redirect and the return page the key lives only in the
browser tab’s
sessionStorage. It dies with the tab and is never sent implicitly. If the tab lost it, the return page asks you to type it again. - Responses are whitelisted projections of the API objects; the page never echoes request fields back.
Limits (read before relying on it)
- Dev only, test keys only. The routes and pages answer solely on
checkout-test.devfluveo.comwithFLUVEO_CHECKOUT_PLAYGROUND=1; ondashboard.devfluveo.comand on any deployment without the flag every/checkout-testpath is a404. Removing the infra opt-in is a complete kill switch. - Events may be unavailable. Merchant-public Events are documented as
unavailable (see Checkout overview). Any non-200 answer
from
GET /v1/eventsis shown as “Events unavailable”, never as a failure of the session read. Thech_id depends on those events and may be missing. - Rate limit 10/min per client, per pod. The dashboard runs two replicas,
so a single client may get up to 20 requests per minute cluster-wide before
seeing
429 rate_limitedwithretry-after. Clients without the edge attestation share one bucket. - The playground hostname is not a fully separate site. Its middleware host
gate 404s the dashboard pages and every other matched path, but the
dashboard’s middleware matcher never sees
/api/auth/login,/api/auth/signup,/api/fluveo/*or paths containing a dot, so those handlers also answer oncheckout-test.devfluveo.com. Each is self-gated (credentials, dashboard session cookie, proxy scope) and carries no privilege beyond whatdashboard.devfluveo.comalready exposes; the assets under/_nextand/faviconare served as well. - Reachability is an operator step. The HTTPRoute ships with the dev edge
and the Terraform-owned ACM certificate (
*.devfluveo.com,infra/terraform/envs/dev/alb.tf) already covers the hostname; only the Cloudflare CNAMEcheckout-test.devfluveo.com → <gateway-alb-hostname>is created by an operator. Until then the hostname does not resolve; the app-side flag makes that harmless. rk_test_keys are accepted by the page; whether the API issues them is an upstream question, and an upstream401is shown asupstream_error.
The decision record is ADR 0058 (checkout test playground) in the repository.