Thinkphp5 菜鸟版详细部署接入支付宝,PC端支付,手机端跳转支付宝APP支付,退款。

准备工作

申请沙箱环境账号,链接登录 - 支付宝,申请好就是这个样子。

配置好授权回调地址

申请好会有商家信息和买家信息,后面测试需要用到,金额是随便输入的。

下载官方sdk

我下载的是PHP版本;

thinkphp5 放在extend文件下

如图,我放在alipay文件下。就要这些文件就行了。

代码

定义个类Aliay.php,以下方法都在这个类中

namespace app\index\controller;
use think\Config;
use think\Log;
use app\common\model\Order;
class News extends BaseIndex
{
 public function a(){
    ...    
    }
public function ab){
    ...    
    }
}

支付宝配置

需要这两个公钥和私钥,要选非java语言

   'alipay' => [
        //应用ID,您的APPID。
        'app_id' => "9021000128631276",

        //商户私钥
        'merchant_private_key' => "去自己的沙箱环境复制",

        //异步通知地址
        'notify_url' => "https://suanfa.abc.top/notify_url",

        //同步跳转
        'return_url' => "https://suanfa.abc.top/return_url",

        //编码格式
        'charset' => "UTF-8",

        //签名方式
        'sign_type'=>"RSA2",

        //支付宝网关
        'gatewayUrl' => "https://openapi-sandbox.dl.alipaydev.com/gateway.do",

        //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
        'alipay_public_key' => '去自己的沙箱环境复制',
        //日志路径
        'log_path' => "",
    ]

配置的异步地址和同步地址得能正常访问200。

异步通知:支付成功后会访问这个方法,再通过返回的状态码去更改订单状态。

同步跳转:支付成功后会跳转到这个地址,并且会把订单的信息以get的方式跟在连接上,例如:https://suanfa.abc.top/return_url?charset=UTF-8&out_trade_no=202108170100021&method=alipay.trade.page.pay.return&total_amount=0.01&sign=TRdEaGa9.........

订单生成

订单的生成、付款(手机,PC,APP)、查询订单状态、退款(我只写了PC和手机站的相关,因为没有APP),官方的文档链接:小程序文档 - 支付宝文档中心

详细文档和支付方式都在里面,很详细。

先创建订单方法,代码如下,需要注意的是有PC端和手机端。PC端的话直接跳转到一个支付链接,输入密码进行支付。手机端的话会自动跳转到支付宝APP进行支付。

注意:沙箱环境的话在手机上支付,会提示“支付超时的信息”。是因为得在手机上下载一个沙箱版的APP才能正常支付。目前仅支持安卓手机下载这个软件

创建订单方法

    public function pay(){
        import('alipay.aop.AopClient', EXTEND_PATH);
        //pc
        import('alipay.aop.request.AlipayTradePagePayRequest', EXTEND_PATH);
        //手机
        import('alipay.aop.request.AlipayTradeWapPayRequest', EXTEND_PATH);
        $alipayConfig = Config::get('alipay');
        $aop = new \AopClient ();
        $aop->gatewayUrl = $alipayConfig['gatewayUrl'];
        $aop->appId = $alipayConfig['app_id'];
        $aop->rsaPrivateKey = $alipayConfig['merchant_private_key'];
        $aop->alipayrsaPublicKey=$alipayConfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType =$alipayConfig['sign_type'];
        $aop->postCharset=$alipayConfig['charset'];;
        $aop->format='json';
        $request = request()->isMobile() ? new \AlipayTradeWapPayRequest() : new \AlipayTradePagePayRequest();
        //异步接收地址,仅支持http/https,公网可访问
        $request->setNotifyUrl($alipayConfig['notify_url']);
        //同步跳转地址,仅支持http/https
        $request->setReturnUrl($alipayConfig['return_url']);
        /******必传参数******/
        $object = new \stdClass();
        //商户订单号,商家自定义,保持唯一性
        $object->out_trade_no = '20210817010100021';
        //支付金额,最小值0.01元
        $object->total_amount = 0.01;
        //订单标题,不可使用特殊符号
        $object->subject = '测试商品';
        //区分支付场景电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY手机端为QUICK_WAP_WAY
        $object->product_code = request()->isMobile() ? 'QUICK_WAP_WAY' : 'FAST_INSTANT_TRADE_PAY';
        /******可选参数******/
        $object->time_expire = date('Y-m-d H:i:s',time()+120);
        $json = json_encode($object);
        $request->setBizContent($json);
        return $aop->pageExecute($request);
//        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_request";
//        $resultCode = $result->$responseNode->code;
//        if(!empty($resultCode)&&$resultCode == 10000){
//            echo "成功";
//        } else {
//            echo "失败";
//        }
    }

支付页面,PC端,输入沙箱买家信息的用户名和密码还有支付密码

支付页面,手机端,

如果跳转到支付宝APP支付的话,得跳转到沙箱版的APP,跳转正式的支付宝APP会提示“超时”之类的。

也可以“继续浏览器付款”,那就和PC端一样了。输入沙箱的账密就可以支付。

 

异步通知

异步通知看不到结果,可以通过日志打印出来看结果

更新订单状态的时候最好把支付宝的交易单号更新进去,退款要用到这个字段。

    //异步回调地址,用作逻辑处理,更改订单状态。
    public function notify_url(){
        import('alipay.pagepay.service.AlipayTradeService', EXTEND_PATH);
        $arr=$_POST;
        $alipaySevice = new \AlipayTradeService(Config::get('alipay'));
        $alipaySevice->writeLog(var_export($_POST,true));
        $result = $alipaySevice->check($arr);
        if($result) {//验证成功
            /
            //请在这里加上商户的业务逻辑程序代
            //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
            //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
            //商户订单号
            $out_trade_no = $_POST['out_trade_no'];
            //支付宝交易号
            $trade_no = $_POST['trade_no'];
            //交易状态
            $trade_status = $_POST['trade_status'];
            if($_POST['trade_status'] == 'TRADE_FINISHED') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                //请务必判断请求时的total_amount与通知时获取的total_fee为一致的
                //如果有做过处理,不执行商户的业务程序
                //注意:
                //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
                //sjs--结束不做任何处理
            }
            else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
                //sja支付成功后逻辑处理
                if($order_info = Order::where(['out_trade_no'=>($_POST['out_trade_no'])])->find()){
                    if($order_info['state'] == 0){
                        $update = [
                            'state'=>1,
                            'trade_no'=>$trade_no,
                        ];
                        Order::where(['out_trade_no'=>($_POST['out_trade_no'])])->update($update);
                    }
                }
            }
            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
            echo "success";	//请不要修改或删除
        }else {
            //验证失败
            echo "fail";
        }
    }

 同步跳转

支付成功会跳转到这个链接,同时会带上订单信息,get可以获取到。

    //同步回调,支付成功跳转的地址,get方式获取订单信息
    public function return_url(){
        import('alipay.pagepay.service.AlipayTradeService', EXTEND_PATH);
        $arr=$_GET;
        $alipaySevice = new \AlipayTradeService(Config::get('alipay'));
        $result = $alipaySevice->check($arr);
        var_dump($result);
        if($result) {//验证成功
            /
            //请在这里加上商户的业务逻辑程序代码
            //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
            //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表
            //商户订单号
            $out_trade_no = htmlspecialchars($_GET['out_trade_no']);
            //支付宝交易号
            $trade_no = htmlspecialchars($_GET['trade_no']);
            echo "验证成功<br />支付宝交易号:".$trade_no;
            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
            //
            echo '<pre>';
            print_r($_GET);
            echo '</pre>';
            exit();
            /
        }
        else {
            //验证失败
            echo "验证失败";
        }
    }

成功后页面打印信息

订单查询

以上图的数据为例,查询一个订单的支付状态,传入的是支付宝的交易单号。


    //查询支付宝订单结果
    public function checkOrder(){
        $id = input('post.id/d') ? : 1;//查询订单
        import('alipay.aop.AopClient', EXTEND_PATH);
        import('alipay.aop.request.AlipayTradeQueryRequest', EXTEND_PATH);
        $alipayConfig = Config::get('alipay');
        $aop = new \AopClient ();
        $aop->gatewayUrl = $alipayConfig['gatewayUrl'];
        $aop->appId = $alipayConfig['app_id'];
        $aop->rsaPrivateKey = $alipayConfig['merchant_private_key'];
        $aop->alipayrsaPublicKey=$alipayConfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType =$alipayConfig['sign_type'];
        $aop->postCharset=$alipayConfig['charset'];;
        $aop->format='json';
        $request = new \AlipayTradeQueryRequest();
        $o_info = Order::get($id);
        $setBizContent = [
            'out_trade_no'=>$o_info['out_trade_no'],//可不传
            'trade_no'=>$o_info['trade_no'],
        ];
        $request->setBizContent(json_encode($setBizContent));
        $result = $aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        if(!empty($resultCode)&&$resultCode == 10000){
            echo "成功";
            //打印订单信息
            echo '<pre>';
            print_r($result);
            echo '</pre>';
            exit();
        } else {
            echo "失败";
        }
    }

结果打印

注意:查询订单的时候会报错

Class 'SignData' not found

此时修改 AopClient.php 顶部加入一行代码require_once 'SignData.php';

订单退款

    //支付宝退款
    public function tuikuan(){
        $id = input('post.id/d') ? : 1;//查询订单
        import('alipay.aop.AopClient', EXTEND_PATH);
        import('alipay.aop.request.AlipayTradeRefundRequest', EXTEND_PATH);
        $alipayConfig = Config::get('alipay');
        $aop = new \AopClient ();
        $aop->gatewayUrl = $alipayConfig['gatewayUrl'];
        $aop->appId = $alipayConfig['app_id'];
        $aop->rsaPrivateKey = $alipayConfig['merchant_private_key'];
        $aop->alipayrsaPublicKey=$alipayConfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType =$alipayConfig['sign_type'];
        $aop->postCharset=$alipayConfig['charset'];;
        $aop->format='json';
        $o_info = Order::get($id);


        $object = new \stdClass();
        $object->trade_no = $o_info['trade_no'];//订单号(支付宝订单号)
        $object->refund_amount = $o_info['order_money'];//订单金额
//        $object->out_request_no = 'HZ01RF001';
         返回参数选项,按需传入
        //$queryOptions =[
        //   'refund_detail_item_list'
        //];
        //$object->query_options = $queryOptions;
        $json = json_encode($object);
        $request = new \AlipayTradeRefundRequest();
        $request->setBizContent($json);

        $result = $aop->execute ( $request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;
        if(!empty($resultCode)&&$resultCode == 10000){
            echo "成功";
        } else {
            echo "失败";
        }
    }

 需要传入支付宝交易号,执行退款操作前需要先查询订单状态是否能退款,订单查询后的“trade_status”为TRADE_SUCCESS才能退款。

超过三个月订单会变成TRADE_FINISHED就不能进行退款操作了,支付宝官方说的是三个月后就自动变成TRADE_FINISHED了。也可以执行修改订单状态接口进行修改订单的trade_status,接口文档都有。

退款成功后再次查询该订单时,trade_status会变成TRADE_CLOSED。

我用的是沙箱的账号测试的。正式上线的话把配置文件的信息改了就行了。

希望对大家有帮助,有错误的请评论指正。

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
thinkphp5 可以通过支付宝开放平台的 SDK 来对接支付宝支付功能。首先,我们需要在 thinkphp5 的项目中引入支付宝 SDK,可以通过 Composer 来安装 SDK,或者手动下载 SDK 的包来引入。接下来,我们需要在项目中配置支付宝支付相关的参数,如支付宝AppID、App 私钥、支付宝公钥等。这些参数可以在支付宝开放平台开发者中心进行获取。 在配置好参数后,我们可以在 thinkphp5 的控制器中编写代码来实现支付宝支付的功能。一般来说,支付宝支付的流程包括生成支付订单、跳转支付页面、支付成功回调等步骤。我们可以通过调用支付宝 SDK 提供的相关方法来完成这些步骤。 首先,我们可以使用 SDK 提供的方法来生成支付订单,并将订单信息保存在数据库或其他地方。然后,我们可以使用 SDK 提供的方法来生成支付表单,将用户重定向到支付宝支付页面上。用户在支付页面上完成支付后,支付宝会将支付结果返回给我们的网站,我们可以通过配置支付宝回调地址,并编写回调方法来接收支付结果。 在接收到支付结果后,我们可以根据支付结果更新订单的状态,并做相应的业务逻辑处理。例如,如果支付成功,我们可以将订单状态改为已支付,并向用户展示支付成功的页面。 综上所述,通过引入支付宝 SDK,配置相关参数,编写相应的代码,我们就可以在 thinkphp5 中实现支付宝支付功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

驻足生活

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

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

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

打赏作者

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

抵扣说明:

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

余额充值