因项目需求,最近做了下支付宝支付和微信支付,今天先介绍下支付宝支付。
去支付宝平台下载 DEMO,将文件解压放到相关目录下,我这里是放到项目根目录下的common/libs
目录下
修改配置文件,我这里是把配置参数放在config/params.php
中,然后在相关文件中用Yii::$app->params['alipay']
方法获取相关参数即可。
好了,先说支付页面,我这里就用的 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>
点击支付直接跳到这个页面,如下图所示
扫码支付成功后,支付宝会调用回调接口,在回调处处理订单即可。
接下来主要讲一下回调
如配置所示,回调在AlipayController
下的notifyurl
。
这里需注意的是,回调地址必须可以直接访问,刚开始的时候控制器继承的是BaseController
,测试的时候回调怎么都不成功,后来查看了错误日志才发现这个控制器需要登录( ),浪费了好几分钱,一分钱也是钱呐(
)。
这里讲一下我是怎么测试这个回调的,因为看不到回调返回的数据,也不知道接收的参数如何,我采用了一种比较笨的方法,在回调接口处把返回的参数写入一个表,如图所示
看看接收到的参数如何,如果表里没有任何记录的话,说明没有访问到这个回调地址,就要看下你的配置或路径是否正确。如果能收到,那么 OK,根据返回的状态进行一些操作即可。我这里是根据返回的这两种”TRADE_FINISHED” “TRADE_SUCCESS”状态做的判断,然后修改订单状态即可,当然了,可能还会涉及到一些其它的表的操作什么的,都在这里一一处理了。
基本完成后,最好先测试一下逻辑是否正确再去扫码测试支付,因为有时候可能逻辑会问题,一些修改不成功,会造成回调失败的情况,在这里我就是直接注释掉支付宝的参数,给个订单号,走一遍基本上就可以了。我一开始没有这么测试,结果浪费了几十分钱( )。
下面贴出所有代码,仅供参考
<?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。