72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
import { Router } from "express";
|
|
import { z } from "zod";
|
|
import { authorize, requireAuth } from "../middleware/auth";
|
|
import {
|
|
createInvoicePaymentLink,
|
|
handleManualInvoicePayment,
|
|
processFlutterwaveWebhook,
|
|
processPaystackWebhook,
|
|
verifyFlutterwaveSignature,
|
|
verifyPaystackSignature
|
|
} from "../services/payment.service";
|
|
|
|
const router = Router();
|
|
|
|
const createLinkSchema = z.object({
|
|
provider: z.enum(["paystack", "flutterwave", "manual"]).optional()
|
|
});
|
|
|
|
router.post("/invoices/:id/link", requireAuth, authorize("billing:manage"), async (req, res, next) => {
|
|
try {
|
|
const payload = createLinkSchema.parse(req.body ?? {});
|
|
const result = await createInvoicePaymentLink(req.params.id, payload.provider);
|
|
res.json(result);
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
const manualSchema = z.object({
|
|
payment_reference: z.string().min(2)
|
|
});
|
|
|
|
router.post("/invoices/:id/manual-pay", requireAuth, authorize("billing:manage"), async (req, res, next) => {
|
|
try {
|
|
const payload = manualSchema.parse(req.body ?? {});
|
|
const invoice = await handleManualInvoicePayment(req.params.id, payload.payment_reference, req.user?.email ?? "manual@system");
|
|
res.json(invoice);
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
router.post("/webhooks/paystack", async (req, res, next) => {
|
|
try {
|
|
const signature = req.header("x-paystack-signature");
|
|
const valid = await verifyPaystackSignature(signature, req.rawBody);
|
|
if (!valid) {
|
|
return res.status(401).json({ error: { code: "INVALID_SIGNATURE", message: "Invalid signature" } });
|
|
}
|
|
const result = await processPaystackWebhook(req.body);
|
|
return res.json(result);
|
|
} catch (error) {
|
|
return next(error);
|
|
}
|
|
});
|
|
|
|
router.post("/webhooks/flutterwave", async (req, res, next) => {
|
|
try {
|
|
const signature = req.header("verif-hash");
|
|
const valid = await verifyFlutterwaveSignature(signature);
|
|
if (!valid) {
|
|
return res.status(401).json({ error: { code: "INVALID_SIGNATURE", message: "Invalid signature" } });
|
|
}
|
|
const result = await processFlutterwaveWebhook(req.body);
|
|
return res.json(result);
|
|
} catch (error) {
|
|
return next(error);
|
|
}
|
|
});
|
|
|
|
export default router;
|