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
