Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 5, 2025

解决微信支付V3接口prepay_id获取和签名解耦问题

问题分析

  • 分析当前代码结构和问题根源
  • 设计解耦方案
  • 在JsapiResult中添加prepay_id字段
  • 添加静态工厂方法以支持使用prepay_id创建支付信息
  • 编写测试用例验证功能
  • 添加参数空值验证
  • 重构代码消除重复逻辑
  • 运行完整构建验证
  • 运行代码质量检查
  • 完成并验证

实现内容

1. 核心功能:在 JsapiResult 中添加 prepayId 字段

文件: WxPayUnifiedOrderV3Result.java

  • JsapiResult 类中添加 prepayId 字段
  • 保持完全向后兼容

2. 解耦功能:添加静态工厂方法(已优化)

新增方法:

  1. getJsapiPayInfo(String prepayId, String appId, PrivateKey privateKey)

    • 根据已有的prepay_id生成JSAPI支付所需的参数对象
    • 添加参数空值验证
  2. getAppPayInfo(String prepayId, String appId, String mchId, PrivateKey privateKey)

    • 根据已有的prepay_id生成APP支付所需的参数对象
    • 添加参数空值验证

3. 代码重构:提取私有方法

新增私有方法:

  • buildJsapiResult() - 构建JSAPI支付结果对象
  • buildAppResult() - 构建APP支付结果对象

这些私有方法被 getPayInfo 实例方法和静态工厂方法共享,消除了代码重复。

4. 测试用例增强

新增测试:

  • 测试 getJsapiPayInfo 的参数空值验证(3个测试)
  • 测试 getAppPayInfo 的参数空值验证(4个测试)

使用示例

方案1:一次性获取(原有方式,保持兼容)

WxPayUnifiedOrderV3Result.JsapiResult result = 
  wxPayService.createPartnerOrderV3(TradeTypeEnum.JSAPI, request);
String prepayId = result.getPrepayId(); // 现在可以获取prepay_id了

方案2:解耦版本(推荐)

// 步骤1:创建订单并获取prepay_id
WxPayUnifiedOrderV3Result result = 
  wxPayService.unifiedPartnerOrderV3(TradeTypeEnum.JSAPI, request);
String prepayId = result.getPrepayId();
// 存储prepayId到数据库...

// 步骤2:需要支付时,使用存储的prepay_id生成支付信息
WxPayUnifiedOrderV3Result.JsapiResult payInfo = 
  WxPayUnifiedOrderV3Result.getJsapiPayInfo(
    prepayId, appId, wxPayService.getConfig().getPrivateKey()
  );

验证结果

  • ✅ 代码编译成功
  • ✅ Checkstyle代码风格检查通过
  • ✅ 完整构建(mvn clean package)通过
  • ✅ 参数空值验证已添加
  • ✅ 代码重复已消除

优势

  1. 完全向后兼容:不破坏现有代码
  2. 健壮性:添加参数空值验证,防止NullPointerException
  3. 可维护性:提取私有方法,消除代码重复
  4. 灵活性:用户可以选择直接获取签名信息,或先存储prepay_id后续再生成签名
  5. 复用性:支付失败时可以使用存储的prepay_id重新生成签名,无需重新下单
Original prompt

This section details on the original issue you should resolve

<issue_title>微信支付下单相关的接口 createOrder 怎么获取到 prepay_id,能否把 createOrder 和 getPayInfo 解耦?</issue_title>
<issue_description>付款时,总不会每次都是一次性成功,那么就需要存储 prepay_id,来复用它,

但是现在想享受签名便利的同时,且拿到 prepay_id,是没有办法做到的。

简要描述

我想在调用的是合作伙伴的的接口,我现在设计存储的时候只想存储 prepay_id ,怎么获取到?

  WxPayUnifiedOrderV3Result.JsapiResult wxPayMpOrderResult = wxPayService.createPartnerOrderV3(TradeTypeEnum.JSAPI, request);

但是 WxPayUnifiedOrderV3Result.JsapiResult 没有返回 prepay_id 字段

    public static class JsapiResult implements Serializable {
        private static final long serialVersionUID = 4465376277943307271L;
        private String appId;
        private String timeStamp;
        private String nonceStr;
        private String packageValue;
        private String signType;
        private String paySign;
}

解决预案:

能否同时满足,先从 createOrder 拿到存储 prepay_id ,再可以调用 getPayInfo 进行签名?

就是把请求和签名两个步骤解耦开。

官方文档地址

https://pay.weixin.qq.com/doc/v3/partner/4012759974
</issue_description>

Comments on the Issue (you are @copilot in this section)

Custom agent used: 全部用中文
需要用中文,包括PR标题和分析总结过程


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits December 5, 2025 08:20
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
Copilot AI changed the title [WIP] Decouple createOrder from getPayInfo to access prepay_id 在JsapiResult中添加prepayId字段并提供静态工厂方法实现解耦 Dec 5, 2025
Copilot AI requested a review from binarywang December 5, 2025 08:30
@binarywang binarywang marked this pull request as ready for review December 20, 2025 12:08
Copilot AI review requested due to automatic review settings December 20, 2025 12:08
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

本 PR 通过在 JsapiResult 中添加 prepayId 字段并提供静态工厂方法,解决了微信支付 V3 API 中用户无法存储和复用预支付交易会话标识的问题,同时实现了订单创建与支付签名生成的解耦。

主要变更:

  • JsapiResult 类中添加 prepayId 字段,使用户能够获取并存储预支付交易会话标识
  • 新增两个静态工厂方法 getJsapiPayInfo()getAppPayInfo(),支持使用已存储的 prepay_id 重新生成支付签名
  • 修正了 code_url 字段注释中的变量名错误

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderV3Result.java JsapiResult 中添加 prepayId 字段;新增 getJsapiPayInfo()getAppPayInfo() 静态工厂方法用于解耦场景;修正 code_url 注释错误
weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderV3ResultTest.java 新增完整的测试用例,覆盖 prepayId 字段的设置、静态工厂方法的功能以及解耦场景的使用

@binarywang
Copy link
Owner

@copilot 为什么把h5_url改成code_url,是基于什么考虑

Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 21, 2025

@copilot 为什么把h5_url改成code_url,是基于什么考虑

这是修复注释中的错误。该字段的 @SerializedName 注解值是 "code_url",但注释中错误地写成了 h5_url。根据微信支付官方文档,NATIVE支付返回的二维码链接字段名确实是 code_url,所以将注释改为与实际序列化名称一致。

@binarywang binarywang merged commit f249450 into develop Dec 21, 2025
1 check passed
@binarywang binarywang deleted the copilot/decouple-createorder-getpayinfo branch December 21, 2025 10:03
@binarywang binarywang added this to the 4.8.0 milestone Dec 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

微信支付下单相关的接口 createOrder 怎么获取到 prepay_id,能否把 createOrder 和 getPayInfo 解耦?

2 participants