tp5实现支付宝电脑支付(详解)

首先吐槽一下支付宝的官方文档,它只是简单介绍一下开发的流程和参数,而对于新人来说如果只看它的官方文档很多时候是看不懂的,我也是边看文档边网上查资料才把它弄懂。下面我详细介绍支付宝的电脑支付是如何实现

电脑网站支付

第一步:进入官网,在电脑网站支付下载它的demo

第二步:沙箱环境

想要实现支付宝支付,你要准备一堆东西,对于只想测试的人来说这太麻烦了,而支付宝为我们提供了沙箱环境,这里面有我们开发测试需要的东西

进入沙箱环境,在沙箱应用里下载沙箱钱包(只支持扫一扫、付款码、门店详情页功能,其余功能不提供),它是用户测试扫码支付用的

第三步:把demo放进项目

一般来说支付宝demo属于扩展文件,所以我把它放到extend目录下

然后把config.php放到application\extra(注:可以不放,我放在里面只是方便调用它配置参数)

第四步: 填写配置参数

这里的参数在沙箱环境都已经有,你就根据它的注释填写就可以

支付宝的公钥和商户私钥,你要下载"支付宝开放平台开发助手",它可以生成秘钥,然后把应用公钥放在设置里面

这样他就生成支付宝公钥,你就把它放到alipay的里面的支付宝公钥,而应用私钥直接放到alipay的商户秘钥

这里我主要说一下同步和异步通知地址,新人肯定不知道是有什么用,大佬略过即可。支付宝支付成功后会执行这两个方法(注:同步是支付宝支付成功要跳转的地址),系统会把你支付的信息用POST方式异步传给你的方法。因为是异步,所以页面是没有变化的,在异步这个方法里可以写你自己的业务逻辑。比如接收值,存入数据库之类。这里有个大坑,坑了我两天,即在异步方法里是没法用session取值的,我原本想用session取用户登录id存入数据库中,后来问了师傅才知道,异步是服务器和服务器之间的交互,所以没有cookieId,没有cookieId当然没有session值。

注意:异步通知程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);

第五步: 调用支付接口

首先我们要修改extend\alipay\pagepay\Pagepay.php,因为直接调用的话会报错:

<?php
use think\Loader;
Loader::import("alipay.pagepay.service.AlipayTradeService",EXTEND_PATH);
Loader::import('alipay.pagepay.buildermodel.AlipayTradePagePayContentBuilder',EXTEND_PATH);

class Pagepay
{
    //支付入口
    public static function pay($params)
    {
        //第一步:校检参数
        self::checkParams($params);

        //第二步:构造参数
        $payRequestBuilder = new AlipayTradePagePayContentBuilder();
        $payRequestBuilder->setBody($params['t_body']);//描述
        $payRequestBuilder->setSubject($params['trade_name']);//订单名称,必填
        $payRequestBuilder->setTotalAmount($params['total_amount']);//付款金额,必填
        $payRequestBuilder->setOutTradeNo($params['out_trade_no']);//商户订单号,商户网站订单系统中唯一订单号,必填

        //第三步:获取配置
        $config = config('alipay');
        $aop = new AlipayTradeService($config);

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

    //支付检验
    private static function checkParams($params)
    {
        //商户订单号
        if(empty(trim($params['out_trade_no']))){
            self::processError("你输入的商户订单号有误!");
        }
        //订单名称
        if(empty(trim($params['trade_name']))){
            self::processError("订单名称为空!");
        }
        //付款金额
        if(floatval(trim($params['total_amount'])) <= 0){
            self::processError("付款金额有误!!");
        }
    }

    //统一错误处理接口
    private static function processError($msg)
    {
        throw new \think\Exception($msg);
    }

}

修改完之后我们就可以在控制器里调用支付宝接口:

<?php
namespace app\aliyun\controller;
use think\Controller;

//支付控制器
class Pay extends Controller
{
    public function index(){
        return $this->fetch();
    }

    //电脑支付宝接口
    public function index2(){
        //付款金额
        $total_amount = input('WIDtotal_amount');
        if($total_amount){
            $params = [
                //商户订单号,商户网站订单系统中唯一订单号,必填
                'out_trade_no'  =>  input('WIDout_trade_no'),
                //订单名称,必填
                'trade_name'       =>  input('WIDsubject'),
                //付款金额,必填
                'total_amount'  =>  $total_amount,
                //描述
                't_body'        =>  input('WIDbody'),
            ];
            import('alipay.pagepay.Pagepay',EXTEND_PATH);
            \Pagepay::pay($params);
        }
    }

//异步通知地址 public function notify_url(){ /* * * 功能:支付宝服务器异步通知页面 * 版本:2.0 * 修改日期:2017-05-01 * 说明: * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 *************************页面功能说明************************* * 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。 * 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。 * 如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知 */ import('alipay.pagepay.service.AlipayTradeService',EXTEND_PATH); $arr=$_POST; $alipaySevice = new \AlipayTradeService(config("alipay")); $alipaySevice->writeLog(var_export($_POST,true)); $result = $alipaySevice->check($arr); /* 实际验证过程建议商户添加以下校验。 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) 4、验证app_id是否为该商户本身。 */ if($result) {//验证成功 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //请在这里加上商户的业务逻辑程序代 //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 //商户订单号 $out_trade_no = $_POST['out_trade_no']; //支付宝交易号 $trade_no = $_POST['trade_no']; //交易状态 $trade_status = $_POST['trade_status'];        //描述 $body = $_POST['body']; if($_POST['trade_status'] == 'TRADE_FINISHED') { //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //请务必判断请求时的total_amount与通知时获取的total_fee为一致的 //如果有做过处理,不执行商户的业务程序 //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //请务必判断请求时的total_amount与通知时获取的total_fee为一致的 //如果有做过处理,不执行商户的业务程序 //注意: //付款完成后,支付宝系统发送该交易状态通知 } //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— echo "success"; //请不要修改或删除 }else { //验证失败 echo "fail"; } }
//同步跳转,支付成功,由客户的浏览器触发的一个通知 public function return_url(){ echo "支付宝成功"; } }

到了这一步基本就完成了,点击付款就会跳转到这个页面,我们可以使用沙箱钱包扫码支付或登录沙箱账号支付

遇到的问题及解决方案

如果是新手的第一次接入支付宝接口,或多或少遇到一些问题,今天我就把我遇到的问题总结一些

问题一:调试错误,请回到请求来源地,重新发起请求

这很有可以就是你得网关有问题,沙箱环境支付宝网关如下:

https://openapi.alipaydev.com/gateway.do

没有修改之前demo文件支付宝网关是已经写好,但默认的网关没有加dev,如果你在沙箱环境中必须加上dev

问题二:each()函数报错

支付宝支付的时候遇到的问题,这种是因为php7+以上版本抛弃了each函数导致,我们找到extend\alipay\aop\AopClient.php

while (list ($key, $val) = each ($para_temp)) {

改为

foreach ($para_temp as $key => $val) {

猜你喜欢

转载自www.cnblogs.com/bushui/p/12008774.html