
Medusa 移动支付从零接入实战支付宝、微信支付一次讲透的避坑指南【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa你负责的跨境电商小程序定在月底上线老板甩来一句加上支付宝和微信支付越快越好。你打开 Medusa 项目盯着packages/modules/payment/目录一时不知从何下手——这很正常移动支付接入的难点从来不在调通 API而在于签名、回调、退款、对账这一整套链路里藏着太多让人半夜惊醒的暗坑。这篇文章不打算罗列概念而是顺着一条真实的接入路线把 Medusa 里跑通支付宝、微信支付的全过程拆给你看。读完你会发现先搞懂架构再写代码一切都会顺很多。动手之前先搞懂 Medusa 把钱放在哪Medusa 的支付系统不是一堆零散代码而是一个边界清晰的模块。核心逻辑集中在 packages/modules/payment/services/payment-module.ts负责支付会话、收款单、捕获、退款这些业务编排services/payment-provider.ts则是所有第三方支付商的接线板。真正关键的是抽象出来的支付商接口。从 payment-provider.ts 能看到Medusa 对每个接入方只要求实现一套固定的动作创建会话、更新会话、授权、查询状态、捕获、取消、退款外加一个处理异步回调的 webhook 入口。这意味着不管你是接 Stripe、支付宝还是微信插件只要补齐这套动作上层业务一行都不用改。记住这个思路Medusa 不关心谁在收钱只关心每个收钱的人有没有把这套动作做完。不用从零开始把 Stripe 当教科书抄Medusa 官方内置的 Stripe 支付商位于 packages/modules/providers/payment-stripe/它就是你写支付宝、微信插件的最佳参照物。目录结构很有讲究core/stripe-base.ts一个继承自AbstractPaymentProvider的抽象基类把创建支付单、金额换算、签名校验等公共逻辑全部收拢在这里services/stripe-provider.ts真正的插件类继承基类并声明自己的标识符几十行代码就能注册成一个可用支付商utils/get-smallest-unit.ts处理元转分这类金额单位换算的小工具写支付宝时同样用得上。模仿这套结构你的支付宝插件可以这样组织// 示意自定义支付商的骨架 class AlipayProviderService extends AlipayBase { static identifier pp_alipay // 注册标识 // 继承基类覆写支付相关的动作方法 // initiatePayment(): 创建预下单返回唤起支付的参数 // getPaymentStatus(): 主动查询订单状态 // getWebhookActionAndData(): 解析支付宝异步通知 } // 启动时校验配置是否齐全缺 appId / 私钥就直接报错 static validateOptions(options) { // 缺配置就 throw避免带着残缺配置上线 }支付商文件只需放在项目的src/providers/下并正确注册Medusa 的模块加载器会自动发现并把它注入容器。这就是整套架构最妙的地方新增一种支付方式等于新增一个实现固定接口的类而不是改动订单、购物车这些既有代码。三步打通支付宝支付链路第一步预下单与签名用户在结算页选择支付宝后Medusa 会调用你插件的创建会话方法。这一步你只需要做两件事一是用商户私钥对订单参数做 RSA2 签名金额、订单号、商品描述都要参与二是把签名后的请求发给支付宝获取交易串。签名是新手最容易翻车的地方——参数排序必须严格按支付宝约定的字典序多一个空格、少一个字段签名校验就直接失败。第二步等待异步通知用户付完钱支付宝会往你配置的回调地址推一条异步通知。这里是整套流程的高危区验签先行用支付宝公钥对通知内容做验签验不过的请求直接丢弃别碰任何业务逻辑幂等处理支付宝的通知可能重复推送收到trade_status为已支付的通知时要先查这笔订单是否已处理过应答格式处理成功后必须原样返回success字样否则支付宝会按失败重试重试次数一多还会把你划进风险名单。Medusa 的 webhook 入口会自动把原始请求体交给你插件里的解析方法你要做的就是在验签通过后把支付状态同步给 Medusa 的支付模块让它推进订单状态。第三步配置注册在项目的medusa-config里把插件挂上并按环境注入密钥// medusa-config.js 片段 modules: [{ resolve: ./src/providers/alipay, // 本地支付商路径 options: { appId: process.env.ALIPAY_APP_ID, // 应用ID privateKey: process.env.ALIPAY_PRIVATE_KEY, // 商户私钥别硬编码 alipayPublicKey: process.env.ALIPAY_PUBLIC_KEY // 支付宝公钥 } }]密钥务必走环境变量明文写在配置文件里的后果不用我多说。微信支付一个商户号四种场景微信支付比支付宝复杂的地方在于场景分化小程序里用 JSAPI、App 内用 APP 支付、手机浏览器用 H5、PC 网页用 Native。四种场景共用一套签名与回调机制差别主要在调起参数上。小程序 / JSAPI需要前端传openid用 code 换 openid 这一步建议放在服务端做别把appsecret暴露给前端APP 支付客户端拿到预支付参数后唤起微信服务端只负责下单和验签H5 支付注意微信会校验Referer域名白名单测试时最容易在这里卡壳。插件设计上可以在基类里实现下单、验签、退款这些公共逻辑四个场景各写一个子类复用对应关系一目了然。回调验证这样写最稳微信的回调消息体本身经过加密需要先用 API 密钥做 AES 解密再验签、解析transaction_id最后核对金额与商户订单号。这里有个很容易被忽略的细节回调里的金额要和本地订单做一致性比对只查订单号存在是不够的——攻击者完全可以伪造一笔小金额通知来试探你的校验逻辑。一个稳妥的写法是验签 → 解密 → 比对金额与状态 → 幂等落库 → 返回成功应答五步缺一不可。Medusa 侧你会把最终结果映射为支付模块的会话状态由它驱动订单流转而不是在回调里直接改订单表。退款与对账别等出事了才想起它们支付平台的对账单支付宝日账单、微信账单文件建议每天拉取一次和本地支付记录做逐笔比对。Medusa 的支付模块本身有完整的支付记录、捕获、退款数据模型见 packages/modules/payment/src/models/ 下的payment、refund、capture对账时可以据此做脚本化核对而不是靠人工翻后台。退款接口要走支付平台提供的退款 API处理全额退和部分退两种场景退款结果通常也是异步返回记得监听退款回调。从沙箱到生产的一次完整演练支付宝的沙箱环境和微信的模拟支付工具都能让你在真实流程里走通下单、支付、回调、退款全链路唯一要注意的是沙箱的 AppID 和密钥与生产完全不同务必分开配置。Medusa 本身就支持按环境区分配置把两套密钥分别放进.env.dev和.env.prod就能安全隔离。演练清单按这个顺序走一遍沙箱里完成一笔完整支付确认订单状态正确流转模拟回调重复推送验证幂等处理不产生重复订单用错误金额/伪造签名触发回调确认被拒之门外发起全额退与部分退核对后台退款记录拉取一天的对账单跑通自动比对脚本生产环境上线时把支付相关的错误日志接到监控告警里设置支付失败率阈值。支付平台通常不保证回调的即时性主动查询接口如支付宝的订单查询可以作为兜底——建议加一个定时任务对长时间未回调的订单做主动对账。上线前必查清单所有密钥走环境变量杜绝明文入库回调地址强制 HTTPS签名与验签逻辑单元测试覆盖金额单位换算统一为最小单位分避免浮点误差幂等键设计到位回调、退款均可重放安全准备好回滚方案出问题时优先降级支付方式而非全站下线写在最后回头看支付宝和微信支付的接入难点并不在 API 本身而在于你对 Medusa 模块化边界的理解以及签名、回调、幂等这些看不见的功夫。把 packages/modules/payment/ 的结构吃透再照着 payment-stripe 这套官方模板套一遍你会发现接入过程其实相当顺滑。下一步建议你做的先把仓库https://gitcode.com/GitHub_Trending/me/medusaclone 下来跑通 Stripe 的本地演示再动手写自己的支付宝插件——从抄作业开始的接入永远比从零硬啃快。【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考