微信支付例子

微信支付

 

微信支付,和我们支付宝支付大致都是一样的,只不过微信支付配置的时候很复杂,注意的细节:

开通商务号:

公众号,或者小程序,任意一个就可以,必须要有一个否则,无法申请支付,支付配置就要有appid如果公众号有,那么写公众号,有小程序就有小程序。

 

支付必备:

  1. 商务号:

小程序,或公众号任意一个即可。

  1. Appid

也就是商务号的id

 

上面两种情况我们如果都没有那么我们可以进行借权,但是借权

扫描二维码关注公众号,回复: 10884157 查看本文章

授权问题:

在登录小程序或者公众号的时候,有的会提示你,要获取你的账户信息,你是否允许,然后它提示你你点击允许,那么他可以获取你的头像和账户信息,有的不用你点击直接进去的,那么他就是静默授权,他获取不到你的头像,和名字,其他内容可以获取的到。

 

  1. 商务平台,连续交易90天

切忌不能刷单,不能用一个账号去刷,换着账号去刷,如果一天没有,从新开始

 

  1. 支付需要证书,证书两年过期,过期后不能使用,使用支付失败。

 

  1. 微信的支付单位是分

 

  1. 支付交易类型,有h5,小程序,公众号等。

 

    1. 支付的流程分析

先说一下支付的流程再说配置问题。

H5流程:

点击下单->后台将订单插入数据库->将订单号、商品名称、价钱(*100,因为他是一分)、appid、商户号、随机字符串、回调url、交易类型,传给微信支付->支付判断->支付成功->同步、异步返回信息->更改订单状态->给腾讯返回的信息(腾讯的订单信息)。

 

 

    1. 代码实例
<?php
// +----------------------------------------------------------------------
// | ******微信支付
// +----------------------------------------------------------------------
namespace app\api\controller;
use think\Controller;
use  think\DB;


class Wxpay extends Common
{
 
	//微信支付
	public function index(){
		
		//接收用户下单信息
		$goodsname = input('goodsname');//商品名称
		$data['goodsid']=input('goodsid');//商品id
		$data['buy_number_count']=input('buy_number_count');//购买数量
		$data['total_price']=input('total_price');//商品价格
		$data['add_time']=time();//下单时间
		$data['phone']=input('phone');//用户手机号
		$data['username']=input('username');//用户姓名
		$data['address']=input('address');//收货地址
		$data['userid']=input('userid');//用户id
		if(input('goodstype')){
			$data['goodstype']=input('goodstype');//商品类型
		}
		
		$user = Db::name('user')->where(array('id' => $data['userid']))->field('openid')->find();//获取当前用户openID/这个我们登录的时候都存在了
       
		
		//发起微信支付,调用统一下单支付接口
		$fee = $data['total_price'];//支付金额
		$appid =        '****************';//appid.如果是公众号 就是公众号的appid
		$body =         $goodsname;
		$mch_id =       '*******************';  //商户号
		$nonce_str =    $this->nonce_str();//随机字符串
		$notify_url =   '域名/api/wxpay/notifyurl'; //回调的url
		$openid =       $user['openid'];
		$time = time();
		$year = date('Y',$time);
		$rand = rand(000000000,999999999);
		$out_trade_no = $year.$rand;//订单号
		
		//$out_trade_no = $this->order_number($openid);//商户订单号
		$spbill_create_ip = $_SERVER["REMOTE_ADDR"];//服务器的ip;
		$total_fee =    $fee*100;// 微信支付单位是分,所以这里需要*100
		$trade_type = 'JSAPI';//交易类型 默认
		
		$data['order_no']=$out_trade_no;
		$order = Db::name('order')->insert($data);
		
	 
		//这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
		$post['appid'] = $appid;
		$post['body'] = $body;
		$post['mch_id'] = $mch_id;
		$post['nonce_str'] = $nonce_str;//随机字符串
		$post['notify_url'] = $notify_url;
		$post['openid'] = $openid;
		$post['out_trade_no'] = $out_trade_no;
		$post['spbill_create_ip'] = $spbill_create_ip;//用户终端的ip
		$post['total_fee'] = $total_fee;//总金额 
		$post['trade_type'] = $trade_type;
		$sign = $this->sign($post);//签名
		$post_xml = '<xml>
			   <appid>'.$appid.'</appid>
			   <body>'.$body.'</body>
			   <mch_id>'.$mch_id.'</mch_id>
			   <nonce_str>'.$nonce_str.'</nonce_str>
			   <notify_url>'.$notify_url.'</notify_url>
			   <openid>'.$openid.'</openid>
			   <out_trade_no>'.$out_trade_no.'</out_trade_no>
			   <spbill_create_ip>'.$spbill_create_ip.'</spbill_create_ip>
			   <total_fee>'.$total_fee.'</total_fee>
			   <trade_type>'.$trade_type.'</trade_type>
			   <sign>'.$sign.'</sign>
			</xml> ';
	 
	 
		//print_r($post_xml);die;
		//统一接口prepay_id
		$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//调用统一下单
		$xml = $this->http_request($url,$post_xml);
	 
		$array = $this->xml($xml);//全要大写
	
		//print_r($array);
		//统一下单请求成功回调前端支付参数
		if($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS'){
			$time = time();
			$tmp='';//临时数组用于签名
			$tmp['appId'] = $appid;
			$tmp['nonceStr'] = $nonce_str;
			$tmp['package'] = 'prepay_id='.$array['PREPAY_ID'];
			$tmp['signType'] = 'MD5';
			$tmp['timeStamp'] = $time;
	 
	 
			$data['state'] = 200;
			$data['timeStamp'] = $time;//时间戳
			$data['nonceStr'] = $nonce_str;//随机字符串
			$data['signType'] = 'MD5';//签名算法,暂支持 MD5
			$data['package'] = 'prepay_id='.$array['PREPAY_ID'];//统一下单接口返回的 prepay_id 参数值
			$data['paySign'] = $this->sign($tmp);//签名
			$data['out_trade_no'] = $out_trade_no;
	 
	 
		}else{
			$data['state'] = 0;
			$data['text'] = "错误";
			$data['RETURN_CODE'] = $array['RETURN_CODE'];
			$data['RETURN_MSG'] = $array['RETURN_MSG'];
		}
	 
	 
		echo json_encode($data);
	}
	 
	 
	 
	 
	//随机32位字符串
	private function nonce_str(){
		$result = '';
		$str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
		for ($i=0;$i<32;$i++){
			$result .= $str[rand(0,48)];
		}
		return $result;
	}
	 
	 
	 
	//生成订单号
	private function order_number($openid){
		//date('Ymd',time()).time().rand(10,99);//18位
		return md5($openid.time().rand(10,99));//32位
	}
	 
	 
	 
	//签名 $data要先排好顺序
	private function sign($data){
		$stringA = '';
		foreach ($data as $key=>$value){
			if(!$value) continue;
			if($stringA) $stringA .= '&'.$key."=".$value;
			else $stringA = $key."=".$value;
		}
		$wx_key = '************************';//申请支付后有给予一个商户账号和密码,登陆后自己设置的key
		$stringSignTemp = $stringA.'&key='.$wx_key;
		return strtoupper(md5($stringSignTemp));
	}
	 
	 
	//curl请求
	public function http_request($url,$data = null,$headers=array())
	{
		$curl = curl_init();
		if( count($headers) >= 1 ){
			curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
		}
		curl_setopt($curl, CURLOPT_URL, $url);
	 
	 
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
	 
	 
		if (!empty($data)){
			curl_setopt($curl, CURLOPT_POST, 1);
			curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
		}
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$output = curl_exec($curl);
		curl_close($curl);
		return $output;
	}
	 
	 
	//获取xml
	private function xml($xml){
		$p = xml_parser_create();
		xml_parse_into_struct($p, $xml, $vals, $index);
		xml_parser_free($p);
		$data = "";
		foreach ($index as $key=>$value) {
			if($key == 'xml' || $key == 'XML') continue;
			$tag = $vals[$value[0]]['tag'];
			$value = $vals[$value[0]]['value'];
			$data[$tag] = $value;
		}
		return $data;
	}
	
	//支付回调接口
	public function notifyurl(){
		
		$res_xml = file_get_contents("php://input");
		libxml_disable_entity_loader(true);
		$ret = json_decode(json_encode(simplexml_load_string($res_xml,'simpleXMLElement',LIBXML_NOCDATA)),true);
		$data = array();
		$data['order_sn'] = $ret['out_trade_no'];
		$data['trade_no'] = $ret['transaction_id'];
		$data['total_fee'] = $ret['total_fee'];
		
		$check_info = DB::name('order')->where(array('order_no'=>$data['order_sn']))->find();
		if (!$check_info) {
			echo json_encode(array('state'=>1,'msg'=>'订单信息错误...'));
		}

		

		$up = array();
		$up['status'] = 1;
		$up['pay_time'] = time();
		$res = DB::name('order')->where(array('order_no'=>$data['order_sn']))->update($up);//更新订单状态
		
		//支付成功升级等级
		if($user['status'] == 0){
			$device = DB::name('terminus') ->where('userid',$check_info['userid'])->count();//查询用户名下终端机具
			
			$where['status'] = 1;
			$where['upd_time'] = time();
			if($device >= 10){
				$userdata = DB::name('user')->where(['id'=>$check_info['userid']])->update($where);//更新当前用户等级为VIP
				if($userdata){
					echo json_encode(array('state'=>1,'msg'=>'等级更新成功'));
					exit;
				}else{
					echo json_encode(array('state'=>2,'msg'=>'等级更新失败'));
					exit;
				}
			}
		}
		
		//$result = $this->orderhandle($data);
		if ($res) {
			//将信息返回给腾讯一次
			$xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg>";
			$xml.="</xml>";
			echo $xml;
		}
	}
	
	
 
 
} 

 

 

发布了127 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44944193/article/details/105562808