//native
/**
* Cancel Subscription
* Cancel a subscription now, or at the end of the current period when `at_period_end` is set (it stays active until then and can be resumed by updating `cancel_at_period_end`). `invoice_now` and `prorate` apply to immediate cancellation only.
*/
export async function main(
auth: RT.Stripe,
subscription_id: string,
at_period_end: boolean | undefined,
invoice_now: boolean | undefined,
prorate: boolean | undefined,
comment: string | undefined
) {
const url = new URL(
`https://api.stripe.com/v1/subscriptions/${subscription_id}`
)
const headers = {
Authorization: `Bearer ${auth.token}`,
Accept: "application/json",
"Stripe-Version": "2025-03-31.basil",
}
let response: Response
if (at_period_end) {
response = await fetch(url, {
method: "POST",
headers: {
...headers,
"Content-Type": "application/x-www-form-urlencoded",
},
body: toForm({
cancel_at_period_end: true,
cancellation_details: { comment },
}),
})
} else {
url.search = toForm({
invoice_now: invoice_now || undefined,
prorate: prorate || undefined,
cancellation_details: { comment },
}).toString()
response = await fetch(url, { method: "DELETE", headers })
}
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
return await response.json()
}
// Stripe takes form-encoded params with bracketed nesting: metadata[key]=v, items[0][price]=p
function toForm(
params: { [key: string]: any },
prefix = "",
out = new URLSearchParams()
) {
for (const [key, value] of Object.entries(params)) {
if (value == null || value === "") continue
const name = prefix ? `${prefix}[${key}]` : key
if (typeof value === "object") toForm(value, name, out)
else out.append(name, String(value))
}
return out
}
Submitted by hugo989 3 hours ago