Blogger Information
Blog 57
fans 3
comment 0
visits 60512
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
商城项目-支付宝支付接入
岂几岂几
Original
1193 people have browsed it

商城项目-支付宝支付接入

  • 没有支付宝商户号, 只记录老师视频中的实现过程

1. 文档

  • 支付宝开放平台的文档中心点击”网页&移动应用”链接, 进入开发文档.

    • 支付宝网页支付的使用场景跟微信差不多, 站点下单, 连通支付宝, 并调到支付宝的收银台(有支付二维码), 扫码支付成功后, 在支付成功页面自动跳回自己的站点页面.
    • 准入条件:
    • 照上面的准入条件申请完成后, 会获得: 应用id(即: APPID), 商户私钥(merchant_private_key), 支付宝公钥
  • 点击”开放能力”页签, 依次选择”电脑网站支付/支付能力/快速接入/电脑网站支付 SDK & Demo”, 下载PHP版本的资源包, 解压到laravel项目的/vendor目录下(假设重命名为/vendor/alipay).

2. 连通支付宝并跳转到支付宝收银台

  • 其中的/vendor/alipay/pagepay/pagepay.php就是生成支付页面(有支付二维码)的脚本, 拷贝其中的PHP代码, 粘贴到一个控制器方法中(假设是\admin\front\Shop@ali_pay). 调整各种require的文件路径.

    1. // 连通支付宝支付
    2. public function ali_pay(Request $req)
    3. {
    4. // 订单号
    5. $ord_no = $req->ord_no;
    6. // 用相对路径导航到alipay根目录
    7. $alipayPath = __DIR__ . "/../../../../vendor/alipay/";
    8. require_once $alipayPath . 'config.php';
    9. require_once $alipayPath . 'pagepay/service/AlipayTradeService.php';
    10. require_once $alipayPath . 'pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';
    11. //商户订单号,商户网站订单系统中唯一订单号,必填
    12. $out_trade_no = $ord_no; //trim($_POST['WIDout_trade_no']);
    13. //订单名称,必填
    14. $subject = '测试商品名称';//trim($_POST['WIDsubject']);
    15. //付款金额,必填(假设为1分钱)
    16. $total_amount = 0.01;//trim($_POST['WIDtotal_amount']);
    17. //商品描述,可空
    18. $body = '';//trim($_POST['WIDbody']);
    19. //构造参数
    20. $payRequestBuilder = new \AlipayTradePagePayContentBuilder();
    21. $payRequestBuilder->setBody($body);
    22. $payRequestBuilder->setSubject($subject);
    23. $payRequestBuilder->setTotalAmount($total_amount);
    24. $payRequestBuilder->setOutTradeNo($out_trade_no);
    25. $aop = new \AlipayTradeService($config);
    26. /**
    27. * pagePay 电脑网站支付请求
    28. * @param $builder 业务参数,使用buildmodel中的对象生成。
    29. * @param $return_url 同步跳转地址,公网可以访问--在支付宝的收银台支付完成后, 支付宝主动跳转到的站点地址.
    30. * @param $notify_url 异步通知地址,公网可以访问--类似微信支付, 支付完成后, 微信主动发送请求的站点回调地址.
    31. * @return $response 支付宝返回的信息
    32. */
    33. $response = $aop->pagePay($payRequestBuilder, $config['return_url'], $config['notify_url']);
    34. //输出表单
    35. var_dump($response);
    36. }
  • 把申请到的APPID, 商户私钥, 商户公钥填到/vendor/alipay/config.php中的对应位置.

  • /vendor/alipay/目录下新建文件夹tmp, 并把/vendor/alipay/AopSdk.php的第18行改为: define("AOP_SDK_WORK_DIR", dirname(__FILE__) . "/tmp/");;

  • 因为支付宝SDK的加密/解密方法跟laravel的加密/解密方法同名, 导致系统报错: “Cannot redeclare Decrypt()”, 所以把支付宝的加密/解密方法重命名(或删除, 逻辑是相同的. 直接用laravel提供的同名加密/解密方法即可). 重命名涉及下面3个文件, 在这3个文件中查找, 把encrypt/decrypt替换成alipayEncrypt/alipayDecrypt.

    • /vendor/alipay/aop/AopEncrypt.php
    • /vendor/alipay/aop/AopClient.php
    • /vendor/alipay/lotusphp_runtime/Cookie/Cookie.php
  • 因为PHP7+ 不再支持each()循环, 所以需要把/vendor/alipay/aop/AopClient.php的413行的while (list ($key, $val) = each ($para_temp))改为foreach($para_temp as $key => $val)

至此, 订单创建完成后, 就能跳转到支付宝的收银台了.

3. 支付完成后的业务处理

  • 下单成功后, 页面请求\admin\front\Shop@ali_pay控制器方法, 跳转到支付宝收银台.

  • 编写一个控制器方法, 作为支付完成后, 支付宝轮询发送含有支付结果信息的post请求的目标回调方法, 处理站点支付完成后的业务逻辑(假设是: \admin\front\Shop@alipay_notify). 该回调方法处理完成后, 必须返回”success”字符串, 否则支付宝会一直轮询发送请求, 直到24小时22分后不再发送.

    1. /**
    2. * 支付完成后, 支付宝发送的post请求的目标回调处理方法, 支付宝需要回调处理方法在24小时22分钟内返回'success'字符串, 否则它也会各一段时间请求一次
    3. */
    4. public function alipay_notify() {
    5. // 支付宝生成的交易号
    6. $trade_no = $_POST['trade_no'];
    7. // 站点订单号
    8. $out_trade_no = $_POST['out_trade_no'];
    9. // 支付结果, 若值为"TRADE_SUCCESS"表示支付成功.
    10. $trade_status = $_POST['trade_status'];
    11. // 支付不成功, 则执行站点支付不成功的业务逻辑, 然后返回"success"字符串给支付宝, 通知其停止轮询发送请求
    12. if($trade_status != "TRADE_SUCCESS") {
    13. // 支付不成功时的业务逻辑....
    14. return 'success';
    15. }
    16. $order = DB::table('orders')->where('ord_no', $out_trade_no)->getFirst();
    17. // 找不到订单, 则认为是无效信息, 直接返回
    18. if (!$order) {
    19. // 告诉支付宝支付结果已处理, 不需要再继续发送请求
    20. return 'success';
    21. }
    22. // 已支付过, 也不处理.
    23. if ($order['status'] == 1) {
    24. // 告诉支付宝支付结果已处理, 不需要再继续发送请求
    25. return 'success';
    26. }
    27. // 当前调用正好支付完成, 才执行操作
    28. if ($order['status'] == 0) {
    29. // 设置订单支付状态已支付
    30. DB::table('orders')->where('ord_no', $out_trade_no)->update(['status' => 1, 'trance_id' => $trade_no]);
    31. // 发送优惠券, 积分等
    32. // 发送短信通知客户等
    33. // 通知支付宝已成功处理, 不要再发送支付结果的处理请求了
    34. return 'success';
    35. }
    36. }
  • 配置/vendor/alipay/config.php中的notify_urlreturn_url配置项, 前者是上一步创建的回调方法, 后者是给支付宝自动跳转的站点页面路由地址, 如用户订单列表等页面.

Correction status:Uncorrected

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post