首页 > 代码库 > 微信支付

微信支付

<?php
/**
 * Description of WxpayJsapi
 *微信网页支付
 * @author xinjun
 */
namespace Controller\Wx;

use Controller\Home\HomeBase;
use Framework\Net\Request as R;
use Model\Order\OrderModel;

class WxpayJsapi extends HomeBase
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 微信支付的配置信息
     * @return type
     */
    public function doPay()
    {

        //订单id
        $orderId = R::post(‘orderId‘, R::TYPE_INT);
        $orderModel = new OrderModel();
        $orderDatas = $orderModel->getOrder($orderId);
        
        //总价
        $totalPrice = $orderDatas[‘nf_orderPrice‘];
        //订单号
        $orderNum = $orderDatas[‘nf_orderNumber‘];
        //用户openid
        $openid = $_POST[‘openid‘];
        //统一下单
        $res =  $this->orderData($orderNum, $totalPrice,$openid);
        //把xml转化成数组
        $res = $this->xmlToArray($res);
        $data[‘appId‘] = parent::$appid;
        $data[‘timeStamp‘] = 1500429725;//time();
        //少于32位的随机字符串(不要特殊字符)
        $data[‘nonceStr‘] = $this->getRandCount(31);
        $data[‘package‘] = ‘prepay_id=‘.$res[‘prepay_id‘];
        $data[‘signType‘] = ‘MD5‘;
        $data[‘paySign‘] = $this->MakeSign($data);
        return $this->getData($data);  
    }

    /**
     * 统一下单
     * @param type $order
     * @param type $totalPrice
     * @return type
     */
    public function orderData($order, $totalPrice,$openid)
    {
        
        $data = http://www.mamicode.com/array();"store_info" : {"id": "SZTX001","name": "腾大餐厅","area_code": "440305","address": "科技园中一路腾讯大厦" }})
        //门店id,门店名name,门店行政区划码area_code,门店详细地址address
//        $data[‘scene_info‘] = ‘‘;
        //通过签名算法计算得出的签名值
        //第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
        //特别注意以下重要规则:
        //◆ 参数名ASCII码从小到大排序(字典序);
        //◆ 如果参数的值为空不参与签名;
        //◆ 参数名区分大小写;
        //◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
        //◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
        //第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
        //stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
        //第二步:拼接API密钥:
        //stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注:key为商户平台设置的密钥key
        //sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注:MD5签名方式
        //sign=hash_hmac("sha256",stringSignTemp,key) //注:HMAC-SHA256签名方式
        $data[‘sign‘] = $this->MakeSign($data);
        $url = ‘https://api.mch.weixin.qq.com/pay/unifiedorder‘;
        $https = ‘true‘;
        $method = ‘post‘;
        $arr = $this->arrayToXml($data);
        return $this->request($url, $https, $method, $arr);
    }

    /**
     * 生成指定长度的字符串
     * @param type $length
     * @return string
     */
    public function getRandCount($length = 8)
    {
        // 密码字符集,可任意添加你需要的字符 
        $chars = ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789‘;
        $password = ‘‘;
        for ($i = 0; $i < $length; $i++) {
            // 这里提供两种字符获取方式 
            // 第一种是使用 substr 截取$chars中的任意一位字符; 
            // 第二种是取字符数组 $chars 的任意元素 
            // $password .= substr($chars, mt_rand(0, strlen($chars) – 1), 1); 
            $password .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $password;
    }

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

    /**
     * 格式化参数格式化成url参数
     * @param type $data
     * @return type
     */
    public function ToUrlParams($data)
    {
        $buff = "";
        foreach ($data as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 数组转xml
     * @param type $arr
     * @return string
     */
    public function arrayToXml($arr)
    {
        $xml = "<root>";
        foreach ($arr as $key => $val) {
            if (is_array($val)) {
                $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
        }
        $xml .= "</root>";
        return $xml;
    }

    /**
     * xml转数组
     * @param type $xml
     * @return type
     */
    public function xmlToArray($xml)
    {
        //禁止引用外部xml实体 
        libxml_disable_entity_loader(true);
        $xmlstring = simplexml_load_string($xml, ‘SimpleXMLElement‘, LIBXML_NOCDATA);
        $val = json_decode(json_encode($xmlstring), true);
        return $val;
    }

}

  

微信支付