mirror of
https://gitee.com/egzosn/pay-java-parent.git
synced 2026-05-07 19:46:15 +08:00
微信V3版本接入直连接口,自测通过
This commit is contained in:
@@ -162,7 +162,7 @@ public class DefaultWxPayAssistService implements WxPayAssistService {
|
||||
String associatedData = encryptCertificate.getString("associated_data");
|
||||
String nonce = encryptCertificate.getString("nonce");
|
||||
String ciphertext = encryptCertificate.getString("ciphertext");
|
||||
String publicKey = AntCertificationUtil.decryptToString(associatedData, nonce, ciphertext, payConfigStorage.getSecretKey(), payConfigStorage.getInputCharset());
|
||||
String publicKey = AntCertificationUtil.decryptToString(associatedData, nonce, ciphertext, payConfigStorage.getV3ApiKey(), payConfigStorage.getInputCharset());
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(publicKey.getBytes(StandardCharsets.UTF_8));
|
||||
AntCertificationUtil.loadCertificate(certificate.getString("serial_no"), inputStream);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
* 微信支付分配的子商户号,开发者模式下必填 合作者id
|
||||
*/
|
||||
private String subMchId;
|
||||
/**
|
||||
* V2 Api密钥
|
||||
*/
|
||||
private String apiKey;
|
||||
|
||||
/**
|
||||
* 商户API证书
|
||||
@@ -111,19 +115,33 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
addAttr("mchId", mchId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为商户平台设置的密钥key
|
||||
*
|
||||
* @return 微信密钥
|
||||
* @return 微信v2密钥
|
||||
*/
|
||||
public String getSecretKey() {
|
||||
return getKeyPrivate();
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public void setSecretKey(String secretKey) {
|
||||
setKeyPrivate(secretKey);
|
||||
public void setApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
addAttr("apiKey", apiKey);
|
||||
}
|
||||
|
||||
public void setV3ApiKey(String v3ApiKey) {
|
||||
setKeyPrivate(v3ApiKey);
|
||||
}
|
||||
/**
|
||||
* 为商户平台设置的密钥key
|
||||
*
|
||||
* @return 微信v3密钥
|
||||
*/
|
||||
public String getV3ApiKey() {
|
||||
return getKeyPrivate();
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
@@ -147,6 +165,7 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
|
||||
public void setSubAppId(String subAppId) {
|
||||
this.subAppId = subAppId;
|
||||
addAttr("subAppId", subAppId);
|
||||
}
|
||||
|
||||
public String getSpAppId() {
|
||||
@@ -155,6 +174,7 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
|
||||
public void setSpAppId(String spAppId) {
|
||||
this.spAppId = spAppId;
|
||||
addAttr("spAppId", spAppId);
|
||||
}
|
||||
|
||||
public String getSpMchId() {
|
||||
@@ -163,6 +183,7 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
|
||||
public void setSpMchId(String spMchId) {
|
||||
this.spMchId = spMchId;
|
||||
addAttr("spMchId", spMchId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,6 +201,7 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
@Deprecated
|
||||
public void setSubAppid(String subAppid) {
|
||||
this.subAppId = subAppid;
|
||||
addAttr("subAppId", subAppId);
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +211,7 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
|
||||
public void setSubMchId(String subMchId) {
|
||||
this.subMchId = subMchId;
|
||||
addAttr("subMchId", subMchId);
|
||||
}
|
||||
|
||||
public Object getApiClientKeyP12() {
|
||||
@@ -197,6 +220,7 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
|
||||
public void setApiClientKeyP12(Object apiClientKeyP12) {
|
||||
this.apiClientKeyP12 = apiClientKeyP12;
|
||||
addAttr("apiClientKeyP12", apiClientKeyP12);
|
||||
}
|
||||
|
||||
public CertStoreType getCertStoreType() {
|
||||
@@ -205,6 +229,7 @@ public class WxPayConfigStorage extends BasePayConfigStorage {
|
||||
|
||||
public void setCertStoreType(CertStoreType certStoreType) {
|
||||
this.certStoreType = certStoreType;
|
||||
addAttr("certStoreType", certStoreType);
|
||||
}
|
||||
|
||||
public CertEnvironment getCertEnvironment() {
|
||||
|
||||
@@ -20,7 +20,6 @@ import static com.egzosn.pay.wx.api.WxConst.RETURN_CODE;
|
||||
import static com.egzosn.pay.wx.api.WxConst.RETURN_MSG_CODE;
|
||||
import static com.egzosn.pay.wx.api.WxConst.SANDBOXNEW;
|
||||
import static com.egzosn.pay.wx.api.WxConst.SUCCESS;
|
||||
import static com.egzosn.pay.wx.v3.utils.AntCertificationUtil.getCertificate;
|
||||
import static com.egzosn.pay.wx.v3.utils.WxConst.FAILURE;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@@ -52,14 +51,17 @@ import com.egzosn.pay.common.util.sign.SignUtils;
|
||||
import com.egzosn.pay.common.util.sign.encrypt.RSA2;
|
||||
import com.egzosn.pay.common.util.str.StringUtils;
|
||||
import com.egzosn.pay.wx.bean.WxPayError;
|
||||
import com.egzosn.pay.wx.bean.WxPayMessage;
|
||||
import com.egzosn.pay.wx.v3.bean.response.WxPayMessage;
|
||||
import com.egzosn.pay.wx.bean.WxTransferType;
|
||||
import com.egzosn.pay.wx.v3.bean.WxAccountType;
|
||||
import com.egzosn.pay.wx.v3.bean.WxBillType;
|
||||
import com.egzosn.pay.wx.v3.bean.WxTransactionType;
|
||||
import com.egzosn.pay.wx.v3.bean.order.Amount;
|
||||
import com.egzosn.pay.wx.v3.bean.order.RefundAmount;
|
||||
import com.egzosn.pay.wx.v3.bean.response.Resource;
|
||||
import com.egzosn.pay.wx.v3.bean.response.WxNoticeParams;
|
||||
import com.egzosn.pay.wx.v3.bean.response.WxRefundResult;
|
||||
import com.egzosn.pay.wx.v3.utils.AntCertificationUtil;
|
||||
import com.egzosn.pay.wx.v3.utils.WxConst;
|
||||
|
||||
/**
|
||||
@@ -94,6 +96,8 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
|
||||
public WxPayAssistService getAssistService() {
|
||||
if (null == wxPayAssistService) {
|
||||
wxPayAssistService = new DefaultWxPayAssistService(this);
|
||||
//在这预先进行初始化
|
||||
wxPayAssistService.refreshCertificate();
|
||||
}
|
||||
return wxPayAssistService;
|
||||
}
|
||||
@@ -121,17 +125,26 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
|
||||
super(payConfigStorage, configStorage);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置支付配置
|
||||
*
|
||||
* @param payConfigStorage 支付配置
|
||||
* 初始化之后执行
|
||||
*/
|
||||
@Override
|
||||
public BasePayService setPayConfigStorage(WxPayConfigStorage payConfigStorage) {
|
||||
payConfigStorage.loadCertEnvironment();
|
||||
this.payConfigStorage = payConfigStorage;
|
||||
wxParameterStructure = new WxParameterStructure(payConfigStorage);
|
||||
return this;
|
||||
protected void initAfter() {
|
||||
new Thread(() -> {
|
||||
payConfigStorage.loadCertEnvironment();
|
||||
wxParameterStructure = new WxParameterStructure(payConfigStorage);
|
||||
//在这预先进行初始化
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
|
||||
}
|
||||
getAssistService();
|
||||
}).start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,15 +197,15 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
|
||||
public boolean verify(NoticeParams noticeParams) {
|
||||
|
||||
//当前使用的微信平台证书序列号
|
||||
String serial = noticeParams.getHeader("Wechatpay-Serial");
|
||||
String serial = noticeParams.getHeader("wechatpay-serial");
|
||||
//微信服务器的时间戳
|
||||
String timestamp = noticeParams.getHeader("Wechatpay-Timestamp");
|
||||
String timestamp = noticeParams.getHeader("wechatpay-timestamp");
|
||||
//微信服务器提供的随机串
|
||||
String nonce = noticeParams.getHeader("Wechatpay-Nonce");
|
||||
String nonce = noticeParams.getHeader("wechatpay-nonce");
|
||||
//微信平台签名
|
||||
String signature = noticeParams.getHeader("Wechatpay-Signature");
|
||||
String signature = noticeParams.getHeader("wechatpay-signature");
|
||||
|
||||
Certificate certificate = getCertificate(serial);
|
||||
Certificate certificate = getAssistService().getCertificate(serial);
|
||||
|
||||
Map<String, Object> attr = noticeParams.getAttr();
|
||||
|
||||
@@ -328,7 +341,21 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
|
||||
*/
|
||||
@Override
|
||||
public NoticeParams getNoticeParams(NoticeRequest request) {
|
||||
NoticeParams noticeParams = new NoticeParams();
|
||||
WxNoticeParams noticeParams = null;
|
||||
try (InputStream is = request.getInputStream()) {
|
||||
String body = IOUtils.toString(is);
|
||||
noticeParams = JSON.parseObject(body, WxNoticeParams.class);
|
||||
noticeParams.setAttr(new MapGen<String, Object>(WxConst.RESP_BODY, body).getAttr());
|
||||
Resource resource = noticeParams.getResource();
|
||||
String associatedData = resource.getAssociatedData();
|
||||
String nonce = resource.getNonce();
|
||||
String ciphertext = resource.getCiphertext();
|
||||
String data = AntCertificationUtil.decryptToString(associatedData, nonce, ciphertext, payConfigStorage.getV3ApiKey(), payConfigStorage.getInputCharset());
|
||||
noticeParams.setBody(JSON.parseObject(data));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("获取回调参数异常", e);
|
||||
}
|
||||
Map<String, List<String>> headers = new HashMap<>();
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
while (headerNames.hasMoreElements()) {
|
||||
@@ -336,15 +363,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
|
||||
headers.put(name, Collections.list(request.getHeaders(name)));
|
||||
}
|
||||
noticeParams.setHeaders(headers);
|
||||
try (InputStream is = request.getInputStream()) {
|
||||
String body = IOUtils.toString(is);
|
||||
noticeParams.setAttr(new MapGen<String, Object>(WxConst.RESP_BODY, body).getAttr());
|
||||
noticeParams.setBody(JSON.parseObject(body));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("获取回调参数异常", e);
|
||||
}
|
||||
return super.getNoticeParams(request);
|
||||
return noticeParams;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,7 +375,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
|
||||
*/
|
||||
@Override
|
||||
public PayOutMessage getPayOutMessage(String code, String message) {
|
||||
return PayOutMessage.XML().code(code.toUpperCase()).content(message).build();
|
||||
return PayOutMessage.JSON().content("code", code).content("message", message).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +388,7 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
|
||||
*/
|
||||
@Override
|
||||
public PayOutMessage successPayOutMessage(PayMessage payMessage) {
|
||||
return PayOutMessage.XML().code("SUCCESS").content("成功").build();
|
||||
return getPayOutMessage("SUCCESS", "成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -73,6 +73,18 @@ public enum WxTransactionType implements TransactionType {
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* H5支付
|
||||
* 兼容 后期会抛弃
|
||||
*/
|
||||
@Deprecated
|
||||
MWEB("pay{partner}/transactions/h5", MethodType.POST, true) {
|
||||
@Override
|
||||
public void setAttribute(Map<String, Object> parameters, PayOrder order) {
|
||||
H5.setAttribute(parameters, order);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,9 +3,12 @@ package com.egzosn.pay.wx.v3.bean.order;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 支付场景信息描述
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2021/8/1
|
||||
* </pre>
|
||||
*/
|
||||
public class SceneInfo {
|
||||
|
||||
@@ -15,7 +18,7 @@ public class SceneInfo {
|
||||
@JSONField(name = "payer_client_ip")
|
||||
private String payerClientIp;
|
||||
/**
|
||||
* 商户端设备号
|
||||
* 商户端设备号(门店号或收银设备ID)。
|
||||
*/
|
||||
@JSONField(name = "device_id")
|
||||
private String deviceId;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 通知资源数据
|
||||
* json格式,见示例
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egan@egzosn.com
|
||||
* date 2021/10/4
|
||||
* </pre>
|
||||
*/
|
||||
public class Resource {
|
||||
|
||||
|
||||
/**
|
||||
* 对开启结果数据进行加密的加密算法,目前只支持AEAD_AES_256_GCM。
|
||||
*/
|
||||
private String algorithm;
|
||||
/**
|
||||
* Base64编码后的开启/停用结果数据密文。
|
||||
*/
|
||||
private String ciphertext;
|
||||
/**
|
||||
* 附加数据。
|
||||
*/
|
||||
@JSONField(name = "associated_data")
|
||||
private String associatedData;
|
||||
|
||||
/**
|
||||
* 原始回调类型。
|
||||
*/
|
||||
@JSONField(name = "original_type")
|
||||
private String originalType;
|
||||
/**
|
||||
* 加密使用的随机串。
|
||||
*/
|
||||
private String nonce;
|
||||
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public void setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public String getCiphertext() {
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
public void setCiphertext(String ciphertext) {
|
||||
this.ciphertext = ciphertext;
|
||||
}
|
||||
|
||||
public String getAssociatedData() {
|
||||
return associatedData;
|
||||
}
|
||||
|
||||
public void setAssociatedData(String associatedData) {
|
||||
this.associatedData = associatedData;
|
||||
}
|
||||
|
||||
public String getOriginalType() {
|
||||
return originalType;
|
||||
}
|
||||
|
||||
public void setOriginalType(String originalType) {
|
||||
this.originalType = originalType;
|
||||
}
|
||||
|
||||
public String getNonce() {
|
||||
return nonce;
|
||||
}
|
||||
|
||||
public void setNonce(String nonce) {
|
||||
this.nonce = nonce;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.egzosn.pay.common.bean.NoticeParams;
|
||||
|
||||
/**
|
||||
* 微信通知参数
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egzosn@gmail.com
|
||||
* date 2021/10/4
|
||||
*</pre>
|
||||
*/
|
||||
public class WxNoticeParams extends NoticeParams {
|
||||
|
||||
|
||||
/**
|
||||
* 通知的唯一ID
|
||||
* 示例值:EV-2018022511223320873
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
*通知创建的时间,遵循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
|
||||
*/
|
||||
@JSONField(name = "create_time")
|
||||
private String createTime;
|
||||
/**
|
||||
* 通知的类型:
|
||||
* TRANSACTION.SUCCESS 支付成功通知
|
||||
* REFUND.SUCCESS:退款成功通知
|
||||
* REFUND.ABNORMAL:退款异常通知
|
||||
* REFUND.CLOSED:退款关闭通知
|
||||
* 示例值:REFUND.SUCCESS
|
||||
*/
|
||||
@JSONField(name = "event_type")
|
||||
private String eventType;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 通知的资源数据类型,支付成功通知为encrypt-resource
|
||||
* 示例值:encrypt-resource
|
||||
*/
|
||||
@JSONField(name = "resource_type")
|
||||
private String resourceType;
|
||||
|
||||
/**
|
||||
* 通知资源数据
|
||||
* json格式,见示例
|
||||
*/
|
||||
private Resource resource;
|
||||
/**
|
||||
* 通知简要说明
|
||||
* 示例值:退款成功
|
||||
* 示例值:支付成功
|
||||
*/
|
||||
private String summary;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(String createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getEventType() {
|
||||
return eventType;
|
||||
}
|
||||
|
||||
public void setEventType(String eventType) {
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
public String getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
public void setSummary(String summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public void setResourceType(String resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.egzosn.pay.common.bean.PayMessage;
|
||||
import com.egzosn.pay.wx.v3.bean.WxTransactionType;
|
||||
import com.egzosn.pay.wx.v3.bean.order.SceneInfo;
|
||||
import com.egzosn.pay.wx.v3.bean.response.order.Amount;
|
||||
import com.egzosn.pay.wx.v3.bean.response.order.Payer;
|
||||
import com.egzosn.pay.wx.v3.bean.response.order.PromotionDetail;
|
||||
import com.egzosn.pay.wx.v3.bean.response.order.TradeState;
|
||||
|
||||
/**
|
||||
* 支付回调消息
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egan@egzosn.com
|
||||
* date 2021/10/4
|
||||
* </pre>
|
||||
*/
|
||||
public class WxPayMessage extends PayMessage {
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 直连模式应用ID,服务商模式请解析spAppid
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 直连模式商户号,服务商模式请解析spMchid
|
||||
*/
|
||||
private String mchid;
|
||||
/**
|
||||
* 服务商模式服务商APPID
|
||||
*/
|
||||
@JSONField(name = "sp_appid")
|
||||
private String spAppid;
|
||||
/**
|
||||
* 服务商模式服务商户号
|
||||
*/
|
||||
@JSONField(name = "sp_mchid")
|
||||
private String spMchid;
|
||||
/**
|
||||
* 服务商模式-子商户appid
|
||||
*/
|
||||
@JSONField(name = "sub_appid")
|
||||
private String subAppid;
|
||||
/**
|
||||
* 服务商模式-子商户商户id
|
||||
*/
|
||||
@JSONField(name = "sub_mchid")
|
||||
private String subMchid;
|
||||
|
||||
/**
|
||||
* 商户订单号
|
||||
* 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一。
|
||||
* 示例值:1217752501201407033233368018
|
||||
*/
|
||||
@JSONField(name = "out_trade_no")
|
||||
private String outTradeNo;
|
||||
|
||||
/**
|
||||
* 微信支付订单号
|
||||
* 微信支付系统生成的订单号。
|
||||
* 示例值:1217752501201407033233368018
|
||||
*/
|
||||
@JSONField(name = "transaction_id")
|
||||
private String transactionId;
|
||||
|
||||
/**
|
||||
* 交易类型,枚举值:
|
||||
* JSAPI:公众号支付
|
||||
* NATIVE:扫码支付
|
||||
* APP:APP支付
|
||||
* MICROPAY:付款码支付
|
||||
* MWEB:H5支付
|
||||
* FACEPAY:刷脸支付
|
||||
* 示例值:MICROPAY
|
||||
*/
|
||||
@JSONField(name = "trade_type")
|
||||
private WxTransactionType tradeType;
|
||||
|
||||
|
||||
/**
|
||||
* 交易状态,枚举值:
|
||||
* SUCCESS:支付成功
|
||||
* REFUND:转入退款
|
||||
* NOTPAY:未支付
|
||||
* CLOSED:已关闭
|
||||
* REVOKED:已撤销(付款码支付)
|
||||
* USERPAYING:用户支付中(付款码支付)
|
||||
* PAYERROR:支付失败(其他原因,如银行返回失败)
|
||||
*/
|
||||
@JSONField(name = "trade_state")
|
||||
private TradeState tradeState;
|
||||
|
||||
|
||||
/**
|
||||
* 交易状态描述
|
||||
* 示例值:支付成功
|
||||
*/
|
||||
@JSONField(name = "trade_state_desc")
|
||||
private String tradeStateDesc;
|
||||
/**
|
||||
* 银行类型,采用字符串类型的银行标识。
|
||||
* 银行标识请参考 <a target= "_blank" href= "https://pay.weixin.qq.com/wiki/doc/apiv3/terms_definition/chapter1_1_3.shtml#part-6">《银行类型对照表》</a>
|
||||
* 示例值:CMC
|
||||
*/
|
||||
@JSONField(name = "bank_type")
|
||||
private String bankType;
|
||||
|
||||
/**
|
||||
* 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
|
||||
*/
|
||||
private String attach;
|
||||
|
||||
/**
|
||||
* 支付完成时间,遵循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
|
||||
*/
|
||||
@JSONField(name = "success_time", format = "yyyy-MM-dd'T'HH:mm:ssXXX")
|
||||
private Date successTime;
|
||||
/**
|
||||
* 支付者信息
|
||||
*/
|
||||
private Payer payer;
|
||||
|
||||
|
||||
/**
|
||||
* 订单金额
|
||||
*/
|
||||
private Amount amount;
|
||||
/**
|
||||
* 支付场景信息描述
|
||||
*/
|
||||
@JSONField(name = "scene_info")
|
||||
private SceneInfo sceneInfo;
|
||||
|
||||
/**
|
||||
* 优惠功能,享受优惠时返回该字段。
|
||||
*/
|
||||
@JSONField(name = "promotion_detail")
|
||||
private List<PromotionDetail> promotionDetail;
|
||||
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getMchid() {
|
||||
return mchid;
|
||||
}
|
||||
|
||||
public void setMchid(String mchid) {
|
||||
this.mchid = mchid;
|
||||
}
|
||||
|
||||
public String getSpAppid() {
|
||||
return spAppid;
|
||||
}
|
||||
|
||||
public void setSpAppid(String spAppid) {
|
||||
this.spAppid = spAppid;
|
||||
}
|
||||
|
||||
public String getSpMchid() {
|
||||
return spMchid;
|
||||
}
|
||||
|
||||
public void setSpMchid(String spMchid) {
|
||||
this.spMchid = spMchid;
|
||||
}
|
||||
|
||||
public String getSubAppid() {
|
||||
return subAppid;
|
||||
}
|
||||
|
||||
public void setSubAppid(String subAppid) {
|
||||
this.subAppid = subAppid;
|
||||
}
|
||||
|
||||
public String getSubMchid() {
|
||||
return subMchid;
|
||||
}
|
||||
|
||||
public void setSubMchid(String subMchid) {
|
||||
this.subMchid = subMchid;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public void setOutTradeNo(String outTradeNo) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public WxTransactionType getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
public void setTradeType(WxTransactionType tradeType) {
|
||||
this.tradeType = tradeType;
|
||||
}
|
||||
|
||||
public TradeState getTradeState() {
|
||||
return tradeState;
|
||||
}
|
||||
|
||||
public void setTradeState(TradeState tradeState) {
|
||||
this.tradeState = tradeState;
|
||||
}
|
||||
|
||||
public String getTradeStateDesc() {
|
||||
return tradeStateDesc;
|
||||
}
|
||||
|
||||
public void setTradeStateDesc(String tradeStateDesc) {
|
||||
this.tradeStateDesc = tradeStateDesc;
|
||||
}
|
||||
|
||||
public String getBankType() {
|
||||
return bankType;
|
||||
}
|
||||
|
||||
public void setBankType(String bankType) {
|
||||
this.bankType = bankType;
|
||||
}
|
||||
|
||||
public String getAttach() {
|
||||
return attach;
|
||||
}
|
||||
|
||||
public void setAttach(String attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
public Date getSuccessTime() {
|
||||
return successTime;
|
||||
}
|
||||
|
||||
public void setSuccessTime(Date successTime) {
|
||||
this.successTime = successTime;
|
||||
}
|
||||
|
||||
public Payer getPayer() {
|
||||
return payer;
|
||||
}
|
||||
|
||||
public void setPayer(Payer payer) {
|
||||
this.payer = payer;
|
||||
}
|
||||
|
||||
public Amount getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Amount amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public SceneInfo getSceneInfo() {
|
||||
return sceneInfo;
|
||||
}
|
||||
|
||||
public void setSceneInfo(SceneInfo sceneInfo) {
|
||||
this.sceneInfo = sceneInfo;
|
||||
}
|
||||
|
||||
public List<PromotionDetail> getPromotionDetail() {
|
||||
return promotionDetail;
|
||||
}
|
||||
|
||||
public void setPromotionDetail(List<PromotionDetail> promotionDetail) {
|
||||
this.promotionDetail = promotionDetail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getTotalFee() {
|
||||
return BigDecimal.valueOf(getAmount().getTotal());
|
||||
}
|
||||
|
||||
|
||||
public static final WxPayMessage create(Map<String, Object> message) {
|
||||
WxPayMessage payMessage = new JSONObject(message).toJavaObject(WxPayMessage.class);
|
||||
// payMessage.setPayType("");
|
||||
payMessage.setPayMessage(message);
|
||||
return payMessage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response.order;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 回调中的订单金额信息
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egan@egzosn.com
|
||||
* date 2021/10/4
|
||||
* </pre>
|
||||
*/
|
||||
public class Amount extends com.egzosn.pay.wx.v3.bean.order.Amount{
|
||||
|
||||
/**
|
||||
* 用户支付金额,单位为分。
|
||||
*/
|
||||
private BigDecimal payerTotal;
|
||||
/**
|
||||
* 用户支付币种
|
||||
*/
|
||||
private String payerCurrency;
|
||||
|
||||
public BigDecimal getPayerTotal() {
|
||||
return payerTotal;
|
||||
}
|
||||
|
||||
public void setPayerTotal(BigDecimal payerTotal) {
|
||||
this.payerTotal = payerTotal;
|
||||
}
|
||||
|
||||
public String getPayerCurrency() {
|
||||
return payerCurrency;
|
||||
}
|
||||
|
||||
public void setPayerCurrency(String payerCurrency) {
|
||||
this.payerCurrency = payerCurrency;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response.order;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 单品列表信息
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egan@egzosn.com
|
||||
* date 2021/10/4
|
||||
* </pre>
|
||||
*/
|
||||
public class GoodsDetail {
|
||||
|
||||
/**
|
||||
* 商品编码
|
||||
*/
|
||||
@JSONField(name = "goods_id")
|
||||
private String goodsId;
|
||||
/**
|
||||
* 商品数量
|
||||
*/
|
||||
@JSONField(name = "quantity")
|
||||
private Long quantity;
|
||||
/**
|
||||
* 商品单价
|
||||
*/
|
||||
@JSONField(name = "unit_price")
|
||||
private Long unitPrice;
|
||||
/**
|
||||
* 商品优惠金额,单位【分】
|
||||
*/
|
||||
@JSONField(name = "discount_amount")
|
||||
private Long discountAmount;
|
||||
/**
|
||||
* 商品备注
|
||||
*/
|
||||
@JSONField(name = "goods_remark")
|
||||
private String goodsRemark;
|
||||
|
||||
|
||||
public String getGoodsId() {
|
||||
return goodsId;
|
||||
}
|
||||
|
||||
public void setGoodsId(String goodsId) {
|
||||
this.goodsId = goodsId;
|
||||
}
|
||||
|
||||
public Long getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(Long quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public Long getUnitPrice() {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
public void setUnitPrice(Long unitPrice) {
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
public Long getDiscountAmount() {
|
||||
return discountAmount;
|
||||
}
|
||||
|
||||
public void setDiscountAmount(Long discountAmount) {
|
||||
this.discountAmount = discountAmount;
|
||||
}
|
||||
|
||||
public String getGoodsRemark() {
|
||||
return goodsRemark;
|
||||
}
|
||||
|
||||
public void setGoodsRemark(String goodsRemark) {
|
||||
this.goodsRemark = goodsRemark;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response.order;
|
||||
|
||||
/**
|
||||
* 支付者信息
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egan@egzosn.com
|
||||
* date 2021/10/4
|
||||
* </pre>
|
||||
*/
|
||||
public class Payer {
|
||||
/**
|
||||
* 用户在直连商户appid下的唯一标识。
|
||||
*/
|
||||
private String openid;
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response.order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 优惠功能
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
|
||||
public class PromotionDetail {
|
||||
/**
|
||||
* 券ID
|
||||
*/
|
||||
@JSONField(name = "coupon_id")
|
||||
private String couponId;
|
||||
|
||||
/**
|
||||
* 优惠名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 优惠范围
|
||||
* <ul>
|
||||
* <li> GLOBAL:全场代金券</li>
|
||||
* <li>SINGLE:单品优惠</li>
|
||||
* </ul>
|
||||
* 示例值:GLOBAL
|
||||
*/
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* 优惠类型
|
||||
* <ul>
|
||||
* <li>CASH:充值</li>
|
||||
* <li>NOCASH:预充值</li>
|
||||
* </ul>
|
||||
* 示例值:CASH
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 优惠券面额,单位【分】
|
||||
*/
|
||||
private Long amount;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
@JSONField(name = "stock_id")
|
||||
private String stockId;
|
||||
|
||||
/**
|
||||
* 微信出资,单位为分
|
||||
*/
|
||||
@JSONField(name = "wechatpay_contribute")
|
||||
private Long wechatpayContribute;
|
||||
|
||||
/**
|
||||
* 商户出资,单位为分
|
||||
*/
|
||||
@JSONField(name = "merchant_contribute")
|
||||
private Long merchantContribute;
|
||||
|
||||
/**
|
||||
* 其他出资,单位为分
|
||||
*/
|
||||
@JSONField(name = "other_contribute")
|
||||
private Long otherContribute;
|
||||
|
||||
/**
|
||||
* 优惠币种,
|
||||
* CNY:人民币,境内商户号仅支持人民币。
|
||||
* 示例值:CNY
|
||||
*/
|
||||
private String currency;
|
||||
/**
|
||||
* 单品列表信息
|
||||
*/
|
||||
@JSONField(name = "goods_detail")
|
||||
private List<GoodsDetail> goodsDetail;
|
||||
|
||||
|
||||
public String getCouponId() {
|
||||
return couponId;
|
||||
}
|
||||
|
||||
public void setCouponId(String couponId) {
|
||||
this.couponId = couponId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getStockId() {
|
||||
return stockId;
|
||||
}
|
||||
|
||||
public void setStockId(String stockId) {
|
||||
this.stockId = stockId;
|
||||
}
|
||||
|
||||
public Long getWechatpayContribute() {
|
||||
return wechatpayContribute;
|
||||
}
|
||||
|
||||
public void setWechatpayContribute(Long wechatpayContribute) {
|
||||
this.wechatpayContribute = wechatpayContribute;
|
||||
}
|
||||
|
||||
public Long getMerchantContribute() {
|
||||
return merchantContribute;
|
||||
}
|
||||
|
||||
public void setMerchantContribute(Long merchantContribute) {
|
||||
this.merchantContribute = merchantContribute;
|
||||
}
|
||||
|
||||
public Long getOtherContribute() {
|
||||
return otherContribute;
|
||||
}
|
||||
|
||||
public void setOtherContribute(Long otherContribute) {
|
||||
this.otherContribute = otherContribute;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void setCurrency(String currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public List<GoodsDetail> getGoodsDetail() {
|
||||
return goodsDetail;
|
||||
}
|
||||
|
||||
public void setGoodsDetail(List<GoodsDetail> goodsDetail) {
|
||||
this.goodsDetail = goodsDetail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.egzosn.pay.wx.v3.bean.response.order;
|
||||
|
||||
/**
|
||||
* 微信侧返回交易状态
|
||||
* @author Egan
|
||||
* <pre>
|
||||
* email egan@egzosn.com
|
||||
* date 2021/10/4
|
||||
* </pre>
|
||||
*/
|
||||
public enum TradeState {
|
||||
/**
|
||||
* 支付成功
|
||||
*
|
||||
*
|
||||
*/
|
||||
SUCCESS,
|
||||
/**
|
||||
* 转入退款
|
||||
*
|
||||
*
|
||||
*/
|
||||
REFUND,
|
||||
/**
|
||||
* 未支付
|
||||
*
|
||||
*
|
||||
*/
|
||||
NOTPAY,
|
||||
/**
|
||||
* 已关闭
|
||||
*
|
||||
*
|
||||
*/
|
||||
CLOSED,
|
||||
/**
|
||||
* 已撤销(付款码支付)
|
||||
*
|
||||
*/
|
||||
REVOKED,
|
||||
/**
|
||||
* 用户支付中(付款码支付)
|
||||
*/
|
||||
USERPAYING,
|
||||
/**
|
||||
* 支付失败(其他原因,如银行返回失败)
|
||||
*/
|
||||
PAYERROR,
|
||||
/**
|
||||
* 已接收,等待扣款
|
||||
*
|
||||
*/
|
||||
ACCEPT,
|
||||
}
|
||||
Reference in New Issue
Block a user