Commit eb533493 authored by jmdhappy's avatar jmdhappy
Browse files

提交dubbo版本

parent ddae755c
spring:
dubbo:
application:
name: xxpay4dubbo-service
registry:
address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20880
scan: org.xxpay.dubbo
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/xxpaydb?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false
username: xxpay
password: xxpay
initialSize: 5 # 初始化大小
minIdle: 5 # 最小
maxActive: 20 # 最大
maxWait: 60000 # 获取连接等待超时的时间
timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true # 打开PSCache
maxPoolPreparedStatementPerConnectionSize: 20 # 指定每个连接上PSCache的大小
filters: stat,wall,log4j # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
profiles:
active: prod
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0)
in-memory: true
logging:
file: ./log/xxpay4dubbo-service.log
config:
ali:
notify_url: http://xxpay.nat100.top/notify/pay/aliPayNotifyRes.htm
return_url: http://www.xxpay.org
wx:
certRootPath: /Users/dingzhiwei/java/tmp/cert
notifyUrl: http://xxpay.nat100.top/notify/pay/wxPayNotifyRes.htm
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.xxpay</groupId>
<artifactId>xxpay4dubbo-web</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>xxpay4dubbo-web</name>
<description>xxpay4dubbo-web</description>
<parent>
<groupId>org.xxpay</groupId>
<artifactId>xxpay4dubbo</artifactId>
<version>1.0.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.xxpay</groupId>
<artifactId>xxpay4dubbo-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.dubbo.springboot</groupId>
<artifactId>spring-boot-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package org.xxpay.dubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
*
*/
@SpringBootApplication
@ComponentScan(basePackages={"org.xxpay"})
public class XxPayDubboWebAppliaction {
public static void main(String[] args) {
SpringApplication.run(XxPayDubboWebAppliaction.class, args);
}
}
package org.xxpay.dubbo.web.ctrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.MyLog;
import org.xxpay.dubbo.web.service.NotifyPayService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @Description: 接收处理支付宝通知
* @author dingzhiwei jmdhappy@126.com
* @date 2017-07-05
* @version V1.0
* @Copyright: www.xxpay.org
*/
@RestController
public class Notify4AliPayController {
private static final MyLog _log = MyLog.getLog(Notify4AliPayController.class);
@Autowired
private NotifyPayService notifyPayService;
/**
* 支付宝移动支付后台通知响应
* @param request
* @return
* @throws ServletException
* @throws IOException
*/
@RequestMapping(value = "/notify/pay/aliPayNotifyRes.htm")
@ResponseBody
public String aliPayNotifyRes(HttpServletRequest request) throws ServletException, IOException {
_log.info("====== 开始接收支付宝支付回调通知 ======");
String notifyRes = doAliPayRes(request);
_log.info("响应给支付宝:{}", notifyRes);
_log.info("====== 完成接收支付宝支付回调通知 ======");
return notifyRes;
}
public String doAliPayRes(HttpServletRequest request) throws ServletException, IOException {
String logPrefix = "【支付宝支付回调通知】";
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
_log.info("{}通知请求数据:reqStr={}", logPrefix, params);
if(params.isEmpty()) {
_log.error("{}请求参数为空", logPrefix);
return PayConstant.RETURN_ALIPAY_VALUE_FAIL;
}
return notifyPayService.doAliPayNotify(params);
}
}
package org.xxpay.dubbo.web.ctrl;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.util.MyLog;
import org.xxpay.dubbo.web.service.NotifyPayService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Description: 接收处理微信通知
* @author dingzhiwei jmdhappy@126.com
* @date 2017-07-05
* @version V1.0
* @Copyright: www.xxpay.org
*/
@RestController
public class Notify4WxPayController {
private static final MyLog _log = MyLog.getLog(Notify4WxPayController.class);
@Autowired
private NotifyPayService notifyPayService;
/**
* 微信支付(统一下单接口)后台通知响应
* @param request
* @return
* @throws ServletException
* @throws IOException
*/
@RequestMapping("/notify/pay/wxPayNotifyRes.htm")
@ResponseBody
public String wxPayNotifyRes(HttpServletRequest request) throws ServletException, IOException {
_log.info("====== 开始接收微信支付回调通知 ======");
String notifyRes = doWxPayRes(request);
_log.info("响应给微信:{}", notifyRes);
_log.info("====== 完成接收微信支付回调通知 ======");
return notifyRes;
}
public String doWxPayRes(HttpServletRequest request) throws ServletException, IOException {
String logPrefix = "【微信支付回调通知】";
String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
_log.info("{}通知请求数据:reqStr={}", logPrefix, xmlResult);
return notifyPayService.doWxPayNotify(xmlResult);
}
}
package org.xxpay.dubbo.web.ctrl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.MyLog;
import org.xxpay.common.util.MySeq;
import org.xxpay.common.util.XXPayUtil;
import org.xxpay.dubbo.web.service.MchInfoService;
import org.xxpay.dubbo.web.service.PayChannelService;
import org.xxpay.dubbo.web.service.PayOrderService;
/**
* @Description: 支付订单,包括:统一下单,订单查询,补单等接口
* @author dingzhiwei jmdhappy@126.com
* @date 2017-07-05
* @version V1.0
* @Copyright: www.xxpay.org
*/
@RestController
public class PayOrderController {
private final MyLog _log = MyLog.getLog(PayOrderController.class);
@Autowired
private PayOrderService payOrderService;
@Autowired
private PayChannelService payChannelService;
@Autowired
private MchInfoService mchInfoService;
/**
* 统一下单接口:
* 1)先验证接口参数以及签名信息
* 2)验证通过创建支付订单
* 3)根据商户选择渠道,调用支付服务进行下单
* 4)返回下单数据
* @param params
* @return
*/
@RequestMapping(value = "/api/pay/create_order")
public String payOrder(@RequestParam String params) {
_log.info("###### 开始接收商户统一下单请求 ######");
String logPrefix = "【商户统一下单】";
try {
JSONObject po = JSONObject.parseObject(params);
JSONObject payContext = new JSONObject();
JSONObject payOrder = null;
// 验证参数有效性
Object object = validateParams(po, payContext);
if (object instanceof String) {
_log.info("{}参数校验不通过:{}", logPrefix, object);
return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, object.toString(), null, null));
}
if (object instanceof JSONObject) payOrder = (JSONObject) object;
if(payOrder == null) return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "支付中心下单失败", null, null));
int result = payOrderService.createPayOrder(payOrder);
_log.info("{}创建支付订单,结果:{}", logPrefix, result);
if(result != 1) {
return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "创建支付订单失败", null, null));
}
String channelId = payOrder.getString("channelId");
switch (channelId) {
case PayConstant.PAY_CHANNEL_WX_APP :
return payOrderService.doWxPayReq(PayConstant.WxConstant.TRADE_TYPE_APP, payOrder, payContext.getString("resKey"));
case PayConstant.PAY_CHANNEL_WX_JSAPI :
return payOrderService.doWxPayReq(PayConstant.WxConstant.TRADE_TYPE_JSPAI, payOrder, payContext.getString("resKey"));
case PayConstant.PAY_CHANNEL_WX_NATIVE :
return payOrderService.doWxPayReq(PayConstant.WxConstant.TRADE_TYPE_NATIVE, payOrder, payContext.getString("resKey"));
case PayConstant.PAY_CHANNEL_WX_MWEB :
return payOrderService.doWxPayReq(PayConstant.WxConstant.TRADE_TYPE_MWEB, payOrder, payContext.getString("resKey"));
case PayConstant.PAY_CHANNEL_ALIPAY_MOBILE :
return payOrderService.doAliPayReq(channelId, payOrder, payContext.getString("resKey"));
case PayConstant.PAY_CHANNEL_ALIPAY_PC :
return payOrderService.doAliPayReq(channelId, payOrder, payContext.getString("resKey"));
case PayConstant.PAY_CHANNEL_ALIPAY_WAP :
return payOrderService.doAliPayReq(channelId, payOrder, payContext.getString("resKey"));
case PayConstant.PAY_CHANNEL_ALIPAY_QR :
return payOrderService.doAliPayReq(channelId, payOrder, payContext.getString("resKey"));
default:
return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "不支持的支付渠道类型[channelId="+channelId+"]", null, null));
}
}catch (Exception e) {
_log.error(e, "");
return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "支付中心系统异常", null, null));
}
}
/**
* 验证创建订单请求参数,参数通过返回JSONObject对象,否则返回错误文本信息
* @param params
* @return
*/
private Object validateParams(JSONObject params, JSONObject payContext) {
// 验证请求参数,参数有问题返回错误提示
String errorMessage;
// 支付参数
String mchId = params.getString("mchId"); // 商户ID
String mchOrderNo = params.getString("mchOrderNo"); // 商户订单号
String channelId = params.getString("channelId"); // 渠道ID
String amount = params.getString("amount"); // 支付金额(单位分)
String currency = params.getString("currency"); // 币种
String clientIp = params.getString("clientIp"); // 客户端IP
String device = params.getString("device"); // 设备
String extra = params.getString("extra"); // 特定渠道发起时额外参数
String param1 = params.getString("param1"); // 扩展参数1
String param2 = params.getString("param2"); // 扩展参数2
String notifyUrl = params.getString("notifyUrl"); // 支付结果回调URL
String sign = params.getString("sign"); // 签名
String subject = params.getString("subject"); // 商品主题
String body = params.getString("body"); // 商品描述信息
// 验证请求参数有效性(必选项)
if(StringUtils.isBlank(mchId)) {
errorMessage = "request params[mchId] error.";
return errorMessage;
}
if(StringUtils.isBlank(mchOrderNo)) {
errorMessage = "request params[mchOrderNo] error.";
return errorMessage;
}
if(StringUtils.isBlank(channelId)) {
errorMessage = "request params[channelId] error.";
return errorMessage;
}
if(!NumberUtils.isNumber(amount)) {
errorMessage = "request params[amount] error.";
return errorMessage;
}
if(StringUtils.isBlank(currency)) {
errorMessage = "request params[currency] error.";
return errorMessage;
}
if(StringUtils.isBlank(notifyUrl)) {
errorMessage = "request params[notifyUrl] error.";
return errorMessage;
}
if(StringUtils.isBlank(subject)) {
errorMessage = "request params[subject] error.";
return errorMessage;
}
if(StringUtils.isBlank(body)) {
errorMessage = "request params[body] error.";
return errorMessage;
}
// 根据不同渠道,判断extra参数
if(PayConstant.PAY_CHANNEL_WX_JSAPI.equalsIgnoreCase(channelId)) {
if(StringUtils.isEmpty(extra)) {
errorMessage = "request params[extra] error.";
return errorMessage;
}
JSONObject extraObject = JSON.parseObject(extra);
String openId = extraObject.getString("openId");
if(StringUtils.isBlank(openId)) {
errorMessage = "request params[extra.openId] error.";
return errorMessage;
}
}else if(PayConstant.PAY_CHANNEL_WX_NATIVE.equalsIgnoreCase(channelId)) {
if(StringUtils.isEmpty(extra)) {
errorMessage = "request params[extra] error.";
return errorMessage;
}
JSONObject extraObject = JSON.parseObject(extra);
String productId = extraObject.getString("productId");
if(StringUtils.isBlank(productId)) {
errorMessage = "request params[extra.productId] error.";
return errorMessage;
}
}else if(PayConstant.PAY_CHANNEL_WX_MWEB.equalsIgnoreCase(channelId)) {
if(StringUtils.isEmpty(extra)) {
errorMessage = "request params[extra] error.";
return errorMessage;
}
JSONObject extraObject = JSON.parseObject(extra);
String productId = extraObject.getString("sceneInfo");
if(StringUtils.isBlank(productId)) {
errorMessage = "request params[extra.sceneInfo] error.";
return errorMessage;
}
if(StringUtils.isBlank(clientIp)) {
errorMessage = "request params[clientIp] error.";
return errorMessage;
}
}
// 签名信息
if (StringUtils.isEmpty(sign)) {
errorMessage = "request params[sign] error.";
return errorMessage;
}
// 查询商户信息
JSONObject mchInfo = mchInfoService.getByMchId(mchId);
if(mchInfo == null) {
errorMessage = "Can't found mchInfo[mchId="+mchId+"] record in db.";
return errorMessage;
}
if(mchInfo.getByte("state") != 1) {
errorMessage = "mchInfo not available [mchId="+mchId+"] record in db.";
return errorMessage;
}
String reqKey = mchInfo.getString("reqKey");
if (StringUtils.isBlank(reqKey)) {
errorMessage = "reqKey is null[mchId="+mchId+"] record in db.";
return errorMessage;
}
payContext.put("resKey", mchInfo.getString("resKey"));
// 查询商户对应的支付渠道
JSONObject payChannel = payChannelService.getByMchIdAndChannelId(mchId, channelId);
if(payChannel == null) {
errorMessage = "Can't found payChannel[channelId="+channelId+",mchId="+mchId+"] record in db.";
return errorMessage;
}
if(payChannel.getByte("state") != 1) {
errorMessage = "channel not available [channelId="+channelId+",mchId="+mchId+"]";
return errorMessage;
}
// 验证签名数据
boolean verifyFlag = XXPayUtil.verifyPaySign(params, reqKey);
if(!verifyFlag) {
errorMessage = "Verify XX pay sign failed.";
return errorMessage;
}
// 验证参数通过,返回JSONObject对象
JSONObject payOrder = new JSONObject();
payOrder.put("payOrderId", MySeq.getPay());
payOrder.put("mchId", mchId);
payOrder.put("mchOrderNo", mchOrderNo);
payOrder.put("channelId", channelId);
payOrder.put("amount", Long.parseLong(amount));
payOrder.put("currency", currency);
payOrder.put("clientIp", clientIp);
payOrder.put("device", device);
payOrder.put("subject", subject);
payOrder.put("body", body);
payOrder.put("extra", extra);
payOrder.put("channelMchId", payChannel.getString("channelMchId"));
payOrder.put("param1", param1);
payOrder.put("param2", param2);
payOrder.put("notifyUrl", notifyUrl);
return payOrder;
}
String getJsonParam(String[] names, Object[] values) {
JSONObject jsonParam = new JSONObject();
for (int i = 0; i < names.length; i++) {
jsonParam.put(names[i], values[i]);
}
return jsonParam.toJSONString();
}
String getJsonParam(String name, Object value) {
JSONObject jsonParam = new JSONObject();
jsonParam.put(name, value);
return jsonParam.toJSONString();
}
}
package org.xxpay.dubbo.web.ctrl;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.MyLog;
import org.xxpay.common.util.XXPayUtil;
import org.xxpay.dubbo.web.service.MchInfoService;
import org.xxpay.dubbo.web.service.PayOrderService;
import java.util.Map;
/**
* @Description: 支付订单查询
* @author dingzhiwei jmdhappy@126.com
* @date 2017-08-31
* @version V1.0
* @Copyright: www.xxpay.org
*/
@RestController
public class QueryPayOrderController {
private final MyLog _log = MyLog.getLog(QueryPayOrderController.class);
@Autowired
private PayOrderService payOrderService;
@Autowired
private MchInfoService mchInfoService;
/**
* 查询支付订单接口:
* 1)先验证接口参数以及签名信息
* 2)根据参数查询订单
* 3)返回订单数据
* @param params
* @return
*/
@RequestMapping(value = "/api/pay/query_order")
public String queryPayOrder(@RequestParam String params) {
_log.info("###### 开始接收商户查询支付订单请求 ######");
String logPrefix = "【商户支付订单查询】";
try {
JSONObject po = JSONObject.parseObject(params);
JSONObject payContext = new JSONObject();
// 验证参数有效性
String errorMessage = validateParams(po, payContext);
if (!"success".equalsIgnoreCase(errorMessage)) {
_log.warn(errorMessage);
return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, errorMessage, null, null));
}
_log.debug("请求参数及签名校验通过");
String mchId = po.getString("mchId"); // 商户ID
String mchOrderNo = po.getString("mchOrderNo"); // 商户订单号
String payOrderId = po.getString("payOrderId"); // 支付订单号
String executeNotify = po.getString("executeNotify"); // 是否执行回调
JSONObject payOrder = payOrderService.queryPayOrder(mchId, payOrderId, mchOrderNo, executeNotify);
_log.info("{}查询支付订单,结果:{}", logPrefix, payOrder);
if (payOrder == null) {
return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "支付订单不存在", null, null));
}
Map<String, Object> map = XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_SUCCESS, null);
map.put("result", payOrder);
_log.info("###### 商户查询订单处理完成 ######");
return XXPayUtil.makeRetData(map, payContext.getString("resKey"));
}catch (Exception e) {
_log.error(e, "");
return XXPayUtil.makeRetFail(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_FAIL, "支付中心系统异常", null, null));
}
}
/**
* 验证创建订单请求参数,参数通过返回JSONObject对象,否则返回错误文本信息
* @param params
* @return
*/
private String validateParams(JSONObject params, JSONObject payContext) {
// 验证请求参数,参数有问题返回错误提示
String errorMessage;
// 支付参数
String mchId = params.getString("mchId"); // 商户ID
String mchOrderNo = params.getString("mchOrderNo"); // 商户订单号
String payOrderId = params.getString("payOrderId"); // 支付订单号
String sign = params.getString("sign"); // 签名
// 验证请求参数有效性(必选项)
if(StringUtils.isBlank(mchId)) {
errorMessage = "request params[mchId] error.";
return errorMessage;
}
if(StringUtils.isBlank(mchOrderNo) && StringUtils.isBlank(payOrderId)) {
errorMessage = "request params[mchOrderNo or payOrderId] error.";
return errorMessage;
}
// 签名信息
if (StringUtils.isEmpty(sign)) {
errorMessage = "request params[sign] error.";
return errorMessage;
}
// 查询商户信息
JSONObject mchInfo = mchInfoService.getByMchId(mchId);
if(mchInfo == null) {
errorMessage = "Can't found mchInfo[mchId="+mchId+"] record in db.";
return errorMessage;
}
if(mchInfo.getByte("state") != 1) {
errorMessage = "mchInfo not available [mchId="+mchId+"] record in db.";
return errorMessage;
}
String reqKey = mchInfo.getString("reqKey");
if (StringUtils.isBlank(reqKey)) {
errorMessage = "reqKey is null[mchId="+mchId+"] record in db.";
return errorMessage;
}
payContext.put("resKey", mchInfo.getString("resKey"));
// 验证签名数据
boolean verifyFlag = XXPayUtil.verifyPaySign(params, reqKey);
if(!verifyFlag) {
errorMessage = "Verify XX pay sign failed.";
return errorMessage;
}
return "success";
}
}
package org.xxpay.dubbo.web.service;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.common.util.RpcUtil;
import java.util.HashMap;
import java.util.Map;
/**
* @author: dingzhiwei
* @date: 17/9/9
* @description:
*/
@Service
public class MchInfoService {
@Autowired
private RpcCommonService rpcCommonService;
public JSONObject getByMchId(String mchId) {
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("mchId", mchId);
String jsonParam = RpcUtil.createBaseParam(paramMap);
Map<String, Object> result = rpcCommonService.rpcMchInfoService.selectMchInfo(jsonParam);
String s = RpcUtil.mkRet(result);
if(s==null) return null;
return JSONObject.parseObject(s);
}
}
package org.xxpay.dubbo.web.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.RpcUtil;
import java.util.HashMap;
import java.util.Map;
/**
* @author: dingzhiwei
* @date: 17/9/10
* @description:
*/
@Service
public class NotifyPayService {
@Autowired
private RpcCommonService rpcCommonService;
public String doAliPayNotify(Map params) {
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("params", params);
String jsonParam = RpcUtil.createBaseParam(paramMap);
Map<String, Object> result = rpcCommonService.rpcNotifyPayService.doAliPayNotify(jsonParam);
String s = RpcUtil.mkRet(result);
if(s == null) {
return PayConstant.RETURN_ALIPAY_VALUE_FAIL;
}
return s;
}
public String doWxPayNotify(String xmlResult) {
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("xmlResult", xmlResult);
String jsonParam = RpcUtil.createBaseParam(paramMap);
// 返回给微信的数据格式已经有service处理(包括正确与错误),肯定会返回result
Map<String, Object> result = rpcCommonService.rpcNotifyPayService.doWxPayNotify(jsonParam);
return RpcUtil.mkRet(result);
}
}
package org.xxpay.dubbo.web.service;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.common.util.RpcUtil;
import java.util.HashMap;
import java.util.Map;
/**
* @author: dingzhiwei
* @date: 17/9/9
* @description:
*/
@Service
public class PayChannelService {
@Autowired
private RpcCommonService rpcCommonService;
public JSONObject getByMchIdAndChannelId(String mchId, String channelId) {
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("mchId", mchId);
paramMap.put("channelId", channelId);
String jsonParam = RpcUtil.createBaseParam(paramMap);
Map<String, Object> result = rpcCommonService.rpcPayChannelService.selectPayChannel(jsonParam);
String s = RpcUtil.mkRet(result);
if(s == null) return null;
return JSONObject.parseObject(s);
}
}
package org.xxpay.dubbo.web.service;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.common.constant.PayConstant;
import org.xxpay.common.util.MyLog;
import org.xxpay.common.util.RpcUtil;
import org.xxpay.common.util.XXPayUtil;
import java.util.HashMap;
import java.util.Map;
/**
* @author: dingzhiwei
* @date: 17/9/9
* @description:
*/
@Service
public class PayOrderService {
private static final MyLog _log = MyLog.getLog(PayOrderService.class);
@Autowired
private RpcCommonService rpcCommonService;
public int createPayOrder(JSONObject payOrder) {
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("payOrder", payOrder);
String jsonParam = RpcUtil.createBaseParam(paramMap);
Map<String, Object> result = rpcCommonService.rpcPayOrderService.createPayOrder(jsonParam);
String s = RpcUtil.mkRet(result);
if(s == null) return 0;
return Integer.parseInt(s);
}
public JSONObject queryPayOrder(String mchId, String payOrderId, String mchOrderNo, String executeNotify) {
Map<String,Object> paramMap = new HashMap<>();
Map<String, Object> result;
if(StringUtils.isNotBlank(payOrderId)) {
paramMap.put("mchId", mchId);
paramMap.put("payOrderId", payOrderId);
String jsonParam = RpcUtil.createBaseParam(paramMap);
result = rpcCommonService.rpcPayOrderService.selectPayOrderByMchIdAndPayOrderId(jsonParam);
}else {
paramMap.put("mchId", mchId);
paramMap.put("mchOrderNo", mchOrderNo);
String jsonParam = RpcUtil.createBaseParam(paramMap);
result = rpcCommonService.rpcPayOrderService.selectPayOrderByMchIdAndPayOrderId(jsonParam);
}
String s = RpcUtil.mkRet(result);
if(s == null) return null;
boolean isNotify = Boolean.parseBoolean(executeNotify);
JSONObject payOrder = JSONObject.parseObject(s);
if(isNotify) {
paramMap = new HashMap<>();
paramMap.put("payOrderId", payOrderId);
String jsonParam = RpcUtil.createBaseParam(paramMap);
result = rpcCommonService.rpcNotifyPayService.sendBizPayNotify(jsonParam);
s = RpcUtil.mkRet(result);
_log.info("业务查单完成,并再次发送业务支付通知.发送结果:{}", s);
}
return payOrder;
}
public String doWxPayReq(String tradeType, JSONObject payOrder, String resKey) {
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("tradeType", tradeType);
paramMap.put("payOrder", payOrder);
String jsonParam = RpcUtil.createBaseParam(paramMap);
Map<String, Object> result = rpcCommonService.rpcPayChannel4WxService.doWxPayReq(jsonParam);
String s = RpcUtil.mkRet(result);
if(s == null) {
return XXPayUtil.makeRetData(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_FAIL, "0111", "调用微信支付失败"), resKey);
}
Map<String, Object> map = XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_SUCCESS, null);
map.putAll((Map) result.get("bizResult"));
return XXPayUtil.makeRetData(map, resKey);
}
public String doAliPayReq(String channelId, JSONObject payOrder, String resKey) {
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("payOrder", payOrder);
String jsonParam = RpcUtil.createBaseParam(paramMap);
Map<String, Object> result;
switch (channelId) {
case PayConstant.PAY_CHANNEL_ALIPAY_MOBILE :
result = rpcCommonService.rpcPayChannel4AliService.doAliPayMobileReq(jsonParam);
break;
case PayConstant.PAY_CHANNEL_ALIPAY_PC :
result = rpcCommonService.rpcPayChannel4AliService.doAliPayPcReq(jsonParam);
break;
case PayConstant.PAY_CHANNEL_ALIPAY_WAP :
result = rpcCommonService.rpcPayChannel4AliService.doAliPayWapReq(jsonParam);
break;
case PayConstant.PAY_CHANNEL_ALIPAY_QR :
result = rpcCommonService.rpcPayChannel4AliService.doAliPayQrReq(jsonParam);
break;
default:
result = null;
break;
}
String s = RpcUtil.mkRet(result);
if(s == null) {
return XXPayUtil.makeRetData(XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_FAIL, "0111", "调用支付宝支付失败"), resKey);
}
Map<String, Object> map = XXPayUtil.makeRetMap(PayConstant.RETURN_VALUE_SUCCESS, "", PayConstant.RETURN_VALUE_SUCCESS, null);
map.putAll((Map) result.get("bizResult"));
return XXPayUtil.makeRetData(map, resKey);
}
}
package org.xxpay.dubbo.web.service;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
import org.xxpay.dubbo.api.service.*;
/**
* @author: dingzhiwei
* @date: 17/9/10
* @description:
*/
@Service
public class RpcCommonService {
@Reference(version = "1.0.0", timeout = 10000, retries = 0)
public IMchInfoService rpcMchInfoService;
@Reference(version = "1.0.0", timeout = 10000, retries = 0)
public IPayChannelService rpcPayChannelService;
@Reference(version = "1.0.0", timeout = 10000, retries = 0)
public IPayOrderService rpcPayOrderService;
@Reference(version = "1.0.0", timeout = 10000, retries = 0)
public IPayChannel4WxService rpcPayChannel4WxService;
@Reference(version = "1.0.0", timeout = 10000, retries = 0)
public IPayChannel4AliService rpcPayChannel4AliService;
@Reference(version = "1.0.0", timeout = 10000, retries = 0)
public INotifyPayService rpcNotifyPayService;
}
server:
port: 3020
spring:
dubbo:
application:
name: xxpay4dubbo-web
registry:
address: zookeeper://127.0.0.1:2181
scan: org.xxpay.dubbo
\ No newline at end of file
...@@ -76,7 +76,7 @@ public class Notify4WxPayController extends Notify4BasePay { ...@@ -76,7 +76,7 @@ public class Notify4WxPayController extends Notify4BasePay {
WxPayConfig wxPayConfig = (WxPayConfig) payContext.get("wxPayConfig"); WxPayConfig wxPayConfig = (WxPayConfig) payContext.get("wxPayConfig");
wxPayService.setConfig(wxPayConfig); wxPayService.setConfig(wxPayConfig);
// 这里做了签名校验(这里又做了一次xml转换对象,可以考虑优化) // 这里做了签名校验(这里又做了一次xml转换对象,可以考虑优化)
wxPayService.getOrderNotifyResult(xmlResult); wxPayService.parseOrderNotifyResult(xmlResult);
// 处理订单 // 处理订单
byte payStatus = payOrder.getStatus(); // 0:订单生成,1:支付中,-1:支付失败,2:支付成功,3:业务处理完成,-2:订单过期 byte payStatus = payOrder.getStatus(); // 0:订单生成,1:支付中,-1:支付失败,2:支付成功,3:业务处理完成,-2:订单过期
if (payStatus != PayConstant.PAY_STATUS_SUCCESS && payStatus != PayConstant.PAY_STATUS_COMPLETE) { if (payStatus != PayConstant.PAY_STATUS_SUCCESS && payStatus != PayConstant.PAY_STATUS_COMPLETE) {
......
...@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject; ...@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
...@@ -93,11 +94,44 @@ public class PayChannel4WxController{ ...@@ -93,11 +94,44 @@ public class PayChannel4WxController{
break; break;
} }
case PayConstant.WxConstant.TRADE_TYPE_APP : { case PayConstant.WxConstant.TRADE_TYPE_APP : {
map.put("payParams", wxPayService.getPayInfo(wxPayUnifiedOrderRequest)); Map<String, String> payInfo = new HashMap<>();
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
String nonceStr = String.valueOf(System.currentTimeMillis());
// APP支付绑定的是微信开放平台上的账号,APPID为开放平台上绑定APP后发放的参数
String appId = wxPayConfig.getAppId();
Map<String, String> configMap = new HashMap<>();
// 此map用于参与调起sdk支付的二次签名,格式全小写,timestamp只能是10位,格式固定,切勿修改
String partnerId = wxPayConfig.getMchId();
configMap.put("prepayid", wxPayUnifiedOrderResult.getPrepayId());
configMap.put("partnerid", partnerId);
String packageValue = "Sign=WXPay";
configMap.put("package", packageValue);
configMap.put("timestamp", timestamp);
configMap.put("noncestr", nonceStr);
configMap.put("appid", appId);
// 此map用于客户端与微信服务器交互
payInfo.put("sign", SignUtils.createSign(configMap, wxPayConfig.getMchKey(), null));
payInfo.put("prepayId", wxPayUnifiedOrderResult.getPrepayId());
payInfo.put("partnerId", partnerId);
payInfo.put("appId", appId);
payInfo.put("packageValue", packageValue);
payInfo.put("timeStamp", timestamp);
payInfo.put("nonceStr", nonceStr);
map.put("payParams", payInfo);
break; break;
} }
case PayConstant.WxConstant.TRADE_TYPE_JSPAI : { case PayConstant.WxConstant.TRADE_TYPE_JSPAI : {
map.put("payParams", wxPayService.getPayInfo(wxPayUnifiedOrderRequest)); Map<String, String> payInfo = new HashMap<>();
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
String nonceStr = String.valueOf(System.currentTimeMillis());
payInfo.put("appId", wxPayUnifiedOrderResult.getAppid());
// 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
payInfo.put("timeStamp", timestamp);
payInfo.put("nonceStr", nonceStr);
payInfo.put("package", "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId());
payInfo.put("signType", WxPayConstants.SignType.MD5);
payInfo.put("paySign", SignUtils.createSign(payInfo, wxPayConfig.getMchKey(), null));
map.put("payParams", payInfo);
break; break;
} }
case PayConstant.WxConstant.TRADE_TYPE_MWEB : { case PayConstant.WxConstant.TRADE_TYPE_MWEB : {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment