这个 processOrderAndPay 函数(位于 src/utils/common.ts)其实是你“支付与 SDK 调度中心”的重要补充。它是一个面向过程的业务聚合函数,而 useWxSdk 和 usePayment 是底层的能力原子。
结合这两个文件,第 5 点(也就是原来的第 2 点)可以描述得更丰满,强调你不仅封装了底层 SDK,还抽象了上层业务流程。
怎么说(START 法则版)
Situation (情境): 项目中有普通商品购买、购物车结算、优惠券包购买等多种下单场景,且每种场景都涉及“创建订单 -> 预支付 -> 唤起收银台(微信/泊链) -> 支付结果回调”这一冗长流程。原有代码在每个页面都重复写这套逻辑,导致代码冗余度高,一旦支付接口变动,需要修改十几个页面,维护成本极高。
Task (任务): 需要设计一套标准化的支付与 SDK 调度体系,将底层的微信 JSSDK 能力与上层的业务支付流程解耦,实现“一套代码,处处调用”,同时支持微信支付、泊链支付、积分兑换等多种支付渠道。
Action (行动):
- 底层能力封装:开发
useWxSdkHook,统一管理 JSSDK 的初始化、签名缓存及 API 调用(扫码/定位/分享),屏蔽底层配置细节。 - 业务流程抽象:封装通用函数
processOrderAndPay,采用策略模式处理不同类型的订单创建(普通/购物车/优惠券),并将“下单-预支付-跳转”全链路逻辑固化为标准模版。 - 统一调度:在业务层只需传入对应的 API 方法和参数,即可自动完成从下单到唤起支付的全过程,无需关心中间的参数透传和错误处理。
Result (结果): 构建了高复用的支付中台模块,将新增支付业务的开发代码量减少 70%(从几十行缩减为 1 行调用),同时彻底杜绝了因漏写错误处理导致的支付卡死问题,支撑了营销活动和扫码核销业务的快速上线。
简历中的精简写法(结合 common.ts 和 useWxSdk.ts)
- 构建统一支付与 SDK 调度体系:基于策略模式封装
processOrderAndPay通用支付流程,将普通/购物车/优惠券等多场景下单逻辑标准化;结合useWxSdk统一管理 JSSDK 鉴权与调用,实现“一行代码唤起支付”,将新业务接入效率提升 70%,大幅降低业务耦合度。
面试官问题
针对“微信 JSSDK 集成”和“统一支付流程”这一块,面试官通常会从原理、坑点、架构设计三个维度发问。结合你的代码,我为你准备了高频面试题及参考答案:
1. JSSDK 相关
Q1: 微信 JSSDK 的鉴权流程是怎样的?为什么有时候会签名失败(invalid signature)?
- 流程:前端把当前页面 URL(不带 hash)传给后端 -> 后端用 appId + appSecret 换 access_token -> 再换 jsapi_ticket -> 结合 nonceStr、timestamp、url 生成签名 -> 返回给前端 -> 前端调用
wx.config。 - 你的代码体现中
location.href.split('#')[0]取了 URL。 - 常见坑点(必考):
- URL 不一致:IOS 和 Android 对 URL 的处理不同。IOS 单页应用(SPA)中,微信记录的是落地页(刚进来的那个页面)的 URL,而 Android 记录的是当前页 URL。
- 解决方案:你的代码目前是直接取
location.href。如果遇到 IOS 签名失败,可能需要判断机型,IOS 传落地页 URL,Android 传当前页 URL。(面试时可以补充这点思考,显示你有经验)。 - 动态加载:你的代码做了
missingApis判断,这是个亮点,避免了重复 config。
2. 支付流程相关
Q3: 你说的“策略模式”处理多种订单,具体是怎么实现的?
- 你的回答:
- 我看待“支付”这个动作,它包含三个固定步骤:创建订单 -> 获取预支付参 -> 唤起支付。
- 但是“创建订单”的参数和接口各不相同(普通商品、购物车、优惠券)。
- 所以我把
createOrderAPI(创建订单的接口函数)作为参数传给processOrderAndPay。 - 在调用层,我根据业务场景传入不同的 API(比如
creatCartOrderAPI或createOrderAPI),而支付核心流程(预支付、H5 跳转/唤起)是统一的。这就把**变化的部分(下单逻辑)和不变的部分(支付流程)**分离开了。
Q4: 支付过程中,如果用户支付完成后没有回调(或者回调慢),前端怎么处理?
- 你的回答:
processOrderAndPay里的callback主要是做页面跳转(比如跳到订单详情页)。- 核心保障:前端不能完全信任
success回调。我在跳转到“订单详情页”或“支付结果页”的onShow生命周期里,会主动轮询查一下后端接口,确认订单的真实状态(是paid还是unpaid)。 - 兜底:如果一直查不到,会提示用户“支付状态确认中”,而不是直接告诉他失败。
Q5: 你的支付封装里,怎么处理并发点击或者重复支付?
- 你的回答:
- 我在
usePayment里加了isLoading状态锁 - 或者在
processOrderAndPay调用前,按钮会置灰。 - 另外,后端接口层面应该也有幂等性处理(同一个订单号不能重复支付)。
- 我在
3. 综合场景
Q6: 为什么要把 JSSDK 和支付分开封装,又在业务层组合?
- 你的回答:
- 单一职责原则:
useWxSdk只管和微信客户端打交道(签名、调用能力);processOrderAndPay只管业务流转。 - 场景复用:有些场景只需要 SDK(比如扫码核销,不需要支付);有些场景只需要支付(比如 H5 外部浏览器支付,不需要微信 SDK)。分开封装可以灵活组合,不会为了用一个功能引入一堆不必要的逻辑。
- 单一职责原则:
准备好这些问题的答案,面试时结合你的代码细节(比如 missingApis 的判断、location.href 的处理)去聊,会非常加分。
