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执行速度全攻略
Oct 09 PHP
中国站长站 For Dede4.0 采集规则
May 27 PHP
php初学者写及时补给skype用户充话费的小程序
Nov 02 PHP
解析关于java,php以及html的所有文件编码与乱码的处理方法汇总
Jun 24 PHP
php不允许用户提交空表单(php空值判断)
Nov 12 PHP
THINKPHP2.0到3.0有哪些改进之处
Jan 04 PHP
PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍
Jan 20 PHP
php中header跳转使用include包含解决参数丢失问题
May 08 PHP
php正则判断是否为合法身份证号的方法
Mar 16 PHP
PHP fopen函数用法实例讲解
Feb 15 PHP
PHP中非常有用却鲜有人知的函数集锦
Aug 17 PHP
php中文语义分析实现方法示例
Sep 28 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
星际流派综述
2020/03/04 星际争霸
javascript中的几个运算符
2007/06/29 Javascript
改进版通过Json对象实现深复制的方法
2012/10/24 Javascript
jquery如何改变html标签的样式(两种实现方法)
2013/01/16 Javascript
jQuery之尺寸调整组件的深入解析
2013/06/19 Javascript
jquery用get实现ajax在ie里面刷新不进入后台解决方法
2013/08/12 Javascript
JS实现程序暂停与继续功能代码解读
2013/10/10 Javascript
纯JS实现旋转图片3D展示效果
2015/04/12 Javascript
AngularJS在IE8的不支持的解决方法
2016/05/13 Javascript
Javascript随机标签云代码实例
2016/06/21 Javascript
快速掌握jQuery插件开发
2017/01/19 Javascript
Javascript for in的缺陷总结
2017/02/03 Javascript
微信小程序调用PHP后台接口 解析纯html文本
2017/06/13 Javascript
vuex state及mapState的基础用法详解
2018/04/19 Javascript
Vue中在新窗口打开页面及Vue-router的使用
2018/06/13 Javascript
vue3.0实现插件封装
2020/12/14 Vue.js
[03:55]2016国际邀请赛中国区预选赛首日TOP10精彩集锦
2016/06/27 DOTA
[06:53]2018DOTA2国际邀请赛寻真——勇于创新的Vici Gaming
2018/08/14 DOTA
详解python3中tkinter知识点
2018/06/21 Python
在python中将list分段并保存为array类型的方法
2019/07/15 Python
使用opencv将视频帧转成图片输出
2019/12/10 Python
Python计算机视觉里的IOU计算实例
2020/01/17 Python
Pandas —— resample()重采样和asfreq()频度转换方式
2020/02/26 Python
python飞机大战游戏实例讲解
2020/12/04 Python
Pycharm plot独立窗口显示的操作
2020/12/11 Python
Paradigit比利时电脑卖场:购买笔记本、电脑、平板和外围设备
2016/11/28 全球购物
Oroton中国官网:澳洲知名奢侈配饰品牌
2017/03/26 全球购物
Tommy Hilfiger美国官网:美国高端休闲领导品牌
2019/01/14 全球购物
抽象类和接口的区别
2012/09/19 面试题
高中美术教学反思
2014/01/19 职场文书
旅游个人求职信范文
2014/01/30 职场文书
小学生中国梦演讲稿
2014/04/23 职场文书
心理健康活动总结
2014/04/30 职场文书
法人代表证明书格式
2014/10/01 职场文书
入党积极分子考察意见
2015/06/02 职场文书
你有一份《诚信考试承诺书》待领取
2019/11/13 职场文书