5fd0d3c148
pay-server 自带 /_test 测试页:创建订单→显示收款地址+精确金额(可复制)
+过期倒计时→轮询状态到 paid。同源、无 CORS/CSP 摩擦,不碰营销站安全头;
纯调 POST /order + GET /order/{id},无私钥无密钥。生产收银台后续走独角数卡门面。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
258 lines
19 KiB
HTML
258 lines
19 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>Pangolin 支付落地方案 · 发卡/Reseller 收款 + 激活码自动发货</title>
|
||
<style>
|
||
:root{
|
||
--bg:#0f1117; --panel:#171a22; --panel2:#1d2129; --fg:#e6e8ee; --fg2:#a8afbd;
|
||
--accent:#e0884f; --accent2:#5fb0c9; --ok:#5ec27a; --bad:#e06a6a; --warn:#e0b84f;
|
||
--border:#272c36; --mono:"SF Mono",ui-monospace,Menlo,Consolas,monospace;
|
||
--sans:-apple-system,"PingFang SC","Helvetica Neue",Arial,sans-serif;
|
||
}
|
||
*{box-sizing:border-box}
|
||
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--sans);line-height:1.7;font-size:15px}
|
||
.wrap{max-width:960px;margin:0 auto;padding:48px 24px 96px}
|
||
h1{font-size:30px;line-height:1.3;margin:0 0 8px;letter-spacing:-.01em}
|
||
.sub{color:var(--fg2);font-size:15px;margin:0 0 32px}
|
||
h2{font-size:21px;margin:44px 0 14px;padding-bottom:8px;border-bottom:1px solid var(--border)}
|
||
h3{font-size:16px;margin:24px 0 8px;color:var(--fg)}
|
||
p{margin:10px 0}
|
||
code{font-family:var(--mono);font-size:.86em;background:var(--panel2);padding:1px 6px;border-radius:5px;color:#f0d9c4}
|
||
pre{background:#0a0c11;border:1px solid var(--border);border-radius:10px;padding:14px 16px;overflow-x:auto;font-family:var(--mono);font-size:12.5px;line-height:1.55;color:#cdd3df}
|
||
.tag{display:inline-block;font-size:12px;font-weight:600;padding:2px 9px;border-radius:999px;vertical-align:middle}
|
||
.tag.ok{background:rgba(94,194,122,.16);color:var(--ok)}
|
||
.tag.warn{background:rgba(224,184,79,.16);color:var(--warn)}
|
||
.tag.info{background:rgba(95,176,201,.16);color:var(--accent2)}
|
||
.tag.bad{background:rgba(224,106,106,.16);color:var(--bad)}
|
||
.card{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:16px 20px;margin:14px 0}
|
||
.card h3{margin-top:0;color:var(--accent2)}
|
||
table{width:100%;border-collapse:collapse;margin:16px 0;font-size:14px}
|
||
th,td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--border);vertical-align:top}
|
||
th{color:var(--fg2);font-weight:600;font-size:13px}
|
||
ul,ol{padding-left:22px;margin:8px 0}
|
||
li{margin:5px 0}
|
||
.lead{background:linear-gradient(180deg,rgba(224,136,79,.10),transparent);border:1px solid var(--border);border-radius:12px;padding:18px 20px;margin:0 0 8px}
|
||
.small{color:var(--fg2);font-size:13px}
|
||
a{color:var(--accent2)}
|
||
.back{display:inline-block;margin-bottom:24px;font-size:13px}
|
||
b{color:#fff}
|
||
.phase{font-size:19px;margin:40px 0 6px;color:var(--accent);font-weight:700}
|
||
.diagram{overflow-x:auto;background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:20px;margin:16px 0}
|
||
.diagram svg{display:block;width:100%;height:auto;max-width:820px;margin:0 auto}
|
||
.legend{display:flex;gap:20px;flex-wrap:wrap;font-size:13px;color:var(--fg2);margin-top:12px;justify-content:center}
|
||
.legend span{display:inline-flex;align-items:center;gap:6px}
|
||
.legend i{width:22px;height:0;border-top-width:3px;border-top-style:solid;display:inline-block}
|
||
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:14px 0}
|
||
@media(max-width:680px){.grid2{grid-template-columns:1fr}}
|
||
.rec{border-left:3px solid var(--ok);padding-left:12px}
|
||
.warnbox{background:rgba(224,106,106,.08);border:1px solid rgba(224,106,106,.35);border-radius:12px;padding:14px 18px;margin:14px 0}
|
||
.warnbox b{color:var(--bad)}
|
||
.num{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background:var(--accent);color:#0f1117;font-weight:700;font-size:13px;margin-right:8px;flex-shrink:0}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="wrap">
|
||
<a class="back" href="index.html">← 文档索引</a>
|
||
<h1>Pangolin 支付落地方案</h1>
|
||
<p class="sub">2026-07-08 · <span class="tag info">设计方案</span> · 发卡 / Reseller 收款 + 激活码自动发货(“付完秒发货”体验,收款风险不落在你的主体上)</p>
|
||
|
||
<div class="lead">
|
||
<b>一句话:</b>把「收钱」和「你的品牌 VPN」彻底解耦——<b>收款外包给发卡平台 / Reseller</b>(他们承担支付宝/微信跑分、冻卡、跑路风险),你只做一件事:<b>把一段「激活码」交付出去</b>。所有渠道(发卡法币、USDT、Telegram Stars)进来的钱最后都汇成同一种“货币”——激活码;客户端与用户中心<b>只认码</b>。你们的 <code>codes</code> 激活码模块已实现,支付层只是「入账 → 发码 → 核销」的适配器。
|
||
</div>
|
||
|
||
<h2>为什么是这个形状(约束)</h2>
|
||
<p>上一轮已经确认的硬约束,直接决定方案形状:</p>
|
||
<ul>
|
||
<li><b>中国主体 / 中国支付不能碰</b>:支付宝 / 微信 / 银联 + 岩美(北京)主体卖 VPN → 冻结商户号 + 法律风险。<span class="tag bad">红线</span></li>
|
||
<li><b>灰产 bot 的做法 = 跑分</b>:那些“资源入群助手”用的是<b>四方聚合支付 + 个人账户跑分</b>(帮信罪 / 冻卡 / 平台跑路)。你自己的主体<b>绝不直接接跑分</b>。</li>
|
||
<li><b>能保留“支付宝/微信便利”的唯一干净姿势</b>:把这一环<b>外包</b>——发卡平台/Reseller 用他们的通道收人民币,风险在他们;你拿结算 + 发激活码。或主力走 <b>USDT(你自己钱包,链上干净)</b> + <b>Telegram Stars(TG 官方)</b>。</li>
|
||
</ul>
|
||
|
||
<h2>整体流程图</h2>
|
||
<p>一笔订单从下单到订阅生效的完整流转。<b>橙色 = 钱流,青色 = 码流,绿色虚线 = 结算/对账</b>。收款与跑分风险全部圈在「发卡平台 / Reseller」内,不进入 Pangolin 主体。</p>
|
||
|
||
<div class="diagram">
|
||
<svg viewBox="0 0 820 610" role="img" aria-label="发卡/Reseller 收款 + 激活码自动发货流程图">
|
||
<defs>
|
||
<marker id="ah-money" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 z" fill="#e0884f"/></marker>
|
||
<marker id="ah-code" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 z" fill="#5fb0c9"/></marker>
|
||
<marker id="ah-settle" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 z" fill="#5ec27a"/></marker>
|
||
</defs>
|
||
|
||
<!-- boxes: main column x=70..560 (w=490) -->
|
||
<!-- ① 用户 -->
|
||
<rect x="70" y="24" width="490" height="50" rx="10" fill="#1d2129" stroke="#272c36"/>
|
||
<circle cx="96" cy="49" r="12" fill="#e0884f"/><text x="96" y="53" text-anchor="middle" font-size="13" font-weight="700" fill="#0f1117">1</text>
|
||
<text x="122" y="46" font-size="14" font-weight="700" fill="#e6e8ee">用户 · 在下单页 / 发卡平台选套餐</text>
|
||
<text x="122" y="63" font-size="12" fill="#a8afbd">Pro 月/年、Team……(对应你的定价档)</text>
|
||
|
||
<!-- ② 发卡平台收款 (risk) -->
|
||
<rect x="70" y="118" width="490" height="70" rx="10" fill="#1d2129" stroke="#e06a6a" stroke-width="1.5"/>
|
||
<circle cx="96" cy="143" r="12" fill="#e0884f"/><text x="96" y="147" text-anchor="middle" font-size="13" font-weight="700" fill="#0f1117">2</text>
|
||
<text x="122" y="140" font-size="14" font-weight="700" fill="#e6e8ee">发卡平台 / Reseller · 收款</text>
|
||
<text x="122" y="158" font-size="12" fill="#a8afbd">支付宝/微信(跑分)· USDT · 国际代付 —— 通道与</text>
|
||
<text x="122" y="174" font-size="12" fill="#e06a6a">冻卡/跑路风险都在这一层,不进入 Pangolin 主体</text>
|
||
|
||
<!-- ③ 取激活码 -->
|
||
<rect x="70" y="232" width="490" height="70" rx="10" fill="#1d2129" stroke="#272c36"/>
|
||
<circle cx="96" cy="257" r="12" fill="#e0884f"/><text x="96" y="261" text-anchor="middle" font-size="13" font-weight="700" fill="#0f1117">3</text>
|
||
<text x="122" y="254" font-size="14" font-weight="700" fill="#e6e8ee">取一个激活码</text>
|
||
<text x="122" y="272" font-size="12" fill="#a8afbd">A · 从你预充的「卡密库存」取一张(最松耦合)</text>
|
||
<text x="122" y="288" font-size="12" fill="#a8afbd">B · 支付成功 webhook 调你 API → 实时签发一张</text>
|
||
|
||
<!-- ④ 秒发码 -->
|
||
<rect x="70" y="346" width="490" height="50" rx="10" fill="#1d2129" stroke="#272c36"/>
|
||
<circle cx="96" cy="371" r="12" fill="#5fb0c9"/><text x="96" y="375" text-anchor="middle" font-size="13" font-weight="700" fill="#0f1117">4</text>
|
||
<text x="122" y="368" font-size="14" font-weight="700" fill="#e6e8ee">发卡平台把激活码「秒发」给用户</text>
|
||
<text x="122" y="385" font-size="12" fill="#a8afbd">这就是灰产 bot 的“付完自动发货”体验</text>
|
||
|
||
<!-- ⑤ 兑换 + 核销 -->
|
||
<rect x="70" y="440" width="490" height="70" rx="10" fill="#1d2129" stroke="#5fb0c9" stroke-width="1.5"/>
|
||
<circle cx="96" cy="465" r="12" fill="#5fb0c9"/><text x="96" y="469" text-anchor="middle" font-size="13" font-weight="700" fill="#0f1117">5</text>
|
||
<text x="122" y="462" font-size="14" font-weight="700" fill="#e6e8ee">用户在 Pangolin 客户端/用户中心输码兑换</text>
|
||
<text x="122" y="480" font-size="12" fill="#a8afbd">→ 后端 codes 模块核销(一次性、幂等、防重放)</text>
|
||
<text x="122" y="496" font-size="12" fill="#5ec27a">→ 订阅/时长生效,全端同步</text>
|
||
|
||
<!-- 结算 side box -->
|
||
<rect x="612" y="118" width="180" height="70" rx="10" fill="#141922" stroke="#5ec27a" stroke-dasharray="4 3"/>
|
||
<text x="702" y="143" text-anchor="middle" font-size="13" font-weight="700" fill="#e6e8ee">你 · US LLC</text>
|
||
<text x="702" y="161" text-anchor="middle" font-size="11.5" fill="#a8afbd">定期结算(扣佣)</text>
|
||
<text x="702" y="177" text-anchor="middle" font-size="11.5" fill="#a8afbd">法币 / USDT 到账</text>
|
||
|
||
<!-- arrows down -->
|
||
<line x1="315" y1="74" x2="315" y2="116" stroke="#e0884f" stroke-width="2.5" marker-end="url(#ah-money)"/>
|
||
<text x="325" y="99" font-size="11.5" fill="#e0884f">付款 ¥ / USDT</text>
|
||
<line x1="315" y1="188" x2="315" y2="230" stroke="#e0884f" stroke-width="2.5" marker-end="url(#ah-money)"/>
|
||
<text x="325" y="213" font-size="11.5" fill="#e0884f">订单支付成功</text>
|
||
<line x1="315" y1="302" x2="315" y2="344" stroke="#5fb0c9" stroke-width="2.5" marker-end="url(#ah-code)"/>
|
||
<text x="325" y="327" font-size="11.5" fill="#5fb0c9">交付激活码</text>
|
||
<line x1="315" y1="396" x2="315" y2="438" stroke="#5fb0c9" stroke-width="2.5" marker-end="url(#ah-code)"/>
|
||
<text x="325" y="421" font-size="11.5" fill="#5fb0c9">用户输码</text>
|
||
|
||
<!-- settle dashed arrow from ② to settlement box -->
|
||
<line x1="560" y1="153" x2="610" y2="153" stroke="#5ec27a" stroke-width="2" stroke-dasharray="4 3" marker-end="url(#ah-settle)"/>
|
||
</svg>
|
||
<div class="legend">
|
||
<span><i style="border-color:#e0884f"></i>钱流</span>
|
||
<span><i style="border-color:#5fb0c9"></i>码流(激活码)</span>
|
||
<span><i style="border-color:#5ec27a;border-top-style:dashed"></i>结算 / 对账</span>
|
||
<span><i style="border-color:#e06a6a"></i>风险边界(发卡层内)</span>
|
||
</div>
|
||
</div>
|
||
|
||
<h2>逐环节详解</h2>
|
||
|
||
<div class="card">
|
||
<h3><span class="num">1</span>用户下单</h3>
|
||
<p>入口有三种形态(见后文“落地节奏”):① 你的 Telegram bot 菜单;② 用户中心内“获取激活码”下单页;③ 第三方发卡平台的商品页。用户选套餐档位(Pro 月/年、Team),点支付。</p>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3><span class="num">2</span>发卡平台收款 <span class="tag bad">风险都在这层</span></h3>
|
||
<p>发卡平台/Reseller 用<b>他们自己的通道</b>收人民币(支付宝/微信走跑分)、USDT、国际代付。<b>关键:收款主体、收款码、跑分账户、冻卡与跑路风险,全部是发卡平台的,不是你的。</b>你和 Pangolin 主体永远不出现在这条法币收款链上。你付出的代价是<b>佣金 / 折扣</b>(业界常见 8%–20%,视通道与结算周期)。</p>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3><span class="num">3</span>取激活码(两种对接模型)</h3>
|
||
<p>这是唯一需要你出工程的地方,二选一(下一节详述):</p>
|
||
<ul>
|
||
<li><b>A · 预充卡密库存</b>:你批量生成激活码 → 充值进发卡平台的“卡密库存” → 平台卖一张发一张。你系统<b>零对接</b>,只需生成码 + 补货。</li>
|
||
<li><b>B · API 实时签发</b>:用户支付成功 → 发卡平台 <code>webhook</code> 通知你后端 → 你实时签发一张激活码返回 → 平台转发。库存不积压、可控性强,需对接一个回调接口。</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3><span class="num">4</span>秒发货</h3>
|
||
<p>发卡平台把激活码即时发给用户(页面展示 / bot 消息 / 邮件)。用户体验和那些灰产 bot 的“付完自动发”<b>完全一致</b>——差别只在风险归属。</p>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3><span class="num">5</span>兑换 + 核销</h3>
|
||
<p>用户在 Pangolin 客户端或用户中心输入激活码 → 后端 <code>codes</code> 模块<b>核销</b>:校验有效性、一次性消费(幂等 + 防重放 + 并发锁)、把对应套餐时长写进账户 → 订阅生效、全端同步。这一步你们<b>已经实现</b>,是整套方案的“落地点”。</p>
|
||
</div>
|
||
|
||
<h2>两种对接模型对比</h2>
|
||
<table>
|
||
<thead><tr><th>维度</th><th>A · 预充卡密库存 <span class="tag ok">MVP 首选</span></th><th>B · API 实时签发</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>你要出的工程</td><td>几乎为零:批量生成激活码导出即可</td><td>一个签发回调接口 + 验签 + 幂等</td></tr>
|
||
<tr><td>库存管理</td><td>要盯库存、及时补货(卖光即断供)</td><td>无库存概念,按需签发</td></tr>
|
||
<tr><td>可控性 / 风控</td><td>码一旦充进平台就“出手”了,作废要靠平台配合</td><td>你实时决定发不发、发什么档、可即时止血</td></tr>
|
||
<tr><td>对账</td><td>按“充进多少 / 平台报售出多少”对</td><td>按你签发条数对,最准</td></tr>
|
||
<tr><td>换平台成本</td><td>低(码是通用的,换平台重充即可)</td><td>中(每个平台对接一次回调)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<p class="rec"><b>建议:</b>起步用 <b>A(预充库存)</b>——零工程、当天能卖。跑通量之后,对主力发卡平台升级到 <b>B(API 实时签发)</b>拿回控制权与精准对账;两者可并存(不同渠道用不同模型)。</p>
|
||
|
||
<h2>落地节奏(先能卖,再自动化)</h2>
|
||
|
||
<div class="phase">阶段 0 · MVP(当天可开卖,零/极少开发)</div>
|
||
<ul>
|
||
<li>你们 <code>codes</code> 模块已可批量生成激活码 → 手动生成一批 → 挂到 <b>1 个发卡平台</b>(预充库存模型 A)或直接 Telegram 人工收 USDT/发卡平台链接。</li>
|
||
<li>用户付款 → 平台秒发码 → 用户在客户端兑换。<b>验证需求、跑通话术与定价</b>。</li>
|
||
</ul>
|
||
|
||
<div class="phase">阶段 1 · 半自动(API 实时签发 + 自动对账)</div>
|
||
<ul>
|
||
<li>后端加 <b>发卡回调接口</b> <code>POST /v1/codes/issue</code>(B 模型):验签 → 幂等键(平台订单号)→ 签发激活码返回。</li>
|
||
<li>加<b>对账任务</b>:平台售出流水 ↔ 你签发/核销记录,日结核对,异常告警(防超发/漏发/重放)。</li>
|
||
</ul>
|
||
|
||
<div class="phase">阶段 2 · 自助下单页(可选,长期)</div>
|
||
<ul>
|
||
<li>用户中心 / 官网内做“获取激活码”自助页:接 <b>USDT 自动收款</b>(链上 watcher 到账→签发,你自己钱包,最干净)+ 可选 <b>Telegram Stars</b>。这条不依赖第三方发卡,抽成低、主体干净,但要自己做收款系统。</li>
|
||
<li>发卡/Reseller 继续作为“支付宝/微信便利”的并行兜底渠道。</li>
|
||
</ul>
|
||
|
||
<h2>激活码系统要补的接口(阶段 1)</h2>
|
||
<div class="card">
|
||
<h3>B 模型 · 发卡平台签发回调</h3>
|
||
<pre>POST /v1/codes/issue # 发卡平台在“支付成功”后调用(服务端对服务端)
|
||
headers: X-Reseller-Sign # HMAC 验签(每个 reseller 一个密钥,Bitwarden 存)
|
||
body: {
|
||
reseller_id, reseller_order_no, # 幂等键 = (reseller_id, reseller_order_no)
|
||
sku, # 套餐档位 → 映射时长/等级
|
||
amount, currency
|
||
}
|
||
→ 200 { code: "PGL-XXXX-XXXX-XXXX", expires_at } # 幂等:同一订单号重复调用返回同一张码</pre>
|
||
<p class="small">要点:① <b>幂等</b>——同一 <code>reseller_order_no</code> 只签发一张(防平台重试超发);② <b>验签</b>——HMAC + 时间戳防伪造/重放;③ <b>SKU 映射表</b>——reseller 的商品 ↔ 你的套餐;④ 记录 <code>issued_by=reseller</code> 便于对账与止血作废。</p>
|
||
</div>
|
||
|
||
<h2>对账 · 防滥用 · 风险边界</h2>
|
||
<ul>
|
||
<li><b>对账</b>:每个渠道的“进货/售出”对上“签发/核销”。A 模型对充值批次,B 模型对签发流水。日结 + 异常告警。</li>
|
||
<li><b>防滥用</b>:激活码一次性、绑定套餐、可设过期;核销侧限频;发现某 reseller 泄漏/超卖可<b>整批作废</b>未核销的码。</li>
|
||
<li><b>风险边界(务必守住)</b>:见下。</li>
|
||
</ul>
|
||
<div class="warnbox">
|
||
<b>红线:</b>Pangolin 主体(尤其中国岩美)<b>永不</b>直接对接跑分/四方聚合、永不用中国支付账户收 VPN 款。法币收款的通道与冻卡/跑路风险,<b>只允许存在于发卡平台/Reseller 那一层</b>。你和用户之间流动的只有<b>激活码</b>,钱到你手里时已经是发卡平台的<b>结算款</b>(法币/USDT,走 US LLC)。挑选 reseller 时优先<b>预付结算 / 短结算周期</b>,降低平台跑路敞口。
|
||
</div>
|
||
|
||
<h2>主体与渠道归属</h2>
|
||
<table>
|
||
<thead><tr><th>渠道</th><th>收款主体</th><th>干净度</th><th>定位</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>发卡/Reseller(支付宝/微信)</td><td>发卡平台(非你)</td><td>风险外包,你侧干净</td><td>大陆“便利”主力</td></tr>
|
||
<tr><td>USDT 自动收款</td><td>你 · US LLC 钱包</td><td><span class="tag ok">干净</span></td><td>大陆技术型用户 / 长期主力</td></tr>
|
||
<tr><td>Telegram Stars</td><td>TG 官方 → 你</td><td><span class="tag ok">干净</span></td><td>补充(抽成,走 Apple/Google IAP)</td></tr>
|
||
<tr><td>App Store IAP(海外区)</td><td>Apple → 你</td><td><span class="tag ok">干净</span></td><td>海外华人补充</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<p class="small">加密/结算入账的会计处理归 <code>code/accounting</code> 专门 agent,不在本项目做费用台账。</p>
|
||
|
||
<h2>待定 / 下一步</h2>
|
||
<ul>
|
||
<li>选定 <b>1 个起步发卡平台</b>(先 A 预充库存跑 MVP)——需要你定候选。</li>
|
||
<li>确认 <b>SKU ↔ 套餐</b> 映射与各档定价(对齐 <code>design/CLAUDE.md §7</code> / 官网 Pricing)。</li>
|
||
<li>阶段 1 排期:<code>POST /v1/codes/issue</code> 回调 + 对账任务(落 todo,走 codes 模块)。</li>
|
||
<li>是否并行启动 <b>阶段 2 的 USDT 自动收款</b>(自建下单页),还是先只靠发卡 + 人工。</li>
|
||
</ul>
|
||
|
||
<p class="small" style="margin-top:32px">相关:灰产 bot 收款机制分析(跑分/四方聚合)见对话记录;本方案是其“合规化替身”——同样的“付完秒发货”,风险不落在你的主体上。</p>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|