PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

博客列表 > 商城项目-支付宝支付接入

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

岂几岂几
岂几岂几 原创
2020年07月15日 00:10:28 1164浏览

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

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

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配置项, 前者是上一步创建的回调方法, 后者是给支付宝自动跳转的站点页面路由地址, 如用户订单列表等页面.

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议