Fix invoice status transitions, tip-split validation, refund idempotency, and tip-split response format #278

Merged
the-dogfather-cto[bot] merged 4 commits from fix/gro-637-invoice-refund-fixes into main 2026-04-15 06:04:38 +00:00
3 changed files with 37 additions and 17 deletions
Showing only changes of commit 8f06f32e7d - Show all commits
+4 -2
View File
@@ -395,8 +395,9 @@ invoicesRouter.post(
return c.json({ error: "No Stripe payment intent found for this invoice" }, 422);
}
return await db.transaction(async (tx) => {
if (body.idempotencyKey) {
const [existing] = await db
const [existing] = await tx
.select()
.from(refunds)
.where(eq(refunds.idempotencyKey, body.idempotencyKey));
@@ -408,7 +409,7 @@ invoicesRouter.post(
const result = await processRefund(id, body.amountCents);
if (!result) return c.json({ error: "Refund failed" }, 500);
await db.insert(refunds).values({
await tx.insert(refunds).values({
invoiceId: id,
stripeRefundId: result.refundId,
idempotencyKey: body.idempotencyKey ?? null,
@@ -416,5 +417,6 @@ invoicesRouter.post(
});
return c.json({ refundId: result.refundId });
});
}
);
+11
View File
@@ -0,0 +1,11 @@
CREATE TABLE "refunds" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
"invoice_id" uuid NOT NULL REFERENCES "invoices"("id") ON DELETE RESTRICT,
"stripe_refund_id" text NOT NULL,
"idempotency_key" text UNIQUE,
"amount_cents" integer,
"created_at" timestamp NOT NULL DEFAULT NOW()
);
CREATE INDEX "idx_refunds_invoice_id" ON "refunds"("invoice_id");
CREATE INDEX "idx_refunds_idempotency_key" ON "refunds"("idempotency_key");
@@ -190,6 +190,13 @@
"when": 1775568867192,
"tag": "0026_stripe_payment",
"breakpoints": true
},
{
"idx": 27,
"version": "7",
"when": 1775655267192,
"tag": "0027_refunds",
"breakpoints": true
}
]
}