feat: Shopier payment integration with 3DS callback + unified checkout action
This commit is contained in:
@@ -11,6 +11,7 @@ import { DATABASE_ID, TABLES, type SubscriptionPayment, type TenantPlan } from "
|
||||
import { createAdminClient } from "./server";
|
||||
import { requireRole, requireTenant } from "./tenant-guard";
|
||||
import { PLAN_CATALOG } from "./subscription-types";
|
||||
import { isShopierEnabled } from "../payments/shopier";
|
||||
|
||||
const PRO_VALIDITY_DAYS = 30;
|
||||
|
||||
@@ -218,3 +219,52 @@ export async function downgradeToFreeAction(): Promise<void> {
|
||||
revalidatePath("/settings/billing");
|
||||
redirect(`/settings/billing?downgraded=1`);
|
||||
}
|
||||
|
||||
export async function startShopierCheckoutAction(formData: FormData): Promise<void> {
|
||||
const plan = String(formData.get("plan") ?? "") as TenantPlan;
|
||||
if (plan !== "pro") throw new Error("Geçersiz plan.");
|
||||
|
||||
const ctx = await requireTenant();
|
||||
requireRole(ctx, ["owner"]);
|
||||
|
||||
const catalog = PLAN_CATALOG[plan];
|
||||
const orderId = generateOrderId();
|
||||
|
||||
const { tablesDB } = createAdminClient();
|
||||
await tablesDB.createRow(
|
||||
DATABASE_ID,
|
||||
TABLES.subscriptionPayments,
|
||||
ID.unique(),
|
||||
{
|
||||
tenantId: ctx.tenantId,
|
||||
createdBy: ctx.user.id,
|
||||
orderId,
|
||||
plan,
|
||||
amount: catalog.price,
|
||||
currency: catalog.currency,
|
||||
status: "pending",
|
||||
provider: "shopier",
|
||||
},
|
||||
teamRowPermissions(ctx.tenantId),
|
||||
);
|
||||
|
||||
await logAudit({
|
||||
tenantId: ctx.tenantId,
|
||||
userId: ctx.user.id,
|
||||
action: "create",
|
||||
entityType: "subscription_payment",
|
||||
entityId: orderId,
|
||||
changes: { plan, amount: catalog.price, provider: "shopier" },
|
||||
});
|
||||
|
||||
redirect(`/settings/billing/checkout/${orderId}/shopier`);
|
||||
}
|
||||
|
||||
// Unified entry point — branches on PAYMENT_PROVIDER env variable.
|
||||
// Set PAYMENT_PROVIDER=shopier in production; leave unset (or "mock") for testing.
|
||||
export async function startCheckoutAction(formData: FormData): Promise<void> {
|
||||
if (isShopierEnabled()) {
|
||||
return startShopierCheckoutAction(formData);
|
||||
}
|
||||
return startMockCheckoutAction(formData);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user