feat(contribution): free-to-paid uses cadence plan id, persists billingCadence

This commit is contained in:
Jennie Robinson Faber 2026-04-18 17:37:35 +01:00
parent e8c81cf062
commit 0eeed94772
2 changed files with 180 additions and 21 deletions

View file

@ -53,6 +53,20 @@ export default defineEventHandler(async (event) => {
});
}
// Resolve plan id before entering the try/catch (so missing plan → 500, not swallowed 400)
const cadence = body.cadence; // defaulted to 'monthly' by Zod
const paymentPlanId = getHelcimPlanId(cadence);
if (!paymentPlanId) {
throw createError({
statusCode: 500,
statusMessage: cadence === 'annual'
? 'Annual plan id not configured'
: 'Monthly plan id not configured',
});
}
const tierInfo = getContributionTierByValue(newTier);
try {
const customerData = await getHelcimCustomer(member.helcimCustomerId);
const customerCode = customerData.customerCode;
@ -61,7 +75,7 @@ export default defineEventHandler(async (event) => {
throw new Error("No customer code found");
}
// Check for saved cards (FIX: use the correct endpoint)
// Check for saved cards
const cards = await listHelcimCustomerCards(member.helcimCustomerId);
const hasCards = Array.isArray(cards) && cards.length > 0;
@ -69,27 +83,14 @@ export default defineEventHandler(async (event) => {
throw new Error("No saved payment methods");
}
// Create new subscription with saved payment method
const newPlanId = getHelcimPlanId(newTier);
if (!newPlanId) {
throw createError({
statusCode: 400,
statusMessage: `Plan not configured for tier ${newTier}`,
});
}
const idempotencyKey = generateIdempotencyKey();
// Get tier amount
const tierInfo = getContributionTierByValue(newTier);
const subscriptionData = await createHelcimSubscription(
{
dateActivated: new Date().toISOString().split("T")[0],
paymentPlanId: parseInt(newPlanId),
customerCode: customerCode,
recurringAmount: parseFloat(tierInfo.amount),
paymentPlanId: parseInt(paymentPlanId),
customerCode,
recurringAmount: getTierAmount(tierInfo, cadence),
paymentMethod: "card",
},
idempotencyKey,
@ -104,11 +105,17 @@ export default defineEventHandler(async (event) => {
// Update member record
await Member.findByIdAndUpdate(
member._id,
{ $set: { contributionTier: newTier, helcimSubscriptionId: subscription.id, paymentMethod: "card", status: "active" } },
{ $set: {
contributionTier: newTier,
helcimSubscriptionId: subscription.id,
paymentMethod: "card",
status: "active",
billingCadence: cadence,
} },
{ runValidators: false }
);
logContributionChange()
logContributionChange();
return {
success: true,
@ -145,7 +152,7 @@ export default defineEventHandler(async (event) => {
// Update member to free tier
await Member.findByIdAndUpdate(
member._id,
{ $set: { contributionTier: newTier, helcimSubscriptionId: null, paymentMethod: "none" } },
{ $set: { contributionTier: newTier, helcimSubscriptionId: null, paymentMethod: "none", billingCadence: "monthly" } },
{ runValidators: false }
);