146 lines
5.2 KiB
PHP
146 lines
5.2 KiB
PHP
<?php
|
||
//https://ciyon.local.ciy.cn/ajax/api/v1.transfer
|
||
//https://ciyon.local.ciy.cn/ajax/api/v1.query
|
||
namespace web\api;
|
||
|
||
class v1 {
|
||
public static function json_transfer() {
|
||
global $db;
|
||
$post = new \ciy\post();
|
||
$api = self::verifyapi($db, $post);
|
||
if (is_string($api))
|
||
return errjson($api);
|
||
$thirdno = $post->get('thirdno');
|
||
$notifyurl = $post->get('notifyurl');
|
||
$amount = $post->getint('amount');
|
||
$csql = new \ciy\sql('ap_transfer');
|
||
$csql->where('thirdno', $thirdno);
|
||
$chkrow = $db->getone($csql);
|
||
if (is_array($chkrow))
|
||
return errjson('单号已存在');
|
||
//检查thirdno是否存在,等幂下单
|
||
$updata = array();
|
||
$updata['amount'] = $amount;
|
||
$updata['thirdno'] = $thirdno;
|
||
$updata['notifyurl'] = $notifyurl;
|
||
$updata['retimes'] = 0;
|
||
$updata['uptimes'] = 0;
|
||
$updata['nexttimes'] = MAXTIMES;
|
||
$updata['addtimes'] = time();
|
||
$updata['signature'] = '';
|
||
$updata['orderstatus'] = 10;
|
||
$updata['apiid'] = $api['id'];
|
||
if (isset($api['sign'])) {
|
||
//验证签名
|
||
$addtimes = $post->getint('timestamp');
|
||
if (abs(time() - $addtimes) > 300) {
|
||
return errjson('签名已过期,请检查timestamp时间戳是否与北京时间一致');
|
||
}
|
||
$updata['addtimes'] = $addtimes;
|
||
$waitsignstr = 'amount=' . $updata['amount'] . ',addtimes=' . $addtimes;
|
||
$retsign = self::verifysign($api['pubkey'], $waitsignstr, $api['sign']);
|
||
if (is_string($retsign))
|
||
return errjson($retsign);
|
||
$updata['signature'] = $api['sign'];
|
||
$updata['orderstatus'] = 20;
|
||
}
|
||
|
||
try {
|
||
$db->begin();
|
||
$csql = new \ciy\sql('ap_transfer');
|
||
if ($db->insert($csql, $updata) === false)
|
||
throw new \Exception('新增失败:' . $db->error);
|
||
$id = $db->insert_id();
|
||
$db->commit();
|
||
} catch (\Exception $ex) {
|
||
$db->rollback();
|
||
savelogfile('err_db', $ex->getMessage());
|
||
return errjson($ex->getMessage());
|
||
}
|
||
$ret['newid'] = $id;
|
||
return succjson($ret);
|
||
}
|
||
public static function json_query() {
|
||
global $db;
|
||
$post = new \ciy\post();
|
||
$api = self::verifyapi($db, $post);
|
||
if (is_string($api))
|
||
return errjson($api);
|
||
$thirdno = $post->get('thirdno');
|
||
$csql = new \ciy\sql('ap_transfer');
|
||
$csql->where('thirdno', $thirdno);
|
||
$row = $db->getone($csql);
|
||
if (!is_array($row))
|
||
return errjson('单号不存在');
|
||
$ret = array();
|
||
$ret['data'] = $row;
|
||
return succjson($ret);
|
||
}
|
||
static function verifyapi($db, &$post) {
|
||
global $db;
|
||
$hash = $post->get('hash');
|
||
if (empty($hash))
|
||
return 'hash不存在';
|
||
unset($post->post['hash']);
|
||
$sign = $post->get('sign');
|
||
if (!empty($sign))
|
||
unset($post->post['sign']);
|
||
$appid = $post->getint('appid');
|
||
if ($appid <= 0)
|
||
return 'appid不合法';
|
||
$timestamp = $post->getdate('timestamp');
|
||
if (abs(time() - $timestamp) > 600) {
|
||
return 'timestamp与服务器相差超过10分钟,服务器时间:' . date('Y-m-d H:i:s');
|
||
}
|
||
|
||
$csql = new \ciy\sql('ap_api');
|
||
$csql->where('id', $appid);
|
||
$apirow = $db->getone($csql);
|
||
if (!is_array($apirow)) {
|
||
return 'appid不存在';
|
||
}
|
||
if (empty($apirow['apisecret']))
|
||
return '经检测,您的api接入不符合要求,已经暂停接入,请调整代码后重置ApiKey';
|
||
|
||
$hashstr = '';
|
||
ksort($post->post);
|
||
foreach ($post->post as $key => $value) {
|
||
$hashstr .= $key . '=' . $value . '&';
|
||
}
|
||
$hashstr = substr($hashstr, 0, -1) . $apirow['apisecret'];
|
||
if ($hash != sha256($hashstr)) {
|
||
return 'hash验证错误';
|
||
}
|
||
$ip = getip();
|
||
if (!empty($apirow['ips'])) {
|
||
$ips = explode("\n", $apirow['ips']);
|
||
if (!in_array($ip, $ips)) {
|
||
return 'ip不在白名单内';
|
||
}
|
||
}
|
||
if (!empty($sign)) {
|
||
if (empty($apirow['pubkey']))
|
||
return '未安装数字证书';
|
||
$apirow['sign'] = $sign;
|
||
}
|
||
return $apirow;
|
||
}
|
||
static function verifysign($pubkey, $data, $sign) {
|
||
$signbin = hex2bin($sign);
|
||
if ($signbin === false) {
|
||
return '签名格式错误';
|
||
}
|
||
$hashbin = hex2bin(hash('sha256', $data));
|
||
if (strpos($pubkey, '-----BEGIN RSA PUBLIC KEY-----') === false && strpos($pubkey, '-----BEGIN PUBLIC KEY-----') === false)
|
||
$pubkey = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($pubkey, 64, "\n") . "\n-----END PUBLIC KEY-----";
|
||
|
||
$result = openssl_verify($hashbin, $signbin, $pubkey, OPENSSL_ALGO_SHA256);
|
||
if ($result === 0) {
|
||
return '数字证书验签失败';
|
||
} else if ($result !== 1) {
|
||
return '数字证书验签错误:' . openssl_error_string();
|
||
}
|
||
return true;
|
||
}
|
||
}
|