chore: initialize repository with deployment baseline
This commit is contained in:
71
backend/src/routes/payment.routes.ts
Normal file
71
backend/src/routes/payment.routes.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user