Browse Source

支付宝退款

undefined
v-Brocloni 4 years ago
parent
commit
502f8597b1
11 changed files with 1630 additions and 6 deletions
  1. +28
    -0
      addons/epay/library/Service.php
  2. +2
    -2
      addons/epay/library/Yansongda/Pay/Gateways/Alipay/Alipay.php
  3. +307
    -0
      addons/nzf/AliPay.php
  4. +466
    -0
      addons/nzf/CurlInterface.php
  5. +98
    -0
      addons/nzf/PayService.php
  6. +343
    -0
      addons/nzf/Util.php
  7. +337
    -0
      addons/nzf/WeChatPay.php
  8. +23
    -1
      addons/unishop/behavior/Order.php
  9. +11
    -2
      addons/unishop/controller/Order.php
  10. +12
    -0
      addons/unishop/controller/Pay.php
  11. +3
    -1
      composer.json

+ 28
- 0
addons/epay/library/Service.php View File

@@ -2,10 +2,12 @@

namespace addons\epay\library;

use addons\unishop\model\Config;
use Exception;
use think\Log;
use think\Response;
use think\Session;
use Yansongda\Pay\Gateways\Alipay\Alipay;
use Yansongda\Pay\Pay;

/**
@@ -156,6 +158,32 @@ class Service
}

/**
* @param string $orderNo 订单号
* @param string $type 支付类型 wechat alipay
* @param int $amount 退款金额
*/
public static function refund($orderNo,$type,$amount){
$config = Service::getConfig($type);
$pay = new Pay($config);
if ($type == "alipay") {
$config_biz = [
'out_trade_no' => $orderNo,
'refund_amount' => $amount,
];
$pay->driver($type)->gateway()->refund($config_biz);
} else {
$config_biz = [
'out_trade_no' => $orderNo,
'out_refund_no' => $orderNo,
'total_fee' => bcmul($amount, 100),
'refund_fee' => bcmul($amount, 100),
];
$pay->driver($type)->gateway()->refund($config_biz);
}

}

/**
* 创建支付对象
* @param string $type 支付类型
* @param array $config 配置信息


+ 2
- 2
addons/epay/library/Yansongda/Pay/Gateways/Alipay/Alipay.php View File

@@ -53,8 +53,8 @@ abstract class Alipay implements GatewayInterface
'charset' => 'UTF-8',
'sign_type' => 'RSA2',
'version' => '1.0',
'return_url' => $this->user_config->get('return_url', ''),
'notify_url' => $this->user_config->get('notify_url', ''),
'notifyurl' => \addons\unishop\model\Config::getByName('ali_notify_url')['value'],
'returnurl' => \addons\unishop\model\Config::getByName('ali_return_url')['value'],
'timestamp' => date('Y-m-d H:i:s'),
'sign' => '',
'biz_content' => '',


+ 307
- 0
addons/nzf/AliPay.php View File

@@ -0,0 +1,307 @@
<?php
/**
*
* ============================================================================
* * 版权�?�? 运游�? * *
* 网站地址: http://www.zhizhuchuxing.com
* ----------------------------------------------------------------------------
* 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改�?
* 使用;不允许对程序代码以任何形式任何目的的再发布�?
* ============================================================================
* Author By: 倪宗�?
* PhpStorm AliPayService.php
* Create By 2016/12/12 14:32 $
*/


namespace addons\nzf;


use addons\unishop\model\Config;

class AliPay
{
private static $gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
/**
* Des:扫描支付
* Name: unifiedOrderByOrderIdForSao
* @param $par
* @return array
* @author 倪宗锋
*/
public function unifiedOrderByOrderIdForSao($par)
{
$aliPay = new AliPay();
//交易参数
$params['body'] = $par['name'];
$params['subject'] = $par['name'];
$params['order_id'] = $par['order_id'];
$params['price'] = $par['total_fee'];
$params['timeout_express'] = '1m';
$params['goType'] = 3;
$params['method'] = 'alipay.trade.precreate';
$getUrl = $aliPay->getAliPayUrl($params);
$url = '/fx/?r=weChat/we-chat/q-code&qCode=' . urlencode($getUrl['data']['codUrl']) . '&_math=' . rand(100, 999);
return Util::returnArrSu('', array('codUrl' => $url, 'price' => $par['total_fee']));
}

/**
* Function Description:支付宝web支付
* Function Name: webPay
* @param $param array
* @return array
*
* @author nzf
*/
public function webPay($param)
{
//交易参数
$params['body'] = $param['name'];
$params['subject'] = $param['name'];
$params['order_id'] = $param['order_id'];
$params['price'] = $param['total_fee'];
$params['timeout_express'] = '1m';
$params['goType'] = 2;
$params['method'] = 'alipay.trade.wap.pay';
$return = static::getAliPayUrl($params);
return $return;
}

/********************通用方法**************************/
/**
* Function Description:获取阿里支付pay
* Function Name: getAliPayUrl
* @param $params array
*
* @return array
*
* @author 倪宗�?
*/
private static function getAliPayUrl($params)
{
$sysParams = self::getSysParams();
$sysParams["method"] = $params['method'];
//交易参数
$body['productCode'] = 'QUICK_WAP_PAY';
$body['body'] = $params['body'];
$body['subject'] = $params['subject'];
$body['out_trade_no'] = $params['order_id'];
$body['total_amount'] = $params['price'];
$body['timeout_express'] = "1m";

$sysParams['biz_content'] = json_encode($body);
if ($params['goType'] == 1) {//如果是页面跳�?
$sysParams['sign'] = urlencode(static::getSign($sysParams));
$paramString = static::getSignContent($sysParams);
$requestUrl = static::$gatewayUrl . "?" . $paramString;
return Util::returnArrSu('', ['payData' => $requestUrl]);
} elseif ($params['goType'] == 2) {//如果是参数返�?
$sysParams['sign'] = static::getSign($sysParams);
$result = self::buildRequestForm($sysParams);
return Util::returnArrSu('', ['payData' => $result]);
} else {
$sysParams['sign'] = urlencode(static::getSign($sysParams));
$paramString = static::getSignContent($sysParams);
$requestUrl = static::$gatewayUrl . "?" . $paramString;
$curl = new CurlInterface('', 5);
$result = $curl->execute($requestUrl, 'GET');
$result = json_decode($result, true);
$return['codUrl'] = '';
if ($result['alipay_trade_precreate_response']['code'] == '10000') {
$return['codUrl'] = $result['alipay_trade_precreate_response']['qr_code'];
}
return Util::returnArrSu('', $return);
}
}

/**
* Function Description:取消订单
* Function Name: cancelOrder
* @param $params
*
* @return array
*
* @author 倪宗�?
*/
public static function cancelOrder($params)
{
$sysParams = self::getSysParams();
$sysParams["method"] = 'alipay.trade.refund';
$body = array(
'out_trade_no' => $params['order_id'],//订单�?
'refund_amount' => $params['refund_fee'],//退款金额
'refund_reason' => $params['memo'],
'out_request_no' => $params['order_id'] . '-' . date('YmdHis') . rand(100, 999)//�?款原�?
);
unset($sysParams["notify_url"]);
unset($sysParams["return_url"]);
$sysParams['biz_content'] = json_encode($body);
$sysParams['sign'] = static::getSign($sysParams);
$sysParams['sign'] = urlencode(static::getSign($sysParams));
$paramString = static::getSignContent($sysParams);
$requestUrl = static::$gatewayUrl."?".$paramString;
//调用款接
$curlInterface = new CurlInterface($sysParams, 5);
$result = $curlInterface->execute($requestUrl, 'GET');
$result = json_decode(mb_convert_encoding($result, 'utf-8'), true);
if (isset($result['alipay_trade_refund_response']) && $result['alipay_trade_refund_response']['code'] == '10000') {
return Util::returnArrSu();
}
return Util::returnArrEr('退款失败!');
}

/**
* Function Description:获取系统通用参数
* Function Name: getSysParams
* @param $app_id string
* @param $order_id string
* @return mixed
*
* @author 倪宗�?
*/
private static function getSysParams()
{
//组装系统参数
$sysParams["app_id"] = Config::getByName('ali_app_id')['value'];
$sysParams["version"] = '1.0';
$sysParams["format"] = 'json';
$sysParams["sign_type"] = 'RSA2';

$sysParams["timestamp"] = date("Y-m-d H:i:s");
$sysParams["alipay_sdk"] = 'alipay-sdk-php-20160411';
$sysParams["prod_code"] = '';
$sysParams["notify_url"] = Config::getByName('ali_notify_url')['value'];
$sysParams["return_url"] = Config::getByName('ali_return_url')['value'];
$sysParams["charset"] = "utf-8";
return $sysParams;
}

/**
* Function Description:建立请求,以表单HTML形式构�?�(默认�?
* Function Name: buildRequestForm
* @param $para_temp
*
* @return string 提交表单HTML文本
*
* @author 倪宗�?
*/
protected static function buildRequestForm($para_temp)
{
$sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='" . static::$gatewayUrl . "?charset=utf-8' method='get'>";
while (list ($key, $val) = each($para_temp)) {
if (false === static::checkEmpty($val)) {
$val = str_replace("'", "&apos;", $val);
$sHtml .= "<input type='hidden' name='" . $key . "' value='" . $val . "'/>";
}
}
return $sHtml;
}

/**
* Function Description:获取签名
* Function Name: getSign
* @param $params
* @param $app_id
* @return string
*
* @author 倪宗�?
*/
public static function getSign($params)
{
if (isset($params['sign'])) {
unset($params['sign']);
}
$content = self::getSignContent($params);
$priKey = Config::getByName('ali_private_key')['value'];
// $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
// wordwrap($priKey, 64, "\n", true) .
// "\n-----END RSA PRIVATE KEY-----";
// openssl_sign($content, $sign, $res);
// $sign = base64_encode($sign);
// return $sign;

$res = "-----BEGIN RSA PRIVATE KEY-----\n".
wordwrap($priKey, 64, "\n", true).
"\n-----END RSA PRIVATE KEY-----";

openssl_sign($content, $sign, $res, OPENSSL_ALGO_SHA256);

return base64_encode($sign);
}


/**
* Function Description:将数组转换为符合阿里支付的路由参�?
* Function Name: getSignContent
* @param $params
*
* @return string
*
* @author 倪宗�?
*/
public static function getSignContent($params)
{
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === self::checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 转换成目标字符集
$v = self::characet($v, 'utf-8');

if ($i == 0) {
$stringToBeSigned.="$k"."="."$v";
} else {
$stringToBeSigned.="&"."$k"."=".$v;
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}

/**
* Function Description:校验$value是否非空
* Function Name: checkEmpty
* @param $value
*
* @return bool
*
* @author 倪宗�?
*/
private static function checkEmpty($value)
{
if (!isset($value)) {
return true;
}
if ($value === null) {
return true;
}
if (trim($value) === "") {
return true;
}
return false;
}

/**
* Function Description:转换字符集编�?
* Function Name: characet
* @param $data
* @param $targetCharset
*
* @return string
*
* @author 倪宗�?
*/
private static function characet($data, $targetCharset)
{
if (!empty($data)) {
$fileType = 'utf-8';
if (strcasecmp($fileType, $targetCharset) != 0) {
$data = mb_convert_encoding($data, $targetCharset);
}
}
return $data;
}
}

+ 466
- 0
addons/nzf/CurlInterface.php View File

@@ -0,0 +1,466 @@
<?php
/**
* 接口调用
* ============================================================================
* * 版权所有 蜘蛛行 * *
* 网站地址: http://www.zhizhuchuxing.com
* ----------------------------------------------------------------------------
* 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和
* 使用;不允许对程序代码以任何形式任何目的的再发布。
* ============================================================================
* Author By: 倪宗锋
* PhpStorm CurlInterface.php
* Create By 2016/11/10 13:20 $
*/


namespace addons\nzf;
class CurlInterface
{
protected $url = null;
protected $verb = 'GET';
protected $body = '';
protected $requestLength = 0;
protected $baseUrl = null;
protected $timeOut = 200;
protected $clientId = 1;//站点类型 1 微信
protected $responseBody = null;//接收到的返回值
protected $notReturn = false; //是否有返回值
protected $siteConfig = null; //配置参数
protected $curlGetInfo = null;//交易概要
private $logMessage = ''; //日志内容
private $curlOptHeader = 0; //是否返回头部信息
private $bodyType = 1;
private $cert = false;//是否使用证书
private $certPem;
private $keyPem;

/****************============类的初始化=============*******************/

/**
* @param null $body 2:xml
* @param int $type 1:json 2:xml 3 发送原数据接收xml 4 发送原数据 接收json 5:都是原数据
*/
public function __construct($body = null, $type = 1)
{
$this->setBody($body, $type);
$this->setBaseUrl();
}

/*****************==========参数设置函数开始=========******************/
/**
* Function Description:设置是否返回头部信息
* Function Name: setCurlOptHeader
* @param $curlOptHeader
*
*
* @author 倪宗锋
*/
public function setCurlOptHeader($curlOptHeader)
{
$this->curlOptHeader = $curlOptHeader;
}

/**
* Function Description:获取交易概要
* Function Name: getCurlGetInfo
*
* @return null
*
* @author 倪宗锋
*/
public function getCurlGetInfo()
{
return $this->curlGetInfo;
}

/**
* Function Description:获取返回值报文
* Function Name: getResponseBody
*
* @return null
*
* @author 倪宗锋
*/
public function getResponseBody()
{
return $this->responseBody;
}

/**
* Function Description:获取全路径地址
* Function Name: getUrl
*
* @return null
*
* @author 倪宗锋
*/
public function getUrl()
{
return $this->url;
}

/**
* Function Description:设置路径 在baseUrl基础上
* Function Name: setUrl
* @param $url
*
*
* @author 倪宗锋
*/
public function setUrl($url)
{
$this->url = $this->baseUrl . $url;
}

/**
* Function Description:设置过期时间
* Function Name: setTimeOut
* @param $timeOut
*
*
* @author 倪宗锋
*/
public function setTimeOut($timeOut)
{
$this->timeOut = $timeOut;
}

/**
* Function Description:设置传值方式
* Function Name: setVerb
* @param $verb
*
*
* @author 倪宗锋
*/
public function setVerb($verb)
{
$this->verb = $verb;
}

/**
* Function Description:设置baseUrl
* Function Name: setBaseUrl
* @param $baseUrl string
*
* @author 倪宗锋
*/
public function setBaseUrl($baseUrl = '')
{
$this->baseUrl = $baseUrl;
}

/**
* Function Description:获取BaseUrl
* Function Name: getBaseUrl
*
* @return null
*
* @author 倪宗锋
*/
public function getBaseUrl()
{
return $this->baseUrl;
}

/**
* Function Description:设置是否有返回值
* Function Name: setNotReturn
* @param $str
*
*
* @author 倪宗锋
*/
public function setNotReturn($str)
{
$this->notReturn = $str;
}

/**
* Function Description:设置请求报文 $body 必须是个数组
* Function Name: setBody
* @param $body
* @param $type int 1:json 2:xml 3 发送原数据接收xml 4 发送原数据 接收json 5:都是原数据
*
* @author 倪宗锋
*/
public function setBody($body, $type = 1)
{
$this->body = '';
if (is_array($body)) {
if ($type == 1) {
$this->body = json_encode($body);
$this->requestLength = strlen($this->body);
} elseif ($type == 2) {
$this->body = '<?xml version="1.0" encoding="UTF-8"?>' . Util::arraysToXml(['response' => $body]);
$this->requestLength = strlen($this->body);
} elseif (in_array($type, array(3, 4, 5))) {
$this->body = $body;
}
} else {
$this->body = $body;
}
$this->bodyType = $type;
}

/**
* Function Description:设置ssl类型
* Function Name: setCert
* @param $certArr array
*
*
* @author 倪宗锋
*/
public function setCert($certArr)
{
$this->cert = true;
$this->certPem = $certArr['SSLCERT_PATH'];
$this->keyPem = $certArr['SSLKEY_PATH'];
}

/*****************==========参数设置函数结束=========******************/
/*****************==========调用接口并返回结果===开始======******************/

/**
* Function Description:执行交易
* Function Name: execute
* @param $url string sap地址
* @param $verb string 请求方式 post|get
* @return array
* @author nizongfeng
* Modify Date:2016.11.10
*/
public function execute($url, $verb = 'GET')
{
$url = preg_replace('# #','%20',$url);
$this->verb = $verb;
$this->url = $this->baseUrl . $url;

$this->logMessage .= date('Y-m-d H:i:s') . " Url : {$this->url}";
$this->logMessage .= ' Method:' . $this->verb . PHP_EOL;
if (is_array($this->body)) {
$this->logMessage .= "sendContent: " . json_encode($this->body) . PHP_EOL;
} else {
$this->logMessage .= "sendContent: {$this->body}" . PHP_EOL;
}

$ch = curl_init($this->url);
try {
switch (strtoupper($this->verb)) {
case 'GET':
$this->executeGet($ch);
break;
case 'POST':
$this->executePost($ch);
break;
case 'PUT':
$this->executePut($ch);
break;
case 'DELETE':
$this->executeDelete($ch);
break;
default:
$this->logMessage .= "current verb: {$this->verb}, is an invalid REST verb." . PHP_EOL;
break;
}
} catch (\Exception $e) {
$this->logMessage .= $e->getMessage() . PHP_EOL;
}
curl_close($ch);
$ch = null;
return $this->getResult();
}

/**
* Function Description:获取返回数据
* Function Name: getResult
*
* @return array|mixed
*
* @author nizongfeng
* Modify Date:2016.11.10
*/
public function getResult()
{
if (in_array($this->bodyType, array(1, 4))) {
$return = json_decode($this->responseBody, true);
} elseif (in_array($this->bodyType, array(2, 3))) {
$return = Util::xmlToArray($this->responseBody);
} elseif ($this->bodyType == 5) {
$return = $this->responseBody;
} else {
$return = '';
}
// file_put_contents(APP_PATH . '/log/curl/' . date('Y-m-d') . '.log', $this->logMessage . PHP_EOL, FILE_APPEND);
return $return;
}

/*******************=====GET传值=====********************/
/**
* Function Description:GET传值
* Function Name: executeGet
* @param $ch
*
* @return void
*
* @author nizongfeng 2016.11.10
*/
protected function executeGet($ch)
{
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$this->doExecute($ch);
}

/*******************=====POST传值=====********************/
/**
* Function Description:POST传值
* Function Name: executePost
* @param $ch
*
* @return void
*
* @author nizongfeng 2016.11.10
*/
protected function executePost($ch)
{
// curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_POST, true);
if (is_array($this->body)) {
$cnt = $this->getmaxdim($this->body);
if ($cnt > 1) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($this->body));
} else {
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body);
}
} else {
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body);
}
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$this->doExecute($ch);
}

/*******************=====PUT传值=====********************/
/**
* Function Description:PUT传值
* Function Name: executePut
* @param $ch
*
*
* @author 倪宗锋
*/
protected function executePut($ch)
{
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body);
$this->doExecute($ch);
}

/*******************=====DELETE传值=====********************/
/**
* Function Description:DELETE传值
* Function Name: executeDelete
* @param $ch
*
*
* @author 倪宗锋
*/
protected function executeDelete($ch)
{
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
$this->doExecute($ch);
}

/*******************=====传值及接收=====********************/
/**
* Function Description: 传值及接受数据
* Function Name: doExecute
* @param $curlHandle
*
* @return void
*
* @author nizongfeng 2015.12.08
*/
protected function doExecute(&$curlHandle)
{

if ($this->verb != 'get') {
$this->setCurlOpts($curlHandle);
}
curl_setopt($curlHandle, CURLOPT_HEADER, $this->curlOptHeader);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, CURLOPT_TIMEOUT, $this->timeOut);

//记录报文发送时间
$sendTime = microtime(true);
$this->responseBody = curl_exec($curlHandle);
//记录报文返回时间
$responseTime = microtime(true);
$timeIncrement = round(floatval($responseTime - $sendTime), 3);
//记录返回的报文信息
$this->logMessage .= "response: {$this->responseBody}" . PHP_EOL;
$curlInfo = curl_getinfo($curlHandle);
$this->curlGetInfo = $curlInfo;
if (empty($curlInfo['primary_port'])) {
$curlInfo['primary_port'] = '';
}
$curlInfoStr = '';
if (isset($_SERVER['SERVER_ADDR']) && $_SERVER['SERVER_PORT']) {
$curlInfoStr = " toIP {$curlInfo['primary_ip']}:{$curlInfo['primary_port']}";
$curlInfoStr .= " selfIP {$_SERVER['SERVER_ADDR']} {$_SERVER['SERVER_PORT']}";
}
//记录通信信息及性能指标
$this->logMessage .= "Info: " . json_encode($curlInfoStr) . PHP_EOL;
$this->logMessage .= "sendTime: " . date('H:i:s', $sendTime) . " , responseTime: ";
$this->logMessage .= date('H:i:s', $responseTime) . " , timeIncrement:" . $timeIncrement . 's'
. PHP_EOL;
$curlError = curl_error($curlHandle);
if ($curlError) {
$this->logMessage .= "Error: " . $curlError . PHP_EOL;
}
}

/*******************=====头部设置=====********************/
/**
* Function Description:头部设置
* Function Name: setCurlOpts
* @param $curlHandle
*
*
* @author 倪宗锋
*/
protected function setCurlOpts(&$curlHandle)
{
if ($this->cert == 1) {
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($curlHandle, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($curlHandle, CURLOPT_SSLCERT, $this->certPem);
curl_setopt($curlHandle, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curlHandle, CURLOPT_SSLKEY, $this->keyPem);
}

}
/*****************==========调用接口并返回结果===结束======******************/
//获取数组是几维数组
private function getmaxdim($vDim)
{
if (!is_array($vDim)) return 0;
else {
$max1 = 0;
foreach ($vDim as $item1) {
$t1 = $this->getmaxdim($item1);
if ($t1 > $max1) $max1 = $t1;
}
return $max1 + 1;
}
}

}

?>

+ 98
- 0
addons/nzf/PayService.php View File

@@ -0,0 +1,98 @@
<?php
/**
*
* ============================================================================
* * 版权所有 蜘蛛出行 * *
* 网站地址: http://www.zhizhuchuxing.com
* ----------------------------------------------------------------------------
* 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和
* 使用;不允许对程序代码以任何形式任何目的的再发布。
* ============================================================================
* Author By: 倪宗锋
* PhpStorm PayService.php
* Create By 2017/3/3 19:53 $
*/

namespace addons\nzf;

class PayService
{
/**
* Des:扫码支付
* Name: sao
* @param $params array order_id:订单ID name:订单名称 total_fee:总金额-元
* @param int $type 3、微信4、支付宝
* @return array
* @author 倪宗锋
*/
public static function sao($params, $type = 1)
{
if ($type == 3) {
$pay = new WeChatPay();//微信支付类
} else {
$pay = new AliPay();//支付宝支付类
}
$return = $pay->unifiedOrderByOrderIdForSao($params);
return $return;
}

/**
* Des:取消订单
* Name: cancel
* @param $params array order_id:订单ID name:订单名称 total_fee:总金额-元 refund_fee退款金额
* @param int $type 3、微信 4、支付宝
* @return array
* @author 倪宗锋
*/
public static function cancel($params, $type)
{
if ($type == 3) {//微信支付
$pay = new WeChatPay();
$return = $pay->cancelOrder($params);
} else {//阿里支付
$pay = new AliPay();
$return = $pay->cancelOrder($params);
}
return $return;
}

/**
* Des: 直接付款
* Name: pay
* @param $params array
* $order_id string 订单表 订单ID
* $name string 产品名称
* $total_fee int 总金额 单位元
* $openid string 用户opendid
* @param $type 1微信 2支付宝
*
* @return array
* @author 倪宗锋
*/
public static function pay($params,$type = 1)
{
if($type == 1) {
$pay = new WeChatPay();//微信支付类
}else {
$pay = new AliPay();//支付宝支付类
}
$return = $pay->webPay($params);
return $return['data']['payData'];
}


/**
* Des: 支付 目前只支持微信直接支付
* Name: pay
* @param $orderId string 订单ID
*
* @return array
* @author 倪宗锋
*/
public static function checkIsPay($orderId)
{
$pay = new WeChatPay();
$return = $pay->checkIsPay($orderId);
return $return;
}
}

+ 343
- 0
addons/nzf/Util.php View File

@@ -0,0 +1,343 @@
<?php
/**
* 全局通用方法集合
* ============================================================================
* * 版权所有 蜘蛛出行 * *
* 网站地址: http://www.zhizhuchuxing.com
* ----------------------------------------------------------------------------
* 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和
* 使用;不允许对程序代码以任何形式任何目的的再发布。
* ============================================================================
* Author By: 倪宗锋
* PhpStorm Util.php
* Create By 2017/2/22 19:44 $
*/

namespace addons\nzf;

class Util
{

/**
* Function Description:返回成功Json数据到
* Function Name: returnSu
* @param string $msg 提示信息
* @param string $url 跳转地址
* @param string|array $data 需要传递的数据
* @param string $code 错误码
*
* @return string
*
* @author 倪宗锋
*/
public static function returnJsSu($msg = '', $data = '', $url = '', $code = '')
{
$return = array();
$return['flag'] = true;
$return['msg'] = $msg;
$return['url'] = $url;
$return['code'] = $code;
$return['data'] = $data;
return json_encode($return);
}

/**
* Function Description:返回成功Json数据
* Function Name: returnEr
* @param string $msg 提示信息
* @param string $url 跳转地址
* @param string|array $data 需要传递的数据
* @param string $code 错误码
*
* @return string
*
* @author 倪宗锋
*/
public static function returnJsEr($msg = '', $data = '', $url = '', $code = '')
{
$return = array();
$return['flag'] = false;
$return['msg'] = $msg;
$return['url'] = $url;
$return['code'] = $code;
$return['data'] = $data;
return json_encode($return);
}

/**
* Function Description:返回成功数组数据
* Function Name: returnArrSu
* @param string $msg 提示信息
* @param string $url 跳转地址
* @param string|array $data 需要传递的数据
* @param string $code 错误码
*
* @return array
*
* @author 倪宗锋
*/
public static function returnArrSu($msg = '', $data = '', $url = '', $code = '')
{
$return = array();
$return['flag'] = true;
$return['msg'] = $msg;
$return['url'] = $url;
$return['code'] = $code;
$return['data'] = $data;
return $return;
}

/**
* Function Description:返回错误数组数据
* Function Name: returnArrEr
* @param string $msg 提示信息
* @param string $url 跳转地址
* @param string|array $data 需要传递的数据
* @param string $code 错误码
*
* @return array
*
* @author 倪宗锋
*/
public static function returnArrEr($msg = '', $data = '', $url = '', $code = '')
{
$return = array();
$return['flag'] = false;
$return['msg'] = $msg;
$return['url'] = $url;
$return['code'] = $code;
$return['data'] = $data;
return $return;
}



/**
* Function Description:json转换为xml
* Function Name: jsonToXml
* @param $json
*
* @return bool|string
*
* @author 倪宗锋
*/
public static function jsonToXml($json)
{
if (empty($json)) {
return false;
}
$array = json_decode($json);
$xml = '';
$xml .= '<?xml version="1.0" encoding="UTF-8"?>' . self::arraysToXml(['response' => $array]);
return $xml;
}


/**
* Function Description:数组转换成xml
* Function Name: arrayToXml
* @param $array
* @param $key
* @return string
*
* @author 倪宗锋
*/
public static function arraysToXml($array, $key = '')
{
$string = '';
if (count($array) == 0) {
return '';
}
foreach ($array as $k => $v) {
if (is_array($v) && isset($v['0'])) {
$string .= self::arraysToXml($v, $k);//是数组或者对像就的递归调用
} else {
if ($key != '') {
$k = $key;
}
$string .= '<' . $k . '>';
if (is_array($v) || is_object($v)) {//判断是否是数组,或者,对像
$string .= self::arraysToXml($v);//是数组或者对像就的递归调用
} elseif (is_numeric($v)) {
$string .= $v;
} elseif ($v != '') {
$string .= '<![CDATA[' . $v . ']]>';
} else {
$string .= '';
}
$string .= '</' . $k . '>';
}
}
return $string;
}

/**
* Function Description:xml转换为json
* Function Name: xml_to_json
* @param $source
*
* @return string
*
* @author 倪宗锋
*/
public static function xmlToJson($source)
{
if (is_file($source)) { //传的是文件,还是xml的string的判断
$xml_array = simplexml_load_file($source);
} else {
$xml_array = simplexml_load_string(trim($source));
}
$json = json_encode($xml_array, true);
return $json;
}

/**
* Function Description:xml转换成数组
* Function Name: xmlToArray
* @param $source
*
* @return mixed
*
* @author 倪宗锋
*/
public static function xmlToArray($source)
{
libxml_disable_entity_loader(true);
$getResult = json_decode(json_encode(simplexml_load_string(trim($source), 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $getResult;
}

/** Function Description:加密解密函数
* Function Name: authCode
* @param $string
* @param string $operation
* @param int $expiry
* @return string|array
* @author 倪宗锋
*/
static function authCode($string, $operation = 'DECODE', $expiry = 0)
{
$key = 'udM5A8S50eg8veH15dd0m601de7073N8Bcn7d1I8Res7C7o7z274D6y342I4C7t7';
$ckey_length = 4; // 随机密钥长度 取值 0-32;
// 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
// 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
// 当此值为 0 时,则不产生随机密钥

$key = md5($key);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';

$cryptkey = $keya . md5($keya . $keyc);
$key_length = strlen($cryptkey);

$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
$string_length = strlen($string);

$result = '';
$box = range(0, 255);

$rndkey = array();
for ($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}

for ($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for ($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if ($operation == 'DECODE') {
if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc . str_replace('=', '', base64_encode($result));
}

}



/**
* 获取客户端IP地址
* @return mixed
*/
public static function getclientip()
{
static $realip = NULL;

if ($realip !== NULL) {
return $realip;
}
if (isset($_SERVER)) {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { //但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的 IP 地址,而不是真正的客户端 IP 地址。要想透过代理服务器取得客户端的真实 IP 地址,就要使用 $_SERVER["HTTP_X_FORWARDED_FOR"] 来读取。
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
/* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */
foreach ($arr AS $ip) {
$ip = trim($ip);
if ($ip != 'unknown') {
$realip = $ip;
break;
}
}
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是"超级匿名代理",则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。
$realip = $_SERVER['HTTP_CLIENT_IP'];
} else {
if (isset($_SERVER['REMOTE_ADDR'])) { //正在浏览当前页面用户的 IP 地址
$realip = $_SERVER['REMOTE_ADDR'];
} else {
$realip = '0.0.0.0';
}
}
} else {
//getenv环境变量的值
if (getenv('HTTP_X_FORWARDED_FOR')) {//但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的 IP 地址,而不是真正的客户端 IP 地址。要想透过代理服务器取得客户端的真实 IP 地址
$realip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_CLIENT_IP')) { //获取客户端IP
$realip = getenv('HTTP_CLIENT_IP');
} else {
$realip = getenv('REMOTE_ADDR'); //正在浏览当前页面用户的 IP 地址
}
}
preg_match("/[\d\.]{7,15}/", $realip, $onlineip);
$realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
return $realip;
}

/**
* Des:获取浏览器机器类型
* Name: get_device_type
* @return string
* @author 倪宗锋
*/
public static function get_device_type()
{
//全部变成小写字母
$agent = strtolower($_SERVER['HTTP_USER_AGENT']);
$type = 'other';
//分别进行判断
if (strpos($agent, 'iphone') || strpos($agent, 'ipad')) {
$type = 'ios';
}

if (strpos($agent, 'android')) {
$type = 'android';
}
return $type;
}

}

+ 337
- 0
addons/nzf/WeChatPay.php View File

@@ -0,0 +1,337 @@
<?php

namespace addons\nzf;

use addons\unishop\model\Config;

/**
* Class WxPayService
* 微信交易接口调用核心
* @package Base\Tool
*/
class WeChatPay
{
public $unifiedOrderUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//统一下单API
/************************手机浏览器内web支付**************************************/
/**
*
*/
public function H5Pay($params)
{
if (empty($params['notify_url'])) {
$params['notify_url'] = Config::getByName('notify_url')['value'];
}
$data = array(
'name' => $params['name'],//名称
'order_id' => (string)$params['order_id'] . '_' . rand(1000, 9999),//支付ID
'total_fee' => (string)$params['total_fee'] * 100,//总金
'notify_url' => $params['notify_url'],//支付回调接口
'trade_type' => 'MWEB',//用户的OPENID
'scene_info' => [
'h5_info' => [
'type' => 'Wap',
'wap_url' => Config::getByName('name')['value'],
'wap_name' => Config::getByName('name')['value']
]
]
);
$getpay = $this->unifiedOrderForWeChat($data);//统一下单API
if ($getpay['flag'] == false) {
return $getpay;
}
if (empty($getpay['data']['mweb_url'])) {
return Util::returnArrEr('预支付会话异常!');
}
return Util::returnArrSu('', ['pay_url' => $getpay['data']['mweb_url']]);
}
/************************微信浏览器内web支付**************************************/
/**
* Function Description:去微信下单并获取返回
* Function Name: unifiedOrderByOrderId
* @param $params array
* $order_id string 订单表 订单ID
* $name string 产品名称
* $total_fee int 总金额 单位分
* $openid string 用户opendid
* @return array
*
* @author nzf
*/
public function webPay($params)
{
if (empty($params['notify_url'])) {
$params['notify_url'] = Config::getByName('notify_url')['value'];;
}
$data = array(
'name' => $params['name'],//名称
'order_id' => (string)$params['order_id'] . '_' . rand(1000, 9999),//支付ID
'total_fee' => (string)$params['total_fee'] * 100,//总金
'notify_url' => $params['notify_url'],//支付回调接口
'openid' => $params['openid']//用户的OPENID
);
$getPrepayId = $this->unifiedOrderForWeChat($data);//统一下单API
if ($getPrepayId['flag'] == false) {
return $getPrepayId;
}
//设置成功返回的结果数
$return = array(
'appId' => Config::getByName('app_id')['value'],//微信�?放平台审核�?�过的应用APPID
'package' => 'prepay_id=' . $getPrepayId['data']['prepay_id'],//微信返回的支付交易会话ID
'nonceStr' => self::getNonceStr(),//随机字符�?
'signType' => 'MD5',
'timeStamp' => strval(time()),//当前时间�?
);
$return['paySign'] = self::getSign($return);
return Util::returnArrSu('', array('payData' => $return, 'price' => $params['total_fee']));
}

/**
* Function Description:统一下单API
* Function Name: unifiedOrder
* @param $params array
* attach 附加数据,在查询API和支付知中原样返回,该字段主要用于商户携带订单的自定义数
* line_name 线路名称
* order_id 订单ID
* total_fee 总金
* notify_url 回调地址
*
* @return array
*
* @author nzf
*/
public function unifiedOrderForWeChat($params)
{
$data = array(
'appid' => Config::getByName('app_id')['value'],//微信开放平台审核过的应用APPID
'attach' => empty($params['attach']) ? '' : $params['attach'],
'body' => $params['name'],//产品名称
'mch_id' => Config::getByName('mch_id')['value'],//商户微信支付分配的商户号
'nonce_str' => $this->getNonceStr(),//随机字符
'notify_url' => $params['notify_url'],//通知地址
'out_trade_no' => $params['order_id'],//商户订单ID加上当前时间
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],//用户端实际ip
'total_fee' => $params['total_fee'],//订单总金额,单位为分
'trade_type' => empty($params['trade_type']) ? 'JSAPI' : $params['trade_type'],//交易类型
);
if (empty($params['openid']) == false) {//存在openid
$data['openid'] = $params['openid'];
}
if (isset($params['scene_info'])) {
$data['scene_info'] = json_encode($params['scene_info']);
}
$data['sign'] = $this->getSign($data);//交易签名
$curl = new CurlInterface($data, 2);//函数
$curl->setBaseUrl($this->unifiedOrderUrl);
$result = $curl->execute('', 'POST');
if (empty($result['prepay_id'])) {
return Util::returnArrEr('预支付交易会话异常!');
}
return Util::returnArrSu('', array('prepay_id' => $result['prepay_id'], 'mweb_url' => empty($result['mweb_url']) ? '' : $result['mweb_url']));
}
/************************扫描支付**************************************/

/**
* Function Description:去微信下单并获取返回
* Function Name: unifiedOrderByOrderId
* @param $par
* @return array
*
* @author nzf
*/
public function unifiedOrderByOrderIdForSao($par)
{
$notify_url = Config::getByName('notify_url')['value'];
$data = array(
'name' => $par['name'],//线路名称
'order_id' => (string)$par['order_id'] . '_' . rand(100, 999),//订单ID
'total_fee' => $par['total_fee'] * 100,//总金
'notify_url' => $notify_url
);
$codUrl = $this->unifiedOrderForSao($data);//统一下单API
if ($codUrl['flag'] == false) {
return $codUrl;
}
//设置成功返回的结果数�?
$url = '/fx/?r=weChat/we-chat/q-code&qCode=' . urlencode($codUrl['data']['code_url']) . '&_math=' . rand(100, 999);
return Util::returnArrSu('', array('codUrl' => $url, 'price' => $par['total_fee']));
}

/**
* Function Description:统一下单API
* Function Name: unifiedOrder
* @param $params array
* attach 附加数据,在查询API和支付知中原样返回,该字段主要用于商户携带订单的自定义数
* line_name 线路名称
* order_id 订单ID
* total_fee 总金
* notify_url 回调地址
*
* @return array
*
* @author 倪宗�?
*/
public function unifiedOrderForSao($params)
{
$data = array(
'appid' => Config::getByName('app_id')['value'],//微信�?放平台审核�?�过的应用APPID
'mch_id' => Config::getByName('mch_id')['value'],//商户�? 微信支付分配的商户号
'nonce_str' => $this->getNonceStr(),//随机字符�?
'body' => $params['name'],//线路名称 �? 上订单ID
'out_trade_no' => $params['order_id'],//商户订单ID加上当前时间
'total_fee' => $params['total_fee'],//订单总金额,单位为分
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],//用户端实际ip
'notify_url' => $params['notify_url'],//通知地址
'trade_type' => 'NATIVE',//交易类型
);
$data['sign'] = $this->getSign($data);//交易签名
$curl = new CurlInterface($data, 2);//函数�?
$curl->setBaseUrl($this->unifiedOrderUrl);
$result = $curl->execute('', 'POST');
if (empty($result['prepay_id'])) {
return Util::returnArrEr('预支付交易会话异常!');
}
return Util::returnArrSu('', array('prepay_id' => $result['prepay_id'], 'code_url' => $result['code_url']));
}

/***************************************退款****************************************/

/**
* Des:微信退款接口
* Name: cancelOrder
* @param $params
* @return array
* @author 倪宗锋
*/
public static function cancelOrder($params)
{
$arr = array(
'appid' => Config::getByName('app_id')['value'],
'mch_id' => Config::getByName('mch_id')['value'],
'nonce_str' => static::getNonceStr(),
'out_trade_no' => (string)$params['order_id'],//订单ID
'out_refund_no' => (string)date('YmdHis') . rand(100, 999),//退款ID
'total_fee' => (string)$params['total_fee'] * 100,//订单总金额 元
'refund_fee' => (string)$params['refund_fee'] * 100,//退款金额 元
'op_user_id' => Config::getByName('mch_id')['value']
);
$arr['sign'] = static::getSign($arr);
$curl = new CurlInterface($arr, 2);//函数类
$certArr = [
"SSLCERT_PATH"=>ROOT_PATH.Config::getByName('cert_path')['value'],
"SSLKEY_PATH"=>ROOT_PATH.Config::getByName('key_path')['value']
];
$curl->setCert($certArr);
$curl->setBaseUrl('https://api.mch.weixin.qq.com/secapi/pay/refund');
$result = $curl->execute('', 'POST');
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
return Util::returnArrSu();
}
$msg = $result['return_msg'];
if ($msg == 'OK') {
$msg = $result['err_code_des'];
}
return Util::returnArrEr('退款失败!' . $msg);

}

/*************************************通用方法**************************************/
/**
* Des:检测是否已经支付
* Name: checkIsPay
* @param $orderId
* @return array
* @author 倪宗锋
*/
public static function checkIsPay($orderId)
{
$arr = array(
'appid' => Config::getByName('app_id')['value'],
'mch_id' => Config::getByName('mch_id')['value'],
'out_trade_no' => (string)$orderId,//订单ID
'nonce_str' => static::getNonceStr(),
);
$arr['sign'] = static::getSign($arr);
$curl = new CurlInterface($arr, 2);//函数类
$certArr = [
"SSLCERT_PATH"=>ROOT_PATH.Config::getByName('cert_path')['value'],
"SSLKEY_PATH"=>ROOT_PATH.Config::getByName('key_path')['value']
];
$curl->setCert($certArr);
$curl->setBaseUrl('https://api.mch.weixin.qq.com/pay/orderquery');
$result = $curl->execute('', 'POST');
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
return Util::returnArrSu('', $result);
}
$msg = $result['return_msg'];
if ($msg == 'OK') {
$msg = $result['err_code_des'];
}
return Util::returnArrEr('退款失败!' . $msg);
}

/**
* Function Description:获取签名
* Function Name: getSign
* @param $params
* @return string
*
* @author nzf
*/
public static function getSign($params)
{
if (isset($params['sign'])) {
unset($params['sign']);
}
//签名步骤按字典序排序参
ksort($params);
$string = self::ToUrlParams($params);
//签名步骤二:在string后加入KEY
$string = $string . "&key=" . Config::getByName('key')['value'];
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:有字符转为大
$result = strtoupper($string);
return $result;

}

/**
* Function Description:格式化参�? 格式化成url参数
* Function Name: ToUrlParams
* @param $params
*
* @return string
*
* @author 倪宗�?
*/
public static function ToUrlParams($params)
{
$buff = "";
foreach ($params as $k => $v) {
if ($k != "sign" && $v != "" && !is_array($v)) {
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}

/**
* Function Description:产生的随机字符串 不长
* Function Name: getNonceStr
* @param int $length
*
* @return string
*
* @author 倪宗�?
*/
public static function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
}

+ 23
- 1
addons/unishop/behavior/Order.php View File

@@ -2,6 +2,7 @@

namespace addons\unishop\behavior;

use addons\epay\library\Service;
use addons\unishop\extend\Ali;
use addons\unishop\extend\Hashids;
use addons\unishop\extend\Wechat;
@@ -256,7 +257,7 @@ $address=[];
* 行为一:退款
* @param array $params 订单数据
*/
public function orderRefund(&$params)
public function orderRefundOld(&$params)
{
$order = &$params;

@@ -281,4 +282,25 @@ $address=[];

// More ...
}

/**
* 订单退款
* 行为一:退款
* @param array $params 订单数据
*/
public function orderRefund(&$params)
{
$order = &$params;
// 行为一
switch ($order['pay_type']) {
case \addons\unishop\model\Order::PAY_WXPAY:
Service::refund($params["out_trade_no"],"wechat",$params["total_price"]);
break;
case \addons\unishop\model\Order::PAY_ALIPAY:
Service::refund($params['out_trade_no'],"alipay",$params['total_price']);
break;
}

// More ...
}
}

+ 11
- 2
addons/unishop/controller/Order.php View File

@@ -9,6 +9,8 @@

namespace addons\unishop\controller;

use addons\nzf\AliPay;
use addons\nzf\PayService;
use addons\unishop\extend\Hashids;
use addons\unishop\model\Area;
use addons\unishop\model\Config;
@@ -600,9 +602,15 @@ class Order extends Base
$order->status = \addons\unishop\model\Order::STATUS_REFUND;
$order->refund_status = \addons\unishop\model\Order::REFUND_STATUS_AGREE;
$result = $order->save();
Hook::add('order_refund', 'addons\\unishop\\behavior\\Order');
if ($result !== false){
Hook::listen('order_refund', $row);
//order_id:订单ID name:订单名称 total_fee:总金额-元 refund_fee退款金额
$param = [
"order_id"=>$order['out_trade_no'],
"total_fee"=>$order['total_price'],
"refund_fee"=>$order['total_price'],
"name"=>$order['订单退款'],
];
PayService::cancel($param,$order["pay_type"]);
$this->success("success",[]);
}
$this->error("订单信息错误");
@@ -651,4 +659,5 @@ class Order extends Base

}


}

+ 12
- 0
addons/unishop/controller/Pay.php View File

@@ -10,6 +10,7 @@
namespace addons\unishop\controller;

use addons\epay\library\Service;
use addons\nzf\AliPay;
use addons\unishop\extend\Ali;
use addons\unishop\extend\Hashids;
use addons\unishop\extend\Wechat;
@@ -240,4 +241,15 @@ class Pay extends Base
}


// public function notify(){
// $order = [
// "order_id"=>"202009275f7076e5c6f2f23",
// "total_fee"=>11,
// "memo"=>'取消订单',
// "refund_fee"=>11,
//
// ];//order_id:订单ID name:订单名称 total_fee:总金额-元 refund_fee退款金额
// AliPay::cancelOrder($order);
//
// }
}

+ 3
- 1
composer.json View File

@@ -24,7 +24,9 @@
"phpmailer/phpmailer": "~6.0.6",
"karsonzhang/fastadmin-addons": "~1.1.9",
"overtrue/pinyin": "~3.0",
"phpoffice/phpspreadsheet": "^1.2"
"phpoffice/phpspreadsheet": "^1.2",
"ext-json": "*",
"ext-curl": "*"
},
"config": {
"preferred-install": "dist"


Loading…
Cancel
Save