Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,38 @@
* 微信支付服务商退款请求
* 文档见:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_9.shtml
*
* @author Pursuer
* @version 1.0
* @date 2023/3/2
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class WxPayPartnerRefundV3Request extends WxPayRefundV3Request implements Serializable {
private static final long serialVersionUID = -1L;
/**
* <pre>
* 字段名:服务商应用ID
* 变量名:sp_appid
* 是否必填:是
* 类型:string[1, 32]
* 描述:
* 服务商申请的公众号或移动应用appid。
* 示例值:wx8888888888888888
* </pre>
*/
@SerializedName(value = "sp_appid")
Copy link

Choose a reason for hiding this comment

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

sp_appid 在微信服务商退款接口里是必填项,但目前 WxPayService#partnerRefundV3 只会兜底补 sub_mchid/notify_url,如果调用方遗漏 spAppid 仍会发出不合法请求并被微信侧拒绝;建议确认是否需要在调用链上做同样的兜底或校验。

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

private String spAppid;
/**
* <pre>
* 字段名:子商户应用ID
* 变量名:sub_appid
* 是否必填:否
* 类型:string[1, 32]
* 描述:
* 子商户申请的公众号或移动应用appid。如果传了sub_appid,那sub_appid对应的订单必须存在。
* 示例值:wx8888888888888888
* </pre>
*/
@SerializedName(value = "sub_appid")
private String subAppid;
/**
* <pre>
* 字段名:退款资金来源
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,12 @@ public WxPayRefundV3Result refundV3(WxPayRefundV3Request request) throws WxPayEx

@Override
public WxPayRefundV3Result partnerRefundV3(WxPayPartnerRefundV3Request request) throws WxPayException {
if (StringUtils.isBlank(request.getSpAppid())) {
request.setSpAppid(this.getConfig().getAppId());
}
if (StringUtils.isBlank(request.getSubAppid()) && StringUtils.isNotBlank(this.getConfig().getSubAppId())) {
request.setSubAppid(this.getConfig().getSubAppId());
}
if (StringUtils.isBlank(request.getNotifyUrl())) {
request.setNotifyUrl(this.getConfig().getRefundNotifyUrl());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.github.binarywang.wxpay.bean.request;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.testng.annotations.Test;

import static org.assertj.core.api.Assertions.assertThat;

/**
* {@link WxPayPartnerRefundV3Request} 单元测试
*
*/
public class WxPayPartnerRefundV3RequestTest {

@Test
public void testSpAppidAndSubAppidSerialization() {
WxPayPartnerRefundV3Request request = new WxPayPartnerRefundV3Request();
request.setSpAppid("wx8888888888888888");
request.setSubAppid("wxd678efh567hg6999");
request.setSubMchid("1230000109");
request.setOutRefundNo("1217752501201407033233368018");
request.setFundsAccount("AVAILABLE");

Gson gson = new Gson();
Copy link

Choose a reason for hiding this comment

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

这里使用 new Gson() 做序列化断言,可能与生产路径里统一使用的 Gson 配置(例如 BaseWxPayServiceImpl 内的 GsonBuilder 实例)在未来发生偏离,导致单测与真实请求不一致;建议确认是否应复用项目内同一套 Gson 构建方式。

Severity: low

Other Locations
  • weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/request/WxPayPartnerRefundV3RequestTest.java:43

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

String json = gson.toJson(request);
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);

assertThat(jsonObject.has("sp_appid")).isTrue();
assertThat(jsonObject.get("sp_appid").getAsString()).isEqualTo("wx8888888888888888");
assertThat(jsonObject.has("sub_appid")).isTrue();
assertThat(jsonObject.get("sub_appid").getAsString()).isEqualTo("wxd678efh567hg6999");
assertThat(jsonObject.has("sub_mchid")).isTrue();
assertThat(jsonObject.get("sub_mchid").getAsString()).isEqualTo("1230000109");
assertThat(jsonObject.has("out_refund_no")).isTrue();
assertThat(jsonObject.get("out_refund_no").getAsString()).isEqualTo("1217752501201407033233368018");
assertThat(jsonObject.has("funds_account")).isTrue();
assertThat(jsonObject.get("funds_account").getAsString()).isEqualTo("AVAILABLE");
}

@Test
public void testSubAppidIsOptional() {
WxPayPartnerRefundV3Request request = new WxPayPartnerRefundV3Request();
request.setSpAppid("wx8888888888888888");
request.setSubMchid("1230000109");
request.setOutRefundNo("1217752501201407033233368018");

Gson gson = new Gson();
String json = gson.toJson(request);
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);

assertThat(jsonObject.has("sp_appid")).isTrue();
assertThat(jsonObject.get("sp_appid").getAsString()).isEqualTo("wx8888888888888888");
assertThat(jsonObject.has("sub_appid")).isFalse();
}
}