428 lines
22 KiB
HTML
428 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>justsolutionsWeb — 后端 API 调用清单</title>
|
||
<style>
|
||
:root {
|
||
--bg: #f6f8fa;
|
||
--card: #ffffff;
|
||
--text: #24292f;
|
||
--muted: #57606a;
|
||
--border: #d0d7de;
|
||
--accent: #0969da;
|
||
--accent-soft: #ddf4ff;
|
||
--code-bg: #f0f3f6;
|
||
--th-bg: #f0f3f6;
|
||
--row-alt: #fafbfc;
|
||
--warn-bg: #fff8c5;
|
||
--warn-border: #d4a72c;
|
||
--note-bg: #ddf4ff;
|
||
--note-border: #54aeff;
|
||
--get: #1a7f37;
|
||
--post: #9a6700;
|
||
}
|
||
* { box-sizing: border-box; }
|
||
body {
|
||
margin: 0;
|
||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Helvetica, Arial, sans-serif;
|
||
background: var(--bg);
|
||
color: var(--text);
|
||
line-height: 1.65;
|
||
font-size: 15px;
|
||
}
|
||
.wrap {
|
||
max-width: 1040px;
|
||
margin: 0 auto;
|
||
padding: 32px 24px 80px;
|
||
}
|
||
header.page {
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 28px 32px;
|
||
margin-bottom: 28px;
|
||
}
|
||
header.page h1 { margin: 0 0 8px; font-size: 26px; }
|
||
header.page p { margin: 4px 0; color: var(--muted); }
|
||
.toc {
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 18px 28px;
|
||
margin-bottom: 28px;
|
||
}
|
||
.toc h2 { font-size: 15px; margin: 0 0 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
|
||
.toc ol { margin: 0; padding-left: 20px; columns: 2; column-gap: 36px; }
|
||
.toc li { margin: 4px 0; break-inside: avoid; }
|
||
.toc a { color: var(--accent); text-decoration: none; }
|
||
.toc a:hover { text-decoration: underline; }
|
||
section {
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 24px 32px;
|
||
margin-bottom: 22px;
|
||
}
|
||
h2 { font-size: 21px; margin: 0 0 16px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
|
||
h3 { font-size: 17px; margin: 24px 0 12px; }
|
||
p { margin: 12px 0; }
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: 16px 0;
|
||
font-size: 14px;
|
||
}
|
||
th, td {
|
||
border: 1px solid var(--border);
|
||
padding: 8px 12px;
|
||
text-align: left;
|
||
vertical-align: top;
|
||
}
|
||
th { background: var(--th-bg); font-weight: 600; }
|
||
tbody tr:nth-child(even) { background: var(--row-alt); }
|
||
code {
|
||
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
||
background: var(--code-bg);
|
||
padding: 1px 6px;
|
||
border-radius: 5px;
|
||
font-size: 13px;
|
||
color: #cf222e;
|
||
word-break: break-word;
|
||
}
|
||
td code { color: #0550ae; }
|
||
.method { font-weight: 700; font-size: 12px; letter-spacing: .5px; }
|
||
.method.get { color: var(--get); }
|
||
.method.post { color: var(--post); }
|
||
.num { text-align: center; font-variant-numeric: tabular-nums; color: var(--muted); }
|
||
.callout {
|
||
border-radius: 8px;
|
||
padding: 12px 16px;
|
||
margin: 16px 0;
|
||
border-left: 4px solid;
|
||
font-size: 14px;
|
||
}
|
||
.callout.warn { background: var(--warn-bg); border-color: var(--warn-border); }
|
||
.callout.note { background: var(--note-bg); border-color: var(--note-border); }
|
||
.callout p { margin: 6px 0; }
|
||
ul.tight li { margin: 5px 0; }
|
||
.pill {
|
||
display: inline-block;
|
||
background: var(--accent-soft);
|
||
color: var(--accent);
|
||
border-radius: 999px;
|
||
padding: 1px 10px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
margin-left: 4px;
|
||
}
|
||
footer { text-align: center; color: var(--muted); font-size: 13px; margin-top: 30px; }
|
||
.small { font-size: 13px; color: var(--muted); }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="wrap">
|
||
|
||
<header class="page">
|
||
<h1>justsolutionsWeb — 后端 API 调用清单</h1>
|
||
<p>前端:<code>justsolutions-web</code> v1.2.0 · Angular 16 · Angular CLI 16.2.14</p>
|
||
<p class="small">基于源码静态分析(<code>src/app</code> 下所有 <code>*.ts</code>)整理。共 14 个后端端点。</p>
|
||
</header>
|
||
|
||
<nav class="toc">
|
||
<h2>目录</h2>
|
||
<ol>
|
||
<li><a href="#arch">调用架构概览</a></li>
|
||
<li><a href="#list">调用清单(按端点汇总)</a></li>
|
||
<li><a href="#auth">鉴权(OAuth Token)</a></li>
|
||
<li><a href="#amlquery">AML 查询模块</a></li>
|
||
<li><a href="#contact">联系我们模块</a></li>
|
||
<li><a href="#plans">套餐与下单模块</a></li>
|
||
<li><a href="#prefix">端点前缀分布</a></li>
|
||
<li><a href="#flow">速查 · 典型流程</a></li>
|
||
</ol>
|
||
</nav>
|
||
|
||
<section id="arch">
|
||
<h2>1. 调用架构概览</h2>
|
||
<p>所有业务 API 调用都收口在统一的 <strong><code>HttpService</code></strong>(<code>src/app/services/http.service.ts</code>):</p>
|
||
<ul class="tight">
|
||
<li><strong>基地址</strong>:请求时把相对路径拼到 <code>environment.apis.url</code> 之后,即 <code>environment.apis.url + request.url</code>。</li>
|
||
<li><strong>鉴权</strong>:自动从 <code>localStorage</code> 或 <code>sessionStorage</code> 读取 <code>aml_access_token</code>,存在时加上请求头 <code>Authorization: Bearer <token></code>。</li>
|
||
<li><strong>请求模型</strong>:统一使用 <code>Http.Request<T></code>(<code>src/app/models/http.ts</code>),字段含 <code>method</code> / <code>url</code> / <code>body</code> / <code>params</code> / <code>headers</code> / <code>responseType</code> 等。</li>
|
||
</ul>
|
||
<div class="callout note">
|
||
<p><strong>例外</strong>:支付跳转直接 <code>location.href</code> 重定向到 QFPay 外部网关(见第 6 节),不经过 <code>HttpService</code>。</p>
|
||
</div>
|
||
|
||
<h3>1.1 环境与基地址配置</h3>
|
||
<table>
|
||
<thead>
|
||
<tr><th>环境文件</th><th><code>apis.url</code>(API 基地址)</th><th><code>apis.amlUrl</code>(AML 门户来源)</th><th><code>apis.test</code></th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><code>environment.ts</code>(本地默认)</td><td><code>https://api-aml.iconsz.com</code></td><td><code>https://aml.iconsz.com</code></td><td><code>true</code></td></tr>
|
||
<tr><td><code>environment.dev.ts</code></td><td><code>https://api-aml.iconsz.com</code></td><td><code>https://aml.iconsz.com</code></td><td><code>true</code></td></tr>
|
||
<tr><td><code>environment.prod.ts</code></td><td><code>https://api.justsolutions.ai</code></td><td><code>https://aml.justsolutions.ai</code></td><td><code>false</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
<ul class="tight">
|
||
<li><code>apis.amlUrl</code>:仅用于 <code>plans</code> 页面与父窗口(AML 门户 iframe 宿主)之间的 <code>postMessage</code> 通信,<strong>并非 HTTP 端点</strong>。</li>
|
||
<li><code>apis.test</code>:为 <code>true</code> 时支付金额固定写死为 <code>10</code>(分),用于测试支付(见第 6 节)。</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section id="list">
|
||
<h2>2. 调用清单(按端点汇总)</h2>
|
||
<table>
|
||
<thead>
|
||
<tr><th class="num">#</th><th>方法</th><th>端点(相对 <code>apis.url</code>)</th><th>用途</th><th>前端方法</th><th>所在文件</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="num">1</td><td><span class="method post">POST</span></td>
|
||
<td><code>/connect/token?__tenant=2C</code></td>
|
||
<td>OAuth 取 access token</td>
|
||
<td><code>getToken()</code></td>
|
||
<td><code>aml-query.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">2</td><td><span class="method get">GET</span></td>
|
||
<td><code>/api/aml/ConsumerPortal/GetPrice/{inputCode}</code></td>
|
||
<td>查询消费者查询价格</td>
|
||
<td><code>getPrice()</code></td>
|
||
<td><code>aml-query.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">3</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/customer/CreateFeedback</code></td>
|
||
<td>提交联系表单反馈</td>
|
||
<td><code>sendContactEmailAndReturnFeedback()</code></td>
|
||
<td><code>contact.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">4</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/aml/emailQueue/CreateEmailQueue</code></td>
|
||
<td>发送通知邮件(管理员 + 用户回执两次调用)</td>
|
||
<td><code>sendContactEmail()</code> / <code>sendContactByReturnEmail()</code></td>
|
||
<td><code>contact.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">5</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/plan/portal/GetPlanList</code></td>
|
||
<td>获取套餐列表(基础/jQ/加人/KYC)</td>
|
||
<td><code>getAllPlanList()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">6</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/Order/portal/GetEditionList</code></td>
|
||
<td>获取系统定义的 edition(所属行业)列表</td>
|
||
<td><code>getEditionList()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">7</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/Order/getCategoryByTypes</code></td>
|
||
<td>获取国家/地区列表(<code>typeCodes: ['COUNTRY']</code>)</td>
|
||
<td><code>getCountryList()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">8</td><td><span class="method get">GET</span></td>
|
||
<td><code>/api/identity/users/SearchUserByCodeAndType/{userCode}/true</code></td>
|
||
<td>校验优惠码/代理商是否存在</td>
|
||
<td><code>getAgentor()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">9</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/Order/portal/queryRenewableTenant</code></td>
|
||
<td>查询可续费租户</td>
|
||
<td><code>queryTenant()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">10</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/Order/portal/ExistsByOrganizationBRCI</code></td>
|
||
<td>校验商业登记号(BR)/公司编号(CI)是否已存在</td>
|
||
<td><code>checkBRCI()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">11</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/customer/portal/CheckEmailExists/{email}</code></td>
|
||
<td>校验管理员邮箱是否已存在</td>
|
||
<td><code>checkEmailExist()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">12</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/Order/portal/CreateOrder</code></td>
|
||
<td>新租户下单</td>
|
||
<td><code>createOrder()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">13</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/Order/portal/TenantRenewal</code></td>
|
||
<td>租户续费下单</td>
|
||
<td><code>tenantRenewal()</code></td>
|
||
<td><code>plan.service.ts</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="num">14</td><td><span class="method post">POST</span></td>
|
||
<td><code>/api/amlPortal/Order/portal/PaymentWebhook</code></td>
|
||
<td>支付完成回调(作为 <code>notify_url</code> 传给 QFPay,由其服务端回调,<strong>非前端直接调用</strong>)</td>
|
||
<td>—</td>
|
||
<td><code>plan4.component.ts</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section id="auth">
|
||
<h2>3. 鉴权(OAuth Token)</h2>
|
||
<p><strong>端点 1</strong> — <code>POST /connect/token?__tenant=2C</code></p>
|
||
<ul class="tight">
|
||
<li>位置:<code>AmlQueryService</code>。在该服务<strong>构造函数中自动触发</strong>:当 <code>localStorage</code> 无 <code>aml_access_token</code> 时,调用 <code>getToken()</code> 并把返回的 <code>access_token</code> 写入 <code>localStorage</code>。</li>
|
||
<li>请求头:<code>Content-Type: application/x-www-form-urlencoded</code></li>
|
||
</ul>
|
||
<p>Body(<code>x-www-form-urlencoded</code>,硬编码凭证):</p>
|
||
<table>
|
||
<thead><tr><th>字段</th><th>值</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>grant_type</code></td><td><code>password</code></td></tr>
|
||
<tr><td><code>response_type</code></td><td><code>token</code></td></tr>
|
||
<tr><td><code>username</code></td><td><code>customer1</code></td></tr>
|
||
<tr><td><code>password</code></td><td><code>1qaz@WSX</code></td></tr>
|
||
<tr><td><code>scope</code></td><td><code>FX</code></td></tr>
|
||
<tr><td><code>client_id</code></td><td><code>customer1_client</code></td></tr>
|
||
<tr><td><code>client_secret</code></td><td><code>1qaz@WSX</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="callout warn">
|
||
<p>⚠️ 用户名/密码/client secret 以明文硬编码在前端源码中(<code>aml-query.service.ts:47-51</code>),属于公开网站内置的固定访客凭证。</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="amlquery">
|
||
<h2>4. AML 查询模块(aml-query)</h2>
|
||
<p><strong>端点 2</strong> — <code>GET /api/aml/ConsumerPortal/GetPrice/{inputCode}</code></p>
|
||
<ul class="tight">
|
||
<li>调用方:<code>aml-query-layout.component.ts</code>(<code>ngOnInit</code> 时以 <code>getPrice('E')</code> 拉取价格)。</li>
|
||
<li>价格的真正计算逻辑在 <code>AmlQueryService.calculatePrice()</code>(本地计算,不走接口)。</li>
|
||
</ul>
|
||
<div class="callout note">
|
||
<p><code>aml-query/pages/result/result.component.ts</code>(评估报告页)当前使用<strong>本地 mock 数据 / <code>Math.random()</code></strong> 生成风险评估结果,PDF 下载指向 <code>assets/sample-report.pdf</code>,<code>apiIntegration()</code> 弹窗里的 <code>api.credit-risk.example.com</code> 等仅为示例文案,<strong>不是真实后端调用</strong>。</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="contact">
|
||
<h2>5. 联系我们模块(contact)</h2>
|
||
<p>调用方:<code>contact/pages/contact/contact.component.ts</code> 提交表单时触发。</p>
|
||
<ul class="tight">
|
||
<li><strong>端点 3</strong> <code>POST /api/amlPortal/customer/CreateFeedback</code>:保存反馈记录。
|
||
<br><span class="small">Body(<code>CreateFeedbackParam</code>):<code>companyName</code>、<code>customerName</code>、<code>customerEmail</code>、<code>typeOfQuery</code>、<code>message</code>、<code>userHost</code>、<code>destEmail</code>、<code>emailSubject</code>、<code>emailBody</code>。</span>
|
||
</li>
|
||
<li><strong>端点 4</strong> <code>POST /api/aml/emailQueue/CreateEmailQueue</code>:进入邮件发送队列,被调用<strong>两次</strong>:
|
||
<ul class="tight">
|
||
<li><code>sendContactEmail()</code> → 通知管理员(收件人 <code>environment.email.contact</code>)。</li>
|
||
<li><code>sendContactByReturnEmail()</code> → 给提交者发送回执邮件(收件人为用户填写邮箱)。</li>
|
||
</ul>
|
||
<span class="small">Body(<code>CreateEmailQueueParam</code>):<code>subject</code>、<code>to</code>、<code>body</code>(HTML)、<code>businessType: 2100</code>、<code>businessId: ''</code>。</span>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section id="plans">
|
||
<h2>6. 套餐与下单模块(plans / Order)</h2>
|
||
<p><code>PlanService</code> 集中了套餐查询、校验与下单接口。各端点的页面调用关系:</p>
|
||
<table>
|
||
<thead><tr><th>端点</th><th>调用页面</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>getAllPlanList()</code><span class="pill">端点 5</span></td><td><code>plans.component.ts</code>(进入套餐页 / 收到父窗口 <code>postMessage</code> 后)</td></tr>
|
||
<tr><td><code>getEditionList()</code><span class="pill">端点 6</span></td><td><code>plans.component.ts</code>、<code>plan3.component.ts</code></td></tr>
|
||
<tr><td><code>getCountryList()</code><span class="pill">端点 7</span></td><td><code>plans.component.ts</code>、<code>plan3.component.ts</code></td></tr>
|
||
<tr><td><code>getAgentor()</code><span class="pill">端点 8</span></td><td><code>plan3.component.ts</code>(输入优惠码校验)</td></tr>
|
||
<tr><td><code>queryTenant()</code><span class="pill">端点 9</span></td><td><code>plan1.component.ts</code>、<code>plan3.component.ts</code>(续费选租户)</td></tr>
|
||
<tr><td><code>checkBRCI()</code><span class="pill">端点 10</span></td><td><code>plan3.component.ts</code></td></tr>
|
||
<tr><td><code>checkEmailExist()</code><span class="pill">端点 11</span></td><td><code>plan1.component.ts</code>、<code>plan3.component.ts</code></td></tr>
|
||
<tr><td><code>createOrder()</code><span class="pill">端点 12</span></td><td><code>plan4.component.ts</code>(<code>type === 'new'</code>)</td></tr>
|
||
<tr><td><code>tenantRenewal()</code><span class="pill">端点 13</span></td><td><code>plan4.component.ts</code>(<code>type === 'renew'</code>)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h3>关键请求体</h3>
|
||
<ul class="tight">
|
||
<li><strong><code>getAllPlanList</code></strong>(<code>GetPlanListParam</code>):<code>pageIndex: 0</code>、<code>pageSize: 9999</code>、<code>tag1List: ['B','jQ','j','AdlU','KYC']</code>、<code>tag2List</code>/<code>tag3List</code>(由调用方传入)、<code>agentUserId</code>。</li>
|
||
<li><strong><code>getCountryList</code></strong>:<code>{ typeCodes: ['COUNTRY'] }</code>。</li>
|
||
<li><strong><code>checkBRCI</code></strong>:通过 <code>params</code> 传 <code>br</code> / <code>ci</code>(query string)。</li>
|
||
<li><strong><code>createOrder</code></strong>(<code>CreateOrderParam</code>):<code>planList[]</code>(<code>planId</code>/<code>planDetailId</code>/<code>pcs</code>)、<code>tenantName</code>、<code>tenantAdminEmail</code>、<code>jurisdiction</code>、<code>organizationBR</code>、<code>organizationCI</code>、<code>organizationReference</code>、<code>contactPerson</code>、<code>companyAddress</code>、<code>phone</code>、<code>effectiveStartTime</code>、<code>agentorId</code>、<code>isOfflinePayment: false</code>、<code>isAgentBehalf</code>。</li>
|
||
<li><strong><code>tenantRenewal</code></strong>(<code>TenantRenewalParam</code>):<code>targetTenantID</code>、<code>planList[]</code>、<code>agentorId</code>、<code>tenantAdminEmail</code>、<code>isOfflinePayment: false</code>、<code>isAgentBehalf</code>。</li>
|
||
</ul>
|
||
|
||
<h3>6.1 支付跳转(QFPay 外部网关,不经过 HttpService)</h3>
|
||
<p>位置:<code>plan4.component.ts</code> 的 <code>payFn()</code>。下单成功(<code>createOrder</code>/<code>tenantRenewal</code> 返回 <code>code === 0</code>)后:</p>
|
||
<ul class="tight">
|
||
<li>若订单 <code>paymentStatus === 200</code> 或 <code>txamt === 0</code> → 直接跳转 <code>plans-plus/payment-success</code>。</li>
|
||
<li>否则通过 <code>location.href</code> 重定向到 QFPay 收银台:<br>
|
||
<code>https://openapi-hk.qfapi.com/checkstand/#/?<参数>&sign=<sha256></code></li>
|
||
</ul>
|
||
<p>主要参数:</p>
|
||
<table>
|
||
<thead><tr><th>参数</th><th>值</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>appcode</code></td><td><code>environment.qfpay.appcode</code>(固定值)</td></tr>
|
||
<tr><td><code>goods_name</code></td><td>下单返回的 <code>planName</code></td></tr>
|
||
<tr><td><code>out_trade_no</code></td><td>下单返回的 <code>orderCode</code></td></tr>
|
||
<tr><td><code>paysource</code></td><td><code>remotepay_checkout</code></td></tr>
|
||
<tr><td><code>return_url</code></td><td><code>{baseUrl}/plans-plus/payment-success</code></td></tr>
|
||
<tr><td><code>failed_url</code></td><td><code>{baseUrl}/plans-plus/payment-failure</code></td></tr>
|
||
<tr><td><code>notify_url</code></td><td><code>{apis.url}/api/amlPortal/Order/portal/PaymentWebhook</code>(端点 14,QFPay 服务端回调后端)</td></tr>
|
||
<tr><td><code>txamt</code></td><td><code>apis.test ? 10 : planPrice * 100</code>(单位:分)</td></tr>
|
||
<tr><td><code>txcurrcd</code></td><td><code>HKD</code></td></tr>
|
||
<tr><td><code>sign</code></td><td><code>sha256(<排序后的参数串> + api_key)</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section id="prefix">
|
||
<h2>7. 端点前缀分布</h2>
|
||
<table>
|
||
<thead><tr><th>前缀</th><th>含义</th><th>涉及端点</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>/connect/*</code></td><td>OpenIddict/IdentityServer OAuth</td><td>端点 1</td></tr>
|
||
<tr><td><code>/api/aml/*</code></td><td>AML 主模块(消费者查询、邮件队列)</td><td>端点 2、4</td></tr>
|
||
<tr><td><code>/api/amlPortal/*</code></td><td>AML 门户模块(客户、套餐、订单)</td><td>端点 3、5、6、7、9、10、11、12、13、14</td></tr>
|
||
<tr><td><code>/api/identity/*</code></td><td>ABP Identity(用户)</td><td>端点 8</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section id="flow">
|
||
<h2>8. 速查 · 典型流程(按调用次序)</h2>
|
||
<ul class="tight">
|
||
<li><strong>应用启动</strong>:<code>AmlQueryService</code> 构造 → 端点 1 取 token。</li>
|
||
<li><strong>AML 查询页加载</strong>:端点 2 取价格。</li>
|
||
<li><strong>联系页提交</strong>:端点 3 + 端点 4(×2)。</li>
|
||
<li><strong>套餐购买流程</strong>:
|
||
<ol>
|
||
<li>进入套餐页:端点 5、6、7。</li>
|
||
<li>填写租户/续费信息:端点 8(优惠码)、9(租户)、10(BR/CI)、11(邮箱)。</li>
|
||
<li>确认下单:端点 12(新购)或 13(续费)。</li>
|
||
<li>跳转 QFPay 支付 → 支付完成后 QFPay 回调端点 14。</li>
|
||
</ol>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<footer>
|
||
justsolutionsWeb 后端 API 调用清单 · 基于源码静态分析整理
|
||
</footer>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|