fix stripe error
Build & Push / Pipeline Tests (push) Successful in 1m51s
Test / Type Check (all packages) (push) Successful in 55s
Build & Push / Build & Push Docker Image (push) Successful in 5m44s
Test / API Unit Tests (push) Successful in 1m12s
Test / Homepage Unit Tests (push) Successful in 47s
Test / Carplace Unit Tests (push) Successful in 46s
Test / Admin Unit Tests (push) Successful in 43s
Test / Dashboard Unit Tests (push) Successful in 44s
Test / API Integration Tests (push) Successful in 1m8s
Build & Push / Pipeline Tests (push) Successful in 1m51s
Test / Type Check (all packages) (push) Successful in 55s
Build & Push / Build & Push Docker Image (push) Successful in 5m44s
Test / API Unit Tests (push) Successful in 1m12s
Test / Homepage Unit Tests (push) Successful in 47s
Test / Carplace Unit Tests (push) Successful in 46s
Test / Admin Unit Tests (push) Successful in 43s
Test / Dashboard Unit Tests (push) Successful in 44s
Test / API Integration Tests (push) Successful in 1m8s
This commit is contained in:
@@ -74,18 +74,9 @@ webhookRouter.post('/webhooks/stripe', async (req, res, next) => {
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
// ─── PayPal capture (auth but no subscription check) ──────────
|
||||
// ─── Authenticated billing recovery/self-service ───────────────
|
||||
|
||||
router.post('/capture-paypal', requireCompanyAuth, requireTenant, requireSubscriptionFull, requireRole('OWNER'), async (req, res, next) => {
|
||||
try {
|
||||
const { paypalOrderId } = parseBody(capturePaypalSchema, req)
|
||||
ok(res, await service.capturePaypal(req.companyId, paypalOrderId))
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
// ─── Authenticated ─────────────────────────────────────────────
|
||||
|
||||
router.use(requireCompanyAuth, requireTenant, requireSubscriptionRead)
|
||||
router.use(requireCompanyAuth, requireTenant)
|
||||
|
||||
router.get('/me', async (req, res, next) => {
|
||||
try { ok(res, await service.getSubscription(req.companyId)) } catch (err) { next(err) }
|
||||
@@ -103,34 +94,45 @@ router.get('/entitlement', async (req, res, next) => {
|
||||
try { ok(res, await service.getEntitlement(req.companyId)) } catch (err) { next(err) }
|
||||
})
|
||||
|
||||
router.post('/trial', requireSubscriptionFull, requireRole('OWNER'), async (req, res, next) => {
|
||||
router.post('/trial', requireRole('OWNER'), async (req, res, next) => {
|
||||
try {
|
||||
const body = parseBody(startTrialSchema, req)
|
||||
ok(res, await service.startTrial(req.companyId, body.plan, body.billingPeriod, body.currency))
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
router.post('/checkout', requireSubscriptionFull, requireRole('OWNER'), async (req, res, next) => {
|
||||
router.post('/checkout', requireRole('OWNER'), async (req, res, next) => {
|
||||
try {
|
||||
const body = parseBody(checkoutSchema, req)
|
||||
ok(res, await service.checkout(req.companyId, body))
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
router.post('/reactivate', requireSubscriptionFull, requireRole('OWNER'), async (req, res, next) => {
|
||||
router.post('/reactivate', requireRole('OWNER'), async (req, res, next) => {
|
||||
try {
|
||||
const body = parseBody(reactivateSchema, req)
|
||||
ok(res, await service.reactivate(req.companyId, body))
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
router.post('/change-plan', requireSubscriptionFull, requireRole('OWNER'), async (req, res, next) => {
|
||||
router.post('/change-plan', requireRole('OWNER'), async (req, res, next) => {
|
||||
try {
|
||||
const body = parseBody(changePlanSchema, req)
|
||||
ok(res, await service.changePlan(req.companyId, body))
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
router.post('/capture-paypal', requireRole('OWNER'), async (req, res, next) => {
|
||||
try {
|
||||
const { paypalOrderId } = parseBody(capturePaypalSchema, req)
|
||||
ok(res, await service.capturePaypal(req.companyId, paypalOrderId))
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
// ─── Active subscription actions ───────────────────────────────
|
||||
|
||||
router.use(requireSubscriptionRead)
|
||||
|
||||
router.post('/cancel', requireSubscriptionFull, requireRole('OWNER'), async (req, res, next) => {
|
||||
try {
|
||||
const { mode, reason } = parseBody(cancelSchema, req)
|
||||
|
||||
@@ -128,6 +128,26 @@ describe('Subscriptions API', () => {
|
||||
expect(res.body.data.some((item: any) => item.id === invoice.id)).toBe(true)
|
||||
})
|
||||
|
||||
it('allows expired subscriptions to read billing recovery data', async () => {
|
||||
const { company, employee } = await createCompanyWithEmployee({ role: 'OWNER' })
|
||||
const subscription = await prisma.subscription.update({
|
||||
where: { companyId: company.id },
|
||||
data: { status: 'EXPIRED' },
|
||||
})
|
||||
const invoice = await createSubscriptionInvoice(company.id, subscription.id)
|
||||
const token = signEmployeeToken(employee.id, company.id, 'OWNER')
|
||||
|
||||
const [subscriptionRes, invoicesRes] = await Promise.all([
|
||||
request(app).get('/api/v1/subscriptions/me').set(authHeader(token)),
|
||||
request(app).get('/api/v1/subscriptions/invoices').set(authHeader(token)),
|
||||
])
|
||||
|
||||
expect(subscriptionRes.status).toBe(200)
|
||||
expect(subscriptionRes.body.data.status).toBe('EXPIRED')
|
||||
expect(invoicesRes.status).toBe(200)
|
||||
expect(invoicesRes.body.data.some((item: any) => item.id === invoice.id)).toBe(true)
|
||||
})
|
||||
|
||||
it('changes the subscription plan for OWNER', async () => {
|
||||
const res = await request(app)
|
||||
.post('/api/v1/subscriptions/change-plan')
|
||||
|
||||
Reference in New Issue
Block a user