目录

  • 微信支付
  • 微信退款

1.以下代码修改完自己的
2.appid
3.商户号
4.商户密钥

微信支付

 //微信支付public function index(){//接收用户下单信息$data = [];$data['sorts'] = input('sorts');//套餐分类$data['sciencename']=input('sciencename');//景区名称$data['price']=input('price');//订单价格$data['create_time']=time();//下单时间$data['phone']=input('phone');//用户手机号$data['userid']=input('userid');//用户id$data['menuid']=input('menuid');//套餐id$data['scienceid'] = input('scienceid');//景区ID$data['num'] = input('num');//景区IDif(input('type')){$data['type']=input('type');//1为音频套餐}$user = Db::name('user_info')->where(array('id' => $data['userid']))->field('openid')->find();//获取当前用户openID//发起微信支付,调用统一下单支付接口$fee = $data['price'];//支付金额$appid =        '用到的appid';//appid.如果是公众号 就是公众号的appid$body =         $data['sorts'];$mch_id =       '用到的商户号';  //商户号$nonce_str =    $this->nonce_str();//随机字符串$notify_url =   'https://ht.hongtuzhijian.top/api/order/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;//echo json_encode($data);exit;$order = Db::name('user_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);//全要大写//echo json_encode($array);exit;//print_r($array);unset($data);//统一下单请求成功回调前端支付参数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';//申请支付后有给予一个商户账号和密码,登陆后自己设置的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;}//获取xmlpublic 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('user_order')->where(array('order_no'=>$data['order_sn']))->find();if (!$check_info) {echo json_encode(array('state'=>1,'msg'=>'订单信息错误'));}if($ret['return_code'] == 'SUCCESS'){$up = array();$up['status'] = 2;$up['update_time'] = time();$res = DB::name('user_order')->where(array('order_no'=>$data['order_sn']))->update($up);//更新订单状态}// 更新成功 付款成功if ($res) {$xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg>";$xml.="</xml>";echo $xml;}}

微信退款

退款需要传订单号和订单金额两个必要参数

      /*** 默认支付参数配置,可以在这里配置,也可以在初始化的时候,统一传入参数* @var array*/private $config = array('appid'           => '用到的小程序id', //小程序id'mch_id'      => '用到的商户号',//商户号'pay_apikey'   => '用到的商户key',//商户key);/*** 使用 $this->name=$value     配置参数* @param  string $name     配置名称* @param  string $value    配置值*/public function __set($name,$value){if(isset($this->config[$name])) {$this->config[$name] = $value;}}/*** 使用 $this->name 获取配置* @param  string $name 配置名称* @return multitype    配置值*/public function __get($name) {return $this->config[$name];}public function __isset($name){return isset($this->config[$name]);}//----------------------------------------------------------退款---------------------------------------------------------/*** 微信退款(POST)* @param string(28) $out_trade_no      在微信支付的时候,微信服务器生成的订单流水号,在支付通知中有返回* @param string $out_refund_no      同订单号* @param string $total_fee             微信支付的时候支付的总金额(单位:分)* @param string $refund_fee             此次要退款金额(单位:分)* @return string                      xml格式的数据*/public function refund($row){$config = $this->config;//退款参数$refundorder = array('appid'            => $config['appid'],'mch_id'        => $config['mch_id'],'nonce_str'        => $this->getNonceStr(),'out_trade_no' => $row['order_no'],'out_refund_no' => $row['order_no'],'total_fee'     => $row['price']*100,'refund_fee'   => $row['price']*100);$refundorder['sign'] = self::makeSign($refundorder);//请求数据,进行退款$xmldata = self::array2xml($refundorder);$url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';$res = self::curl_post_ssl($url, $xmldata);if(!$res){return array('status'=>0, 'msg'=>"Can't connect the server" );}// 这句file_put_contents是用来查看服务器返回的结果 测试完可以删除了// file_put_contents('./log3.txt',$res,FILE_APPEND);$content = self::xml2array($res);// if(strval($content['result_code']) == 'FAIL'){//return array('status'=>0, 'msg'=>strval($content['err_code']).':'.strval($content['err_code_des']));//     }if(strval($content['return_code']) == 'SUCCESS'){//退款成功//自己写退款成功之后要运行的代码}// return $content;}//---------------------------------------------------------------用到的函数------------------------------------------------------/*** 将一个数组转换为 XML 结构的字符串* @param array $arr 要转换的数组* @param int $level 节点层级, 1 为 Root.* @return string XML 结构的字符串*/protected function array2xml($arr, $level = 1) {$s = $level == 1 ? "<xml>" : '';foreach($arr as $tagname => $value) {if (is_numeric($tagname)) {$tagname = $value['TagName'];unset($value['TagName']);}if(!is_array($value)) {$s .= "<{$tagname}>".(!is_numeric($value) ? '<![CDATA[' : '').$value.(!is_numeric($value) ? ']]>' : '')."</{$tagname}>";} else {$s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>";}}$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);return $level == 1 ? $s."</xml>" : $s;}/*** 将xml转为array* @param  string     $xml xml字符串* @return array    转换得到的数组*/protected function xml2array($xml){   //禁止引用外部xml实体libxml_disable_entity_loader(true);$result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);        return $result;}/*** * 产生随机字符串,不长于32位* @param int $length* @return 产生的随机字符串*/protected function getNonceStr($length = 32) {$chars = "abcdefghijklmnopqrstuvwxyz0123456789";  $str ="";for ( $i = 0; $i < $length; $i++ )  {  $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  } return $str;}/*** 生成签名* @return 签名*/protected function makeSign($data){//获取微信支付秘钥$key = $this->config['pay_apikey'];// 去空$data=array_filter($data);//签名步骤一:按字典序排序参数ksort($data);$string_a=http_build_query($data);$string_a=urldecode($string_a);//签名步骤二:在string后加入KEY$string_sign_temp=$string_a."&key=".$key;//签名步骤三:MD5加密$sign = md5($string_sign_temp);// 签名步骤四:所有字符转为大写$result=strtoupper($sign);return $result;}/*** 获取IP地址* @return [String] [ip地址]*/protected function getip() {static $ip = '';$ip = $_SERVER['REMOTE_ADDR'];if(isset($_SERVER['HTTP_CDN_SRC_IP'])) {$ip = $_SERVER['HTTP_CDN_SRC_IP'];} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {$ip = $_SERVER['HTTP_CLIENT_IP'];} elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {foreach ($matches[0] AS $xip) {if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {$ip = $xip;break;}}}return $ip;}/*** 微信支付退款发起请求*/protected function curl_post_ssl($url, $xmldata, $second=30,$aHeader=array()){$config = $this->config;$ch = curl_init();//超时时间curl_setopt($ch,CURLOPT_TIMEOUT,$second);curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);//这里设置代理,如果有的话//curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);curl_setopt($ch, CURLOPT_SSLVERSION, 1);$cert = __DIR__.'/cert/apiclient_cert.pem';$key = __DIR__.'/cert/apiclient_key.pem';//默认格式为PEM,可以注释curl_setopt($ch,CURLOPT_SSLCERT, $cert); //这个是证书的位置绝对路径curl_setopt($ch,CURLOPT_SSLKEY, $key); //这个也是证书的位置绝对路径//curl_setopt($ch,CURLOPT_CAINFO,$config['rootca']);if( count($aHeader) >= 1 ){curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);}curl_setopt($ch,CURLOPT_POST, true);curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);$data = curl_exec($ch);if($data){curl_close($ch);return $data;}else { $error = curl_errno($ch);echo "call faild, errorCode:$error\n"; curl_close($ch);return false;}}

ThinkPHP 微信支付及退款相关推荐

  1. php微信支付分取消订单,PHP实现微信支付和退款

    这次给大家带来PHP实现微信支付和退款,PHP实现微信支付和退款的注意事项有哪些,下面就是实战案例,一起来看一下. 之前有写过几篇文章将微信支付和退款: 1.PHP实现微信支付(jsapi支付)流程 ...

  2. 关于微信支付的退款那些事

    关于微信支付的退款那些事 微信支付的退款 需要双向证书 一个是操作人的电脑上  需要安装的证书 以p12为结尾的 另外一个证书是2个,需要放到服务器上 微信支付的退款,在请求接口的时候,会在发起人的电 ...

  3. springboot之微信支付与退款

    基于springboot实现小程序微信支付与退款 最近需要再写小程序商城,无可避免的需要用到微信支付与商品售后退款等功能.于是研究了一些大佬的代码之后整合出了这个比较简单的微信支付与退款. 相关内容引 ...

  4. java微信支付v3系列——8.微信支付之退款成功回调

    目录 java微信支付v3系列--1.微信支付准备工作 java微信支付v3系列--2.微信支付基本配置 java微信支付v3系列--3.订单创建准备操作 java微信支付v3系列--4.创建订单的封 ...

  5. 微信支付-“申请退款”接口遇到curl出错,错误码:58解决方案

    微信支付后 退款,接口遇到curl出错,错误码:58 这个问题基本上是证书没对应上(微信支付不需要申请证书,退款要用到证书),证书要去微信商户号后台(账户中心-API安全-申请证书)下载,已经下载过忘 ...

  6. 用java实现微信支付,退款,部分退款服务端

    由于公司业务需要,最近搞微信退款功能,今天抽空在此记录一下,以后用到也可以到这来看一眼.废话不多说,进入正题. 微信支付以及付款呢,先要有个证书,不清楚的,还要有证书,可以去微信平台看证书怎么下载 h ...

  7. 微信退款返回58 linux,小程序微信支付申请退款返回cUrl错误,错误码:58

    2019-04-03 15:15:29 如何看待微信公开课小程序热门讨论「小程序微信支付申请退款返回cUrl错误,错误码:58」 摘要:小程序微信支付申请退款返回cUrl错误,错误码:58 展开:调用 ...

  8. 基于微信支付、退款的一个取消预约的方案

    一.前提 本方案是基于 「微信非付款码支付」 进行设计的. 二.业务场景 首先,大家先大概了解下「预约」和「取消预约」两个流程. 预约 取消预约 三.遇到的问题 试想如下场景: 用户预约,拉起微信支付 ...

  9. 微信支付 自动退款 php,银联在线、微信、支付宝自动退款接口文档总结和API地址...

    关于微信和支付宝自动退款接口的接入总结 一:支付宝的自动退款接口接入 支付宝官方api:https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a ...

最新文章

  1. 我生于1997,我骄傲了吗?
  2. MySQL必知必会读书笔记
  3. 【机器学习】基于LightGBM算法实现数据挖掘!
  4. 阿里云ARMS助力「叫叫阅读」解锁系统定位分析技能包
  5. python使用opencv_教你快速使用OpenCV/Python/dlib進行眨眼檢測識別!
  6. 数据结构之线性表(附代码)
  7. 大型网站的架构设计问题—-大型高并发高负载网站的系
  8. jmeter判断值是否相等_jmeter beanshell判断响应的json值是否正确;
  9. 【javascript】简单原型链、借用构造函数
  10. 一片关于Bootstarp4的文章
  11. Atitit fsm有限状态机概念与最佳实践 目录 1. 概念组成与原理成分 1 1.1. 1、状态机的要素 4个要素,即现态、条件、动作、次态 2 1.2. 状态表 2 2. 性状 2 2.1.
  12. 苹果真伪查询_拆解报告:山寨版苹果AirPods Pro
  13. 计算机系统变慢的原因,计算机系统运行速度变慢4大原因
  14. 加盟店 -- 祖坟刨干记
  15. java 判断汉字_Java 完美判断中文字符的方法
  16. python处理图片去白底-Python实现将蓝底照片转化为白底照片功能完整实例
  17. 设置编程软件的背景颜色
  18. 基于Go语言Echo+Layui的OA办公系统
  19. Unity进阶课程【一】Input Field 组件的失焦和使用
  20. Mysql优化之6年工作经验总结

热门文章

  1. Kindle资源-史上最全60GB的Kindle电子书资源网盘打包下载
  2. 《领导沟通艺术与真实影响力》感想二
  3. 华为存储FusionStorage(备份②)
  4. word文档中的毕业论文的页眉与页脚设置
  5. 为自动驾驶保驾护航—谈谈主流中间件设计
  6. Linux系列学习(二) - Vim编辑器的介绍及使用、文件编译的过程、Makefile工具、Gdb调试器
  7. Excel 2010 VBA 入门 028 向单元格输入公式
  8. 全网最全之接口测试【加密解密攻防完整版】实战教程详解
  9. 我的世界斗罗封神服务器怎么注册,我的世界斗罗封神服务器-我的世界斗罗封神mod手机版v1.17.2.01-游戏宝手游网...
  10. 什么是序列化与反序列化,为什么序列化