feat(payments): persist helcimCustomerCode + skip getOrCreateCustomer on card-on-file

This commit is contained in:
Jennie Robinson Faber 2026-04-27 11:54:54 +01:00
parent 0a41b30db7
commit ac5e979c78
10 changed files with 330 additions and 33 deletions

View file

@ -8,7 +8,7 @@
*/
import Member from '../../models/member.js'
import Payment from '../../models/payment.js'
import { listHelcimCustomerTransactions } from '../../utils/helcim.js'
import { getHelcimCustomer, listHelcimCustomerTransactions } from '../../utils/helcim.js'
import { connectDB } from '../../utils/mongoose.js'
import { upsertPaymentFromHelcim } from '../../utils/payments.js'
@ -56,7 +56,7 @@ export default defineEventHandler(async (event) => {
const members = await Member.find(
{ helcimCustomerId: { $exists: true, $ne: null } },
{ _id: 1, email: 1, name: 1, helcimCustomerId: 1, helcimSubscriptionId: 1, billingCadence: 1 }
{ _id: 1, email: 1, name: 1, helcimCustomerId: 1, helcimCustomerCode: 1, helcimSubscriptionId: 1, billingCadence: 1 }
).lean()
let txExamined = 0
@ -66,6 +66,25 @@ export default defineEventHandler(async (event) => {
let memberErrors = 0
async function processMember(member) {
// Opportunistic backfill: members predating the helcimCustomerCode field
// get it filled in here so the daily cron acts as the migration. Only on
// the missing path — no overwrite, no extra API call once populated.
if (!member.helcimCustomerCode) {
try {
const customer = await getHelcimCustomer(member.helcimCustomerId)
if (customer?.customerCode) {
await Member.findByIdAndUpdate(
member._id,
{ $set: { helcimCustomerCode: customer.customerCode } },
{ runValidators: false }
)
}
} catch (err) {
// Backfill is best-effort — never fail the reconcile run on it.
console.warn(`[reconcile] customerCode backfill failed for member=${member._id}: ${err?.message || err}`)
}
}
let txs
try {
txs = await listTransactionsWithRetry(member.helcimCustomerId)