Thinkphp8接入alipay sdk使用pc网站支付

官网下载php版本的alipay-php-demo

  1. 解压后复制文件夹中的aop文件包,粘贴到tp8/extend目录下,并修改目录名为alipay_aop;。
  2. 修改alipay_aop目录下AopClient.php文件,在第一行加入命名空间:namespace alipay_aop;
<?php
namespace alipay_aop;
require_once 'AopEncrypt.php';
class AopClient {
  ......
}
  1. 修改alipay_aop/request/目录下AlipayTradePagePayRequest.php文件,加入命名空间:alipay_aop\request;
<?php
namespace alipay_aop\request;
/**
 * ALIPAY API: alipay.trade.page.pay request
 *
 * @author auto create
 * @since 1.0, 2017-04-06 15:55:36
 */
class AlipayTradePagePayRequest
{
    /** 
     * 统一收单下单并支付页面接口
     **/
  ......
}

使用

  1. tp8/app/model目录下新建AlipayModel.php文件
<?php
namespace app\model;
use alipay_aop\AopClient;
use alipay_aop\request\AlipayTradePagePayRequest;

class AlipayModel {
    //应用ID,APPID。
    // private $appId = "";
    //商户私钥
    // private $merchantPrivateKey = "";
    //异步通知地址
    private $notifyUrl = "https://api.mydomain.com/notify.html";
    //同步跳转
    private $returnUrl = "https://api.mydomain.com/returns.html";
    //编码格式
    private $charset = "UTF-8";
    //签名方式
    private $signType = "RSA2";
    //支付宝网关
    private $gatewayUrl = "https://openapi.alipay.com/gateway.do";
    // 支付宝公钥,
    private $alipayPublicKey = "MIIBIjANBgkqhkiG9w0lnUw2TTjDFwj3D1Qk3iSKUAZg9CTcQB129+5DRlLkzEfWyffnUkUtA4VYLS8r6ycvG0iYHd6tN4muXg0b6029iaWzjuR9meJ079KIKAqQkSdfCESBJMSsVp62a7gVbIwXILDn3P6jGaiuA8317yCCd0bhEw9JeKLGmlQOaBUwIDAQAB";
    //开启AES加密后密钥
    // private $encryptKey = "";

    // 电脑网站支付下单
    public function webPagePay($data, $channelConfig) {
        //商户订单号,商户网站订单系统中唯一订单号,必填
        $out_trade_no = trim($data['platform_order_no']);

        //订单名称,必填
        $subject = trim($data['subject']);

        //付款金额,必填
        $total_amount = trim($data['amount']);

        //商品描述,可空
        $body = trim($data['remark']);

        /** PHP 语言 普通公钥签名
         *  $aop = new AopClient;
        $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
        $aop->appId = "app_id";
        $aop->rsaPrivateKey = '请填写开发者私钥去头去尾去回车,一行字符串';
        $aop->format = "json";
        $aop->charset = "UTF-8";
        $aop->signType = "RSA2";
        $aop->alipayrsaPublicKey = '请填写支付宝公钥,一行字符串';
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        $request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数,这里只需要传入业务参数
        $request->setBizContent("{\"body\":\"我是测试数据\","
        . "\"subject\": \"App支付测试\","
        . "\"out_trade_no\": \"20170125test01\","
        . "\"timeout_express\": \"30m\","
        . "\"total_amount\": \"0.01\","
        . "\"product_code\":\"QUICK_MSECURITY_PAY\""
        . "}");
        $request->setNotifyUrl("商户外网可以访问的异步地址");
        //这里和普通的接口调用不同,使用的是sdkExecute
        $response = $aop->sdkExecute($request);
        //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题
        echo htmlspecialchars($response);//就是orderString 可以直接给客户端请求,无需再做处理。
         *
         *
         */
        $aop = new AopClient();
        $aop->gatewayUrl = $channelConfig['gateway'];
        $aop->appId = $channelConfig['appid'];
        $aop->format = "json";
        $aop->charset = $this->charset;
        $aop->signType = $this->signType;
        $aop->encryptKey = $channelConfig['encryptKey'];
        $aop->alipayrsaPublicKey = $channelConfig['providerPublicKey'];
        $aop->rsaPrivateKey = $channelConfig['merchantPrivateKey'];

        $biz_content = json_encode([
            'out_trade_no' => $out_trade_no,
            'product_code' => 'FAST_INSTANT_TRADE_PAY', // 固定值
            'total_amount' => $total_amount,
            'subject' => $subject,
            'timeout_express' => '120m',
            // 'qr_pay_mode'    => '0',
        ]);
        // 判断是否需要内容aes加密
        $needEncrypt = empty(trim($channelConfig['encryptKey'])) ? false : true;

        $payRequest = new AlipayTradePagePayRequest();
        $payRequest->setReturnUrl($this->returnUrl);
        $payRequest->setNotifyUrl($this->notifyUrl);
        $payRequest->setNeedEncrypt($needEncrypt);
        // $payRequest->setQrPayMode('0');
        $payRequest->setBizContent($biz_content);
        $response = $aop->sdkExecute($payRequest);

        return $channelConfig['gateway'] . '?' . $response;
        // echo('<a href="https://openapi.alipay.com/gateway.do?'.$response.'">');
    }

    // 查询接口
    public function query() {
          ......
    }
    /**
     * 验签方法
     * @param $arr 验签支付宝返回的信息,使用支付宝公钥。
     * @return boolean
     */
    function checkSign($data) {
        /** 异步同步通知数据验签
         *  $aop = new AopClient ();
        //编码格式
        $aop->postCharset="UTF-8";
        //支付宝公钥赋值
        $aop->alipayrsaPublicKey="";
        //回调的待验签字符串
        $_POST="buyer_id=20880****42&total_amount=0.01&body=煜雨电脑网站测试&trade_no=2019032922001481941025940236&notify_time=2019-03-29 19:42:04&subject=煜雨测试电脑网站支付&sign_type=RSA2&charset=UTF-8&auth_app_id=201****22&notify_type=trade_status_sync&invoice_amount=0.01&out_trade_no=20190329ygyg45484544100003&trade_status=TRADE_SUCCESS&gmt_payment=2019-03-29 19:42:03&version=1.0&point_amount=0.00&sign=LDDUIGQmc+1qNtk3oyoAKVeMUKTngdX3ZjVeZOK0EjiPDJ/+Nk+0WSqcE6J7/5xb96Z/vP0yY3pVhZUiFVJ1G45/ys/HAleHh+EERZ1lkCkule1sSyaGFTKQGKx4uHpTyqIgRB1bouf19RPbSx1EkA0VkCarSy9G/OEG5Qmg8UdL2dRulMhlbOHS7tdMJJycDA8vOspOUMeQmk/H6IK9R2Kou5hN2T3KR1GWLYFK+z1jeZhQB3q52lZynO0OFjSzU4aQUBMW5QskQppBYd/ghtY/2YP+2H6YVGNgVmaheZMQ3PVTBALEV+8rZa91salH9DkKN2UCYGvNSNDT1VGCTQ==&gmt_create=2019-03-29 19:42:00&buyer_pay_amount=0.01&receipt_amount=0.01&fund_bill_list=[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]&seller_id=208850*0**&app_id=20141****2&notify_id=2019032900222194204081941005192208";
        //签名方式
        $sign_type="RSA2";
        //把字符串通过&符号拆分成数组
        $data = explode('&', $_POST);
        $params = array();
        //遍历数组
        foreach ($data as $param) {
        $item = explode('=', $param,"2");
        $params[$item[0]] = $item[1];
        }
        //输出拆分后的数据
        //print_r($params);
        //验签代码
        $flag = $aop->rsaCheckV1($params, null, $sign_type);
        //输出验签结果
        //echo $flag;
        if ($flag)
        {
        echo "success";
        }
        else
        {
        echo "fail";
        }
         *
         *
         */
        $aop = new AopClient();
        $aop->postCharset = $this->charset;
        $aop->signType = $this->signType;
        $aop->alipayrsaPublicKey = $this->alipayPublicKey;
        //验签代码
        $flag = $aop->rsaCheckV1($data, null, $this->signType);
        // var_dump($flag);
        return $flag;
    }
}
  1. 调用
$alipayModel = new AlipayModel();
// 这里是向支付宝提交平台订单号
$data['platform_order_no'] = $orderNo;
// 读取商户通道配置文件
$config = [
    'appid' => $hasChannel['appid'],
    'gateway' => $hasChannel['gateway'],
    'merchantPrivateKey' => $hasChannel['private_key'],
    'providerPublicKey' => $hasChannel['provider_public_key'],
    'encryptKey' => $hasChannel['encrypt_key'],
];
$returnPayLink = $alipayModel->webPagePay($data, $config);
  1. 接收支付宝异步通知时验证签名:
<?php
namespace app\controller;

use app\model\AlipayModel;
// 这里一定要加入header设置,否则支付宝收到的返回值可能会在success或fail前加入一个空格,导致支付宝会多次回调
header('Content-Type: text/plain; charset=utf-8');
class Notify{
  public function Index(){
    $data = $_POST;
    // 写入日志
    $this->debugModel->writeLog(var_export($_POST, true));
    // 验证支付宝接口签名
    $alipayModel = new AlipayModel();
    $result = $alipayModel->checkSign($data);
    if ($result) {
      echo "success";
    }else{
      echo "fail";
    }
  }
}

一定要加入header设置,否则支付宝收到的返回值可能会在success或fail前加入一个空格,导致支付宝会多次回调

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容