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

//微信退款控制器

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 = "";
    foreach ($arr as $key=>$val)
    {
        if (is_numeric($val)){
            $xml.="<".$key.">".$val.".$key.">";
        }else{
            $xml.="<".$key.">.$val."]]>.$key.">";
        }
    }
    $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"."
"
; curl_close($ch); return false; } } }

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

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

然后就可以成功退款啦。

你可能感兴趣的:(小程序,PHP)