近期项目要求打通支付宝支付和微信支付,所以趟了一趟接入支付的浑水:

支付宝接入流程

微信支付流程

分析完之后就对照官方的文档开始行动了

一:支付宝支付

  1. 打开支付宝
  2. 选择商家平台
  3. 选择手机网站支付如下操作

https://b.alipay.com/signing/productDetail.htm?productId=I1011000290000001001

选择手机网站支付,填写资料

填写后等待审核通过

然后进入开放平台->开发者中心->网页&移动应用,

然后创建应用

然后点击进入查看详情

然后添加手机网站支付功能

然后点击应用信息访问进行开发配置

在配置上图的回调地址和密钥,接下来就是开发了

这里有官方的demo

https://docs.open.alipay.com/270/106291/

二 、微信支付

接下来介绍微信支付,微信支付没有官方的demo

比较蛋疼,踩过很多的坑

支付宝支付相对接入比较容易,微信支付需要分微信内打开和微信外打开,微信内走公众号支付,微信外走H5支付,刚开始接入的时候发现H5链接在微信内打开支付不了才知道微信内强制走的是公众号支付,这一点不知道可能让你的功能在提测的时候不通过,或者延期

先到微信公众平台

申请开通公众号支付和H5支付

然后配置

添加公众号授权,然后就是接入开发了

微信或者支付宝下单/支付回调

PayController.java

package com.lebo.pay.controller;import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import com.alibaba.fastjson.JSON;
import com.lebo.pay.controller.BaseController;
import com.lebo.pay.entity.OpenIdClass;
import com.lebo.pay.entity.Order;
import com.lebo.pay.entity.WechatUnifiedOrder;
import com.lebo.pay.service.AlipayTradeService;
import com.lebo.pay.service.WechatTradeService;
import com.lebo.pay.service.impl.OrderService;
import com.lebo.util.PageData;
import com.lebo.util.RedisUtil;
import com.lebo.util.ResultUtil;
import com.lebo.util.StatusEnum;
import com.lebo.util.StringUtil;
import com.lebo.util.UIDUtil;
import com.lebo.util.XmlUtil;/*** * @ClassName:  PayController   * @author chenrui* @QQ: 914221084* @date:   2018年6月12日 下午8:46:18   */
@Controller
@RequestMapping("/pay")
public class PayController extends BaseController{private static Logger logger = Logger.getLogger(PayController.class);@Autowiredprivate AlipayTradeService alipayTradeService; @Autowiredprivate WechatTradeService wechatTradeService; @Autowiredprivate OrderService orderService; /** 微信或者支付宝支付下单*/@RequestMapping(value="/unifiedOrder")@ResponseBodypublic Object unifiedOrder(Order order,Model model){ResultUtil reUtil = new ResultUtil(StatusEnum.SUCCESS.getCode(), StatusEnum.SUCCESS.getMessage());String outTradeNo = order.getOutTradeNo();if(StringUtils.isBlank(outTradeNo)){reUtil.setCodeAndMessage(StatusEnum.ORDERNO_IS_CANNOT_NULL.getCode(), StatusEnum.ORDERNO_IS_CANNOT_NULL.getMessage());return reUtil;}if("P".equals(RedisUtil.getStr(outTradeNo+"status"))){reUtil.setCodeAndMessage(StatusEnum.ORDER_HAVE_PAY.getCode(), StatusEnum.ORDER_HAVE_PAY.getMessage());return reUtil;}order.setStatus("w");if("w".equals(RedisUtil.getStr(outTradeNo+"status"))){String orderStr = (String) RedisUtil.getStr("order"+outTradeNo);if(StringUtils.isNoneBlank(orderStr)){TreeMap<String,String> prepareH5Pay = (TreeMap<String, String>) JSON.parseObject(orderStr, TreeMap.class);reUtil.setData(prepareH5Pay);return reUtil;}}if(StringUtils.isNotBlank(order.getIp())){if(StringUtil.isInnerIp(order.getIp())){reUtil.setCodeAndMessage(StatusEnum.IP_IS_WRONG.getCode(), StatusEnum.IP_IS_WRONG.getMessage());}}if(RedisUtil.tryLock(outTradeNo,15)){try {if(StringUtils.isBlank(order.getPayType())){order.setPayType("weChat");}order.setPayId(UIDUtil.getUUID());orderService.insertOrder(order);RedisUtil.putObj("order"+outTradeNo,JSON.toJSONString(order),(int) TimeUnit.DAYS.toSeconds(10));} catch (Exception e1) {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_FAIL.getCode(), StatusEnum.PREPARORDER_FAIL.getMessage());logger.error("支付失败:params"+JSON.toJSONString(order)+","+e1.getMessage());return reUtil;}if("weChat".equals(order.getPayType())){WechatUnifiedOrder wechatOrder = new WechatUnifiedOrder();String isWxbrowser = (String) getRequest().getParameter("isWxbrowser");if("true".equals(isWxbrowser)){String code = (String) getRequest().getParameter("code");logger.info("支付失败:code="+code+"isWxbrowser="+isWxbrowser);wechatOrder.setTrade_type("JSAPI");try {OpenIdClass openData  = wechatTradeService.getOpenId(code);if(openData==null){reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_FAIL.getCode(), StatusEnum.PREPARORDER_FAIL.getMessage());return reUtil;}wechatOrder.setOpenid(openData.getOpenid());} catch (Exception e) {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_FAIL.getCode(), StatusEnum.PREPARORDER_FAIL.getMessage());logger.error("获取openid失败:params"+JSON.toJSONString(order)+","+e.getMessage());return reUtil;}}wechatOrder.setBody(order.getBody());wechatOrder.setDetail(order.getDetail());wechatOrder.setGoods_tag(order.getGoodsTag());wechatOrder.setOut_trade_no(outTradeNo);wechatOrder.setFee_type("CNY");wechatOrder.setTotal_fee((int)(order.getTotalAmount()*100));if(StringUtils.isBlank(order.getIp())){wechatOrder.setSpbill_create_ip("119.139.197.202");}else{wechatOrder.setSpbill_create_ip(order.getIp());}wechatOrder.setTime_start(System.currentTimeMillis()+"");wechatOrder.setLimit_pay("cera");wechatOrder.setTime_expire(order.getTimeExpire());//TODO  生成预付单   try {TreeMap<String,String> data = wechatTradeService.unifiedOrderRequest(wechatOrder);if(data!=null) {reUtil.setData(data);}else {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_FAIL.getCode(), StatusEnum.PREPARORDER_FAIL.getMessage());}} catch (Exception e) {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_EXCEPTION.getCode(), StatusEnum.PREPARORDER_EXCEPTION.getMessage());logger.error("支付失败:params"+JSON.toJSONString(order)+","+e.getMessage());}}else{try {Map<String,String> paraMap = new HashMap<String,String>();paraMap.put("out_trade_no",outTradeNo);paraMap.put("total_amount",String.valueOf(order.getTotalAmount()));paraMap.put("subject",order.getBody());paraMap.put("body",order.getDetail());paraMap.put("product_code","QUICK_WAP_PAY");String resultStr = alipayTradeService.TradeWapPayRequest(paraMap);if(resultStr!=null) {reUtil.setData(resultStr);}else {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_FAIL.getCode(), StatusEnum.PREPARORDER_FAIL.getMessage());}} catch (Exception e) {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_EXCEPTION.getCode(), StatusEnum.PREPARORDER_EXCEPTION.getMessage());logger.error("支付失败:params"+JSON.toJSONString(order)+","+e.getMessage());}} }else{reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_IS_PRODUCTING.getCode(), StatusEnum.PREPARORDER_IS_PRODUCTING.getMessage());}logger.info("接口結果:json:"+JSON.toJSONString(reUtil));return  reUtil;}/** 微信支付成功回调*/@RequestMapping(value="/wechatNotify")@ResponseBodypublic Object wechatNotify(HttpServletRequest request){PageData pd = new PageData(request);Map<String,String> return_data = new HashMap<String,String>();try {logger.info("access to wechatNotify");if(wechatTradeService.verifyNotify(request)) {return_data.put("return_code", "SUCCESS");  return_data.put("return_msg", "OK");  }else {return_data.put("return_code", "FAIL");  return_data.put("return_msg", "return_code不正确");  }} catch (Exception e) {return_data.put("return_code", "FAIL");  return_data.put("return_msg", "支付回调异常");  logger.error("支付失败:params"+JSON.toJSONString(pd)+","+e.getMessage());}return  XmlUtil.GetMapToXML(return_data);}/** 支付宝支付成功回调*/@RequestMapping(value="/alipayNotify")@ResponseBodypublic Object alipayNotify(HttpServletRequest request){PageData pd = new PageData(request);logger.info("access to alipayNotify");String result = "success";try {if(alipayTradeService.verifyNotify(request)) {logger.info("支付成功:params"+JSON.toJSONString(pd));}else {result = "fail";logger.error("支付失败:params"+JSON.toJSONString(pd)+",支付回调失败");}} catch (Exception e) {result = "fail";logger.error("支付失败:params"+JSON.toJSONString(pd)+","+e.getMessage());}return  result;}/** 获取公众号相关的用户信息*/@RequestMapping(value="/getOpenid")@ResponseBodypublic Object getOpenid(HttpServletRequest request){PageData pd = new PageData(request);ResultUtil reUtil = new ResultUtil(StatusEnum.SUCCESS.getCode(), StatusEnum.SUCCESS.getMessage());Map<String, Object> data = new HashMap<String, Object>();logger.info("access to getOpenid");String url = request.getRequestURI();logger.info("request url : " + url);Enumeration<String> em = request.getParameterNames();while (em.hasMoreElements()) {String nameParam = em.nextElement();String valueParam = request.getParameter(nameParam);data.put(nameParam, valueParam);logger.info(nameParam + " = " + valueParam);}String result = "success";try {if(StringUtils.isBlank(pd.getString("code"))){reUtil.setCodeAndMessage(StatusEnum.VALIDATION_FAIL.getCode(), StatusEnum.VALIDATION_FAIL.getMessage());return reUtil;}OpenIdClass openData  = wechatTradeService.getOpenId(pd.getString("code"));if(openData!=null) {data.put("openid", openData.getOpenid());data.put("access_token", openData.getAccess_token());data.put("refresh_token", openData.getRefresh_token());data.put("scope", openData.getScope());data.put("unionid", openData.getUnionid());reUtil.setData(data);}else {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_FAIL.getCode(), StatusEnum.PREPARORDER_FAIL.getMessage());}} catch (Exception e) {reUtil.setCodeAndMessage(StatusEnum.PREPARORDER_EXCEPTION.getCode(), StatusEnum.PREPARORDER_EXCEPTION.getMessage());logger.error("获取openId失败:params"+JSON.toJSONString(pd)+","+e.getMessage());}return  result;}/** 获取订单状态*/@RequestMapping(value="/getOrderStatus")@ResponseBodypublic Object getOrderStatus(HttpServletRequest request){PageData pd = new PageData(request);ResultUtil reUtil = new ResultUtil(StatusEnum.SUCCESS.getCode(), StatusEnum.SUCCESS.getMessage());Map<String, Object> data = new HashMap<String, Object>();String outTradeNo = pd.getString("outTradeNo");if(StringUtils.isBlank(pd.getString("outTradeNo"))){reUtil.setCodeAndMessage(StatusEnum.VALIDATION_FAIL.getCode(), StatusEnum.VALIDATION_FAIL.getMessage());return reUtil;}data.put("status", RedisUtil.getStr(outTradeNo+"status"));reUtil.setData(data);return  reUtil;}}

微信支付service

WechatTradeServiceImpl .java

package com.lebo.pay.service.impl;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.lebo.pay.config.WechatConfig;
import com.lebo.pay.entity.AccessToken;
import com.lebo.pay.entity.OpenIdClass;
import com.lebo.pay.entity.Order;
import com.lebo.pay.entity.WechatPayNotify;
import com.lebo.pay.entity.WechatRefund;
import com.lebo.pay.entity.WechatRefundQuery;
import com.lebo.pay.entity.WechatUnifiedOrder;
import com.lebo.pay.entity.WxTicket;
import com.lebo.pay.service.WechatTradeService;
import com.lebo.util.HttpUtil;
import com.lebo.util.RedisUtil;
import com.lebo.util.SignUtil;
import com.lebo.util.WebUtils;
import com.lebo.util.XmlUtil;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;import javax.servlet.http.HttpServletRequest;/*** 微信交易* @author chenrui* @date 2018/06/11*/
@Service
public class WechatTradeServiceImpl implements WechatTradeService{private static Logger logger = LoggerFactory.getLogger(WechatTradeServiceImpl.class);@Autowiredprivate OrderService orderService; /*** 微信统一下单* @param unifiedOrder 要下单的内容* @return 返回H5下单请求需要内容*/public TreeMap<String,String> unifiedOrderRequest(WechatUnifiedOrder unifiedOrder){WechatUnifiedOrder.Response response =  WechatConfig.getInstance().unifiedOrder(unifiedOrder);if (response.getResult_code().equals(WechatConfig.SUCCESS_REQUEST)){TreeMap<String,String> prepareH5Pay = new TreeMap<String, String>();prepareH5Pay.put("appId", WechatConfig.APP_ID);prepareH5Pay.put("nonceStr", WechatConfig.getInstance().nonce_str(16));if("JSAPI".equals(unifiedOrder.getTrade_type())){prepareH5Pay.put("package", "prepay_id="+response.getPrepay_id());}else{prepareH5Pay.put("partnerId", WechatConfig.MCH_ID);prepareH5Pay.put("package", "Sign=WXPay");prepareH5Pay.put("prepayId",response.getPrepay_id());}prepareH5Pay.put("signType", "MD5");prepareH5Pay.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));prepareH5Pay.put("sign", WechatConfig.getInstance().sign(prepareH5Pay));prepareH5Pay.put("mweburl",response.getMweb_url());RedisUtil.putObj("order"+unifiedOrder.getOut_trade_no(), JSON.toJSONString(prepareH5Pay), 120);RedisUtil.putObj(unifiedOrder.getOut_trade_no()+"status", "w", 120);return prepareH5Pay;}return null;}/*** 微信退款请求* @param refund 退款请求参数* @return 返回参数(同步接口,直接返回),只有return_code和result_code都成功则退款成功*/public WechatRefund.Response refundRequest(WechatRefund refund){WechatRefund.Response response = WechatConfig.getInstance().refund(refund);return response;}/*** 微信退款查询请求* @param refund 退款请求参数* @return 返回参数(同步接口,直接返回),只有return_code和result_code都成功则查询成功*/public WechatRefundQuery.Response refundQueryRequest(WechatRefundQuery refund){WechatRefundQuery.Response response = WechatConfig.getInstance().refundQuery(refund);return response;}/*** 微信回调验签* @param request  回调请求* @return true成功*/@SuppressWarnings("unchecked")public boolean verifyNotify(HttpServletRequest request){try {InputStream inputStream = request.getInputStream();WechatPayNotify notice = XmlUtil.xmlToBean(inputStream, WechatPayNotify.class);//更新预付单状态if (notice == null) return false;logger.debug("微信回调参数:"+ JSON.toJSONString(notice));String sign = WechatConfig.getInstance().sign(SignUtil.bean2TreeMap(notice));boolean ischeck = sign.equals(notice.getSign());if(ischeck){RedisUtil.putObj(notice.getOut_trade_no()+"status", "P",(int) TimeUnit.DAYS.toSeconds(10));Order order = new Order();order.setOutTradeNo(notice.getOut_trade_no());order.setStatus("p");try {orderService.updateOrder(order);order = (Order) RedisUtil.getObj("order"+notice.getOut_trade_no());if(order==null){order =orderService.getOrder(notice.getOut_trade_no());}Map<String,Object>  parameterMap = new HashMap<String,Object>();parameterMap.put("outTradeNo", notice.getOut_trade_no());parameterMap.put("userId",order.getUserId());parameterMap.put("payType","weChat");String result = WebUtils.post(order.getNotifyUrl(), parameterMap);Map<String,String> resultMap = (Map<String, String>) JSON.parseObject(result, Map.class);logger.info(order.getNotifyUrl()+"接口結果:json:"+JSON.toJSONString(result));if("00".equals(resultMap.get("code"))){ischeck = true;}else{ischeck = false;}} catch (Exception e) {logger.error("订单更新失败:"+ JSON.toJSONString(notice));ischeck = false;}logger.debug("微信验签结果:"+ischeck);}return ischeck;} catch (IOException e) {e.printStackTrace();}return false;}// 获取access_token的接口地址(GET) 限200(次/天)  public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";  public final static String ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card";  public final static String auth_url = "https://api.weixin.qq.com/card/invoice/getauthurl?access_token=ACCESS_TOKEN";  /** * 获取access_token *  * @param appid 凭证 * @param appsecret 密钥 * @return */  public static AccessToken getAccessToken() {  AccessToken accessToken = null;  String requestUrl = ticket_url.replace("ACCESS_TOKEN", WechatConfig.APP_ID).replace("APPSECRET", WechatConfig.APP_SECRET);  String jsonStr = WebUtils.get(requestUrl, null) ;// 如果请求成功  if (null != jsonStr) {  try {  JSONObject jsonObject = JSONObject.parseObject(jsonStr);accessToken = new AccessToken();  accessToken.setToken(jsonObject.getString("access_token"));  accessToken.setExpiresIn(jsonObject.getIntValue("expires_in"));  } catch (JSONException e) {  accessToken = null;  // 获取token失败  logger.error("获取token失败 errcode:{} errmsg:{}",jsonStr);  }  }  return accessToken;  }  public static WxTicket getTickect(AccessToken  accessToken) {  WxTicket wxTicket = null;  if(accessToken==null){logger.error("获取wxTicket失败 ");  return wxTicket;}String requestUrl = ticket_url.replace("ACCESS_TOKEN", accessToken.getToken());  String jsonStr = WebUtils.get(requestUrl, null) ;// 如果请求成功  if (null != jsonStr) {  try {  JSONObject jsonObject = JSONObject.parseObject(jsonStr);wxTicket = new WxTicket();  wxTicket.setTicket(jsonObject.getString("ticket")); wxTicket.setExpiresIn(jsonObject.getIntValue("expires_in"));  } catch (JSONException e) {  wxTicket = null;  // 获取token失败  logger.error("获取token失败 errcode:{} errmsg:{}",jsonStr);  }  }  return wxTicket;  }  public String  getAuth(Order order) {  String auth = null;  AccessToken accessToken = getAccessToken();  WxTicket wxTicket = getTickect(accessToken) ;if(wxTicket==null){logger.error("获取wxTicket失败 ");  return auth;}String requestUrl = auth_url.replace("ACCESS_TOKEN", accessToken.getToken());  Map<String, Object> params = new HashMap<String, Object>();params.put("s_pappid", "");//开票平台在微信的标识号,商户需要找开票平台提供params.put("order_id", order.getOutTradeNo());//订单id,在商户内单笔开票请求的唯一识别号,params.put("money", (int)(order.getTotalAmount()*100));//订单金额,以分为单位params.put("timestamp", String.valueOf(System.currentTimeMillis() /1000));//时间戳params.put("source", "wap");//开票来源,app:app开票,web:微信h5开票,wxa:小程序开发票,wap:普通网页开票params.put("redirect_url", "");//授权成功后跳转页面。本字段只有在source为H5的时候需要填写,引导用户在微信中进行下一步流程。app开票因为从外部app拉起微信授权页,授权完成后自动回到原来的app,故无需填写。params.put("ticket", wxTicket.getTicket());//从上一环节中获取params.put("type", "1");//授权类型,0:开票授权,1:填写字段开票授权,2:领票授权String jsonStr = WebUtils.post(requestUrl, params);// 如果请求成功  if (null != jsonStr) {  try {  JSONObject jsonObject = JSONObject.parseObject(jsonStr);auth = jsonObject.getString("auth_url");} catch (JSONException e) {  wxTicket = null;  // 获取token失败  logger.error("获取auth失败 errcode:{} errmsg:{}",jsonStr);  }  }  return auth;  }  @Overridepublic OpenIdClass getOpenId(String code) throws Exception {logger.info("************************getOpenId*********************");logger.info("+++++++++++" + code + "++++++++++");if (code != null) {// 狗日的微信又是必须要https请求,千万不要搞错了String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"+ "appid="+WechatConfig.APP_ID+ "&secret="+WechatConfig.OFFICAL_ACCOUNT_SECRET + "&code="+ code + "&grant_type=authorization_code";logger.info("url="+url);String returnData = HttpUtil.loadJSON(url);logger.info("returnData="+returnData + "################");OpenIdClass  openIdClass  = JSON.parseObject(returnData,OpenIdClass.class);  if (openIdClass.getOpenid() != null) {return openIdClass;}}return null;}}

支付宝支付service

AlipayTradeServiceImpl.java

package com.lebo.pay.service.impl;import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.lebo.pay.config.AliPayConfig;
import com.lebo.pay.entity.Order;
import com.lebo.pay.service.AlipayTradeService;
import com.lebo.util.RedisUtil;
import com.lebo.util.SignUtil;
import com.lebo.util.WebUtils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;import javax.servlet.http.HttpServletRequest;/*** 支付宝交易类* @author chenrui* @date 2018/06/11*/
@Service
public class AlipayTradeServiceImpl  implements  AlipayTradeService{private Logger logger = LoggerFactory.getLogger(AlipayTradeServiceImpl.class);@Autowiredprivate OrderService orderService; /*** web支付下单并支付(web支付在安卓中是可以直接唤醒支付宝APP的)* url https://doc.open.alipay.com/doc2/detail.htm?treeId=203&articleId=105463&docType=1#s1* @return web支付的表单*/public String TradeWapPayRequest(Map<String, String> sParaTemp){AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();alipayRequest.setReturnUrl(AliPayConfig.RETURN_URL);alipayRequest.setNotifyUrl(AliPayConfig.PAY_NOTIFY);// 待请求参数数组sParaTemp.put("seller_id",AliPayConfig.SELLER_ID);alipayRequest.setBizContent(JSON.toJSONString(sParaTemp));String form = "";try {form = AliPayConfig.getInstance().pageExecute(alipayRequest).getBody();} catch (AlipayApiException e) {logger.error("支付宝构造表单失败",e);}logger.debug("支付宝支付表单构造:"+form);return form;}/*** 申请退款* @param sParaTemp 退款参数* @return true成功,回调中处理* 备注:https://doc.open.alipay.com/docs/api.htm?spm=a219a.7629065.0.0.3RjsEZ&apiId=759&docType=4*/public boolean tradeRefundRequest(Map<String, ?> sParaTemp) throws AlipayApiException {AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();request.setReturnUrl(AliPayConfig.RETURN_URL);request.setNotifyUrl(AliPayConfig.REFUND_NOTIFY);// 待请求参数数组request.setBizContent(JSON.toJSONString(sParaTemp));AlipayTradeRefundResponse response = AliPayConfig.getInstance().execute(request);logger.debug("支付宝退货结果:"+response.isSuccess());return response.isSuccess();}/*** 支付宝回调验签* @param request 回调请求* @return true成功* 备注:验签成功后,按照支付结果异步通知中的描述(二次验签接口,貌似称为历史接口了)*/public boolean verifyNotify(HttpServletRequest request) throws AlipayApiException {Map<String,String> paranMap = SignUtil.request2Map(request);logger.debug("支付宝回调参数:"+paranMap.toString());boolean isVerify = false;if (AliPayConfig.SUCCESS_REQUEST.equals(paranMap.get("trade_status")) || AliPayConfig.TRADE_CLOSED.equals(paranMap.get("trade_status"))) {isVerify = AlipaySignature.rsaCheckV1(paranMap, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.CHARSET,AliPayConfig.SIGN_TYPE); //调用SDK验证签名if(isVerify){String orderNo = paranMap.get("out_trade_no");RedisUtil.putObj(orderNo+"status", "P",(int) TimeUnit.DAYS.toSeconds(10));Order order = new Order();order.setOutTradeNo(orderNo);order.setStatus("p");try {orderService.updateOrder(order);order = (Order) RedisUtil.getObj("order"+orderNo);if(order==null){order =orderService.getOrder(orderNo);}Map<String,Object>  parameterMap = new HashMap<String,Object>();parameterMap.put("outTradeNo", orderNo);parameterMap.put("userId",order.getUserId());parameterMap.put("payType","alipay");String result = WebUtils.post(order.getNotifyUrl(), parameterMap);logger.info(order.getNotifyUrl()+"接口結果:json:"+JSON.toJSONString(result));Map<String,String> resultMap = (Map<String, String>) JSON.parseObject(result, Map.class);if("00".equals(resultMap.get("code"))){isVerify =true;}else{isVerify =false;}}catch(Exception e){logger.error("verifyNotify error:"+e.getMessage());isVerify =false;}}}logger.debug("支付宝验签结果"+isVerify);return isVerify;}
}

支付宝下单后生产预付单,接口会生成form数据,通过js自动提交(<form> ...submit</form>)

微信支付分为H5支付和公众号支付

H5支付在微信内是不能支付支付成功的,微信会强制在微信内用微信公众号支付,这样就少不了走公众号支付那一套,这里严重吐槽一下,

进入前页面后要判断是在微信内还是为微信外,微信内就要用

http://open.weixin.qq.com/connect/oauth2/authorize拿取授权码,因为公众号支付需要openId,而openId需要通过授权code获得,拿到授权code就可以调用jssdk支付了,在微信外走H5支付为调用接口生成预付单后微信会生成一个字段mweburl,这个是一个url,通过这个地址就可以唤起微信支付了,但是要传入refer如果你直接点击能想办法传过去也是可以的,我这里采用的方法是在页面内绑定点击事件,它传过去的时候就会解析到refer了,不传的话会报商家配置参数有误,

然后贴上html代码,供大家参考

wxpayDemo2.html(微信支付(融合H5支付、公众号支付))

<!DOCTYPE html>
<html><head><title>微信手机网站支付接口页面demo</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>*{margin:0;padding:0;}ul,ol{list-style:none;}body{font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;}.hidden{display:none;}.new-btn-login-sp{padding: 1px;display: inline-block;width: 75%;}.new-btn-login {background-color: #02aaf1;color: #FFFFFF;font-weight: bold;border: none;width: 100%;height: 30px;border-radius: 5px;font-size: 16px;}#main{width:100%;margin:0 auto;font-size:14px;}.red-star{color:#f00;width:10px;display:inline-block;}.null-star{color:#fff;}.content{margin-top:5px;}.content dt{width:100px;display:inline-block;float: left;margin-left: 20px;color: #666;font-size: 13px;margin-top: 8px;}.content dd{margin-left:120px;margin-bottom:5px;}.content dd input {width: 85%;height: 28px;border: 0;-webkit-border-radius: 0;-webkit-appearance: none;}#foot{margin-top:10px;position: absolute;bottom: 15px;width: 100%;}.foot-ul{width: 100%;}.foot-ul li {width: 100%;text-align:center;color: #666;}.note-help {color: #999999;font-size: 12px;line-height: 130%;margin-top: 5px;width: 100%;display: block;}#btn-dd{margin: 20px;text-align: center;}.foot-ul{width: 100%;}.one_line{display: block;height: 1px;border: 0;border-top: 1px solid #eeeeee;width: 100%;margin-left: 20px;}.am-header {display: -webkit-box;display: -ms-flexbox;display: box;width: 100%;position: relative;padding: 7px 0;-webkit-box-sizing: border-box;-ms-box-sizing: border-box;box-sizing: border-box;background: #1D222D;height: 50px;text-align: center;-webkit-box-pack: center;-ms-flex-pack: center;box-pack: center;-webkit-box-align: center;-ms-flex-align: center;box-align: center;}.am-header h1 {-webkit-box-flex: 1;-ms-flex: 1;box-flex: 1;line-height: 18px;text-align: center;font-size: 18px;font-weight: 300;color: #fff;}
</style>
</head>
<script src="./js/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="./js/qrcode.min.js" type="text/javascript"></script><div style="display: none;margin-top: 20px;"><a id="getBrandWCPayRequest" href="#" style="font-size:40px;">H5非微信app支付</a>移动端,非微信app使用<br>
</div><div id="qrcode" style="display: none;margin-top: 20px;"><a id="getBrandWCPayRequest" href="#" style="font-size:40px;">H5非微信app支付</a>移动端,非微信app使用<br>
</div>
<script>var appId = "";var timeStamp = "";var nonceStr = "";var pg = "";var signType = "";var paySign = "";var openid = "";var code  = "";function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } function getOpenId(){var isWxbrowser = isWeiXin();if(isWxbrowser){code = getQueryString("code")if(code==null||code==undefined||code==""){//获取openidwindow.location.href="http://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxx&redirect_uri=http://xxx/payDemo/wxpayDemo2.html&response_type=code&scope=snsapi_base&state=wxpay#wechat_redirect";}}}$(function(){getOpenId();})function createWxH5Pay(){var isWxbrowser = isWeiXin();var data = "body="+$("#body1").val()+"&detail="+$("#detail").val()+"&outTradeNo="+$("#outTradeNo").val()+"&totalAmount="+$("#totalAmount").val()+"&payType="+$("#payType").val()+"&isWxbrowser="+isWxbrowser+"&code="+code;var outTradeNo = $("#outTradeNo").val();if(outTradeNo==null||outTradeNo==undefined||outTradeNo==""){//处理alert("商户订单号不能为空");return;}var body1 = $("#body1").val();if(body1==null||body1==undefined||body1==""){//处理alert("订单名称不能为空");return;}var totalAmount = $("#totalAmount").val();if(totalAmount==null||totalAmount==undefined||totalAmount==""){//处理alert("付款金额不能为空");return;}var detail = $("#detail").val();if(detail==null||detail==undefined||detail==""){//处理alert("商品描述不能为空");return;}$.ajax({url: '/payDemo/pay/unifiedOrder.do',type: 'post',cache:false,async:false,data:  data,dataType: 'JSON',timeout: 5000,success: function(data){console.log("data="+data.prepayid);if(data!=null){if(data.code!="00")alert(data.code+data.message);appId = data.data.appId;timeStamp = data.data.timeStamp;nonceStr = data.data.nonceStr;pg =  data.data.package;signType = "MD5";paySign = data.data.sign;if(!isWeiXin()){$("#getBrandWCPayRequest").attr("href",data.data.mweburl);document.getElementById("getBrandWCPayRequest").click();}else{pay();}}}});}function isWeiXin(){var ua = window.navigator.userAgent.toLowerCase();if(ua.match(/MicroMessenger/i) == 'micromessenger'){return true;}else{return false;}}//开始支付function onBridgeReady(){console.log("-------------------------------->>>>:")WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId" : appId,     //公众号名称,由商户传入"timeStamp": timeStamp+"",         //时间戳,自1970年以来的秒数"nonceStr" : nonceStr, //随机串"package" : pg,"signType" : signType,         //微信签名方式:"paySign" : paySign    //微信签名},function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ) {alert("支付成功");  // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。}else if (res.err_msg == "get_brand_wcpay_request:cancel")  {alert("支付过程中用户取消");}else{//支付失败// alert("appId="+appId+",timestamp="+timeStamp+",nonceStr="+nonceStr+",package="+pg+",signType="+signType+",paySign="+paySign);alert(res.err_msg)}});}//唤起微信支付function pay(){if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);}else if (document.attachEvent){document.attachEvent('WeixinJSBridgeReady', onBridgeReady);document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);}}else{onBridgeReady();}}</script><body text=#000000 bgColor="#ffffff" leftMargin=0 topMargin=4>
<header class="am-header"><h1>微信手机网站支付接口快速通道</h1>
</header>
<div id="main"><div id="body" style="clear:left"><dl class="content"><dt>商户订单号(*):</dt><dd><input id="outTradeNo" name="outTradeNo" /></dd><hr class="one_line"><dt>订单名称(*):</dt><dd><input id="body1" name="body1" /></dd><hr class="one_line"><dt>付款金额(*):</dt><dd><input id="totalAmount" name="totalAmount" /></dd><hr class="one_line"/><dt>商品描述(*):</dt><dd><input id="detail" name="detail" /></dd><dt></dt><dd><input type="hidden"  id="payType" name="payType" value="weChat" /></dd><hr class="one_line"><dt></dt><dd id="btn-dd"><span class="new-btn-login-sp"><button class="new-btn-login"  onclick='createWxH5Pay(this);'  style="text-align:center;">确 认</button></span><span class="note-help">如果您点击“确认”按钮,即表示您同意该次的执行操作。</span></dd></dl></div><div id="foot"><ul class="foot-ul"><li>深圳市xxxxx公司版权所有  2015-2018 </li></ul></div></div>
</body></html>

alipayDemo.html(支付宝支付)

<!DOCTYPE html>
<html><head><title>支付宝手机网站支付接口</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>*{margin:0;padding:0;}ul,ol{list-style:none;}body{font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;}.hidden{display:none;}.new-btn-login-sp{padding: 1px;display: inline-block;width: 75%;}.new-btn-login {background-color: #02aaf1;color: #FFFFFF;font-weight: bold;border: none;width: 100%;height: 30px;border-radius: 5px;font-size: 16px;}#main{width:100%;margin:0 auto;font-size:14px;}.red-star{color:#f00;width:10px;display:inline-block;}.null-star{color:#fff;}.content{margin-top:5px;}.content dt{width:100px;display:inline-block;float: left;margin-left: 20px;color: #666;font-size: 13px;margin-top: 8px;}.content dd{margin-left:120px;margin-bottom:5px;}.content dd input {width: 85%;height: 28px;border: 0;-webkit-border-radius: 0;-webkit-appearance: none;}#foot{margin-top:10px;position: absolute;bottom: 15px;width: 100%;}.foot-ul{width: 100%;}.foot-ul li {width: 100%;text-align:center;color: #666;}.note-help {color: #999999;font-size: 12px;line-height: 130%;margin-top: 5px;width: 100%;display: block;}#btn-dd{margin: 20px;text-align: center;}.foot-ul{width: 100%;}.one_line{display: block;height: 1px;border: 0;border-top: 1px solid #eeeeee;width: 100%;margin-left: 20px;}.am-header {display: -webkit-box;display: -ms-flexbox;display: box;width: 100%;position: relative;padding: 7px 0;-webkit-box-sizing: border-box;-ms-box-sizing: border-box;box-sizing: border-box;background: #1D222D;height: 50px;text-align: center;-webkit-box-pack: center;-ms-flex-pack: center;box-pack: center;-webkit-box-align: center;-ms-flex-align: center;box-align: center;}.am-header h1 {-webkit-box-flex: 1;-ms-flex: 1;box-flex: 1;line-height: 18px;text-align: center;font-size: 18px;font-weight: 300;color: #fff;}
</style>
</head>
<script src="./js/jquery-1.9.1.min.js" type="text/javascript"></script><script>function createAliH5Pay(){var data = "body="+$("#body1").val()+"&detail="+$("#detail").val()+"&outTradeNo="+$("#outTradeNo").val()+"&totalAmount="+$("#totalAmount").val()+"&payType="+$("#payType").val();var outTradeNo = $("#outTradeNo").val();if(outTradeNo==null||outTradeNo==undefined||outTradeNo==""){//处理alert("商户订单号不能为空");return;}var body1 = $("#body1").val();if(body1==null||body1==undefined||body1==""){//处理alert("订单名称不能为空");return;}var totalAmount = $("#totalAmount").val();if(totalAmount==null||totalAmount==undefined||totalAmount==""){//处理alert("付款金额不能为空");return;}var detail = $("#detail").val();if(detail==null||detail==undefined||detail==""){//处理alert("商品描述不能为空");return;}$.ajax({url: '/payDemo/pay/unifiedOrder.do',type: 'post',cache:false,async:false,data:  data,dataType: 'JSON',timeout: 5000,success: function(data){console.log("data="+data.data);if(data!=null){if(data.code!="00")alert("["+data.code+"]"+data.message);$("body").html(data.data);}}});
}</script><body text=#000000 bgColor="#ffffff" leftMargin=0 topMargin=4>
<header class="am-header"><h1>支付宝手机网站支付接口快速通道(接口名:alipay.trade.wap.pay)</h1>
</header>
<div id="main"><div id="body" style="clear:left"><dl class="content"><dt>商户订单号(*):</dt><dd><input id="outTradeNo" name="outTradeNo" /></dd><hr class="one_line"><dt>订单名称(*):</dt><dd><input id="body1" name="body" /></dd><hr class="one_line"><dt>付款金额(*):</dt><dd><input id="totalAmount" name="totalAmount" /></dd><hr class="one_line"/><dt>商品描述(*):</dt><dd><input id="detail" name="detail" /></dd><dt></dt><dd><input type="hidden" id="payType" name="payType" value="aliPay" /></dd><hr class="one_line"><dt></dt><dd id="btn-dd"><span class="new-btn-login-sp"><button class="new-btn-login" type="button" onclick='createAliH5Pay(this);' style="text-align:center;">确 认</button></span><span class="note-help">如果您点击“确认”按钮,即表示您同意该次的执行操作。</span></dd></dl></div><div id="foot"><ul class="foot-ul"><li>深圳市xxxxx公司版权所有 2015-2018 </li></ul></div></div>
</body></html>

springMVC后端接入支付宝,微信相关推荐

  1. WooCommerce接入支付宝微信支付

    WooCommerce接入支付宝微信支付 前言 安装支付宝插件(方法一) 安装配置 获取注册信息 安装支付宝插件(方法二) 安装微信支付插件 下载及安装 获取微信公众号APPID,微信支付密钥 获取微 ...

  2. 个人怎么接入支付宝微信支付?

    如今支付接口被广泛运用到各行各业,可以说交易即离不开支付.但是很多人对申请支付宝微信免签约支付感到头疼,一边难以达到大支付平台的接口资质要求,但是又有强烈的支付安全需求. 作为个人开发者,想为辛苦开发 ...

  3. JavaWEB后端支付银联,支付宝,微信对接

    注:本文来源于:<  JavaWEB后端支付银联,支付宝,微信对接  > JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所 ...

  4. 腾腾流氓,云云更流氓(问微信怎样接入支付宝支付),手贱的赶紧点,你会感谢我的...

    草原上的两匹马! 打从当年微信开始布局公众号之初时,估计就已经想到了与支付宝正面冲突的场面,所以微信先来个瞒天过海,在春晚搞了个微信红包,那叫一个火呀,此时的云云隐隐感觉到些许不安. 早期的微信开发者 ...

  5. java对接支付宝微信银联_JavaWEB后端支付银联,支付宝,微信对接

    JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所以对接部分做成了一个小模块. 先说下项目要求: 后端要对接银联无跳转Token支付,支 ...

  6. android微信支付回调方法,Android接入支付宝和微信支付的方法

    前言 很多APP都需要支付功能,国内一般就是支付宝和微信了.目前这2种接入方式对于APP端来说都已经比较方便了,因为大部分的安全校验之类的逻辑都在服务端. APP端总结起来就是三步走: 接入支付的库 ...

  7. android平台安全支付服务(msp)应用开发接口,Android接入支付宝和微信支付的方法...

    前言 很多APP都需要支付功能,国内一般就是支付宝和微信了.目前这2种接入方式对于APP端来说都已经比较方便了,因为大部分的安全校验之类的逻辑都在服务端. APP端总结起来就是三步走: 接入支付的库 ...

  8. 西米支付:支付宝/微信支付/银联支付通道的接入介绍

    本文以电脑网站支付为例,着重对第三方支付通道的接入进行了分析,包括支付宝支付接入.微信支付接入及银联支付接入. 1.支付宝支付接入 支付宝支付能力主要有当面付.刷脸付.App支付.手机网站支付.电脑网 ...

  9. Android接入支付宝和微信支付

    前言 很多APP都需要支付功能,国内一般就是支付宝和微信了.目前这2种接入方式对于APP端来说都已经比较方便了,因为大部分的安全校验之类的逻辑都在服务端. APP端总结起来就是三步走: 接入支付的库 ...

最新文章

  1. 10 ping不通widwos7 windwos_弱电老司机总结的10种视频监控系统故障解决方法,学会,事半功倍...
  2. es6箭头函数(=)与展开特性运算符(...)的使用
  3. 解决EXECL单元格不可以填充颜色
  4. windows下安装nginx
  5. SAP Commerce Cloud SmartEdit 的安装
  6. 分布式是写出来的(六)
  7. Г函数(伽马函数)、分布
  8. JavaScript对象类型Object
  9. WP8多分辨率解决方案
  10. 走进javascript——DOM事件
  11. 各省简称 拼音 缩写_近50个拼音/英文缩写合集 (一)
  12. 任玉刚【Android开发艺术探索】读后笔记一
  13. 关于企业如何再深化5s管理的几点建议
  14. 网课教育大火,平板逆袭,华为、联想等接连出手,小米还要苦等几时?
  15. 调查问卷生成json字符串
  16. 应用上云2小时烧掉近50万,创始人:差点破产
  17. 环境企业表单权限分配填报数据系统设计与实现
  18. github push报错 Support for password authentication was removed on August 13, 2021. Please use a perso
  19. spring+ehcache实现页面整体缓存和页面局部缓存
  20. Java开发——Mindmaster/Typora思维导图

热门文章

  1. python编程老师岗位需求表_岗位需求一览表
  2. linux查找文件,搜索字段
  3. sql注入--布尔盲注
  4. 迭代算法6——近似迭代法之二分法
  5. 数据可视化:教你打造升职加薪的报表
  6. KWS Water System Standard Rendering 教程
  7. 【论文笔记】Semi-supervised Domain Adaptation via Minimax Entropy(ICCV 2019)
  8. 搭建教育app系统源码时,都需要准备哪些三方信息呢?
  9. vue-rx的初步使用
  10. [gdc15]Farcry4的adaptive virtual texture