refractor code,

This commit is contained in:
root
2026-05-21 12:35:49 -04:00
parent e74681e810
commit f009ca10c6
158 changed files with 215801 additions and 5884 deletions
@@ -0,0 +1,114 @@
import { PLAN_PRICES } from '@rentaldrivego/types'
import { prisma } from '../../lib/prisma'
import { ValidationError } from '../../http/errors'
import * as amanpay from '../../services/amanpayService'
import * as paypal from '../../services/paypalService'
import * as repo from './subscription.repo'
export function addPeriod(date: Date, period: string): Date {
const d = new Date(date)
period === 'ANNUAL' ? d.setFullYear(d.getFullYear() + 1) : d.setMonth(d.getMonth() + 1)
return d
}
export function getPlans() {
return PLAN_PRICES
}
export function getProviders() {
return { amanpay: amanpay.isConfigured(), paypal: paypal.isConfigured() }
}
export function getSubscription(companyId: string) {
return repo.findByCompany(companyId)
}
export function getInvoices(companyId: string) {
return repo.findInvoices(companyId)
}
export async function handleAmanpayWebhook(event: any) {
const transactionId = event.transaction_id ?? event.id
const status = event.status?.toUpperCase()
if (status === 'PAID' || status === 'SUCCEEDED') {
const invoice = await repo.findInvoiceByAmanpay(transactionId)
if (invoice) {
await repo.markInvoicePaid(invoice.id)
await repo.activateSubscription(invoice.subscriptionId, addPeriod(new Date(), invoice.subscription.billingPeriod))
}
}
}
export async function handlePaypalWebhook(event: any) {
if (event.event_type === 'PAYMENT.CAPTURE.COMPLETED') {
const captureId = event.resource?.id as string
const invoice = await repo.findInvoiceByPaypal(captureId)
if (invoice) {
await repo.markInvoicePaid(invoice.id)
await repo.activateSubscription(invoice.subscriptionId, addPeriod(new Date(), invoice.subscription.billingPeriod))
}
}
}
export async function checkout(companyId: string, body: {
plan: 'STARTER' | 'GROWTH' | 'PRO'; billingPeriod: 'MONTHLY' | 'ANNUAL'
currency: 'MAD' | 'USD' | 'EUR'; provider: 'AMANPAY' | 'PAYPAL'
successUrl: string; failureUrl: string
}) {
const prices = PLAN_PRICES[body.plan]?.[body.billingPeriod]
if (!prices) throw new ValidationError('Invalid plan or billing period')
const amount = (prices as any)[body.currency]
if (!amount) throw new ValidationError('Currency not supported for this plan')
const company = await prisma.company.findUniqueOrThrow({ where: { id: companyId } })
const subscription = await repo.findOrCreateSubscription(companyId, body.plan, body.billingPeriod, body.currency)
const orderId = `sub-${companyId}-${Date.now()}`
const description = `${body.plan} plan — ${body.billingPeriod}`
const webhookBase = process.env.API_URL ?? 'http://localhost:4000'
let checkoutUrl: string
let amanpayTransactionId: string | null = null
let paypalCaptureId: string | null = null
if (body.provider === 'AMANPAY') {
if (!amanpay.isConfigured()) throw new ValidationError('AmanPay is not configured on this platform')
const result = await amanpay.createCheckout({
amount, currency: body.currency, orderId, description,
customerEmail: company.email, customerName: company.name,
successUrl: body.successUrl, failureUrl: body.failureUrl,
webhookUrl: `${webhookBase}/api/v1/subscriptions/webhooks/amanpay`,
})
checkoutUrl = result.checkoutUrl
amanpayTransactionId = result.transactionId
} else {
if (!paypal.isConfigured()) throw new ValidationError('PayPal is not configured on this platform')
const result = await paypal.createOrder({ amount, currency: body.currency, orderId, description, returnUrl: body.successUrl, cancelUrl: body.failureUrl })
checkoutUrl = result.approveUrl
paypalCaptureId = result.orderId
}
const invoice = await repo.createInvoice({ companyId, subscriptionId: subscription.id, amount, currency: body.currency, paymentProvider: body.provider, amanpayTransactionId, paypalCaptureId })
return { invoice, checkoutUrl }
}
export async function capturePaypal(companyId: string, paypalOrderId: string) {
const invoice = await repo.findInvoiceByPaypalForCompany(paypalOrderId, companyId)
const capture = await paypal.captureOrder(paypalOrderId) as Record<string, any>
const captureId = capture.purchase_units?.[0]?.payments?.captures?.[0]?.id ?? paypalOrderId
await repo.updateInvoicePaypal(invoice.id, captureId)
await repo.activateSubscription(invoice.subscriptionId, addPeriod(new Date(), invoice.subscription.billingPeriod))
return { success: true }
}
export function changePlan(companyId: string, data: { plan: any; billingPeriod: any; currency: string }) {
return repo.updatePlan(companyId, data)
}
export function cancel(companyId: string) {
return repo.setCancelAtPeriodEnd(companyId, true)
}
export function resume(companyId: string) {
return repo.setCancelAtPeriodEnd(companyId, false)
}