c5_labsci/web/api/v1.php

146 lines
5.2 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
//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;
}
}