Su、 发表于 2021-4-25 18:16

ThinkPHP5.1微信支付,记录踩过的坑

本帖最后由 Su、 于 2021-4-25 18:19 编辑




参考文章:https://blog.csdn.net/I_lost/article/details/104637027/?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242

SDK下载:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

完整源码下载:https://download.csdn.net/download/sp888001/17663081

把SDK的源码提取了,然后放到extend里面,具体看压缩包中的源码把,直接搭建好在config/pay.php中设置好相关信息就可以生成支付二维码了

记录下备用
其实其他地方看SDK很好理解,最关键的坑我觉得就是

appid Key MerchantId 明明都填写正确 就是报错 那么请到商户后台重置KEY```
publicfunction index()
    {

      //调用前 请到config/pay.php中设置appid Key MerchantId
      //有遇到一个坑就是 明明都填写正确 就是报错 那么请到商户后台重置
      require APP_ROOT . "/../extend/wx/WxPay.Api.php";
      require APP_ROOT . '/../extend/phpqrcode/phpqrcode.php';
      //获取支付二维码
      /**
         * 流程:
         * 1、调用统一下单,取得code_url,生成二维码
         * 2、用户扫描二维码,进行支付
         * 3、支付完成之后,微信服务器会通知支付成功
         * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
         */
      //Extend里面得微信sdk 是官方下载下来得 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
      //除了改了require_once路径 其他没做改动 可以参照自己理解
      $trade_no =DoCreateOrderNumber(); //订单号
      $Total_fee =1; //支付金额 单位分
      $shop_name = "余额充值";
      $pay_type = 1;
      $user_id = 1;
      $attach["pay_type"] = $pay_type; //交易类型 0充值 1支出
      $attach["pay_model"] = 2; //订单分类2微信支付 3支付宝支付这个里面是微信得方法 固定为2
      $attach["user_id"] = $user_id; //用户ID

      $starttime = date("YmdHis");
      $exprietime = date("YmdHis", time() + 600);
      $notify = new \NativePay();
      $input = new \WxPayUnifiedOrder();
      $input->SetBody($shop_name); //商品简单描述
      $input->SetAttach(urlencode(json_encode($attach, true))); //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据这里做好编码通知回调中也要解码 然后在生成sign不然会一直提示签名错误
      $input->SetOut_trade_no($trade_no); //商户系统内部的订单号,32个字符内、可包含字母
      $input->SetTotal_fee("$Total_fee"); //总金额
      $input->SetTime_start($starttime); //交易起始时间
      $input->SetTime_expire($exprietime); //交易结束时间
      $input->SetGoods_tag("test"); //商品标记,代金券或立减优惠功能的参数
      $input->SetNotify_url("http://你的域名/index/index/wx"); //回调地址
      $input->SetTrade_type("NATIVE");
      $input->SetProduct_id("CZ001"); //商品ID
      // echo $input->ToXml();
      $result = $notify->GetPayUrl($input);
      if ($result["return_code"] == "SUCCESS") {
            if (!empty($result['err_code_des'])) {
                return JsonReturn(-1, -200, $result["err_code_des"]);
            }
            // print_r($result);
            $url2 = $result["code_url"];
            ob_start(); //开启缓冲区
            $qrcpde = \QRcode::png($url2, false, QR_ECLEVEL_L, 8, 2);
            $img = ob_get_contents(); //获取缓冲区内容
            ob_end_clean(); //清除缓冲区内容
            return JsonReturn(-1, 200, "请在十分钟内扫码完成支付", [], ["pay_type" =>$pay_type, "pay_model" => $attach["pay_model"], "trade_no" => $trade_no, "expiretime" => strtotime($exprietime), "qrcode" => "data:png;base64," . (base64_encode($img))]);
      } else {
            return JsonReturn(-1, -200, $result["return_msg"]);
      };
    }
    public function wx()
    {

      //CreatePay 方法里面mysql需要根据自己数据库去修改 这里演示得是如何获取通知
      // 获取微信回调的数据
      $notifiedData = file_get_contents('php://input');
      $xmlObj = json_decode(xml2json($notifiedData), true);
      // addlog(-1, json_decode([], true), $xmlObj);
      // $xmlObj = '{"appid":"这里我删掉了","attach":"%7B%22pay_type%22%3A0%2C%22user_id%22%3A1%7D","bank_type":"CMB_CREDIT","cash_fee":"1","fee_type":"CNY","is_subscribe":"N","mch_id":"1607627986","nonce_str":"zfyrxd1h11u3gau8l6m7pijz2fhgu7s8","openid":"这里我删掉了","out_trade_no":"SU20210422575310299100","result_code":"SUCCESS","return_code":"SUCCESS","sign":"E384B59BDFCA202DE33AD2555EA8D7D5B213C030788BD22D369F2CD418E3348A","time_end":"20210422223327","total_fee":"1","trade_type":"NATIVE","transaction_id":"4200001049202104224836706014"}';
      //上面是回调得xml解析成json后得内容
      // $xmlObj = json_decode($xmlObj, true);
      // print_r($xmlObj);

      $jsonXML = $xmlObj;
      if ($xmlObj) {
            //如果成功返回了
            $out_trade_no = $xmlObj['out_trade_no'];
            if ($xmlObj['return_code'] == 'SUCCESS' && $xmlObj['result_code'] == 'SUCCESS') {

                //获取返回的所以参数
                //这里是要把微信返给我们的所有值,先删除sign的值,其他值 按ASCII从小到大排序,md5加密+‘key’;
                $xmlSign = "";
                $sign = "";
                foreach ($xmlObj as $k => $v) {
                  if ($k == 'sign') {
                        $xmlSign = $xmlObj[$k];
                        unset($xmlObj[$k]);
                  } else {
                        $sign .= $k . "=" . $xmlObj[$k] . "&";
                  }
                }
                $sign = substr($sign, 0, strlen($sign) - 1);
                // $sign = http_build_query($xmlObj, "", "&", PHP_QUERY_RFC3986);官方demo里面是这样生成得 不建议 会把SetAttach里面得内容编码然后导致签名错误 一个坑
                // echo $sign;

                //md5处理
                $sign = strtoupper(hash_hmac("sha256", $sign . '&key=' . config("pay.wx.Key"), config("pay.wx.Key")));
                //验签名。
                // echo $sign;
                // echo$xmlSign;
                if ($sign === $xmlSign) {
                  //验证加密后的32位值和 微信返回的sign 是否一致!!!
                  // 总订单号

                  //到这里说明微信回调成功了然后就根据参数 做自己想要得事情
                  //更多得是上面生成二维码得坑多
                  // try {
                  //   $trade_no = $xmlObj['out_trade_no'];
                  //   $attach = json_decode(urldecode($xmlObj['attach']), true);
                  //   $total_fee = $xmlObj['total_fee'];
                  //   $user_id = $attach["user_id"];
                  //   // $user_id = 1;
                  //   // print_r($attach);
                  //   if ($attach["pay_type"] == 0) {
                  //         //pay_type == 0是充值
                  //         CreatePay($user_id, $trade_no,   $attach["pay_type"], $total_fee, $attach["pay_model"]); //创建支付订单记录 更新用户余额
                  //   } else if ($attach["pay_type"] == 1) {
                  //         //购买商品
                  //         $data["status"] = 1;
                  //         $data["pay_model"] = 2;
                  //         db("tb_order_list")->where("orderID",$trade_no)->update($data); //更新交易记录
                  //         CreatePay($user_id, $trade_no,1, $total_fee, $attach["pay_model"]);
                  //   }
                  //   $ret = "<xml><return_code><!]></return_code><return_msg><!]></return_msg></xml>";
                  //   addlog(-1, json_decode(xml2json($ret), true), $jsonXML);
                  //   echo $ret;
                  // } catch (\Exception $e) {
                  //   //pay_type == 1是支出

                  //   $ret = "<xml><return_code><!]></return_code><return_msg><!]></return_msg></xml>";
                  //   addlog(-1,JsonReturn(0, -200, "error", $e->getMessage()), $jsonXML);
                  //   echo $ret;
                  // }
                } else {
                  $ret ="<xml><return_code><!]></return_code><return_msg><!]></return_msg></xml>";
                  addlog(-1, json_decode(xml2json($ret), true), $jsonXML);
                  echo $ret;
                }
            }
      } else {
            $ret ="<xml><return_code><!]></return_code><return_msg><!]></return_msg></xml>";
            addlog(-1, json_decode(xml2json($ret), true), $jsonXML);
            echo $ret;
      }
    }
```

H不讲武德 发表于 2021-4-25 18:29

wuai920981023 发表于 2021-4-25 18:30

这是什么软件?

myweb1996 发表于 2021-4-25 18:39

;wwwthinkphp 5.1 又远程代码执行漏洞,你得注意了

bwngbwng 发表于 2021-4-25 19:26

感谢分享,好高端

Su、 发表于 2021-4-25 19:26

myweb1996 发表于 2021-4-25 18:39
thinkphp 5.1 又远程代码执行漏洞,你得注意了

可以修复的

garfield1112 发表于 2021-4-25 20:24

谢谢分享,期待更多的代码分享

sixtypojie 发表于 2021-4-25 20:31

感谢楼主分享

orginly 发表于 2021-4-25 21:18

感谢分享
页: [1]
查看完整版本: ThinkPHP5.1微信支付,记录踩过的坑