ThinkPHP 框架下支付宝支付

44 篇文章 10 订阅

背景

  • 近期项目需要接入支付宝支付功能,其中开发使用了ThinkPHP3.2.3框架,通过参考开放平台文档可以知道,网站开发有两种场景,一种是手机网站支付,直接唤醒支付宝app进入支付操作;另一种多是 PC 端显示支付二维码的形式,然后使用手机的支付宝app扫描。
  • 此处主要介绍手机网站支付的实现,后期补充扫码支付。

一、接入配置

1).接入步骤

  • 第一步:创建应用并获取APPID
  • 第二步:配置密钥
  • 第三步:搭建和配置开发环境
  • 第四步:调用接口

2).配置截图

应用配置截图

3).提示说明

  • 虽然官方文档已经做的很详细、成熟,不过还是有几点需要着重提醒一下,以免不必要的纠结。
  • 应用创建成功后需要大概一到三天的审核
  • 配置密钥时建议下载其提供的加密工具,可参考RSA密钥生成方法
  • 此处我所下载的是开发平台服务端SDK中的PHP版资源,而非DEMO文件,相信两者还是有所区别的

二、手机网站支付接口实现

1).测试入口页面

  • 如下图所示,我在此创建了一个简单的入口文件,根据开发文档中的介绍是需要统一编码格式的,此处我选择的是UTF-8
    代码参考-header处理

2).html代码参考

  • 需要注意的是,接口指明需要 POST 方式进行提交请求
    入口界面参考截图

3).支付宝配置信息

  • 对于支付宝的配置信息,我写在 “Application/Common/Conf/config.php” 中
//支付宝 支付配置
    'ALI_CONFIG'  => array(
        'gatewayUrl'            => 'https://openapi.alipay.com/gateway.do',//支付宝网关(固定)'
        'appId'                 => '2017xxxxxxxx9',//APPID即创建应用后生成
        //由开发者自己生成: 请填写开发者私钥去头去尾去回车,一行字符串
        'rsaPrivateKey'         =>  'MIIExxxxxxxxxxxxxxxxxxxxxxxxxxxq',
        //支付宝公钥,由支付宝生成: 请填写支付宝公钥,一行字符串
        'alipayrsaPublicKey'    =>  'IIBxxxxxxxxxxxxxxxxxxxEFAA',
        'notifyUrl'             => 'http://www.xxx.com/m/cartpay/notify_ali', // 支付成功通知地址
        'returnUrl'             => 'http://www.xxx.com', // 支付后跳转地址
        'returnPcUrl'           => 'http://www.xxx.com/Home', // PC端扫码支付后跳转地址
    ),

4).服务端SDK导入

  • 将前面所下载的SDK放入自定义的位置,在此,我习惯放在如下的路径中,…\ThinkPHP\Library\Vendor\Alipay,特别提醒一点,对于各文件类的引用会依据代码框架而不同,需要自行确认。

5).支付接口实现

  • 在请求唤醒支付宝支付的路径中进行接口代码的编辑
    代码参考-手机端支付接口

  • 提示

>- 通过实验发现,如果在电脑端进行此功能的支付测试,
>  会报出如下的类似错误,个人认为源于手机和PC的内置配置不同
>- 对于手机网站支付需要在手机上测试,可自行配置虚拟域名手机访问即可,不要在此问题上花费不必要的时间
>- 因为本人就是在电脑有报错,手机端访问却能完美实现,
>  从而走了验证签名的过程到最后却并非错在签名,当然也不排除你的操作过程签名一定是没问题的哦.

无效签名报错
手机支付参考截图

  • 代码实现如下:
    /**
     * 支付宝支付post提交页面
     */
    public function alipay(){
        if (IS_POST){
            Vendor('Alipay.aop.AopClient');
            Vendor('Alipay.aop.request.AlipayTradeWapPayRequest');
            //$out_trade_no = I('post.order_sn');
            /*
             *  $out_trade_no 为自己业务逻辑中要支付的订单号
             *      可从POST数据中提取,具体安全起见可自行加密操作 此处仅举例测试数据
             *  $order_amount 为要进行支付的金额 注意要用小数转换
             *      例如:3.50,10.00
             *  $aliConfig 获取支付宝配置数据
             */
            $out_trade_no = '2017M'.time();
            $body = '欢迎购买商品,愿您购物愉快';
            $subject = '你好';
            $order_amount = 9.00;
            $aliConfig = C('ALI_CONFIG');
            $aop = new \AopClient();
            $aop->gatewayUrl = $aliConfig['gatewayUrl'];
            $aop->appId = $aliConfig['appId'];
            $aop->rsaPrivateKey = $aliConfig['rsaPrivateKey'];
            $aop->alipayrsaPublicKey=$aliConfig['alipayrsaPublicKey'];
            $aop->apiVersion = '1.0';
            $aop->postCharset='UTF-8';
            $aop->format='json';
            $aop->signType='RSA2';
            $request = new \AlipayTradeWapPayRequest ();
            $bizContent = "{" .
                "    \"body\":\"$body.\"," .
                "    \"subject\":\"$subject\"," .
                "    \"out_trade_no\":\"$out_trade_no\"," .
                "    \"timeout_express\":\"90m\"," .
                "    \"total_amount\":$order_amount," .
                "    \"product_code\":\"QUICK_WAP_WAY\"" .
                "  }";
            $request->setBizContent($bizContent);
            $request->setNotifyUrl($aliConfig['notifyUrl']);
            $request->setReturnUrl($aliConfig['returnUrl']);
            $result = $aop->pageExecute ( $request);
            echo $result;
        }else{
            echo 'sorry,非法请求失败';
        }
    }

6).支付成功后的通知处理

  • 此时,通过获取所提交过来的post数据,进行订单号的剥离,从而进行下一步的业务逻辑处理即可.

[注意]:

  • 接口文档中有点明,支付通知功能最后需要输出‘success
  • 此处的通知路径要与配置中确定的 ‘notifyUrl’完全一致
  /**
   * 支付宝支付通知功能
   */
    public function notify_ali(){
        $out_trade_no = I('post.out_trade_no');
        $this->toUpdatePayInfo($out_trade_no,'ali');
        echo 'success';
    }

三、电脑网站支付接口实现

  • 对比来看,其实 PC 端的代码设计与手机端大同小异,在此点明一下使用情景,可进行参考。

1).支付接口实现

电脑端支付接口代码截图

  • 提示:
测试发现,接口中定义“subject”时,对于文字的数目有要求,不能超过四个字,
至于字母似乎没有特别限制,开发过程中原想显示全部的商品名称却无法实现,还请注意。

提供的代码暂时未进行界面的设计,可参考 手机端接口思想,接收并处理订单信息后再唤醒支付宝,
当前的代码可以在公共文件配置正确的情况下,直接公网访问接口链接即可展示效果。

支付成功后的通知处理,请参考手机端实现方式.

2).实现效果截图

电脑端唤醒支付宝接口

手机扫码效果

电脑端支付方式-登录

3).代码实现如下:

 /**
     * 电脑端唤醒 支付宝扫码支付接口
     */
    public function aliPayPage(){
        $out_trade_no = '2017PC'.time();
        $order_amount = '12.88';
        $proName = "真米黑米 XXXXXX";
        Vendor('Alipay.aop.AopClient');
        Vendor('Alipay.aop.request.AlipayTradePagePayRequest');
        //构造参数
        $aop = new \AopClient();
        $aliConfig = C('ALI_CONFIG');
        $aop->gatewayUrl = $aliConfig['gatewayUrl'];
        $aop->appId = $aliConfig['appId'];
        $aop->rsaPrivateKey = $aliConfig['rsaPrivateKey'];

        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset= 'utf-8';
        $aop->format='json';
        $request = new \AlipayTradePagePayRequest ();
        $request->setReturnUrl($aliConfig['returnPcUrl']);
        $request->setNotifyUrl($aliConfig['notifyUrl']);
        $request->setBizContent(
            "{" .
            "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," .
            "    \"subject\":\"$proName\"," .
            "    \"out_trade_no\":\"$out_trade_no\"," .
            "    \"total_amount\":$order_amount," .
            "    \"body\":\"Iphone6 16G\"" .
            "  }");
        //请求
        $result = $aop->pageExecute ($request);
        //输出
        echo $result;
    }

附录 :

{
	"gmt_create": "2023-09-08 10:25:42",
	"charset": "UTF-8",
	"seller_email": "1476256088@qq.com",
	"subject": "现代膳食",
	"sign": "FGjLQQX\/PY6Okn47rAS+IRJVjZp\/bpp7L8guu28qObfgQ8eBzYrjkLeLNVZEoHKj0vlZQtpEiTlYDliBP1PFOkjnlfpTeGRb9mUaP3X6gX40yqnmsIGaqTNRnW58uuiqsgni5b3F\/gDxcMakAGQlX9zvEPgO5ASi0joZon8K1l1bIjnkMqcdXQ1IlUQQeHeGSEwQOaN\/8BcuhC0cc5AixRLie5fNQhlGt7M2Ds4Dbxm50cs0+EW164XyWWwRNHmsTwqX7zntgXSYsCSl3kLc5iGKB5x\/BBzUE4O3Ua4KsQuAJTMz1VYXWM5HIjteaES+Dfdeq6Qs2bNr2WyJ6mly1A==",
	"buyer_id": "2088702838245430",
	"body": "商品",
	"invoice_amount": "0.01",
	"notify_id": "2023090801222102547045431413451241",
	"fund_bill_list": "[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]",
	"notify_type": "trade_status_sync",
	"trade_status": "TRADE_SUCCESS",
	"receipt_amount": "0.01",
	"buyer_pay_amount": "0.01",
	"app_id": "2021003184677834",
	"sign_type": "RSA2",
	"seller_id": "2088541915302114",
	"gmt_payment": "2023-09-08 10:25:46",
	"notify_time": "2023-09-08 10:25:47",
	"version": "1.0",
	"out_trade_no": "2023090810253542281",
	"total_amount": "0.01",
	"trade_no": "2023090822001445431424023419",
	"auth_app_id": "2021003184677834",
	"buyer_logon_id": "zha***@sina.com",
	"point_amount": "0.00"
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值