Skip to content

Billing (YooKassa / Stripe)

Yearly one-shot checkout for Pro and Business. Enterprise is sales-assisted (no online checkout).

Enable

Set in .env:

BILLING_ENABLED=true
BILLING_PROVIDER=yookassa   # or stripe
BILLING_SUCCESS_URL=https://agentops.com.ru/settings?billing=success
BILLING_CANCEL_URL=https://agentops.com.ru/settings?billing=cancel
PLAN_PRO_PRICE_YEARLY=29900
PLAN_BUSINESS_PRICE_YEARLY=99900

YooKassa

YOOKASSA_SHOP_ID=...
YOOKASSA_SECRET_KEY=...

Webhook URL in the YooKassa cabinet:

https://<your-domain>/api/v1/billing/webhooks/yookassa

Events: payment.succeeded, payment.canceled.

Stripe

BILLING_PROVIDER=stripe
STRIPE_SECRET_KEY=sk_...
STRIPE_WEBHOOK_SECRET=whsec_...
PLAN_PRO_PRICE_YEARLY_USD=299
PLAN_BUSINESS_PRICE_YEARLY_USD=999

Webhook endpoint:

https://<your-domain>/api/v1/billing/webhooks/stripe

Subscribe to checkout.session.completed (and optionally checkout.session.expired).

Flow

  1. Admin opens Settings → Subscription and clicks Upgrade.
  2. API creates a payments row (pending) and a provider checkout session.
  3. User pays on the provider page.
  4. Webhook marks the payment succeeded and sets tenant settings:
{
  "plan": "pro",
  "plan_expires_at": "2027-08-11T12:00:00Z",
  "billing_last_payment_id": "..."
}
  1. After 365 days resolve_plan treats the tenant as free until renewed.

API

Method Path Notes
GET /api/v1/billing/plans Catalog + enabled flag
GET /api/v1/billing/status Current plan / optional payment_id
POST /api/v1/billing/checkout Body { "plan": "pro" } — Admin+
POST /api/v1/billing/webhooks/yookassa Public
POST /api/v1/billing/webhooks/stripe Public + signature

Ops checklist

  • Run migrations (018_billing_payments).
  • Keep BILLING_ENABLED=false until provider credentials and webhooks are live.
  • Prefer sandbox shop / Stripe test mode first.
  • Confirm HTTPS health after deploy: GET /api/v1/billing/plans (authenticated).