当前位置: 首页 > 工具软件 > Yii-wechat > 使用案例 >

PHP YII2 微信H5支付

赵开诚
2023-12-01

本demo使用框架为Yii2基础模板(框架使用什么没区别的)

    /**
     * @param $money 支付金额 元
     * @param $tmpdata 微信支付的K 公众账号ID等的json串
     * @param $server $_SERVER
     * @param $userdata 我是用户ID+随机字符串等 生成唯一商户系统内部的订单号使用
     */
    public function wechat($money, $tmpdata, $server, $userdata)
    {

        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';

        $tmpdata = json_decode($tmpdata, true);
        //微信 参数
        $key = $tmpdata['key'];//支付秘钥K
        $appid = $tmpdata['appid'];//微信分配的公众账号ID(企业号corpid即为此appId)
        $mch_id = $tmpdata['mch_id'];//微信支付分配的商户号
        $nonce_str = md5(uniqid(microtime(true), true));//随机字符串,不长于32位。推荐随机数生成算法
        $body = "商品简单描述";//商品简单描述,该字段须严格按照规范传递,具体请见参数规定 示例腾讯充值中心-QQ会员充值
        $out_trade_no = $this->order($userdata);//商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
        $total_fee = $money * 100;//订单总金额,单位为分,详见支付金额
        $spbill_create_ip = \Yii::$app->request->userIP;//必须传正确的用户端IP,支持ipv4、ipv6格式,获取方式详见获取用户ip指引  再此我使用的是YII2 框架自带的获取IP方式
        $notify_url = 'http://' . $server['HTTP_HOST'] . '/front/payment_callback/index';//接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
        $trade_type = "MWEB";//H5支付的交易类型为MWEB
        $scene_info = json_encode([
            'h5_info' => 'h5_info',
            'type' => 'Wap',
            'wap_url' => 'http://' . $server['HTTP_HOST'] . '/front/my/index',
            'wap_name' => '名称',
        ]);//该字段用于上报支付的场景信息

        /*
         * 生成签名
         */
        $sign = "appid={$appid}";
        $sign .= "&body={$body}";
        $sign .= "&mch_id={$mch_id}";
        $sign .= "&nonce_str={$nonce_str}";
        $sign .= "&notify_url={$notify_url}";
        $sign .= "&out_trade_no={$out_trade_no}";
        $sign .= "&scene_info={$scene_info}";
        $sign .= "&spbill_create_ip={$spbill_create_ip}";
        $sign .= "&total_fee={$total_fee}";
        $sign .= "&trade_type={$trade_type}";
        $sign .= "&key={$key}";
        $sign = strtoupper(md5($sign));

        //处理XML
        $data = "<xml>
<appid>{$appid}</appid>
<body>{$body}</body>
<mch_id>{$mch_id}</mch_id>
<nonce_str>{$nonce_str}</nonce_str>
<notify_url>{$notify_url}</notify_url>
<out_trade_no>{$out_trade_no}</out_trade_no>
<spbill_create_ip>{$spbill_create_ip}</spbill_create_ip>
<total_fee>{$total_fee}</total_fee>
<trade_type>{$trade_type}</trade_type>
<scene_info>{$scene_info}</scene_info>
<sign>{$sign}</sign>
</xml>";

        $data = $this->CURL($url, $data);
        $objectxml = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的XML 转换成数组
        if ($objectxml['return_code'] == 'FAIL') {
            echo json_encode(['code' => 4004, 'message' => $objectxml['return_msg']]);
            exit;
        }
        if ($objectxml['result_code'] == 'FAIL') {
            echo json_encode(['code' => 4004, 'message' => $objectxml['err_code_des']]);
            exit;
        }
        echo json_encode(['code' => 200, 'mweb_url' => $objectxml['mweb_url'], 'referer' => 'http://' . $server['HTTP_HOST']]);
        exit;
    }

商户订单号生成

    /*
     * 生成唯一32位商户订单号
     */
    public function order($userdata)
    {
        $id = $userdata['id'];
        $order = str_pad($id, 11, 'A', STR_PAD_LEFT);
        $order .= time() . rand(00000000000, 99999999999);
        return $order;
    }

curl

    public function CURL($url, $data)
    {
        $headers = array();
        $headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
        $headers[] = 'Connection: Keep-Alive';
        $headers[] = 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3';
        $headers[] = 'Accept-Encoding: gzip, deflate';
        $headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }

回调请参考我的另一篇文章 https://blog.csdn.net/qq_39733426/article/details/88657199

如有不足请评论留言,菜鸟上路请多多指教

 类似资料: