291 lines
7.3 KiB
PHP
291 lines
7.3 KiB
PHP
<?php
|
||
|
||
|
||
namespace app\private_api\controller\robotApi;
|
||
|
||
use app\gateway\service\RedisService;
|
||
use app\merchant\service\MerchantService;
|
||
use dever\Log;
|
||
use think\admin\Controller;
|
||
|
||
/**
|
||
* 接口核心控制器
|
||
* Class Core
|
||
* @package app\gateway\service
|
||
*/
|
||
class Core extends Controller
|
||
{
|
||
|
||
#redis
|
||
protected $redis = false;
|
||
# 是否检测数据
|
||
protected bool $check = true;
|
||
# 商户appid
|
||
protected string $appid = '';
|
||
# 商户id
|
||
protected $mid = 0;
|
||
# 商户信息
|
||
protected array $merchant = array();
|
||
# token key
|
||
protected string $key = '';
|
||
# product key
|
||
protected string $product = 'query';
|
||
# proid
|
||
protected $proid = 0;
|
||
# input
|
||
protected array $input = array();
|
||
# use_product
|
||
protected array $use_product = array();
|
||
# sign_type
|
||
protected $sign_type = 1;
|
||
protected string $request_ip = '';
|
||
# code码定义
|
||
protected array $code = array
|
||
(
|
||
# 成功
|
||
1 => 'ok',
|
||
# 小于0为失败
|
||
-1 => 'mid为空',
|
||
-2 => '产品错误',
|
||
-3 => 'appid无效',
|
||
-4 => '余额不足或者没有传入价格',
|
||
|
||
-5 => 'sign不能为空',
|
||
-6 => 'nonce不能为空',
|
||
-7 => 'time不能为空',
|
||
-8 => 'sign已失效',
|
||
-9 => 'sign验证失败',
|
||
-10 => '参数错误',
|
||
|
||
-100 => '请求错误',
|
||
-101 => '订单不存在',
|
||
-102 => '订单号重复',
|
||
-103 => '请求错误,请求格式不正确,请使用json请求',
|
||
-104 => '回调渠道订单号不匹配,请核对',
|
||
|
||
-201 => '安全进价低于实际进价',
|
||
|
||
-801 => 'ip: 请求错误,不在白名单',
|
||
-802 => '方法不存在',
|
||
-803 => '版本号不正确',
|
||
|
||
-1000 => '系统维护中',
|
||
|
||
|
||
);
|
||
|
||
#找不到方法错误响应
|
||
public function __call($name, $arguments)
|
||
{
|
||
|
||
$this->error('请求' . $name . '错误', '{-null-}', -802);
|
||
}
|
||
|
||
|
||
|
||
protected function redis()
|
||
{
|
||
if (!$this->redis) {
|
||
$this->redis = RedisService::getInstance();
|
||
}
|
||
}
|
||
|
||
public function initialize(): void
|
||
{
|
||
|
||
parent::initialize();
|
||
$this->sign_type = sysconf('sign_type');
|
||
if ($this->check) {
|
||
$this->check();
|
||
}
|
||
}
|
||
|
||
# 获取输入的信息
|
||
public function input(): void
|
||
{
|
||
$this->input = input();
|
||
if (!$this->input) {
|
||
$this->no(-100);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 检测输入信息是否合法
|
||
*/
|
||
protected function check()
|
||
{
|
||
if (!str_contains($this->request->header('content_type'), "application/json")) $this->no(-103);
|
||
|
||
|
||
// $this->input();
|
||
$input = input();
|
||
if (!$input) {
|
||
$this->no(-100);
|
||
}
|
||
|
||
$ip_white_data = sysconf('MerchantSystem_ip_white');
|
||
$request_ip = $this->getRealIp();
|
||
// if()
|
||
$ip_white_array = $ip_white_data ? explode(',', $ip_white_data) : [];
|
||
|
||
|
||
if (!$ip_white_array || !in_array($request_ip, $ip_white_array)) {
|
||
$this->no(-801, 'ip:' . $request_ip . ',请求错误,不在白名单内。');
|
||
}
|
||
|
||
$old_sign = $input['sign'];
|
||
unset($input['sign']);
|
||
#版本签名
|
||
|
||
$signature = $this->sign($input, $this->merchant['token'], $request_ip);
|
||
|
||
if($signature != $old_sign){
|
||
$this->no(-9, 'sign验证失败');
|
||
}
|
||
}
|
||
|
||
public function sign($dta,$token,$ip)
|
||
{
|
||
ksort($dta);
|
||
$signature_string = '';
|
||
foreach ($dta as $k => $v) {
|
||
$signature_string .= $k . '=' . $v . '&';
|
||
}
|
||
|
||
$tokens = md5($token.'||'.$ip);
|
||
|
||
$signature_string .= 'key='.$tokens;
|
||
#此处采用ip+token进行签名
|
||
return md5($signature_string);
|
||
|
||
}
|
||
|
||
public function getRealIp(): string
|
||
{
|
||
$forwardedFor = $this->request->header('x-forwarded-for');
|
||
|
||
if ($forwardedFor) {
|
||
// 可能有多个IP,第一个通常是真实的
|
||
$ips = explode(',', $forwardedFor);
|
||
return trim($ips[0]);
|
||
}
|
||
|
||
return $this->request->ip(); // 如果没有X-Forwarded-For头,则返回当前请求的IP
|
||
}
|
||
|
||
# 检测开放或者维护时间
|
||
protected function checkOpenTime($opentime): void
|
||
{
|
||
if ($opentime && strstr($opentime, ':')) {
|
||
$opentime = str_replace(':', '', $opentime);
|
||
if (str_contains($opentime, '-')) {
|
||
$value = explode('-', $opentime);
|
||
$cur = intval(date('Hi'));
|
||
$value[0] = intval($value[0]);
|
||
$value[1] = intval($value[1]);
|
||
if ($value[1] < $value[0]) {
|
||
if ($cur >= $value[0] || $cur < $value[1]) {
|
||
$this->no(-1000);
|
||
}
|
||
} else {
|
||
if ($cur >= $value[0] && $cur < $value[1]) {
|
||
$this->no(-1000);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
# 获取商户信息
|
||
protected function getMerchant(): void
|
||
{
|
||
$this->merchant = MerchantService::instance()->get($this->mid);
|
||
if (!$this->merchant) {
|
||
$this->no(-3);
|
||
}
|
||
|
||
if ($this->product != 'query') {
|
||
if (empty($this->input['cash'])) {
|
||
$this->no(-4);
|
||
}
|
||
if ($this->product == 'dxdc') {
|
||
$cash = 0.23;//这里后续处理
|
||
if ($this->merchant['credit_surplus'] < $cash && $this->merchant['account_surplus'] < $cash) {
|
||
$this->no(-4);
|
||
}
|
||
} else {
|
||
if ($this->merchant['credit_surplus'] < $this->input['cash'] && $this->merchant['account_surplus'] < $this->input['cash']) {
|
||
$this->no(-4);
|
||
}
|
||
}
|
||
}
|
||
|
||
$this->mid = $this->merchant['id'];
|
||
if ($this->sign_type == 2) {
|
||
$this->key = $this->merchant['appsecret'];
|
||
} else {
|
||
$this->key = $this->appid . '|' . $this->merchant['appsecret'];
|
||
}
|
||
|
||
}
|
||
|
||
# 查找订单
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 返回失败的消息
|
||
* @param mixed $info
|
||
* @param string $data
|
||
* @param integer $code
|
||
*/
|
||
protected function no(int $code = 0, $info = '', $data = '{-null-}')
|
||
{
|
||
$msg = $this->code[$code] ?? 'error';
|
||
if ($info) {
|
||
$msg .= ':' . $info;
|
||
}
|
||
$data = '{-null-}';
|
||
$this->error($msg, $data, $code);
|
||
}
|
||
|
||
/**
|
||
* 返回成功的消息
|
||
* @param mixed $info
|
||
* @param string $data
|
||
* @param integer $code
|
||
*/
|
||
protected function yes($data = '{-null-}', $info = 'ok', $code = 1)
|
||
{
|
||
if (is_string($data) && $data != 'ok' && $data != 'success') {
|
||
if ($data == '订单号重复') {
|
||
return $this->no(-102);
|
||
}
|
||
return $this->no(-100, $data);
|
||
}
|
||
$this->success($info, $data, $code);
|
||
}
|
||
|
||
# 记录日志
|
||
protected function log($data)
|
||
{
|
||
Log::write('private_api', 'merchantApi', $data);
|
||
}
|
||
|
||
# 队列
|
||
protected function queue($key, $value = false)
|
||
{
|
||
$redis = RedisService::getInstance();
|
||
if (!$value) {
|
||
return $redis->pop($key);
|
||
} else {
|
||
return $redis->push($key, $value);
|
||
}
|
||
}
|
||
} |