前言:
现在咱们对“php对接微信支付教程”大概比较讲究,朋友们都想要剖析一些“php对接微信支付教程”的相关资讯。那么小编在网上收集了一些有关“php对接微信支付教程””的相关内容,希望我们能喜欢,朋友们一起来了解一下吧!最近在做应用商城涉及到小程序微信支付和app微信支付,所以也大概地将这方面的东西看了一个遍,整个流程梳理总结一下。
环境是:tp5 + 小程序 + App
appid 小程序的appid
appsecret 小程序appsecret
mch_id 商户号
key 商户支付密钥Key
文件位置 \extends\service\PayService//微信支付类 <?php/** 微信支付类,可直接根据各种框架复制里面的方法直接引用!* * 作者 (1612666131@qq.com)* Date:2021-03-12*/namespace service;use think\Controller;use think\Db;use think\db\Query;class PayService extends Controller { private $appid; //小程序appid private $appsecret; //小程序的secret private $MCHID; //商户号id private $KEY; //商户号key private $url=';; //商户号key public function __construct($config){ $this->appid=$config['appid']; $this->appsecret=$config['appsecret']; $this->MCHID=$config['MCHID']; $this->KEY=$config['KEY']; } public function dopay($out_trade_no,$money,$notify_url){ //总金额(分) $total_fee = intval($money*100); //商品类型信息 $body=''; //附加数据 $attach=date('YmdHis'); $out_trade_no=$out_trade_no.rand(1111,9999); //构造请求参数 $key= $this->KEY; $appid='wxacd6ff08cd2e7b6f'; $mch_id=$this->MCHID; $device_info='WEB'; $nonce_str=$this->randomkeys(32); $fee_type='CNY'; $spbill_create_ip=getIP(); $trade_type='APP'; $limit_pay='no_credit'; $sign=$this->sign($appid,$mch_id,$attach,$body,$nonce_str,$key,$out_trade_no,$total_fee,$spbill_create_ip,$notify_url,$trade_type); $signs = md5($sign); $signss=strtoupper($signs); $transData='<xml> <appid><![CDATA['.$appid.']]></appid> <attach><![CDATA['.$attach.']]></attach> <body><![CDATA['.$body.']]></body> <mch_id><![CDATA['.$mch_id.']]></mch_id> <nonce_str><![CDATA['.$nonce_str.']]></nonce_str> <notify_url><![CDATA['.$notify_url.']]></notify_url> <out_trade_no><![CDATA['.$out_trade_no.']]></out_trade_no> <spbill_create_ip><![CDATA['.$spbill_create_ip.']]></spbill_create_ip> <total_fee><![CDATA['.$total_fee.']]></total_fee> <trade_type><![CDATA['.$trade_type.']]></trade_type> <sign>'.$signss.'</sign> </xml>'; $data=$this->curl_post(";,$transData); $sinsagin=$this->again($data,$appid,$out_trade_no,$nonce_str,$key); $weixin = $this->fors($data,$appid,$nonce_str,$out_trade_no,$sinsagin); return $weixin; } //发送请求 public function curl_get_contents($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //忽略证书错误信息 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); @curl_setopt($ch, CURLOPT_GET, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result=curl_exec($ch); // $result = json_decode($resp,true); curl_close($ch); return $result; } public function payOrder($order){ $total_fee =$order['money']; //支付金额 if(empty($order['money']) || empty($order['openid'])){ //一定要有用户Openid和支付金额 die("缺少参数!"); } $total_fee = $total_fee * 100; //支付金额单位是分的,所以要乘100 $appid = $this->appid; $MCHID = $this->MCHID; //商户号 $KEY = $this->KEY; //商户key $data['appid'] = $appid; //小程序appid $data['mch_id'] = $MCHID; //商户号id $data['nonce_str'] = md5($MCHID.time()); //验证的支付 $data['openid'] = $order['openid']; //用户openid $data['body'] = '油BOSS订单【'.$order['pay_no'].'】'; //微信支付对应的商家/公司主体名 $data['out_trade_no'] = $order['pay_no'].rand(1111,9999); //订单号id,用于回调改订单状态 $data['total_fee'] = $total_fee; //支付金额,单位为分!! $data['spbill_create_ip'] = '8.8.8.8'; //验证ip地址,这个不用改随意 $data['notify_url'] = $order['notify_url']; //微信支付成功的回调路径,要写死这个路径,记得要是小程序允许访问的路径 $data['trade_type'] = "JSAPI"; //小程序支付,所以是JSAPI // --------------------以下这一串都不用改-------------------------------- ksort($data); $sign_str = $this->ToUrlParams($data); $sign_str = $sign_str."&key=".$KEY; // echo $sign_str; $data['sign'] = strtoupper(md5($sign_str)); $xml = $this->arrayToXml($data); $r = $this->postXmlCurl($xml,$this->url,true); $result = json_decode($this->xml_to_json($r)); if($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS' ){ $sdata['appId'] = $appid; $sdata['timeStamp'] = (string)time(); $sdata['nonceStr'] = md5(time().rand().rand().$data['openid']); $sdata['package'] = "prepay_id=".$result->prepay_id; $sdata['signType'] = "MD5"; ksort($sdata); $sign_str = $this->ToUrlParams($sdata); $sign_str = $sign_str."&key=".$KEY; $sdata['paySign'] = strtoupper(md5($sign_str)); $info['code']='1'; $info['data']=$sdata; $data['msg']=''; return $info; }else{ $info['code']='0'; $info['data']=array(); $info['msg']=$result->err_code_des; return $info; } // -----------------------都不用改----------------------------------------------- } /** * 【支付成功后回调】 * * by: leoyi * Date:2018-04-08 */ public function suc_call(Request $request) { $data=file_get_contents('php://input'); $msg = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA); if($msg['result_code'] == "SUCCESS") { // 支付成功这里要做的操作! $sql = "update ....";//可以修改订单的状态之类的 $result = DB::update($sql); } echo '<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> </xml>'; } /** * 【退款的接口】 * * by:leoyi * Date: 2018-04-08 */ private function payRefund(Request $request){ // 具体代码后期另外写 也可以联系我私发 } /* * 注意:以下方法都是为了方便直接调取转换格式用的方法, * 个人需要可以另外抽取出来放 *========================================== * 以下代码不需要修改!! */ /** * 用户post方法请求xml信息用的 * @author write by leoyi 2018-04-8 */ public function postXmlCurl($xml, $url, $useCert = false, $second = 10) { $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验2 //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //运行curl $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); curl_close($ch); return $error; } } /* * 用于微信支付转换认证的信息用的 * by:leoyi * date:2018-4-8 */ public function ToUrlParams($data) { $buff = ""; foreach ($data as $k => $v) { if($k != "sign" && $v != "" && !is_array($v)){ $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } /* * 微信支付-数组转xml * by:leoyi * date:2018-4-8 */ public 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; } /* * 微信支付-数组转xml * by:leoyi * date:2018-4-8 */ public function xml_to_json($xmlstring) { return json_encode($this->xml_to_array($xmlstring),JSON_UNESCAPED_UNICODE); } /* * post方法 * by:leoyi * date:2018-4-8 */ public function post_url($post_data, $url) { $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验2 curl_setopt($ch, CURLOPT_HEADER, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $data = curl_exec($ch); curl_close($ch); return $data; } /* * 把xml转换成array * by:leoyi * Date:2018-4-11 */ public function xml_to_array($xml) { //return ((array) simplexml_load_string($xmlstring)); return simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA); //return json_decode(xml_to_json($xmlstring)); } private function sign($appid,$mch_id,$attach,$body,$nonce_str,$key,$out_trade_no,$total_fee,$spbill_create_ip,$notify_url,$trade_type) { $sign=''; $stringSignTemp=''; $stringSignTemp="appid=".$appid."&attach=".$attach."&body=".$body."&mch_id=".$mch_id."&nonce_str=".$nonce_str."¬ify_url=".$notify_url."&out_trade_no=".$out_trade_no."&spbill_create_ip=".$spbill_create_ip."&total_fee=".$total_fee."&trade_type=".$trade_type."&key=$key"; $sign=$stringSignTemp; return $sign; } private function curl_post($url,$data) { if(is_array($data)) $data=http_build_query($data); $curl = curl_init(); //$url=$url; curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,false); // 对认证证书来源的检查 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); $result = curl_exec($curl); curl_close($curl); if($result === false){ return curl_error($curl); } else{ return $result; } } private function again($data,$appid,$out_trade_no,$nonce_str,$key) { $res = simplexml_load_string($data,NULL,LIBXML_NOCDATA); $res = json_decode(json_encode($res),true); if ($res['result_code'] == "FAIL") { echoJson($res['err_code_des'],"1001"); } $partnerid=$out_trade_no; $prepayid=$res['prepay_id']; $package='Sign=WXPay'; $noncestr=$nonce_str; $timestamp=time(); $sign=''; $stringSignTemp=''; $stringSignTemp="appid=".$appid."&noncestr=".$noncestr."&package=".$package."&partnerid=".$partnerid."&prepayid=".$prepayid."×tamp=".$timestamp."&key=$key"; $sign=MD5($stringSignTemp); $signs=strtoupper($sign); return $signs; } private function fors($data,$appid,$nonce_str,$out_trade_no,$sinsagin) { $time=(string)time(); $res = simplexml_load_string($data,NULL,LIBXML_NOCDATA); $res = json_decode(json_encode($res),true); return array( 'appid'=>$appid, 'noncestr'=>$nonce_str, 'package'=>'Sign=WXPay', 'partnerid'=>$out_trade_no, 'prepayid'=>$res['prepay_id'], 'timestamp'=>$time, 'sign'=>$sinsagin ); } /** * 生成32位随机字符串 WX * @param unknown $length * @return string */ private function randomkeys($length) { $key=''; $pattern='1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ'; for ($i = 0; $i < $length; $i++) { $key.= $pattern{mt_rand(1,60)}; //生成php随机数 } return $key; }}
小程序微信支付调用
use service\PayService;<?php/** pay_no string 支付单号 * money string 支付金额(单位分)* openid 用户openID* notify_url 支付后回调地址* Date:2021-03-12*///微信支付function parampay($pay_no,$money,$openid,$notify_url){ $config['appid'] = '';// 小程序appid $config['appsecret'] = '';// 小程序appsecret $config['MCHID'] = ''; //微信商户 $config['KEY'] = ''; //微信商户key $pay = new PayService($config); $order['money'] = $money; $order['openid'] = $$openid; $order['pay_no'] = $pay_no; $order['notify_url']= $notify_url; return $pay->payOrder($order);}?>
app微信支付
use service\PayService;<?php/** pay_no string 支付单号 * money string 支付金额(单位分)* notify_url 支付后回调地址* Date:2021-03-12*///微信支付function parampay($pay_no,$money,$notify_url){ $config['appid'] = '';// 小程序appid $config['appsecret'] = '';// 小程序appsecret $config['MCHID'] = ''; //微信商户 $config['KEY'] = ''; //微信商户key $notify_url= WEB_URL.'/api/Onilnestudy/notifyUrl'; $PayService=new PayService($config); return $PayService->dopay($pay_no,$money,$notify_url);}?>
异步回调消息处理
public function notifyUrl(){ $xmlData = file_get_contents('php://input'); libxml_disable_entity_loader(true); $result = json_decode(json_encode(simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA)), true); ksort($result); $str = ''; foreach ($result as $k => $v) { $str .= $k.':'.$v."\r\n"; } $fp = fopen("./wechatnotify.txt","a"); flock($fp, LOCK_EX) ; fwrite($fp,"--返回微信支付数据--执行日期:".strftime("%Y-%m-%d %H:%M:%S",time())."--------------------\r\n".$str."\r\n\r\n"); flock($fp, LOCK_UN); fclose($fp); // $result['result_code']='SUCCESS'; // $result['out_trade_no']='650380663249821367350'; if($result['result_code'] == 'SUCCESS'){ //此处应该更新一下订单状态,商户自行增删操作 $map = []; $map['pay_no'] = substr($result['out_trade_no'],0,-4); $info = DB::name("onilne_study_buy")->where($map)->find(); if ($info['is_status'] > 0) { die('success'); } if ($info) { $data = [ "is_status" => 1, "pay_time" => date('Y-m-d H:i:s'), ]; $re = DB::name("onilne_study_buy")->where($map)->update($data); if ($re) { die("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"); } } }else{ die("fail"); } }
版权声明:
本站文章均来自互联网搜集,如有侵犯您的权益,请联系我们删除,谢谢。
标签: #php对接微信支付教程