个人免签支付开发原理和示例源码分享

个人免签是什么?

官方支付接口比如支付宝、微信支付接口都需要营业执照才能申请,个人没有资质是无法申请的,想用官方支付是需要和商家签约的。

个人免签支付就是专门为没资质的个人使用的在线支付接口,无需签约,就可以使用。

个人免签原理

1、APP监听收款码的支付结果,然后修改页面的支付结果。

2、二次清算。款先到拥有官方支付接口的商户中,由商户给你结算。

3、Xposed微信插件实现全自动监听创建收款码、以及收款过程,容易封号。

方案其实有很多种,但是以上的方案都有不少的缺点,当然这些方案仍有不少人在用,没办法,确实是解决问题的一种办法。

实战示例分享

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

创建支付请求代码

index.php

1
2
3
4
5
6
7
8
9
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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>

该页面是用于创建订单的,其中 $order_price = 0.01; 就是创建一笔0.01元的订单。
创建订单前,程序会查询数据库来确定当前金额是否存在未支付的订单,如果存在,需支付的金额会在当前订单金额基础上+0.01元。
为什么要这么做?因为APP监听只能监听到收到了多少钱,无法监听到订单号,所以无法区分这个金额是你支付的还是其他人支付的。 所以在当前订单有效期内,你需要注意两件事,第一,你这个程序的访问量一定不能太高,不允许高并发的情况出现,适合小众,小规模,小流量的业务使用,一旦人多了,短时间内订单量多了,很难做到精准的监听支付结果。

实时监听支付代码

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

1
2
3
4
5
6
7
8
9
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给你的服务器然后修改数据库的支付结果,以实现支付回调的目的。

1
2
3
4
5
6
7
8
9
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);
     
?>

爱搜源码 » 个人免签支付开发原理和示例源码分享

发表评论

发表评论