PHP使用支付宝SDK完成支付

时间:2024-02-29 16:08:36

最近在写支付 , 遇到了一些支付宝的坑,这里也记录分享一下

首先必须在蚂蚁金服上面有一个应用 , 并且把商户私钥 , 支付宝公钥等都设置好

然后下载支付宝php的SDK , 链接如下
https://docs.open.alipay.com/270/106291/

我用的是TP5框架

这里把SDK下好解压之后放到TP的extend目录下

首先我们需要在自己的数据库中保存以下内容 :

1.subject       //订单标题
2.total_amount  //需付款金额
3.body          //商品描述, 可空
4.out_trade_no  //订单号, 需自己生成
5.user_id       //这个不用传给支付宝

 这里附上我的生成订单号代码

//生成订单号
$osn = date(\'YmdHis\').substr(implode(NULL, array_map(\'ord\', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

以上都完成之后 , 就可以使用SDK了
这里我遇到了第一个问题 , 第三方类的引用. 由于支付宝SDK无法使用composer下载 , 导致了整个包里面的
类都没有命名空间 .
引用的时候总是报错文件不存在或类不存在

查阅了许多资料之后 , 终于找到了解决方法 :
使用Loader加载

 Loader::import(\'alipay.pagepay.service.AlipayTradeService\');
 Loader::import(\'alipay.pagepay.buildermodel.AlipayTradePagePayContentBuilder\');

这样的话即使第三方类库没有命名空间 , 也能完美引用

我把SDK之中的pagepay.php 写到了我的class之中

    //以下是简化过后的代码
    public function payment ()
    {
        $data =  $this->request->param();
        $user_id = $this->userInfo[\'id\'];
        
        //生成唯一订单号
        $osn = date(\'YmdHis\').substr(implode(NULL, array_map(\'ord\', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

        //保存订单
        $res = Db::name(\'order\')->insert([
           \'title\'  => $data[\'subject\'],   //订单标题
           \'type\'   => $data[\'type\'],      //订单类型
           \'number\' => $osn,              //订单编号
           \'money\'  => $data[\'total_amount\'],
           \'user_id\'=> $user_id,
           \'create_time\'=>time(),
        ]);

        if($res){
            //订单信息保存成功
            Loader::import(\'alipay.pagepay.service.AlipayTradeService\');
            Loader::import(\'alipay.pagepay.buildermodel.AlipayTradePagePayContentBuilder\');

            $payRequestBuilder = new \AlipayTradePagePayContentBuilder();
            $payRequestBuilder->setBody($data[\'body\']);
            $payRequestBuilder->setSubject($data[\'subject\']);
            $payRequestBuilder->setTotalAmount($data[\'total_amount\']);
            $payRequestBuilder->setOutTradeNo($osn);

            $aop = new \AlipayTradeService(config(\'alipay\'));
            /**
             * pagePay 电脑网站支付请求
             * @param $builder 业务参数,使用buildmodel中的对象生成。
             * @param $return_url 同步跳转地址,公网可以访问
             * @param $notify_url 异步通知地址,公网可以访问
             * @return $response 支付宝返回的信息
             */
            $response = $aop->pagePay($payRequestBuilder,config(\'alipay\')[\'return_url\'],config(\'alipay\')[\'notify_url\']);
        }

        echo $osn; //2018070499495653
    }

这里的config函数是我提前就在application目录下的config.php文件中部署好的

//在你application目录下的config文件之后加上支付宝的一些配置信息 
// 之后就可以直接使用config(\'alipay\')调用此数组
//一定要确保这些数据没有任何问题
   \'alipay\'=>[
            //应用ID,您的APPID。
            \'app_id\' => "",
            //商户私钥
            \'merchant_private_key\' => "",
            //异步通知地址
            \'notify_url\' => "",
            //同步跳转
            \'return_url\' => "",
            //编码格式
            \'charset\' => "UTF-8",
            //签名方式
            \'sign_type\'=>"RSA2",
            //支付宝网关
            \'gatewayUrl\' => "https://openapi.alipay.com/gateway.do",
            //支付宝公钥
            \'alipay_public_key\' => "",
    ],

至此 , 调用了pagepay之后 , 就会出现付款界面了

 

 

付款成功 , 接下来是支付宝的支付结果异步通知
此通知是支付宝单方面访问你的接口 , 你需要在此接口之中处理商户的业务逻辑
成功之后返回 “success” 即可

注意 ! 请不要把支付宝的异步请求的接口放在继承了登陆等判断的class之中 , 因为如果加了这些判断 ,
则支付宝无法正常请求我们的接口
此接口必须放在服务器上 ,如果在本地则支付宝服务器无法请求

  /**
     * 支付宝异步回调接口
     */
    public function notify_url ()
    {
        Loader::import(\'alipay.pagepay.service.AlipayTradeService\');
        $arr=$_POST;

        $alipaySevice = new \AlipayTradeService(config(\'alipay\'));
        $alipaySevice->writeLog(var_export($_POST,true));
        $result = $alipaySevice->check($arr); //这一步验签

        if($result) {//验证成功
            //商户订单号
            $out_trade_no = $_POST[\'out_trade_no\'];
            //订单金额
            $total_amount = $_POST[\'total_amount\'];
            //支付宝交易号
            $trade_no = $_POST[\'trade_no\'];
            //交易状态
            $trade_status = $_POST[\'trade_status\'];

            if($_POST[\'trade_status\'] == \'TRADE_FINISHED\') {
                //--交易结束执行的业务逻辑--
            }else if ($_POST[\'trade_status\'] == \'TRADE_SUCCESS\') {
                //--交易支付成功执行的业务逻辑--
            }
            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
            echo "success";    //请不要修改或删除
        }else {
            //验证失败
            echo "fail";
        }
    }

到这里使用支付宝SDK就结束了
这里还说一下 , 你的服务器必须开启openssl拓展 , 调用check验签 , 必需开启openssl