Menu
Platform
AI
App store purchases
Credits
Database
Flags
Generated Assets
Monitoring
Notifications
Organizations
Payments
- Payments
- Payments quickstart
- Checkout policies
- Checkout sessions
- Customer subscriptions
- Entitlement grants
- Exchange rates
- Licence keys
- Licence tokens
- Merchant accounts
- Portal sessions
- Price catalogs
- Revenue
- Revenue facts
- Revenue sources
- Tax threshold statuses
- Usage events
- Usage invoices
- Usage meter prices
- Usage meters
- Usage reservations
- Usage settings
- Usage tiers
Sandboxes
Webhooks
Getting Started
Authentication
KV Store
Deploy & Infrastructure
Reference
Payments quickstart
A connected test account, a synced plan, a paid checkout, and an entitlement
This takes you from nothing to a paying test subscriber, using only a key,
your Stripe account in test mode, and curl. Nothing is deployed and no
webhook is set up by hand: Payments creates its own on your account.
The examples use the environment orgs/acme/projects/shop/envs/production;
use your own. sylphx access whoami prints the environment your key belongs
to, and a key only reaches its own environment.
export ENV=orgs/acme/projects/shop/envs/production#1. Connect your Stripe account in test mode
In the Stripe dashboard, in test mode, open Developers, API keys, and create a restricted key with: Account read; Webhook Endpoints, Products, Prices, Customers, Checkout Sessions, Billing Portal, Subscriptions and Refunds write; Invoices, Charges, Payment Intents and Disputes read. Then connect it:
curl -sS -X POST "https://api.sylphx.com/v1/$ENV/merchant_accounts:connect" \
-H "Authorization: Bearer $SYLPHX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"restricted_key": "rk_test_…"}' | jq .merchant_account.account_idThe account connects in this call. The key is sealed: it is never returned
or logged. Without a restricted key, send {"return_url": "https://…"}
instead and open the authorize_url in the answer to approve the connection
with Stripe's OAuth.
#2. Declare a plan and push it to Stripe
The catalog is the one place your prices live. Amounts are integer minor units
(499 is US$4.99), and prices are tax inclusive.
curl -sS -X PATCH "https://api.sylphx.com/v1/$ENV/price_catalogs/default?allow_missing=true" \
-H "Authorization: Bearer $SYLPHX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"spec": {
"features": [{"key": "plus"}],
"products": [{"key": "plus", "display_name": "Plus", "features": {"plus": "true"},
"prices": [{"key": "plus_monthly", "recurring_interval": "month",
"tax_behavior": "inclusive", "unit_amounts": {"USD": "499"}}]}]
}}'
curl -sS -X POST "https://api.sylphx.com/v1/$ENV/price_catalogs/default:sync" \
-H "Authorization: Bearer $SYLPHX_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'The product, its price and its lookup key now exist in your Stripe account.
#3. Open a checkout
From your server, open a checkout for one of your users. The subject is your own account id for them.
curl -sS -X POST "https://api.sylphx.com/v1/$ENV/checkout_sessions" \
-H "Authorization: Bearer $SYLPHX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject": {"end_user": "user-42"},
"line_items": [{"price": "plus_monthly"}],
"success_url": "https://example.com/billing/return?s={CHECKOUT_SESSION_ID}",
"cancel_url": "https://example.com/pricing"}' | jq -r .urlOpen the url, and pay with the test card 4242 4242 4242 4242, any future
date and any CVC. A retried create never starts a second checkout.
#4. Check access
The success page grants nothing on its own: the grant arrives when Stripe's webhook reaches Payments, usually within seconds. Ask:
curl -sS -X POST "https://api.sylphx.com/v1/$ENV/entitlement_grants:check" \
-H "Authorization: Bearer $SYLPHX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject": {"end_user": "user-42"}, "feature": "plus"}'The answer is entitled: true with the expire_time of the paid period. Cache
it for at most 60 seconds and never past expire_time, and check again when
access is decided.
#Read it back
curl -sS "https://api.sylphx.com/v1/$ENV/customer_subscriptions" \
-H "Authorization: Bearer $SYLPHX_API_KEY"The subscription, mirrored from Stripe. A portal session
(POST …/portal_sessions with the subject and a return_url) lets the buyer
cancel at period end; :check stays true until that end. To go live, connect
your live account with an rk_live_… key and sync the catalog again.