ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Medusa接入支付宝微信支付完整实战:从0到上线的四个小步与三次踩坑

Medusa接入支付宝微信支付完整实战:从0到上线的四个小步与三次踩坑 Medusa接入支付宝微信支付完整实战从0到上线的四个小步与三次踩坑【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa大促前夜运营晓雯盯着后台的订单流失报表发愁活动页曝光量翻了四倍可结算页转化率纹丝不动。一查日志问题出在支付环节——顾客选完商品跳转到支付页就卡住超过一半的人在这一步离开。她不懂代码只知道一句话我们的商城好像付不了款。这个商城跑在 Medusa 上。Medusa 自称the worlds most flexible commerce platform for agents and developers它的支付系统是模块化的Stripe 能跑支付宝、微信支付理论上也能跑——只是没人接。接下来的一个月我从零开始给这套开源电商平台接上了国内移动支付全程记录了它真实的脾气。这篇实战记就是那段时间的浓缩版。两条路摆在面前自己造轮子还是站在轮子上接手的第一件事不是写代码而是开会。技术负责人抛出一个经典问题支付这块是自己写还是接入现成的支付 SDK对比维度自己造轮子用 Medusa 支付模块扩展开发量要自己写订单状态机、对账、回调重试只补支付网关的对接层维护成本每个接口变动都要跟进核心逻辑随社区版本走风险点金额精度、回调乱序全靠自己兜需要先吃透它的约定时间动辄数月几天到一两周结论很快出来支付网关的 API 是胳膊订单与资金的流转逻辑才是大腿。Medusa 已经把大腿长好了我们要做的只是给胳膊装上去。动手前先清点四样东西缺一不可一个能跑起来的 Medusa 项目版本与官方仓库保持同步避免 API 对不上支付宝开放平台 / 微信商户平台的沙箱测试账号提前把 AppID、商户号、密钥申请下来一台有公网地址的开发机或者一个内网穿透工具——回调测试离不开它一颗耐心支付调试的报错信息永远比你预想的更隐晦第一小步看懂 Medusa 支付模块的插槽结构Medusa 的支付模块长这样核心逻辑在packages/modules/payment/src/services/下真正的插槽是payment-provider.ts里的PaymentProviderService它负责把外部支付服务取出来调用而每个支付服务要长什么样由packages/core/types/src/payment/provider.ts里的IPaymentProvider接口规定。这个接口像一份合同列明了所有需要履约的方法接口方法对应业务动作initiatePayment创建支付会话authorizePayment授权预扣款capturePayment确认收款refundPayment退款retrievePayment/getPaymentStatus查询支付状态cancelPayment取消支付deletePayment清理支付数据换句话说你不需要关心订单怎么流转只需要按这份合同把支付宝和微信的 API 翻译成这些方法的实现。第二小步仿照 Stripe 写一个最小可跑的本地提供商Medusa 自带了 Stripe 参考实现路径在packages/modules/providers/payment-stripe/src/core/stripe-base.ts。它继承了一个抽象基类AbstractPaymentProvider把 Stripe 的 PaymentIntent 封装成 Medusa 认得的支付会话。我照葫芦画瓢先写了一个假装能支付的本地提供商——收到initiatePayment就返回一个假支付链接点开就是成功页。这一步不接任何真实网关目的是验证插槽本身通不通。class MockProviderService extends AbstractPaymentProviderOptions { static identifier payment-mock async initiatePayment({ amount }) { return { id: mock_${Date.now()}, data: { amount } } } async getPaymentStatus() { return PaymentSessionStatus.AUTHORIZED } }写完后记得看一个关键文件packages/modules/payment/src/loaders/providers.ts。它规定每个提供商必须以pp_{identifier}的形式注册进容器少一个static identifier都会在启动时直接报错。预期结果后台的支付设置里能看到payment-mock这个选项下单能走到支付成功。第三小步把支付宝和微信的官方 SDK 接进来插槽验证通过后真正的活才开始。这一步把官方 SDK 的调用填进刚才的骨架initiatePayment里发预下单请求拿到支付参数返回给前端拉起收银台capturePayment里根据回调结果确认入账。// medusa-config.js 中注册你的支付提供商 modules: { payment: { providers: [ { resolve: ./src/providers/payment-alipay, options: { appId: process.env.ALIPAY_APP_ID, privateKey: process.env.ALIPAY_PRIVATE_KEY, alipayPublicKey: process.env.ALIPAY_PUBLIC_KEY } } ] } }微信支付那边同理只是多了 JSAPI、APP、小程序几种支付场景实现上就多几个initiatePayment的分支。每一行配置背后都对应商户平台上的一个设置项缺一个webhookSecret启动时 Medusa 会不厌其烦地打警告。第四小步用 Webhook 把支付结果签收回来支付回调可以理解成快递签收通知用户付完钱支付宝/微信异步告诉你的服务器这笔单子成了。Medusa 只认它自己的状态机——PENDING → AUTHORIZED → CAPTURED所以回调到达后要做两件事验签然后把它翻译成一次capturePayment。沙箱里最容易忽略的是这件事回调的地址必须公网可达。我第一次测试回调静默丢失订单永远停在待付款排查了半天才发现是内网地址根本收不到通知。三次真实的踩坑记录坑一金额单位对不上现象下单 100 元支付宝账单显示 1 元。原因支付宝以元为金额单位而 Medusa 内部统一按最小货币单位分存储我直接把amount原样传了出去。解决参考 Stripe 提供商的getSmallestUnit工具入参前换算一次。这个坑赔了不止一杯奶茶。坑二回调验签一直失败现象Webhook 能收到但验签 100% 报错。原因支付宝的验签参数是 URL 编码后的字符串直接用原始 body 去验顺序全乱了。解决严格按官方文档规定的参数拼接顺序组装验签串先本地单测再联调。坑三沙箱用户扫码后无响应现象App 内拉起支付后页面一直转圈。原因沙箱环境只支持沙箱版客户端真机上用了正式版支付宝自然查无此单。解决测试手机统一安装沙箱专用 App所有测试账号走同一套环境。沙箱环境隔离是最容易被忽略的隐形坑。上线前必查的五件事金额精度全链路核对一遍最小单位换算尤其是退款路径反向换算最容易出错。回调幂等支付宝/微信可能重复通知同一笔订单capturePayment必须对重复回调无副作用。日志留痕支付相关日志单独建文件记录请求签名、原始回调报文出问题能回溯。密钥管理私钥不进代码库用环境变量或密钥管理服务商户证书设置有效期提醒。回滚预案支付网关升级前保留旧版本的容器镜像约定好观察 15 分钟失败即回滚。还能怎么玩两个进阶方向接完基础支付只是开始。第一个方向是多提供商并存——给支付会话配一个优先级列表支付宝挂了自动降级到微信结算页的支付成功率报表会好看很多。第二个方向是把account_holder能力用起来让用户绑定银行卡或开通免密支付复购时一键扣款把支付从交易终点变成增长杠杆。给你的行动清单五件小事先跑通本地 Mock 提供商确认插槽通畅再碰真实网关金额单位换算写成一个工具函数从第一天就全局复用Webhook 回调地址用公网环境沙箱手机装专用测试客户端每笔支付的关键日志打全包括验签原始报文上线前完整走一遍支付-回调-退款-重复回调四连测接入支付这件事90% 的时间花在跟约定较劲上——跟 Medusa 的约定跟支付平台的约定。把这层约定吃透了剩下的只是翻译工作。而 Medusa 最值钱的地方恰恰是它把那些约定固化成了清晰的接口合同让翻译这件事变成了照本宣科。【免费下载链接】medusaThe worlds most flexible commerce platform for agents and developers项目地址: https://gitcode.com/GitHub_Trending/me/medusa创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表