PHP支付,TP5.0接入支付宝支付流程(附教程)

一、本地环境的话,首先需要有沙箱
登录支付宝,蚂蚁金服账号(个人支付宝账号)戳这里!戳这里!
点击 右上角的控制台,然后在拉倒最下面,就能看到 沙箱环境
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

需要自己开启,配置一下信息,特别注意,网关地址:沙箱环境是有dev的,正式上要去掉 dev
生成秘钥工具,可以在支付宝 开发文档里面自行下载。在这里插入图片描述

因为是测试,这里选择了 电脑网站支付测试,选择下载Demo。
在这里插入图片描述

下载好之后的文件夹,是这样的:
在这里插入图片描述
把这个文件夹,整体放倒TP5项目的 extend 文件夹中,此文件夹就是为了放一些扩展的。
在这里插入图片描述
有几个文件,需要特别注意:
1.config : 文件是防止你所有的配置,公钥,私钥,回调地址,appid等信息
2.notify_url :是回调地址的文件
3.return_url : 是同步调用的文件
解释:
回调地址:说白了,就是告诉你支付成功了,这个识货,你需要在这个里面修改订单状态。——后续再说整体支付流程
同步调用:再说白了,就是支付成功,跳转到一个新的页面,支付成功会带着支付的一些信息。
回调地址是看不到请求的,因为是服务器请求服务器,只能看日志,所以需要在回调地址里面 写上日志请求。

在这里插入图片描述

回调 和同步地址,因为是在本地,地址就写成了本地,你可以看成这两个,就是两个aciton
配置完事了,接下来是代码了,因为是测试 ,so 代码只是为了言简意赅,就忽略LOW,谢谢!话不多说,上代码

<?php
/***
 *
 * @package     APP支付宝支付
 *
 * @subpackage  支付宝支付
 *
 * @author      Tggui 2017-7-4 23:52:27
 *
 */
namespace app\index\controller;
// 引用各种类,就不用说了
use think\Controller;
use think\Model;
use think\Db;
use think\Log;
class Alipay
{

    /**
     * Alipay constructor.
     *  支付流程:
     * 点击付款的时候,就已经入库 ,订单状态是未付款状态
     * 支付完成后,在回调里面修改订单状态,改成已付款状态。
     * 引入需要的文件
     */
    public function __construct()
    {
        require_once '../extend/alipay/pagepay/service/AlipayTradeService.php';
        require_once '../extend/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';
//        require_once "../extend/alipay/aop/AopClient.php";
//        require_once "../extend/alipay/aop/request/AlipayTradeAppPayRequest.php";
    }

    /**
     * 创建APP支付订单
     * @return array 返回订单信息
     */
    public function AlipayDemo(){
        return view('/alipay/index');
    }

    public function payDemo(){
    // 接取所有的值,或者可以使用 input('params.');
        $data = input('post.');
        // 咳咳... 这里只是为了方便理解,正常是要调用config的,或者封装起来的!!! 千万不要在代码里面这么写 
        $config = array (
            //应用ID,您的APPID。
            'app_id' => "2016102300747406",
            //商户私钥
            'merchant_private_key' => "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9jsFMchdH6ZAGPVoDg/kuL3e4Q0UCPO1T7dbrP2sKEf/JESYngAupo/7g6/UNkW9s1oamSnQzMdSCLgQGy42li+rCsKTMTpFQfRU761TA0NJrMY8fWLz6S0W+7oikrn9/b0hyS6cRmTJLzyS/556Meqf2zbYm5aIP+Wue4JpTw5fvjX1WRcX36iXOHdBVdCShyjHv3uu+HDLVE/5Hb9VfeoKS0HfySdg/WX0pw0UKW91edzrhMOoCfFA3a83VxLehCOAGhkbiHmXOhvjJ+lYHWLz4Jpn5g8reyrTOBtmc85v/H+0unCsURX+Plpv4Hu8qk/u3+kmTg69j+y/u+RdlAgMBAAECggEAG7tq5Dg817R/8anAJYuFRRCEv1x4GB+5yPGe48PfcRW5Cj2MC3NcQXFQtK9Qpq+EUbQA9wslfOfpYzJAPI5DJtkVe25Ebe+AqvnhxWZke+ERJ8WUXs2ouCWTCp/zNcShuo8ZVj9jLdvv0892XO0R8RNwx1bJM1+dGiEvcYsCiQZvmj4KOLZcNp2skUd/ZKlikHPigyiAHfJdDpDPVJLfSrryYxTifuwMcHf1irNjI/dW4N8fcAykGNypcjVYkvGjTO33WEHjOrp0ArNpDR7XPnF8WmjGBL4ldCZ8gZ9KY2f15iztnT8dSDDDTax2XUfjK2L+hBqiSuxmYuNpaBmycQKBgQD5l0t4TxvVvKNAvIhHZW2AtHf999liu8jEbe5sSDYCtstNQIG0WpGqVWHzmijE85cVXJclooGWMuxZ8sJIIXRE1tav/RRFPfVAtJknyjdAbGGNSzQmV/XB3f5J6CPRlpE/Nk7vt+8rs1XYu8lJmozx1wH8zrT2XJvi2yyTfS8jewKBgQDCbNOTbQkgQ/vxYO9V/VrtJJQFAJeM5TXEdYPTAFeEVOSvcl3+jS9iqM7mTJ1xDCEWZJyvDygdTXWgpQc38jMEt5Q5DjfruxPs5MII8rw9TPtiMeIZjtxC09ZVG5zdBO7gaXmiF2P8TM2YjtC9Ayg+0Hf+FLUwCR+DgIkTiinKnwKBgQDFb1rx5pI8NyZk1T5wS9mdUCUDL4Y0xhsA130dBtpCt1qG15pCkspblYMQckgB1DcVXNLroGsl505zsMbizCPvOItHV8krJOHWt4XXpeyi95kLbgvosPfkzbiTuiBrcNGg0VML6dI2HXyxH4sQwELyI4Sc+N7Ja2ScxYeze/lH9QKBgCiMUcPZZaHZC95XfRLN9/ylOEmiyfiUhRYn/AoxdA8hNWBx1bCU+WD2G9BkAiHlibEF4rePzanu0a1jPZIpbQJ61urfUEJVjd5GB0Gefiu6tmLQTHtQFBfL3lN5osllkfwzgy6O+kdQLUC36EjDM82F5MCUyQTvoibm06/DjNu5AoGAJdkZClCgT8RjIHeEIiNjSN+K6+3diCeNi/9WZVSJ6Irf4HqxN88RhAT2Eq4NxjCdr43dpPYQ+oh+Tm7u+8uyBHyZHO8AiELzsEZb8CQZ6D/sgxN+6jLfE5BU1lsqk1zXhukrNxBBGupKd9Ki4Rszw7CvuwKkCTi+07sEJ2KQjpw=",
            //异步通知地址
//		'notify_url' => "http://外网可访问网关地址/alipay.trade.page.pay-PHP-UTF-8/notify_url.php",
            'notify_url' => "http://www.tp5project.com/index.php/index/Alipay/notify",
            //同步跳转
//		'return_url' => "http://外网可访问网关地址/alipay.trade.page.pay-PHP-UTF-8/return_url.php",
            'return_url' => "http://www.tp5project.com/index.php/index/Alipay/returnUrl",
            //编码格式
            'charset' => "UTF-8",
            //签名方式
            'sign_type'=>"RSA2",
            //支付宝网关
            'gatewayUrl' => "https://openapi.alipaydev.com/gateway.do",
            //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
            'alipay_public_key' => "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnF1yIZGAPBJdndftqiK1s0nztfggZDTPtojoWJGKLIQmPg0DTGw3oxiQfwHQd+uxVzkON2BYmYjN7yvbRK9VAEhy+KJ7uafn8QyfNSLszHHGsEzlkCIfITAaawW0Gf989zZ7FWeMnVtA6pxYywramHN+AuJjcHsb1s9UPRft4RJA1qtp5QaXyKmIqqJDy4qil6Wlgh/Ppc7vmRI8S2YKzzZt3M2pr0Opch4VSosD4ujhXzrm24R/c8CaBpRDgsb3aATMRHQL2Ht7Sq2JZBfaCtswWrG8uMd5XdlARR4Eh53dq1HvLi/fVqUZvm+b81eEJpeQIjL4Q99T0LsR3g5CAQIDAQAB",
            //日志路径
            'log_path' => "",
        );
        $payRequestBuilder = new \AlipayTradePagePayContentBuilder();
        // 订单的各种信息,说明,主体,订单号,订单金额,支付成功后返回
        $payRequestBuilder->setBody($data['WIDsubject']);
        $payRequestBuilder->setSubject($data['WIDbody']);
        $payRequestBuilder->setTotalAmount($data['WIDtotal_amount']);
        $payRequestBuilder->setOutTradeNo($data['WIDout_trade_no']);
        $aop = new \AlipayTradeService($config);
        $response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
        echo $response;
        echo '<pre>';var_dump($data);die();
    }

	// 异步方法,这个方法里面,获取了所有的参数,然后写进日志
	// 正常情况下,是需要在这个里面判断订单是否超时,并且修改订单状态等操作,然后再写日志,写日志是因为看不到请求,除了问题只能看日志。
    public function notify(){
        $data = input('param.');
        Log::write('haha','info',$data);
    }
    // 这个是同步跳转,也是会带出各种信息,这个是支付成功或者失败的显示,说白了。
    public function returnUrl(){
       $data = input('get.');
       echo '<pre>';var_dump($data);die();
    }
}
<?php
/* *
 * 功能:支付宝电脑支付调试入口页面
 * 说明:
 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 * 这个是支付宝自带的页面,可以用这个进行测试
 */

?>
<!DOCTYPE html>
<html>
	<head>
	<title>支付宝电脑网站支付</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
    *{
        margin:0;
        padding:0;
    }
    ul,ol{
        list-style:none;
    }
    body{
        font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
    }
    .tab-head{
        margin-left:120px;
        margin-bottom:10px;
    }
    .tab-content{
        clear:left;
        display: none;
    }
    h2{
        border-bottom: solid #02aaf1 2px;
        width: 200px;
        height: 25px;
        margin: 0;
        float: left;
        text-align: center;
        font-size: 16px;
    }
    .selected{
        color: #FFFFFF;
        background-color: #02aaf1;
    }
    .show{
        clear:left;
        display: block;
    }
    .hidden{
        display:none;
    }
    .new-btn-login-sp{
        padding: 1px;
        display: inline-block;
        width: 75%;
    }
    .new-btn-login {
        background-color: #02aaf1;
        color: #FFFFFF;
        font-weight: bold;
        border: none;
        width: 100%;
        height: 30px;
        border-radius: 5px;
        font-size: 16px;
    }
    #main{
        width:100%;
        margin:0 auto;
        font-size:14px;
    }
    .red-star{
        color:#f00;
        width:10px;
        display:inline-block;
    }
    .null-star{
        color:#fff;
    }
    .content{
        margin-top:5px;
    }
    .content dt{
        width:100px;
        display:inline-block;
        float: left;
        margin-left: 20px;
        color: #666;
        font-size: 13px;
        margin-top: 8px;
    }
    .content dd{
        margin-left:120px;
        margin-bottom:5px;
    }
    .content dd input {
        width: 85%;
        height: 28px;
        border: 0;
        -webkit-border-radius: 0;
        -webkit-appearance: none;
    }
    #foot{
        margin-top:10px;
        position: absolute;
        bottom: 15px;
        width: 100%;
    }
    .foot-ul{
        width: 100%;
    }
    .foot-ul li {
        width: 100%;
        text-align:center;
        color: #666;
    }
    .note-help {
        color: #999999;
        font-size: 12px;
        line-height: 130%;
        margin-top: 5px;
        width: 100%;
        display: block;
    }
    #btn-dd{
        margin: 20px;
        text-align: center;
    }
    .foot-ul{
        width: 100%;
    }
    .one_line{
        display: block;
        height: 1px;
        border: 0;
        border-top: 1px solid #eeeeee;
        width: 100%;
        margin-left: 20px;
    }
    .am-header {
        display: -webkit-box;
        display: -ms-flexbox;
        display: box;
        width: 100%;
        position: relative;
        padding: 7px 0;
        -webkit-box-sizing: border-box;
        -ms-box-sizing: border-box;
        box-sizing: border-box;
        background: #1D222D;
        height: 50px;
        text-align: center;
        -webkit-box-pack: center;
        -ms-flex-pack: center;
        box-pack: center;
        -webkit-box-align: center;
        -ms-flex-align: center;
        box-align: center;
    }
    .am-header h1 {
        -webkit-box-flex: 1;
        -ms-flex: 1;
        box-flex: 1;
        line-height: 18px;
        text-align: center;
        font-size: 18px;
        font-weight: 300;
        color: #fff;
    }
</style>
</head>
<body text=#000000 bgColor="#ffffff" leftMargin=0 topMargin=4>
<header class="am-header">
        <h1>支付宝电脑网站支付体验入口页</h1>
</header>
<div id="main">
    <div id="tabhead" class="tab-head">
        <h2 id="tab1" class="selected" name="tab">付 款</h2>
        <h2 id="tab2" name="tab">交 易 查 询</h2>
        <h2 id="tab3" name="tab">退 款</h2>
        <h2 id="tab4" name="tab">退 款 查 询</h2>
        <h2 id="tab5" name="tab">交 易 关 闭</h2>
    </div>
<!--        <form name=alipayment action=pagepay/pagepay.php method=post target="_blank">-->
        <form name=alipayment action=payDemo method=post target="_blank">
            <div id="body1" class="show" name="divcontent">
                <dl class="content">
                    <dt>商户订单号
:</dt>
                    <dd>
                        <input id="WIDout_trade_no" name="WIDout_trade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>订单名称
:</dt>
                    <dd>
                        <input id="WIDsubject" name="WIDsubject" />
                    </dd>
                    <hr class="one_line">
                    <dt>付款金额
:</dt>
                    <dd>
                        <input id="WIDtotal_amount" name="WIDtotal_amount" />
                    </dd>
                    <hr class="one_line">
                    <dt>商品描述:</dt>
                    <dd>
                        <input id="WIDbody" name="WIDbody" />
                    </dd>
                    <hr class="one_line">
                    <dt></dt>
                    <dd id="btn-dd">
                        <span class="new-btn-login-sp">
                            <button class="new-btn-login" type="submit" style="text-align:center;">付 款</button>
                        </span>
                        <span class="note-help">如果您点击“付款”按钮,即表示您同意该次的执行操作。</span>
                    </dd>
                </dl>
            </div>
		</form>
        <form name=tradequery action=pagepay/query.php method=post target="_blank">
            <div id="body2" class="tab-content" name="divcontent">
                <dl class="content">
                    <dt>商户订单号
:</dt>
                    <dd>
                        <input id="WIDTQout_trade_no" name="WIDTQout_trade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>支付宝交易号
:</dt>
                    <dd>
                        <input id="WIDTQtrade_no" name="WIDTQtrade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt></dt>
                     <dd>
                        <span style="line-height: 28px; color:red;">注意:商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no</span>
                    </dd>
                    <dd id="btn-dd">
                        <span class="new-btn-login-sp">
                            <button class="new-btn-login" type="submit" style="text-align:center;">交 易 查 询</button>
                        </span>
                        <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“交易查询”按钮,即表示您同意该次的执行操作。</span>
                    </dd>
                </dl>
            </div>
        </form>
        <form name=traderefund action=pagepay/refund.php method=post target="_blank">
            <div id="body3" class="tab-content" name="divcontent">
                <dl class="content">
                    <dt>商户订单号
:</dt>
                    <dd>
                        <input id="WIDTRout_trade_no" name="WIDTRout_trade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>支付宝交易号
:</dt>
                    <dd>
                        <input id="WIDTRtrade_no" name="WIDTRtrade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>退款金额
:</dt>
                    <dd>
                        <input id="WIDTRrefund_amount" name="WIDTRrefund_amount" />
                    </dd>
                    <hr class="one_line">
                    <dt>退款原因
:</dt>
                    <dd>
                        <input id="WIDTRrefund_reason" name="WIDTRrefund_reason" />
                    </dd>
                    <hr class="one_line">
                    <dt>退款请求号
:</dt>
                    <dd>
                        <input id="WIDTRout_request_no" name="WIDTRout_request_no" />
                    </dd>
                    <hr class="one_line">
                    <dt></dt>
                    <dd>
                        <span style="line-height: 28px; color:red;">注意:如是部分退款,则参数退款单号(out_request_no)必传。</span>
                    </dd>
                    <dd id="btn-dd">
                        <span class="new-btn-login-sp">
                            <button class="new-btn-login" type="submit" style="text-align:center;">退 款</button>
                        </span>
                        <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“退款”按钮,即表示您同意该次的执行操作。</span>
                    </dd>
                </dl>
            </div>
        </form>
        <form name=traderefundquery action=pagepay/refundquery.php method=post target="_blank">
            <div id="body4" class="tab-content" name="divcontent">
                <dl class="content">
                    <dt>商户订单号
:</dt>
                    <dd>
                        <input id="WIDRQout_trade_no" name="WIDRQout_trade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>支付宝交易号
:</dt>
                    <dd>
                        <input id="WIDRQtrade_no" name="WIDRQtrade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>退款请求号
:</dt>
                    <dd>
                        <input id="WIDRQout_request_no" name="WIDRQout_request_no" />
                    </dd>
                    <hr class="one_line">
                    <dt></dt>
                    <dd>
                        <span style="line-height: 28px; color:red;">注意:退款请求号值(必传,退款时传的值,如果退款时没传则无法查询)商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no</span>
                    </dd>
                    <dd id="btn-dd">
                        <span class="new-btn-login-sp">
                            <button class="new-btn-login" type="submit" style="text-align:center;">退 款 查 询</button>
                        </span>
                        <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“退款查询”按钮,即表示您同意该次的执行操作。</span>
                    </dd>
                </dl>
            </div>
        </form>
        <form name=tradeclose action=pagepay/close.php method=post target="_blank">
            <div id="body5"  class="tab-content" name="divcontent">
                <dl class="content">
                    <dt>商户订单号
:</dt>
                    <dd>
                        <input id="WIDTCout_trade_no" name="WIDTCout_trade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt>支付宝交易号
:</dt>
                    <dd>
                        <input id="WIDTCtrade_no" name="WIDTCtrade_no" />
                    </dd>
                    <hr class="one_line">
                    <dt></dt>
                    <dd>
                        <span style="line-height: 28px; color:red;">注意:商户订单号和支付宝交易号不能同时为空。 trade_no、  out_trade_no如果同时存在优先取trade_no</span>
                    </dd>
                    <dd id="btn-dd">
                        <span class="new-btn-login-sp">
                            <button class="new-btn-login" type="submit" style="text-align:center;">交 易 关 闭</button>
                        </span>
                        <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“交易关闭”按钮,即表示您同意该次的执行操作。</span>
                    </dd>
                </dl>
            </div>
        </form>
        <div id="foot">
			<ul class="foot-ul">
				<li>
					支付宝版权所有 2015-2018 ALIPAY.COM
				</li>
			</ul>
		</div>
	</div>
</body>
<script language="javascript">
    var tabs = document.getElementsByName('tab');
    var contents = document.getElementsByName('divcontent');

    (function changeTab(tab) {
        for(var i = 0, len = tabs.length; i < len; i++) {
            tabs[i].onmouseover = showTab;
        }
    })();

    function showTab() {
        for(var i = 0, len = tabs.length; i < len; i++) {
            if(tabs[i] === this) {
                tabs[i].className = 'selected';
                contents[i].className = 'show';
            } else {
                tabs[i].className = '';
                contents[i].className = 'tab-content';
            }
        }
    }

	function GetDateNow() {
		var vNow = new Date();
		var sNow = "";
		sNow += String(vNow.getFullYear());
		sNow += String(vNow.getMonth() + 1);
		sNow += String(vNow.getDate());
		sNow += String(vNow.getHours());
		sNow += String(vNow.getMinutes());
		sNow += String(vNow.getSeconds());
		sNow += String(vNow.getMilliseconds());
		document.getElementById("WIDout_trade_no").value =  sNow;
		document.getElementById("WIDsubject").value = "测试";
		document.getElementById("WIDtotal_amount").value = "0.01";
	}
	GetDateNow();
</script>
</html>

至此,支付宝支付的简单测试,就完成了。
支付的时候,可能会有一个报错,each 可能会报错
需要修改 AopClient.php 415行代码,把while 改成foreach,因为php 更新后,就不支持each了。需要注意下!

在这里插入图片描述

辛苦您,留下一键三连支持下吧 万分感谢!!!

在这里插入图片描述

  • 15
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
我作为AI语言模型,无法编写、运行和测试完整的代码,以下提供一个TP5.0框架下集成支付宝支付的样例代码,供参考: // 公共方法 // 加载composer自动加载器 require __DIR__ . '/vendor/autoload.php'; // 导入需要使用的类 use think\facade\Config; use think\facade\Log; use think\facade\Request; use think\Db; /** * 发起支付宝支付 * * @param float $totalFee 支付金额 * @param string $outTradeNo 商户订单号 * @param string $body 商品描述 * @return string 支付宝支付页面 */ function aliPay($totalFee, $outTradeNo, $body) { // 支付宝必要参数 $config = Config::get('payment.ali_pay'); $appId = $config['app_id']; $merchantPrivateKey = $config['merchant_private_key']; $alipayPublicKey = $config['alipay_public_key']; $gatewayUrl = $config['gateway_url']; $charset = $config['charset']; $signType = $config['sign_type']; // 拼接支付宝请求参数 $bizContent = [ 'body' => $body, 'subject' => $body, 'out_trade_no' => $outTradeNo, 'total_amount' => $totalFee, 'product_code' => 'QUICK_WAP_WAY', ]; $params = [ 'app_id' => $appId, 'method' => 'alipay.trade.wap.pay', 'format' => 'JSON', 'charset' => $charset, 'sign_type' => $signType, 'timestamp' => date('Y-m-d H:i:s'), 'version' => '1.0', 'notify_url' => 'http://example.com/api/pay/notify', // 支付宝异步通知地址 'return_url' => 'http://example.com/order/success', // 支付宝同步通知地址 'biz_content' => json_encode($bizContent), ]; // 对支付宝请求参数进行签名 $params['sign'] = generateSign($params, $merchantPrivateKey, $signType); // 跳转至支付宝支付页面 $url = $gatewayUrl . '?' . http_build_query($params); return redirect($url); } /** * 生成支付宝参数签名 * * @param array $params 请求参数 * @param string $merchantPrivateKey 商户私钥 * @param string $signType 签名类型 * @return string 签名结果 */ function generateSign($params, $merchantPrivateKey, $signType = 'RSA2') { // 排序请求参数 ksort($params); // 拼接请求参数 $paramStr = ''; foreach ($params as $key => $value) { $paramStr .= $key . '=' . $value . '&'; } $paramStr = rtrim($paramStr, '&'); // 生成签名 $rsa = new \phpseclib\Crypt\RSA(); $rsa->setPrivateKeyFormat(\phpseclib\Crypt\RSA::PRIVATE_FORMAT_PKCS1); $rsa->setPublicKeyFormat(\phpseclib\Crypt\RSA::PUBLIC_FORMAT_PKCS1); $rsa->loadKey($merchantPrivateKey); $sign = $rsa->sign($paramStr, $signType == 'RSA2' ? \phpseclib\Crypt\RSA::SIGNATURE_SHA256 : \phpseclib\Crypt\RSA::SIGNATURE_SHA1); $sign = base64_encode($sign); return $sign; } /** * 支付宝支付异步通知处理方法 * * @param array $data 异步通知数据 * @param float $totalFee 实际支付金额 * @return bool 是否处理成功 */ function aliPayNotify($data, $totalFee) { // 验证异步通知签名 $config = Config::get('payment.ali_pay'); $alipayPublicKey = $config['alipay_public_key']; $signType = $config['sign_type']; $result = verifySign($data, $alipayPublicKey, $signType); if (!$result) { return false; } // 验证商户订单号和支付宝交易号是否已处理 $outTradeNo = $data['out_trade_no']; $tradeNo = $data['trade_no']; $orderInfo = Db::name('orders')->where('out_trade_no', $outTradeNo)->field('id,payment_status,transaction_id')->find(); if (!$orderInfo || $orderInfo['transaction_id']) { return false; } // 修改订单状态并保存交易号 Db::name('orders')->where('id', $orderInfo['id'])->update([ 'payment_status' => 1, 'transaction_id' => $tradeNo, 'payment_time' => time(), // 可选,记录支付时间 ]); // 处理完成,返回true结束回调 return true; } /** * 验证支付宝异步通知签名 * * @param array $data 异步通知数据 * @param string $alipayPublicKey 支付宝公钥 * @param string $signType 签名类型 * @return bool 是否验证通过 */ function verifySign($data, $alipayPublicKey, $signType = 'RSA2') { // 获取通知参数中的签名字符串 $sign = $data['sign']; unset($data['sign'], $data['sign_type']); // 排序请求参数 ksort($data); // 拼接请求参数 $paramStr = ''; foreach ($data as $key => $value) { $paramStr .= $key . '=' . $value . '&'; } $paramStr = rtrim($paramStr, '&'); // 验证签名 $rsa = new \phpseclib\Crypt\RSA(); $rsa->setPrivateKeyFormat(\phpseclib\Crypt\RSA::PRIVATE_FORMAT_PKCS1); $rsa->setPublicKeyFormat(\phpseclib\Crypt\RSA::PUBLIC_FORMAT_PKCS1); $rsa->loadKey($alipayPublicKey); $result = $rsa->verify($paramStr, base64_decode($sign), $signType == 'RSA2' ? \phpseclib\Crypt\RSA::SIGNATURE_SHA256 : \phpseclib\Crypt\RSA::SIGNATURE_SHA1); return $result; } // 使用样例 $totalFee = 0.01; // 支付金额 $outTradeNo = '202205271331482050'; // 商户订单号 $body = '测试商品'; // 商品描述 $payUrl = aliPay($totalFee, $outTradeNo, $body); // 获取支付页面链接 // 支付宝支付异步通知处理方法 $data = Request::param(); // 异步通知数据 $totalFee = 0.01; // 实际支付金额 $notifyResult = aliPayNotify($data, $totalFee); // 处理支付结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

付煜晨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值