d256e7ac85
- tokens.css/site.css 逐值对齐原型设计系统,icons 雪碧图,零外链;首页/下载/帮助/法务全站重皮肤,真实截图 - 注册与登录在官网内完成(写 shared_preferences_web 兼容 localStorage,不再跳 App) - 价格区四档:免费/标准 299/高级 599/定制;登录后标准/高级按钮变「购买 / 续费」 - 新增 /checkout/(套餐+月付年付切换)与 /license/result/(支付回跳轮询到账) - 登录页支持 ?next= 站内回跳;二维码措辞改「扫码看详情可分享」 - 下载页构建期真实下载链接+运行时 release 刷新;旧 features 页/死 CSS/dist 产物清理 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
78 lines
2.9 KiB
Plaintext
78 lines
2.9 KiB
Plaintext
---
|
||
layout: base.njk
|
||
title: 支付结果
|
||
description: 支付宝支付完成后的到账确认页。
|
||
permalink: /license/result/
|
||
---
|
||
{# pay 回跳页(return_url,pay 拼 out_trade_no):轮询购买单状态,到账以 webhook 续期为准。 #}
|
||
<div class="container" style="padding:64px 24px 96px">
|
||
<div class="result" id="waiting">
|
||
<div class="ring wait"><svg class="ic"><use href="#i-ic11"/></svg></div>
|
||
<h2>确认到账中…</h2>
|
||
<p>支付完成后到账通常在数秒内确认,请稍候。<br/>本页会自动刷新结果,无需手动操作。</p>
|
||
</div>
|
||
|
||
<div class="result" id="ok" style="display:none">
|
||
<div class="ring good"><svg class="ic"><use href="#i-check"/></svg></div>
|
||
<h2>支付成功,授权已续期</h2>
|
||
<p id="okDetail">门店授权已更新。</p>
|
||
<div class="ono">订单号 <b id="orderNo">—</b></div>
|
||
<div class="acts">
|
||
<a class="btn primary lg" href="/app/">进入系统</a>
|
||
<a class="btn ghost lg" href="/#pricing">返回套餐</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="result" id="slow" style="display:none">
|
||
<div class="ring wait"><svg class="ic"><use href="#i-ic11"/></svg></div>
|
||
<h2>到账确认中</h2>
|
||
<p>付款已提交,但到账确认比平时慢一些。<br/>授权会在到账后自动续期——稍后可在 App「系统设置 → 授权」查看,无需重复付款。</p>
|
||
<div class="acts">
|
||
<a class="btn primary lg" href="/app/">进入系统</a>
|
||
<a class="btn ghost lg" href="mailto:{{ site.support.email }}">联系支持</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
(function () {
|
||
var API = '{{ site.appBaseUrl }}';
|
||
function $(id) { return document.getElementById(id); }
|
||
function token() {
|
||
var raw = localStorage.getItem('flutter.access_token');
|
||
if (!raw) return null;
|
||
try { return JSON.parse(raw); } catch (e) { return raw; }
|
||
}
|
||
var otn = new URLSearchParams(location.search).get('out_trade_no');
|
||
if (!otn || !token()) { $('waiting').style.display = 'none'; $('slow').style.display = 'block'; return; }
|
||
|
||
var tries = 0, maxTries = 30; // 2s × 30 = 60s
|
||
function poll() {
|
||
tries++;
|
||
fetch(API + '/api/v1/license/purchase/' + encodeURIComponent(otn), {
|
||
headers: { 'Authorization': 'Bearer ' + token() },
|
||
})
|
||
.then(function (r) { return r.ok ? r.json() : null; })
|
||
.then(function (j) {
|
||
var d = j && j.data;
|
||
if (d && d.status === 'paid') {
|
||
$('orderNo').textContent = otn;
|
||
if (d.expires_at) {
|
||
$('okDetail').textContent = '门店授权已续期至 ' + new Date(d.expires_at).toLocaleDateString('zh-CN') + '。';
|
||
}
|
||
$('waiting').style.display = 'none';
|
||
$('ok').style.display = 'block';
|
||
return;
|
||
}
|
||
next();
|
||
})
|
||
.catch(next);
|
||
}
|
||
function next() {
|
||
if (tries >= maxTries) { $('waiting').style.display = 'none'; $('slow').style.display = 'block'; return; }
|
||
setTimeout(poll, 2000);
|
||
}
|
||
poll();
|
||
})();
|
||
</script>
|