您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > 小程序

微信支付之扫码、APP、小程序支付接入详解

时间:2019-09-04 13:53:08  来源:  作者:

电商平台的小伙伴都知道,支付服务是必不可少的一部分,今天我们开始就说说支付服务的接入及实现。目前在国内,几乎90%中小公司的支付系统都离不开微信支付和支付宝支付。那么大家要思考了,为什么微信支付和支付宝支付能作为大多数公司接入的首选呢?其实这个问题大多小伙伴应该是很清楚的,说白了就是人家有庞大的用户流量,目前微信在国内的用户已突破10亿,支付宝也接近8亿左右,如此庞大的用户群体,你还会选择其他的第三方支付(微博钱包、财付通、快钱等)吗,作为普通客户,大家都希望能方便快捷,谁会为了在一个平台买点东西下载或开通其他服务呢,除非你给他有诱惑性的好处。今天我们先说说微信支付的接入及实现。

微信支付之扫码、APP、小程序支付接入详解

微信支付接入

首选我们去微信支付的官网,先看看官方提供的开发文档。链接地址:https://pay.weixin.qq.com/wiki/doc/api/index.html

微信支付之扫码、APP、小程序支付接入详解

 

我们先看看微信支付目前提供的支付方式(如上图),本次只讲原生支付(扫码支付)、App支付及小程序支付三种。

一,准备工作

在开发前,需要先申请一个商家版的微信公众号或微信小程序(目前微信支付只有商家版公众号可开通),然后开通微信支付功能,并做相应的配置。

微信支付之扫码、APP、小程序支付接入详解

 

申请开通微信公众号和开通微信支付(商户)需要等待审核,一般都5个工作日左右。开通成功后,需要获取配置信息:

wx.pay.appid=***
wx.pay.mchid=***
wx.pay.key=***
wx.pay.secret=***

注:appid是公众号ID,mchid是支付的商户ID,

其中appid和secret可以在公众平台找着,mchid和key则在商户平台找到,特别是key(即API_KEY)要在商户平台设置好。本项目中这些配置通过properties文件放在***-payment-service工程的resource根路径下。

在编码之前,还需要登录微信商户平台配置支付回调URL,此配置作为支付成功后回调接口的域名。如果配置的URL为:http://www.abc.com/, 你的支付回调路径则可设置为:http://www.abc.com/api/payment/notify。

二,编码阶段

在开始编码前,我们必须先了解清楚微信支付的对接及支付的业务流程。

  • 扫码支付的业务流程:
微信支付之扫码、APP、小程序支付接入详解

 

App支付的业务流程:

微信支付之扫码、APP、小程序支付接入详解

 

小程序支付的业务流程:

微信支付之扫码、APP、小程序支付接入详解

 

从官方提供的业务流程图我们可以大致总结对接流程如下:

1,在发起支付前,先在自己的商户后台下单,生成商户订单信息;

2,根据对应支付方式的参数需求,封装对应所需参数,并调用微信官方提供的统一下单Api接口下单;

3,统一下单成功,微信后台返回对应的响应数据。返回数据类型如下:

a,扫码支付统一下单后会返回生成二维码图片的链接code_url;

b,app和小程序支付统一下单后会返回预支付id,即:prepay_id;

4,如果扫码支付,你要用code_url生成一个二维码展示在前端页面供客户扫码付款;如果是app和小程序支付,后端只需将prepay_id及需要的参数传给app和小程序端。app会通过调用SDK、小程序会通过调用微信的JS发起支付。

5,客户付款成功后,客户的微信端会展示付款结果信息,同时微信后台会异步调用商户后台的回调接口(回调的api接口在统一下单作为下单参数),更新商户系统的支付单状态。

看到这里,大家会发现这三种方式的基本业务流程都差不多,只是由于不同支付方式调起微信应用支付功能的方式不同,所以统一下单成功后返回的参数有所不同。

Controller接口层:

@RestController
@RequestMapping(value = "/api/payment/")
public class PaymentController {
 private static Logger logger = LoggerFactory.getLogger(PaymentController.class);
 @Autowired
 private PaymentService paymentService;
 
 /**
 * App支付接口
 * 微信和支付宝统一下单入口
 * 
 * @param request
 * @return
 * @throws Exception
 */
 @ResponseBody
 @RequestMapping(value="toPay", method=RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
 public JSONObject toPay(HttpServletRequest request) throws Exception {
 String requestStr = RequestStr.getRequestStr(request);
 if (StringUtils.isEmpty(requestStr)) {
 throw new ParamException();
 }
 JSONObject jsonObj = JSONObject.parseobject(requestStr);
 if(StringUtils.isEmpty(jsonObj.getString("orderNo")) || StringUtils.isEmpty(jsonObj.getString("payAmount"))){
 throw new ParamException();
 }
 //验证订单是否存在
 String orderNo = jsonObj.getString("orderNo");
 double payAmount = jsonObj.getDouble("payAmount");
 if(payAmount < 0.01){
 return AjaxUtil.renderFailMsg("订单有误,请确认!");
 } else {
 //微信支付
 Map<String, String> resMap = paymentService.wxAppPayment(orderInfo.getOrderNo(),orderInfo.getPayPrice(),null);
 //判断微信统一下单是否成功
 if("SUCCESS".equals(resMap.get("returnCode")) && "OK".equals(resMap.get("returnMsg"))){
 //统一下单成功
 resMap.remove("returnCode");
 resMap.remove("returnMsg");
 logger.info("【App支付服务】微信支付下单成功!");
 return AjaxUtil.renderSuccessMsg(resMap);
 }else{
 logger.info("【App支付服务】微信支付下单失败!原因:"+resMap.get("returnMsg"));
 return AjaxUtil.renderFailMsg(resMap.get("returnMsg"));
 }
 }
}

PaymentService接口方法:

微信支付之扫码、APP、小程序支付接入详解

 

PaymentService实现类部分代码(微信App支付):

@Service(value = "paymentService")
public class PaymentServiceImpl implements PaymentService {
 
 private static Logger LOGGER = LoggerFactory.getLogger(PaymentServiceImpl.class);
 @Value("${spring.profiles.active}")
 private String PROJECT_ENV;
 @Value("${hcc.pay.domain}")
 private String payDomain;
 @Autowired
 private PaymentRecordMapper paymentRecordMapper;
 
 @Override
 @Transactional(readOnly=false,rollbackFor={Exception.class})
 public Map<String,String> wxAppPayment(String orderId, double money,Long customerId) throws Exception {
 LOGGER.info("【微信App支付】 统一下单开始, 订单编号="+orderId);
 SortedMap<String, String> resultMap = new TreeMap<String, String>();
 //生成支付金额
 double payAmount = PayUtils.getPayAmountByEnv(PROJECT_ENV, money);
 //TODO 操作数据库,添加或更新支付记录
 //this.addOrUpdatePaymentRecord(......);
 //微信统一下单
 Map<String,String> resMap = this.wxUnifieldOrder(orderId, PayConfig.TRADE_TYPE_APP, payAmount, null);
 if(PayConstant.SUCCESS.equals(resMap.get("return_code")) && PayConstant.OK.equals(resMap.get("return_msg"))){
 //封装参数返回
 resultMap.put("appid", PayConfig.WX_APP_ID);
 resultMap.put("partnerid", PayConfig.WX_MCH_ID);
 resultMap.put("prepayid", resMap.get("prepay_id"));
 resultMap.put("package", "Sign=WXPay");
 resultMap.put("noncestr", PayUtils.makeUUID(32));
 resultMap.put("timestamp", PayUtils.getCurrentTimeStamp());
 resultMap.put("sign", PayUtils.createSign(resultMap,PayConfig.WX_KEY));
 resultMap.put("returnCode", "SUCCESS");
 resultMap.put("returnMsg", "OK");
 LOGGER.info("【微信App支付】统一下单成功,返回参数:"+resultMap);
 }else{
 resultMap.put("returnCode", resMap.get("return_code"));
 resultMap.put("returnMsg", resMap.get("return_msg"));
 LOGGER.info("【微信App支付】统一下单失败,失败原因:"+resMap.get("return_msg"));
 }
 return resultMap;
} 

统一下单方法(在PaymentService实现类里):

  •  
/**
 * <p>微信支付统一下单</p>
 *
 * @param orderId 订单编号
 * @param tradeType 支付类型
 * @param payAmount 支付金额
 * @param openid
 * @return
 * @throws Exception
 */
 private Map<String,String> wxUnifieldOrder(String orderId, String tradeType, double payAmount, String openid) throws Exception{
 //封装参数
 SortedMap<String,String> paramMap = new TreeMap<String,String>();
 String appid = PayConfig.WX_APP_ID;
 String mchid = PayConfig.WX_MCH_ID;
 if(PayConstant.WX_TRADE_TYPE_JSAPI.equals(tradeType)){
 appid = PayConfig.XCX_APP_ID;
 mchid = PayConfig.XCX_MCH_ID;
 }
 paramMap.put("appid", appid);
 paramMap.put("mch_id", mchid);
 paramMap.put("nonce_str", PayUtils.makeUUID(32));
 paramMap.put("body", BaseConstants.PLATFORM_COMPANY_NAME);
 paramMap.put("out_trade_no", orderId);
 paramMap.put("total_fee", PayUtils.moneyToIntegerStr(payAmount));
 paramMap.put("spbill_create_ip", PayUtils.getLocalIp());
 paramMap.put("notify_url", this.getNotifyUrl(PayConstant.PAY_TYPE_WX));
 paramMap.put("trade_type", tradeType);
 if(PayConstant.WX_TRADE_TYPE_JSAPI.equals(tradeType)){
 paramMap.put("openid",openid);
 }
 paramMap.put("sign", PayUtils.createSign(paramMap,PayConfig.WX_KEY));
 //转换为xml
 String xmlData = PayUtils.mapToXml(paramMap);
 //请求微信后台
 String resXml = HttpUtils.postData(PayConfig.WX_PAY_UNIFIED_ORDER, xmlData);
 LOGGER.info("【微信支付】 统一下单响应:n"+resXml);
 return PayUtils.xmlStrToMap(resXml);
 }

 

统一下单完成,微信后台将相应的参数以xml的形式返回,统一下单成功后返回xml示例:

<xml>
 <return_code><![CDATA[SUCCESS]]></return_code>
 <return_msg><![CDATA[OK]]></return_msg>
 <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
 <mch_id><![CDATA[10000100]]></mch_id>
 <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
 <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
 <result_code><![CDATA[SUCCESS]]></result_code>
 <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
 <trade_type><![CDATA[APP]]></trade_type>
</xml>

因此我们需要将统一下单后的xml解析成map(上面的统一下单方法里已经转换成map),并判断下单状态。如果返回的return_code为SUCCESS并return_msg为OK,那么表示统一下单成功,然后封装对应的参数返回给前端。

前端根据下单成功后JAVA后端返回的参数,进行相应的处理并唤起微信应用的支付服务。注意,扫码支付是用统一下单成功后微信后台返回的code_url生成二维码展示给客户。二维码的生成可以前端也可Java后端生成然后以输出流的形式输出到网页上(坚决不建议Java端生成二维码图片保存到文件服务器然后再展示)。

客户在手机调起微信支付服务并输入密码成功付款后,客户手机的微信里会收到支付成功的付款信息,同时微信后台也在异步调用商户的后台接口。这个回调地址就是在统一下单方法里我们传的notify_url字段的参数值。

下面是回调接口代码:

  •  
/**
 * 微信支付完成回调Api
 * 
 * @param request
 * @param response
 * @throws Exception
 */
 @RequestMapping(value="notify")
 public void wxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception {
 InputStream inputStream = request.getInputStream();
 //获取请求输入流
 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 byte[] buffer = new byte[1024];
 int len = 0;
 while ((len=inputStream.read(buffer))!=-1){
 outputStream.write(buffer,0,len);
 }
 outputStream.close();
 inputStream.close();
 Map<String,Object> map = BeanToMap.getMapFromXML(new String(outputStream.toByteArray(),"utf-8"));
 logger.info("【微信支付回调】 回调数据:n"+map);
 String resXml = "";
 String returnCode = (String) map.get("return_code");
 if ("SUCCESS".equalsIgnoreCase(returnCode)) {
 String returnmsg = (String) map.get("result_code");
 if("SUCCESS".equals(returnmsg)){
 //更新支付单状态信息
 int result = paymentService.wxNotify(map);
 if(result > 0){
 //支付成功
 resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
 + "<return_msg><![CDATA[OK]]></return_msg>"+"</xml>";
 }
 }else{
 resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
 + "<return_msg><![CDATA[报文为空]></return_msg>" + "</xml>";
 logger.info("支付失败:"+resXml);
 }
 }else{
 resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
 + "<return_msg><![CDATA[报文为空]></return_msg>" + "</xml>";
 logger.info("【订单支付失败】");
 }
 logger.info("【微信支付回调响应】 响应内容:n"+resXml);
 //做出响应
 response.getWriter().print(resXml);
 }

 

到此为止,所有的编码工作已完成。

三,测试(用扫码支付)

选择要购买的商品,然后下单,再去发起支付。

微信支付之扫码、APP、小程序支付接入详解

 

单击“去支付”按钮,跳转到二维码支付页面:

微信支付之扫码、APP、小程序支付接入详解

 

扫码支付完成后,显示二维码的页面会跳转到支付成功页面(带微信支付成功logo),并有3s的倒计时,然后跳转到“订单详情”页。

微信支付之扫码、APP、小程序支付接入详解

 

学习更多的教程关注“重庆千锋”公众号,获取更多的学习教程。



Tags:微信支付   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
如今,微信支付已经是人们再熟悉不过的日常操作了,人们无论是在网上购物,还是在日常出行买菜,亦或者是外出游玩,都需要涉及到微信支付,而现如今,微信支付已经几乎覆盖了我们很多人的...【详细内容】
2021-09-14  Tags: 微信支付  点击:(51)  评论:(0)  加入收藏
手机支付越来越便捷的今天,大部分人已经极少使用现金支付。 微信支付、支付宝支付 = 钱包。 但是,就算揣自己怀里的钱,都有可能被偷、被抢,更别说放在手机里了。 再加上现在个人...【详细内容】
2021-09-13  Tags: 微信支付  点击:(128)  评论:(0)  加入收藏
自从有了电子移动支付,我们出门基本就不带现金了,移动支付给我们的生活带来很多便利,我们使用的电子支付方式主要有两种,微信支付和支付宝支付,今天我就说说使用微信支付需要注意...【详细内容】
2021-09-01  Tags: 微信支付  点击:(81)  评论:(0)  加入收藏
微信支付对于当下的我们来说,是非常重要的一个手机功能,可以方便我们在出门购物消费时直接支付,而不再需要随身携带现金。在使用微信支付之前,是需要实名认证、绑定我们的身份证...【详细内容】
2021-08-25  Tags: 微信支付  点击:(55)  评论:(0)  加入收藏
近期小编听说有的小伙伴名下绑定了多个微信支付账户却毫不知情,这是非常危险的!下面小编为大家介绍一个小方法可以在手机上快速查询名下微信号,闲置的微信号最好还是解绑了哟需...【详细内容】
2021-08-17  Tags: 微信支付  点击:(254)  评论:(0)  加入收藏
商家想要实现微信支付宝收款码二合一,也就是聚合收款码,做法其实很简单。 一,我们首先来认识聚合收款码 1,聚合收款码是什么?聚合收款二维码,从字面来理解就是一个二维码支持多种...【详细内容】
2021-05-26  Tags: 微信支付  点击:(261)  评论:(0)  加入收藏
5月8日,数字人民币APP更新,钱包运营机构中的“网商银行(支付宝)”已呈现可用状态。同时,工、农、中、建、交、邮储六大国有银行数字人民币钱包下均增加了饿了么、盒马鲜生、天猫...【详细内容】
2021-05-11  Tags: 微信支付  点击:(116)  评论:(0)  加入收藏
手机支付最主要的就是通过支付宝和微信了,很多人也会在微信钱包里放入不少零钱,方便支付使用。我们除了可以给手机添加密码外,还可以在微信支付上添加密码,保障大家的财产安全。...【详细内容】
2021-04-30  Tags: 微信支付  点击:(75)  评论:(0)  加入收藏
现如今,微信支付十分方便,很多中老年人也能轻松上手,节省了很多找零时间,也避免了没带钱包的尴尬。可是,在这种便捷背后,信息安全问题却不容小觑!前段时间有新闻报道称,一女子发现了...【详细内容】
2020-11-09  Tags: 微信支付  点击:(171)  评论:(0)  加入收藏
很多早期注册的微信都没有实名制或者是非本人认证的,这时候就需要注销微信支付重新认证,一起看看怎么操作。微信注销更换实名制教程进入微信,点击我的后点击支付,如下图所示 点...【详细内容】
2020-10-10  Tags: 微信支付  点击:(188)  评论:(0)  加入收藏
▌简易百科推荐
一、项目背景随着小程序在用户规模和商业化上取得的极大成功,各大平台都推出了自己的小程序。然而这些平台的小程序开发在语法上又不尽相同,不同平台小程序代码的维护需要投入...【详细内容】
2021-11-05  携程技术    Tags:小程序   点击:(65)  评论:(0)  加入收藏
作者:灰灰来源:JS每日一题 一、背景传统的web开发实现登陆功能,一般的做法是输入账号密码、或者输入手机号及短信验证码进行登录服务端校验用户信息通过之后,下发一个代表登录态...【详细内容】
2021-10-29  Nodejs开发    Tags:微信小程序   点击:(43)  评论:(0)  加入收藏
总结列举微信小程序开放能力清单 硬件能力 蓝牙 NFC读写 连接WIFI设备 开放能力 ...【详细内容】
2021-09-27  软件开发分享    Tags:微信小程序   点击:(60)  评论:(0)  加入收藏
核心商城(CoreShop)介绍核心小程序商城系统(CoreShop) 是基于 Asp.Net 5.0、Uni-App开发、支持可视化布局的小程序商城系统;前后端分离,支持分布式部署,跨平台运行;拥有分销、代理、...【详细内容】
2021-07-20  码农也有梦想    Tags:小程序商城   点击:(115)  评论:(0)  加入收藏
介绍Vue3发布已经有一段时间了,从目前来看,其生态还算可以,也已经有了各种组件库给予了支持,但是不管是Vue3还是Vue2都无法直接用来开发小程序,因此国内一些技术团队针对Vue开发...【详细内容】
2021-07-13  爱分享Coder    Tags:小程序   点击:(204)  评论:(0)  加入收藏
首先明确几个概念1. W3C:指万维网联盟(World Wide Web Consortium),是一个国际的标准的制定机构。2. H5(HTML5,HyperText Markup Language 5的缩写),HTML5 是由W3C制定的新HTML标...【详细内容】
2021-07-06  畅游零和一的海洋    Tags:微信小程序   点击:(153)  评论:(0)  加入收藏
在开发微信公众号时,需要不时请求URL和数据封装。为了不做重复的工作。提取公共部分进行封装。产生了相应的公众类。今天先来写下请求类,代码如下:public class HttpRequestP...【详细内容】
2021-06-16  java浮萍  今日头条  Tags:公共类   点击:(134)  评论:(0)  加入收藏
小程序上线后,改版了很多次,包括一些 Api 接口也有改动。如果你学习一个很久之前的小程序项目是没有意义的,本文推荐的小程序都是最近有更新的。相信在你学习、部署的过程中,不...【详细内容】
2021-06-08    程序猿久一  Tags:微信小程序   点击:(207)  评论:(0)  加入收藏
自从2019年微信公开课Pro在微信之夜演示《跳一跳》以来,微信小游戏已经不知不觉走过的三年,这三年中我们可以明显看到微信对小游戏的扶持,对于微信开发者来说,微信小游戏开发以...【详细内容】
2021-05-25  开课吧科科  今日头条  Tags:微信小游戏   点击:(212)  评论:(0)  加入收藏
学习编程从hello world开始。学习微信小程序开发首先要安装一个微信开发者工具,官网上免费下载童叟无欺,下载完傻瓜式安装即可。 双击微信开发者工具,然后选择小程序,然后点击...【详细内容】
2021-05-12  程序员fearlazy  fearlazy  Tags:微信小程序   点击:(268)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条