微信小程序-微信支付退款(可直接使用)

//微信退款控制器
<?php
namespace app\pay\controller;

/*
 * 小程序微信退款支付
 */
class Winxinrefund{

  protected $SSLCERT_PATH = APP_PATH.'/pay/cert/apiclient_cert.pem';//证书路径
  protected $SSLKEY_PATH =  APP_PATH.'/pay/cert/apiclient_key.pem';//证书路径
  protected $opUserId = '';//商户号
  protected $KEY = '';

  function __construct($openid,$outTradeNo,$totalFee,$outRefundNo,$refundFee){

    //初始化退款类需要的变量

    $this->openid = $openid;

    $this->outTradeNo = $outTradeNo;

    $this->totalFee = $totalFee*100;

    $this->outRefundNo = $outRefundNo;

    $this->refundFee = $refundFee*100;

  }

  public function refund(){

    //对外暴露的退款接口

    $result = $this->wxrefundapi();

    return $result;

  }

  private function wxrefundapi(){

    //通过微信api进行退款流程

    $parma = array(

      'appid'=> 'wx9aa3d23bd288511a',

      'mch_id'=> '1594691381',

      'nonce_str'=> $this->createNoncestr(),

      'out_refund_no'=> $this->outRefundNo,

      'out_trade_no'=> $this->outTradeNo,

      'total_fee'=> $this->totalFee,

      'refund_fee'=> $this->refundFee

    );
    $parma['sign'] = $this->getSign($parma);

    $xmldata = $this->arrayToXml($parma);

    $xmlresult = $this->postXmlSSLCurl($xmldata,'https://api.mch.weixin.qq.com/secapi/pay/refund');

    $result = $this->xmlToArray($xmlresult);

    return $result;

  }
protected function getSign($Obj){
    foreach ($Obj as $k => $v){
        $Parameters[$k] = $v;
    }
    //签名步骤一:按字典序排序参数
    ksort($Parameters);
    $String = $this->formatBizQueryParaMap($Parameters, false);
    //签名步骤二:在string后加入KEY
    $String = $String."&key=".$this->KEY;
    //签名步骤三:MD5加密
    $String = md5($String);
    //签名步骤四:所有字符转为大写
    $result_ = strtoupper($String);
    return $result_;
}

/*
 *排序并格式化参数方法,签名时需要使用
 */
protected function formatBizQueryParaMap($paraMap, $urlencode)
{
    $buff = "";
    ksort($paraMap);
    foreach ($paraMap as $k => $v)
    {
        if($urlencode)
        {
            $v = urlencode($v);
        }
        //$buff .= strtolower($k) . "=" . $v . "&";
        $buff .= $k . "=" . $v . "&";
    }
    $reqPar = "";
    if (strlen($buff) > 0)
    {
        $reqPar = substr($buff, 0, strlen($buff)-1);
    }
    return $reqPar;
}

/*
 * 生成随机字符串方法
 */
protected function createNoncestr($length = 32 ){
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str ="";
    for ( $i = 0; $i < $length; $i++ ) {
        $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return $str;
}
//数组转字符串方法
protected function arrayToXml($arr){
    $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;
}

protected static function xmlToArray($xml){
  // dump($xml);die;
    $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $array_data;
}

//需要使用证书的请求
private function postXmlSSLCurl($xml,$url,$second=30)
{
    $ch = curl_init();
    //超时时间
    curl_setopt($ch,CURLOPT_TIMEOUT,$second);
    //这里设置代理,如果有的话
    //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
    //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
    //设置header
    curl_setopt($ch,CURLOPT_HEADER,FALSE);
    //要求结果为字符串且输出到屏幕上
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
    //设置证书
    //使用证书:cert 与 key 分别属于两个.pem文件
    //默认格式为PEM,可以注释
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH);
    //默认格式为PEM,可以注释
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLKEY,$this->SSLKEY_PATH);
    //post提交方式
    curl_setopt($ch,CURLOPT_POST, true);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
    $data = curl_exec($ch);
    //返回结果
    if($data){
        curl_close($ch);
        return $data;
    }
    else {
        $error = curl_errno($ch);
        echo "curl出错,错误码:$error"."<br>";
        curl_close($ch);
        return false;
   	}
}
}

PHP调用退款接口,实现退款功能

$pay = new Winxinrefund($openid,支付时传递的订单号,支付的价格,退款单号,退款金额);
$result = $pay->refund();

然后就可以成功退款啦。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值