微信支付相关

1:先封装一个微信支付类weixin.php

<?php

/**
 * 
 * 微信api基础类
 *
 */
 
class Weixin{
	
	public $app_id='';
    public $app_secret='';
    public $partnerid = '';
    public $paySignKey = '';
    public $partnerKey ='';
	
	public function __construct()
	{
		$this->app_id = "XXXXXXXX";
        $this->app_secret = "XXXXXXXX";
        $this->partnerid = "XXXXXXXX";
        $this->paySignKey = "XXXXXXXX";
        $this->partnerKey = "XXXXXXXX";
	}
	
	public function open($api_url){
		$ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $api_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $ret = curl_exec($ch);
        $error = curl_error($ch);

        if($error){
            return false;
        }

        $json = json_decode($ret, TRUE);

        return $json;
    }
    
    
    public function post($api_url,$data){
	    $context = array('http' => array('method' => "POST", 'header' => "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) \r\n Accept: */*", 'content' => $data));
	    $stream_context = stream_context_create($context);
	    $ret = @file_get_contents($api_url, FALSE, $stream_context);
	    return json_decode($ret, true);
    }
    
    
    
    /**
     * 获取access token
     * @return array
     */
    public function access_token($cache=true){
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->app_id&secret=$this->app_secret";
        $access_token = '';
        $cachefile = "./token.txt";
        if ( file_exists($cachefile) && $cache ){
        	$access_token = file_get_contents($cachefile);
        	return $access_token;
    	}
        try{
            $ret = $this->open($url);
            @unlink($cachefile);
            file_put_contents($cachefile,$ret['access_token'],FILE_APPEND );
            return $ret['access_token'];
        }catch(Exception $e){
            return '';
        }
        
    }
    
    
    /**
 	* 除去数组中的空值和签名参数
 	* @param $para 签名参数组
 	* return 去掉空值与签名参数后的新签名参数组
 	*/
	
	public	function parafilter($para) {
		$para_filter = array();
		foreach ($para as $key => $val ) {
			if($key == "sign_method" || $key == "sign" ||$val == "")continue;
			else	$para_filter[$key] = $para[$key];
		}
		return $para_filter;
	}
	
	/**
	 * 对数组排序
 	* @param $para 排序前的数组
 	* return 排序后的数组
 	*/
	public function argsort($para) {
		ksort($para);
		reset($para);
		return $para;
	}
	
	/**
	 * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
	 * @param $para 需要拼接的数组
	 * return 拼接完成以后的字符串
	 */
	public function createlinkstring($para) {
		$arg  = "";
		foreach ($para as $key => $val ) {
			$arg.=strtolower($key)."=".$val."&";
		}
		//去掉最后一个&字符
		$arg = substr($arg,0,count($arg)-2);
		
		//如果存在转义字符,那么去掉转义
		if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
		
		return $arg;	

	}

    /**
     * 创建app_signature
     * @return string
     */
    public function create_app_signature( $arr ){
        $para = $this->parafilter($arr);
		$para = $this->argsort($para); 
		$signValue = sha1($this->createlinkstring($para));
        return $signValue;
    }
    
    
    /**
     * 创建sign
     * @return string
     */
    public function create_sign( $arr ){
        $para = $this->parafilter($arr);
		$para = $this->argsort($para);
		$signValue = $this->createlinkstring($para);
		$signValue = $signValue."&key=".$this->partnerKey;
		$signValue = strtoupper(md5($signValue));	
        return $signValue;
    }
    
    
	/**
     * 获取用户基本信息
     * @return array
     */
    public function user_info($openid){
    	$ret = $this->open("https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$this->access_token()."&openid=$openid&lang=zh_CN");
    	if ( in_array($ret['errcode'],array(40001,40002,42001)) ){
        	$this->access_token(false);
         	return $this->user_info($openid);
        }
        return $ret;
    }
    
    
    /**
     * 标记客户的投诉处理状态
     * @return bool
     */
    public function payfeedback_update($openid,$feedbackid){
    	 $url = "https://api.weixin.qq.com/payfeedback/update?access_token=".$this->access_token()."&openid=".$openid."&feedbackid=".$feedbackid;
         $ret = $this->open($url);
         if ( in_array($ret['errcode'],array(40001,40002,42001)) ){
         	$this->access_token(false);
         	return $this->payfeedback_update($openid,$feedbackid);
         }
         return $ret;
    }
    
    /**
     * 发货通知
     *  
     * openid					购买用户的 OpenId,这个已经放在最终支付结果通知的 PostData 里了 
     * transid					交易单号
     * out_trade_no				第三方订单号
     * deliver_timestamp		发货时间戳
     * deliver_status			发货状态	1:成功 0:失败
     * deliver_msg				发货状态信息	
    
     *
     */
    public function delivernotify($openid,$transid,$out_trade_no,$deliver_status=1,$deliver_msg='ok'){
    	$post = array();
    	$post['appid'] = $this->app_id;
    	$post['appkey'] = $this->paySignKey;
    	$post['openid'] = $openid;
    	$post['transid'] = $transid;
    	$post['out_trade_no'] = $out_trade_no;
    	$post['deliver_timestamp'] = time();
    	$post['deliver_status'] = $deliver_status;
    	$post['deliver_msg'] = $deliver_msg;
    	
    	$post['app_signature'] = $this->create_app_signature($post);
    	$post['sign_method'] = "SHA1";
    	
    	$data = json_encode($post);
    	
    	$url = 'https://api.weixin.qq.com/pay/delivernotify?access_token=' . $this->access_token();
	    $ret = $this->post($url,$data);
	    if ( in_array($ret['errcode'],array(40001,40002,42001)) ){
         	$this->access_token(false);
         	return $this->delivernotify($openid,$transid,$out_trade_no,$deliver_status,$deliver_msg);
        }
	    return $ret;
    }
    
    
     /**
     * 订单查询
     * @return array
     */
    public function order_query($out_trade_no){
    	$post = array();
    	$post['appid'] = $this->app_id;
    	$sign = $this->create_sign(array('out_trade_no' => $out_trade_no , 'partner' => $this->partnerid ));
    	$post['package'] = "out_trade_no=$out_trade_no&partner=".$this->partnerid."&sign=$sign";
    	$post['timestamp'] = time();
    	
    	$post['app_signature'] = $this->create_app_signature(array('appid' => $this->app_id , 'appkey' => $this->paySignKey , 'package' => $post['package'] , 'timestamp' => $post['timestamp'] ));
    	$post['sign_method'] = "SHA1";
    	
    	$data = json_encode($post);
    	
    	$url = 'https://api.weixin.qq.com/pay/orderquery?access_token=' . $this->access_token();
	    $ret = $this->post($url,$data);
	    if ( in_array($ret['errcode'],array(40001,40002,42001)) ){
         	$this->access_token(false);
         	return $this->order_query($out_trade_no);
        }
	    return $ret;
    }
    
    
    /**
     * 构建支付请求数组
     * @return array
     */
    public function bulidForm($parameter){
    	$parameter['package'] = $this->buildPackage($parameter); // 生成订单package
       	$paySignArray = array('appid' => $this->app_id, 'appkey' => $this->paySignKey ,'noncestr' => $parameter['noncestr'], 'package' => $parameter['package'], 'timestamp' => $parameter['timestamp']);
       	$parameter['paysign'] = $this->create_app_signature($paySignArray);
       	return $parameter;
    }
    
    
    /**
     * 构建支付请求包
     * @return string
     */
    public function buildPackage($parameter){
    	$filter = array('bank_type', 'body', 'attach', 'partner', 'out_trade_no', 'total_fee', 'fee_type', 'notify_url','spbill_create_ip', 'time_start', 'time_expire', 'transport_fee', 'product_fee', 'goods_tag', 'input_charset');
        $base = array(
            'bank_type' => 'WX',
            'fee_type' => '1',
            'input_charset' => 'UTF-8',
            'partner' => $this->partnerid
        );
        $parameter = array_merge($parameter, $base);
        $array = array();
        foreach ($parameter as $k => $v) {
            if (in_array($k, $filter)) {
                $array[$k] = $v;
            }
        }
        ksort($array);
        $signPars = '';
        reset($array);
        foreach ($array as $k => $v) {
            $signPars .= strtolower($k) . "=" . $v . "&";
        }
        $sign = strtoupper(md5($signPars . 'key=' . $this->partnerKey));
        $signPars = '';
        reset($array);
        foreach ($array as $k => $v) {
            $signPars .= strtolower($k) . "=" . urlencode($v) . "&";
        }        
        
        return $signPars . 'sign=' . $sign;
    }
    
    
    /**
     * 从xml中获取数组
     * @return array
     */
    public function getXmlArray() {
		$postStr = @file_get_contents('php://input');
		if ($postStr) {
			$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            if (! is_object($postObj)) {
                return false;
            }
            $array = json_decode(json_encode($postObj), true); // xml对象转数组
            return array_change_key_case($array, CASE_LOWER); // 所有键小写
        } else {
            return false;
        }        
    }
    
    
    /**
	 * 验证服务器通知
	 * @param array $data
	 * @return array
	 */
	public function verifyNotify($post,$sign) {
        $para = $this->parafilter($post);
		$para = $this->argsort($para); 
		$signValue = $this->createlinkstring($para);
		$signValue = $signValue."&key=".$this->partnerKey;
		$signValue = strtoupper(md5($signValue));
		if ( $sign == $signValue ){
			return true;	
		}else{
			return false;
		}
		
	}
	
	
	 /**
	 * 是否支持微信支付
	 * @return bool
	 */
	public function is_show_pay($agent) {
		$ag1  = strstr($agent,"MicroMessenger");
		$ag2 = explode("/",$ag1);
		$ver = floatval($ag2[1]);
		if ( $ver < 5.0 || empty($aid) ){
			return false;
    	}else{
    		return true;
    	}
	}
	
	
	
    
    
}

2:支付实例pay.php


<?php

	include 'weixin.php';
	
	$weixin = new Weixin();
	
	$data = array(
    	'timestamp' => time(), 						// 位时间戳
    	'noncestr' => md5(uniqid(time(),true)), 					// 随机字符串
		'body' => 'test', 		// 商品描述
		'out_trade_no' => time().rand(111111,999999), // 本站订单号
		'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], // 微信用户IP
		'total_fee' => 1, // 支付金额 单位:分
	);
	
	$data += $weixin->bulidForm($data);

	$data['appId'] =  $weixin->app_id;
	$data['partnerid'] =  $weixin->partnerid;
	$data['partnerKey'] =  $weixin->partnerKey;
	$data['paySignKey'] =  $weixin->paySignKey;
	$data['successUrl'] =  'http://www.xxx.com/successurl';
		
		
?>
<!DOCTYPE html>
<html>
    <head>
        <title>支付测试</title>
        <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
        <meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;" />
        <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js"></script>
        <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
        <script Language="javascript"> 
        	
        	//以下是package组包过程:
            
            var oldPackageString;//记住package,方便最后进行整体签名时取用
            
        	function getPackage()
            {
                var banktype = "WX";
                var body = '<?= $data['body'] ?>';//商品名称信息,这里由测试网页填入。
                var fee_type = "1";//费用类型,这里1为默认的人民币
                var input_charset = "UTF-8";//字符集,这里将统一使用GBK
                var notify_url = "http://www.xxx.com/notify.php";//支付成功后将通知该地址
                var out_trade_no = "<?= $data['out_trade_no'] ?>";//订单号,商户需要保证该字段对于本商户的唯一性
                var partner = "<?= $data['partnerid'] ?>";//测试商户号
                var spbill_create_ip = "<?= $data['spbill_create_ip'] ?>";//用户浏览器的ip,这个需要在前端获取。这里使用127.0.0.1测试值
                var total_fee = "<?= $data['total_fee'] ?>";//总金额。
                var partnerKey = "<?= $data['partnerKey'] ?>";//这个值和以上其他值不一样是:签名需要它,而最后组成的传输字符串不能含有它。这个key是需要商户好好保存的。
                
                //首先第一步:对原串进行签名,注意这里不要对任何字段进行编码。这里是将参数按照key=value进行字典排序后组成下面的字符串,在这个字符串最后拼接上key=XXXX。由于这里的字段固定,因此只需要按照这个顺序进行排序即可。
                var signString = "bank_type="+banktype+"&body="+body+"&fee_type="+fee_type+"&input_charset="+input_charset+"&notify_url="+notify_url+"&out_trade_no="+out_trade_no+"&partner="+partner+"&spbill_create_ip="+spbill_create_ip+"&total_fee="+total_fee+"&key="+partnerKey;
                
                var md5SignValue =  ("" + CryptoJS.MD5(signString)).toUpperCase();
                //然后第二步,对每个参数进行url转码,如果您的程序是用js,那么需要使用encodeURIComponent函数进行编码。
                
                
                banktype = encodeURIComponent(banktype);
                body=encodeURIComponent(body);
                fee_type=encodeURIComponent(fee_type);
                input_charset = encodeURIComponent(input_charset);
                notify_url = encodeURIComponent(notify_url);
                out_trade_no = encodeURIComponent(out_trade_no);
                partner = encodeURIComponent(partner);
                spbill_create_ip = encodeURIComponent(spbill_create_ip);
                total_fee = encodeURIComponent(total_fee);
                
                //然后进行最后一步,这里按照key=value除了sign外进行字典序排序后组成下列的字符串,最后再串接sign=value
                var completeString = "bank_type="+banktype+"&body="+body+"&fee_type="+fee_type+"&input_charset="+input_charset+"&notify_url="+notify_url+"&out_trade_no="+out_trade_no+"&partner="+partner+"&spbill_create_ip="+spbill_create_ip+"&total_fee="+total_fee;
                completeString = completeString + "&sign="+md5SignValue;
                
                
                oldPackageString = completeString;//记住package,方便最后进行整体签名时取用
                
                return completeString;
            }
          	
          	function getSign()
            {
                var app_id = '<?= $data['appId'] ?>';
                var app_key = '<?= $data['paySignKey'] ?>';
                var nonce_str = '<?= $data['noncestr'] ?>';
                var package_string = oldPackageString;
                var time_stamp = '<?= $data['timestamp'] ?>';
                //第一步,对所有需要传入的参数加上appkey作一次key=value字典序的排序
                var keyvaluestring = "appid="+app_id+"&appkey="+app_key+"&noncestr="+nonce_str+"&package="+package_string+"&timestamp="+time_stamp;
                sign = CryptoJS.SHA1(keyvaluestring).toString();
                return sign;
            }
            
          	// 当微信内置浏览器完成内部初始化后会触发WeixinJSBridgeReady事件。
            document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
                                      
                                       WeixinJSBridge.invoke('getBrandWCPayRequest',{
                                                                        "appId" : '<?= $data['appId'] ?>', 
                                                                        "timeStamp" : '<?=$data['timestamp'] ?>', //时间戳
                                                                        "nonceStr" : '<?= $data['timestamp'] ?>', //随机串
                                                                        "package" : getPackage(),//扩展包
                                                                        "signType" : 'SHA1', //微信签名方式:
                                                                        "paySign" : getSign() //微信签名
                                                                    },function(res){
                                                                         if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                                                                         	window.location.href = '<?= $data['successUrl'] ?>'; 
                                                                         }else{
                                                                         	window.location.href = 'http://www.xxx.com';  
                                                                         }
                                                                   
                                                             }); 
                                                                             
                                      
                                      }, false)
            
          </script>
    </head>
    <body>
    </body>
</html>


3:通知回调notify.php

<?php

	include 'weixin.php';
	
	$weixin = new Weixin();
	
	$xml = $this->weixin->getXmlArray();
	$openid = $xml['openid'];
	
	$out_trade_no = $_GET['out_trade_no'];
    $trade_no = $_GET['transaction_id'];
    $trade_status = $_GET['trade_state'];
    
    $isweixin = $weixin->verifyNotify($_GET,$_GET['sign']);
	if (  $isweixin ){
		if( $trade_status == 0 ) { //支付成功
			$delivernotify = $weixin->delivernotify($openid,$trade_no,$out_trade_no);	//发货	
			//业务处理
			echo "success";
		}else{			
    		echo "fail";
    	}
	}else{
		echo "不是微信回调";
	}
	
	

以上是基本的支付回流,另外维权数据获取和维权订单更新。参照上面直接调用类中的相应方法即可。

如在过程中遇到问题,随时交流.qq:124960772

with models showing off your work on the catwalk
weight loss tips A Bit Of History About Military Camouflage Clothing

Healthy Ways to Diet for Teen Girls
cartoon pornMerona topcoats and peacoat fit album
large porn tube
此条目发表在 网站开发 分类目录,贴了 标签。将固定链接加入收藏夹。

评论功能已关闭。