yii2 支付宝支付教程 [ 2.0 版本 ]

支付宝支付流程个人理解大致就这三步
1.前台页面将支付信息数据通过立即支付按钮 ajax提交到订单处理层
2.在订单处理层引用支付宝的接口 将支付数据写入 支付宝会抛出一个from表单 action 到支付宝的付款页面
3.用户完成付款后会调用到同步回调和异步回调进行业务逻辑的处理

第一步 前端界面
111.png

/*支付按钮点击*/
$('body').on('click', '.payBtn', function () {
    var money = $('.moneylist .current').attr('data-money');
    var author_id = $(this).attr('data-author-id');
    var itemid = $(this).attr('data-itemid');
    var pay_type = $('.payType .current').attr('data-pay-type');
    //pay_type 是区分微信和支付宝的  先无视掉pay_type ==1 的
    if (pay_type == 1) {
        //pay_type 是区分微信和支付宝的  先无视掉pay_type ==1 的
	        } else {
        $.ajax({
	                type: "POST",
	                url: "/alipay/pay",//这个就是进入到第二步将数据带入支付宝类库进行处理
	                data: params,//数据
	                async: false,
	                success: function success(data) {
            $('#payform').html(data);
        }
	            });
	        }
});

第二步 将支付数据带入到支付宝类库中处理

先放一张数据库字段的图片
22222.png

<?php
/**
 * Created by PhpStorm.
 * User: jayrui612
 * Date: 2017/5/11
 * Time: 14:27
 */

namespace frontend\controllers;

use frontend\components\payment\alipay\lib\AlipaySubmit;
use frontend\components\payment\alipay\lib\AlipayNotify;
use common\models\SanDbSponsor;
use yii\web\Controller;
use Yii;

class AlipayController extends Controller
{

    public $enableCsrfValidation = false;

    public function actionPay()
    {
        //商户订单号,商户网站订单系统中唯一订单号,必填
        $out_trade_no = $_POST['WIDout_trade_no'];

        //订单名称,必填
        $subject = $_POST['WIDsubject'];

        //付款金额,必填
        $total_fee = $_POST['WIDtotal_amount'];

        //商品描述,可空
        $body = $_POST['WIDbody'];

        //创建支付订单
            $db = Yii::$app->db;
            try {
                $sponsorData                 = $_POST['sponsor_params'];
                $sponsorData['pay_type']     = 2;   //  支付方式。(1:微信 ,2:支付宝)
                $sponsorData['pay_status']   = 0;   //  支付状态。(0:未支付,1:支付成功,2:支付失败)
                $sponsorData['price']        = $total_fee;
                $sponsorData['out_trade_no'] = $out_trade_no;
                $sponsorData['create_time']  = time();

                $db->createCommand()->insert('supe_sponsor', $sponsorData)->execute();

            } catch(\Exception $e) {
                //throw $e;
                return $this->redirect(Yii::$app->urlManager->createUrl(["news/detail", 'itemid' => $_POST['sponsor_params']['itemid']]))->send();
            }
        
        $parameter = array(
            "service"       => Yii::$app->params['pc_alipay']['service'],
            "partner"       => Yii::$app->params['pc_alipay']['partner'],
            "seller_id"     => Yii::$app->params['pc_alipay']['seller_id'],
            "payment_type"	=> Yii::$app->params['pc_alipay']['payment_type'],
            "notify_url"	=> Yii::$app->params['pc_alipay']['notify_url'],
            "return_url"	=> Yii::$app->params['pc_alipay']['return_url'],

            "anti_phishing_key"=>Yii::$app->params['pc_alipay']['anti_phishing_key'],
            "exter_invoke_ip"=>Yii::$app->params['pc_alipay']['exter_invoke_ip'],
            "out_trade_no"	=> $out_trade_no,
            "subject"	=> $subject,
            "total_fee"	=> $total_fee,
            "body"	=> $body,
            "_input_charset" => trim(strtolower(Yii::$app->params['pc_alipay']['input_charset']))
        );

        //建立请求
        $alipaySubmit = new AlipaySubmit(Yii::$app->params['pc_alipay']);
        $html_text = $alipaySubmit->buildRequestForm($parameter,"get", "确认");

        echo $html_text;

    }

第三步 用户付款 同步回调和异步回调
33333.png

这里做下说明 支付付款页面 用户付款后会自动调用 同步回调actionReturn_sync_ali 和异步回调actionReturn_async_ali
同步回调是做页面跳转之类的事情 异步回调是主要的 做订单状态的逻辑操作

下面的方法也是 在class AlipayController extends Controller下面

    /**
     *  支付宝同步回调通知
     */
    public function actionReturn_sync_ali()
    {
        $alipayNotify = new AlipayNotify(Yii::$app->params['pc_alipay']);
        $verify_result = $alipayNotify->verifyReturn();
        if($verify_result) {//验证成功
            //商户订单号
            $out_trade_no = htmlspecialchars($_GET['out_trade_no']);

            //收款方id
            $seller_id    = htmlspecialchars($_GET['seller_id']);

            //支付宝交易号
            $trade_no = $_GET['trade_no'];

            //交易状态
            $trade_status = $_GET['trade_status'];

            if($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') {
                return $this->redirect(Yii::$app->urlManager->createUrl(["news/detail"]))->send();

            } else {
                echo '<script>window.close();</script>';
            }
        }
        else {
            echo "验证失败";
        }
    }

  /**
     *  支付宝异步回调地址
     */
    public function actionReturn_async_ali()
    {

        $alipayNotify = new AlipayNotify(Yii::$app->params['pc_alipay']);

        $verify_result = $alipayNotify->verifyNotify();

        if($verify_result) {//验证成功

            //  本站订单号
            $out_trade_no   = $_POST['out_trade_no'];

            //  支付宝交易号
            $trade_no       = $_POST['trade_no'];

            //  交易状态
            $trade_status   = $_POST['trade_status'];

            //  订单金额
            $total_amount   = $_POST['total_fee'];

            //  实收金额
            $receipt_amount = $_POST['price'];

            //  回调通知的发送时间
            $notify_time    = $_POST['notify_time'];

          if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                //请务必判断请求时的total_amount与通知时获取的total_fee为一致的
                //如果有做过处理,不执行商户的业务程序
                //注意:
                //付款完成后,支付宝系统发送该交易状态通知


                if ($_POST['seller_id'] == Yii::$app->params['pc_alipay']['seller_id']
                    && $receipt_amount != 0 && ($total_amount == $receipt_amount))
                {
                    $hasRecord = SanDbSponsor::find()
                        ->where(['out_trade_no' => $out_trade_no])
                        ->one();

                    // update
                    if ($hasRecord && $hasRecord->pay_status != 1)
                    {
                        $hasRecord->pay_status  = 1;    //  支付状态。(1:支付成功 )
                        $hasRecord->create_time = strtotime($notify_time);
                        $hasRecord->save();
                    }
                }

            }
            //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——

            echo "success";		//请不要修改或删除

        } else {

            //验证失败
            echo "fail";	//请不要修改或删除

        }
    }

大致就是这样了 还有配置文件和支付宝的类库文件没有贴上

<?php
return [

    // PC 端 赞赏支付宝配置
    'pc_alipay' => [
        //  签约账号
        'partner' => '111111',
        //  收款支付宝账号,一般情况下收款账号就是签约账号
        'seller_id' => '111111',

        //商户的私钥,
        'private_key' => 'xxxxxxxx',
        //支付宝的公钥
        'alipay_public_key' => 'yyyyyyyyyyyyyy',
        // 异步通知页面路径
        'notify_url' => 'http://www.jay.com/alipay/return_async_ali.php',

        // 页面跳转同步通知页面路径
        'return_url' => "http://www.jay.com/alipay/return_sync_ali.php",

        //签名方式
        'sign_type' => strtoupper('RSA'),

        //字符编码格式 目前支持 gbk 或 utf-8
        'input_charset' => strtolower('utf-8'),

        //  ca证书路径地址,用于curl中ssl校验
        //  请保证cacert.pem文件在当前文件夹目录中
        'cacert' => getcwd().'\\cacert.pem',

        //  访问模式
        'transport' =>  'http',

        //  支付类型 ,无需修改
        'payment_type' => '1',

        //  产品类型,无需修改
        'service' => "create_direct_pay_by_user",

        //  以下防钓鱼信息,如果没开通防钓鱼功能,为空即可
        'anti_phishing_key' => '',
        'exter_invoke_ip' => ''
    ],

];

类库文件的截图
333333.png

 

文章转自他人,文章写的很清晰,只供本人学习之用

 

posted @ 2017-11-24 17:25  御世制人  阅读(919)  评论(0编辑  收藏  举报