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 相关文章推荐
PHP中的MYSQL常用函数(php下操作数据库必备)
Sep 12 PHP
常见的PHP五种设计模式小结
Mar 23 PHP
解析PHP多种序列化与反序列化的方法
Jun 06 PHP
php计算给定时间之前的函数用法实例
Apr 03 PHP
浅析Yii2集成富文本编辑器redactor实例教程
Apr 25 PHP
深入分析PHP优化及注意事项
Jul 04 PHP
实现PHP搜索加分页
Oct 12 PHP
浅谈关于PHP解决图片无损压缩的问题
Sep 01 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
Apr 20 PHP
Laravel 微信小程序后端实现用户登录的示例代码
Nov 26 PHP
php 函数中静态变量使用的问题实例分析
Mar 05 PHP
PHP7 list() 函数修改
Mar 09 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
4.与数据库的连接
2006/10/09 PHP
改写ThinkPHP的U方法使其路由下分页正常
2014/07/02 PHP
通过php动态传数据到highcharts
2017/04/05 PHP
php 中self,this的区别和操作方法实例分析
2019/11/04 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
javascript制作的网页侧边弹出框思路及实现代码
2014/05/21 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
2014/05/28 Javascript
Bootstrap modal使用及点击外部不消失的解决方法
2016/12/13 Javascript
微信小程序 slider的简单实例
2017/04/19 Javascript
jQuery 实时保存页面动态添加的数据的示例
2017/08/14 jQuery
Bootstrap table中toolbar新增条件查询及refresh参数使用方法
2018/05/18 Javascript
react-native android状态栏的实现
2018/06/15 Javascript
AngularJS与后端php的数据交互方法
2018/08/13 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
js实现多图和单图上传显示
2019/12/18 Javascript
详解JavaScript修改注册表的方法
2020/01/05 Javascript
原生js实现俄罗斯方块
2020/10/20 Javascript
python基于urllib实现按照百度音乐分类下载mp3的方法
2015/05/25 Python
Python实现公历(阳历)转农历(阴历)的方法示例
2017/08/22 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
2017/12/25 Python
Tensorflow中使用tfrecord方式读取数据的方法
2018/06/19 Python
Python数据预处理之数据规范化(归一化)示例
2019/01/08 Python
Python常用特殊方法实例总结
2019/03/22 Python
python实现差分隐私Laplace机制详解
2019/11/25 Python
使用python+poco+夜神模拟器进行自动化测试实例
2020/04/23 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
2020/10/29 Python
经典c++面试题三
2015/07/08 面试题
体育教师求职信
2014/05/24 职场文书
校园文明标语
2014/06/13 职场文书
2014镇副书记群众路线专题民主生活会思想汇报
2014/09/23 职场文书
2014年内部审计工作总结
2014/12/09 职场文书
2015年物业公司保洁工作总结
2015/10/22 职场文书
少儿励志名言(80句)
2019/08/14 职场文书
个人房屋租赁合同(标准范本)
2019/09/16 职场文书
python geopandas读取、创建shapefile文件的方法
2021/06/29 Python
Vue3如何理解ref toRef和toRefs的区别
2022/02/18 Vue.js