diff --git a/app/Controller/Payment/NotifyController.php b/app/Controller/Payment/NotifyController.php index 01e3b36..c74050e 100644 --- a/app/Controller/Payment/NotifyController.php +++ b/app/Controller/Payment/NotifyController.php @@ -8,6 +8,8 @@ use App\Helper\Efps\Result; use App\Helper\Efps\Signer; use App\Helper\Log; use App\Helper\Platform\Notification; +use App\Helper\Platform\Signer as PlatformSigner; +use App\Helper\StringHelper; use App\Model\App; use App\Model\Order; use App\Model\RefundOrder; @@ -139,6 +141,9 @@ class NotifyController extends AbstractController } protected function notify($url, $app, $data) { + if (empty($url)) { + return 'empty url'; + } $params = [ 'app_id' => $app->app_id, 'nonce_str' => StringHelper::getRandomString(32), diff --git a/app/Controller/Payment/PageController.php b/app/Controller/Payment/PageController.php deleted file mode 100644 index c850776..0000000 --- a/app/Controller/Payment/PageController.php +++ /dev/null @@ -1,36 +0,0 @@ -input('order_no', ''); - Log::info('redirectToOut orderNo:' . $orderNo, [], 'omipay'); - if (! $orderNo) { - return '订单号错误'; - } - $order = Order::where('order_no', $orderNo)->first(); - if (! $order) { - return '订单号错误'; - } - Log::info('redirectToOut url:' . $order->redirect_url, [], 'omipay'); - return $response->redirect($order->redirect_url); - } -} diff --git a/app/Controller/Payment/PayController.php b/app/Controller/Payment/PayController.php index 64b0d5e..1e8e4ef 100644 --- a/app/Controller/Payment/PayController.php +++ b/app/Controller/Payment/PayController.php @@ -4,18 +4,6 @@ declare(strict_types=1); namespace App\Controller\Payment; -use App\Exception\BusinessException; -use App\Helper\Efps\Api; -use App\Model\Order; -use App\Model\RefundOrder; -use App\Request\BindCardConfirmRequest; -use App\Request\BindCardRequest; -use App\Request\PaymentQueryRequest; -use App\Request\ProtocolPayConfirmRequest; -use App\Request\ProtocolPayPreRequest; -use App\Request\RefundQueryRequest; -use App\Request\RefundRequest; -use App\Request\UnBindCardRequest; use Hyperf\HttpServer\Contract\RequestInterface; use App\Service\PaymentService; @@ -30,32 +18,20 @@ class PayController extends AbstractController public function bindCard(RequestInterface $request) { - $req = new BindCardRequest($request->all()); - $result = Api::bindCard($req->getData()); - if (!$result->isSuccess()) { - throw new BusinessException($result->getMessage()); - } - return $this->success($result->getData()); + $data = $this->paymentService->bindCard($request->all()); + return $this->success($data); } public function bindCardConfirm(RequestInterface $request) { - $req = new BindCardConfirmRequest($request->all()); - $result = Api::bindCardConfirm($req->getData()); - if (!$result->isSuccess()) { - throw new BusinessException($result->getMessage()); - } - return $this->success($result->getData()); + $data = $this->paymentService->bindCardConfirm($request->all()); + return $this->success($data); } public function unBindCard(RequestInterface $request) { - $req = new UnBindCardRequest($request->all()); - $result = Api::unBindCard($req->getData()); - if (!$result->isSuccess()) { - throw new BusinessException($result->getMessage()); - } - return $this->success($result->getData()); + $data = $this->paymentService->unBindCard($request->all()); + return $this->success($data); } public function protocolPayPreRequest(RequestInterface $request) @@ -71,82 +47,17 @@ class PayController extends AbstractController } public function refund(RequestInterface $request) { - $req = new RefundRequest($request->all()); - $app = $req->getApp(); - $data = $req->getData(); - - $refundOrder = new RefundOrder(); - $refundOrder->app_id = $app->app_id; - $refundOrder->out_order_no = $data['outTradeNo'] ?: ''; - $refundOrder->out_refund_order_no = $data['outRefundNo'] ?: ''; - $refundOrder->order_amount = $data['amount'] ?: ''; - $refundOrder->refund_amount = $data['refundAmount'] ?: ''; - $refundOrder->remark = $data['remark'] ?: ''; - $refundOrder->notify_url = $data['notifyUrl'] ?: ''; - - $result = Api::refund($data); - if (!$result->isSuccess()) { - $refundOrder->status = RefundOrder::STATUS_APPLY_FAILED; - $refundOrder->error_code = $result->getCode(); - $refundOrder->error_msg = $result->getMessage(); - $refundOrder->save(); - throw new BusinessException($result->getMessage()); - } - $refundOrder->status = RefundOrder::STATUS_APPLY_SUCCESS; - $refundOrder->save(); - - return $this->success($result->getData()); + $data = $this->paymentService->refund($request->all()); + return $this->success($data); } public function refundQuery(RequestInterface $request) { - $req = new RefundQueryRequest($request->all()); - $data = $req->getData(); - $result = Api::refundQuery($data); - if (!$result->isSuccess()) { - throw new BusinessException($result->getMessage()); - } - - $order = RefundOrder::where('out_refund_order_no', $result->get('outRefundNo')) - ->where('status', RefundOrder::STATUS_APPLY_SUCCESS) - ->first(); - if ($order) { - $this->paymentService->handleRefundResult($result, $order); - } - - return $this->success( - $result->getData([ - 'outRefundNo', - 'transactionNo', - 'amount', - 'refundAmount', - 'refundState' - ]) - ); + $data = $this->paymentService->refundQuery($request->all()); + return $this->success($data); } public function paymentQuery(RequestInterface $request) { - $req = new PaymentQueryRequest($request->all()); - $data = $req->getData(); - $result = Api::paymentQuery($data); - if (!$result->isSuccess()) { - throw new BusinessException($result->getMessage()); - } - - $order = Order::where('out_order_no', $result->get('outTradeNo')) - ->where('status', Order::STATUS_WAIT_PAY) - ->first(); - if ($order) { - $this->paymentService->handlePayResult($result, $order); - } - - return $this->success( - $result->getData([ - 'outTradeNo', - 'transactionNo', - 'payState', - 'procedureFee', - 'amount' - ]) - ); + $data = $this->paymentService->paymentQuery($request->all()); + return $this->success($data); } } diff --git a/app/Controller/Recharge/AbstractController.php b/app/Controller/Recharge/AbstractController.php new file mode 100644 index 0000000..165ab44 --- /dev/null +++ b/app/Controller/Recharge/AbstractController.php @@ -0,0 +1,38 @@ +paymentService = $paymentService; + } + + public function recharge(RequestInterface $request) { + $app = App::query()->orderBy('id', 'asc')->first(); + $name = $request->input('name'); + if (empty($name)) { + throw new BusinessException('请输入姓名'); + } + $amount = $request->input('amount'); + if (empty($amount)) { + throw new BusinessException('请输入金额'); + } + if (!is_numeric($amount)) { + throw new BusinessException('请输入金额'); + } + if ($amount <= 0) { + throw new BusinessException('金额需大于0'); + } + $cardNo = $request->input('cardNo'); + if (empty($cardNo)) { + throw new BusinessException('请输入身份证号'); + } + $mobile = $request->input('mobile'); + if (empty($mobile)) { + throw new BusinessException('请输入手机号'); + } + $bankCardNo = $request->input('bankCardNo'); + if (empty($bankCardNo)) { + throw new BusinessException('请输入银行卡号'); + } + $memberId = $this->paymentService->generateMemberId($app->app_key, $cardNo); + $user = User::where('member_id', $memberId)->first(); + $bankCard = null; + if ($user) { + $bankCard = BankCard::where('member_id', $user->member_id)->where('bank_card_no', $bankCardNo)->where('status', BankCard::STATUS_ACTIVE)->first(); + } + + if ($bankCard) { + $outTradeNo = StringHelper::generateOrderNo(); + $nextStep = 'confirm-pay'; + $bizData = $this->paymentService->protocolPayPreRequest($this->buildPrepayParams($user->member_id, $outTradeNo, $bankCard->protocol, intval($amount * 100), $app)); + } else { + $mchOrderNo = StringHelper::generateBankCardOrderNo(); + $nextStep = 'confirm-bind'; + $bizData = $this->paymentService->bindCard($this->buildBindCardParams($mchOrderNo, $memberId, $name, $cardNo, $mobile, $bankCardNo, $app)); + } + return $this->success([ + 'nextStep' => $nextStep, + 'memberId' => $memberId, + 'bizData' => $bizData + ]); + } + + public function confirmBindCard(RequestInterface $request) { + $app = App::query()->orderBy('id', 'asc')->first(); + $memberId = $request->input('memberId'); + $smsNo = $request->input('smsNo'); + $smsCode = $request->input('smsCode'); + $bizData = $this->paymentService->bindCardConfirm($this->buildComfirmBindCardParams($memberId, $smsNo, $smsCode, $app)); + return $this->success([ + 'memberId' => $memberId, + 'bizData' => $bizData + ]); + } + + public function confirmPay(RequestInterface $request) { + $app = App::query()->orderBy('id', 'asc')->first(); + $memberId = $request->input('memberId'); + $token = $request->input('token'); + $protocol = $request->input('protocol'); + $smsCode = $request->input('smsCode'); + $bizData = $this->paymentService->protocolPayConfirm($this->buildConfirmPayParams($token, $protocol, $smsCode, $app)); + return $this->success([ + 'memberId' => $memberId, + 'bizData' => ['outTradeNo' => $bizData['outTradeNo']] + ]); + } + + private function buildBindCardParams($mchOrderNo, $memberId, $name, $cardNo, $mobile, $bankCardNo, $app) + { + $params = [ + 'app_id' => $app->app_id, + 'timestamp' => time(), + 'nonce_str' => StringHelper::getRandomString(32), + 'data' => json_encode([ + 'mchtOrderNo' => $mchOrderNo, + 'memberId' => $memberId, + 'userName' => $name, + 'phoneNum' => $mobile, + 'bankCardNo' => $bankCardNo, + 'bankCardType' => 'debit', + 'certificatesNo' => $cardNo, + ]), + ]; + $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); + $params['sign'] = $sign; + return $params; + } + + private function buildPrepayParams($memberId, $outTradeNo, $protocol, $amount, $app) + { + $params = [ + 'app_id' => $app->app_id, + 'timestamp' => time(), + 'nonce_str' => StringHelper::getRandomString(32), + 'data' => json_encode([ + 'memberId' => $memberId, + 'outTradeNo' => $outTradeNo, + 'protocol' => $protocol, + 'payAmount' => $amount, + ]), + ]; + $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); + $params['sign'] = $sign; + return $params; + } + + private function buildConfirmPayParams($token, $protocol, $smsCode, $app) + { + $params = [ + 'app_id' => $app->app_id, + 'timestamp' => time(), + 'nonce_str' => StringHelper::getRandomString(32), + 'data' => json_encode([ + 'token' => $token, + 'protocol' => $protocol, + 'smsCode' => $smsCode, + ]), + ]; + $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); + $params['sign'] = $sign; + return $params; + } + + private function buildComfirmBindCardParams($memberId, $smsNo, $smsCode, $app) + { + $params = [ + 'app_id' => $app->app_id, + 'timestamp' => time(), + 'nonce_str' => StringHelper::getRandomString(32), + 'data' => json_encode([ + 'memberId' => $memberId, + 'smsNo' => $smsNo, + 'smsCode' => $smsCode, + ]), + ]; + $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); + $params['sign'] = $sign; + return $params; + } + + public function orders(RequestInterface $request) + { + $page = $request->input('page', 1); + $pageSize = $request->input('pageSize', 20); + $token = $request->input('token'); + + $value = Redis::get('token:' . $token); + $users = $this->getUsers(); + if (empty($value) || !isset($users[$value])) { + throw new UnauthorizedException(); + } + + $offset = ($page - 1) * $pageSize; + $orders = Order::query()->orderBy('id', 'desc')->offset($offset)->limit($pageSize)->get(); + $protocols = $orders->pluck('protocol'); + $bankCards = BankCard::whereIn('protocol', $protocols)->get(); + $bankCards = $bankCards->keyBy('protocol'); + + $records = []; + foreach ($orders as $order) { + $bankCard = $bankCards[$order->protocol] ?? null; + $records[] = [ + 'out_order_no' => $order->out_order_no, + 'payed_at' => $order->payed_at, + 'status' => $order->status, + 'amount' => number_format($order->amount / 100, 2, '.', ''), + 'real_name' => $bankCard ? $bankCard->real_name : '', + 'bank_card_no' => $bankCard ? $bankCard->bank_card_no : '', + 'mobile' => $bankCard ? $bankCard->mobile : '', + 'card_no' => $bankCard ? $bankCard->card_no : '', + 'status_text' => $order->getStatusText(), + ]; + } + + $total = Order::query()->count(); + return $this->success([ + 'records' => $records, + 'total' => $total, + ]); + } + + public function login(RequestInterface $request) + { + $username = $request->input('username'); + $password = $request->input('password'); + + if (empty($username) || empty($password)) { + throw new BusinessException('账号或密码错误'); + } + + $users = $this->getUsers(); + + if (isset($users[$username]) && $users[$username] === $password) { + $token = md5(microtime() . $username . $password); + Redis::set('token:' . $token, $username); + Redis::expire('token:' . $token, 60*60); + return $this->success(['token' => $token]); + } + throw new BusinessException('账号或密码错误'); + } + + private function getUsers() { + return [ + 'owx0tlx' => 'lSoLW28NxtMlxUazC8p', + 'ioexlp2' => 'wwU8Ir3Xp0rxXssA9NV' + ]; + } +} diff --git a/app/Exception/UnauthorizedException.php b/app/Exception/UnauthorizedException.php new file mode 100644 index 0000000..1013ae1 --- /dev/null +++ b/app/Exception/UnauthorizedException.php @@ -0,0 +1,20 @@ + '申请失败', + self::STATUS_WAIT_PAY => '待支付', + self::STATUS_PAYED => '支付成功', + self::STATUS_FAILED => '支付失败', + ]; + return $statusMap[$this->status]; + } } \ No newline at end of file diff --git a/app/Service/PaymentService.php b/app/Service/PaymentService.php index c6f9ad3..d9ff475 100644 --- a/app/Service/PaymentService.php +++ b/app/Service/PaymentService.php @@ -10,20 +10,32 @@ use App\Helper\Efps\Result; use App\Helper\Redis; use App\Helper\RedisKey; use App\Model\App; +use App\Model\BankCard; use App\Model\Order; use App\Model\RefundOrder; +use App\Model\User; +use App\Request\BindCardConfirmRequest; +use App\Request\BindCardRequest; +use App\Request\PaymentQueryRequest; use App\Request\ProtocolPayConfirmRequest; use App\Request\ProtocolPayPreRequest; +use App\Request\RefundQueryRequest; +use App\Request\RefundRequest; +use App\Request\UnBindCardRequest; class PaymentService extends AbstractService { + public function generateMemberId($appKey, $cardNo) { + return md5($appKey . '-' . $cardNo); + } + public function createOrder(App $app, array $params) { $order = new Order(); $order->app_id = $app->app_id; - $order->out_order_no = $params['outTradeNo'] ?: ''; - $order->amount = $params['payAmount'] ?: 0; - $order->notify_url = $params['notifyUrl'] ?: ''; - $order->order_info = json_encode($params['orderInfo'] ?: [], JSON_UNESCAPED_UNICODE); + $order->out_order_no = $params['outTradeNo'] ?? ''; + $order->amount = $params['payAmount'] ?? 0; + $order->notify_url = $params['notifyUrl'] ?? ''; + $order->order_info = json_encode($params['orderInfo'] ?? [], JSON_UNESCAPED_UNICODE); return $order; } @@ -117,4 +129,183 @@ class PaymentService extends AbstractService $this->handlePayResult($result, $order); return $result->getData(); } + + public function bindCard($params) { + $req = new BindCardRequest($params); + $app = $req->getApp(); + $reqData = $req->getData(); + + $memberId = $this->generateMemberId($app->app_key, $reqData['certificatesNo']); + $reqData['memberId'] = $memberId; + + $bankCard = BankCard::where('app_id', $app->app_id) + ->where('member_id', $memberId) + ->where('bank_card_no', $reqData['bankCardNo']) + ->where('status', BankCard::STATUS_ACTIVE) + ->first(); + if ($bankCard) { + throw new BusinessException('该卡已绑定'); + } + + $result = Api::bindCard($reqData); + if (!$result->isSuccess()) { + throw new BusinessException($result->getMessage()); + } + + $user = User::where('member_id', $memberId)->first(); + if (!$user) { + $user = new User(); + $user->member_id = $memberId; + $user->app_id = $app->app_id; + $user->real_name = $reqData['userName']; + $user->card_no = $reqData['certificatesNo']; + $user->mobile = $reqData['phoneNum']; + $user->save(); + } + $bankCard = new BankCard(); + $bankCard->member_id = $memberId; + $bankCard->app_id = $app->app_id; + $bankCard->real_name = $reqData['userName']; + $bankCard->card_no = $reqData['certificatesNo']; + $bankCard->mobile = $reqData['phoneNum']; + $bankCard->sms_no = $result->get('smsNo', ''); + $bankCard->bank_card_no = $reqData['bankCardNo']; + $bankCard->bank_card_type = $reqData['bankCardType']; + $bankCard->protocol = $result->get('protocol', ''); + $bankCard->expired = $reqData['expired'] ?? ''; + $bankCard->cvn = $reqData['cvn'] ?? ''; + $bankCard->status = BankCard::STATUS_WAIT_CONFIRM; + $bankCard->save(); + return array_merge($result->getData(), ['memberId' => $memberId]); + } + + public function bindCardConfirm($params) + { + $req = new BindCardConfirmRequest($params); + $app = $req->getApp(); + $reqData = $req->getData(); + + $bankCard = BankCard::where('app_id', $app->app_id) + ->where('member_id', $reqData['memberId']) + ->where('sms_no', $reqData['smsNo']) + ->where('status', BankCard::STATUS_WAIT_CONFIRM) + ->first(); + if (!$bankCard) { + throw new BusinessException('绑卡申请不存在'); + } + + $result = Api::bindCardConfirm($reqData); + if (!$result->isSuccess()) { + throw new BusinessException($result->getMessage()); + } + $bankCard->status = BankCard::STATUS_ACTIVE; + $bankCard->protocol = $result->get('protocol', ''); + $bankCard->save(); + + return $result->getData(); + } + + public function refundQuery($params) + { + $req = new RefundQueryRequest($params); + $data = $req->getData(); + $result = Api::refundQuery($data); + if (!$result->isSuccess()) { + throw new BusinessException($result->getMessage()); + } + + $order = RefundOrder::where('out_refund_order_no', $result->get('outRefundNo')) + ->where('status', RefundOrder::STATUS_APPLY_SUCCESS) + ->first(); + if ($order) { + $this->handleRefundResult($result, $order); + } + + return $result->getData([ + 'outRefundNo', + 'transactionNo', + 'amount', + 'refundAmount', + 'refundState' + ]); + } + + public function paymentQuery($params) + { + $req = new PaymentQueryRequest($params); + $data = $req->getData(); + $result = Api::paymentQuery($data); + if (!$result->isSuccess()) { + throw new BusinessException($result->getMessage()); + } + + $order = Order::where('out_order_no', $result->get('outTradeNo')) + ->where('status', Order::STATUS_WAIT_PAY) + ->first(); + if ($order) { + $this->handlePayResult($result, $order); + } + + return $result->getData([ + 'outTradeNo', + 'transactionNo', + 'payState', + 'procedureFee', + 'amount' + ]); + } + + public function unBindCard($params) + { + $req = new UnBindCardRequest($params); + $app = $req->getApp(); + $reqData = $req->getData(); + $bankCard = BankCard::where('app_id', $app->app_id) + ->where('member_id', $reqData['memberId']) + ->where('protocol', $reqData['protocol']) + ->where('status', BankCard::STATUS_ACTIVE) + ->first(); + if (!$bankCard) { + throw new BusinessException('绑卡不存在'); + } + + $result = Api::unBindCard($reqData); + if (!$result->isSuccess()) { + throw new BusinessException($result->getMessage()); + } + + $bankCard->status = BankCard::STATUS_UNBIND; + $bankCard->save(); + + return $result->getData(); + } + + public function refund($params) + { + $req = new RefundRequest($params); + $app = $req->getApp(); + $data = $req->getData(); + + $refundOrder = new RefundOrder(); + $refundOrder->app_id = $app->app_id; + $refundOrder->out_order_no = $data['outTradeNo'] ?: ''; + $refundOrder->out_refund_order_no = $data['outRefundNo'] ?: ''; + $refundOrder->order_amount = $data['amount'] ?: ''; + $refundOrder->refund_amount = $data['refundAmount'] ?: ''; + $refundOrder->remark = $data['remark'] ?: ''; + $refundOrder->notify_url = $data['notifyUrl'] ?: ''; + + $result = Api::refund($data); + if (!$result->isSuccess()) { + $refundOrder->status = RefundOrder::STATUS_APPLY_FAILED; + $refundOrder->error_code = $result->getCode(); + $refundOrder->error_msg = $result->getMessage(); + $refundOrder->save(); + throw new BusinessException($result->getMessage()); + } + $refundOrder->status = RefundOrder::STATUS_APPLY_SUCCESS; + $refundOrder->save(); + + return $result->getData(); + } } diff --git a/config/autoload/server.php b/config/autoload/server.php index 56f6afb..e778ebd 100644 --- a/config/autoload/server.php +++ b/config/autoload/server.php @@ -37,6 +37,8 @@ return [ Constant::OPTION_MAX_REQUEST => 100000, Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024, Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024, + Constant::OPTION_DOCUMENT_ROOT => BASE_PATH . '/public', + Constant::OPTION_ENABLE_STATIC_HANDLER => true, ], 'callbacks' => [ Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], diff --git a/config/routes.php b/config/routes.php index 98b343b..afd0d8b 100644 --- a/config/routes.php +++ b/config/routes.php @@ -4,6 +4,7 @@ declare(strict_types=1); use App\Controller\Payment\NotifyController; use App\Controller\Payment\PayController; +use App\Controller\Recharge\RechargeController; use Hyperf\HttpServer\Router\Router; Router::get('/favicon.ico', function () { @@ -22,6 +23,14 @@ Router::addGroup('/payment',function () { Router::post('/payment-query', [PayController::class, 'paymentQuery']); }, ['middleware' => [\App\Middleware\RequestLogMiddleware::class]]); +Router::addGroup('/recharge',function () { + Router::post('/recharge', [RechargeController::class, 'recharge']); + Router::post('/confirm-bind-card', [RechargeController::class, 'confirmBindCard']); + Router::post('/confirm-pay', [RechargeController::class, 'confirmPay']); + Router::post('/orders', [RechargeController::class, 'orders']); + Router::post('/login', [RechargeController::class, 'login']); +}); + Router::addGroup('/notify',function () { Router::addRoute(['GET', 'POST'], '/payment', [NotifyController::class, 'payment']); Router::addRoute(['GET', 'POST'], '/refund', [NotifyController::class, 'refund']); diff --git a/payment.sql b/payment.sql index 3513f83..1d26672 100644 --- a/payment.sql +++ b/payment.sql @@ -22,17 +22,16 @@ CREATE TABLE `request_logs` ( CREATE TABLE `users` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', - `request_id` varchar(22) not null COMMENT '请求ID', `app_id` varchar(16) NOT NULL COMMENT '应用ID', - `member_id` varchar(20) not null default '', - `merId` varchar(50) not null default '', + `member_id` varchar(32) not null default '', + `real_name` varchar(20) not null default '', `card_no` varchar(32) not null default '', `mobile` varchar(15) not null default '', - `card_valid_to` varchar(10) default NULL COMMENT '身份证有效期', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY `idx_appid` (`app_id`) USING BTREE, KEY `idx_memberid` (`member_id`) USING BTREE, + KEY `idx_cardno` (`card_no`) USING BTREE, KEY `idx_createdat` (`created_at`) USING BTREE, PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC; @@ -48,7 +47,8 @@ CREATE TABLE `bank_cards` ( `bank_card_type` varchar(10) not null default '', `sms_no` varchar(32) NOT NULL DEFAULT '', `protocol` varchar(32) NOT NULL DEFAULT '', - `bind_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '支付时间', + `expired` varchar(4) NOT NULL DEFAULT '', + `cvn` varchar(10) NOT NULL DEFAULT '', `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..2974828 --- /dev/null +++ b/public/index.html @@ -0,0 +1,170 @@ + + +
+ + + +