Skip to content
Console
Menu

Getting Started

Authentication

KV Store

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.

Shell
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:

Shell
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_id

The 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 .url

Open 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

Shell
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.

#Next