微信运挫、支付寶二碼合一掃碼支付實現(xiàn)思路

一、支付二維碼(預(yù)訂單)

根據(jù)需要購買的信息創(chuàng)建預(yù)訂單套耕,將訂單信息保存到Redis中谁帕,并設(shè)置有效期,注意生產(chǎn)二維碼的鏈接后的參數(shù)可以關(guān)聯(lián)到Redis中的key箍铲;

QRCode 為servlet掃碼請求的URL雇卷;

UUIDUtils.getUUID() 為預(yù)訂單單號鬓椭,在servlet請求中截取颠猴,然后在Redis中查找對應(yīng)的Key的數(shù)據(jù);

二維碼地址:http://kung900519.qicp.io/interface/QRCode/UUIDUtils.getUUID()小染;

二翘瓮、創(chuàng)建二維碼掃碼請求地址servlet:QRCodeServlet;微信支付重定向請求servlet:WechatPayServlet裤翩;支付寶重定向請求servlet:AliPayServlet资盅;

QRCodeServlet 用于用戶使用微信或者支付寶掃碼二維碼進行客戶端識別及重定向到對應(yīng)的業(yè)務(wù)處理调榄;

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(根據(jù)請求的后綴獲取該數(shù)據(jù)編碼對應(yīng)的數(shù)據(jù),并重定向到頁面)
 * @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());
        // 授權(quán)頁面地址
        String requestUrl = aliPayConfig.getAuthgateway();
        requestUrl = requestUrl.replace("APPID", aliPayConfig.getAppId()).replace("SCOPE", aliPayConfig.getScope()).replace("REDIRECT_URI", redirecturi);
        // 重定向到授權(quán)頁面
        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());
        // 授權(quán)頁面地址
        String requestUrl = publicConfig.getAuthorizeinterface();
        requestUrl = requestUrl.replace("APPID", publicConfig.getAppId()).replace("REDIRECT_URI", redirecturi).replace("SCOPE", publicConfig.getScope()).replace("STATE", publicConfig.getState());
        // 重定向到授權(quán)頁面
        response.sendRedirect(requestUrl);
    } else {
        logger.info("未知來源");
    }
    logger.info("####################請求結(jié)束####################");
}

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

WechatPayServlet 在獲取到Redis中預(yù)訂單數(shù)據(jù)后,創(chuàng)建真實訂單并調(diào)用微信“統(tǒng)一下單接口”呵扛;

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 {
        // 用戶同意授權(quán)后每庆,能獲取到code
        String code = request.getParameter("code");
        // 用戶同意授權(quán)
        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());
            // 獲取網(wǎng)頁授權(quán)access_token
            WeiXinOAuth2Token weixinOauth2Token = WeiXinOAuth2Util.getOAuth2AccessToken(publicConfig,code);
            // 網(wǎng)頁授權(quán)接口訪問憑證
            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("####################請求結(jié)束####################");
                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("####################請求結(jié)束####################");
                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("####################請求結(jié)束####################");
                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("####################請求結(jié)束####################");
                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) {
                //創(chuàng)建訂單
                boolean bool = OrderServcie.createorder(QRCodeReqInfo, PayTypeConstant.Wechat, payConfig.getAppID(), userid, openId, orderid, jsonObject, lotteryOrderService);
                if (bool) {
                    //刪除預(yù)訂單信息
                    redis.del(advancekey);//一個預(yù)訂單只能創(chuàng)建一個訂單
                    String paymoney =  String.valueOf(money);
                    if (!isProduction) {//測試環(huán)境
                        paymoney = BigDecimal.valueOf(Long.valueOf(paymoney)).divide(new BigDecimal(100)).toString();//真實金額除100
                    }
                    logger.debug("是否生產(chǎn)環(huán)境:"+isProduction+";訂單金額為:"+String.valueOf(money)+";實際支付金額為:"+paymoney);
                    //創(chuàng)建微信訂單
                    Map<String, String> map = WeiXinPayUtils.createOrderJsapi(domain, payConfig, orderid, paymoney, lotterytype==0?"即開票":"電腦票", openId);
                    logger.debug("創(chuàng)建微信支付預(yù)訂單返回數(shù)據(jù):"+JSONObject.toJSONString(map));
                    if (map != null) {
                        if (map.get("return_code").equals("SUCCESS")) {
                            if (map.get("result_code").equals("SUCCESS")) {
                                logger.debug("創(chuàng)建微信支付預(yù)訂單成功");
                                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("返回到客戶端的數(shù)據(jù):"+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("創(chuàng)建訂單失斀翊: 創(chuàng)建支付預(yù)訂單失敗");
                                request.setAttribute("code", ResultContant.createordererror);
                                request.setAttribute("message", "創(chuàng)建訂單失敗");
                                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                            }
                        } else {
                            logger.debug("創(chuàng)建訂單失旂土椤:創(chuàng)建支付預(yù)訂單失敗");
                            request.setAttribute("code", ResultContant.createordererror);
                            request.setAttribute("message", "創(chuàng)建訂單失敗");
                            request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                        }
                    } else {
                        logger.debug("創(chuàng)建訂單失敗:創(chuàng)建支付預(yù)訂單失敗");
                        request.setAttribute("code", ResultContant.createordererror);
                        request.setAttribute("message", "創(chuàng)建訂單失敗");
                        request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                    }
                } else {
                    logger.debug("創(chuàng)建訂單失斃渡埂:創(chuàng)建支付預(yù)訂單失敗");
                    request.setAttribute("code", ResultContant.createordererror);
                    request.setAttribute("message", "創(chuàng)建訂單失敗");
                    request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
                }
            } else {
                logger.debug("創(chuàng)建訂單失斎觥;訂單金額或者訂單號數(shù)據(jù)有誤");
                request.setAttribute("code", ResultContant.createordererror);
                request.setAttribute("message", "創(chuàng)建訂單失敗");
                request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        logger.debug("系統(tǒng)異常");
        request.setAttribute("code", ResultContant.notuserdqrcode);
        request.setAttribute("message", "二維碼失效");
        request.getRequestDispatcher("../wechat/WechatPay.jsp").forward(request, response);
    }
    logger.debug("####################請求結(jié)束####################");
}

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

AliPayServlet 在獲取到Redis中預(yù)訂單數(shù)據(jù)后芝薇,創(chuàng)建真實訂單并調(diào)用支付寶“手機網(wǎng)站支付接口”胚嘲;

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 {
        //用戶同意授權(quán)后,能獲取到code
        String code = request.getParameter("auth_code");
        //用戶同意授權(quán)
        if (!code.equals("")) {
            CommonConfig commonConfig = new CommonConfig();
            //具體業(yè)務(wù)
            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"));
            }
            //獲取網(wǎng)頁授權(quán)access_token
            AliPayOAuth2Token aliPayOAuth2Token  = AliPayOAuth2Util.getOAuth2AccessToken(aliPayConfig,code);
            //網(wǎng)頁授權(quán)接口訪問憑證
            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("####################請求結(jié)束####################");
                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("####################請求結(jié)束####################");
                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("####################請求結(jié)束####################");
                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("####################請求結(jié)束####################");
                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) {
                //創(chuàng)建訂單
                boolean bool  = OrderServcie.createorder(QRCodeReqInfo, PayTypeConstant.Alipay, aliPayConfig.getAppId(), userid, aliuserid, orderid, jsonObject, lotteryOrderService);
                if (bool) {
                    //刪除預(yù)訂單信息
                    redis.del(advancekey);//一個預(yù)訂單只能創(chuàng)建一個訂單
                    String paymoney = BigDecimal.valueOf(Long.valueOf(money)).divide(new BigDecimal(100)).toString();
                    if (!isProduction) {//測試環(huán)境
                        paymoney = BigDecimal.valueOf(Long.valueOf(paymoney)).divide(new BigDecimal(100)).toString();//真實金額除100
                    }
                    logger.debug("是否生產(chǎn)環(huán)境:"+isProduction+";訂單金額為:"+BigDecimal.valueOf(Long.valueOf(money)).divide(new BigDecimal(100)).toString()+";實際支付金額為:"+paymoney);
                    //創(chuàng)建支付寶訂單
                    String responsestr  = AlipayPayUtils.createOrderWapPay(domain, aliPayConfig, orderid, lotterytype==0?"即開票":"電腦票", paymoney, "");
                    logger.debug("創(chuàng)建支付寶支付預(yù)訂單返回數(shù)據(jù):"+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("創(chuàng)建訂單失敳雠:創(chuàng)建支付預(yù)訂單失敗");
                        request.setAttribute("code", ResultContant.createordererror);
                        request.setAttribute("message", "創(chuàng)建訂單失敗");
                        request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                    }
                } else {
                    logger.debug("創(chuàng)建訂單失敗:創(chuàng)建支付預(yù)訂單失敗");
                    request.setAttribute("code", ResultContant.createordererror);
                    request.setAttribute("message", "創(chuàng)建訂單失敗");
                    request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
                }
            } else {
                logger.debug("創(chuàng)建訂單失斄浪弧侣滩;訂單金額或者訂單號數(shù)據(jù)有誤");
                request.setAttribute("code", ResultContant.createordererror);
                request.setAttribute("message", "創(chuàng)建訂單失敗");
                request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        logger.debug("系統(tǒng)異常");
        request.setAttribute("code", "二維碼失效");
        request.setAttribute("message", "二維碼失效");
        request.getRequestDispatcher("../alipay/AliPay.jsp").forward(request, response);
    }
    logger.debug("####################請求結(jié)束####################");
}

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

三、創(chuàng)建微信支付結(jié)果回調(diào)接口和支付寶支付接口回調(diào)接口变擒,用于接收微信或者支付寶的支付結(jié)果通知君珠;

aliPayNotify 支付寶支付成功回調(diào)接口

/**
* @Title: aliPayNotify
* @Description: TODO(支付寶支付成功過回調(diào))
* @author chenkun
* @return 參數(shù)
* @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); // 將異步通知中收到的待驗證所有參數(shù)都存放到map中
    String paramsJson = JSON.toJSONString(params);
    logger.info("支付寶支付回調(diào),{" + 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"));
        }
        // 調(diào)用SDK驗證簽名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, aliPayConfig.getAliPayPublicKey(),
                aliPayConfig.getCharset(), aliPayConfig.getSigntype());
        if (signVerified) {
            logger.info("支付寶回調(diào)簽名認證成功");
            // 按照支付結(jié)果異步通知中的描述娇斑,對支付結(jié)果中的業(yè)務(wù)內(nèi)容進行1\2\3\4二次校驗策添,校驗成功后在response中返回success,校驗失敗返回failure
            this.check(params);
            // 另起線程處理業(yè)務(wù)
            executorService.execute(new AliPayNotifyTask(params,payCallBackService));
            // 如果簽名驗證正確毫缆,立即返回success唯竹,后續(xù)業(yè)務(wù)另起線程單獨處理
            // 業(yè)務(wù)處理失敗,可查看日志進行補償苦丁,跟支付寶已經(jīng)沒多大關(guān)系浸颓。
            return "success";
        } else {
            logger.info("支付寶回調(diào)簽名認證失敗,signVerified=false, paramsJson:{}", paramsJson);
            return "failure";
        }
    } catch (AlipayApiException e) {
        logger.error("支付寶回調(diào)簽名認證失敗,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());
        return "failure";
    }
}

WechatPayNotify 微信支付成功回調(diào)

/**
* @Title: WechatPayNotify
* @Description: TODO(微信支付成功回調(diào))
* @author chenkun
* @return 參數(shù)
* @return String 返回類型
* @throws
 */
@RequestMapping(value = "/WechatPayNotify", method = RequestMethod.POST)
public String WechatPayNotify() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    String result = "";// 返回給微信的處理結(jié)果
    String notityXml = "";// 微信給返回的東西  
    String inputLine;
    try {
        while ((inputLine = request.getReader().readLine()) != null) {
            notityXml += inputLine;
        }
        request.getReader().close();
    } catch (Exception e) {
        logger.error("微信支付回調(diào)失敗,paramsJson:{},errorMsg:{}", "回調(diào)數(shù)據(jù)獲取失敗", e.getMessage());
        result = setXml("fail", "xml獲取失敗");
        e.printStackTrace();
    }
    if (StringUtils.isEmpty(notityXml)) {
        logger.info("微信支付回調(diào)失敗:回調(diào)數(shù)據(jù)為空");
        result = setXml("fail", "xml為空");
    }
    try {
        logger.info("微信支付回調(diào)數(shù)據(jù):{" + notityXml + "}");
        Map<String, String> map = WXPayUtil.xmlToMap(notityXml);
        String result_code = (String) map.get("result_code");// 業(yè)務(wù)結(jié)果  
        String return_code = (String) map.get("return_code");// SUCCESS/FAIL  
        // 解析各種數(shù)據(jù)  
        if (result_code.equals("SUCCESS")) {
            result = setXml("SUCCESS", "OK");
        } else {
            logger.info("微信返回的交易狀態(tài)不正確(result_code=" + result_code + ")");
            result = setXml("fail", "微信返回的交易狀態(tài)不正確(result_code=" + result_code + ")");
        }
        // 如果微信返回的結(jié)果是success旺拉,則修改訂單狀態(tài)  
        if (return_code.equals("SUCCESS")) {

            // 這里是我的業(yè)務(wù)........................................
            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("微信支付回調(diào)失敗,paramsJson:{},errorMsg:{}", "回調(diào)數(shù)據(jù)處理失敗", e.getMessage());
        result = setXml("fail", "回調(diào)數(shù)據(jù)處理失敗");
        e.printStackTrace();
    }
    logger.info("回調(diào)成功----返回給微信的xml:" + result);
    return result;
}

僅此供給大家产上,在大家有這方面的需求時,少走彎路蛾狗!如果對大家有用晋涣,請大家多多點贊支持!

尊重原創(chuàng)沉桌,轉(zhuǎn)載請注明出處

kung900519

http://www.reibang.com/p/b0282b43007b

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谢鹊,一起剝皮案震驚了整個濱河市算吩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌佃扼,老刑警劉巖偎巢,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異兼耀,居然都是意外死亡艘狭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門翠订,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巢音,“玉大人,你說我怎么就攤上這事尽超」俸常” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵似谁,是天一觀的道長傲绣。 經(jīng)常有香客問我,道長巩踏,這世上最難降的妖魔是什么秃诵? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮塞琼,結(jié)果婚禮上菠净,老公的妹妹穿的比我還像新娘。我一直安慰自己彪杉,他們只是感情好毅往,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著派近,像睡著了一般攀唯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渴丸,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天侯嘀,我揣著相機與錄音,去河邊找鬼谱轨。 笑死戒幔,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的碟嘴。 我是一名探鬼主播溪食,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娜扇!你這毒婦竟也來了错沃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤雀瓢,失蹤者是張志新(化名)和其女友劉穎枢析,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刃麸,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡醒叁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了泊业。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片把沼。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吁伺,靈堂內(nèi)的尸體忽然破棺而出饮睬,到底是詐尸還是另有隱情,我是刑警寧澤篮奄,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布捆愁,位于F島的核電站,受9級特大地震影響窟却,放射性物質(zhì)發(fā)生泄漏昼丑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一夸赫、第九天 我趴在偏房一處隱蔽的房頂上張望菩帝。 院中可真熱鬧,春花似錦茬腿、人聲如沸胁附。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽控妻。三九已至,卻和暖如春揭绑,著一層夾襖步出監(jiān)牢的瞬間弓候,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工他匪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留菇存,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓邦蜜,卻偏偏與公主長得像依鸥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子悼沈,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355