Skip to main content

Billing API

The Billing module integrates with Stripe to handle checkout sessions, subscription management, and payment processing. It drives automatic license issuance, renewal, suspension, and revocation based on Stripe webhook events.


Endpoints

MethodPathDescription
POST/api/billing/checkoutCreate a Stripe checkout session
GET/api/billing/subscriptionsList active subscriptions
GET/api/billing/subscriptions/:idGet subscription details
POST/api/billing/subscriptions/:id/cancelCancel a subscription
GET/api/billing/invoicesList Stripe invoices
GET/api/billing/invoices/:idGet a Stripe invoice
GET/api/billing/payment-methodsList saved payment methods
POST/api/billing/payment-methodsAdd a payment method
DELETE/api/billing/payment-methods/:idRemove a payment method
POST/api/billing/webhooksStripe webhook receiver (Stripe only)
GET/api/portal/billingCustomer billing dashboard

Create a Checkout Session

Initiates a Stripe-hosted checkout for one or more products. On success, the user is redirected to successUrl; on cancel, to cancelUrl.

POST /api/billing/checkout
Content-Type: application/json
Authorization: Bearer eco_live_...

Request Body

{
"items": [
{
"productId": "018e5678-abcd-7000-8000-000000000001",
"quantity": 1
}
],
"successUrl": "https://ecosire.com/dashboard/licenses?session={CHECKOUT_SESSION_ID}",
"cancelUrl": "https://ecosire.com/cart"
}

Response:

{
"sessionId": "cs_live_xxxxx",
"url": "https://checkout.stripe.com/pay/cs_live_xxxxx"
}

Redirect the user to url. Do not store sessionId — licenses are issued automatically via webhook.


Subscriptions

List Subscriptions

GET /api/billing/subscriptions

Returns all active Stripe subscriptions for the authenticated user.

{
"data": [
{
"id": "sub_1PxxxStripeId",
"status": "active",
"currentPeriodStart": "2026-03-01T00:00:00Z",
"currentPeriodEnd": "2026-04-01T00:00:00Z",
"cancelAtPeriodEnd": false,
"items": [
{
"productId": "018e5678-abcd-7000-8000-000000000001",
"productName": "ECOSIRE Shopify Connector — Pro",
"price": 14900,
"currency": "usd",
"interval": "month"
}
]
}
]
}

Cancel a Subscription

POST /api/billing/subscriptions/sub_1PxxxStripeId/cancel
Content-Type: application/json

{
"cancelAtPeriodEnd": true
}

Set cancelAtPeriodEnd: false to cancel immediately. Associated licenses are suspended on cancellation.


Webhook Events

Stripe sends events to POST /api/billing/webhooks. The following events are handled:

Stripe EventECOSIRE Action
checkout.session.completedCreate order + issue licenses + send welcome email
invoice.paidRecord payment + extend license expiry + send receipt
customer.subscription.deletedRevoke licenses + update order status
customer.subscription.updatedSuspend or reactivate licenses based on new status
charge.refundedRevoke licenses + update order to refunded
payment_intent.payment_failedSend payment failure email

See Webhooks for payload formats and signature verification.


Payment Methods

List Payment Methods

GET /api/billing/payment-methods
[
{
"id": "pm_1PxxxStripeId",
"type": "card",
"brand": "visa",
"last4": "4242",
"expiryMonth": 12,
"expiryYear": 2028,
"isDefault": true
}
]

Remove a Payment Method

DELETE /api/billing/payment-methods/pm_1PxxxStripeId

Cannot remove the default payment method if active subscriptions exist.


Customer Portal (Stripe)

Redirect customers to the Stripe Billing Portal for self-service payment management:

POST /api/billing/portal-session
Content-Type: application/json

{
"returnUrl": "https://ecosire.com/dashboard/billing"
}
{
"url": "https://billing.stripe.com/session/..."
}

Redirect the customer to this URL. It provides a full self-service UI for updating payment methods, downloading invoices, and cancelling subscriptions.


Testing with Stripe Test Mode

Use Stripe test card numbers in the sandbox environment:

CardResult
4242 4242 4242 4242Always succeeds
4000 0000 0000 9995Always fails (insufficient funds)
4000 0025 0000 3155Requires 3D Secure authentication

Set STRIPE_SECRET_KEY to your sk_test_... key in .env.local to use test mode.


Status Codes

CodeScenario
200Session, subscription, or payment method retrieved
201Checkout session created
204Payment method removed
400Cannot remove default payment method
401Stripe webhook signature invalid
404Subscription or payment method not found
422Empty cart or invalid product ID