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; } }