微信jssdk支付

微信的开发文档花里胡哨的看的眼花....我参考多种方法总结出来一个比较简单的单文件支付文件

以下为thinkphp5的示例

需要有授权登陆方可使用!!!!

注意命名空间,代码需要根据业务逻辑修改!!!

param();
        unset($data['/shop/Pay/wexinpay_js_html']);
        // 此处根据实际业务情况生成订单 然后拿着订单去支付(请根据实际业务更改)
        $order_sn = date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        // 组合url
        $url = url("shop/Pay/getParameters", array('out_trade_no' => $order_sn));
        // 前往支付
        echo json_encode($url);
    }
    /**
     * 公众号支付 必须以get形式传递 out_trade_no 参数
     */

    /**
     * 获取jssdk需要用到的数据
     * @return array jssdk需要用到的数据
     */
    public function getParameters()
    {
        header("Access-Control-Allow-Origin: *");
        $out_trade_no = request()->param('out_trade_no');
        $openid='xxxxxx';//获取客户微信id
        // 订单数据  请根据订单号out_trade_no 从数据库中查出实际的body、total_fee、out_trade_no、product_id
        $order = array(
            'body' => 'test',// 商品描述(需要根据自己的业务修改)
            'total_fee' => 1,// 订单金额  以(分)为单位(需要根据自己的业务修改)
            'out_trade_no' => $out_trade_no,// 订单号(需要根据自己的业务修改)
            'product_id' => 1,// 商品id(需要根据自己的业务修改)
            'trade_type' => 'JSAPI',// JSAPI公众号支付
            'openid' => $openid// 获取到的openid
        );

        // 统一下单 获取prepay_id
        $unified_order = $this->unifiedOrder($order);
        // 获取当前时间戳
        $time = time();
        // 组合jssdk需要用到的数据
        $data = array(
            'appId' => 'wxpay.APPID', //appid
            'timeStamp' => strval($time), //时间戳
            'nonceStr' => $unified_order['nonce_str'],// 随机字符串
            'package' => 'prepay_id=' . $unified_order['prepay_id'],// 预支付交易会话标识
            'signType' => 'MD5'//加密方式
        );
        // 生成签名
        $data['paySign'] = $this->makeSign($data);
        echo json_encode($data);
        exit();
//        }
    }

    /**
     * 统一下单
     * @param  array $order 订单 必须包含支付所需要的参数 body(产品描述)、total_fee(订单金额)、out_trade_no(订单号)、product_id(产品id)、trade_type(类型:JSAPI,NATIVE,APP)
     */
    public function unifiedOrder($order)
    {
        // 生成随机加密盐
        $nonce_str = $this->makeCode(32);
        // 获取配置项
        $config = array(
            'appid' => 'wxpay.APPID',//appid
            'mch_id' => 'wxpay.MCHID',//mch_id
            'nonce_str' => $nonce_str,
            'spbill_create_ip' => '192.168.0.1',
            'notify_url' => 'XXXXXXXXX/Pay/isnotify'//你的域名
        );
        // 合并配置数据和订单数据
        $data = array_merge($order, $config);
        // 生成签名
        $sign = $this->makeSign($data);
        $data['sign'] = $sign;
        $xml = $this->toXml($data);
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//接收xml数据的文件
        $header[] = "Content-type: text/xml";//定义content-type为xml,注意是数组
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 兼容本地没有指定curl.cainfo路径的错误
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            // 显示报错信息;终止继续执行
            die(curl_error($ch));
        }
        curl_close($ch);
        $result = $this->toArray($response);
        // 显示错误信息
        if ($result['return_code'] == 'FAIL') {
            die($result['return_msg']);
        }
        $result['sign'] = $sign;
        $result['nonce_str'] = $nonce_str;
        return $result;
    }

    /**
     * 验证
     * @return array 返回数组格式的notify数据
     */
    public function notify()
    {
        // 获取xml
        $xml = file_get_contents('php://input', 'r');
        // 转成php数组
        $data = $this->toArray($xml);
        // 保存原sign
        $data_sign = $data['sign'];
        // sign不参与签名
        unset($data['sign']);
        $sign = $this->makeSign($data);
        // 判断签名是否正确  判断支付状态
        if ($sign === $data_sign && $data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS') {
            $result = $data;
        } else {
            $result = false;
        }
        // 返回状态给微信服务器
        if ($result) {
            $str = '';
        } else {
            $str = '';
        }
        echo $str;
        return $result;
    }

    public function isnotify()
    {
        $result = $this->notify();
        if ($result) {
//            // 验证成功 修改数据库的订单状态等 $result['out_trade_no']为订单id
            $order = $result['out_trade_no'];
//            操作数据库修改购买状态
        } else {
//           验证失败 那就没交易成功
            $order = $result['out_trade_no'];
        }
    }

    /**
     * 输出xml字符
     * @throws WxPayException
     **/
    public function toXml($data)
    {
        if (!is_array($data) || count($data) <= 0) {
            throw new WxPayException("数组数据异常!");
        }
        $xml = "";
        foreach ($data as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "";
            } else {
                $xml .= "<" . $key . ">";
            }
        }
        $xml .= "";
        return $xml;
    }

    /**
     * 生成签名
     * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
     */
    public function makeSign($data)
    {
        // 去空
        $data = array_filter($data);
        //签名步骤一:按字典序排序参数
        ksort($data);
        $string_a = http_build_query($data);
        $string_a = urldecode($string_a);
        //签名步骤二:在string后加入KEY
        $string_sign_temp = $string_a . "&key=" . config('wxpay.KEY');
        //签名步骤三:MD5加密
        $sign = md5($string_sign_temp);
        // 签名步骤四:所有字符转为大写
        $result = strtoupper($sign);
        return $result;
    }

    /**
     * 将xml转为array
     * @param  string $xml xml字符串
     * @return array       转换得到的数组
     */
    public function toArray($xml)
    {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $result = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $result;
    }

    /**
     * 生成随机串
     * @param $count 随机串个数
     */
    public function makeCode($count)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $nonce_str = '';
        for ($i = 0; $i < $count; $i++) {
            $nonce_str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $nonce_str;
    }

    /**
     * curl 请求http
     */
    public function curl_get_contents($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);                //设置访问的url地址
        // curl_setopt($ch,CURLOPT_HEADER,1);               //是否显示头部信息
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);               //设置超时
        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);   //用户访问代理 User-Agent
        curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_HOST']);        //设置 referer
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);          //跟踪301
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        //返回结果
        $r = curl_exec($ch);
        curl_close($ch);
        return $r;
    }

    /**
     *   生成10位绝不重复订单号
     */
    function order_number()
    {
        static $ORDERSN = array();                                        //静态变量
        $ors = date('ymd') . substr(time(), -5) . substr(microtime(), 2, 5);     //生成16位数字基本号
        if (isset($ORDERSN[$ors])) {                                    //判断是否有基本订单号
            $ORDERSN[$ors]++;                                           //如果存在,将值自增1
        } else {
            $ORDERSN[$ors] = 1;
        }
        return $ors . str_pad($ORDERSN[$ors], 2, '0', STR_PAD_LEFT);     //链接字符串
    }
}

前端进行请求获取参数调起微信支付




    
    
    
    调用支付






可以使用,大致逻辑没问题......新手,勿喷

你可能感兴趣的:(微信jssdk支付)