Skip to content

Commit 6885cac

Browse files
committed
微信V3实现合单支付
1 parent d409619 commit 6885cac

15 files changed

Lines changed: 902 additions & 63 deletions
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package com.egzosn.pay.wx.v3.api;
2+
3+
import java.util.LinkedHashMap;
4+
import java.util.Map;
5+
6+
import com.alibaba.fastjson.JSON;
7+
import com.alibaba.fastjson.JSONObject;
8+
import com.alibaba.fastjson.serializer.SerializerFeature;
9+
import com.egzosn.pay.common.bean.CloseOrder;
10+
import com.egzosn.pay.common.bean.Order;
11+
import com.egzosn.pay.common.bean.OrderParaStructure;
12+
import com.egzosn.pay.common.bean.PayMessage;
13+
import com.egzosn.pay.common.bean.PayOrder;
14+
import com.egzosn.pay.common.bean.result.PayException;
15+
import com.egzosn.pay.common.exception.PayErrorException;
16+
import com.egzosn.pay.common.http.HttpConfigStorage;
17+
import com.egzosn.pay.common.util.DateUtils;
18+
import com.egzosn.pay.common.util.MapGen;
19+
import com.egzosn.pay.common.util.str.StringUtils;
20+
import com.egzosn.pay.wx.v3.bean.WxTransactionType;
21+
import com.egzosn.pay.wx.v3.bean.combine.CombinePayMessage;
22+
import com.egzosn.pay.wx.v3.utils.WxConst;
23+
24+
/**
25+
* 微信合单支付服务
26+
*
27+
* @author egan
28+
* <pre>
29+
* email egzosn@gmail.com
30+
* date 2016-5-18 14:09:01
31+
* </pre>
32+
*/
33+
public class WxCombinePayService extends WxPayService {
34+
35+
/**
36+
* 创建支付服务
37+
*
38+
* @param payConfigStorage 微信对应的支付配置
39+
*/
40+
public WxCombinePayService(WxPayConfigStorage payConfigStorage) {
41+
super(payConfigStorage);
42+
}
43+
44+
/**
45+
* 创建支付服务
46+
*
47+
* @param payConfigStorage 微信对应的支付配置
48+
* @param configStorage 微信对应的网络配置,包含代理配置、ssl证书配置
49+
*/
50+
public WxCombinePayService(WxPayConfigStorage payConfigStorage, HttpConfigStorage configStorage) {
51+
super(payConfigStorage, configStorage);
52+
}
53+
54+
55+
/**
56+
* 获取公共参数
57+
*
58+
* @return 公共参数
59+
*/
60+
public Map<String, Object> getPublicParameters() {
61+
Map<String, Object> parameters = new LinkedHashMap<>();
62+
parameters.put(WxConst.COMBINE_APPID, payConfigStorage.getAppId());
63+
parameters.put(WxConst.COMBINE_MCH_ID, payConfigStorage.getMchId());
64+
return parameters;
65+
}
66+
67+
/**
68+
* 初始化通知URL必须为直接可访问的URL,不允许携带查询串,要求必须为https地址。
69+
*
70+
* @param parameters 订单参数
71+
* @param order 订单信息
72+
* @return 订单参数
73+
*/
74+
public void initNotifyUrl(Map<String, Object> parameters, Order order) {
75+
OrderParaStructure.loadParameters(parameters, WxConst.NOTIFY_URL, payConfigStorage.getNotifyUrl());
76+
OrderParaStructure.loadParameters(parameters, WxConst.NOTIFY_URL, order);
77+
}
78+
79+
/**
80+
* 微信统一下单接口
81+
*
82+
* @param order 支付订单集
83+
* @return 下单结果
84+
*/
85+
public JSONObject unifiedOrder(PayOrder order) {
86+
87+
//统一下单
88+
Map<String, Object> parameters = getPublicParameters();
89+
90+
// 订单号
91+
parameters.put(WxConst.COMBINE_OUT_TRADE_NO, order.getOutTradeNo());
92+
93+
OrderParaStructure.loadDateParameters(parameters, WxConst.TIME_START, order, DateUtils.YYYY_MM_DD_T_HH_MM_SS);
94+
OrderParaStructure.loadDateParameters(parameters, WxConst.TIME_EXPIRE, order, DateUtils.YYYY_MM_DD_T_HH_MM_SS);
95+
initNotifyUrl(parameters, order);
96+
//支付场景描述
97+
OrderParaStructure.loadParameters(parameters, WxConst.SCENE_INFO, order);
98+
//子单信息 最多支持子单条数:50
99+
OrderParaStructure.loadParameters(parameters, WxConst.SUB_ORDERS, order);
100+
//支付者信息
101+
if (StringUtils.isNotEmpty(order.getOpenid())) {
102+
parameters.put("combine_payer_info", new MapGen<>("openid", order.getOpenid()).getAttr());
103+
}
104+
105+
return getAssistService().doExecute(parameters, order);
106+
}
107+
108+
109+
/**
110+
* 交易查询接口
111+
*
112+
* @param transactionId 微信支付平台订单号
113+
* @param outTradeNo 商户单号
114+
* @return 返回查询回来的结果集,支付方原值返回
115+
*/
116+
@Override
117+
public Map<String, Object> query(String transactionId, String outTradeNo) {
118+
return getAssistService().doExecute("", WxTransactionType.COMBINE_TRANSACTION, outTradeNo);
119+
}
120+
121+
122+
/**
123+
* 交易关闭接口
124+
*
125+
* @param transactionId 支付平台订单号
126+
* @param outTradeNo 商户单号
127+
* @return 返回支付方交易关闭后的结果
128+
*/
129+
@Override
130+
public Map<String, Object> close(String transactionId, String outTradeNo) {
131+
throw new PayErrorException(new PayException("failure", "合单关闭必须要有子单"));
132+
}
133+
134+
/**
135+
* 交易关闭接口
136+
*
137+
* @param closeOrder 关闭订单
138+
* @return 返回支付方交易关闭后的结果
139+
*/
140+
@Override
141+
public Map<String, Object> close(CloseOrder closeOrder) {
142+
Map<String, Object> parameters = new MapGen<String, Object>(WxConst.COMBINE_APPID, payConfigStorage.getAppId())
143+
.keyValue(WxConst.SUB_ORDERS, closeOrder.getAttr(WxConst.SUB_ORDERS))
144+
.getAttr();
145+
String requestBody = JSON.toJSONString(parameters, SerializerFeature.WriteMapNullValue);
146+
return getAssistService().doExecute(requestBody, WxTransactionType.COMBINE_CLOSE, closeOrder.getOutTradeNo());
147+
}
148+
149+
/**
150+
* 创建消息
151+
*
152+
* @param message 支付平台返回的消息
153+
* @return 支付消息对象
154+
*/
155+
@Override
156+
public PayMessage createMessage(Map<String, Object> message) {
157+
return CombinePayMessage.create(message);
158+
}
159+
}

pay-java-wx/src/main/java/com/egzosn/pay/wx/v3/api/WxPayService.java

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.alibaba.fastjson.JSONObject;
2323
import com.egzosn.pay.common.api.BasePayService;
2424
import com.egzosn.pay.common.bean.BillType;
25+
import com.egzosn.pay.common.bean.CloseOrder;
2526
import com.egzosn.pay.common.bean.CurType;
2627
import com.egzosn.pay.common.bean.MethodType;
2728
import com.egzosn.pay.common.bean.NoticeParams;
@@ -81,27 +82,13 @@ public class WxPayService extends BasePayService<WxPayConfigStorage> {
8182
/**
8283
* 辅助api
8384
*/
84-
private volatile WxPayAssistService wxPayAssistService;
85+
private volatile WxPayAssistService assistService;
8586

8687
/**
8788
* 微信参数构造器
8889
*/
8990
private volatile WxParameterStructure wxParameterStructure;
9091

91-
92-
public WxPayAssistService getAssistService() {
93-
if (null == wxPayAssistService) {
94-
wxPayAssistService = new DefaultWxPayAssistService(this);
95-
//在这预先进行初始化
96-
wxPayAssistService.refreshCertificate();
97-
}
98-
return wxPayAssistService;
99-
}
100-
101-
public void setAssistService(WxPayAssistService wxPayAssistService) {
102-
this.wxPayAssistService = wxPayAssistService;
103-
}
104-
10592
/**
10693
* 创建支付服务
10794
*
@@ -123,25 +110,23 @@ public WxPayService(WxPayConfigStorage payConfigStorage, HttpConfigStorage confi
123110

124111

125112
/**
126-
* 初始化之后执行
113+
* 辅助api
114+
* @return 辅助api
127115
*/
128-
@Override
129-
protected void initAfter() {
130-
new Thread(() -> {
131-
payConfigStorage.loadCertEnvironment();
132-
wxParameterStructure = new WxParameterStructure(payConfigStorage);
116+
public WxPayAssistService getAssistService() {
117+
if (null == assistService) {
118+
assistService = new DefaultWxPayAssistService(this);
133119
//在这预先进行初始化
134-
try {
135-
Thread.sleep(10);
136-
}
137-
catch (InterruptedException e) {
120+
assistService.refreshCertificate();
121+
}
122+
return assistService;
123+
}
138124

139-
}
140-
getAssistService();
141-
}).start();
125+
public void setAssistService(WxPayAssistService assistService) {
126+
this.assistService = assistService;
127+
}
142128

143129

144-
}
145130

146131
/**
147132
* 设置api服务器地址
@@ -154,6 +139,14 @@ public WxPayService setApiServerUrl(String apiServerUrl) {
154139
return this;
155140
}
156141

142+
public String getApiServerUrl() {
143+
return apiServerUrl;
144+
}
145+
146+
public WxParameterStructure getWxParameterStructure() {
147+
return wxParameterStructure;
148+
}
149+
157150
/**
158151
* 根据交易类型获取url
159152
*
@@ -323,6 +316,7 @@ public String createSign(String content, String characterEncoding) {
323316
* @param is 请求流
324317
* @return 获得回调的请求参数
325318
*/
319+
@Deprecated
326320
@Override
327321
public Map<String, Object> getParameter2Map(Map<String, String[]> parameterMap, InputStream is) {
328322
throw new PayErrorException(new WxPayError(FAILURE, "微信V3不支持方式"));
@@ -350,7 +344,7 @@ public NoticeParams getNoticeParams(NoticeRequest request) {
350344
noticeParams.setBody(JSON.parseObject(data));
351345
}
352346
catch (IOException e) {
353-
LOG.error("获取回调参数异常", e);
347+
throw new PayErrorException(new WxPayError(FAILURE, "获取回调参数异常"), e);
354348
}
355349
Map<String, List<String>> headers = new HashMap<>();
356350
Enumeration<String> headerNames = request.getHeaderNames();
@@ -457,8 +451,20 @@ public Map<String, Object> query(String transactionId, String outTradeNo) {
457451
*/
458452
@Override
459453
public Map<String, Object> close(String transactionId, String outTradeNo) {
454+
return close(new CloseOrder(outTradeNo));
455+
}
456+
457+
458+
/**
459+
* 交易关闭接口
460+
*
461+
* @param closeOrder 关闭订单
462+
* @return 返回支付方交易关闭后的结果
463+
*/
464+
@Override
465+
public Map<String, Object> close(CloseOrder closeOrder) {
460466
String parameters = wxParameterStructure.getSpParameters();
461-
return getAssistService().doExecute(parameters, WxTransactionType.CLOSE, outTradeNo);
467+
return getAssistService().doExecute(parameters, WxTransactionType.CLOSE, closeOrder.getOutTradeNo());
462468
}
463469

464470
/**

0 commit comments

Comments
 (0)