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

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

根据需要购买的信息创建预订单,将订单信息保存到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;
 }

仅此供给大家,在大家有这方面的需求时,少走弯路!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现微信H5支付方法详解

    前面做了app微信支付的回调处理,现在需要做微信公众号的支付,花了一天多时间,终于折腾出来了!鉴于坑爹的微信官方没有提供Java版的demo,所以全靠自己按照同样坑爹的文档敲敲敲,所以记录下来,以供自己及后来人参考,不足之处,还请指正. 首先,我们贴出调用支付接口的H5页面,当然,在这个页面之前,还需要做很多其他的操作,我们一步一步的来. 坑爹的官方文档给了两个不同的支付接口,在微信公众平台开发中文档的"微信JS-SDK说明文档"中,给出的支付方式是下面被屏蔽的那一部分,而在商户平台的

  • java服务端微信APP支付接口详解

    一.微信APP支付接入商户服务中心 [申请流程指引] (https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317780&token=84f23b4e9746c5963128711f225476cfd49ccf8c&lang=zh_CN) 二.开始开发 1.配置相关的配置信息 1.1.配置appid(Androi

  • 详解java集成支付宝支付接口(JSP+支付宝20160912)

    吐槽一下: 支付宝的接口和微信的DEMO和文档真心太难看懂了,乱七八糟,都不知道去哪里找自己要的东西,最近几天我们公司需要做类似的开发,我作为先锋,率先解决Java集成支付宝支付和微信支付接口工作. 我们的工作环境:JSP网站+支付接口,目前工作的支付宝接口为20160912,微信为V3版本,如遇到版本升级,请联系相关机构的客户服务人员升级. 本文介绍JSP+支付宝接口,本文非原创. 新手注意: 1.本文使用的接口地址和参数为沙箱的地址,无论你在使用沙箱或者正式地址,务必核实使用接口地址和参数,

  • 微信支付H5调用支付详解(java版)

    最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一.配置公众号微信支付  需要我们配置微信公众号支付地址和测试白名单. 比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/ 那此处配置www.xxx.com/shop/pay/ 二.开发流程 借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/d

  • java开发微信公众号支付

    最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时间,也只是达到了实现功能的水平,并没有太多考虑到性能问题,所以这篇文章比较适合初学者. 微信公众号支付的总体其实很简单,大致就分为三步.第一步需要获取用户授权:第二步调用统一下单接口获取预支付id:第三步H5调起微信支付的内置的js.下面介绍具体每一步的开发流程. 一    首先要明确微信公众号支付属于网页版支付,所以相较于app的直接调取微信支付要多一步微信授权.也就是需要获取用户的openid.微信公众号使用的交易类型是JSAPI,

  • java后台实现支付宝支付接口和支付宝订单查询接口(前端为APP)

    最近项目APP需要接入微信.支付宝支付功能,在分配开发任务时,听说微信支付接口比支付宝支付接口要难实现,由于我开发经验不是那么丰富(现工作经验1年半)且未接触过支付接口开发,组里刚好又有支付接口的老司机,所以很自然把简单的支付宝接口开发任务交给了我,看来开发组的组长还是很好人的嘛.....,废话就不多说了,我们开始吧! 实现支付宝接口详细过程 1.去支付宝官网申请公司企业账号并开通一个应用,在应用里签约APP支付功能 具体的申请截图步骤,在这里我就不详细说了,因为这不是文章的重点,可参考支付宝官

  • Java微信支付之公众号支付、扫码支付实例

    微信支付现在已经变得越来越流行了,随之也出现了很多以可以快速接入微信支付为噱头的产品,不过方便之余也使得我们做东西慢慢依赖第三方,丧失了独立思考的能力,这次打算分享下我之前开发过的微信支付. 一 .H5公众号支付 要点:正确获取openId以及统一下单接口,正确处理支付结果通知,正确配置支付授权目录 H5的支付方式是使用较为广泛的方式,这种支付方式主要用于微信内自定义菜单的网页,依赖手机上安装的微信客户端,高版本的微信才支持微信支付,下面按我的流程注意说明 1  编写用于支付的页面,由于是测试用

  • 微信小程序 支付后台java实现实例

    微信小程序 支付后台java实现实例 前言: 前些天使用 LeanCloud 云引擎写了个小程序的支付相关 以前只做过 APP 支付 这次在小程序支付爬了两天的坑 把代码也分享出来 支付流程: 1.小程序前端获取微信 openId 以及订单号 传给后台 2,后台根据 openId 和订单号进行签名 post 微信统一下单接口 3.后台获取微信返回的xml字符串 解析 二次签名以后返回给前端 4.前端调起支付微信支付 API 先看支付函数: //获取支付信息 @EngineFunction("ge

  • Java实现支付宝之第三方支付宝即时到账支付功能

    alipay 的几个内核功能文件: AlipayFunction.java package com.test.util.alipay; import java.io.FileWriter; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import ja

  • Java通过JsApi方式实现微信支付

    要使用JsApi进行微信支付,首先要从微信获得一个prepay_id,然后通过调用微信的jsapi完成支付,JS API的返回结果get_brand_wcpay_request:ok仅在用户成功完成支付时返回.由于前端交互复杂,get_brand_wcpay_request:cancel或者get_brand_wcpay_request:fail可以统一处理为用户遇到错误或者主动放弃,不必细化区分. 示例代码如下: function onBridgeReady(){ WeixinJSBridge

随机推荐