feat:mollie and footer

This commit is contained in:
2026-03-05 16:08:33 +01:00
parent 835f0941dc
commit 3f5bb61e35
15 changed files with 580 additions and 293 deletions

View File

@@ -134,82 +134,49 @@ export const drinkkaartRouter = {
.handler(async ({ input, context }) => {
const { env: serverEnv, session } = context;
if (
!serverEnv.LEMON_SQUEEZY_API_KEY ||
!serverEnv.LEMON_SQUEEZY_STORE_ID ||
!serverEnv.LEMON_SQUEEZY_DRINKKAART_VARIANT_ID
) {
if (!serverEnv.MOLLIE_API_KEY) {
throw new ORPCError("INTERNAL_SERVER_ERROR", {
message: "Lemon Squeezy Drinkkaart variant is niet geconfigureerd",
message: "Mollie is niet geconfigureerd",
});
}
const card = await getOrCreateDrinkkaart(session.user.id);
const response = await fetch(
"https://api.lemonsqueezy.com/v1/checkouts",
{
method: "POST",
headers: {
Accept: "application/vnd.api+json",
"Content-Type": "application/vnd.api+json",
Authorization: `Bearer ${serverEnv.LEMON_SQUEEZY_API_KEY}`,
},
body: JSON.stringify({
data: {
type: "checkouts",
attributes: {
custom_price: input.amountCents,
product_options: {
name: "Drinkkaart Opladen",
description: `Drinkkaart top-up — ${formatCents(input.amountCents)}`,
redirect_url: `${serverEnv.BETTER_AUTH_URL}/account?topup=success`,
},
checkout_data: {
email: session.user.email,
name: session.user.name,
custom: {
type: "drinkkaart_topup",
drinkkaartId: card.id,
userId: session.user.id,
},
},
checkout_options: {
embed: false,
locale: "nl",
},
},
relationships: {
store: {
data: {
type: "stores",
id: serverEnv.LEMON_SQUEEZY_STORE_ID,
},
},
variant: {
data: {
type: "variants",
id: serverEnv.LEMON_SQUEEZY_DRINKKAART_VARIANT_ID,
},
},
},
},
}),
// Mollie amounts must be formatted as "10.00" (string, 2 decimal places)
const amountValue = (input.amountCents / 100).toFixed(2);
const response = await fetch("https://api.mollie.com/v2/payments", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${serverEnv.MOLLIE_API_KEY}`,
},
);
body: JSON.stringify({
amount: { value: amountValue, currency: "EUR" },
description: `Drinkkaart Opladen — ${formatCents(input.amountCents)}`,
redirectUrl: `${serverEnv.BETTER_AUTH_URL}/account?topup=success`,
webhookUrl: `${serverEnv.BETTER_AUTH_URL}/api/webhook/mollie`,
locale: "nl_NL",
metadata: {
type: "drinkkaart_topup",
drinkkaartId: card.id,
userId: session.user.id,
},
}),
});
if (!response.ok) {
const errorData = await response.json();
console.error("Lemon Squeezy Drinkkaart checkout error:", errorData);
console.error("Mollie Drinkkaart checkout error:", errorData);
throw new ORPCError("INTERNAL_SERVER_ERROR", {
message: "Kon checkout niet aanmaken",
});
}
const data = (await response.json()) as {
data?: { attributes?: { url?: string } };
_links?: { checkout?: { href?: string } };
};
const checkoutUrl = data.data?.attributes?.url;
const checkoutUrl = data._links?.checkout?.href;
if (!checkoutUrl) {
throw new ORPCError("INTERNAL_SERVER_ERROR", {
message: "Geen checkout URL ontvangen",