PHP实现微信申请退款功能


Posted in PHP onOctober 01, 2018

本文实例为大家分享了PHP实现微信申请退款的具体代码,供大家参考,具体内容如下

微信公众号开发文档链接地址

前面讲了怎么实现微信支付,详见博文:PHP实现微信支付(jsapi支付)流程  和ThinkPHP中实现微信支付(jsapi支付)流程。由于业务需求,还需要有微信退款,经过研究和摸索,也终于搞定了。

前期准备:

当然是搞定了微信支付,不然怎么退款,这次还是使用官方的demo。当然网上可能也有很多大神自己重写和封装了demo,或许更加好用简洁,但是我还是不提倡用,原因如下:
(1)可能功能不全,或许他只是实现了微信支付,但是还有申请退款、查询退款、订单查询、撤销订单等业务功能可能是你后续需要的,如果你依赖于大神的SDK的便捷,如果有新的业务需求,你就懵逼了;
(2)安全考虑,涉及到支付涉及到金钱,必须要非常安全。官方SDK虽然我也吐槽,但至少会相对比较安全,再次重写,虽然暂时没看出问题,但是万一有漏洞就不好了。

本篇还是使用到官方提供的SDK中的最重要的一个类文件WxPay.Api.PHP中提供的refund()方法来实现,此方法在WxPay.Api.php文件的第141行,代码如下:

/** 
   * 
   * 申请退款,WxPayRefund中out_trade_no、transaction_id至少填一个且 
   * out_refund_no、total_fee、refund_fee、op_user_id为必填参数 
   * appid、mchid、spbill_create_ip、nonce_str不需要填入 
   * @param WxPayRefund $inputObj 
   * @param int $timeOut 
   * @throws WxPayException 
   * @return 成功时返回,其他抛异常 
   */ 
  public static function refund($inputObj, $timeOut = 6){ 
    $url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; 
    //检测必填参数 
    if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) { 
      throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!"); 
    }else if(!$inputObj->IsOut_refund_noSet()){ 
      throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!"); 
    }else if(!$inputObj->IsTotal_feeSet()){ 
      throw new WxPayException("退款申请接口中,缺少必填参数total_fee!"); 
    }else if(!$inputObj->IsRefund_feeSet()){ 
      throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!"); 
    }else if(!$inputObj->IsOp_user_idSet()){ 
      throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!"); 
    } 
    $inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID 
    $inputObj->SetMch_id(WxPayConfig::MCHID);//商户号 
    $inputObj->SetNonce_str(self::getNonceStr());//随机字符串 

    $inputObj->SetSign();//签名 
    $xml = $inputObj->ToXml(); 
    $startTimeStamp = self::getMillisecond();//请求开始时间 
    $response = self::postXmlCurl($xml, $url, true, $timeOut); 
    $result = WxPayResults::Init($response); 
    self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间 

    return $result; 
  }

官方的方法,写的很清楚需要哪些参数,还有一些必须参数SDK已经帮我们补齐了,我将这个方法重新封装一下,便于在项目中调用:

/** 
   * 微信退款 
   * @param string  $order_id  订单ID 
   * @return 成功时返回(array类型),其他抛异常 
   */ 
  function wxRefund($order_id){ 
    //我的SDK放在项目根目录下的Api目录下 
    require_once APP_ROOT."/Api/wxpay/lib/WxPay.Api.php"; 
    //查询订单,根据订单里边的数据进行退款 
    $order = M('order')->where(array('id'=>$order_id,'is_refund'=>2,'order_status'=>1))->find(); 
    $merchid = WxPayConfig::MCHID; 

    if(!$order) return false; 

    $input = new WxPayRefund(); 
    $input->SetOut_trade_no($order['order_sn']);     //自己的订单号 
    $input->SetTransaction_id($order['transaction_id']);   //微信官方生成的订单流水号,在支付成功中有返回 
    $input->SetOut_refund_no(getrand_num(true));     //退款单号 
    $input->SetTotal_fee($order['total_price']);     //订单标价金额,单位为分 
    $input->SetRefund_fee($order['total_price']);      //退款总金额,订单总金额,单位为分,只能为整数 
    $input->SetOp_user_id($merchid); 

    $result = WxPayApi::refund($input); //退款操作 

    // 这句file_put_contents是用来查看服务器返回的退款结果 测试完可以删除了 
    //file_put_contents(APP_ROOT.'/Api/wxpay/logs/log3.txt',arrayToXml($result),FILE_APPEND); 
    return $result; 
  }

这里需要吐槽一下,竟然不说返回值的类型,在支付的时候返回的是XML数据,这里竟然返回的是数组,让我措手不及,哈哈不过还是返回数组比较好,可以直接判断处理。

方法调用就更加简单了:

//微信退款 
  $result = wxRefund($order_id); 
  // 这句file_put_contents是用来查看服务器返回的退款结果 测试完可以删除了 
  //file_put_contents(APP_ROOT.'/Api/wxpay/logs/log4.txt',arrayToXml($result),FILE_APPEND); 
  if(($result['return_code']=='SUCCESS') && ($result['result_code']=='SUCCESS')){ 
    //退款成功 
  }else if(($result['return_code']=='FAIL') || ($result['result_code']=='FAIL')){ 
    //退款失败 
    //原因 
    $reason = (empty($result['err_code_des'])?$result['return_msg']:$result['err_code_des']); 
  }else{ 
    //失败 
  }

退款成功返回如下:

PHP实现微信申请退款功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
Mysql的常用命令
Oct 09 PHP
PHP源码分析之变量的存储过程分解
Jul 03 PHP
ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
Jul 22 PHP
php采用ajax数据提交post与post常见方法总结
Nov 10 PHP
php使用curl打开https网站的方法
Jun 17 PHP
php实现可运算的验证码
Nov 10 PHP
round robin权重轮循算法php实现代码
May 28 PHP
thinkPHP中钩子的两种配置调用方法详解
Nov 11 PHP
php魔法函数与魔法常量使用介绍
Jul 23 PHP
详解PHP序列化和反序列化原理
Jan 15 PHP
php实现session共享的实例方法
Sep 19 PHP
php获取是星期几的的一些常用姿势
Dec 15 PHP
微信企业转账之入口类分装php代码
Oct 01 #PHP
PHP实现微信对账单处理
Oct 01 #PHP
php提取微信账单的有效信息
Oct 01 #PHP
YII分模块加载路由的实现方法
Oct 01 #PHP
php实现微信公众号企业转账功能
Oct 01 #PHP
详解json在php中的应用
Sep 30 #PHP
php实现数组重复数字统计实例
Sep 30 #PHP
You might like
编写安全 PHP应用程序的七个习惯深入分析
2013/06/08 PHP
PHP将HTML转换成文本的实现代码
2015/01/21 PHP
laravel中的一些简单实用功能
2018/11/03 PHP
Thinkphp5框架ajax接口实现方法分析
2019/08/28 PHP
jquery 分页控件实现代码
2009/11/30 Javascript
Jquery之美中不足小结
2011/02/16 Javascript
让人印象深刻的10个jQuery手风琴效果应用
2012/05/08 Javascript
document.createElement()用法
2013/03/13 Javascript
js动态拼接正则表达式的两种方法
2014/03/04 Javascript
Node.js中的缓冲与流模块详细介绍
2015/02/11 Javascript
jQuery中extend()和fn.extend()方法详解
2015/06/03 Javascript
js实现精确到秒的倒计时效果
2016/05/29 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
2016/06/03 Javascript
微信小程序 实战小程序实例
2016/10/08 Javascript
JavaScript Ajax实现异步通信
2016/12/14 Javascript
jQuery日期范围选择器附源码下载
2017/05/23 jQuery
在Layui 的表格模板中,实现layer父页面和子页面传值交互的方法
2019/09/10 Javascript
原生JS与JQ获取元素的区别详解
2020/02/13 Javascript
Python读取环境变量的方法和自定义类分享
2014/11/22 Python
python3调用百度翻译API实现实时翻译
2018/08/16 Python
Python datetime和unix时间戳之间相互转换的讲解
2019/04/01 Python
Python 循环终止语句的三种方法小结
2019/06/24 Python
python如何解析配置文件并应用到项目中
2019/06/27 Python
python3实现二叉树的遍历与递归算法解析(小结)
2019/07/03 Python
Python爬虫实现使用beautifulSoup4爬取名言网功能案例
2019/09/15 Python
基于python实现数组格式参数加密计算
2020/04/21 Python
python mysql自增字段AUTO_INCREMENT值的修改方式
2020/05/18 Python
小学生期末自我鉴定
2014/01/19 职场文书
家长给小学生的评语
2014/01/30 职场文书
新教师培训心得体会
2014/09/02 职场文书
颐和园的导游词
2015/01/30 职场文书
幽默导游词开场白
2015/05/29 职场文书
道士塔读书笔记
2015/06/30 职场文书
公司新员工欢迎词
2015/09/30 职场文书
基于Python实现对比Exce的工具
2022/04/07 Python
Java后端 Dubbo retries 超时重试机制的解决方案
2022/04/14 Java/Android