提交
This commit is contained in:
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace app\miniapi\controller;
|
namespace app\miniapi\controller;
|
||||||
|
|
||||||
|
use app\miniapi\service\Payment\MiniPayService;
|
||||||
use app\miniapi\service\VisaApplication\VisaApplicationService;
|
use app\miniapi\service\VisaApplication\VisaApplicationService;
|
||||||
|
|
||||||
final class VisaApplication extends Base
|
final class VisaApplication extends Base
|
||||||
@@ -11,7 +12,31 @@ final class VisaApplication extends Base
|
|||||||
public function start() { return $this->call(fn($service, $userId) => $service->start($userId, $this->postData(), $this->orderSource())); }
|
public function start() { return $this->call(fn($service, $userId) => $service->start($userId, $this->postData(), $this->orderSource())); }
|
||||||
public function application() { return $this->call(fn($service, $userId) => $service->application($userId, trim((string)$this->request->param('public_id', '')))); }
|
public function application() { return $this->call(fn($service, $userId) => $service->application($userId, trim((string)$this->request->param('public_id', '')))); }
|
||||||
public function draft() { return $this->call(fn($service, $userId) => $service->saveDraft($userId, $this->postData()), '草稿已保存'); }
|
public function draft() { return $this->call(fn($service, $userId) => $service->saveDraft($userId, $this->postData()), '草稿已保存'); }
|
||||||
public function submit() { return $this->call(fn($service, $userId) => $service->submit($userId, $this->postData()), '提交成功'); }
|
public function submit()
|
||||||
|
{
|
||||||
|
$userId = $this->requireLogin(); if (!is_int($userId)) return $userId;
|
||||||
|
$input = $this->postData();
|
||||||
|
$result = (new VisaApplicationService())->submit($userId, $input);
|
||||||
|
if ((int)($result['code'] ?? 0) !== 1) return $this->fail((string)($result['msg'] ?? '服务异常,请稍后重试'));
|
||||||
|
$data = (array)($result['data'] ?? []);
|
||||||
|
if (!empty($data['requires_payment'])) {
|
||||||
|
$target = VisaApplicationService::nativePaymentForCheck($data);
|
||||||
|
$openid = trim((string)($input['openid'] ?? ''));
|
||||||
|
if (!$target || $openid === '') return $this->fail($openid === '' ? '微信用户信息缺失,请重新登录后支付' : '支付订单信息异常');
|
||||||
|
$pay = (new MiniPayService())->requestForTarget(
|
||||||
|
$this->currentMiniAppContext('visa'),
|
||||||
|
$target['order_sn'],
|
||||||
|
$target['money'],
|
||||||
|
$openid,
|
||||||
|
$target['target_table'],
|
||||||
|
'miniapi visa mini pay'
|
||||||
|
);
|
||||||
|
if ((int)($pay['code'] ?? 0) !== 1) return $this->fail((string)($pay['msg'] ?? '支付参数获取失败'));
|
||||||
|
$data['pay'] = $pay['data'];
|
||||||
|
}
|
||||||
|
unset($data['target_orders'], $data['pay_url']);
|
||||||
|
return $this->ok($data, '提交成功');
|
||||||
|
}
|
||||||
public function agree()
|
public function agree()
|
||||||
{
|
{
|
||||||
$result = (new VisaApplicationService())->agree(trim((string)$this->request->param('doc_code', '')));
|
$result = (new VisaApplicationService())->agree(trim((string)$this->request->param('doc_code', '')));
|
||||||
|
|||||||
@@ -12,6 +12,29 @@ class MiniPayService
|
|||||||
public function request(MiniAppContext $context, string $orderSn, $money, string $openid, string $scene = 'miniapi mini pay'): array
|
public function request(MiniAppContext $context, string $orderSn, $money, string $openid, string $scene = 'miniapi mini pay'): array
|
||||||
{
|
{
|
||||||
$payConfig = (new PaymentChannelService())->miniPay($context);
|
$payConfig = (new PaymentChannelService())->miniPay($context);
|
||||||
|
return $this->send($payConfig, $orderSn, $money, $openid, $scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function requestForTarget(MiniAppContext $context, string $orderSn, $money, string $openid, string $targetTable, string $scene = 'miniapi target mini pay'): array
|
||||||
|
{
|
||||||
|
$payConfig = (new PaymentChannelService())->miniPay($context);
|
||||||
|
$mark = self::targetMarkForCheck((string)$payConfig['mark_prefix'], $targetTable);
|
||||||
|
if ($mark === '') {
|
||||||
|
return ['code' => 0, 'msg' => '支付配置未完成', 'data' => []];
|
||||||
|
}
|
||||||
|
$payConfig['mark'] = $mark;
|
||||||
|
return $this->send($payConfig, $orderSn, $money, $openid, $scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function targetMarkForCheck(string $prefix, string $targetTable): string
|
||||||
|
{
|
||||||
|
return preg_match('/^[A-Za-z0-9_]+$/', $prefix) && preg_match('/^[A-Za-z0-9_]+$/', $targetTable)
|
||||||
|
? $prefix . $targetTable
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function send(array $payConfig, string $orderSn, $money, string $openid, string $scene): array
|
||||||
|
{
|
||||||
if ($payConfig['url'] === '') {
|
if ($payConfig['url'] === '') {
|
||||||
return [
|
return [
|
||||||
'code' => 0,
|
'code' => 0,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class PaymentChannelService
|
|||||||
'url' => $url,
|
'url' => $url,
|
||||||
'body' => trim((string)($config['body'] ?? 'EVUS登记服务费')) ?: 'EVUS登记服务费',
|
'body' => trim((string)($config['body'] ?? 'EVUS登记服务费')) ?: 'EVUS登记服务费',
|
||||||
'mark' => trim((string)($config['mark'] ?? $config['attach'] ?? 'msg')) ?: 'msg',
|
'mark' => trim((string)($config['mark'] ?? $config['attach'] ?? 'msg')) ?: 'msg',
|
||||||
|
'mark_prefix' => trim((string)($config['mark_prefix'] ?? '')),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,20 @@ final class VisaApplicationService
|
|||||||
return $this->request('agree', 0, ['doc_code' => $docCode]);
|
return $this->request('agree', 0, ['doc_code' => $docCode]);
|
||||||
}
|
}
|
||||||
public static function decorateSubmitForCheck(array $result): array { if ((int)($result['code'] ?? 0) === 1 && !empty($result['data']['requires_payment']) && !empty($result['data']['order_sn'])) $result['data']['pay_url'] = 'https://www.qlevisa.com/index/pay/h5pay.html?order_sn=' . rawurlencode((string)$result['data']['order_sn']); return $result; }
|
public static function decorateSubmitForCheck(array $result): array { if ((int)($result['code'] ?? 0) === 1 && !empty($result['data']['requires_payment']) && !empty($result['data']['order_sn'])) $result['data']['pay_url'] = 'https://www.qlevisa.com/index/pay/h5pay.html?order_sn=' . rawurlencode((string)$result['data']['order_sn']); return $result; }
|
||||||
|
public static function nativePaymentForCheck(array $data): array
|
||||||
|
{
|
||||||
|
$cents = (int)($data['total_price'] ?? 0);
|
||||||
|
if (empty($data['requires_payment']) || $cents <= 0 || !is_array($data['target_orders'] ?? null)) return [];
|
||||||
|
$target = null;
|
||||||
|
foreach ($data['target_orders'] as $item) {
|
||||||
|
if (is_array($item) && (int)($item['applicant_index'] ?? -1) === 0) { $target = $item; break; }
|
||||||
|
}
|
||||||
|
if ($target === null) $target = $data['target_orders'][0] ?? null;
|
||||||
|
$table = trim((string)($target['target_table'] ?? ''));
|
||||||
|
$orderSn = trim((string)($target['target_order_sn'] ?? ''));
|
||||||
|
if (!preg_match('/^[A-Za-z0-9_]+$/', $table) || !preg_match('/^[A-Za-z0-9_-]{1,100}$/', $orderSn)) return [];
|
||||||
|
return ['target_table' => $table, 'order_sn' => $orderSn, 'money' => intdiv($cents, 100) . '.' . str_pad((string)($cents % 100), 2, '0', STR_PAD_LEFT)];
|
||||||
|
}
|
||||||
public function payload(int $userId, array $params = []): array { $source = (string)($params['order_source'] ?? ''); unset($params['order_source']); return ['user_token' => authcode((string)json_encode(['purpose' => 'visa_api', 'user_id' => $userId, 'order_source' => $source], JSON_UNESCAPED_UNICODE), 'ENCODE', MINIAPI_TOKEN_KEY, 120)] + $params; }
|
public function payload(int $userId, array $params = []): array { $source = (string)($params['order_source'] ?? ''); unset($params['order_source']); return ['user_token' => authcode((string)json_encode(['purpose' => 'visa_api', 'user_id' => $userId, 'order_source' => $source], JSON_UNESCAPED_UNICODE), 'ENCODE', MINIAPI_TOKEN_KEY, 120)] + $params; }
|
||||||
public function endpoint(string $userUrl, string $action): string
|
public function endpoint(string $userUrl, string $action): string
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,5 +53,31 @@ return [
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'visa' => [
|
||||||
|
'mini_pay' => [
|
||||||
|
'url' => '',
|
||||||
|
'body' => '签证及入境服务费',
|
||||||
|
// 与公共网站的 PAY_MARK 保持一致,最终 mark 为此前缀加目标订单表名。
|
||||||
|
'mark_prefix' => 'bjglobal',
|
||||||
|
],
|
||||||
|
'companies' => [
|
||||||
|
'jn' => [
|
||||||
|
'mini_pay' => [],
|
||||||
|
],
|
||||||
|
'bj' => [
|
||||||
|
'mini_pay' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'apps' => [
|
||||||
|
'evus_jn_mp' => [
|
||||||
|
'company_code' => 'jn',
|
||||||
|
'mini_pay' => [],
|
||||||
|
],
|
||||||
|
'evus_bj_mp' => [
|
||||||
|
'company_code' => 'bj',
|
||||||
|
'mini_pay' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -20,6 +20,15 @@ if (!str_contains((string)file_get_contents(dirname(__DIR__) . '/app/miniapi/con
|
|||||||
$neutral = VisaApplicationService::decorateSubmitForCheck(['code' => 1, 'data' => ['order_sn' => 'V1', 'requires_payment' => false]]);
|
$neutral = VisaApplicationService::decorateSubmitForCheck(['code' => 1, 'data' => ['order_sn' => 'V1', 'requires_payment' => false]]);
|
||||||
$payable = VisaApplicationService::decorateSubmitForCheck(['code' => 1, 'data' => ['order_sn' => 'V 1', 'requires_payment' => true]]);
|
$payable = VisaApplicationService::decorateSubmitForCheck(['code' => 1, 'data' => ['order_sn' => 'V 1', 'requires_payment' => true]]);
|
||||||
if (isset($neutral['data']['pay_url']) || ($payable['data']['pay_url'] ?? '') !== 'https://www.qlevisa.com/index/pay/h5pay.html?order_sn=V%201') throw new RuntimeException('miniapi payment decoration failed');
|
if (isset($neutral['data']['pay_url']) || ($payable['data']['pay_url'] ?? '') !== 'https://www.qlevisa.com/index/pay/h5pay.html?order_sn=V%201') throw new RuntimeException('miniapi payment decoration failed');
|
||||||
|
$native = VisaApplicationService::nativePaymentForCheck([
|
||||||
|
'requires_payment' => true,
|
||||||
|
'total_price' => 7900,
|
||||||
|
'target_orders' => [
|
||||||
|
['target_table' => 'singapore', 'target_order_sn' => '2026090412000012', 'applicant_index' => 0],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
if ($native !== ['target_table' => 'singapore', 'order_sn' => '2026090412000012', 'money' => '79.00']) throw new RuntimeException('native payment target failed');
|
||||||
|
if (VisaApplicationService::nativePaymentForCheck(['requires_payment' => true, 'total_price' => 7900, 'target_orders' => [['target_table' => 'bad-table', 'target_order_sn' => '1']]]) !== []) throw new RuntimeException('unsafe payment target accepted');
|
||||||
if (VisaApplicationService::dataSourceQueryForCheck('inac.city', ['model' => 'region', 'source_code' => 'jnwxmini', 'state_id' => '11', 'hotel_state' => '12', 'provinceCode' => '13', 'country' => 'CN', 'application_token' => 'secret', 'user_token' => 'secret']) !== ['type' => 'inac.city', 'model' => 'region', 'source_code' => 'jnwxmini', 'state_id' => '11', 'hotel_state' => '12', 'provinceCode' => '13', 'country' => 'CN']) throw new RuntimeException('miniapi data source filtering failed');
|
if (VisaApplicationService::dataSourceQueryForCheck('inac.city', ['model' => 'region', 'source_code' => 'jnwxmini', 'state_id' => '11', 'hotel_state' => '12', 'provinceCode' => '13', 'country' => 'CN', 'application_token' => 'secret', 'user_token' => 'secret']) !== ['type' => 'inac.city', 'model' => 'region', 'source_code' => 'jnwxmini', 'state_id' => '11', 'hotel_state' => '12', 'provinceCode' => '13', 'country' => 'CN']) throw new RuntimeException('miniapi data source filtering failed');
|
||||||
$controllerSource = (string)file_get_contents(dirname(__DIR__) . '/app/miniapi/controller/VisaApplication.php');
|
$controllerSource = (string)file_get_contents(dirname(__DIR__) . '/app/miniapi/controller/VisaApplication.php');
|
||||||
$routeSource = (string)file_get_contents(dirname(__DIR__) . '/app/miniapi/route/app.php');
|
$routeSource = (string)file_get_contents(dirname(__DIR__) . '/app/miniapi/route/app.php');
|
||||||
|
|||||||
Reference in New Issue
Block a user