Yii2 支付宝支付 扫码支付

PHP/Mysql/Nginx Alice 5年前 (2018-10-30) 2439次浏览 4个评论

因项目需求,最近做了下支付宝支付和微信支付,今天先介绍下支付宝支付。

去支付宝平台下载 DEMO,将文件解压放到相关目录下,我这里是放到项目根目录下的common/libs目录下

Yii2 支付宝支付 扫码支付

修改配置文件,我这里是把配置参数放在config/params.php中,然后在相关文件中用Yii::$app->params['alipay']方法获取相关参数即可。

Yii2 支付宝支付 扫码支付

好了,先说支付页面,我这里就用的 demo 的支付页面,稍微做下调整就能用,将其中的一些参数换成自己的就可以了,下面是代码,供参考

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>支付</title>
</head>
<body>
<?php
require_once __DIR__ . '/../../../common/libs/alipay/pagepay/service/AlipayTradeService.php';
require_once __DIR__ . '/../../../common/libs/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';
$order_id = Yii::$app->request->get('order_id', '');

$order = \common\models\Order::findOne($order_id);

if ($order == null) {
    throw new \yii\web\NotFoundHttpException('The requested page does not exist.');
}

$exp = unserialize($order['metadata']);

$config = Yii::$app->params['alipay'];

$out_trade_no = trim($order['order_num']);
$subject = trim($order['order_name']);
$total_amount = trim($order['pay_amount']) * $exp['rate'];
$body = trim($order['description']);

$payRequestBuilder = new \AlipayTradePagePayContentBuilder();
$payRequestBuilder->setBody($body);
$payRequestBuilder->setSubject($subject);
$payRequestBuilder->setTotalAmount($total_amount);
$payRequestBuilder->setOutTradeNo($out_trade_no);

$aop = new \AlipayTradeService($config);

$response = $aop->pagePay($payRequestBuilder, $config['return_url'], $config['notify_url']);

//输出表单
echo $response;
?>
</body>
</html>

点击支付直接跳到这个页面,如下图所示

Yii2 支付宝支付 扫码支付

扫码支付成功后,支付宝会调用回调接口,在回调处处理订单即可。

接下来主要讲一下回调

如配置所示,回调在AlipayController下的notifyurl

这里需注意的是,回调地址必须可以直接访问,刚开始的时候控制器继承的是BaseController,测试的时候回调怎么都不成功,后来查看了错误日志才发现这个控制器需要登录( :arrow: ),浪费了好几分钱,一分钱也是钱呐( :lol: )。

这里讲一下我是怎么测试这个回调的,因为看不到回调返回的数据,也不知道接收的参数如何,我采用了一种比较笨的方法,在回调接口处把返回的参数写入一个表,如图所示

Yii2 支付宝支付 扫码支付

看看接收到的参数如何,如果表里没有任何记录的话,说明没有访问到这个回调地址,就要看下你的配置或路径是否正确。如果能收到,那么 OK,根据返回的状态进行一些操作即可。我这里是根据返回的这两种”TRADE_FINISHED” “TRADE_SUCCESS”状态做的判断,然后修改订单状态即可,当然了,可能还会涉及到一些其它的表的操作什么的,都在这里一一处理了。

基本完成后,最好先测试一下逻辑是否正确再去扫码测试支付,因为有时候可能逻辑会问题,一些修改不成功,会造成回调失败的情况,在这里我就是直接注释掉支付宝的参数,给个订单号,走一遍基本上就可以了。我一开始没有这么测试,结果浪费了几十分钱( :cry: )。

下面贴出所有代码,仅供参考

<?php
namespace backend\controllers;

//这里引用相关库,因为没用命名空间,直接用的 require_once
require_once __DIR__ . '/../../common/libs/alipay/pagepay/service/AlipayTradeService.php';
require_once __DIR__ . '/../../common/libs/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';


use backend\service\PayService;
use common\models\Order;
use Yii;
use yii\web\Controller;

class AlipayController extends Controller
{
    public $enableCsrfValidation = false;
    public $layout = false;

    //支付页面
    public function actionIndex()
    {
        return $this->render('index');
    }

    //回调
    public function actionNotifyurl()
    {
        //获取配置参数
        $config = Yii::$app->params['alipay'];

        $arr = $_POST;
        $alipaySevice = new \AlipayTradeService($config);
        $result = $alipaySevice->check($arr);

        if($result) {
            $out_trade_no = $_POST['out_trade_no'];
            $order = Order::find()->where(['order_num' => $out_trade_no])->one();
            $exp = unserialize($order['metadata']);

            if($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
                if ($order['status'] == Order::STATUS_INIT && ($order['pay_amount'] * $exp['rate'] == $_POST['total_amount'])) {
                    //相关逻辑处理
                    //我这里是做了一个类,各种支付的逻辑处理都放到一起,这样比较方便
                    $payService = new PayService();
                    $payService->ali_wxpay($order, Order::PAY_SOURCE_ALIPAY);
                }
                //看文档,最后这个 success 是必须的
                echo "success";
            }
        } else {
            echo "fail";
        }
    }

    //支付成功后,需要跳转到的页面
    public function actionReturnurl()
    {
        return $this->redirect(['/account/index']);
    }
}

代码不是很多,怎么样,是不是 so easy。 :mrgreen:


女程序员博客 , 版权所有丨本站采用BY-NC-SA协议进行授权 , 转载请注明Yii2 支付宝支付 扫码支付

【声明】:本博客仅为分享信息,不参与任何交易,也非中介,所有内容仅代表个人观点,均不作直接、间接、法定、约定的保证,读者购买风险自担。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。

【关于安全】:任何 IDC 都有倒闭和跑路的可能,备份永远是最佳选择,服务器也是机器,不勤备份是对自己极不负责的表现,请保持良好的备份习惯。

喜欢 (1)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(4)个小伙伴在吐槽
  1. 对于我来说还是 难!!!
    筑楼2018-12-05 21:44 回复
  2. 突然发现 貌似你们用的主题 评论功能都有问题啊!
    听雨轩2019-04-09 17:15 回复
    • Alice
      是吗?一样的问题?
      Alice2019-04-10 21:57 回复