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删除记录操作代码
Jun 07 PHP
php 设计模式之 工厂模式
Dec 19 PHP
Sorting Array Values in PHP(数组排序)
Sep 15 PHP
如何实现php图片等比例缩放
Jul 28 PHP
PHP模拟asp中response类实现方法
Aug 08 PHP
php实现图片上传时添加文字和图片水印技巧
Apr 18 PHP
如何离线执行php任务
Feb 21 PHP
详解php框架Yaf路由重写
Jun 20 PHP
PHP十六进制颜色随机生成器功能示例
Jul 24 PHP
Laravel如何使用数据库事务及捕获事务失败后的异常详解
Oct 23 PHP
PHP数组式访问接口ArrayAccess用法分析
Dec 28 PHP
Mac M1安装mnmp (Mac+Nginx+MySQL+PHP) 开发环境
Mar 29 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
用 Composer构建自己的 PHP 框架之使用 ORM
2014/10/30 PHP
PHPExcel内存泄漏问题解决方法
2015/01/23 PHP
PHP+APACHE实现网址伪静态
2015/02/22 PHP
Yii2中事务的使用实例代码详解
2016/09/07 PHP
Thinkphp通过一个入口文件如何区分移动端和PC端
2017/04/18 PHP
PHP实现压缩图片尺寸并转为jpg格式的方法示例
2018/05/10 PHP
解决laravel-admin 自己新建页面里 js 需要刷新一次的问题
2019/10/03 PHP
JavaScript 格式字符串的应用
2010/03/29 Javascript
jQuery侧边栏随窗口滚动实现方法
2013/03/04 Javascript
javascript处理表单示例(javascript提交表单)
2014/04/28 Javascript
使用jspdf生成pdf报表
2015/07/03 Javascript
写给小白的JavaScript引擎指南
2015/12/04 Javascript
js弹出窗口返回值的简单实例
2016/05/28 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
AngularJS中的拦截器实例详解
2017/04/07 Javascript
js学习总结之DOM2兼容处理顺序问题的解决方法
2017/07/27 Javascript
微信小程序实现tab切换效果
2017/11/21 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
2019/04/17 Javascript
微信小程序页面间传值与页面取值操作实例分析
2019/04/30 Javascript
uni-app实现点赞评论功能
2019/11/25 Javascript
python读取Android permission文件
2013/11/01 Python
pyqt4教程之实现半透明的天气预报界面示例
2014/03/02 Python
python实现反转部分单向链表
2018/09/27 Python
pyqt5之将textBrowser的内容写入txt文档的方法
2019/06/21 Python
Python3.7 读取 mp3 音频文件生成波形图效果
2019/11/05 Python
centos+nginx+uwsgi+Django实现IP+port访问服务器
2019/11/15 Python
Python concurrent.futures模块使用实例
2019/12/24 Python
解决tensorflow打印tensor有省略号的问题
2020/02/04 Python
Anaconda和ipython环境适配的实现
2020/04/22 Python
Python paramiko使用方法代码汇总
2020/11/20 Python
python 基于Apscheduler实现定时任务
2020/12/15 Python
WoolOvers澳洲官方网站:英国针织服装公司
2018/05/13 全球购物
澳大利亚床上用品、浴巾和家居用品购物网站:Bambury
2020/04/16 全球购物
学生干部培训方案
2014/06/12 职场文书
公司宣传语大全
2015/07/13 职场文书
sql server删除前1000行数据的方法实例
2021/08/30 SQL Server