Platform
Billing
Overview

Billing

Base URL: https://billing-api.pcampus.co

Overview

Billing คือ subscription management service ที่รับผิดชอบทุกอย่างที่เกี่ยวกับเงินและ plan ใน Pcampus ตั้งแต่จัดการ tier ของแต่ละ org, ประมวลผลการชำระเงินผ่าน Stripe, ไปจนถึงให้ entitlement API ที่ทุก service เรียกเพื่อตรวจสอบว่า org นั้นมีสิทธิ์ใช้ feature อะไรได้บ้าง

Developer note: ระหว่าง development ให้ใช้ entitlement stub ที่คืน pro plan เสมอ จนกว่า Billing service จะ implement เสร็จ เพื่อให้ service อื่นพัฒนาต่อได้ทันที

Who uses this

Personaใช้ทำอะไร
Internal serviceทุก service เรียก /billing/orgs/:orgId/entitlements เพื่อตรวจสอบสิทธิ์
Org Adminซื้อ plan, ดู invoices, จัดการ payment methods ผ่าน Console
Enterprise customerติดต่อ sales team เพื่อ custom plan
Finance Adminดู revenue, subscription status, invoice ทุก org

Key features

  • Plan management — Free / Starter / Pro / Enterprise tiers ต่อ organization
  • Add-on management — ซื้อ add-on เพิ่ม limit รายบริการ (เช่น +MAU, +storage)
  • Stripe integration — ชำระเงินผ่าน credit card และ PromptPay ผ่าน Stripe
  • Entitlement API — ให้ service อื่นตรวจสอบ plan + effective limits ต่อ org
  • Self-serve checkout — Starter / Pro สั่งซื้อเองได้ใน Console ผ่าน Stripe Checkout
  • Invoice management — สร้างและส่ง invoice อัตโนมัติทุกรอบ billing
  • Usage tracking — รับ usage metrics จาก services เพื่อตรวจสอบกับ plan limits

Plans

PlanPriceTarget
Free฿0 / เดือนทดลองใช้, สตาร์ทอัพ early stage
Starter฿990 / เดือน / orgทีมเล็ก, early traction
Pro฿3,900 / เดือน / orgทีมที่โตแล้ว, production
Enterpriseติดต่อ salesองค์กรขนาดใหญ่, custom SLA

How it works

Plan enforcement flow

ทุก service ต้องตรวจสอบ entitlement ก่อน process request:

Self-serve purchase flow

Stripe webhook events

Data model

Entitlement API

Service อื่นเรียก endpoint นี้ก่อน process ทุก request ที่มี limit:

GET /billing/orgs/:orgId/entitlements

Response:

{
  "orgId": "org_xxxx",
  "plan": "pro",
  "status": "active",
  "limits": {
    "pip": { "mau": 10000, "applications": 10 },
    "cockpit": { "campaigns": -1, "members": 20 },
    "content_os": { "brands": 5, "assets_gb": 50 },
    "notification": { "sends_per_month": 100000 },
    "mail": { "sends_per_month": 50000 },
    "storage": { "gb": 100 }
  },
  "addOns": [
    { "service": "pip", "resource": "mau", "quantity": 5000 }
  ]
}

-1 หมายถึงไม่จำกัด (unlimited)

Effective limit = base plan limit + sum of add-ons

Service อื่นไม่ต้องคำนวณเอง — limits ที่คืนมาคือ effective limit แล้ว

Plan enforcement responses

# Feature / service not included in plan
HTTP 403
{
  "code": "SERVICE_NOT_INCLUDED",
  "service": "cockpit",
  "requiredPlan": "starter",
  "upgradeUrl": "https://console.pcampus.co/billing/upgrade"
}

# Limit exceeded
HTTP 402
{
  "code": "PLAN_LIMIT_EXCEEDED",
  "service": "pip",
  "limit": "mau",
  "current": 5000,
  "max": 5000,
  "upgradeUrl": "https://console.pcampus.co/billing/upgrade"
}

Security

  • stripe_customer_id, stripe_subscription_id, stripe_price_id เก็บใน DB เท่านั้น
  • ห้ามเก็บ card number ทุกอย่าง tokenize ผ่าน Stripe
  • STRIPE_SECRET_KEY และ STRIPE_WEBHOOK_SECRET เก็บเป็น env var เท่านั้น — ห้าม hardcode ใน code หรือ repo
  • Verify webhook signature ทุกครั้งด้วย STRIPE_WEBHOOK_SECRET

Integration

  • ทุก service — เรียก Billing entitlement API ก่อน enforce limits
  • PIP — access check (billing.read, billing.subscription.write)
  • Notification → Mail — ส่ง invoice, payment success/failure ถึง org admin

API overview

MethodEndpointDescription
GET/billing/orgs/:orgId/entitlementsGet plan + effective limits
GET/billing/orgs/:orgId/subscriptionGet subscription details
POST/billing/checkoutCreate Stripe Checkout session
POST/billing/addonsPurchase add-on
GET/billing/invoicesList invoices
GET/billing/invoices/:idGet invoice detail
GET/billing/payment-methodsList payment methods
DELETE/billing/payment-methods/:idRemove payment method
POST/billing/webhooks/stripeStripe webhook receiver
POST/billing/usageReport usage from service
⚠️

POST /billing/webhooks/stripe ต้องเปิด public โดยไม่ผ่าน PIP access check แต่ต้อง verify Stripe signature ทุก request

Billing

Base URL: https://billing-api.pcampus.co

Overview

Billing is the subscription management service responsible for everything related to money and plans in Pcampus — from managing each organization's tier and processing payments via Stripe, to providing the entitlement API that every service calls to check which features an org is permitted to use.

Developer note: During development, use the entitlement stub that always returns the pro plan until the Billing service is fully implemented, so other services can continue development immediately.

Who uses this

PersonaWhat they do
Internal serviceEvery service calls /billing/orgs/:orgId/entitlements to verify entitlements
Org AdminPurchase plans, view invoices, manage payment methods via Console
Enterprise customerContact the sales team for a custom plan
Finance AdminView revenue, subscription status, and invoices for all orgs

Key features

  • Plan management — Free / Starter / Pro / Enterprise tiers per organization
  • Add-on management — Purchase add-ons to increase per-service limits (e.g. +MAU, +storage)
  • Stripe integration — Accept payments via credit card and PromptPay through Stripe
  • Entitlement API — Lets other services check the plan + effective limits per org
  • Self-serve checkout — Starter / Pro can be purchased self-serve in Console via Stripe Checkout
  • Invoice management — Automatically generate and send invoices every billing cycle
  • Usage tracking — Receive usage metrics from services to check against plan limits

Plans

PlanPriceTarget
Free฿0 / monthTrial, early-stage startups
Starter฿990 / month / orgSmall teams, early traction
Pro฿3,900 / month / orgEstablished teams, production
EnterpriseContact salesLarge organizations, custom SLA

How it works

Plan enforcement flow

Every service must check entitlements before processing a request:

Self-serve purchase flow

Stripe webhook events

Data model

Entitlement API

Other services call this endpoint before processing every request that has a limit:

GET /billing/orgs/:orgId/entitlements

Response:

{
  "orgId": "org_xxxx",
  "plan": "pro",
  "status": "active",
  "limits": {
    "pip": { "mau": 10000, "applications": 10 },
    "cockpit": { "campaigns": -1, "members": 20 },
    "content_os": { "brands": 5, "assets_gb": 50 },
    "notification": { "sends_per_month": 100000 },
    "mail": { "sends_per_month": 50000 },
    "storage": { "gb": 100 }
  },
  "addOns": [
    { "service": "pip", "resource": "mau", "quantity": 5000 }
  ]
}

-1 means unlimited.

Effective limit = base plan limit + sum of add-ons

Other services do not need to calculate this themselves — the limits returned are already the effective limits.

Plan enforcement responses

# Feature / service not included in plan
HTTP 403
{
  "code": "SERVICE_NOT_INCLUDED",
  "service": "cockpit",
  "requiredPlan": "starter",
  "upgradeUrl": "https://console.pcampus.co/billing/upgrade"
}

# Limit exceeded
HTTP 402
{
  "code": "PLAN_LIMIT_EXCEEDED",
  "service": "pip",
  "limit": "mau",
  "current": 5000,
  "max": 5000,
  "upgradeUrl": "https://console.pcampus.co/billing/upgrade"
}

Security

  • stripe_customer_id, stripe_subscription_id, stripe_price_id are stored in the database only
  • Card numbers must never be stored — everything is tokenized through Stripe
  • STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET must be stored as environment variables only — never hardcode them in code or in the repo
  • Always verify the webhook signature with STRIPE_WEBHOOK_SECRET

Integration

  • Every service — calls the Billing entitlement API before enforcing limits
  • PIP — access check (billing.read, billing.subscription.write)
  • Notification → Mail — sends invoice, payment success/failure notifications to the org admin

API overview

MethodEndpointDescription
GET/billing/orgs/:orgId/entitlementsGet plan + effective limits
GET/billing/orgs/:orgId/subscriptionGet subscription details
POST/billing/checkoutCreate Stripe Checkout session
POST/billing/addonsPurchase add-on
GET/billing/invoicesList invoices
GET/billing/invoices/:idGet invoice detail
GET/billing/payment-methodsList payment methods
DELETE/billing/payment-methods/:idRemove payment method
POST/billing/webhooks/stripeStripe webhook receiver
POST/billing/usageReport usage from service
⚠️

POST /billing/webhooks/stripe must be publicly accessible without going through the PIP access check, but must verify the Stripe signature on every request.