Java微信扫码支付模式二Demo ,整合官网直接运行版本

概述

场景介绍 扫码支付模式二,用于web网站。用户点击支付后,根据商品生成的二维码,用户扫码完成支付,手机提示支付成功,微信支付系统把交易结果发送到回调接口中。

详细

功能演示

本地版本:

穿透.png

一、相关配置

微信公众号AppID(登录微信公众平台-->开发-->基本设置-->开发者ID(AppID))

微信公众号AppSecret(登录微信公众平台-->开发-->基本设置-->开发者密码(AppSecret))

微信支付商户号(登录微信商户平台-->账户中心-->商户信息-->基本账户信息-->微信支付商户号)

微信支付商户API密钥(登录微信商户平台-->账户中心-->API安全-->API密钥-->设置API密钥)

application.properties 文件 (Demo上都有官网的默认值,不需要修改直接使用,省心!

 

QQ图片20210108093355.png

支付扫码模式二,流程图

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

SDK与DEMO下载

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

二、目录结构

QQ图片20210118154932.png

准备工作

(1)内网穿透工具

让外网能直接访问,你本地的服务,场景用于,接口调试,支付方面等等。

为了大家找了一个,免费配置简单的。绝对不是卖广告,之前用过花生壳,麻烦到要死坑哇~,现在的所有穿透都要身份证登记,很正常国家出了对应的法规。下载地址:NATAPP-内网穿透 基于ngrok的国内高速内网映射工具

配置和使用说明:外网映射---内网穿透工具NATAPP---灵感源自QQ浏览器微信调试工具_natapp+xampp_kingrome2009的博客-CSDN博客

四、功能演示

本地版本:请看最上面视频及流程图,访问链接  http://127.0.0.1:8080

穿透版本:请看最上面视频及流程图,访问链接 必须使用穿透工具,步骤请看视频~

支付流程:

QQ图片20210402151909.jpg

图片111111.jpg

五、前端代码

<html>
<head >
    <title>微信支付二维码生成</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript" src="/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="/js/websocket/sockjs.min.js"></script>
    <script type="text/javascript" src="/js/websocket/stomp.min.js"></script>
    <script type='text/javascript'>
 
        $(function () {
            wxQRCode();
        });
 
        //当前查询次数
        var nowQueryCount = 0;
        //生成二维码
        function wxQRCode(){
            getOutTradeNo();
            var outTradeNo = $("#outTradeNo").val();
            $("#payImg").attr("src",'/wxPay/payUrl'+"?totalFee="+ $("#totalFee").val()+"&outTradeNo=" + outTradeNo + "&random=" + new Date().getTime());
            //重置查询次数
            nowQueryCount = 0;
            queryOrder();
        }
 
        //获取流水号
        function getOutTradeNo(){
            $.ajax({
                type : "POST",
                url : '/wxPay/outTradeNo',
                async : false,
                success : function(jsonData) {
                    if(jsonData.code == 200){
                        var outTradeNo = jsonData.data;
                        $("h2").html(outTradeNo);
                        $("#outTradeNo").val(outTradeNo);
                        //启动webSocket监听器
                        webSocketListener(outTradeNo);
                    }else{
                        alert(jsonData.message);
                    }
                    return false;
                },
                error:function(XMLHttpRequest,textStatus,errorThrown){
                    alert("服务器错误!状态码:"+XMLHttpRequest.status);
                    // 状态
                    console.log(XMLHttpRequest.readyState);
                    // 错误信息
                    console.log(textStatus);
                    return false;
                }
            });
        }
 
        var stompClient = null;
        //webSocketListener 监听器 是否已经支付
        function webSocketListener(outTradeNo){
            //多次生成二维码,关闭上一次webSocket,避免浏览器负担
            closeWebSocket();
            if ("WebSocket" in window){
                    var socket = new SockJS('/websocket');
                    stompClient = Stomp.over(socket);
                    stompClient.connect({}, function (frame) {
                        console.log('Connected: ' + frame);
                        stompClient.subscribe('/member/'+outTradeNo+'/send/message', function(jsonData) {
                            jsonData = JSON.parse(jsonData.body);
                            if(jsonData.code == 200){
                                var data = jsonData.data;
                                var outTradeNo = data.outTradeNo;
                                var transactionId = data.transactionId;
                                var payDateStr = data.payDateStr;
                                console.log("WebSocket:"+"\n"+"商户订单号:"+outTradeNo +"\n"+"微信支付订单号:"+transactionId+"\n"+"支付时间:"+payDateStr);
                                alert("WebSocket:"+"\n"+"商户订单号:"+outTradeNo +"\n"+"微信支付订单号:"+transactionId+"\n"+"支付时间:"+payDateStr);
                                closeWebSocket();
                                return false;
                            }
                        });
                    });
            }else{
                alert('我不兼容WebSocket');
            }
        }
 
        //关闭webSocket
        function closeWebSocket(){
            if (stompClient != null) {
                stompClient.disconnect();
            }
        }
 
        //查询订单总次数
        var autoQueryCount = 100;
        //定时器
        var queryOrderSetTimeout = null;
        //查询订单状态
        function queryOrder(){
            nowQueryCount ++;
            var outTradeNo = $("#outTradeNo").val();
            $.ajax({
                type : "POST",
                url : '/wxPay/payStatus?outTradeNo='+ outTradeNo +"&random=" + new Date().getTime(),
                async : false,
                success : function(jsonData) {
                    if(jsonData.code == 200){
                        var data = jsonData.data;
                        var outTradeNo = data.outTradeNo;
                        var transactionId = data.transactionId;
                        var payDateStr = data.payDateStr;
                        console.log("查询订单:"+"\n"+"商户订单号:"+outTradeNo +"\n"+"微信支付订单号:"+transactionId+"\n"+"支付时间:"+payDateStr);
                        alert("查询订单:"+"\n"+"商户订单号:"+outTradeNo +"\n"+"微信支付订单号:"+transactionId+"\n"+"支付时间:"+payDateStr);
                        //已支付,清除定时器
                        clearTimeout(queryOrderSetTimeout);
                        return false;
                    }else{
                        if(nowQueryCount < autoQueryCount){
                            //定时查询订单状态,5秒查询一次
                            console.log(currentTime()+" queryOrder:"+jsonData.message+" 查询次数:"+nowQueryCount);
                            queryOrderSetTimeout = setTimeout(queryOrder,5*1000);
                        }else{
                            console.log(currentTime()+" queryOrder:"+jsonData.message+" 查询结束");
                            //超过查询次数,清除定时器
                            clearTimeout(queryOrderSetTimeout);
                            return false;
                        }
                    }
                },
                error:function(XMLHttpRequest,textStatus,errorThrown){
                    alert("服务器错误!状态码:"+XMLHttpRequest.status);
                    // 状态
                    console.log(XMLHttpRequest.readyState);
                    // 错误信息
                    console.log(textStatus);
                    return false;
                }
            });
        }
 
 
        //当时时间
        function currentTime(){
            var date = new Date();
            this.year = date.getFullYear();
            this.month = date.getMonth() + 1;
            this.date = date.getDate();
            this.hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
            this.minute = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
            this.second = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
            var currentTime = this.year+'-'+this.month + '-' + this.date + ' ' + this.hour + ':' + this.minute + ':' + this.second;
            return currentTime;
        }
 
    </script>
</head>
<body>
<p>订单流水号:<h2></h2></p>
支付金额:<input id="totalFee"    type="text"   value="0.01"/>
<button type="button" onclick="wxQRCode();" style="cursor: pointer">生成二维码</button>
<input id="outTradeNo"  type="hidden" />
&nbsp;&nbsp;<img  id="payImg" width="300" height="300"  >
</body>
</html>

六、后端代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>com.juno</groupId>
   <artifactId>weixin-websoket</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
 
   <name>weixin-websoket</name>
   <description>Demo project for Spring Boot</description>
 
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.4.0</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
 
   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
      <commons-lang3.version>3.7</commons-lang3.version>
      <commons-collections.version>3.2.2</commons-collections.version>
      <com.google.zxing.version>3.3.3</com.google.zxing.version>
      <fastjson.version>1.2.46</fastjson.version>
   </properties>
 
   <dependencies>
      <!-- mvc支持-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
 
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
 
      <!-- 热部署模块 -->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
         <optional>true</optional>
      </dependency>
 
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
 
      <!-- Commons utils begin -->
      <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
         <version>${commons-lang3.version}</version>
      </dependency>
      <dependency>
         <groupId>commons-collections</groupId>
         <artifactId>commons-collections</artifactId>
         <version>${commons-collections.version}</version>
      </dependency>
      <!-- Commons utils end -->
 
      <!-- google 生成二维码 begin-->
      <dependency>
         <groupId>com.google.zxing</groupId>
         <artifactId>javase</artifactId>
         <version>${com.google.zxing.version}</version>
      </dependency>
      <!-- google 生成二维码 end-->
 
      <!-- JSONObject JSONArray begin -->
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>${fastjson.version}</version>
      </dependency>
      <!-- JSONObject JSONArray end -->
 
      <!-- websocket begin -->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-websocket</artifactId>
      </dependency>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <scope>test</scope>
      </dependency>
      <!-- websocket end -->
 
   </dependencies>
 
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
               <fork>true</fork>
            </configuration>
         </plugin>
      </plugins>
   </build>
 
 
</project>

WxPayController.java

package com.juno.weixin.modules.controller.wx;
 
import com.juno.weixin.modules.common.util.JSONResponse;
import com.juno.weixin.modules.common.wx.WxConfig;
import com.juno.weixin.modules.common.wx.WxConstants;
import com.juno.weixin.modules.common.wx.WxUtil;
import com.juno.weixin.modules.service.WxMenuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
/**
 * 微信支付控制类
 * @author lujunjie
 * @date   2020/12/31
 */
@Controller
public class WxPayController {
 
    @Autowired
    private WxMenuService wxMenuService;
 
    /**
     * 二维码首页
     */
    @RequestMapping(value = {"/"}, method = RequestMethod.GET)
    public String wxPayList(Model model){
        return "/wxPayList";
    }
 
    /**
     * 获取流水号
     */
    @RequestMapping(value = {"/wxPay/outTradeNo"})
    @ResponseBody
    public JSONResponse getOutTradeNo(){
        //商户订单号
        return JSONResponse.success(WxUtil.mchOrderNo());
    }
 
    final private String signType = WxConstants.SING_MD5;
    /**
     * 统一下单-生成二维码
     */
    @RequestMapping(value = {"/wxPay/payUrl"})
    public void payUrl(HttpServletRequest request, HttpServletResponse response,
                       @RequestParam(value = "totalFee")Double totalFee,
                       @RequestParam(value = "outTradeNo")String outTradeNo) throws Exception{
        WxUtil.writerPayImage(response,wxMenuService.wxPayUrl(totalFee,outTradeNo,signType));
    }
    /**
     * 查询订单状态
     */
    @RequestMapping(value = {"/wxPay/payStatus"})
    @ResponseBody
    public JSONResponse payStatus(HttpServletRequest request, HttpServletResponse response,
                       @RequestParam(value = "outTradeNo")String outTradeNo) throws Exception{
        return this.wxMenuService.queryOrder(outTradeNo,signType);
    }
 
    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;
 
    /**
     * 统一下单-通知链接
     */
    @RequestMapping(value = {"/wxPay/unifiedorderNotify"})
    public void unifiedorderNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
 
        //商户订单号
        String outTradeNo = null;
        String xmlContent = "<xml>" +
                "<return_code><![CDATA[FAIL]]></return_code>" +
                "<return_msg><![CDATA[签名失败]]></return_msg>" +
                "</xml>";
 
        try{
            String requstXml = WxUtil.getStreamString(request.getInputStream());
            Map<String,String> map = WxUtil.xmlToMap(requstXml);
            String returnCode= map.get(WxConstants.RETURN_CODE);
            //校验一下 ,判断是否已经支付成功
            if(StringUtils.isNotBlank(returnCode) && StringUtils.equals(returnCode,"SUCCESS")  &&  WxUtil.isSignatureValid(map, WxConfig.key,signType)){
                System.out.println("------------"+"统一下单-通知链接:支付成功"+"------------");
                System.out.println("统一下单-通知链接:"+"requstXml : " + requstXml);
                //商户订单号
                outTradeNo = map.get("out_trade_no");
                System.out.println("统一下单-通知链接 "+"outTradeNo : "+ outTradeNo);
                //微信支付订单号
                String transactionId = map.get("transaction_id");
                System.out.println("统一下单-通知链接 "+"transactionId : "+ transactionId);
                //支付完成时间
                SimpleDateFormat payFormat= new SimpleDateFormat("yyyyMMddHHmmss");
                Date payDate = payFormat.parse(map.get("time_end"));
                SimpleDateFormat systemFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String payDateStr = systemFormat.format(payDate);
                System.out.println("统一下单-通知链接 "+"支付时间:" + payDateStr);
 
                HashMap<String,Object> returnMap = new HashMap<>();
                returnMap.put("outTradeNo",outTradeNo);
                returnMap.put("transactionId",transactionId);
                returnMap.put("payDateStr",payDateStr);
                //通知前台,我完成支付了
                simpMessagingTemplate.convertAndSendToUser(outTradeNo,"/send/message",JSONResponse.success(returnMap));
                xmlContent = "<xml>" +
                        "<return_code><![CDATA[SUCCESS]]></return_code>" +
                        "<return_msg><![CDATA[OK]]></return_msg>" +
                        "</xml>";
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        //返回信息给微信
        WxUtil.responsePrint(response,xmlContent);
    }
 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PHP微信扫码支付Demo是一个用PHP语言编写的示例程序,用于演示如何使用微信支付扫码支付功能。 首先,我们需要在微信商户平台注册一个商户号,并获取到支付相关的参数,包括APPID、商户号、密钥等等。 然后,我们需要搭建一个简单的PHP后台服务器,用于处理支付请求和回调。我们可以使用框架如Laravel或使用原生PHP来实现。 接下来,我们需要创建一个简单的页面,提供给用户进行支付。页面上需要包含一个维码来展示支付链接。 在PHP代码中,我们需要首先获取到用户在前端输入的支付金额和订单号等信息。然后,通过调用微信支付接口的方式,生成一个微信支付维码链接。我们可以使用PHP内置的cURL库来发送请求,并获取到返回的结果。 接下来,我们将支付链接生成的维码显示在前端页面上,供用户进行扫码支付。我们可以使用一些开源的PHP维码生成库来生成维码图片。 当用户扫码支付后,微信服务器会回调我们之前在后台配置的回调URL。我们需要编写相应的代码来处理这个回调请求,并验证回调的合法性。在回调处理中,我们需要根据微信服务器返回的支付结果更新订单状态或进行其他业务逻辑的处理。 最后,我们可以在前端页面上添加一些样式和交互效果,例如显示支付成功或失败的提示信息,并提供订单查询的功能。 通过以上步骤,我们就可以实现一个简单的PHP微信扫码支付Demo。当然,这只是个简单的示例,实际应用中还需要考虑更多的安全性和异常处理等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西安未央

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值