2
<?php
/**
 * 微信app 支付
 *
 * @license    
 * @link       
* @since      
*/
class wxAppPay
{
   private $key = '8102b22a111111176d9f381ec6f837';    //商户号的是key  在微信商户平台上自己设定的api密钥 32位
   private $appid = 'wxbca5555502a91e9a';              // 在微信开放平台申请的appid 
   private $mchId = '1000000';                         // 商户号
   private $payUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';  //统一下单请求接口

/*
    * total_fee      支付金额
    * out_trade_no   订单号
    * notify_url     回调地址
*/
public function doPay($params)
{
    $postData = array();
    $postData['appid']     = $this->appid;
    $postData['mch_id']     = $this->mchId;
    $postData['nonce_str'] = $this->createNoncestr();
    $postData['body']     = 'app支付';   
    $postData['out_trade_no']     = date("YmdHis");     
    $postData['total_fee']     = $params['total_fee'];  
    $postData["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"]; 
    $postData['notify_url'] = $params['notify_url'];
    $postData['trade_type'] = 'APP';
    $postData["sign"] = $this->createSign($postData);

     //把数组转化成xml格式
       $xmlData = $this->arrayToXml($postData);

       $res = $this->curl_post($this->payUrl, $xmlData); 
       $res = simplexml_load_string($res,NULL,LIBXML_NOCDATA);

    // 生成正式支付参数
    $data = array();
    $data['appid'] = $this->appid;
    $data['noncestr'] = $postData['nonce_str'];
    //微信修改接口参数,否则IOS报解析失败
    $data['package'] = 'Sign=WXPay';
    $data['partnerid'] = $this->mchId;
    $data['prepayid'] = (string)$res->prepay_id;
    $data['timestamp'] = time();
    $data['sign'] = $this->createSign($data);   //踩坑,这里一定要再签名一次,不能用上面的,也不能用返回的
    return $data;
}

//发送curl post
private function curl_post($url = '', $param = array(),$headers = array()){ 
    if (empty($url)) {
        return false;
    }
    $ch = curl_init();//初始化curl
    curl_setopt($ch, CURLOPT_URL,$url);//抓取指定网页
    curl_setopt($ch, CURLOPT_HEADER, 0);//设置header
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
    curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
             
    if($headers) curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
    $data = curl_exec($ch);//运行curl
    curl_close($ch);
    return $data;
}


//生成签名
private function createSign($params)
{
    //签名步骤一:按字典序排序参数
    ksort($params);
    $String = $this->formatBizQueryParaMap($params, false);

    //签名步骤二:在string后加入KEY
    $String = $String."&key=".$this->key;
      
    //签名步骤三:MD5加密
    $String = md5($String);

    //签名步骤四:所有字符转为大写
    $result_ = strtoupper($String);

    return $result_;

}

//按字典序排序参数
private function formatBizQueryParaMap($params,$urlencode=false)
{
    ksort($params);
    $buff = '';
    foreach($params as $key=>$val)
    {
        $buff .= $key . "=" . $val . "&";
    }
    $reqPar = substr($buff, 0, strlen($buff)-1);
    return $reqPar;
}

//将数组转换为xml格式 
private function arrayToXml($arr)
{
    $xml = "<xml>";
    foreach($arr as $key=>$val)
    {
        if(is_numeric($val))
            $xml .= '<' . $key .'>' . $val . '</' . $key . '>';
        else
            $xml .= "<".$key."><![CDATA[".$val."]]></".$key.">";
    }

    $xml .="</xml>";
    return $xml;
}


//随机字符串
private function createNoncestr($length=32)
{
    $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
    $str = '';
    for($i=0;$i<$length;$i++){
        $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return $str;
}  

}

调用
$payObj = new wxAppPay();
$params = array(
'total_fee' => 100,
'out_trade_no' => date('YmdHis'),
'notify_url' => '你自己的回调地址'
);
$data = $payObj->doPay();

小坑提示: 如果参数都没有问题,在签名工具上也是说的签名成功。很大的可能是api key 的问题。 重新设置一下key就可以了。
如果需要证书的,也是在这个商户后台去获取证书。


在路上f_x
66 声望7 粉丝

a phper