/**
* 将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. WordCount--统计输入文件的字符数、行数、单词数(java)--初级功能

    码云地址: https://gitee.com/YuRenDaZ/WordCount 个人PSP表格: PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划 180 ...

  2. Junit测试Controller(MockMVC使用),以及传输@RequestBody数据解决办法

    转自:http://www.importnew.com/21153.html 一.单元测试的目的 简单来说就是在我们增加或者改动一些代码以后对所有逻辑的一个检测,尤其是在我们后期修改后(不论是增加新功 ...

  3. 题解 洛谷P2833 【等式】

    运用暴力解方程吸氧过了这道题 通过数据范围看,要是枚举x和y只能炸掉三成的数据. 所以考虑枚举从x1到x2枚举x,通过方程移项可知y=-(ax+c)/b,再判断y是否在y1和y2之间即可. 本题本做法 ...

  4. CentSO7.6下部署Maridb Galera Cluster 实践记录(二)

    早上三个节点的数据库都启动正常,下午上班就都不行了,哎,VM啊,中午就是让主机休息了一些而已么. 今天继续折腾中,第二天再来一遍:重启第一台服务器上的galera时竟然报错了:错误如下:    It ...

  5. Git使用(一)安装配置过程-Win7

    公司项目需要使用Git作为项目的代码库管理工具.正好借此机会写个安装过程 1.首先下载Git下载地址:https://git-scm.com/download/win 当前下载版本:Git-2.13. ...

  6. 64位linux编译32位程序

    昨天接到的任务,编译64位和32位两个版本的.so动态库给其他部门,我的ubuntu虚拟机是64位的,编译32位时遇到了问题: /usr/bin/ld: cannot find -lstdc++ 最后 ...

  7. FaceBook快捷登入

    关于集成FaceBook快捷登入,我上回做了个最简单的版本,所有Web端通用,在这边共享下,有更好的解决方案的,麻烦评论留个地址,有不妥之处请指正. 首先,我们先加载Facebook的Js windo ...

  8. 疑难杂症----udf提权无法导出.dll

    昨天进行测试一个网站,进行udf提权时候,没办法导出.dll, 起初以为是这个马的问题,后来用专用马,一样不行,但是有报错了,有上网找了半天,终于被我找到了. Mysql数据库从文件导入或导出到文件, ...

  9. Day20 磁盘管理2之RAID卡

    1.磁盘的基本分区Gdisk 前面我们已经了解到fdisk分区,但fdisk不支持给高于2TB的磁盘进行分区.如果有单块盘高于2TB,建议使用Gdisk进行分区. 1.使用gdisk进行磁盘分区 1. ...

  10. 006:CSS高级技巧

    目录 前言 理论 CSS高级技巧 一:元素的显示与隐藏 在CSS中有三个显示和隐藏的单词比较常见,我们要区分开,他们分别是 display visibility 和 overflow. 他们的主要目的 ...