PHP implements personal contract-free WeChat payment interface principle + source code

What is personal visa-free payment

Personal visa-free payment is a payment interface for individuals. General payment interfaces require a business license to apply for. It is difficult for individuals to apply, or if they do not have the qualifications to apply, they must sign a contract with the payment provider. Visa-free, as the name implies, does not require a contract. Then there is a market for personal visa-free payment, which is to solve the problem that individuals cannot easily apply for payment interfaces.

There are many visa-free schemes

  1. The APP monitors the payment result of the payment code, and then modifies the payment result on the page.
  2. Second liquidation. The payment first arrives at the merchant with the official payment interface, and the merchant will settle the payment for you.
  3. The Xposed WeChat plug-in realizes automatic monitoring, creation of payment codes, and payment process, and it is easy to block accounts.

There are actually many solutions, but the above solutions have many shortcomings. Of course, many people are still using these solutions. There is no way, but it is indeed a way to solve the problem. In this article, I also realized the first visa-free payment method in which the APP monitors the collection code through simple technical development.

The APP monitors the payment result of the payment code

The whole process is simple:

Access the URL -> Check the database for the order amount that has not been paid within 2 minutes -> If there is an amount that is the same as the current order in the order amount that has not been paid within 2 minutes, you need to add 0.01 yuan to the current amount to distinguish the uniqueness of the order- > The user scans the QR code to pay -> the Android phone APP listens to the payment of this order -> sends the payment amount to the server asynchronously -> the server modifies the payment status of the order amount in the database -> the scanning page keeps polling the order If you find that the payment has been made, modify the payment result on the page -> complete the payment.

upper code

index.php

This page is used to create an order, among which $order_price = 0.01;is to create an order of 0.01 yuan. Before creating an order, the program will query the database to determine whether there is an unpaid order with the current amount. If there is, the amount to be paid will be +0.01 yuan on the basis of the current order amount.

Why do you want to do this? Because the APP monitor can only monitor how much money has been received, but cannot monitor the order number, so it is impossible to distinguish whether the amount was paid by you or someone else.

Therefore, during the validity period of the current order, you need to pay attention to two things. First, the visit volume of your program must not be too high, and high concurrency is not allowed. It is suitable for niche, small-scale, and small-traffic business use. There are too many people, and there are too many orders in a short period of time, so it is difficult to accurately monitor the payment results.

<!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 onload="clock(120)">
    
    <?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/>人工微信号:sansure2016</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

This is used to monitor the payment result in real time on the order page. The database is checked every 2 seconds to obtain the payment result of the order. If the payment is not made after 2 minutes, the query will stop.

<?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

This is an asynchronous callback. The APP monitoring software needs to configure the URL of this file and the passed parameters, POST the monitored amount to your server and then modify the payment result in the database to achieve the purpose of payment callback.

<?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($orderMsg, strripos($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);
    
?>

full code

The above 3 files are core codes, which are only used for technical analysis and implementation principles. The complete code involves styles, pictures, database operation classes, and database table SQL statements, monitoring APP source code and installation packages.

insert image description here

Demo picture

The page is also very simple, and it is also designed by myself. The page is streamlined and beautiful.

insert image description here

Monitor APP configuration

The monitoring APP configuration is also quite simple, you only need to configure the online URL of notify.php to the APP. Please see the screenshot for specific operation:

1. Open the APP, select **[Send Channel] , click [Webhook] , select [GET Request]**, enter the URL of the server where notify.php is located, and fill in the following parameters **[orderMsg=[msg]]** that is Can.

insert image description here

2. Select **[Forwarding Rules] , click [Apply] , add forwarding rules, [APP Package Name] , select [Yes] , enter the package name [com.tencent.mm]**, the selected sending channel is the previous step For the channel you created, you can directly select the notification content in the template below.

insert image description here

At this point, the configuration of the APP is basically completed, and then the automatic startup of the APP is enabled, and the battery optimization whitelist is added to ensure that the APP can always run in the background without being killed.

Appreciation code acquisition

Why use appreciation code instead of payment code? Because the payment code is easier to be controlled by risk, the payment code is more suitable for face-to-face scanning code collection, not suitable for online remote collection, because every payment you make will record the payment ip address, location and other information, scan the code If there are too many times, the system will judge the remote payment, which is easy to trigger risk control. Appreciation codes are used for appreciation on the Internet, and are relatively safer than payment codes.

insert image description here

After obtaining your own appreciation code, cut out the part of the appreciation code and replace zsm.jpgthis file in the source code. Appreciation codes can be used to set appreciation guide words, which can be changed to 【Please click other amount input】to guide users.

Source code download

This source code has only a single page, no background, and is only suitable for personal single-page deployment or research, study, and secondary development. Database configuration, importing database tables, configuring appreciation codes, and preparing APP asynchronous callbacks can also be used for single-page collection. As long as your amount is fixed, it is indeed out of the box.

https://github.com/likeyun/liKeYun_MqPay

author

TANKING

Guess you like

Origin blog.csdn.net/weixin_39927850/article/details/129217591