Skip to main content

Billing

FeatureSignals supports PayU and Stripe as payment gateways for subscription management. Organizations can switch between gateways via the Update Gateway endpoint.

Pricing

Retrieve the canonical pricing configuration. This is a public endpoint — no authentication required.

GET /v1/pricing

Response 200 OK

{
"currency": "INR",
"currency_symbol": "₹",
"plans": {
"free": {
"name": "Free",
"price": 0,
"display_price": "₹0",
"billing_period": "month",
"limits": { "projects": 1, "environments": 2, "seats": 3 },
"features": ["1 project", "2 environments per project", "..."]
},
"pro": {
"name": "Pro",
"price": 999,
"display_price": "₹999",
"billing_period": "month",
"limits": { "projects": -1, "environments": -1, "seats": -1 },
"features": ["Unlimited projects", "Unlimited environments", "..."]
},
"enterprise": {
"name": "Enterprise",
"price": null,
"display_price": "Custom",
"features": ["Everything in Pro", "Dedicated support", "..."]
}
}
}

Create Checkout

Initiate a payment session for upgrading to the Pro plan. The response varies depending on the org's configured gateway (PayU or Stripe).

POST /v1/billing/checkout

Authentication: Bearer JWT

Query Parameters

ParamTypeRequiredDescription
return_urlstringNoFlag Engine path to redirect after payment. Allowed: /settings/billing, /onboarding

Response 200 OK

The response includes a gateway field indicating which payment provider is being used, along with gateway-specific fields.

Stripe — returns a redirect_url for the Stripe Checkout session:

{
"gateway": "stripe",
"redirect_url": "https://checkout.stripe.com/c/pay/..."
}

PayU — returns form fields that the frontend must POST to the payu_url:

{
"gateway": "payu",
"payu_url": "https://secure.payu.in/_payment",
"key": "merchant_key",
"txnid": "FS_abc12345_1711929600000",
"hash": "sha512_hash_string",
"amount": "999.00",
"productinfo": "FeatureSignals Pro Plan",
"firstname": "Jane",
"email": "jane@company.com",
"phone": "9999999999",
"surl": "https://api.featuresignals.com/v1/billing/payu/callback",
"furl": "https://api.featuresignals.com/v1/billing/payu/failure"
}

PayU Callback (Success)

Handles PayU's server-to-server callback after successful payment.

POST /v1/billing/payu/callback

This endpoint:

  1. Verifies the PayU hash signature
  2. Creates or updates the organization's subscription to pro / active
  3. Redirects to the Flag Engine billing page with ?status=success

PayU Failure

Handles PayU's redirect after failed payment.

POST /v1/billing/payu/failure

Redirects to the Flag Engine with ?status=failed.


Stripe Webhook

Handles incoming Stripe webhook events for subscription lifecycle management.

POST /v1/billing/stripe/webhook

Verified via the Stripe-Signature header. Processes the following event types:

EventAction
checkout.session.completedUpgrades org to Pro, creates subscription
customer.subscription.updatedUpdates subscription status
customer.subscription.deletedCancels subscription, downgrades org to Free
invoice.payment_failedMarks subscription as past_due, notifies admins

Duplicate events are handled idempotently via the gateway event ID.


Get Subscription

Retrieve the current organization's subscription and plan details.

GET /v1/billing/subscription

Authentication: Bearer JWT

Response 200 OK

{
"plan": "pro",
"seats_limit": -1,
"projects_limit": -1,
"environments_limit": -1,
"gateway": "stripe",
"status": "active",
"current_period_start": "2026-04-01T00:00:00Z",
"current_period_end": "2026-05-01T00:00:00Z",
"cancel_at_period_end": false,
"can_manage": true,
"seats_used": 2,
"projects_used": 1
}
FieldDescription
statusactive, past_due, canceled, or none
cancel_at_period_endIf true, access continues until current_period_end
can_managetrue for Stripe subscriptions (portal access available)
gatewaypayu or stripe

A limit value of -1 means unlimited (Pro/Enterprise).


Get Usage

Retrieve current resource usage against plan limits.

GET /v1/billing/usage

Authentication: Bearer JWT

Response 200 OK

{
"seats_used": 2,
"seats_limit": 3,
"projects_used": 1,
"projects_limit": 1,
"environments_used": 2,
"environments_limit": 2,
"plan": "free"
}

A limit value of -1 means unlimited (Pro/Enterprise).


Cancel Subscription

Cancel the org's active subscription.

POST /v1/billing/cancel

Authentication: Bearer JWT

Request

{
"at_period_end": true
}
FieldTypeRequiredDescription
at_period_endbooleanNoIf true (default), access continues until the current billing period ends. If false, cancels immediately and downgrades to Free.

Response 200 OK

{
"status": "canceled"
}

Error 400 Bad Request

PayU subscriptions cannot be canceled through the API — contact support.

Error 404 Not Found

No active subscription exists for the organization.


Billing Portal

Get a URL for the Stripe customer billing portal where users can manage payment methods, view invoices, and update billing details.

POST /v1/billing/portal

Authentication: Bearer JWT

Response 200 OK

{
"url": "https://billing.stripe.com/p/session/..."
}

Error 400 Bad Request

Returned if the subscription is not managed by Stripe.

Error 404 Not Found

No active subscription exists for the organization.


Update Gateway

Change the organization's configured payment gateway.

PUT /v1/billing/gateway

Authentication: Bearer JWT

Request

{
"gateway": "stripe"
}
FieldTypeRequiredDescription
gatewaystringYespayu or stripe

Response 200 OK

{
"gateway": "stripe"
}

Error 400 Bad Request

Returned if the gateway name is not supported.