package com.walker.pay.wechat;
|
|
import com.walker.infrastructure.arguments.Variable;
|
import com.walker.infrastructure.utils.KeyValue;
|
import com.walker.infrastructure.utils.MD5;
|
import com.walker.infrastructure.utils.StringUtils;
|
import com.walker.pay.Order;
|
import com.walker.pay.OrderGenerator;
|
import com.walker.pay.OrderStatusQuery;
|
import com.walker.pay.PayChannel;
|
import com.walker.pay.PayContext;
|
import com.walker.pay.PayStatus;
|
import com.walker.pay.PayType;
|
import com.walker.pay.ServiceProvider;
|
import com.walker.pay.response.OrderStatusResponsePay;
|
import com.walker.pay.support.SimplePayEngineProvider;
|
import com.walker.pay.wechat.v2.AppOrderGenerator;
|
import com.walker.pay.wechat.v2.H5OrderGenerator;
|
import com.walker.pay.wechat.v2.RoutineOrderGenerator;
|
import com.walker.pay.wechat.v2.ScanOrderGenerator;
|
import com.walker.pay.wechat.v2.SignUtils;
|
import com.walker.pay.wechat.v2.WechatV2PayContext;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.web.client.RestTemplate;
|
|
import java.util.HashMap;
|
import java.util.LinkedList;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* 微信V2版本支付对接引擎实现。
|
* @author 时克英
|
* @date 2023-01-16
|
*/
|
public class WechatV2PayEngineProvider extends SimplePayEngineProvider {
|
|
private Map<String, OrderGenerator> orderGeneratorMap = new HashMap<>(8);
|
|
public WechatV2PayEngineProvider(RestTemplate restTemplate){
|
if(restTemplate == null){
|
throw new IllegalArgumentException("RestTemplate is required!");
|
}
|
this.restTemplate = restTemplate;
|
this.init();
|
}
|
|
private void init(){
|
this.setServiceProvider(ServiceProvider.Wechat);
|
this.setVersion("v2");
|
this.setPayChannel(PayChannel.ProviderDirect);
|
|
ScanOrderGenerator scanOrderGenerator = new ScanOrderGenerator(this.restTemplate);
|
AppOrderGenerator appOrderGenerator = new AppOrderGenerator(this.restTemplate);
|
H5OrderGenerator h5OrderGenerator = new H5OrderGenerator(this.restTemplate);
|
|
this.orderGeneratorMap.put(Constants.PAY_TYPE_NATIVE, scanOrderGenerator);
|
this.orderGeneratorMap.put(Constants.PAY_TYPE_APP, appOrderGenerator);
|
this.orderGeneratorMap.put(Constants.PAY_TYPE_H5, h5OrderGenerator);
|
|
// 2023-09-15
|
RoutineOrderGenerator routineOrderGenerator = new RoutineOrderGenerator(this.restTemplate);
|
this.orderGeneratorMap.put(Constants.PAY_TYPE_ROUTINE, routineOrderGenerator);
|
}
|
|
@Override
|
protected String acquireProviderPayType(ServiceProvider serviceProvider, PayType payType, PayChannel payChannel) {
|
if(payType == PayType.Scan){
|
return Constants.PAY_TYPE_NATIVE;
|
} else if (payType == PayType.App){
|
return Constants.PAY_TYPE_APP;
|
} else if (payType == PayType.H5) {
|
return Constants.PAY_TYPE_H5;
|
} else if (payType == PayType.Applet){
|
return Constants.PAY_TYPE_ROUTINE;
|
}else {
|
throw new UnsupportedOperationException("代码未实现第三方支付类型转换");
|
}
|
}
|
|
@Override
|
protected OrderGenerator acquireOrderGenerator(String providerPayType, Order platformOrder, Map<String, Variable> configuration) {
|
return this.orderGeneratorMap.get(providerPayType);
|
}
|
|
@Override
|
protected boolean verifySign(Object notifyData) throws Exception {
|
// 暂时不验真签名
|
return true;
|
}
|
|
/*@Override
|
protected void savePrepareOrder(Order platformOrder, ResponsePay responsePay) {
|
if(this.logger.isDebugEnabled()){
|
logger.debug("保存订单:{}", platformOrder);
|
}
|
this.checkOrderCallback();
|
this.getOrderCallback().onOrderPrepare(platformOrder, responsePay);
|
}
|
|
@Override
|
protected void onNotifyOrder(NotifyValue<?> notifyValue) throws Exception {
|
this.checkOrderCallback();
|
try {
|
this.getOrderCallback().onOrderNotify(notifyValue);
|
} catch (CallBackException e) {
|
logger.error("订单支付通知回调错误:{}", notifyValue);
|
throw new CallBackException("", e);
|
}
|
}
|
|
private void checkOrderCallback(){
|
if(this.getOrderCallback() == null){
|
throw new IllegalArgumentException("OrderCallback 未配置,无法执行订单操作! payEngineProvider = " + this.getClass().getName());
|
}
|
}*/
|
|
@Override
|
protected PayContext acquirePayContext(String providerPayType, Order platformOrder, Map<String, Variable> configuration) {
|
WechatV2PayContext payContext = new WechatV2PayContext();
|
payContext.setConfigVariable(configuration.get(Constants.CONFIG_KEY_APP_ID));
|
payContext.setConfigVariable(configuration.get(Constants.CONFIG_KEY_MCH_ID));
|
payContext.setConfigVariable(configuration.get(Constants.CONFIG_KEY_API_KEY));
|
// 2023-09-15,添加小程序支付的应用参数
|
payContext.setConfigVariable(configuration.get(Constants.CONFIG_KEY_APP_ID_ROUTINE));
|
payContext.setConfigVariable(configuration.get(Constants.CONFIG_KEY_API_KEY_ROUTINE));
|
payContext.setConfigVariable(configuration.get(Constants.CONFIG_KEY_MCH_ID_ROUTINE));
|
return payContext;
|
}
|
|
@Override
|
protected OrderStatusQuery acquireOrderStatusQuery(Order order) {
|
throw new UnsupportedOperationException("没写代码呢!");
|
}
|
|
@Override
|
protected OrderStatusResponsePay invokeOrderStatus(OrderStatusQuery orderStatusQuery) {
|
List<KeyValue<String, String>> packageParams = new LinkedList<>();
|
packageParams.add(new KeyValue<>("appid", orderStatusQuery.getAppId()));
|
packageParams.add(new KeyValue<>("mch_id", orderStatusQuery.getMerchantId()));
|
packageParams.add(new KeyValue<>("nonce_str", StringUtils.generateRandomNumber(6)));
|
packageParams.add(new KeyValue<>("out_trade_no", orderStatusQuery.getTradeNo()));
|
packageParams.add(new KeyValue<>("sign_type", MD5.MD5_NAME));
|
// Map<String, String> map = new HashMap<>(8);
|
// map.put("appid", orderStatusQuery.getAppId());
|
String sign = SignUtils.getPackageSign(packageParams, orderStatusQuery.getApiKey());
|
packageParams.add(new KeyValue<>("sign", sign));
|
|
String request = SignUtils.toXml(packageParams);
|
ResponseEntity<String> entity = this.restTemplate.postForEntity(Constants.URL_SEARCH_V2, request, String.class);
|
if(entity == null){
|
throw new RuntimeException("调用'微信H5'查询订单返回空数据, trade_no = " + orderStatusQuery.getTradeNo());
|
}
|
Map<String, String> responseMap = SignUtils.decodeXml(entity.getBody());
|
if(responseMap == null){
|
throw new RuntimeException("调用'微信H5'查询订单返回数据转换为空: SignUtils.decodeXml() == null");
|
}
|
if(logger.isDebugEnabled()){
|
logger.debug(responseMap.toString());
|
}
|
|
OrderStatusResponsePay responsePay = new OrderStatusResponsePay();
|
if(responseMap.get("return_code").equals("FAIL")){
|
responsePay.setStatus(false);
|
responsePay.setMessage(responseMap.get("return_msg"));
|
|
} else if(responseMap.get("result_code").equals("FAIL")){
|
responsePay.setStatus(false);
|
responsePay.setMessage(responseMap.get("err_code_des"));
|
logger.error("微信查询订单调用成功,但返回错误结果:" + responseMap.get("err_code"));
|
|
} else {
|
responsePay.setStatus(true);
|
String tradeState = responseMap.get("trade_state");
|
if(tradeState.equals(Constants.TRADE_STATE_CLOSED)){
|
responsePay.setPayStatus(PayStatus.Closed);
|
responsePay.setMessage("已关闭");
|
} else if(tradeState.equals(Constants.TRADE_STATE_USERPAYING)){
|
responsePay.setPayStatus(PayStatus.Paying);
|
responsePay.setMessage("正在支付中");
|
} else if (tradeState.equals(Constants.TRADE_STATE_NOTPAY)){
|
responsePay.setPayStatus(PayStatus.NotPay);
|
responsePay.setMessage("未支付");
|
} else if(tradeState.equals(Constants.TRADE_STATE_REFUND)){
|
responsePay.setPayStatus(PayStatus.Refund);
|
responsePay.setMessage("转入退款");
|
} else if(tradeState.equals(Constants.TRADE_STATE_PAYERROR)){
|
responsePay.setPayStatus(PayStatus.Error);
|
responsePay.setMessage("支付失败");
|
} else if(tradeState.equals(Constants.TRADE_STATE_REVOKED)){
|
responsePay.setPayStatus(PayStatus.Error);
|
responsePay.setMessage("已撤销(刷卡支付) ");
|
} else if(tradeState.equals(Constants.TRADE_STATE_SUCCESS)){
|
responsePay.setPayStatus(PayStatus.Success);
|
responsePay.setUserPayMoney(Long.parseLong(responseMap.get("cash_fee")));
|
responsePay.setTotalMoney(Long.parseLong(responseMap.get("total_fee")));
|
responsePay.setPaySuccessTime(responseMap.get("time_end"));
|
responsePay.setOrderId(responseMap.get("out_trade_no"));
|
responsePay.setTradeNo(responseMap.get("transaction_id"));
|
responsePay.setAppId(orderStatusQuery.getAppId());
|
responsePay.setMerchantId(orderStatusQuery.getMerchantId());
|
responsePay.setProviderPayType(responseMap.get("trade_type"));
|
} else {
|
throw new UnsupportedOperationException("不支持微信返回的支付类型:" + tradeState);
|
}
|
}
|
return responsePay;
|
}
|
|
public void setRestTemplate(RestTemplate restTemplate) {
|
this.restTemplate = restTemplate;
|
}
|
|
private RestTemplate restTemplate;
|
|
@Override
|
public String generateNotifyResponse(boolean success) {
|
if(success){
|
return SignUtils.toXmlNotifyStatus(Constants.CODE_SUCCESS, Constants.CODE_OK);
|
} else {
|
return SignUtils.toXmlNotifyStatus(Constants.CODE_FAIL, Constants.CODE_FAIL);
|
}
|
}
|
}
|