mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-08-23 22:11:40 +08:00
🎨 #3056 【微信支付】优化支付/退款结果解析,增加对V3版本服务商的下单/退款支持
This commit is contained in:
parent
211f4c7f74
commit
21a95e15df
@ -0,0 +1,30 @@
|
||||
package com.github.binarywang.wxpay.bean.notify;
|
||||
|
||||
/**
|
||||
* 微信支付公用回调
|
||||
*
|
||||
* @author Pursuer
|
||||
* @version 1.0
|
||||
* @date 2023/6/15
|
||||
*/
|
||||
public interface WxPayBaseNotifyV3Result<T> {
|
||||
/**
|
||||
* 设置原始数据
|
||||
*
|
||||
* @param rawData 原始数据
|
||||
* @author Pursuer
|
||||
* @date 2023/6/15
|
||||
* @since 1.0
|
||||
**/
|
||||
void setRawData(OriginNotifyResponse rawData);
|
||||
|
||||
/**
|
||||
* 解密后的数据
|
||||
*
|
||||
* @param data 解密后的数据
|
||||
* @author Pursuer
|
||||
* @date 2023/6/15
|
||||
* @since 1.0
|
||||
**/
|
||||
void setResult(T data);
|
||||
}
|
@ -15,7 +15,7 @@ import java.util.List;
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WxPayOrderNotifyV3Result implements Serializable {
|
||||
public class WxPayNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result<WxPayNotifyV3Result.DecryptNotifyResult> {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* 源数据
|
@ -0,0 +1,568 @@
|
||||
package com.github.binarywang.wxpay.bean.notify;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 微信支付服务商下单回调
|
||||
* 文档见:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_5.shtml
|
||||
*
|
||||
* @author Guo Shuai
|
||||
* @version 1.0
|
||||
* @date 2023/3/2
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WxPayPartnerNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result<WxPayPartnerNotifyV3Result.DecryptNotifyResult> {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* 源数据
|
||||
*/
|
||||
private OriginNotifyResponse rawData;
|
||||
/**
|
||||
* 解密后的数据
|
||||
*/
|
||||
private DecryptNotifyResult result;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class DecryptNotifyResult implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:服务商应用ID
|
||||
* 变量名:spAppid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 由微信生成的应用ID,全局唯一。请求统一下单接口时请注意APPID的应用属性,例如公众号场景下,需使用应用属性为公众号的APPID
|
||||
* 示例值:wxd678efh567hg6787
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sp_appid")
|
||||
protected String spAppid;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:服务商商户号
|
||||
* 变量名:spMchid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 服务商商户号,由微信支付生成并下发。
|
||||
* 示例值:1230000109
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sp_mchid")
|
||||
protected String spMchid;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:子商户应用ID
|
||||
* 变量名:subAppid
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 由微信生成的应用ID,全局唯一。请求统一下单接口时请注意APPID的应用属性,例如公众号场景下,需使用应用属性为公众号的APPID
|
||||
* 示例值:wxd678efh567hg6787
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sub_appid")
|
||||
protected String subAppid;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:子商户商户号
|
||||
* 变量名:subMchid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 子商户商户号,由微信支付生成并下发。
|
||||
* 示例值:1230000109
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sub_mchid")
|
||||
protected String subMchid;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户订单号
|
||||
* 变量名:out_trade_no
|
||||
* 是否必填:是
|
||||
* 类型:string[6,32]
|
||||
* 描述:
|
||||
* 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一。
|
||||
* 特殊规则:最小字符长度为6
|
||||
* 示例值:1217752501201407033233368018
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:微信支付订单号
|
||||
* 变量名:transaction_id
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 微信支付系统生成的订单号。
|
||||
* 示例值:1217752501201407033233368018
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "transaction_id")
|
||||
private String transactionId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:交易类型
|
||||
* 变量名:trade_type
|
||||
* 是否必填:是
|
||||
* 类型:string[1,16]
|
||||
* 描述:
|
||||
* 交易类型,枚举值:
|
||||
* JSAPI:公众号支付
|
||||
* NATIVE:扫码支付
|
||||
* APP:APP支付
|
||||
* MICROPAY:付款码支付
|
||||
* MWEB:H5支付
|
||||
* FACEPAY:刷脸支付
|
||||
* 示例值:MICROPAY
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "trade_type")
|
||||
private String tradeType;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:交易状态
|
||||
* 变量名:trade_state
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 交易状态,枚举值:
|
||||
* SUCCESS:支付成功
|
||||
* REFUND:转入退款
|
||||
* NOTPAY:未支付
|
||||
* CLOSED:已关闭
|
||||
* REVOKED:已撤销(付款码支付)
|
||||
* USERPAYING:用户支付中(付款码支付)
|
||||
* PAYERROR:支付失败(其他原因,如银行返回失败)
|
||||
* 示例值:SUCCESS
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "trade_state")
|
||||
private String tradeState;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:交易状态描述
|
||||
* 变量名:trade_state_desc
|
||||
* 是否必填:是
|
||||
* 类型:string[1,256]
|
||||
* 描述:
|
||||
* 交易状态描述
|
||||
* 示例值:支付成功
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "trade_state_desc")
|
||||
private String tradeStateDesc;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:付款银行
|
||||
* 变量名:bank_type
|
||||
* 是否必填:是
|
||||
* 类型:string[1,16]
|
||||
* 描述:
|
||||
* 银行类型,采用字符串类型的银行标识。银行标识请参考《银行类型对照表》https://pay.weixin.qq.com/wiki/doc/apiv3/terms_definition/chapter1_1_3.shtml#part-6
|
||||
* 示例值:CMC
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "bank_type")
|
||||
private String bankType;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:附加数据
|
||||
* 变量名:attach
|
||||
* 是否必填:否
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
|
||||
* 示例值:自定义数据
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "attach")
|
||||
private String attach;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:支付完成时间
|
||||
* 变量名:success_time
|
||||
* 是否必填:是
|
||||
* 类型:string[1,64]
|
||||
* 描述:
|
||||
* 支付完成时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒。
|
||||
* 示例值:2018-06-08T10:34:56+08:00
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "success_time")
|
||||
private String successTime;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:支付者
|
||||
* 变量名:payer
|
||||
* 是否必填:是
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 支付者信息
|
||||
* </pre>
|
||||
*/
|
||||
private Payer payer;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:订单金额
|
||||
* 变量名:amount
|
||||
* 是否必填:否
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 订单金额信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "amount")
|
||||
private Amount amount;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:场景信息
|
||||
* 变量名:scene_info
|
||||
* 是否必填:否
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 支付场景信息描述
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "scene_info")
|
||||
private SceneInfo sceneInfo;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:优惠功能
|
||||
* 变量名:promotion_detail
|
||||
* 是否必填:否
|
||||
* 类型:array
|
||||
* 描述:
|
||||
* 优惠功能,享受优惠时返回该字段。
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "promotion_detail")
|
||||
private List<PromotionDetail> promotionDetails;
|
||||
}
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class Payer implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:用户标识
|
||||
* 变量名:openid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* 用户在直连商户appid下的唯一标识。
|
||||
* 示例值:oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "openid")
|
||||
private String openid;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class Amount implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:总金额
|
||||
* 变量名:total
|
||||
* 是否必填:否
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 订单总金额,单位为分。
|
||||
* 示例值:100
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "total")
|
||||
private Integer total;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:用户支付金额
|
||||
* 变量名:payer_total
|
||||
* 是否必填:否
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 用户支付金额,单位为分。
|
||||
* 示例值:100
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "payer_total")
|
||||
private Integer payerTotal;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:货币类型
|
||||
* 变量名:currency
|
||||
* 是否必填:否
|
||||
* 类型:string[1,16]
|
||||
* 描述:
|
||||
* CNY:人民币,境内商户号仅支持人民币。
|
||||
* 示例值:CNY
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "currency")
|
||||
private String currency;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:用户支付币种
|
||||
* 变量名:payer_currency
|
||||
* 是否必填:否
|
||||
* 类型:string[1,16]
|
||||
* 描述:
|
||||
* 用户支付币种
|
||||
* 示例值: CNY
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "payer_currency")
|
||||
private String payerCurrency;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class SceneInfo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户端设备号
|
||||
* 变量名:device_id
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 终端设备号(门店号或收银设备ID)。
|
||||
* 示例值:013467007045764
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "device_id")
|
||||
private String deviceId;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class PromotionDetail implements Serializable {
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:券ID
|
||||
* 变量名:coupon_id
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 券ID
|
||||
* 示例值:109519
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "coupon_id")
|
||||
private String couponId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:优惠名称
|
||||
* 变量名:name
|
||||
* 是否必填:否
|
||||
* 类型:string[1,64]
|
||||
* 描述:
|
||||
* 优惠名称
|
||||
* 示例值:单品惠-6
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "name")
|
||||
private String name;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:优惠范围
|
||||
* 变量名:scope
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* GLOBAL:全场代金券
|
||||
* SINGLE:单品优惠
|
||||
* 示例值:GLOBAL
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "scope")
|
||||
private String scope;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:优惠类型
|
||||
* 变量名:type
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* CASH:充值
|
||||
* NOCASH:预充值
|
||||
* 示例值:CASH
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "type")
|
||||
private String type;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:优惠券面额
|
||||
* 变量名:amount
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 优惠券面额
|
||||
* 示例值:100
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "amount")
|
||||
private Integer amount;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:活动ID
|
||||
* 变量名:stock_id
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 活动ID
|
||||
* 示例值:931386
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "stock_id")
|
||||
private String stockId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:微信出资
|
||||
* 变量名:wechatpay_contribute
|
||||
* 是否必填:否
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 微信出资,单位为分
|
||||
* 示例值:0
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "wechatpay_contribute")
|
||||
private Integer wechatpayContribute;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户出资
|
||||
* 变量名:merchant_contribute
|
||||
* 是否必填:否
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 商户出资,单位为分
|
||||
* 示例值:0
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "merchant_contribute")
|
||||
private Integer merchantContribute;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:其他出资
|
||||
* 变量名:other_contribute
|
||||
* 是否必填:否
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 其他出资,单位为分
|
||||
* 示例值:0
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "other_contribute")
|
||||
private Integer otherContribute;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:优惠币种
|
||||
* 变量名:currency
|
||||
* 是否必填:否
|
||||
* 类型:string[1,16]
|
||||
* 描述:
|
||||
* CNY:人民币,境内商户号仅支持人民币。
|
||||
* 示例值:CNY
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "currency")
|
||||
private String currency;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:单品列表
|
||||
* 变量名:goods_detail
|
||||
* 是否必填:否
|
||||
* 类型:array
|
||||
* 描述:
|
||||
* 单品列表信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "goods_detail")
|
||||
private List<GoodsDetail> goodsDetails;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class GoodsDetail implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品编码
|
||||
* 变量名:goods_id
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 商品编码
|
||||
* 示例值:M1006
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "goods_id")
|
||||
private String goodsId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品数量
|
||||
* 变量名:quantity
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 用户购买的数量
|
||||
* 示例值:1
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "quantity")
|
||||
private Integer quantity;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品单价
|
||||
* 变量名:unit_price
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 商品单价,单位为分
|
||||
* 示例值:100
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "unit_price")
|
||||
private Integer unitPrice;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品优惠金额
|
||||
* 变量名:discount_amount
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 商品优惠金额
|
||||
* 示例值:0
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "discount_amount")
|
||||
private Integer discountAmount;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品备注
|
||||
* 变量名:goods_remark
|
||||
* 是否必填:否
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* 商品备注信息
|
||||
* 示例值:商品备注信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "goods_remark")
|
||||
private String goodsRemark;
|
||||
}
|
||||
}
|
@ -0,0 +1,230 @@
|
||||
package com.github.binarywang.wxpay.bean.notify;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 微信支付服务商退款回调
|
||||
* 文档见:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_11.shtml
|
||||
*
|
||||
* @author Guo Shuai
|
||||
* @version 1.0
|
||||
* @date 2023/3/2
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WxPayPartnerRefundNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result<WxPayPartnerRefundNotifyV3Result.DecryptNotifyResult> {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* 源数据
|
||||
*/
|
||||
private OriginNotifyResponse rawData;
|
||||
/**
|
||||
* 解密后的数据
|
||||
*/
|
||||
private DecryptNotifyResult result;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class DecryptNotifyResult implements Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:服务商的商户号
|
||||
* 变量名:sub_mchid
|
||||
* 是否必填:是
|
||||
* 类型:string[1, 32]
|
||||
* 描述:
|
||||
* 服务商的商户号,由微信支付生成并下发。
|
||||
* 示例值:1230000109
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sp_mchid")
|
||||
private String spMchId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:子商户的商户号
|
||||
* 变量名:sub_mchid
|
||||
* 是否必填:是
|
||||
* 类型:string[1, 32]
|
||||
* 描述:
|
||||
* 子商户商户号,由微信支付生成并下发。
|
||||
* 示例值:1230000109
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sub_mchid")
|
||||
private String subMchId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户订单号
|
||||
* 变量名:out_trade_no
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 返回的商户订单号
|
||||
* 示例值: 1217752501201407033233368018
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:微信支付订单号
|
||||
* 变量名:transaction_id
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 微信支付订单号
|
||||
* 示例值: 1217752501201407033233368018
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "transaction_id")
|
||||
private String transactionId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户退款单号
|
||||
* 变量名:out_refund_no
|
||||
* 是否必填:是
|
||||
* 类型:string[1,64]
|
||||
* 描述:
|
||||
* 商户退款单号
|
||||
* 示例值: 1217752501201407033233368018
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "out_refund_no")
|
||||
private String outRefundNo;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:微信支付退款号
|
||||
* 变量名:refund_id
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 微信退款单号
|
||||
* 示例值: 1217752501201407033233368018
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "refund_id")
|
||||
private String refundId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:退款状态
|
||||
* 变量名:refund_status
|
||||
* 是否必填:是
|
||||
* 类型:string[1,16]
|
||||
* 描述:
|
||||
* 退款状态,枚举值:
|
||||
* SUCCESS:退款成功
|
||||
* CLOSE:退款关闭
|
||||
* ABNORMAL:退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往【商户平台—>交易中心】,手动处理此笔退款
|
||||
* 示例值:SUCCESS
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "refund_status")
|
||||
private String refundStatus;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:退款成功时间
|
||||
* 变量名:success_time
|
||||
* 是否必填:否
|
||||
* 类型:string[1,64]
|
||||
* 描述:
|
||||
* 1、退款成功时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日13点29分35秒。
|
||||
* 2、当退款状态为退款成功时返回此参数。
|
||||
* 示例值:2018-06-08T10:34:56+08:00
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "success_time")
|
||||
private String successTime;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:退款入账账户
|
||||
* 变量名:user_received_account
|
||||
* 是否必填:是
|
||||
* 类型:string[1,64]
|
||||
* 描述:
|
||||
* 取当前退款单的退款入账方。
|
||||
* 1、退回银行卡:{银行名称}{卡类型}{卡尾号}
|
||||
* 2、退回支付用户零钱: 支付用户零钱
|
||||
* 3、退还商户: 商户基本账户、商户结算银行账户
|
||||
* 4、退回支付用户零钱通:支付用户零钱通
|
||||
* 示例值:招商银行信用卡0403
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "user_received_account")
|
||||
private String userReceivedAccount;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:金额信息
|
||||
* 变量名:amount
|
||||
* 是否必填:是
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 金额信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "amount")
|
||||
private Amount amount;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class Amount implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:订单金额
|
||||
* 变量名:total
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 订单总金额,单位为分,只能为整数,详见支付金额
|
||||
* 示例值:999
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "total")
|
||||
private Integer total;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:退款金额
|
||||
* 变量名:refund
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 退款金额,币种的最小单位,只能为整数,不能超过原订单支付金额,如果有使用券,后台会按比例退。
|
||||
* 示例值:999
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "refund")
|
||||
private Integer refund;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:用户支付金额
|
||||
* 变量名:payer_total
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 用户实际支付金额,单位为分,只能为整数,详见支付金额
|
||||
* 示例值:999
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "payer_total")
|
||||
private Integer payerTotal;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:用户退款金额
|
||||
* 变量名:payer_refund
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 退款给用户的金额,不包含所有优惠券金额
|
||||
* 示例值:999
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "payer_refund")
|
||||
private Integer payerRefund;
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ import java.io.Serializable;
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WxPayRefundNotifyV3Result implements Serializable {
|
||||
public class WxPayRefundNotifyV3Result implements Serializable, WxPayBaseNotifyV3Result<WxPayRefundNotifyV3Result.DecryptNotifyResult> {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* 源数据
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.github.binarywang.wxpay.bean.request;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 微信支付服务商退款请求
|
||||
* 文档见:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_9.shtml
|
||||
*
|
||||
* @author Guo Shuai
|
||||
* @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>
|
||||
* 字段名:子商户的商户号
|
||||
* 变量名:sub_mchid
|
||||
* 是否必填:是
|
||||
* 类型:string[1, 32]
|
||||
* 描述:
|
||||
* 子商户商户号,由微信支付生成并下发。
|
||||
* 示例值:1230000109
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sub_mchid")
|
||||
private String subMchId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:退款资金来源
|
||||
* 变量名:funds_account
|
||||
* 是否必填:否
|
||||
* 类型:string[1, 32]
|
||||
* 描述:
|
||||
* 若传递此参数则使用对应的资金账户退款,否则默认使用未结算资金退款(仅对老资金流商户适用)
|
||||
* 示例值:
|
||||
* UNSETTLED : 未结算资金
|
||||
* AVAILABLE : 可用余额
|
||||
* UNAVAILABLE : 不可用余额
|
||||
* OPERATION : 运营户
|
||||
* BASIC : 基本账户(含可用余额和不可用余额)
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "funds_account")
|
||||
private String fundsAccount;
|
||||
}
|
@ -0,0 +1,610 @@
|
||||
package com.github.binarywang.wxpay.bean.request;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 微信支付服务商下单请求对象
|
||||
*
|
||||
* @author Guo Shuai
|
||||
* @version 1.0
|
||||
* @date 2023/3/2
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class WxPayPartnerUnifiedOrderV3Request implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:服务商应用ID
|
||||
* 变量名:spAppid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 由微信生成的应用ID,全局唯一。请求统一下单接口时请注意APPID的应用属性,例如公众号场景下,需使用应用属性为公众号的APPID
|
||||
* 示例值:wxd678efh567hg6787
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sp_appid")
|
||||
protected String spAppid;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:服务商商户号
|
||||
* 变量名:spMchid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 服务商商户号,由微信支付生成并下发。
|
||||
* 示例值:1230000109
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sp_mchid")
|
||||
protected String spMchId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:子商户应用ID
|
||||
* 变量名:subAppid
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 由微信生成的应用ID,全局唯一。请求统一下单接口时请注意APPID的应用属性,例如公众号场景下,需使用应用属性为公众号的APPID
|
||||
* 示例值:wxd678efh567hg6787
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sub_appid")
|
||||
protected String subAppid;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:子商户商户号
|
||||
* 变量名:subMchid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 子商户商户号,由微信支付生成并下发。
|
||||
* 示例值:1230000109
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sub_mchid")
|
||||
protected String subMchId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品描述
|
||||
* 变量名:description
|
||||
* 是否必填:是
|
||||
* 类型:string[1,127]
|
||||
* 描述:
|
||||
* 商品描述
|
||||
* 示例值:Image形象店-深圳腾大-QQ公仔
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "description")
|
||||
protected String description;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户订单号
|
||||
* 变量名:out_trade_no
|
||||
* 是否必填:是
|
||||
* 类型:string[6,32]
|
||||
* 描述:
|
||||
* 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
|
||||
* 示例值:1217752501201407033233368018
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "out_trade_no")
|
||||
protected String outTradeNo;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:交易结束时间
|
||||
* 变量名:time_expire
|
||||
* 是否必填:是
|
||||
* 类型:string[1,64]
|
||||
* 描述:
|
||||
* 订单失效时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒。
|
||||
* 示例值:2018-06-08T10:34:56+08:00
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "time_expire")
|
||||
protected String timeExpire;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:附加数据
|
||||
* 变量名:attach
|
||||
* 是否必填:否
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
|
||||
* 示例值:自定义数据
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "attach")
|
||||
protected String attach;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:通知地址
|
||||
* 变量名:notify_url
|
||||
* 是否必填:是
|
||||
* 类型:string[1,256]
|
||||
* 描述:
|
||||
* 通知URL必须为直接可访问的URL,不允许携带查询串,要求必须为https地址。
|
||||
* 格式:URL
|
||||
* 示例值:https://www.weixin.qq.com/wxpay/pay.php
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "notify_url")
|
||||
private String notifyUrl;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:订单优惠标记
|
||||
* 变量名:goods_tag
|
||||
* 是否必填:否
|
||||
* 类型:string[1,256]
|
||||
* 描述:
|
||||
* 订单优惠标记
|
||||
* 示例值:WXG
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "goods_tag")
|
||||
private String goodsTag;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:电子发票入口开放标识
|
||||
* 变量名:support_fapiao
|
||||
* 是否必填:否
|
||||
* 类型:boolean
|
||||
* 描述:传入true时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效。
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "support_fapiao")
|
||||
private Boolean supportFapiao;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:订单金额
|
||||
* 变量名:amount
|
||||
* 是否必填:是
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 订单金额信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "amount")
|
||||
private Amount amount;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:支付者
|
||||
* 变量名:payer
|
||||
* 是否必填:是
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 支付者信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "payer")
|
||||
private Payer payer;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:优惠功能
|
||||
* 变量名:detail
|
||||
* 是否必填:否
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 优惠功能
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "detail")
|
||||
private Discount detail;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:场景信息
|
||||
* 变量名:scene_info
|
||||
* 是否必填:否
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 支付场景描述
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "scene_info")
|
||||
private SceneInfo sceneInfo;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:结算信息
|
||||
* 变量名:settle_info
|
||||
* 是否必填:否
|
||||
* 类型:Object
|
||||
* 描述:结算信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "settle_info")
|
||||
private SettleInfo settleInfo;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class Amount implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:总金额
|
||||
* 变量名:total
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 订单总金额,单位为分。
|
||||
* 示例值:100
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "total")
|
||||
private Integer total;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:币类型
|
||||
* 变量名:currency
|
||||
* 是否必填:否
|
||||
* 类型:string[1,16]
|
||||
* 描述:
|
||||
* CNY:人民币,境内商户号仅支持人民币。
|
||||
* 示例值:CNY
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "currency")
|
||||
private String currency;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class Payer implements Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* <pre>
|
||||
* spOpenid 和 subOpenid二选一 参考官网
|
||||
* 字段名:服务商用户标识
|
||||
* 变量名:spOpenid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* 用户在服务商appid下的唯一标识。
|
||||
* 示例值:oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sp_openid")
|
||||
private String spOpenid;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:子商户应用用户标识
|
||||
* 变量名:subOpenid
|
||||
* 是否必填:是
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* 用户在子商户appid下的唯一标识。
|
||||
* 示例值:oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "sub_openid")
|
||||
private String subOpenid;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class Discount implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:订单原价
|
||||
* 变量名:cost_price
|
||||
* 是否必填:否
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 1、商户侧一张小票订单可能被分多次支付,订单原价用于记录整张小票的交易金额。
|
||||
* 2、当订单原价与支付金额不相等,则不享受优惠。
|
||||
* 3、该字段主要用于防止同一张小票分多次支付,以享受多次优惠的情况,正常支付订单不必上传此参数。
|
||||
* 示例值:608800
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "cost_price")
|
||||
private Integer costPrice;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品小票ID
|
||||
* 变量名:invoice_id
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 商品小票ID
|
||||
* 示例值:微信123
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "invoice_id")
|
||||
private String invoiceId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:单品列表
|
||||
* 变量名:goods_detail
|
||||
* 是否必填:否
|
||||
* 类型:array
|
||||
* 描述:
|
||||
* 单品列表信息
|
||||
* 条目个数限制:【1,6000】
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "goods_detail")
|
||||
private List<GoodsDetail> goodsDetails;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class GoodsDetail implements Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户侧商品编码
|
||||
* 变量名:merchant_goods_id
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 由半角的大小写字母、数字、中划线、下划线中的一种或几种组成。
|
||||
* 示例值:商品编码
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "merchant_goods_id")
|
||||
private String merchantGoodsId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:微信侧商品编码
|
||||
* 变量名:wechatpay_goods_id
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 微信支付定义的统一商品编号(没有可不传)
|
||||
* 示例值:1001
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "wechatpay_goods_id")
|
||||
private String wechatpayGoodsId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品名称
|
||||
* 变量名:goods_name
|
||||
* 是否必填:否
|
||||
* 类型:string[1,256]
|
||||
* 描述:
|
||||
* 商品的实际名称
|
||||
* 示例值:iPhoneX 256G
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "goods_name")
|
||||
private String goodsName;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品数量
|
||||
* 变量名:quantity
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 用户购买的数量
|
||||
* 示例值:1
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "quantity")
|
||||
private Integer quantity;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商品单价
|
||||
* 变量名:unit_price
|
||||
* 是否必填:是
|
||||
* 类型:int
|
||||
* 描述:
|
||||
* 商品单价,单位为分
|
||||
* 示例值:828800
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "unit_price")
|
||||
private Integer unitPrice;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class SceneInfo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:用户终端IP
|
||||
* 变量名:payer_client_ip
|
||||
* 是否必填:是
|
||||
* 类型:string[1,45]
|
||||
* 描述:
|
||||
* 用户的客户端IP,支持IPv4和IPv6两种格式的IP地址。
|
||||
* 示例值:14.23.150.211
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "payer_client_ip")
|
||||
private String payerClientIp;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户端设备号
|
||||
* 变量名:device_id
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 商户端设备号(门店号或收银设备ID)。
|
||||
* 示例值:013467007045764
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "device_id")
|
||||
private String deviceId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:商户门店信息
|
||||
* 变量名:store_info
|
||||
* 是否必填:否
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* 商户门店信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "store_info")
|
||||
private StoreInfo storeInfo;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:H5场景信息
|
||||
* 变量名:h5_info
|
||||
* 是否必填:否(H5支付必填)
|
||||
* 类型:object
|
||||
* 描述:
|
||||
* H5场景信息
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "h5_info")
|
||||
private H5Info h5Info;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class StoreInfo implements Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:门店编号
|
||||
* 变量名:id
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 商户侧门店编号
|
||||
* 示例值:0001
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "id")
|
||||
private String id;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:门店名称
|
||||
* 变量名:name
|
||||
* 是否必填:否
|
||||
* 类型:string[1,256]
|
||||
* 描述:
|
||||
* 商户侧门店名称
|
||||
* 示例值:腾讯大厦分店
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "name")
|
||||
private String name;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:地区编码
|
||||
* 变量名:area_code
|
||||
* 是否必填:否
|
||||
* 类型:string[1,32]
|
||||
* 描述: 地区编码, <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/applyments/chapter4_1.shtml">详细请见省市区编号对照表</a>。
|
||||
* 示例值:440305
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "area_code")
|
||||
private String areaCode;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:详细地址
|
||||
* 变量名:address
|
||||
* 是否必填:是
|
||||
* 类型:string[1,512]
|
||||
* 描述:
|
||||
* 详细的商户门店地址
|
||||
* 示例值:广东省深圳市南山区科技中一道10000号
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "address")
|
||||
private String address;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class H5Info implements Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:场景类型
|
||||
* 变量名:type
|
||||
* 是否必填:是
|
||||
* 类型:string[1,32]
|
||||
* 描述:
|
||||
* 场景类型
|
||||
* 示例值:iOS, Android, Wap
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "type")
|
||||
private String type;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:应用名称
|
||||
* 变量名:app_name
|
||||
* 是否必填:否
|
||||
* 类型:string[1,64]
|
||||
* 描述:
|
||||
* 应用名称
|
||||
* 示例值:王者荣耀
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "app_name")
|
||||
private String appName;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:网站URL
|
||||
* 变量名:app_url
|
||||
* 是否必填:否
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* 网站URL
|
||||
* 示例值:https://pay.qq.com
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "app_url")
|
||||
private String appUrl;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:iOS平台BundleID
|
||||
* 变量名:bundle_id
|
||||
* 是否必填:否
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* iOS平台BundleID
|
||||
* 示例值:com.tencent.wzryiOS
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "bundle_id")
|
||||
private String bundleId;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:Android平台PackageName
|
||||
* 变量名:package_name
|
||||
* 是否必填:否
|
||||
* 类型:string[1,128]
|
||||
* 描述:
|
||||
* Android平台PackageName
|
||||
* 示例值:com.tencent.tmgp.sgame
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "package_name")
|
||||
private String packageName;
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class SettleInfo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* <pre>
|
||||
* 字段名:是否指定分账
|
||||
* 变量名:profit_sharing
|
||||
* 是否必填:否
|
||||
* 类型:boolean
|
||||
* 描述:
|
||||
* 是否指定分账
|
||||
* 示例值:false
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName(value = "profit_sharing")
|
||||
private Boolean profitSharing;
|
||||
}
|
||||
}
|
@ -169,7 +169,7 @@ public interface WxPayService {
|
||||
* <p>
|
||||
* 部分字段会包含敏感信息,所以在提交前需要在请求头中会包含"Wechatpay-Serial"信息
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param url 请求地址
|
||||
* @return 返回请求结果字符串 string
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
@ -550,6 +550,27 @@ public interface WxPayService {
|
||||
*/
|
||||
<T> T createOrderV3(TradeTypeEnum tradeType, WxPayUnifiedOrderV3Request request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 服务商模式调用统一下单接口,并组装生成支付所需参数对象.
|
||||
*
|
||||
* @param <T> 请使用{@link com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result}里的内部类或字段
|
||||
* @param tradeType the trade type
|
||||
* @param request 统一下单请求参数
|
||||
* @return 返回 {@link com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result}里的内部类或字段
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
<T> T createPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
*
|
||||
* @param tradeType the trade type
|
||||
* @param request 请求对象,注意一些参数如spAppid、spMchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置)
|
||||
* @return the wx pay unified order result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayUnifiedOrderV3Result unifiedPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
*
|
||||
@ -802,7 +823,7 @@ public interface WxPayService {
|
||||
WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData, String signType) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析支付结果v3通知.
|
||||
* 解析支付结果v3通知. 直连商户模式
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
@ -810,7 +831,31 @@ public interface WxPayService {
|
||||
* @return the wx pay order notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayOrderNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
WxPayNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 服务商模式解析支付结果v3通知.
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_5.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
* @param header 通知头部数据,不传则表示不校验头
|
||||
* @return the wx pay order notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayPartnerNotifyV3Result parsePartnerOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 支付服务商和直连商户两种模式
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
* @param header 通知头部数据,不传则表示不校验头
|
||||
* @param resultType 结果类型
|
||||
* @param dataType 结果数据类型
|
||||
* @return the wx pay order notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
<T extends WxPayBaseNotifyV3Result<E>, E> T baseParseOrderNotifyV3Result(String notifyData, SignatureHeader header, Class<T> resultType, Class<E> dataType) throws WxPayException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
@ -836,7 +881,7 @@ public interface WxPayService {
|
||||
WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析退款结果通知
|
||||
* 解析直连商户退款结果通知
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=9
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
@ -846,6 +891,17 @@ public interface WxPayService {
|
||||
*/
|
||||
WxPayRefundNotifyV3Result parseRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析服务商模式退款结果通知
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_11.shtml
|
||||
*
|
||||
* @param notifyData 通知数据
|
||||
* @param header 通知头部数据,不传则表示不校验头
|
||||
* @return the wx pay refund notify result
|
||||
* @throws WxPayException the wx pay exception
|
||||
*/
|
||||
WxPayPartnerRefundNotifyV3Result parsePartnerRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException;
|
||||
|
||||
/**
|
||||
* 解析扫码支付回调通知
|
||||
* 详见https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4
|
||||
@ -1380,6 +1436,7 @@ public interface WxPayService {
|
||||
|
||||
/**
|
||||
* 获取服务商支付分服务类
|
||||
*
|
||||
* @return the partner pay score service
|
||||
*/
|
||||
PartnerPayScoreService getPartnerPayScoreService();
|
||||
|
@ -31,6 +31,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.chanjar.weixin.common.error.WxRuntimeException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.reflect.ConstructorUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -343,7 +344,17 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayOrderNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
public WxPayNotifyV3Result parseOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
return baseParseOrderNotifyV3Result(notifyData, header, WxPayNotifyV3Result.class, WxPayNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayPartnerNotifyV3Result parsePartnerOrderNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayPartnerNotifyV3Result.class, WxPayPartnerNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends WxPayBaseNotifyV3Result<E>, E> T baseParseOrderNotifyV3Result(String notifyData, SignatureHeader header, Class<T> resultType, Class<E> dataType) throws WxPayException {
|
||||
if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) {
|
||||
throw new WxPayException("非法请求,头部信息验证失败");
|
||||
}
|
||||
@ -355,12 +366,12 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
String apiV3Key = this.getConfig().getApiV3Key();
|
||||
try {
|
||||
String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
|
||||
WxPayOrderNotifyV3Result.DecryptNotifyResult decryptNotifyResult = GSON.fromJson(result, WxPayOrderNotifyV3Result.DecryptNotifyResult.class);
|
||||
WxPayOrderNotifyV3Result notifyResult = new WxPayOrderNotifyV3Result();
|
||||
E decryptNotifyResult = GSON.fromJson(result, dataType);
|
||||
T notifyResult = ConstructorUtils.invokeConstructor(resultType);
|
||||
notifyResult.setRawData(response);
|
||||
notifyResult.setResult(decryptNotifyResult);
|
||||
return notifyResult;
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
} catch (Exception e) {
|
||||
throw new WxPayException("解析报文异常!", e);
|
||||
}
|
||||
}
|
||||
@ -409,25 +420,12 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
|
||||
@Override
|
||||
public WxPayRefundNotifyV3Result parseRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
if (Objects.nonNull(header) && !this.verifyNotifySign(header, notifyData)) {
|
||||
throw new WxPayException("非法请求,头部信息验证失败");
|
||||
}
|
||||
OriginNotifyResponse response = GSON.fromJson(notifyData, OriginNotifyResponse.class);
|
||||
OriginNotifyResponse.Resource resource = response.getResource();
|
||||
String cipherText = resource.getCiphertext();
|
||||
String associatedData = resource.getAssociatedData();
|
||||
String nonce = resource.getNonce();
|
||||
String apiV3Key = this.getConfig().getApiV3Key();
|
||||
try {
|
||||
String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
|
||||
WxPayRefundNotifyV3Result.DecryptNotifyResult decryptNotifyResult = GSON.fromJson(result, WxPayRefundNotifyV3Result.DecryptNotifyResult.class);
|
||||
WxPayRefundNotifyV3Result notifyResult = new WxPayRefundNotifyV3Result();
|
||||
notifyResult.setRawData(response);
|
||||
notifyResult.setResult(decryptNotifyResult);
|
||||
return notifyResult;
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new WxPayException("解析报文异常!", e);
|
||||
}
|
||||
return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayRefundNotifyV3Result.class, WxPayRefundNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayPartnerRefundNotifyV3Result parsePartnerRefundNotifyV3Result(String notifyData, SignatureHeader header) throws WxPayException {
|
||||
return this.baseParseOrderNotifyV3Result(notifyData, header, WxPayPartnerRefundNotifyV3Result.class, WxPayPartnerRefundNotifyV3Result.DecryptNotifyResult.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -665,6 +663,37 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
||||
return result.getPayInfo(tradeType, request.getAppid(), request.getMchid(), this.getConfig().getPrivateKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T createPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException {
|
||||
WxPayUnifiedOrderV3Result result = this.unifiedPartnerOrderV3(tradeType, request);
|
||||
//获取应用ID
|
||||
String appId = StringUtils.isBlank(request.getSubAppid()) ? request.getSpAppid() : request.getSubAppid();
|
||||
return result.getPayInfo(tradeType, appId, request.getSubMchId(), this.getConfig().getPrivateKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayUnifiedOrderV3Result unifiedPartnerOrderV3(TradeTypeEnum tradeType, WxPayPartnerUnifiedOrderV3Request request) throws WxPayException {
|
||||
if (StringUtils.isBlank(request.getSpAppid())) {
|
||||
request.setSpAppid(this.getConfig().getAppId());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getSpMchId())) {
|
||||
request.setSpMchId(this.getConfig().getMchId());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getNotifyUrl())) {
|
||||
request.setNotifyUrl(this.getConfig().getNotifyUrl());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getSubAppid())) {
|
||||
request.setSubAppid(this.getConfig().getSubAppId());
|
||||
}
|
||||
if (StringUtils.isBlank(request.getSubMchId())) {
|
||||
request.setSubMchId(this.getConfig().getSubMchId());
|
||||
}
|
||||
|
||||
String url = this.getPayBaseUrl() + tradeType.getPartnerUrl();
|
||||
String response = this.postV3(url, GSON.toJson(request));
|
||||
return GSON.fromJson(response, WxPayUnifiedOrderV3Result.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxPayUnifiedOrderV3Result unifiedOrderV3(TradeTypeEnum tradeType, WxPayUnifiedOrderV3Request request) throws WxPayException {
|
||||
if (StringUtils.isBlank(request.getAppid())) {
|
||||
|
@ -796,7 +796,7 @@ public class BaseWxPayServiceImplTest {
|
||||
log.info("请求头参数为:timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
|
||||
|
||||
// V2版本请参考com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResultTest里的单元测试
|
||||
final WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = this.payService.parseOrderNotifyV3Result(RequestUtils.readData(request),
|
||||
final WxPayNotifyV3Result wxPayOrderNotifyV3Result = this.payService.parseOrderNotifyV3Result(RequestUtils.readData(request),
|
||||
new SignatureHeader(timestamp, nonce, signature, serialNo));
|
||||
log.info(GSON.toJson(wxPayOrderNotifyV3Result));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user