CRMEB/extend/service/RoutineRefund.php
2018-12-31 13:39:11 +08:00

159 lines
5.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace service;
/**
* 小程序退款
* Class RoutineRefund
* @package service
*/
class RoutineRefund
{
public static function options(){
$config = SystemConfigService::more(['pay_routine_appid','pay_routine_appsecret','pay_routine_mchid','pay_routine_key','pay_routine_client_cert','pay_routine_client_key']);
return $config;
}
/**
* 退款
* @param float $totalFee 订单金额 单位元
* @param float $refundFee 退款金额 单位元
* @param string $refundNo 退款单号
* @param string $wxOrderNo 微信订单号
* @param string $orderNo 商户订单号
* @param string $refundDesc 退款原因
* @return string
*/
public static function doRefund($totalFee, $refundFee, $refundNo, $wxOrderNo='',$orderNo='',$refundDesc = '')
{
$config = array(
'mch_id' => self::options()['pay_routine_mchid'],
'appid' => self::options()['pay_routine_appid'],
'key' => self::options()['pay_routine_key'],
);
$unified = array(
'appid' => $config['appid'],
'mch_id' => $config['mch_id'],
'nonce_str' => self::createNonceStr(),
'total_fee' => intval($totalFee * 100), //订单金额 单位 转为分
'refund_fee' => intval($refundFee * 100), //退款金额 单位 转为分
'sign_type' => 'MD5', //签名类型 支持HMAC-SHA256和MD5默认为MD5
'transaction_id'=>$wxOrderNo, //微信订单号
'out_trade_no'=>$orderNo, //商户订单号
'out_refund_no'=>$refundNo, //商户退款单号
'refund_desc'=>$refundDesc, //退款原因(选填)
);
$unified['sign'] = self::getSign($unified, $config['key']);
$responseXml = self::curlPost('https://api.mch.weixin.qq.com/secapi/pay/refund', self::arrayToXml($unified));
$unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);
if ($unifiedOrder === false) {
die('parse xml error');
}
if ($unifiedOrder->return_code != 'SUCCESS') {
die($unifiedOrder->return_msg);
}
if ($unifiedOrder->result_code != 'SUCCESS') {
die($unifiedOrder->err_code);
}
return true;
}
public static function curlGet($url = '', $options = array())
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
if (!empty($options)) {
curl_setopt_array($ch, $options);
}
//https请求 不验证证书和host
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
public static function curlPost($url = '', $postData = '', $options = array())
{
if (is_array($postData)) {
$postData = http_build_query($postData);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
if (!empty($options)) {
curl_setopt_array($ch, $options);
}
//https请求 不验证证书和host
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//第一种方法cert 与 key 分别属于两个.pem文件
//默认格式为PEM可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
// curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/cert/apiclient_cert.pem');
curl_setopt($ch,CURLOPT_SSLCERT,realpath('.'.self::options()['pay_routine_client_cert']));
//默认格式为PEM可以注释
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
// curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/cert/apiclient_key.pem');
curl_setopt($ch,CURLOPT_SSLKEY,realpath('.'.self::options()['pay_routine_client_key']));
//第二种方式,两个文件合成一个.pem文件
// curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
public static function createNonceStr($length = 16)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
public static 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;
}
public static function getSign($params, $key)
{
ksort($params, SORT_STRING);
$unSignParaString = self::formatQueryParaMap($params, false);
$signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
return $signStr;
}
protected static function formatQueryParaMap($paraMap, $urlEncode = false)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if (null != $v && "null" != $v) {
if ($urlEncode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
}
?>