个人收款码、赞赏码实现免签约微信支付接口原理+源码(开箱即用)

什么是个人免签支付

个人免签支付就是给个人用的支付接口,一般的支付接口都需要营业执照才能申请,个人很难申请的到,或者是没有资质去申请,要和支付商进行签约的。免签,顾名思义就是不需要签约。那么个人免签支付就有市场了,就是为了解决个人无法轻易申请到支付接口的问题。

免签的方案有很多种

1、APP监听收款码的支付结果,然后修改页面的支付结果。
2、二次清算。款先到拥有官方支付接口的商户中,由商户给你结算。
3、Xposed微信插件实现全自动监听创建收款码、以及收款过程,容易封号。

方案其实有很多种,但是以上的方案都有不少的缺点,当然这些方案仍有不少人在用,没办法,确实是解决问题的一种办法。而本次文章我也是通过简单的技术开发实现第一种APP监听收款码的免签支付方式。

APP监听收款码的支付结果

整个过程很简单:访问URL -> 检查数据库2分钟内未支付的订单金额 -> 如果2分钟内未支付的订单金额中存在当前订单一样的金额,需要在当前金额基础上+0.01元用于区分订单的唯一性 -> 用户扫码支付 -> 安卓手机APP监听到这笔订单的收款 -> 将收款金额异步发送到服务器 -> 服务器修改数据库该笔订单金额的支付状态 -> 扫码页面一直在轮询订单的支付状态,发现已支付就修改页面的支付结果 -> 完成支付。

话不多说,直接上代码

index.php

该页面是用于创建订单的,其中 $order_price = 0.01; 就是创建一笔0.01元的订单。

创建订单前,程序会查询数据库来确定当前金额是否存在未支付的订单,如果存在,需支付的金额会在当前订单金额基础上+0.01元。

为什么要这么做?因为APP监听只能监听到收到了多少钱,无法监听到订单号,所以无法区分这个金额是你支付的还是其他人支付的。 所以在当前订单有效期内,你需要注意两件事,第一,你这个程序的访问量一定不能太高,不允许高并发的情况出现,适合小众,小规模,小流量的业务使用,一旦人多了,短时间内订单量多了,很难做到精准的监听支付结果。

[HTML] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0,viewport-fit=cover">
    <meta charset="utf-8">
    <script src="./js/jquery.min.js"></script>
    <link rel="stylesheet" href="./css/style.css">
    <title>微信赞赏码免签约支付实现原理Demo</title>
</head>
<body>
    
    <?php
    
        // 数据库配置
        include './Db.php';
        
        // 实例化类
        $db new DB_API($config);
        
        // 订单号
        $order_num date('Ymd').time();
        
        // 订单金额
        $order_price 0.01;
        
        // 获取未支付订单列表
        $getOrderList = $db->set_table('mqpay_order')->findAll(['order_status' => 1]);
        
        // 遍历订单
        $orderNoExpire = array();
        for ($i = 0; $i < count($getOrderList); $i++) {
            
            // 订单时间
            $order_time json_decode(json_encode($getOrderList[$i]))->order_time;
            
            // 订单金额
            $order_money = json_decode(json_encode($getOrderList[$i]))->order_money;
            
            // 获取2分钟未支付的订单
            if(countTimes(time(),strtotime($order_time)) <= 2){
                
                // 如果存在
                $orderNoExpire[] = $order_money;
    
            }
        }
        
        // 判断是否有2分钟未支付的订单
        if(count($orderNoExpire) == 0){
            
            $needPay = $order_price;
        }else{
            
            // 获取2分钟未支付的订单的最大金额+0.01
            $needPay = max($orderNoExpire) + 0.01;
            
        }
        
        // 创建订单
        creatOrder($order_num,$order_price,$needPay,$db);
        
        
        // 创建订单
        function creatOrder($order_num,$order_price,$needPay,$db){
            
            // 订单参数
            $createOrder = [
                'order_num' => $order_num,
                'order_price' => $order_price,
                'order_money' => $needPay,
            ];
            
            // 创建
            $createOrderResult = $db->set_table('mqpay_order')->add($createOrder);
            if($createOrderResult){
                
                // 成功
                echo '<div class="payInfoCard">
                    <div class="header">里客云科技</div>
                    <div class="moneyCard">
                        <div class="text">支付金额</div>
                        <div class="money"><span class="rmb">¥</span>'.$needPay.'</div>
                        <!--二维码-->
                        <img src="./img/zsm.jpg" id="zsmQrcode" class="zsmQrcode" />
                        <p class="payWarning">请识别上方赞赏码</p>
                        <p class="payWarning">点击<span class="blueFont">其他金额</span>输入'.$needPay.'元</p>
                        <p class="payWarningMini">输入的金额必须要完全一致</p>
                        <p id="orderExpireTime"></p>
                        <p id="orderNum" style="display:none;">'.$order_num.'</p>
                        <p id="needPay" style="display:none;">'.$needPay.'</p>
                    </div>
                </div>
                
                <!--提示-->
                <p class="payTips">我们通过机器人监测本次支付<br/>支付后会立刻显示支付结果<br/>支付后没显示支付结果请联系人工处理<br/>微信号:xxx</p>';
            }else{
                
                // 失败
                echo '<div class="payInfoCard">
                    <div class="header">里客云科技</div>
                    <div class="moneyCard" style="padding:20px 20px;">
                        创建订单失败!
                    </div>
                </div>';
            }
        }
        
        
        // 计算时间戳的差值
        function countTimes($begin,$end){
            
            $begintimes = $begin;
            $endtimes = $end;
            $timediff = abs($endtimes - $begintimes);
            $days = intval($timediff / 86400);
            $remain = $timediff % 86400;
            $hours = intval($remain / 3600);
            $remain = $remain % 3600;
            $mins = intval($remain / 60);
            $secs = $remain % 60;
            return $mins;
        }
        
    ?>
    
    <script>
    
        // 每2秒获取一次支付结果
        var checkPayInterval = setInterval('checkPay()',2000);
        
        // 获取支付结果
        function checkPay(){
            
            // 获取订单号和支付金额
            var orderNum = $("#orderNum").text();
            var needPay = $("#needPay").text();
            
            $.ajax({
                type: "GET",
                url: "./checkPay.php?order_num="+orderNum+"&order_money="+needPay,
                success: function(res){
  
                    // 判断支付结果
                    if(res.code == 200){
                        
                        console.log('支付成功');
                        $("#zsmQrcode").prop("src","./img/success.png");
                        $('#orderExpireTime').css('display','none');
                        clearInterval(checkPayInterval);
  
                    }else{
                        
                        console.log(res.msg);
                    }
                }
            });
        }
        
        // 倒计时
        function clock(times){
            
            // 获取时分秒
            var h=parseInt(times/3600);
            var m=parseInt((times%3600)/60);
            var s=(times%3600)%60;
            
            // 在页面中显示倒计时
            $('#orderExpireTime').html(m+"分"+s+"秒后过期");
            
            // 倒计时
            if(times > 0){
                times = times-1;
                setTimeout(function (){
                    clock(times);
                }, 1000);
            }else{
                
                // 显示订单过期
                $("#zsmQrcode").prop("src","./img/expire.png");
                $('#orderExpireTime').text('订单已过期,请刷新页面!');
                
                // 结束轮询
                clearInterval(checkPayInterval);
                
                console.log('订单过期,停止监听');
            }
        }
    </script>
</body>
</html>

checkPay.php

这个是用于订单页面实时监听支付结果的,每2秒就查一次数据库获取订单的支付结果,2分钟后未支付会停止查询。

[PHP] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
    // 页面编码
    header("Content-type:application/json");
    
    // 数据库配置
    include './Db.php';
    // 实例化类
    $db new DB_API($config);
    
    // 获取订单号和支付金额
    $order_num $_GET['order_num'];
    $order_money $_GET['order_money'];
    
    // 根据订单号和订单金额来查询支付结果
    $getOrderPayStatus $db->set_table('mqpay_order')->find(['order_num'=>$order_num,'order_money'=>$order_money]);
    
    // 判断支付结果
    if($getOrderPayStatus){
        
        // 支付状态
        $order_status = json_decode(json_encode($getOrderPayStatus))->order_status;
        
        if($order_status == 2){
            
            // 支付成功
            $payResult array(
                'code' => 200,
                'msg' => '支付成功'
            );
        }else{
            
            // 未支付
            $payResult array(
                'code' => 202,
                'msg' => '未支付'
            );
        }
        
    }else{
        
        // 无结果
        $payResult array(
            'code' => 201,
            'msg' => '未支付'
        );
    }
    
    // 返回JSON
    echo json_encode($payResult,JSON_UNESCAPED_UNICODE);
    
?>

notify.php

这个是异步回调,在APP监听软件需要配置这个文件的URL和传递的参数,将监听到的金额POST给你的服务器然后修改数据库的支付结果,以实现支付回调的目的。

[PHP] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
    // 页面编码
    header("Content-type:application/json");
    // 原文
    $orderMsg $_GET['orderMsg'];
    
    // 数据库配置
    include './Db.php';
    // 实例化类
    $db new DB_API($config);
    
    // 订单金额、需支付的金额、通知原文、db实例
    updateOrder($orderMsg,$db);
    
    // 修改支付结果
    function updateOrder($orderMsg,$db){
        
        // 截取
        // 示例:二维码赞赏到账1.00元
        // 截取【到账】后面的
        $money_1 substr($orderMsgstrripos($orderMsg"到账") + 6);
        
        // 截取【元】前面的
        $money_2 substr($money_1, 0, strrpos($money_1"元"));
        
        // 更新订单
        $updateOrderResult $db->set_table('mqpay_order')->update(['order_status'=>1,'order_money'=>$money_2],['order_status'=>2,'order_paytime'=>time(),'order_msg'=>$orderMsg]);
        if($updateOrderResult){
            
            // 成功
            $ret array(
                'code' => 200,
                'msg' => '支付成功',
                'order_num' => $order_num,
                'order_money' => $money_2,
                'order_msg' => $orderMsg
            );
        }else{
            
            // 失败
            $ret array(
                'code' => 200,
                'msg' => '支付失败',
                'order_num' => $order_num
            );
        }
    }
    
    // 返回JSON
    echo json_encode($ret,JSON_UNESCAPED_UNICODE);
    
?>

完整代码

以上3个文件是核心代码,仅作技术分析实现原理。完整的代码涉及到样式、图片、数据库操作类、以及数据库表SQL语句、监听APP源码及安装包。

监听APP配置

监听APP配置也挺简单的,只需要将notify.php的线上URL配置至APP即可。

具体操作请看截图:

1、打开APP,选择【发送通道】点击【Webhook】,选择【GET请求】 ,输入notify.php 所在服务器的URL,下面的参数填写【orderMsg=[msg]】即可。

2、选择【转发规则】,点击【应用】,添加转发规则,【APP包名】,选择【是】,包名输入【com.tencent.mm】,选择的发送通道是上一步你创建的通道,下方的模板直接选择通知内容即可。

到这里,APP基本完成配置,然后将这个APP的自动启动开启,以及加入电池优化白名单,保证这个APP能一直在后台运行不被杀死。

赞赏码获取

为什么用赞赏码而不用收款码?因为收款码更容易被风控,收款码更加适合面对面扫码收款,而不适合线上远程收款,因为你的每一笔支付,都会记录付款ip地址,定位等信息,扫码次数多了,就会被系统判断远程付款,容易触发风控。赞赏码是用于网络上的赞赏使用,相对来说是比收款码安全的。

获得自己的赞赏码后,将赞赏码的那部分裁剪出来,替换掉源码中 zsm.jpg 这个文件就行了。赞赏码是可以设置赞赏的引导语的,可以将引导语修改为【请点击其他金额输入】,引导用户。

支付页面

源码下载

这个源码只有单页面,没有后台,只适合个人单页部署使用或者研究、学习、二次开发,不适合开箱即用,当然其实你有点基础,也算是开箱即用,上传到服务器,修改数据库配置,导入数据库表,配置好赞赏码,配制好APP异步回调,也是可以用来做单页的收款的,只要你的金额是固定的,确实是开箱即用。

下载权限

查看
  • 免费下载
    评论并刷新后下载
    登录后下载

查看演示

  • {{attr.name}}:
您当前的等级为
登录后免费下载登录 小黑屋反思中,不准下载! 评论后刷新页面下载评论 支付以后下载 请先登录 您今天的下载次数(次)用完了,请明天再来 支付积分以后下载立即支付 支付以后下载立即支付 您当前的用户组不允许下载升级会员
您已获得下载权限 您可以每天下载资源次,今日剩余

给TA打赏
共{{data.count}}人
人已打赏
值得一看

最近楼市回暖,个人经历分享一下二手房买卖贷款流程

2023-2-27 14:38:22

值得一看

【赚钱方法】i茅台预约,0撸,兔茅礼盒750佣金,全网佣金置顶,不需要垫付一分钱

2023-3-10 20:52:44

14 条回复 A文章作者 M管理员
  1. fyulixuan0615

    啧啧啧啧啧

  2. US in

    陌陌

  3. 可爱

    这个可以啊

  4. halas

    1111

  5. ht

    真不错

  6. wang

    12312

  7. 哈哈哈哈

    有帮助

  8. 小风车

    感谢楼主

  9. 手机几十块

    66

  10. cbxhema

    1414

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索