/**
* 将xml转为array
* @param string $xml xml字符串
* @return array 转换得到的数组
*/
public function xml2array($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(false);
$result = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
} //用户退款
public function postXmlCurl($xml, $url, $useCert = false, $second = 60, $oid = 0, $source)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second); //如果有配置代理这里就设置代理
if (
WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
&& WxPayConfig::CURL_PROXY_PORT != 0
) {
curl_setopt($ch, CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
curl_setopt($ch, CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
}
curl_setopt($ch, CURLOPT_URL, $url);
// curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
// curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if ($useCert == true && $source == 2) {
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, PayConfig::get_wx_config_info('sslcert_path', $oid));
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, PayConfig::get_wx_config_info('sslkey_path', $oid));
}elseif($useCert == true && $source == 5){ curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, PayConfig::get_wx_config_info('wxGzhsslcert', $oid));
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, PayConfig::get_wx_config_info('wxGzhsslkey', $oid));
} //post提交方式
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);
echo "call faild, errorCode:$error\n";
curl_close($ch);
return false;
}
} /**
* 将一个数组转换为 XML 结构的字符串
* @param array $arr 要转换的数组
* @param int $level 节点层级, 1 为 Root.
* @return string XML 结构的字符串
*/
public 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;
} function wxrefund($order_id, $timeOut = 6)
{
//$order_id = input('orsid');
$order = StoreOd::where('order_num', $order_id)->find();
if (!$order) {
return json(['code' => 2, 'data' => "", 'msg' => "无效订单号"]);
}
$refund_order = time() . rand(1000, 9999); //退款单号
/* $total_price = $order['price'] * 100;
$refund_price = $order['price'] * 100; */
$total_price = 1;
$refund_price = 1; if ($order['source'] == 2){ $merchid = PayConfig::get_wx_config_info('wxmch_id', $order['oid']);
$appid = PayConfig::get_wx_config_info('wxappid', $order['oid']);
$key = PayConfig::get_wx_config_info('wxkey', $order['oid']); } elseif ($order['source'] == 5){ $merchid = PayConfig::get_wx_config_info('wxGzhMch_id', $order['oid']);
$appid = PayConfig::get_wx_config_info('wxGzhAppid', $order['oid']);
$key = PayConfig::get_wx_config_info('wxGzhKey', $order['oid']);
} $nonce_str = '' . strval(mt_rand(100000, 999999)); //随机字符串
$stra = "appid=" . $appid . "&mch_id=" . $merchid . "&nonce_str=" . $nonce_str . "&op_user_id=" . $merchid . "&out_refund_no=" . $refund_order . "&out_trade_no=" . $order['order_num'] . "&refund_fee=" . $refund_price . "&total_fee=" . $total_price . "&key=" . $key;
$sign = strtoupper(md5($stra)); $param = [
'appid' => $appid,
'mch_id' => $merchid,
'nonce_str' => $nonce_str,
'op_user_id' => $merchid,
'out_refund_no' => $refund_order, //商户退款单号
'out_trade_no' => $order['order_num'],
'refund_fee' => $refund_price, //退款金额
'total_fee' => $total_price,
'sign' => $sign
];
$xmldata = self::array2xml($param); //传入参数转换成xml格式
$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
$res = self::postXmlCurl($xmldata, $url, true, $timeOut, $order['oid'], $order['source']); //curl发出请求 if (!$res) {
return ['status' => 1, 'msg' => "服务器连接失败"];
}
$content = self::xml2array($res); $data = ['out_refund_no' => $content['out_refund_no'], 'refund_id' => $content['refund_id'], 'refund_fee' => $content['refund_fee']];
if ($content['result_code'] == 'SUCCESS') {
return json(['code' => 1, 'data' => $data, 'msg' => '操作成功']);
} else {
return json(['code' => 2, 'data' => '', 'msg' => '操作失败,' . $content['err_code_des']]);
}
}
  

  

微信退款(APP和公众号一样)的更多相关文章

  1. 微信中的APP、公众号、小程序的openid及unionid介绍

    微信中的APP.公众号.小程序的openid及unionid介绍 1.unionid 如果开发者拥有多个移动应用.网站应用.和公众帐号(包括小程序),可通过 UnionID 来区分用户的唯一性,因为只 ...

  2. 微信小程序自运营器 微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营)

    自动发单,自动评价,自动评论,自动推广 微信小程序自运营器  微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营) 我们会根据你的微信公众号或微信小程序定制开发带有一定AI智 ...

  3. Python3 itchat微信获取好友、公众号、群聊的基础信息

    Python3 itchat微信获取好友.公众号.群聊的基础信息 一.简介 安装 itchat pip install itchat 使用个人微信的过程当中主要有三种账号需要获取,分别为: 好友 公众 ...

  4. 第三方微信支付,WAP、H5、APP、公众号支付的区别

    你说一个微信支付被腾讯搞了N个版本出来,是技术问题还收费原因不得而知.公众号支付,H5(wap)支付,APP支付.看得小编一头雾水. 带点N个疑问? 1.公众号支付是在公众号里支付,支众号里引入的三方 ...

  5. 集成微信支付的代码。兼容小程序,扫码,app,公众号。h5 支付 ,以及 服务商提现

      /** * 因为微信总是很多个商户号很多和appid.很多个密钥文件,所以全部改成手动传值的方式,就可以支持多商户调用 * * @param appId 商户的appid * @param mch ...

  6. 新增线下、APP、公众号多处入口,小程序会再火起来么?

    现在,大多数互联网创业者最缺的是流量,第二缺的是钱.之前开发者们追捧小程序的重要原因就是在于认为这可能是下一个微信公众号体量的流量入口,因为大家都想从微信的8亿多用户中收获自己的一部分用户. 近期部分 ...

  7. 微信小程序及公众号H5自动化测试攻略

    目前市面上,被大家用来做移动端App UI自动化测试工具最为常见的当属: Appium Airtest 很多小伙伴在刚接触这两款工具做App UI自动化测试时,难免会问到,他们能支持微信小程序或者微信 ...

  8. 微信小程序和公众号和H5之间相互跳转

    参考链接:https://www.imooc.com/article/22900 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 可关联已有的小程序或快速创建小程序.已关联 ...

  9. 微信开发笔记:公众号获取access_token

    微信开发中,access_token的获取是一种非常常见的功能,通过公众号的appid和appsecret来向微信公众平台请求一个临时通行凭证:access_token.公众平台上的绝大部分操作都会需 ...

  10. 微信连WiFi关注公众号流程更新 解决ios微信扫描二维码不关注就能上网的问题

    前几天鼓捣了一下微信连WiFi功能,设置还蛮简单的,但ytkah发现如果是ios版微信扫描微信连WiFi生成的二维码不用关注公众号就可以直接上网了,而安卓版需要关注公众号才能上网,这样就少了很多ios ...

随机推荐

  1. java 中for循环中断的办法

    /* 中断for循环的办法: 1.break ***2.return是结束方法的,不是结束循环的. 3.标签的方法. 格式: 表签名:语句 运行结果:D:\test\day0413>java T ...

  2. Net基础篇_学习笔记_第十一天_面向对象(面向过程与面向对象的区别/类的概念)

    1.面向过程-----> 面向对象 面向过程:面向的是完成这件事儿的过程,强调的是完成这件事儿的动作. 把大象塞进冰箱里1.打开冰箱门2.把大象塞进去,亲下大象的屁股3.关闭冰箱门 孙全 瘦小 ...

  3. Linux 笔记 - 第十三章 Linux 系统日常管理之(一)系统状态监控

    博客地址:http://www.moonxy.com 一.前言 如果你是一名 Linux 运维人员,最主要的工作是优化系统配置,使应用在系统上以最优的状态运行.系统运行状态主要包括:系统负载.内存状态 ...

  4. C#基础知识总结(一)

    1.什么是匿名函数?匿名函数,就是没有名字的函数,或者说就是一组代码块,他的参数只有在方法块内有效,可以有效的减小创建方法事所需要的系统开销 2.lambda表达式是什么?lambda表达式 就是一个 ...

  5. 解决Android数据库异步操作的大问题

    前言 相信大家在开发过程中,也遇到过下面的这种异常: java.lang.IllegalStateException: attempt to re-open an already-closed obj ...

  6. Spring Boot (四): Druid 连接池密码加密与监控

    在上一篇文章<Spring Boot (三): ORM 框架 JPA 与连接池 Hikari> 我们介绍了 JPA 与连接池 Hikari 的整合使用,在国内使用比较多的连接池还有一个是阿 ...

  7. php下api接口的并发http请求

    php下api接口的并发http请求 ,提高app一个页面请求多个api接口,页面加载慢的问题: func_helper.php/** * 并发http请求 * * [ * 'url' //请求地址 ...

  8. 【linux】【Fabric】Centos7搭建Fabric运行环境

    1.安装jdk1.8配置环境变量 参考:https://www.cnblogs.com/jxd283465/p/11541506.html 2.安装git yum -y install git 3.安 ...

  9. Rsync 服务部署与参数详解

    Rsync 简介 rsync 是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据同步备份的优秀工具.Rsync软件适用于unix/linux/windows等多种操作系统平台. 传统的 ...

  10. java Swing 界面化查询数据库表

    两天从0基础写的.没有按钮对话框功能,只是简单的实现. 当然代码上有很多需要优化的,基本需要重写哈哈哈.但是我怕以后有需要所以还是存一下好了.<把RS结果集,放vector里面,用vector构 ...