微信、支付宝二码合一扫码支付实现思路

一、支付二维码(预订单)

根据需要购买的信息创建预订单,将订单信息保存到Redis中,并设置有效期,注意生产二维码的链接后的参数可以关联到Redis中的key;

QRCode 为servlet扫码请求的URL;

UUIDUtils.getUUID() 为预订单单号,在servlet请求中截取,然后在Redis中查找对应的Key的数据;

二维码地址:http://kung900519.qicp.io/interface/QRCode/UUIDUtils.getUUID();

二、创建二维码扫码请求地址servlet:QRCodeServlet;微信支付重定向请求servlet:WechatPayServlet;支付宝重定向请求servlet:AliPayServlet;

QRCodeServlet 用于用户使用微信或者支付宝扫码二维码进行客户端识别及重定向到对应的业务处理;

package com.platform.cloudlottery.servlet;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import com.platform.cloudlottery.common.CommonConfig;
import com.platform.cloudlottery.common.alipay.config.MyAliPayConfig;
import com.platform.cloudlottery.common.wechat.config.WXPublicConfig;
import com.platform.cloudlottery.common.wechat.util.HttpUtil;
import com.platform.cloudlottery.model.SysPayChannel;
import com.platform.cloudlottery.service.Impl.SysPayChannelServiceImpl;
import com.platform.cloudlottery.web.StatusContant.PayTypeConstant;

/**
 * @ClassName: QRCodeServlet
 * @Description: TODO(根据请求的后缀获取该数据编码对应的数据,并重定向到页面)
 * @author chenkun
 * @date 2018年12月29日
 *
 */
public class QRCodeServlet extends HttpServlet {
private static final long serialVersionUID = -8457626626670970403L;
protected Logger logger = LoggerFactory.getLogger(getClass());

private static final String UrlStr = "QRCode/";

private static final String wechatPay = "wechatPay/";

private static final String aliPay = "aliPay/";

@Autowired
private SysPayChannelServiceImpl payChannelService;

public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, servletConfig.getServletContext());
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    logger.info("####################请求开始####################");
    String userAgent = request.getHeader("user-agent");
    String RequestURL = request.getRequestURL().toString();
    logger.info("URL : " + RequestURL);
    String ReqInfo = RequestURL.substring(RequestURL.indexOf(UrlStr)+UrlStr.length());
    logger.info("URL : " + ReqInfo);
    CommonConfig commonConfig = new CommonConfig();
    if (userAgent != null && userAgent.contains("AlipayClient")) {
        logger.info("来自支付宝");
        String redirecturi = HttpUtil.urlEnCode(commonConfig.getDomain() + aliPay + ReqInfo);
        logger.info("REDIRECT_URI="+redirecturi);
        SysPayChannel channel = payChannelService.selectByChannelType(PayTypeConstant.Alipay);
        MyAliPayConfig aliPayConfig = new MyAliPayConfig();
        aliPayConfig.setAppId(channel.getAppid());
        // 授权页面地址
        String requestUrl = aliPayConfig.getAuthgateway();
        requestUrl = requestUrl.replace("APPID", aliPayConfig.getAppId()).replace("SCOPE", aliPayConfig.getScope()).replace("REDIRECT_URI", redirecturi);
        // 重定向到授权页面
        response.sendRedirect(requestUrl);
    } else if (userAgent != null && userAgent.contains("MicroMessenger")) {
        logger.info("来自微信");
        String redirecturi = HttpUtil.urlEnCode(commonConfig.getDomain() + wechatPay + ReqInfo);
        logger.info("REDIRECT_URI="+redirecturi);
        SysPayChannel channel = payChannelService.selectByChannelType(PayTypeConstant.Wechat);
        WXPublicConfig publicConfig = new WXPublicConfig();
        publicConfig.setAppId(channel.getAppid());
        publicConfig.setOriginId(channel.getOriginid());
        publicConfig.setAppSecret(channel.getAppsecret());
        publicConfig.setEncodingAESKey(channel.getEncodingaeskey());
        // 授权页面地址
        String requestUrl = publicConfig.getAuthorizeinterface();
        requestUrl = requestUrl.replace("APPID", publicConfig.getAppId()).replace("REDIRECT_URI", redirecturi).replace("SCOPE", publicConfig.getScope()).replace("STATE", publicConfig.getState());
        // 重定向到授权页面
        response.sendRedirect(requestUrl);
    } else {
        logger.info("未知来源");
    }
    logger.info("####################请求结束####################");
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
}
}

WechatPayServlet 在获取到Redis中预订单数据后,创建真实订单并调用微信“统一下单接口”;

package com.platform.cloudlottery.servlet;

import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.platform.cloudlottery.common.CommonConfig;
import com.platform.cloudlottery.common.jedis.JedisUtil;
import com.platform.cloudlottery.common.lang.StringUtils;
import com.platform.cloudlottery.common.utils.BusinessCodeUtils;
import com.platform.cloudlottery.common.wechat.bean.WeiXinOAuth2Token;
import com.platform.cloudlottery.common.wechat.bean.WeiXinUserInfo;
import com.platform.cloudlottery.common.wechat.config.WXPayConfig;
import com.platform.cloudlottery.common.wechat.config.WXPublicConfig;
import com.platform.cloudlottery.common.wechat.util.WeiXinOAuth2Util;
import com.platform.cloudlottery.common.wechat.util.WeiXinPayUtils;
import com.platform.cloudlottery.model.SysPayChannel;
import com.platform.cloudlottery.service.Impl.LotteryOrderServiceImpl;
import com.platform.cloudlottery.service.Impl.SysPayChannelServiceImpl;
import com.platform.cloudlottery.service.Impl.UserMemberServiceImpl;
import com.platform.cloudlottery.service.OrderServcie;
import com.platform.cloudlottery.service.UserInfoService;
import com.platform.cloudlottery.web.ResultContant;
import com.platform.cloudlottery.web.StatusContant.PayTypeConstant;
import com.platform.cloudlottery.web.SysKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import redis.clients.jedis.Jedis;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* @ClassName: WechatPayServlet
* @Description: TODO(这里用一句话描述这个类的作用)
* @author chenkun
* @date 2019年1月5日
*
 */
public class WechatPayServlet extends HttpServlet {
private static final long serialVersionUID = -8457626626670970403L;
protected Logger logger = LoggerFactory.getLogger(getClass());

private static Jedis redis = JedisUtil.getJedis();

@Value("${config.domain}")
private String domain;

@Value("${config.isProduction}")
private boolean isProduction;

// 请求路径包含的字符串
private static final String UrlStr = "wechatPay/";

@Autowired
private SysPayChannelServiceImpl payChannelService;

@Autowired
private UserMemberServiceImpl  memberService;

@Autowired
private LotteryOrderServiceImpl lotteryOrderService;

public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, servletConfig.getServletContext());
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    logger.debug("####################请求开始####################");
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    try {
        // 用户同意授权后,能获取到code
        String code = request.getParameter("code");
        // 用户同意授权
        if (!"authdeny".equals(code)) {
            CommonConfig commonConfig = new CommonConfig();
            String RequestURL = request.getRequestURL().toString();
            logger.debug("URL : " + RequestURL);
            String QRCodeUrl = RequestURL.substring(RequestURL.indexOf(UrlStr) + UrlStr.length());
            String QRCodeReqInfo = QRCodeUrl.split("&")[0];
            String operatorId = QRCodeUrl.split("&")[1];
            logger.debug("QRCodeReqInfo : " + QRCodeReqInfo +";operatorId : " + operatorId);
            String advancekey = commonConfig.getLotteryorder() + QRCodeReqInfo;

            SysPayChannel channel = payChannelService.selectByChannelType(PayTypeConstant.Wechat);
            WXPublicConfig publicConfig = new WXPublicConfig();
            publicConfig.setAppId(channel.getAppid());
            publicConfig.setOriginId(channel.getOriginid());
            publicConfig.setAppSecret(channel.getAppsecret());
            publicConfig.setEncodingAESKey(channel.getEncodingaeskey());
            WXPayConfig payConfig = new WXPayConfig();
            payConfig.setMchId(channel.getMchid());
            payConfig.setAppId(channel.getAppid());
            payConfig.setKey(channel.getWxkey());
            payConfig.setApicertPath(channel.getPayCertUrl());
            payConfig.setSpbillCreateIp(channel.getSpbillcreateip());
            // 获取网页授权access_token
            WeiXinOAuth2Token weixinOauth2Token = WeiXinOAuth2Util.getOAuth2AccessToken(publicConfig,code);
            // 网页授权接口访问凭证
            String accessToken = weixinOauth2Token.getAccessToken();
            logger.debug("accessToken=" + accessToken);
            // 用户标识
            String openId = weixinOauth2Token.getOpenId();
            logger.debug("openId="+openId);
            // 获取用户信息
            WeiXinUserInfo userInfo = WeiXinOAuth2Util.getOAuth2UserInfo(publicConfig, accessToken, openId);
            logger.debug(userInfo.getNickName()+"=====微信支付====="+userInfo.getOpenId());
            //添加或更新用户信息
            String userid =  UserInfoService.CreateUserMember(userInfo,memberService);

            if (!redis.exists(advancekey)) {// 判断key是否存在
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            if (StringUtils.trimToEmpty(redis.get(advancekey)).equals("")) {
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            JSONObject jsonObject = JSONObject.parseObject(redis.get(advancekey));
            if (null == jsonObject) {
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            if (redis.get(advancekey + "_lock") != null && !redis.get(advancekey + "_lock").equals("")){
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            redis.setex(advancekey + "_lock", 1, "lock");

            String orderid = BusinessCodeUtils.getOrderNo(jsonObject.getString(SysKey.deviceSn));
            int money = jsonObject.getIntValue(SysKey.money);
            int lotterytype = jsonObject.getIntValue(SysKey.lotteryType);
            if (!orderid.equals("") && money!=0) {
                //创建订单
                boolean bool = OrderServcie.createorder(QRCodeReqInfo, PayTypeConstant.Wechat, payConfig.getAppID(), userid, openId, orderid, jsonObject, lotteryOrderService);
                if (bool) {
                    //删除预订单信息
                    redis.del(advancekey);//一个预订单只能创建一个订单
                    String paymoney =  String.valueOf(money);
                    if (!isProduction) {//测试环境
                        paymoney = BigDecimal.valueOf(Long.valueOf(paymoney)).divide(new BigDecimal(100)).toString();//真实金额除100
                    }
                    logger.debug("是否生产环境:"+isProduction+";订单金额为:"+String.valueOf(money)+";实际支付金额为:"+paymoney);
                    //创建微信订单
                    Map<String, String> map = WeiXinPayUtils.createOrderJsapi(domain, payConfig, orderid, paymoney, lotterytype==0?"即开票":"电脑票", openId);
                    logger.debug("创建微信支付预订单返回数据:"+JSONObject.toJSONString(map));
                    if (map != null) {
                        if (map.get("return_code").equals("SUCCESS")) {
                            if (map.get("result_code").equals("SUCCESS")) {
                                logger.debug("创建微信支付预订单成功");
                                Map<String, String> data = new LinkedHashMap<String, String>();
                                data.put("appId", payConfig.getAppID());
                                data.put("timeStamp", String.valueOf(new Date().getTime()/1000));
                                data.put("nonceStr", WXPayUtil.generateNonceStr());
                                data.put("package", "prepay_id="+map.get("prepay_id"));
                                data.put("signType", "MD5");
                                data.put("paySign", WXPayUtil.generateSignature(data, payConfig.getKey()));
                                logger.debug("返回到客户端的数据:"+JSONObject.toJSONString(data));
                                request.setAttribute("appId", data.get("appId"));
                                request.setAttribute("timeStamp", data.get("timeStamp"));
                                request.setAttribute("nonceStr", data.get("nonceStr"));
                                request.setAttribute("package", data.get("package"));
                                request.setAttribute("signType", data.get("signType"));
                                request.setAttribute("paySign", data.get("paySign"));

                                request.setAttribute("code", ResultContant.sucess);
                                request.setAttribute("message", "成功");
                                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                            }else{
                                logger.debug("创建订单失败: 创建支付预订单失败");
                                request.setAttribute("code", ResultContant.createordererror);
                                request.setAttribute("message", "创建订单失败");
                                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                            }
                        } else {
                            logger.debug("创建订单失败:创建支付预订单失败");
                            request.setAttribute("code", ResultContant.createordererror);
                            request.setAttribute("message", "创建订单失败");
                            request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                        }
                    } else {
                        logger.debug("创建订单失败:创建支付预订单失败");
                        request.setAttribute("code", ResultContant.createordererror);
                        request.setAttribute("message", "创建订单失败");
                        request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                    }
                } else {
                    logger.debug("创建订单失败:创建支付预订单失败");
                    request.setAttribute("code", ResultContant.createordererror);
                    request.setAttribute("message", "创建订单失败");
                    request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                }
            } else {
                logger.debug("创建订单失败;订单金额或者订单号数据有误");
                request.setAttribute("code", ResultContant.createordererror);
                request.setAttribute("message", "创建订单失败");
                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        logger.debug("系统异常");
        request.setAttribute("code", ResultContant.notuserdqrcode);
        request.setAttribute("message", "二维码失效");
        request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
    }
    logger.debug("####################请求结束####################");
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
}
}

AliPayServlet 在获取到Redis中预订单数据后,创建真实订单并调用支付宝“手机网站支付接口”;

package com.platform.cloudlottery.servlet;

import com.alibaba.fastjson.JSONObject;
import com.platform.cloudlottery.common.CommonConfig;
import com.platform.cloudlottery.common.alipay.bean.AliPayOAuth2Token;
import com.platform.cloudlottery.common.alipay.bean.AliPayUserInfo;
import com.platform.cloudlottery.common.alipay.config.MyAliPayConfig;
import com.platform.cloudlottery.common.alipay.uitl.AliPayOAuth2Util;
import com.platform.cloudlottery.common.alipay.uitl.AlipayPayUtils;
import com.platform.cloudlottery.common.jedis.JedisUtil;
import com.platform.cloudlottery.common.lang.StringUtils;
import com.platform.cloudlottery.common.properties.PropertiesUtils;
import com.platform.cloudlottery.common.utils.BusinessCodeUtils;
import com.platform.cloudlottery.model.SysPayChannel;
import com.platform.cloudlottery.service.Impl.LotteryOrderServiceImpl;
import com.platform.cloudlottery.service.Impl.SysPayChannelServiceImpl;
import com.platform.cloudlottery.service.Impl.UserMemberServiceImpl;
import com.platform.cloudlottery.service.OrderServcie;
import com.platform.cloudlottery.service.UserInfoService;
import com.platform.cloudlottery.web.ResultContant;
import com.platform.cloudlottery.web.StatusContant.PayTypeConstant;
import com.platform.cloudlottery.web.SysKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import redis.clients.jedis.Jedis;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Properties;

/**
* @ClassName: AliPayServlet
* @Description: TODO(这里用一句话描述这个类的作用)
* @author chenkun
* @date 2019年1月5日
*
 */
public class AliPayServlet extends HttpServlet {
private static final long serialVersionUID = -8457626626670970403L;
protected Logger logger = LoggerFactory.getLogger(getClass());

private static Jedis redis = JedisUtil.getJedis();

@Value("${config.domain}")
private String domain;

@Value("${config.isProduction}")
private boolean isProduction;

// 请求路径包含的字符串
private static final String UrlStr = "aliPay/";

@Autowired
private SysPayChannelServiceImpl payChannelService;

@Autowired
private UserMemberServiceImpl  memberService;

@Autowired
private LotteryOrderServiceImpl lotteryOrderService;

public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);
    SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, servletConfig.getServletContext());
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    logger.debug("####################请求开始####################");
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    try {
        //用户同意授权后,能获取到code
        String code = request.getParameter("auth_code");
        //用户同意授权
        if (!code.equals("")) {
            CommonConfig commonConfig = new CommonConfig();
            //具体业务
            String RequestURL = request.getRequestURL().toString();
            logger.debug("URL : " + RequestURL);
            String QRCodeUrl = RequestURL.substring(RequestURL.indexOf(UrlStr) + UrlStr.length());
            String QRCodeReqInfo = QRCodeUrl.split("&")[0];
            String operatorId = QRCodeUrl.split("&")[1];
            logger.debug("QRCodeReqInfo : " + QRCodeReqInfo +";operatorId : " + operatorId);
            String advancekey = commonConfig.getLotteryorder() + QRCodeReqInfo;

            SysPayChannel channel = payChannelService.selectByChannelType(PayTypeConstant.Alipay);
            MyAliPayConfig aliPayConfig = new MyAliPayConfig();
            aliPayConfig.setAppId(channel.getAppid());
            String certsrc = channel.getPayCertUrl();
            Properties propertiesFile = PropertiesUtils.getPropertiesFile(certsrc);
            if (propertiesFile != null) {
                aliPayConfig.setPayeeAccount(propertiesFile.getProperty("ALI_PAYEE_ACCOUNT"));
                aliPayConfig.setAppId(propertiesFile.getProperty("ALI_APP_ID"));
                aliPayConfig.setAliPayPublicKey(propertiesFile.getProperty("ALI_ALIPAY_PUBLIC_KEY"));
                aliPayConfig.setAppPayPublicKey(propertiesFile.getProperty("ALI_APP_PAY_PUBLIC_KEY"));
                aliPayConfig.setAppPrivateKey(propertiesFile.getProperty("ALI_APP_PRIVATE_KEY"));
            }
            //获取网页授权access_token
            AliPayOAuth2Token aliPayOAuth2Token  = AliPayOAuth2Util.getOAuth2AccessToken(aliPayConfig,code);
            //网页授权接口访问凭证
            String accessToken = aliPayOAuth2Token.getAccessToken();
            logger.debug("accessToken=" + accessToken);
            //用户标识
            String aliuserid = aliPayOAuth2Token.getUserid();
            logger.debug("aliuserid="+aliuserid);
            //获取用户信息
            AliPayUserInfo userInfo = AliPayOAuth2Util.getOAuth2UserInfo(aliPayConfig,accessToken,aliuserid);
            logger.debug(userInfo.getNickName()+"=====支付宝支付====="+userInfo.getUserId());
            //添加或更新用户信息
            String userid = UserInfoService.CreateUserMember(userInfo,memberService);

            if (!redis.exists(advancekey)) {// 判断key是否存在
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            if (StringUtils.trimToEmpty(redis.get(advancekey)).equals("")) {
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            JSONObject jsonObject = JSONObject.parseObject(redis.get(advancekey));
            if (null == jsonObject) {
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            if (redis.get(advancekey + "_lock") != null && !redis.get(advancekey + "_lock").equals("")){
                logger.debug("二维码失效");
                request.setAttribute("code", ResultContant.notuserdqrcode);
                request.setAttribute("message", "二维码失效");
                request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                logger.debug("####################请求结束####################");
                return;
            }

            redis.setex(advancekey + "_lock", 1, "lock");

            String orderid = BusinessCodeUtils.getOrderNo(jsonObject.getString(SysKey.deviceSn));
            int money = jsonObject.getIntValue(SysKey.money);
            int lotterytype = jsonObject.getIntValue(SysKey.lotteryType);
            if (!orderid.equals("") && money != 0) {
                //创建订单
                boolean bool  = OrderServcie.createorder(QRCodeReqInfo, PayTypeConstant.Alipay, aliPayConfig.getAppId(), userid, aliuserid, orderid, jsonObject, lotteryOrderService);
                if (bool) {
                    //删除预订单信息
                    redis.del(advancekey);//一个预订单只能创建一个订单
                    String paymoney = BigDecimal.valueOf(Long.valueOf(money)).divide(new BigDecimal(100)).toString();
                    if (!isProduction) {//测试环境
                        paymoney = BigDecimal.valueOf(Long.valueOf(paymoney)).divide(new BigDecimal(100)).toString();//真实金额除100
                    }
                    logger.debug("是否生产环境:"+isProduction+";订单金额为:"+BigDecimal.valueOf(Long.valueOf(money)).divide(new BigDecimal(100)).toString()+";实际支付金额为:"+paymoney);
                    //创建支付宝订单
                    String responsestr  = AlipayPayUtils.createOrderWapPay(domain, aliPayConfig, orderid, lotterytype==0?"即开票":"电脑票", paymoney, "");
                    logger.debug("创建支付宝支付预订单返回数据:"+responsestr);
                    if (!responsestr.equals("")) {
                        response.setContentType("text/html;charset=UTF-8");
                        response.getWriter().write(responsestr);//直接将完整的表单html输出到页面
                        response.getWriter().flush();
                        response.getWriter().close();
                        response.getWriter().append("Served at: ").append(request.getContextPath());
                    } else {
                        logger.debug("创建订单失败:创建支付预订单失败");
                        request.setAttribute("code", ResultContant.createordererror);
                        request.setAttribute("message", "创建订单失败");
                        request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                    }
                } else {
                    logger.debug("创建订单失败:创建支付预订单失败");
                    request.setAttribute("code", ResultContant.createordererror);
                    request.setAttribute("message", "创建订单失败");
                    request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                }
            } else {
                logger.debug("创建订单失败;订单金额或者订单号数据有误");
                request.setAttribute("code", ResultContant.createordererror);
                request.setAttribute("message", "创建订单失败");
                request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        logger.debug("系统异常");
        request.setAttribute("code", "二维码失效");
        request.setAttribute("message", "二维码失效");
        request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
    }
    logger.debug("####################请求结束####################");
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
}
}

三、创建微信支付结果回调接口和支付宝支付接口回调接口,用于接收微信或者支付宝的支付结果通知;

aliPayNotify 支付宝支付成功回调接口

/**
* @Title: aliPayNotify
* @Description: TODO(支付宝支付成功过回调)
* @author chenkun
* @return 参数
* @return String 返回类型
* @throws
 */
@RequestMapping(value = "/aliPayNotify", method = RequestMethod.POST)
public String aliPayNotify() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
    String paramsJson = JSON.toJSONString(params);
    logger.info("支付宝支付回调,{" + paramsJson + "}");
    try {
        SysPayChannel channel = payChannelService.selectByChannelType(PayTypeConstant.Alipay);
        MyAliPayConfig aliPayConfig = new MyAliPayConfig();
        aliPayConfig.setAppId(channel.getAppid());
        String certsrc = channel.getPayCertUrl();
        Properties propertiesFile = PropertiesUtils.getPropertiesFile(certsrc);
        if (propertiesFile != null) {
            aliPayConfig.setPayeeAccount(propertiesFile.getProperty("ALI_PAYEE_ACCOUNT"));
            aliPayConfig.setAppId(propertiesFile.getProperty("ALI_APP_ID"));
            aliPayConfig.setAliPayPublicKey(propertiesFile.getProperty("ALI_ALIPAY_PUBLIC_KEY"));
            aliPayConfig.setAppPayPublicKey(propertiesFile.getProperty("ALI_APP_PAY_PUBLIC_KEY"));
            aliPayConfig.setAppPrivateKey(propertiesFile.getProperty("ALI_APP_PRIVATE_KEY"));
        }
        // 调用SDK验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, aliPayConfig.getAliPayPublicKey(),
                aliPayConfig.getCharset(), aliPayConfig.getSigntype());
        if (signVerified) {
            logger.info("支付宝回调签名认证成功");
            // 按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failure
            this.check(params);
            // 另起线程处理业务
            executorService.execute(new AliPayNotifyTask(params,payCallBackService));
            // 如果签名验证正确,立即返回success,后续业务另起线程单独处理
            // 业务处理失败,可查看日志进行补偿,跟支付宝已经没多大关系。
            return "success";
        } else {
            logger.info("支付宝回调签名认证失败,signVerified=false, paramsJson:{}", paramsJson);
            return "failure";
        }
    } catch (AlipayApiException e) {
        logger.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());
        return "failure";
    }
}

WechatPayNotify 微信支付成功回调

/**
* @Title: WechatPayNotify
* @Description: TODO(微信支付成功回调)
* @author chenkun
* @return 参数
* @return String 返回类型
* @throws
 */
@RequestMapping(value = "/WechatPayNotify", method = RequestMethod.POST)
public String WechatPayNotify() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    String result = "";// 返回给微信的处理结果
    String notityXml = "";// 微信给返回的东西  
    String inputLine;
    try {
        while ((inputLine = request.getReader().readLine()) != null) {
            notityXml += inputLine;
        }
        request.getReader().close();
    } catch (Exception e) {
        logger.error("微信支付回调失败,paramsJson:{},errorMsg:{}", "回调数据获取失败", e.getMessage());
        result = setXml("fail", "xml获取失败");
        e.printStackTrace();
    }
    if (StringUtils.isEmpty(notityXml)) {
        logger.info("微信支付回调失败:回调数据为空");
        result = setXml("fail", "xml为空");
    }
    try {
        logger.info("微信支付回调数据:{" + notityXml + "}");
        Map<String, String> map = WXPayUtil.xmlToMap(notityXml);
        String result_code = (String) map.get("result_code");// 业务结果  
        String return_code = (String) map.get("return_code");// SUCCESS/FAIL  
        // 解析各种数据  
        if (result_code.equals("SUCCESS")) {
            result = setXml("SUCCESS", "OK");
        } else {
            logger.info("微信返回的交易状态不正确(result_code=" + result_code + ")");
            result = setXml("fail", "微信返回的交易状态不正确(result_code=" + result_code + ")");
        }
        // 如果微信返回的结果是success,则修改订单状态  
        if (return_code.equals("SUCCESS")) {

            // 这里是我的业务........................................
            String sr = payCallBackService.confirmWechatPayOrder(map,true);
            logger.debug(sr);
            if (StringUtils.isNotEmpty(sr)){
                result = setXml("fail",sr);
                executorService.execute(new WechatPayRefundTask(map,payCallBackService));
            } else {
                result = setXml("SUCCESS", "OK");
            }
        } else {
            result = setXml("fail", return_code);
        }
    } catch (Exception e) {
        logger.error("微信支付回调失败,paramsJson:{},errorMsg:{}", "回调数据处理失败", e.getMessage());
        result = setXml("fail", "回调数据处理失败");
        e.printStackTrace();
    }
    logger.info("回调成功----返回给微信的xml:" + result);
    return result;
}

仅此供给大家,在大家有这方面的需求时,少走弯路!如果对大家有用,请大家多多点赞支持!

尊重原创,转载请注明出处

kung900519

https://www.jianshu.com/p/b0282b43007b

https://blog.csdn.net/kung_com/article/details/89468673

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345