微信退款实战案例

简介: 微信退款实战案例
<?php
/* 
 * 咔咔
 * 微信号 fangkangfk
 * author:2018.6.20
 * 一个文件实现微信退款
 */
class Refund
{   
    const REFUND = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
    const KEY = 'h5l4P8S3u5n1H5Y4D7E5l9e6J4Y7S8h3';
    const CODEURL = 'https://open.weixin.qq.com/connect/oauth2/authorize?';
    const OPENIDURL = 'https://api.weixin.qq.com/sns/oauth2/access_token?';
    const APPID = '商户号id';
    const SECRET = '秘钥';
    const MCHID = '商户微信号';
    const UNURL = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    private $params;
    public function __construct($data) {
        //组装数据
        $this->params = [
            'appid'   =>  self::APPID, //APPID
            'mch_id'  =>  self::MCHID, //商户号
            'nonce_str'=> md5(time()), //随机串
            'sign'  => 'md5',          //签名方式
            'transaction_id'=> $data['transaction_id'],//微信支付订单号 与商户订单号二选一
            //'out_trade_no'=> '', //商户订单号 和微信支付订单号二选一
            'out_refund_no' => $data['out_refund_no'],//退单号
            'total_fee'     => $data['total_fee'],    //订单金额
            'refund_fee'    => $data['refund_fee']    //退款金额
        ];
    }
    //发送退款请求
    public function orderRefund(){
        //生成签名
        $signParams = $this->setSign($this->params);
        //将数据转换为xml
        $xmlData = $this->ArrToXml($signParams);
        //发送请求
        return  $this->postStr(self::REFUND, $xmlData);
    }
    //post 字符串到接口
    public function postStr($url,$postfields){
        $ch = curl_init();
        $params[CURLOPT_URL] = $url;    //请求url地址
        $params[CURLOPT_HEADER] = false; //是否返回响应头信息
        $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回
        $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向
        $params[CURLOPT_POST] = true;
        $params[CURLOPT_SSL_VERIFYPEER] = false;//禁用证书校验
    $params[CURLOPT_SSL_VERIFYHOST] = false;
      //以下是证书相关代码
    $params[CURLOPT_SSLCERTTYPE] = 'PEM';
    $params[CURLOPT_SSLCERT] = './cert/apiclient_cert.pem';
    $params[CURLOPT_SSLKEYTYPE] = 'PEM';
    $params[CURLOPT_SSLKEY] = './cert/apiclient_key.pem';
        $params[CURLOPT_POSTFIELDS] = $postfields;
        curl_setopt_array($ch, $params); //传入curl参数
        $content = curl_exec($ch); //执行
        curl_close($ch); //关闭连接
        return $content;
    }
    //生成签名
    public function getSign($arr){
        //去除空值
        $arr = array_filter($arr);
        if(isset($arr['sign'])){
            unset($arr['sign']);
        }
        //按照键名字典排序
        ksort($arr);
        //生成url格式的字符串
       $str = $this->arrToUrl($arr) . '&key=' . self::KEY;
       return strtoupper(md5($str));
    }
    //获取带签名的数组
    public function setSign($arr){
        $arr['sign'] = $this->getSign($arr);;
        return $arr;
    }
    public function arrToUrl($arr){
        return urldecode(http_build_query($arr));
    }
    //验证签名
    public function chekSign($arr){
        $sign = $this->getSign($arr);
        if($sign == $arr['sign']){
            return true;
        }else{
            return false;
        }
    }
     //数组转xml
    public function ArrToXml($arr)
    {
            if(!is_array($arr) || count($arr) == 0) return '';
            $xml = "<xml>";
            foreach ($arr as $key=>$val)
            {
                    if (is_numeric($val)){
                            $xml.="<".$key.">".$val."</".$key.">";
                    }else{
                            $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
                    }
            }
            $xml.="</xml>";
            return $xml; 
    }
    public function XmlToArr($xml)
    {   
        if($xml == '') return '';
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);     
        return $arr;
    }
}
// 获取订单号
$orderdata = D('foodorder')->where([
    'id'=>$_SESSION['orderid']
    ])->find();
// 传值
$data = [
    'transaction_id'    => $orderdata['wx_number'], //微信交易号
    'out_refund_no'    => $orderdata['wx_number'], //退款单号
    'total_fee'    => $orderdata['cash_fee'], //原订单金额
    'refund_fee'    => $orderdata['cash_fee'] //退款金额
];
// 实例化退款类
$obj = new Refund($data);
// 调用退款方法
$res = $obj->orderRefund();
// 退款微信返回数据
$refunddata = $obj->XmlToArr($res);
if($refunddata['return_code'] == 'SUCCESS'){
    $data['wx_refundorder'] = $orderdata['wx_number'];
    $data['user_id'] = $orderdata['userid'];
    $data['refund_fee'] = $orderdata['cash_fee'];
    $data['refund_time'] = time();
    $datas['wxrefund_number'] = $orderdata['wx_number'];
    $orderdata = D('foodorder')->where([
        'wx_number'=>$orderdata['wx_number']
        ])->save($datas);
    if(!$orderdata){
        $log_name= "./Public/Pay/refund_url.log";//log文件路径
        file_put_contents($log_name,"【退款成功 , 订单数据库添加失败通知", FILE_APPEND);
    }
    $refundorder = D('refundorder')->add($data);
    if(!$refundorder){
        $log_name= "./Public/Pay/refund_url.log";//log文件路径
        file_put_contents($log_name,"【退款成功 , 数据库添加失败通知", FILE_APPEND);
    }
}else{
    $log_name= "./Public/Pay/refund_url.log";//log文件路径
    file_put_contents($log_name,"【退款失败", FILE_APPEND);
}
相关文章
|
20天前
|
缓存 数据可视化 Serverless
微信小游戏 案例一 像素飞机
微信小游戏 案例一 像素飞机
16 2
|
14天前
|
JavaScript 小程序 开发者
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
159 0
|
3月前
|
人工智能 搜索推荐 安全
从零到一:微信机器人开发的实战心得
从零到一:微信机器人开发的实战心得
207 2
|
4月前
|
小程序 安全 搜索推荐
【微信小程序开发实战项目】——个人中心页面的制作
本文介绍了如何设计和实现一个网上花店的微信小程序,包括个人中心、我的订单和我的地址等功能模块。个人中心让用户能够查看订单历史、管理地址和与客服互动。代码示例展示了`own.wxml`、`own.wxss`和`own.js`文件,用于构建个人中心界面,包括用户信息、订单链接、收藏、地址、客服和版本信息。我的订单部分展示了订单详情,包括商品图片、名称、销量、价格和订单状态,用户可以查看和管理订单。我的地址功能允许用户输入和编辑收货信息,包括联系人、性别、电话、城市和详细地址。每个功能模块都附有相应的WXML和WXSS代码,以及简洁的样式设计。
189 0
【微信小程序开发实战项目】——个人中心页面的制作
|
4月前
|
小程序 开发者
uniapp实战 —— 开发微信小程序的调试技巧
uniapp实战 —— 开发微信小程序的调试技巧
391 1
|
4月前
|
前端开发 小程序
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)
403 0
|
4月前
|
XML Java 数据格式
支付系统----微信支付20---创建案例项目--集成Mybatis-plus的补充,target下只有接口的编译文件,xml文件了,添加日志的写法
支付系统----微信支付20---创建案例项目--集成Mybatis-plus的补充,target下只有接口的编译文件,xml文件了,添加日志的写法
支付系统----微信支付16----创建案例项目-引入Swagger
支付系统----微信支付16----创建案例项目-引入Swagger
支付系统---微信支付14----创建案例项目---介绍,第二步引入Swagger,接口文档和测试页面生成工具,定义统一结果的目的是让结果变得更加规范,以上就是谷粒项目的几个过程
支付系统---微信支付14----创建案例项目---介绍,第二步引入Swagger,接口文档和测试页面生成工具,定义统一结果的目的是让结果变得更加规范,以上就是谷粒项目的几个过程
|
4月前
|
小程序
【微信小程序】实战案例 -- 向订阅用户发送消息(范例:报名提醒)
【微信小程序】实战案例 -- 向订阅用户发送消息(范例:报名提醒)
237 0

热门文章

最新文章