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+"¬ify_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+"¬ify_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+"×tamp="+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
cartoon pornMerona topcoats and peacoat fit album