Repository navigation
fix(deps): Stripe — stripe 23, stripe-js 10, react-stripe-js 7, API 2026-09-30.endive (#433) - #441
Merged
Merged
Conversation
…09-30.endive (#433) Три мажора платёжного контура одним поездом: серверный SDK закрепляет 2026-09-30.endive, stripe-js 10 грузит js.stripe.com/endive/stripe.js, react-stripe-js 7 — пир stripe-js 10. STRIPE_API_VERSION переведён на endive; lib/stripe-api-version.test.ts был красным до этого шага. Ломающие изменения Endive нас не задевают: payment_method_types мы не шлём, billing_cycle_anchor не трогаем, Payment Request Button не используем, значения ui_mode те же. Новый lib/stripe-browser.test.ts держит поезд Stripe.js в браузере равным поезду серверной версии API, чтобы раздельный бамп пакетов был красным. Мерж — только после репетиции покупки на стенде владельцем. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0184yUssUtNnEmKVaft78cbT
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
ПокрытиеИзменённые строки (diff-cover, порог 85%) |
…нтарий и строка реестра (#433) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0184yUssUtNnEmKVaft78cbT
Owner
Author
|
Владелец выбрал вариант 1 (11.10): сливаю в main → стенд → репетиция покупки по чек-листу в описании → только потом релиз. |
efymd9
enabled auto-merge (squash)
October 11, 2026 12:58
# Conflicts: # docs/registry.md
Merged
This was referenced Oct 11, 2026
This branch was successfully deployed
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.
Что и зачем
Три мажора платёжного контура из Dependabot #431 — одним PR, потому что это один «поезд» Stripe:
stripe2026-08-26.dahlia→2026-09-30.endive@stripe/stripe-jsjs.stripe.com/dahlia/stripe.js→js.stripe.com/endive/stripe.js@stripe/react-stripe-js@stripe/stripe-js >=10 <11Лок закреплён ровно на этих версиях (последние патчи мажоров на сегодня); в
package.jsonдвинулись только три спеки — правка руками +pnpm install, безpnpm update.lib/stripe.ts:STRIPE_API_VERSION = "2026-09-30.endive". До этого шагаlib/stripe-api-version.test.tsбыл красным (expected '2026-09-30.endive' to be '2026-08-26.dahlia'), аtsc— тоже (Type '"2026-08-26.dahlia"' is not assignable to type '"2026-09-30.endive"'). Это и был сигнал «прочитай changelog», ради которого Stripe: «пина» версии API нет — закрепить константой + тест-страж; no-store на redirect-ветках billing-portal #266 вводил пин.lib/stripe-browser.test.ts(jsdom): поезд Stripe.js, который реально вставляетloadStripe(читаетсяsrcвставленного<script>, jsdom ничего не качает), должен совпадать с суффиксомSTRIPE_API_VERSION. Stripe прямо советует держать Stripe.js и серверную версию API на одном поезде («keep the Stripe.js version and server-side API version on the same release train», docs/sdks/stripejs-versioning), а пакеты живут раздельно — раздельный бамп от Dependabot теперь красный. Проверено, что тест падает без изменения: с пиномdahliaи установленным stripe-js 10 —expected 'endive' to be 'dahlia'.docs/gotchas.md→ «Stripe API 2024+ moves» — абзац про три пакета-поезд и что сломал Endive; «Stripe 22» → «Stripe 23» в стекеCLAUDE.md,README.md,docs/services.md.Разбор ломающих изменений (что читал и задевает ли нас)
Источники:
stripe-nodeCHANGELOG 23.0.0,docs.stripe.com/changelog/endive(все пункты «Breaking»), релизыstripe-jsv10.0.0 иreact-stripe-jsv7.0.0 + diff ихdist/; плюс diff.d.tsstripe 22.6.2 ↔ 23.0.0 поCheckout/Sessions,Subscriptions,SubscriptionItems,Invoices,Customers,BillingPortal/Sessions,Prices,Products,EventsиWebhooks.js.API
2026-09-30.endivepayment_method_typesнаcheckout.sessions.create→ 400buildCheckoutSessionParamsвозвращает объект черезas Stripe.Checkout.SessionCreateParams, поэтомуtscтакой ключ не поймал бы — проверено грепом по всему репо: ноль вхожденийbilling_cycle_anchorв update/resume подписки и preview invoice → объект{type}subscriptions.update— толькоmetadata(скраб CAPI,lib/subscription-mirror.ts,scripts/scrub-capi-metadata.ts) иcancel_at_period_end(lib/erase-user.ts)ui_mode'elements' | 'embedded_page' | 'form' | 'hosted_page'— сверено в типах 23.0.0items.data[].current_period_end,invoice.parent.subscription_details.subscription,cancel_at,cancel_at_period_end,status,metadata,customer,client_reference_id,amount_total…)status_details,pending_update.cancel_at_period_end,current_trial, …). EnumSubscription.Statusпрежнийfailed_tax_calculation(automatic tax)ExpressCheckoutElementpaymentMethodTypesв опциях ElementscanConfirm = false, пока висит серверный апдейт Checkout Session (Elements + Checkout Sessions)onConfirmвcomponents/watch/wallet-express-checkout.tsxcanConfirmне читает и зовётcheckout.confirm()по событию кошелька. По описанию Stripe меняется только флаг, но это единственный пункт, который реально проходит через наш код — проверяется репетицией кошелька (п. 6 чек-листа)fields.billingDetails: 'never'у Payment Elementbilling_address_collection: required)SDK
stripe23verifyHeaderбезtoleranceтеперь берётDEFAULT_TOLERANCE;constructEvent(…, 0)реально отключает проверкуconstructEvent(body, sig, secret)с тремя аргументами — былоtolerance || 300, сталоtolerance ?? 300, т.е. те же 300 с (сверено вWebhooks.jsобеих версий)StripeConnectionErrorвместоStripeAPIErrorexpireIfOpenперечитывает сессию при ЛЮБОЙ ошибкеexpire;lib/observability.ts/lib/user-export.ts/scripts/scrub-capi-metadata.tsтолько печатаютname/codeStripe.constructEventWithoutVerification, экспортErrorType, V1-поляV2ListStripe.errors.StripeErrorна месте —tscзелёный).nvmrc= 24; Next 16 и так требует ≥ 20.9scripts/stripe-setup.ts,scrub-capi-metadata.ts,erase-user.ts,export-user-data.ts) создаютnew Stripe(key)безapiVersionproducts/prices list/create/update,subscriptions list/update {metadata},customers.retrieve,invoices.list) в Endive не менялись@stripe/stripe-js10 /@stripe/react-stripe-js7: кроме смены поезда наendiveи удаления PRB — одна автоматическая повторная попытка загрузки скрипта вloadStripe(нашgetStripeBrowserмемоизирует промис как и раньше); «Upgrade to React 19» в react-stripe-js 7 — это девтулинг пакета (jest/RTL), рантайм-diffcheckout.esm.mjs— косметикаuseMemo. Экспорты, которые мы используем (EmbeddedCheckoutProvider,EmbeddedCheckout,CheckoutElementsProvider,ExpressCheckoutElement,useCheckoutElements), и типыcheckout.confirm/ опций Express Checkout не менялись.Вебхук-эндпоинт. Версия эндпоинта задаётся в дашборде Stripe и этим PR не управляется. Поля шести обрабатываемых событий одинаковы в dahlia и endive, так что поднимать версию эндпоинта не обязательно; если владелец захочет — отдельно и после релиза.
Как проверено
pnpm lint— exit 0pnpm typecheck— exit 0 (до смены литерала — exit 2, ровно одна ошибка проapiVersion)pnpm test:unit— exit 0, 156 файлов / 2048 тестов (unit + mobile;cd mobile && npm ciсделан)lib/stripe-api-version.test.ts: красный на 23.0.0 с пином dahlia → зелёный с endivelib/stripe-browser.test.ts: зелёный; доказано, что без изменения (пин dahlia) красныйlab/wallet-slot-variants.tsx— инертная заглушка), голдены не затронуты.env.localне былоКритерии из #433 — по пунктам
lib/stripe-api-version.test.tsдержит SDK и версию API — да: был красным на бампе, переведён литерал, зелёный; плюс новыйlib/stripe-browser.test.tsдержит браузерную половину того же поезда.docs/gotchas.mdобновлён — да, раздел Stripe.Репетиция на стенде — ГЕЙТ МЕРЖА
Условие:
matio-staging.vercel.appдолжен отдавать код этой ветки — вебхуки Stripe test-mode доставляются на этот хост, превью-URL их не получит. Например: в проектеmatio-stagingназначить домену деплой этого PR (Promote), после репетиции стенд вернётся кmainследующим деплоемmain(или передеплоитьmain). Проверка:/api/healthzотвечает"commit"= голова этой ветки.Всё — test-mode Stripe стенда, тестовая карта
4242 4242 4242 4242, любая будущая дата, любой CVC.subscriber→ пейволл → «Become a member · $25/mo» →/checkout: iframe монтируется на нашем домене (без ухода наcheckout.stripe.com), в консоли браузера нет предупрежденияStripe.js@… was loaded on the page, but @stripe/stripe-js@10.0.0 expected Stripe.js@endive→ один line item $25/мес, адрес обязателен, чекбокс ToS с текстом отказа от 14-дневного отзыва → оплатить.1b. Hosted Checkout на новой версии API (путь покупателей из FB/IG, процедура Stripe: «пина» версии API нет — закрепить константой + тест-страж; no-store на redirect-ветках billing-portal #266). DevTools → подмена User-Agent на строку со
Instagram, тот же профиль браузера → гостевой pay-first:/checkoutдолжен целиком уйти на тестовую страницуcheckout.stripe.com, оплата 4242, возврат на/welcome?session_id=…, вебхуки 200, строка подписки на стенде — как в шагах 2–4.checkout.session.completed,customer.subscription.created,invoice.paid— каждый 200.subscriptions—status=active,current_period_end≈ +1 мес; строкаusersсsignup_origin='guest_checkout'иstripe_customer_id. Плюс скраб CAPI (Минимизация: сырой IP и User-Agent (capi_ip/capi_ua) живут в метаданных подписки Stripe бессрочно после единственного Purchase #165): с принятым маркетинговым согласием в Stripe test Dashboard у этой подписки в metadata больше нетcapi_fbp/capi_fbc/capi_ip/capi_ua, аcapi_consentостался (сбой скраба виден только как console.warn — шаг 10 его не поймает)./welcome: тот же браузер → вход по ticket без ввода кода (кукаcheckout_claim), пользователь залогинен.subscriberиграет (/api/playback-token200).WALLET_EXPRESS_CHECKOUT): другой залогиненный аккаунт, устройство с Apple Pay / Google Pay → пейволл → галочка согласия → кнопка появилась → оплатить → возврат сcs=→ доступ сразу. Еслиconfirmупал — это кандидат на Endive-изменениеcanConfirm, сообщить в треде. Предусловия и проверка, что Endive не сломал создание сессии: (а) в Stripe test Dashboard → Settings → Payment method domains доменmatio-staging.vercel.appзарегистрирован и активен (без него слот просто не рисуется); (б) после галочки согласия в Stripe test → Logs запросPOST /v1/checkout/sessionsсui_mode=elementsвернул 200 — сбой создания в коде проглатывается и выглядит так же, как «здесь кошелька нет»; (в) подтверждение оплаты кошельком проходит (Endive:canConfirm=false, пока висит серверный апдейт сессии)./subscribe→/checkout: ещё один тестовый аккаунт → embedded → 4242 → возврат на watch-путь сcs=→ доступ сразу (inline-зеркало), вебхуки 200./api/billing-portal302 → Customer Portal → отменить →customer.subscription.updated200 → в строкеsubscriptionsотмена запланирована (cancel_at/cancel_at_period_end), доступ сохраняется до конца периода./checkoutв двух вкладках → возврат в первую показывает карточку «сессия истекла».environment: staging: новых ошибок за время репетиции нет.Отчёт — в этот тред (какие пункты пройдены, id тестовых подписок/событий). Только после него — ревью/мерж основной сессией.
Отложено
lib/checkout-session-params.tsпросит при смене версии API перепроверить, чтоcustom_textпо-прежнему отвергается подui_mode: 'elements'. На2026-08-26.dahliaэто проверено, на2026-09-30.endive— нет. Вреда нет: поверхность elementscustom_textне шлёт. Строка вdocs/registry.md(после ревью).Ничего: незавершённых кусков в коде нет, строк в
docs/registry.mdне добавлено. Порог покрытия вvitest.config.mtsне трогал — новый тест добавляет считанные строки; если CI покажет переход через шаг рэтчета, пересчитаю.Closes #433
GDPR: не касается — состав данных, уходящих в Stripe (и в Stripe.js), не меняется; новых процессоров, полей, логов и событий нет.
🤖 Generated with Claude Code
https://claude.ai/code/session_0184yUssUtNnEmKVaft78cbT