Backend service for subscription management with:
- Single / Duo / Family plans (1, 2 or 6 seats).
- Split payments — each member pays for their own seat with their own card.
- Integration with Stripe (Customers, PaymentMethods, Subscriptions, Webhooks).
- MongoDB stores households and members.
Install the following tools before you start:
- Node.js (v20+)
- npm (v9+) (bundled with Node)
- MongoDB Community (v6+)
- MongoDB Compass (GUI client for inspecting data)
- Stripe CLI (for local webhooks and event triggers)
git clone https://github.com/shivada727/stripe-subscription-backend.git
cd stripe-subscription-backend
git checkout developmentCreate a .env file in the root directory with the following content:
PORT=3000
MONGODB_URI=mongodb://127.0.0.1:27017/stripe-project
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_PUBLISHER_KEY=pk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
STRIPE_PRICE_SINGLE_SEAT=price_xxx
STRIPE_PRICE_DUO_SEAT=price_xxx
STRIPE_PRICE_FAMILY_SEAT=price_xxx
APP_BASE_URL=http://localhost:3000
LOG_LEVEL=info- Price IDs (
price_xxx) are from [Stripe Dashboard → Products → Prices]. - Webhook secret (
whsec_xxx) is fromstripe listen.
This service provides:
- Households: create single/duo/family with capacity.
- Members: join a household by address/postal code.
- Stripe Customers created automatically on join.
- Subscriptions: each member subscribes individually with their own card.
- Webhooks: update member status when payments succeed, fail, or are canceled.
- Cancel: members can cancel their subscription.
- GET endpoints: inspect household and members state.
npm installnpm run devServer starts on:
- Healthcheck → http://localhost:3000/health
In a separate terminal:
stripe login
stripe listen --forward-to localhost:3000/webhooks/stripeCopy the whsec_xxx value into .env as STRIPE_WEBHOOK_SECRET.
-
POST /households{ "kind": "family", "address": "Almaty, Gogolya 166", "postalCode": "00100" }→ creates a household.
-
GET /households/:id→ returns household details and seat counters.
-
POST /households/:id/join{ "address": "Almaty, Gogolya 166", "postalCode": "00100", "userId": "user@example.com" }→ creates a member and a Stripe Customer.
-
GET /members/:id→ returns member details (status, customerId, subscriptionId).
-
Attach a card to the Customer:
- via Stripe Dashboard → Customer → Add Payment Method → Set as default.
- or via Stripe CLI:
stripe payment_methods create --type card --card[number]=4242424242424242 --card[exp_month]=12 --card[exp_year]=2030 --card[cvc]=123 stripe payment_methods attach pm_xxx --customer cus_xxx stripe customers update cus_xxx --invoice_settings[default_payment_method]=pm_xxx
-
POST /members/:id/subscribe
→ creates a subscription for the member. -
Webhooks (
invoice.paid,payment_failed,subscription.deleted) update Member status.
For testing:stripe trigger invoice.paid stripe trigger invoice.payment_failed stripe trigger customer.subscription.deleted
POST /members/:id/cancel
→ marks subscription to cancel at the end of the current period.
After the period, webhook sets status tocanceled.
{
"dev": "nodemon -r dotenv/config --exec ts-node src/server.ts",
"build": "tsc",
"start": "node dist/server.js"
}npm run dev→ development with hot reload.npm run build→ compile TypeScript.npm start→ run compiled server.
- Create household →
POST /households. - Add member →
POST /households/:id/join. - Add card to the customer (Dashboard/CLI).
- Subscribe →
POST /members/:id/subscribe. - Simulate payment →
stripe trigger invoice.paid. - Inspect →
GET /members/:id. - Cancel →
POST /members/:id/cancel.
- Missing payment method → add a card for the customer.
- Anchor timestamp is in the past → use future billing cycle anchors (handled by resolver).
- Webhook Error → ensure
STRIPE_WEBHOOK_SECRETmatchesstripe listen. - Mongo connection failed → ensure MongoDB is running on
mongodb://127.0.0.1:27017/stripe-project.