fix(scripts): helcim plan-create payload shape + empty-GET handling
Verified against the live Helcim v2 API during the deploy migration:
- POST /payment-plans requires { paymentPlans: [plan] } wrapper (mirrors
the POST /subscriptions shape), and response is { data: [plan] }.
- taxType 'customer' rejects as ERR_VALIDATION_FAILED; must be 'no_tax'
with taxCalculation 'country_province'.
- termLength:1 rejects when termType:'forever' — drop the field.
- GET /subscriptions returns an empty body (not JSON) when no subs exist;
tolerate that instead of failing with 'Unexpected end of JSON input'.
Plans created in the Helcim account: Monthly=50302, Annual=50303.
This commit is contained in:
parent
f8e0cf36ba
commit
549a849bc0
1 changed files with 19 additions and 10 deletions
|
|
@ -44,8 +44,12 @@ const ANNUAL_PLAN = {
|
||||||
billingPeriod: 'yearly',
|
billingPeriod: 'yearly',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shape mirrors the pre-migration legacy plans (verified via backup dump).
|
||||||
|
// taxType:'customer' + missing taxCalculation/termLength caused ERR_VALIDATION_FAILED.
|
||||||
const HELCIM_PLAN_PAYLOAD_BASE = {
|
const HELCIM_PLAN_PAYLOAD_BASE = {
|
||||||
description: 'Ghost Guild membership',
|
businessName: '',
|
||||||
|
businessEmail: '',
|
||||||
|
description: '',
|
||||||
type: 'subscription',
|
type: 'subscription',
|
||||||
status: 'active',
|
status: 'active',
|
||||||
currency: 'CAD',
|
currency: 'CAD',
|
||||||
|
|
@ -54,8 +58,10 @@ const HELCIM_PLAN_PAYLOAD_BASE = {
|
||||||
dateBilling: 'Sign-up',
|
dateBilling: 'Sign-up',
|
||||||
termType: 'forever',
|
termType: 'forever',
|
||||||
freeTrialPeriod: 0,
|
freeTrialPeriod: 0,
|
||||||
taxType: 'customer',
|
taxType: 'no_tax',
|
||||||
|
taxCalculation: 'country_province',
|
||||||
paymentMethod: 'card',
|
paymentMethod: 'card',
|
||||||
|
isProrated: 'no',
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
@ -87,11 +93,12 @@ async function helcimGet(path) {
|
||||||
const res = await fetch(`${HELCIM_API_BASE}${path}`, {
|
const res = await fetch(`${HELCIM_API_BASE}${path}`, {
|
||||||
headers: helcimHeaders(),
|
headers: helcimHeaders(),
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
|
||||||
const body = await res.text()
|
const body = await res.text()
|
||||||
|
if (!res.ok) {
|
||||||
throw new Error(`GET ${path} failed (${res.status}): ${body}`)
|
throw new Error(`GET ${path} failed (${res.status}): ${body}`)
|
||||||
}
|
}
|
||||||
return res.json()
|
if (!body.trim()) return []
|
||||||
|
try { return JSON.parse(body) } catch { return [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function helcimDelete(path) {
|
async function helcimDelete(path) {
|
||||||
|
|
@ -280,9 +287,10 @@ async function main() {
|
||||||
console.log(` [DRY RUN] Would POST /payment-plans with:`)
|
console.log(` [DRY RUN] Would POST /payment-plans with:`)
|
||||||
console.log(' ', JSON.stringify(monthlyPayload, null, 4).split('\n').join('\n '))
|
console.log(' ', JSON.stringify(monthlyPayload, null, 4).split('\n').join('\n '))
|
||||||
} else {
|
} else {
|
||||||
|
const wrapped = { paymentPlans: [monthlyPayload] }
|
||||||
console.log(` POSTing /payment-plans with:`)
|
console.log(` POSTing /payment-plans with:`)
|
||||||
console.log(' ', JSON.stringify(monthlyPayload, null, 4).split('\n').join('\n '))
|
console.log(' ', JSON.stringify(wrapped, null, 4).split('\n').join('\n '))
|
||||||
const result = await helcimPost('/payment-plans', monthlyPayload)
|
const result = await helcimPost('/payment-plans', wrapped)
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
console.error(` [ERROR] POST failed (${result.status}):`)
|
console.error(` [ERROR] POST failed (${result.status}):`)
|
||||||
console.error(' ', JSON.stringify(result.body, null, 2))
|
console.error(' ', JSON.stringify(result.body, null, 2))
|
||||||
|
|
@ -290,7 +298,7 @@ async function main() {
|
||||||
await mongoose.disconnect()
|
await mongoose.disconnect()
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
monthlyPlanId = result.body.id
|
monthlyPlanId = result.body.data?.[0]?.id ?? result.body.paymentPlans?.[0]?.id ?? result.body.id
|
||||||
console.log(` [OK] Created Monthly Membership plan id: ${monthlyPlanId}`)
|
console.log(` [OK] Created Monthly Membership plan id: ${monthlyPlanId}`)
|
||||||
}
|
}
|
||||||
console.log()
|
console.log()
|
||||||
|
|
@ -313,9 +321,10 @@ async function main() {
|
||||||
console.log(' Note: billingPeriod="yearly" is Helcim v2 convention.')
|
console.log(' Note: billingPeriod="yearly" is Helcim v2 convention.')
|
||||||
console.log(' If 4xx on --confirm, check the Helcim API docs for the correct field value.')
|
console.log(' If 4xx on --confirm, check the Helcim API docs for the correct field value.')
|
||||||
} else {
|
} else {
|
||||||
|
const wrapped = { paymentPlans: [annualPayload] }
|
||||||
console.log(` POSTing /payment-plans with:`)
|
console.log(` POSTing /payment-plans with:`)
|
||||||
console.log(' ', JSON.stringify(annualPayload, null, 4).split('\n').join('\n '))
|
console.log(' ', JSON.stringify(wrapped, null, 4).split('\n').join('\n '))
|
||||||
const result = await helcimPost('/payment-plans', annualPayload)
|
const result = await helcimPost('/payment-plans', wrapped)
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
console.error(` [ERROR] POST failed (${result.status}):`)
|
console.error(` [ERROR] POST failed (${result.status}):`)
|
||||||
console.error(' ', JSON.stringify(result.body, null, 2))
|
console.error(' ', JSON.stringify(result.body, null, 2))
|
||||||
|
|
@ -324,7 +333,7 @@ async function main() {
|
||||||
await mongoose.disconnect()
|
await mongoose.disconnect()
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
annualPlanId = result.body.id
|
annualPlanId = result.body.data?.[0]?.id ?? result.body.paymentPlans?.[0]?.id ?? result.body.id
|
||||||
console.log(` [OK] Created Annual Membership plan id: ${annualPlanId}`)
|
console.log(` [OK] Created Annual Membership plan id: ${annualPlanId}`)
|
||||||
}
|
}
|
||||||
console.log()
|
console.log()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue