build(stripe): upgrade Stripe API to Dahlia, migrate field changes - #426
Draft
th0rgall wants to merge 1 commit into
Draft
build(stripe): upgrade Stripe API to Dahlia, migrate field changes#426th0rgall wants to merge 1 commit into
th0rgall wants to merge 1 commit into
Conversation
th0rgall
had a problem deploying
to
e2e-test-emulators
May 20, 2026 15:55 — with
GitHub Actions
Failure
th0rgall
force-pushed
the
claude/update-stripe-components-F31BI
branch
from
May 21, 2026 15:28
e4c91c0 to
07e5641
Compare
th0rgall
had a problem deploying
to
e2e-test-emulators
May 21, 2026 15:28 — with
GitHub Actions
Failure
…nges Pins stripe-node to v21 (which defaults to apiVersion 2026-03-25.dahlia) and updates STRIPE_VERSION env templates accordingly. svelte-stripe was already on v2 (the Svelte 5 release from PR #131) — no frontend changes beyond confirming our PaymentPage already uses the v2 patterns. The bulk of the diff is migrating away from fields that Basil removed: - subscription.current_period_{start,end} → items.data[0].current_period_* - invoice.subscription → invoice.parent.subscription_details.subscription - invoice.payment_intent → invoice.payments[].payment.payment_intent - invoice.charge → invoice.payments[].payment.payment_intent.latest_charge - PaymentIntent.invoice → stripe.invoicePayments.list({ payment: ... }) - invoice.lines.data[].price.unit_amount → lines.data[].pricing.unit_amount_decimal A new api/src/subscriptions/basilCompat.js centralises these accessors so each call site reads naturally and the migration rationale lives in one place.
th0rgall
force-pushed
the
claude/update-stripe-components-F31BI
branch
from
May 21, 2026 15:28
07e5641 to
b104ef0
Compare
th0rgall
had a problem deploying
to
e2e-test-emulators
May 21, 2026 15:29 — with
GitHub Actions
Failure
|
Visit the preview URL for this PR (updated for commit b104ef0): https://wtmg-dev--pr426-claude-update-stripe-wqgc2dp4.web.app (expires Sat, 20 Jun 2026 15:32:29 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 7773005e481e8bc60fd60a58f2d818cc7378f95b |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Maintenance update of our Stripe components per request.
Frontend (
svelte-stripe). We already declared^2.0.0inpackage.json, and the lockfile already resolves to2.0.0(the Svelte 5 release from joshnuss/svelte-stripe#131, published 2026-01-22). I auditedPaymentPage.svelteagainst the v2 API:bind:elementsis still supported, callback-style event props (onready) are correct, and we don't use any of the renamed props (e.g. the oldtheme="flat"shorthand that becameappearance={{ theme: 'flat' }}). No changes were needed; the dependency is already on the version the user asked for.Backend (
stripe-node+ API version). Bumped from^17.7.0(which pins to2024-10-28.acacia) to^21.0.0(which pins to2026-03-25.dahlia, the first Dahlia release).STRIPE_VERSIONenv templates updated accordingly. Between Acacia and Dahlia, Basil (2025-03-31) is the version that actually broke shape on every object we touch; Clover and Dahlia only added more changes that don't materially affect us (V2 event-notification renames in stripe-node v19 — we don't use V2 events;decimal_stringtypes becomingStripe.Decimalin v21 — we only had one such read, see below).Basil field migrations applied
subscription.current_period_{start,end}subscription.items.data[0].current_period_*invoice.subscription(string id)invoice.parent.subscription_details.subscriptionparentfield — invoices can also originate from quotes, etc.invoice.payment_intentinvoice.payments[].payment.payment_intentinvoice.charge(expand:charge)invoice.payments[].payment.payment_intent.latest_chargePaymentIntent.invoicestripe.invoicePayments.list({ payment: { type: 'payment_intent', payment_intent } })invoices/:id/attach_paymentendpoint also lets one PI settle multiple invoices (overpayments, wires), so the singular field stopped being well-defined. Lookup now goes through theInvoicePaymentjoin object.invoice.lines.data[].price.unit_amount(number)invoice.lines.data[].pricing.unit_amount_decimal(string/Decimal)pricingobject on line items, unifying Price/Plan and preparing for new pricing typesAll accessors are centralised in
api/src/subscriptions/basilCompat.jsso each call site stays readable and the rationale lives in one place. Files updated:createOrRetrieveUnpaidSubscription.js— refactored to return{ subscription, clientSecret }from helpers and to walk the newinvoice.paymentsgraph for both expanded list queries and the existing-incomplete reuse path. The cloud-function wire response shape ({ subscriptionId, clientSecret }) is unchanged, so the frontend payment flow doesn't change.subscriptionUpdated.js,subscriptionDeleted.js— use the item-level period via the helper.invoiceCreated.js,invoicePaid.js,invoiceUpcoming.js— read subscription id fromparent.subscription_details, read PI / Charge / unit amount via helpers.paymentIntentProcessing.js,paymentIntentPaymentFailed.js— use the newInvoicePaymentlist endpoint to find the related invoice (previouslypaymentIntent.invoice). We uselimit: 1because a subscription-generated PI is always attached to exactly one invoice in our flow.api/test/util/stripe.js,api/test/{sendInvoice,chargeAutomatically}.test.js— same migrations.The Firestore document shape (
stripeSubscription.currentPeriodStart/End, etc.) is unchanged, so no data migration is required and the frontendUser.tsmodel + stores keep working as-is.Things explicitly not changed
subscriptions.createstill usesexpand: ['latest_invoice'](still valid; we just don't deep-expandpayment_intentany more — we fetch it separately via theinvoice.paymentsgraph).subscriptions.cancelreturning a stringlatest_invoiceincancelUnpaidManualRenewals.jsis still valid for non-expanded subscriptions.?version=query param vsSTRIPE_VERSION) still works lexicographically across Acacia → Basil → Clover → Dahlia because the date prefix sorts correctly.Cannot verify locally
Per the task description there's no access to a Stripe sandbox in this session, so I haven't exercised the full payment / renewal flows. The diff follows the patterns documented in the Basil and Dahlia changelogs, but a sandbox run before merging is strongly advised — especially around the SEPA generated-from-Bancontact mandate retrieval in
invoiceUpcoming.js(the trickiest path through the newinvoice.paymentsgraph).Test plan
yarn installat the repo root andyarn installunderapi/after pulling the branch.STRIPE_VERSION=2026-03-25.dahlia.STRIPE_VERSIONenv values, and re-point the webhook endpoint to send2026-03-25.dahliaevents.