资讯详情

资讯详情

Medusa Stripe 支付提供者 @medusajs/payment-stripe:从 2.0 到 2.20 的能力演进与源码级解析

Medusa Stripe 支付提供者 medusajs/payment-stripe从 2.0 到 2.20 的能力演进与源码级解析【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusamedusajs/payment-stripe 是 Medusa 官方支付模块Modules.PAYMENT的 Stripe 实现负责将 Medusa 的支付会话生命周期发起、授权、捕获、退款、Webhook 对账映射到 Stripe PaymentIntent 与 Customer API。本文以该包的 CHANGELOG.md 为主线骨架结合 packages/modules/providers/payment-stripe 下的源码、类型定义与测试梳理 2.0 大版本重写以来的关键能力演进并给出配置参数、provider 注册方式和底层调用链的完整解析。读完本文你将掌握该模块的 8 个支付方式服务、全部配置项及其作用以及 initiatePayment 到 Webhook 对账的完整实现路径。一、模块概览一个包八种支付方式从 package.json 可以看到该包名称为medusajs/payment-stripe当前版本 2.20.1运行时要求 Node.js 20核心依赖为stripe^15.5.0和medusajs/framework2.20.1peer 与 dev 依赖同版本。模块入口 src/index.ts 通过ModuleProvider(Modules.PAYMENT, { services })向支付模块注册了 8 个服务Provider Key服务类对应支付方式说明stripeStripeProviderService通用 Stripe 支付默认 providerpayment method 由请求上下文决定stripe-oxxoOxxoProviderServiceOXXO墨西哥现金支付支持过期天数配置stripe-bancontactStripeBancontactServiceBancontact比利时本地支付stripe-blikStripeBlikServiceBLIK波兰本地支付stripe-giropayStripeGiropayServicegiropay德国银行转账stripe-idealStripeIdealServiceiDEAL荷兰本地支付stripe-przelewy24StripePrzelewy24ServicePrzelewy24波兰银行转账stripe-promptpayPromptpayProviderServicePromptPay泰国本地支付2.0.3 版本加入这些 Key 集中定义在 src/types/index.ts 的PaymentProviderKeys常量中。其中stripe-ideal、stripe-promptpay等服务通过覆盖paymentIntentOptions的payment_method_types固定各自的支付方式例如 PromptPay 服务固定为[promptpay]且capture_method: automatic见 src/services/stripe-promptpay.ts。二、配置参数StripeOptions 完整说明所有 provider 共享同一份选项类型StripeOptions定义于 src/types/index.ts参数类型是否必填默认值作用apiKeystring是无Stripe 账户 API 密钥缺失时validateOptions直接抛错webhookSecretstring推荐无用于 Webhook 签名校验缺失时启动阶段仅告警见下文 2.16 演进captureboolean否false是否立即捕获automatic capture默认手动捕获capture_method: manualautomaticPaymentMethodsboolean否false为 true 时在 intent 请求上设置automatic_payment_methods: { enabled: true }paymentMethodConfigurationstring否无传入 Stripe Payment Method Configurations 的 IDPMC ID由 Dashboard 托管可用支付方式集合paymentDescriptionstring否无当请求上下文未提供时给 intent 设置的默认描述oxxoExpiresDaysnumber否3OXXO 支付过期天数映射到payment_method_options.oxxo.expires_after_daysasyncPaymentMethodTypesStripe.PaymentMethod.Type[]否无异步支付方式类型列表未配置时所有支付方式按同步处理。异步支付方式在 Stripe 状态为pending时也允许生成订单此外 PaymentIntentOptions 定义了各支付方式服务可以覆写的 intent 参数capture_methodautomatic/manual、setup_future_usageon_session/off_session、payment_method_types以及payment_method_options.oxxo.expires_after_days。配置校验缺失 apiKey 直接报错缺失 webhookSecret 启动告警src/core/stripe-base.ts 中的静态方法validateOptions定义了配置校验规则apiKey缺失时抛出Required option apiKey is missing in Stripe plugin阻止 provider 初始化webhookSecret缺失时打印console.warn并通过静态标志hasWarnedMissingWebhookSecret保证在 8 个 provider 服务各自被 loader 校验时只告警一次。三、版本演进时间线CHANGELOG 中的关键能力节点以下是 CHANGELOG 记录的、对功能有实质影响的版本节点依赖同步更新如medusajs/framework的例行升级不再赘述2.0.0Medusa 2.0 大版本重构2.0.0 条目 标记为Major Changes对应 Medusa 2.0 发布PR #7341。这一代将支付逻辑收敛为AbstractPaymentProviderStripeOptions抽象基类StripeBase统一实现 Stripe 的 PaymentIntent / Customer / Refund / Webhook 调用各支付方式服务仅需通过paymentIntentOptions描述差异。此前在 0.0.2 版本PR #6700中所有模块被打上初始版本号以支持 monorepo 联测。2.0.3加入 PromptPayPR #9789CHANGELOG 2.0.3 条目为泰国市场新增promptpay支付方式注册StripePromptpayService。该服务固定payment_method_types: [promptpay]并采用自动捕获。2.11.x共享支付令牌、PromptPay 注册修复、metadata 合并2.11.0feat(payment-stripe): Allow passing shared payment token in Stripe允许在发起支付时透传 Stripe 共享支付令牌同时修复了StripePromptPayService未在模块 provider 中注册导致 PromptPay 无法工作的问题这也解释了为何 2.0.3 加入 PromptPay 后仍需在 2.11.0 修正注册。2.11.1PR #13801发起支付时将自定义 metadata 与session_id合并写入 intent 的 metadata而不是覆盖。对应源码见 initiatePaymentmetadata: { ...(data?.metadata ?? {}), session_id: data?.session_id as string, }其中session_id是 Webhook 对账的关键锚点下文详述。2.12.0OXXO 支付方式与可配置过期时间PR #13805CHANGELOG 2.12.0 条目新增 OXXO provider 支持并支持配置过期时间。OxxoProviderService通过paymentIntentOptions固定payment_method_types: [oxxo]、capture_method: automatic并将oxxoExpiresDays默认 3 天映射为payment_method_options.oxxo.expires_after_days见 src/services/stripe-oxxo.ts。2.13.2账户持有人删除保护与外部退款同步该版本包含两项行为修正CHANGELOG 2.13.2 条目PR #14112 修改deleteAccountHolder实现避免永久删除底层的 Stripe Customer。从源码看 deleteAccountHolder 当前仍调用stripe_.customers.del社区修正是对删除语义的收敛——确保只在明确上下文下删除避免误删用户 Stripe 档案实施时建议结合实际使用场景评估 account holder 删除策略。PR #14746处理在 Medusa 外部发起退款的情况。对应 refundPayment 中捕获CHARGE_ALREADY_REFUNDEDErrorCodes.CHARGE_ALREADY_REFUNDED错误并静默放行避免外部已退款时内部重复退款抛错。2.16.0webhookSecret 缺失告警与支付方式删除CHANGELOG 2.16.0 条目两项改动webhookSecret缺失时在 provider 初始化阶段告警此前该配置缺失会被静默接受导致后续 Webhook 签名校验失败依赖 Webhook 的支付流程如 3D Secure、异步捕获一直卡在pending。告警文案与validateOptions实现一一对应见上文配置校验小节。新增删除支付方式能力deletePaymentMethod通过stripe_.paymentMethods.detach将支付方式从客户档案解绑源码并配合listPaymentMethods默认limit: 100列出客户全部支付方式与savePaymentMethod基于setupIntents保存形成完整的保存-列表-删除闭环。2.17.2异步支付方式支持PR #15085CHANGELOG 2.17.2 条目在payment、payment-stripe、core-flows、medusa、dashboard、js-sdk、utils、types等多个包中引入异步支付方式async payment methods支持同时修复了 Webhook 中对异步支付方式检查的优雅降级。异步支付方式如银行转账类的特点是Stripe 状态为pending时订单即可被创建。其判定逻辑在 isAsyncPaymentMethod只有options_.asyncPaymentMethodTypes中列出的类型才按异步处理。该判定同时影响两处getStatus中processing状态映射源码异步方式返回PENDING_AUTHORIZATION否则返回PENDINGWebhook 处理payment_intent.created/payment_intent.processing事件时源码异步方式返回PENDING_AUTHORIZATION动作同步方式返回PENDING。2.18.0payment_method_configuration 支持CHANGELOG 2.18.0 条目新增payment_method_configuration支持通过传入 Stripe Payment Method ConfigurationsPMC ID即可在 Stripe Dashboard 上集中管理可用支付方式集合而无需改代码。从源码看该参数有明确的优先级与互斥逻辑normalizePaymentIntentParametersif (!paymentMethodTypes?.length) { res.payment_method_configuration (extra?.payment_method_configuration as string | undefined) ?? this.options_?.paymentMethodConfiguration }即仅当没有显式指定payment_method_types时才应用payment_method_configuration请求上下文优先于全局选项。这与 stripe-base.spec.ts 中 5 个用例逐一对应extra 中的payment_method_configuration优先于 options未传 extra 时使用 options 中的配置固定了payment_method_types的专用 provider如 iDEAL不设置 PMC同时传入payment_method_types与 PMC 时PMC 被忽略全部未配置时 PMC 为undefined且默认capture_method为manual。四、核心实现StripeBase 与支付会话生命周期所有支付方式服务继承自抽象类StripeBasesrc/core/stripe-base.ts它是该模块的心脏。4.1 支付会话生命周期方法StripeBase完整实现AbstractPaymentProviderStripeOptions的全部接口与 Medusa Payment 模块的调用关系如下方法Stripe 底层调用说明initiatePaymentpaymentIntents.create创建 PaymentIntent金额换算为最小货币单位写入session_id等 metadataauthorizePayment复用getPaymentStatus本质是paymentIntents.retrieve并映射状态capturePaymentpaymentIntents.capture手动捕获遇PAYMENT_INTENT_UNEXPECTED_STATE且 intent 已succeeded时视为捕获成功返回cancelPayment/deletePaymentpaymentIntents.cancel取消 intent若 Stripe 已返回canceled状态则容错返回refundPaymentrefunds.create按最小货币单位退款对CHARGE_ALREADY_REFUNDED幂等放行retrievePaymentpaymentIntents.retrieve查询并将金额从最小单位转回标准单位updatePaymentpaymentIntents.update金额变更时更新 intent金额未变则直接返回当前状态createAccountHolder/updateAccountHolder/deleteAccountHoldercustomers.create/customers.update/customers.del将 Medusa 客户映射为 Stripe Customer账单地址映射为 Stripe Shipping 地址listPaymentMethods/savePaymentMethod/deletePaymentMethodcustomers.listPaymentMethods/setupIntents.create/paymentMethods.detach客户支付方式管理所有写操作都透传idempotencyKey来自context.idempotency_key保证网络重试下的幂等性。4.2 金额换算getSmallestUnitStripe 要求金额以最小货币单位如分为单位传入。工具函数 src/utils/get-smallest-unit.ts 维护了一张货币幂表幂 0无小数位BIF、CLP、DJF、GNF、JPY、KMF、KRW、MGA、PYG、RWF、UGX、VND、VUV、XAF、XOF、XPF幂 3千分位BHD、IQD、JOD、KWD、OMR、TND其余货币默认幂 2。getSmallestUnit负责从标准单位换算到最小单位其中对 3 位小数货币还会向上取整到最近的 10对应部分货币的最小支付粒度约束getAmountFromSmallestUnit则用于反向换算Webhook 返回给订单系统的金额均经过该函数。对应的单元测试位于 src/utils/tests/get-smallest-unit.ts。4.3 状态映射PaymentIntent 状态 → Medusa 会话状态getStatus源码是状态映射的核心映射关系如下Stripe PaymentIntent 状态Medusa 会话状态说明requires_payment_method有 last_payment_errorERROR有失败记录requires_payment_method/requires_confirmationPENDING等待支付方式processing异步方式PENDING_AUTHORIZATION2.17 引入的异步语义processing同步方式PENDING处理中requires_actionREQUIRES_MORE需要额外验证如 3D SecurecanceledCANCELED已取消requires_captureAUTHORIZED已授权待捕获succeededCAPTURED已捕获其他PENDING兜底4.4 错误处理与指数退避重试handleStripeError源码按错误类型分派StripeCardErrorintent 已创建但支付失败返回该 intent 供支付会话引用便于 Webhook 对账StripeConnectionError/StripeRateLimitError结果不确定返回retry: trueStripeAPIError按 Stripe 官方建议视为不确定状态indeterminate_due_to: stripe_api_error依赖 Webhook 而非直接判失败其他错误抛出异常触发会话清理。executeWithRetry源码默认最多重试 3 次采用指数退避baseDelay * 2^(attempt-1)并叠加 0.5~1.0 的随机抖动避免重试风暴。五、Webhook 对账以 session_id 为锚的事件驱动getWebhookActionAndData源码是整个异步对账链路的核心工作流程如下签名校验constructWebhookEvent读取请求头stripe-signature调用stripe_.webhooks.constructEvent校验——这正是webhookSecret缺失会导致的故障点来源校验检查 intent metadata 中的session_id。Medusa 创建的 intent 一定会携带该字段见initiatePayment没有session_id的 intent 视为其他集成共享同一 Stripe 账户创建直接返回NOT_SUPPORTED杜绝跨系统误操作事件分派按event.type映射为 Medusa 的PaymentActionsStripe 事件Medusa 动作payment_intent.created/payment_intent.processingPENDING异步方式为PENDING_AUTHORIZATIONpayment_intent.canceledCANCELEDpayment_intent.payment_failedFAILEDpayment_intent.requires_actionREQUIRES_MOREpayment_intent.amount_capturable_updatedAUTHORIZEDpayment_intent.partially_fundedREQUIRES_MOREpayment_intent.succeededSUCCESSFUL其他NOT_SUPPORTED每个动作都携带session_id和换算回标准单位的金额供支付模块定位会话并推进订单状态。六、模块使用方式与升级注意事项6.1 安装与配置要点安装在 Medusa 应用中通过npm install medusajs/payment-stripe对应 package.json 中主入口dist/index.js安装后在medusa-config的支付模块 providers 中注册stripe与所需支付方式并为每个 provider 提供apiKey必填与webhookSecret强烈建议路由在 Stripe Dashboard 配置 Webhook 端点将上述 Stripe 事件payment_intent.succeeded等转发到 Medusa 的支付 Webhook 路由异步方式若使用 Klarna/Affirm 等异步支付方式需配置asyncPaymentMethodTypes并留意payment_intent.created事件返回PENDING_AUTHORIZATION的语义金额所有金额在 src/utils/get-smallest-unit.ts 的货币幂表约束下自动换算无需业务侧手工处理。6.2 升级路径与依赖对齐自 2.6.1 起PR #11738Medusa 移除了包版本的范围约束medusajs/payment-stripe与medusajs/framework严格同版本发布、同步升级2.0.x → 2.20.x 期间该包长期处于Patch Changes节奏唯一一次Major Changes是 2.0.0 的 Medusa 2.0 重写说明其接口在 2.x 生命周期内保持稳定升级风险主要来自medusajs/framework的同步要求若你的订单流程依赖 Webhook 完成状态推进3D Secure、异步捕获、OXXO 等升级后务必确认webhookSecret已配置否则将触发 2.16.0 引入的启动告警并导致支付流程停滞在pending。七、总结从 CHANGELOG 的版本时间线可以看到medusajs/payment-stripe的演进路径清晰2.0 完成框架级重写StripeBase统一抽象2.0.3 起持续补充本地化支付方式PromptPay、OXXO2.11~2.18 密集完善元数据合并、账户持有人安全、异步支付语义与 Payment Method Configurations 集成每一步都通过 stripe-base.spec.ts 等测试锁定行为。对于要在 Medusa 上落地 Stripe 支付尤其是多地区本地支付与异步支付场景的开发者本文梳理的配置项、状态映射表与 Webhook 事件对应关系可以作为排障与二次开发的直接参考。【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →