/**
* 将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. bzoj2141_排队

    题意 给定\(n\)个数,每次交换两个数,输出交换后的逆序数. 分析 交换两个数只会影响到对应区间内的逆序数,具体为减少区间\([l+1,r-1]\)中比\(a[r]\)大的数的个数,增加比\(a[r ...

  2. pycharm中报ImportError: libcublas.so.9.0错误的解决方法。

    前些天不知为啥cuda不能用了,nvidia-smi也没反应.然后我就重新装了一下cuda.后来使用pycharm远程连接时,居然报错了. ImportError: libcublas.so.9.0: ...

  3. Mysql高手系列 - 第11篇:深入了解连接查询及原理

    这是Mysql系列第11篇. 环境:mysql5.7.25,cmd命令中进行演示. 当我们查询的数据来源于多张表的时候,我们需要用到连接查询,连接查询使用率非常高,希望大家都务必掌握. 本文内容 笛卡 ...

  4. Xshell无法连接到虚拟机Linux系统(桥接方式)

    一.  查看主机上网网卡网络配置信息 1.  查看本机所用网卡名称(适用于win10系统) 操作步骤: 1)  状态栏右键“WiFi连接图标” 2)  点击“打开“网络和Internet”设置” 3) ...

  5. java8 新特性精心整理(全)

    前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特 ...

  6. 25 (OC)* iOS网络HTTP、TCP、UDP、Socket 知识总结

    应用层:1.用户接口.应用程序:2.Application典型设备:网关:3.典型协议.标准和应用:TELNET.FTP.HTTP 表示层:1.数据表示.压缩和加密presentation2.典型设备 ...

  7. spring中基于注解使用ehcache

    继续上篇,这篇介绍服务层缓存,基于注解的方式使用ehcache 注解的标签主要有4个:@Cacheable.@CacheEvict.@CachePut.@Caching,他们的用法是: @Cachea ...

  8. 【linux】【FastDFS】FastDFS数据迁移

    后来同步的时候发现有的没有同步过来,应该是没有同步完成我就停止服务了. 最后尝试直接把fastdfs storage的data文件迁移过去即可. 1.在新的storage server服务器上停止所有 ...

  9. 【linux】【gitlab】gitlab安装、备份、恢复、升级、内存消耗问题

    前言 GitLab:GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务.功能:Gitlab 是一个提供代码托管.提交审核和问题跟踪的代码管理平 ...

  10. Java程序语言的后门-反射机制

    在文章JAVA设计模式-动态代理(Proxy)示例及说明和JAVA设计模式-动态代理(Proxy)源码分析都提到了反射这个概念. // 通过反射机制,通知力宏做事情 method.invoke(obj ...