PHP 支付宝app接口

支付接口 1100 浏览

PHP 支付宝app接口。

这里是一个支付宝app支付接口的实例,有需要的同学可以看下。


| 支付申请

一般开始做支付的时候肯定已经申请好了,已经拿到appid,公钥,私钥了。这时候肯定都研究过支付文档,这里不做过多描述了。

| 开始支付(同步回调)

我的私钥使用的代码形式的,还有文件形式的不做描述。

public function alipay(){
    // 接收app端传递的参数
    $post = input('param.');
    // 必传参数
    $out_trade_no = date('YmdHis').rand(00001,99999);   // 生成订单号
    $total_amount = $post['total_amount'];    // 订单金额
    $subject      = $post['subject'];    // 描述

    $data = [
        'order_amount' => $total_amount,
        'pay_method'   => $post['pay_method'],
        'order_num'    => $out_trade_no,
        'create_time'  => time()
    ];
    // order表插入生成的订单,方法自己封装
    $result = $order->insertData($data);

    // 开始支付
    $aop = new AopClient;
    $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
    $aop->appId = '这里写appid';
    $aop->rsaPrivateKey = '这里是私钥rsaPrivateKey';  // 代码形式
    $aop->alipayrsaPublicKey = '这里是公钥alipayrsaPublicKey';  // 代码形式
    $aop->format = "json";
    $aop->charset = "UTF-8";
    $aop->signType = "RSA2";
    //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
    $request = new AlipayTradeAppPayRequest();
    //SDK已经封装掉了公共参数,这里只需要传入业务参数
    $timeout_express = '10m';
    $product_code    = 'QUICK_MSECURITY_PAY';
    $bizcontent = "{
 \"subject\": \"$subject\","
        . "\"out_trade_no\": \"$out_trade_no\","
        . "\"timeout_express\": \"$timeout_express\","
        . "\"total_amount\": \"$total_amount\","
        . "\"product_code\":\"$product_code\""
        . "}";
    // 回调接口
    $request->setNotifyUrl('http://'.$_SERVER['HTTP_HOST'].DS.'api/alipay/async');
    $request->setBizContent($bizcontent);
    //这里和普通的接口调用不同,使用的是sdkExecute
    $response = @$aop->sdkExecute($request);
    return json_encode(['result'=>$response]);
}

一般来说支付都是结合订单来做的,所以我们在支付前生成自己的订单号,回调的时候可以根据生成的订单号在数据库查询,并且根据我们生成的订单号来修改订单状态。

这里返回的结果是该订单同步回调返回的订单信息,但是同步回调可能出现一些情况导致app端没有接收到,所以我们需要以支付宝异步推送给我们的订单状态为准。

| 异步回调

当支付完成时,支付宝会直接同步回调给我们支付结果,还会异步回调我们的一个接口,推送给我们订单支付的状态。大部分情况下,我们会以该回调的结果为准确数据,最后去修改数据库的支付状态,并返回给app端。

public function async(){
    // 一般情况异步回调是get传递参数
    $get = input('param.');
    // 根据订单号查询订单信息
    $info = $order->find(['order_num'=>$get['out_trade_no']]);
    // 如果订单支付完成,输出声明
    if($info['status'] == $order::PAY_YES){
        echo 'success';exit;
    }
    
    // 添加回调日志,一般会保存回调日志,保存哪些参数自己定
    $logAdd = [
        'total_amount' => $get['total_amount'],
        'trade_no'     => $get['trade_no'],
        'out_trade_no' => $get['out_trade_no'],
        'notify_time'  => $get['notify_time'],
        'gmt_payment'  => $get['gmt_payment'],
        'trade_status' => $get['trade_status'],
    ];
    $log = new Bases('asyncLog');
    $log->insert($logAdd);
    
    // 修改订单状态,保存交易流水号和支付时间
    $order = new Bases('order');
    $save = [
        'trade_num' => $get['trade_no'],
        'pay_time'  => $get['gmt_payment'],
        'status'    => Bases::PAY_YES,
    ];
    $result = $order->update($save,['order_num'=>$get['out_trade_no']]);
    if($result){
        echo 'success';exit;
    }
}

异步回调需要注意的是:订单如果完成要输出声明,告诉支付宝已经成功了,支付宝就不会一直回调我们的接口,一般直接echo 'seccess'; 

这样我们的支付就成功啦,最后只要将数据库的状态返回到app端,就完成支付了。

不过也有可能出现极个别的特殊情况,同步异步都没有及时返回支付状态,这里也可以查询支付宝的订单接口,这样更为准确,有兴趣的同学可以自己试试。

为了避免订单出现遗漏,通常还会定期执行计划任务,将数据库的订单和支付宝的订单比对一下,确保不会出现遗漏。这里就不做过多的描述啦。


ps:这里顺便说一下,如果你的服务器是https的,回调接口可能会出现问题,如果http回调一切正常的话,可能就是https服务器签名不支持,这时候就需要换签名了。

|  版权声明:本文为博主原创文章,转载请注明出处。