upload+accessKey

This commit is contained in:
ryan
2026-06-07 21:21:06 +08:00
parent 360a26f109
commit 70a13dc107
35 changed files with 4763 additions and 1321 deletions
+205 -526
View File
@@ -1,15 +1,15 @@
import { type PolicySection } from "./types"
import { CodeBlock } from "@/components/ui/code-block"
import {type PolicySection} from "./types"
import {CodeBlock} from "@/components/ui/code-block"
import {
DocsTable,
DocsTableHeader,
DocsTableBody,
DocsTableHead,
DocsTableRow,
DocsTableCell,
DocsTableHead,
DocsTableHeader,
DocsTableRow,
} from "@/components/ui/docs-table"
export const DOCS_LAST_UPDATED = "2026-04-20"
export const DOCS_LAST_UPDATED = "2026-06-07"
/**
* ------------------------------------------------------------------
@@ -18,572 +18,251 @@ export const DOCS_LAST_UPDATED = "2026-04-20"
*/
export const apiSections: PolicySection[] = [
{
value: "official-service",
title: "1. 官方 LDC 接口",
value: "api-specs",
title: "1. 接口规范与鉴权说明",
content: (
<div className="space-y-4 text-sm leading-relaxed">
<div className="bg-muted/50 border border-border/50 rounded-lg px-3 py-2 mb-6">
<p className="text-muted-foreground m-0">官方原生接口,使用 Ed25519 签名算法,安全性更高</p>
<p className="text-muted-foreground m-0">平台统一接口调用格式规范以及开发者访问令牌鉴权方式说明</p>
</div>
<h3 id="1-1-overview" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">1.1 概览</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2">
<li><strong>协议:</strong>官方 LDC 支付协议</li>
<li><strong>服务类型:</strong>支持 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">type=ldcpay</code></li>
<li><strong>网关基址:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">https://credit.linux.do/epay</code></li>
<li><strong>签名方式:</strong>Ed25519 非对称加密</li>
</ul>
<h3 id="1-2-flow" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">1.2 对接流程</h3>
<ol className="list-decimal pl-4 md:pl-5 space-y-2">
<li>控制台创建应用,配置 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">client_id</code> 并在应用设置中上传商户 Ed25519 公钥</li>
<li>根据“签名算法”及商户私钥生成 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">sign</code></li>
<li>调用 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/pay/submit</code> 发起积分流转请求</li>
<li>认证完成后,通过异步回调或轮询接口同步状态</li>
</ol>
<h3 id="1-3-auth-sign" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">1.3 鉴权与签名</h3>
<h4 className="font-medium text-foreground mt-3 md:mt-4 mb-2">1.3.1 签名算法</h4>
<div className="space-y-4">
<ol className="list-decimal pl-4 md:pl-5 space-y-2">
<li>取除 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">sign</code> 以外的所有非空请求参数</li>
<li>将参数按参数名 ASCII 码从到大排序(字典序)</li>
<li>使用 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">k1=v1&k2=v2...</code> 格式拼接成字符串</li>
<li>将 <strong>应用密钥 (Client Secret)</strong> 直接追加到字符串末尾</li>
<li>使用商户私钥对最终字符串进行 <strong>Ed25519</strong> 签名</li>
<li>将签名结果转换成 Base64 编码作为 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">sign</code> 参数</li>
</ol>
<CodeBlock
code={`// 示例:client_id=1&money=10.00&order_name=Test&out_trade_no=M1&type=ldcpay{SECRET}
data = "client_id=1&money=10.00&order_name=Test&out_trade_no=M1&type=ldcpay" + client_secret
signature = ed25519.Sign(privateKey, []byte(data))
signBase64 = base64.StdEncoding.EncodeToString(signature)`}
language="javascript"
/>
</div>
<h3 id="1-4-submit" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">1.4 积分流转服务</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-6">
<li><strong>方法:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/epay/pay/submit.php</code></li>
<li><strong>编码:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">application/json</code> 或 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">application/x-www-form-urlencoded</code></li>
</ul>
<h3 id="1-1-response-format" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-3">1.1 统一响应格式</h3>
<p>系统所有 API 接口均遵循标准 JSON 响应结构:</p>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[100px] whitespace-nowrap">参数</DocsTableHead>
<DocsTableHead className="w-[80px] whitespace-nowrap">必填</DocsTableHead>
<DocsTableHead className="w-[120px]">字段</DocsTableHead>
<DocsTableHead className="w-[100px]">类型</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">client_id</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>应用客户端 ID</DocsTableCell>
<DocsTableCell className="font-mono text-xs">error_msg</DocsTableCell>
<DocsTableCell>string</DocsTableCell>
<DocsTableCell>错误信息。请求成功时为空字符串 `""`,失败时包含错误详情描述。</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">type</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>固定 <code className="bg-muted px-1 rounded text-xs before:content-none after:content-none">ldcpay</code></DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">out_trade_no</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>业务单号</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">money</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>积分数量,必须保留两位小数(比如,10.00)</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">order_name</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>商品名称</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">notify_url</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>会参与签名;可选订单级异步通知地址。长度不超过 100,需为合法 URL。传入后支付成功优先回调该地址,未传则使用应用 notify_url</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">return_url</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>会参与签名;可选订单级回跳地址。长度不超过 100,需为合法 URL。传入后支付成功页面优先跳转该地址,未传则使用应用 redirect_uri</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">sign</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>按“签名算法”生成的 Base64 签名串</DocsTableCell>
<DocsTableCell className="font-mono text-xs">data</DocsTableCell>
<DocsTableCell>any</DocsTableCell>
<DocsTableCell>接口返回的具体数据内容。请求失败或无数据返回时为 `null`。</DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
<h3 id="1-5-others" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">1.5 其他接口</h3>
<p className="text-muted-foreground mb-4">其他接口定义请参考 <a href="#3-common-services" className="text-primary underline underline-offset-4">3. 其他接口</a>。</p>
<ul className="list-disc pl-4 md:pl-5 space-y-2">
<li><strong>订单查询:</strong>详见 <a href="#3-1-order" className="text-primary underline underline-offset-4">3.1 订单查询</a></li>
<li><strong>订单退款:</strong>详见 <a href="#3-2-refund" className="text-primary underline underline-offset-4">3.2 订单退款</a></li>
<li><strong>异步通知:</strong>详见 <a href="#3-3-notify" className="text-primary underline underline-offset-4">3.3 异步通知</a></li>
</ul>
</div>
),
children: [
{ value: "1-1-overview", title: "1.1 概览" },
{ value: "1-2-flow", title: "1.2 对接流程" },
{ value: "1-3-auth-sign", title: "1.3 鉴权与签名" },
{ value: "1-4-submit", title: "1.4 积分流转服务" },
{ value: "1-5-others", title: "1.5 其他接口" },
]
},
{
value: "epay-compatibility",
title: "2. 易支付兼容接口",
content: (
<div className="space-y-4 text-sm leading-relaxed">
<div className="bg-muted/50 border border-border/50 rounded-lg px-3 py-2 mb-6">
<p className="text-muted-foreground m-0">兼容易支付、CodePay、VPay 等支付协议</p>
</div>
<h3 id="2-1-overview" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">2.1 概览</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2">
<li><strong>协议:</strong>EasyPay / CodePay / VPay 兼容协议</li>
<li><strong>服务类型:</strong>仅支持 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">type=epay</code></li>
<li><strong>网关基址:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">https://credit.linux.do/epay</code></li>
<li><strong>订单有效期:</strong>取系统配置 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">order_expire_minutes</code>(平台端设置)</li>
</ul>
<h3 id="2-2-common-errors" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">2.2 常见错误</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2">
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">不支持的请求类型</code>:<code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">type</code> 仅允许 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">epay</code></li>
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">签名验证失败</code>:参与签名字段与请求体需一致,密钥直接拼接</li>
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">金额必须大于0</code> / <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">积分小数位数不能超过2位</code></li>
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">订单已过期</code>:超出系统配置有效期</li>
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">订单不存在或已完成</code>:订单号错误、已退回或已完成</li>
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">余额不足</code>:余额退回时用户积分不足</li>
</ul>
<h3 id="2-3-flow" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">2.3 对接流程</h3>
<ol className="list-decimal pl-4 md:pl-5 space-y-2">
<li>控制台创建 API Key,记录 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">pid</code>、<code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">key</code>,配置回调地址</li>
<li>按“签名算法”生成 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">sign</code>,调用 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/epay/pay/submit.php</code> 创建积分流转服务并跳转认证界面</li>
<li>可通过 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/epay/api.php</code> 轮询结果,或等待异步回调</li>
<li>退回服务时,携带同一 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">trade_no</code> 和原积分数量,调用积分退回接口</li>
<li>回调验签通过后返回 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">success</code> 完成闭环</li>
</ol>
<h3 id="2-4-auth-sign" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">2.4 鉴权与签名</h3>
<h4 className="font-medium text-foreground mt-3 md:mt-4 mb-2">2.4.1 API Key</h4>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-4">
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">pid</code>:Client ID</li>
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">key</code>:Client Secret(妥善保管)</li>
<li><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">notify_url</code> / <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">return_url</code>:应用级默认回调地址(兜底);创建订单时可在请求中传同名字段作为订单级覆盖,未传时回退应用配置。</li>
</ul>
<h4 className="font-medium text-foreground mt-3 md:mt-4 mb-2">2.4.2 签名算法</h4>
<div className="space-y-4">
<ol className="list-decimal pl-4 md:pl-5 space-y-2">
<li>取所有非空字段(排除 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">sign</code>、<code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">sign_type</code> 字段)</li>
<li>将上述字段按 ASCII 升序,依次拼成 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">k1=v1&k2=v2</code></li>
<li>在末尾追加应用密钥:<code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">k1=v1&k2=v2{"{secret}"}</code></li>
<li>整体进行 MD5,取小写十六进制作为 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">sign</code></li>
</ol>
<CodeBlock
code={`payload="money=10&name=Test&out_trade_no=M20250101&pid=001&type=epay"
sign=$(echo -n "\${payload}\${SECRET}" | md5) # 输出小写`}
language="bash"
/>
</div>
<h3 id="2-5-submit" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">2.5 积分流转服务</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-6">
<li><strong>方法:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/epay/pay/submit.php</code></li>
<li><strong>编码:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">application/json</code> 或 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">application/x-www-form-urlencoded</code></li>
<li><strong>成功:</strong>验签通过后,平台自动创建积分流转服务,并跳转到认证界面(Location=<code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">https://credit.linux.do/paying?order_no=...</code>)</li>
<li><strong>失败:</strong>返回 JSON <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">{`{"error_msg":"...", "data":null}`}</code></li>
</ul>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[100px] whitespace-nowrap">参数</DocsTableHead>
<DocsTableHead className="w-[80px] whitespace-nowrap">必填</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">pid</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>Client ID</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">type</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>固定 <code className="bg-muted px-1 rounded text-xs before:content-none after:content-none">epay</code></DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">out_trade_no</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>业务单号,建议全局唯一</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">name</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>标题,最多 64 字符</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">money</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>积分数量,最多 2 位小数</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">notify_url</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>会参与签名;可选订单级异步通知地址。长度不超过 100,需为合法 URL。传入后支付成功优先回调该地址,未传则使用应用 notify_url</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">return_url</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>会参与签名;可选订单级回跳地址。长度不超过 100,需为合法 URL。传入后支付成功页面优先跳转该地址,未传则使用应用 redirect_uri</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">device</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>终端标识,可选</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">sign</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>按“签名算法”生成</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">sign_type</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>固定 <code className="bg-muted px-1 rounded text-xs before:content-none after:content-none">MD5</code></DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
<p className="text-muted-foreground mb-2">请求示例:</p>
<CodeBlock
code={`curl -X POST https://credit.linux.do/epay/pay/submit.php \\
-H "Content-Type: application/x-www-form-urlencoded" \\
-d "pid=001" \\
-d "type=epay" \\
-d "out_trade_no=M20250101" \\
-d "name=Test" \\
-d "money=10" \\
-d "sign=\${SIGN}" \\
-d "sign_type=MD5"`}
language="bash"
/>
<h3 id="2-6-others" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">2.6 其他接口</h3>
<p className="text-muted-foreground mb-4">其他接口定义请参考 <a href="#3-common-services" className="text-primary underline underline-offset-4">3. 其他接口</a>。</p>
<ul className="list-disc pl-4 md:pl-5 space-y-2">
<li><strong>订单查询:</strong>详见 <a href="#3-1-order" className="text-primary underline underline-offset-4">3.1 订单查询</a></li>
<li><strong>订单退款:</strong>详见 <a href="#3-2-refund" className="text-primary underline underline-offset-4">3.2 订单退款</a></li>
<li><strong>异步通知:</strong>详见 <a href="#3-3-notify" className="text-primary underline underline-offset-4">3.3 异步通知</a></li>
</ul>
</div>
),
children: [
{ value: "2-1-overview", title: "2.1 概览" },
{ value: "2-2-common-errors", title: "2.2 常见错误" },
{ value: "2-3-flow", title: "2.3 对接流程" },
{ value: "2-4-auth-sign", title: "2.4 鉴权与签名" },
{ value: "2-5-submit", title: "2.5 积分流转服务" },
{ value: "2-6-others", title: "2.6 其他接口" },
]
},
{
value: "common-services",
title: "3. 其他接口",
content: (
<div className="space-y-4 text-sm leading-relaxed">
<div className="bg-muted/50 border border-border/50 rounded-lg px-3 py-2 mb-6">
<p className="text-muted-foreground m-0">官方接口与易支付兼容接口公用接口。</p>
</div>
<h3 id="3-1-order" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">3.1 订单查询</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-6">
<li><strong>方法:</strong>GET <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/epay/api.php</code></li>
<li><strong>认证:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">pid</code> + <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">key</code></li>
<li><strong>说明:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">out_trade_no</code> 必填;<code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">act</code> 可传 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">order</code>,后端不强校验。</li>
</ul>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[100px] whitespace-nowrap">参数</DocsTableHead>
<DocsTableHead className="w-[80px] whitespace-nowrap">必填</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">act</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>可选字段,建议 <code className="bg-muted px-1 rounded text-xs before:content-none after:content-none">order</code></DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">pid</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>Client ID</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">key</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>Client Secret</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">out_trade_no</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>业务单号</DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
<p className="text-muted-foreground mb-2">成功响应:</p>
<CodeBlock
code={`{
"code": 1,
"msg": "查询订单号成功!",
"trade_no": "M20250101",
"out_trade_no": "M20250101",
"type": "epay",
"pid": "001",
"addtime": "2025-01-01 12:00:00",
"endtime": "2025-01-01 12:01:30",
"name": "Test",
"money": "10",
"status": 1
}`}
language="json"
/>
<p className="text-muted-foreground text-xs"><strong className="text-foreground">补充:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">status</code> 1=成功,0=失败/处理中;不存在会返回 HTTP 404 且 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">{`{"code":-1,"msg":"服务不存在或已完成"}`}</code>。</p>
<h3 id="3-2-refund" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">3.2 订单退款</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-6">
<li><strong>方法:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/epay/api.php</code></li>
<li><strong>编码:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">application/json</code> 或 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">application/x-www-form-urlencoded</code></li>
<li><strong>限制:</strong>仅支持对已成功的积分流转服务进行积分的全额退回</li>
</ul>
<div>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[100px] whitespace-nowrap">参数</DocsTableHead>
<DocsTableHead className="w-[80px] whitespace-nowrap">必填</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">pid</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>Client ID</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">key</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>Client Secret</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">trade_no</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>编号</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">money</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>必须等于原积分流转服务的积分数量</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">out_trade_no</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>业务单号(兼容)</DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
</div>
<p className="text-muted-foreground mb-2">响应:</p>
<CodeBlock code={`{ "code": 1, "msg": "退款成功" }`} language="json" />
<p className="text-muted-foreground text-xs"><strong className="text-foreground">常见失败:</strong>服务不存在/未认证、金额不合法(&lt;=0 或小数超过 2 位)。</p>
<h3 id="3-3-notify" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">3.3 异步通知</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-6">
<li><strong>触发:</strong>认证成功后;失败自动重试,最多 5 次(单次 30s 超时)</li>
<li><strong>目标:</strong>订单级 notify_url(如有)优先,否则回退到创建应用时设置的 notify_url</li>
<li><strong>方式:</strong>HTTP GET</li>
</ul>
<div>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[100px] whitespace-nowrap">参数</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">pid</DocsTableCell>
<DocsTableCell>Client ID</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">trade_no</DocsTableCell>
<DocsTableCell>编号</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">out_trade_no</DocsTableCell>
<DocsTableCell>业务单号</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">type</DocsTableCell>
<DocsTableCell>固定 <code className="bg-muted px-1 rounded text-xs before:content-none after:content-none">epay</code></DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">name</DocsTableCell>
<DocsTableCell>标题</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">money</DocsTableCell>
<DocsTableCell>积分数量,最多 2 位小数</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">trade_status</DocsTableCell>
<DocsTableCell>固定 <code className="bg-muted px-1 rounded text-xs before:content-none after:content-none">TRADE_SUCCESS</code></DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">sign</DocsTableCell>
<DocsTableCell>按“签名算法”生成</DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
</div>
<p className="text-muted-foreground text-xs">应用需返回 HTTP 200 且响应体为 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">success</code>(大小写不敏感),否则视为失败并继续重试。</p>
<h3 id="3-4-distribute" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">3.4 商户分发接口</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-6">
<li><strong>方法:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/lpay/distribute</code></li>
<li><strong>编码:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">application/json</code></li>
<li><strong>认证:</strong>Basic Auth (使用 <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">client_id:client_secret</code> 进行 Base64 编码)</li>
</ul>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[100px] whitespace-nowrap">参数</DocsTableHead>
<DocsTableHead className="w-[80px] whitespace-nowrap">必填</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">user_id</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>收款人用户 ID (数字)</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">username</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>收款人用户名 (用于二次校验)</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">amount</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>分发积分数量,最多 2 位小数</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">out_trade_no</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>商户自定义单号</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">remark</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>分发备注</DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
<p className="text-muted-foreground text-xs"><strong className="text-foreground">成功响应:</strong><code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">{`{"code":1, "data":{"trade_no":"...", "out_trade_no":"..."}}`}</code></p>
<h3 id="3-5-user-balance" className="text-base md:text-lg font-semibold text-foreground mt-6 md:mt-8 mb-3 md:mb-4">3.5 用户余额统计</h3>
<ul className="list-disc pl-4 md:pl-5 space-y-2 mb-6">
<li><strong>方法:</strong>GET <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono before:content-none after:content-none">/api/v1/dashboard/stats/user-balance</code></li>
<li><strong>认证:</strong>无需鉴权(公开接口)</li>
<li><strong>说明:</strong>获取平台所有用户可用余额的统计数据,结果有缓存,TTL 由系统配置决定</li>
</ul>
<p className="text-muted-foreground mb-2">成功响应:</p>
<p className="mt-2">成功响应示例:</p>
<CodeBlock
code={`{
"error_msg": "",
"data": {
"total_count": 1234,
"total_amount": "98765.00",
"avg_amount": "80.03",
"median_amount": "50.00",
"min_amount": "0.00",
"max_amount": "9999.00",
"std_dev": "123.45"
"id": 1,
"username": "ryan",
"nickname": "Ryan"
}
}`}
language="json"
/>
<p className="mt-2">失败响应示例:</p>
<CodeBlock
code={`{
"error_msg": "用户密码错误",
"data": null
}`}
language="json"
/>
<h3 id="1-2-authentication" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-3">1.2 鉴权方式</h3>
<p>除了公共公开接口(如登录、注册、配置)外,受保护的接口需要携带凭证才能正常访问:</p>
<ul className="list-disc pl-5 space-y-2">
<li><strong>Session 凭证:</strong>浏览器环境下支持利用常规 Session Cookie 会话保持登录。</li>
<li><strong>AccessToken 令牌:</strong>供后台调用或第三方应用集成使用。客户端生成 API 访问令牌后,需要在请求头(Request Header)中携带以进行身份校验。</li>
</ul>
<div className="bg-muted border rounded-xl p-4 mt-2 space-y-2">
<p className="font-bold text-xs">支持携带令牌的请求头格式(二选一):</p>
<ul className="list-disc pl-5 text-xs text-muted-foreground space-y-1">
<li><code className="bg-muted-foreground/10 px-1 rounded text-[11px] font-mono">Authorization: Bearer at_xxx</code></li>
<li><code className="bg-muted-foreground/10 px-1 rounded text-[11px] font-mono">X-Access-Token: at_xxx</code></li>
</ul>
</div>
</div>
),
children: [
{ value: "1-1-response-format", title: "1.1 统一响应格式" },
{ value: "1-2-authentication", title: "1.2 鉴权方式" },
]
},
{
value: "auth-apis",
title: "2. 用户与认证接口",
content: (
<div className="space-y-4 text-sm leading-relaxed">
<h3 id="2-1-register" className="text-base md:text-lg font-semibold text-foreground mt-4 mb-2">2.1 用户注册</h3>
<p><strong>接口:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/register</code></p>
<p><strong>说明:</strong>注册本地账户(在后台注册开关开启状态下)。</p>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[120px] whitespace-nowrap">字段</DocsTableHead>
<DocsTableHead className="w-[120px]">参数</DocsTableHead>
<DocsTableHead className="w-[80px]">必填</DocsTableHead>
<DocsTableHead>类型</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">total_count</DocsTableCell>
<DocsTableCell>统计用户总数</DocsTableCell>
<DocsTableCell className="font-mono text-xs">username</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>string</DocsTableCell>
<DocsTableCell>用户名,必须唯一且无空格。</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">total_amount</DocsTableCell>
<DocsTableCell>所有用户可用余额之和</DocsTableCell>
<DocsTableCell className="font-mono text-xs">password</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>string</DocsTableCell>
<DocsTableCell>密码,长度必须大于等于 8 位。</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">avg_amount</DocsTableCell>
<DocsTableCell>平均余额</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">median_amount</DocsTableCell>
<DocsTableCell>余额中位数</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">min_amount</DocsTableCell>
<DocsTableCell>最小余额</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">max_amount</DocsTableCell>
<DocsTableCell>最大余额</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">std_dev</DocsTableCell>
<DocsTableCell>余额标准差</DocsTableCell>
<DocsTableCell className="font-mono text-xs">nickname</DocsTableCell>
<DocsTableCell>否</DocsTableCell>
<DocsTableCell>string</DocsTableCell>
<DocsTableCell>昵称。未传时默认与用户名一致。</DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
<h3 id="2-2-login" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-2">2.2 密码登录</h3>
<p><strong>接口:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/login</code></p>
<p><strong>说明:</strong>通过常规用户名密码进行登录校验,成功后建立 Session Cookie 会话。</p>
<DocsTable>
<DocsTableHeader>
<DocsTableRow>
<DocsTableHead className="w-[120px]">参数</DocsTableHead>
<DocsTableHead className="w-[80px]">必填</DocsTableHead>
<DocsTableHead>类型</DocsTableHead>
<DocsTableHead>说明</DocsTableHead>
</DocsTableRow>
</DocsTableHeader>
<DocsTableBody>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">username</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>string</DocsTableCell>
<DocsTableCell>用户名</DocsTableCell>
</DocsTableRow>
<DocsTableRow>
<DocsTableCell className="font-mono text-xs">password</DocsTableCell>
<DocsTableCell>是</DocsTableCell>
<DocsTableCell>string</DocsTableCell>
<DocsTableCell>密码</DocsTableCell>
</DocsTableRow>
</DocsTableBody>
</DocsTable>
<h3 id="2-3-logout" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-2">2.3 退出登录</h3>
<p><strong>接口:</strong>GET <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/logout</code></p>
<p><strong>说明:</strong>销毁当前会话 Cookie 并退出登录状态。</p>
<h3 id="2-4-profile" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-2">2.4 获取个人资料</h3>
<p><strong>接口:</strong>GET <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/self</code></p>
<p><strong>说明:</strong>获取当前登录账户的基本数据模型(包含 ID、角色、昵称等)。</p>
</div>
),
children: [
{ value: "3-1-order", title: "3.1 订单查询" },
{ value: "3-2-refund", title: "3.2 订单退款" },
{ value: "3-3-notify", title: "3.3 异步通知" },
{ value: "3-4-distribute", title: "3.4 商户分发接口" },
{ value: "3-5-user-balance", title: "3.5 用户余额统计" },
{ value: "2-1-register", title: "2.1 用户注册" },
{ value: "2-2-login", title: "2.2 密码登录" },
{ value: "2-3-logout", title: "2.3 退出登录" },
{ value: "2-4-profile", title: "2.4 获取个人资料" },
]
},
{
value: "token-apis",
title: "3. 个人访问令牌 (AccessToken) 接口",
content: (
<div className="space-y-4 text-sm leading-relaxed">
<div className="bg-muted/50 border border-border/50 rounded-lg px-3 py-2 mb-4">
<p className="text-muted-foreground m-0">AccessToken 管理相关接口均要求通过 Session 登录后调用,支持普通用户权限。</p>
</div>
<h3 id="3-1-list-token" className="text-base md:text-lg font-semibold text-foreground mt-4 mb-2">3.1 获取令牌列表</h3>
<p><strong>接口:</strong>GET <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/access-tokens</code></p>
<p><strong>说明:</strong>查询当前用户已创建的所有令牌详情(令牌明文已被脱敏)。</p>
<h3 id="3-2-create-token" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-2">3.2 新建访问令牌</h3>
<p><strong>接口:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/access-tokens</code></p>
<p><strong>参数:</strong>JSON Body <code className="bg-muted px-1.5 rounded text-xs font-mono">{`{"name": "token名称"}`}</code></p>
<p><strong>说明:</strong>生成一个全新访问令牌。返回体中包含一次性明文 Token,切勿遗失。</p>
<p className="mt-2">成功返回样例:</p>
<CodeBlock
code={`{
"error_msg": "",
"data": {
"token": "at_628d022b7a95e26bcd8b29c9...",
"record": {
"id": 5,
"user_id": 1,
"name": "my-dev-key",
"masked_token": "at_628d...29c9",
"last_used_at": null,
"created_at": "2026-06-07T21:30:00+08:00"
}
}
}`}
language="json"
/>
<h3 id="3-3-delete-token" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-2">3.3 撤销/删除令牌</h3>
<p><strong>接口:</strong>DELETE <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/access-tokens/:id</code></p>
<p><strong>说明:</strong>通过 ID 物理删除对应访问令牌,该令牌将立即失效。</p>
<h3 id="3-4-rotate-token" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-2">3.4 轮换令牌密钥</h3>
<p><strong>接口:</strong>POST <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/user/access-tokens/:id/rotate</code></p>
<p><strong>说明:</strong>轮换指定令牌的物理密钥值。系统将废弃原有密钥,返回新生成的明文 Token,并将 `last_used_at` 置空,令牌名称与 ID 保持一致。</p>
</div>
),
children: [
{ value: "3-1-list-token", title: "3.1 获取令牌列表" },
{ value: "3-2-create-token", title: "3.2 新建访问令牌" },
{ value: "3-3-delete-token", title: "3.3 撤销/删除令牌" },
{ value: "3-4-rotate-token", title: "3.4 轮换令牌密钥" },
]
},
{
value: "config-apis",
title: "4. 公共配置与管理接口",
content: (
<div className="space-y-4 text-sm leading-relaxed">
<h3 id="4-1-public-config" className="text-base md:text-lg font-semibold text-foreground mt-4 mb-2">4.1 公共系统配置</h3>
<p><strong>接口:</strong>GET <code className="bg-muted px-1.5 py-0.5 rounded text-xs font-mono">/api/v1/config/public</code></p>
<p><strong>说明:</strong>无感获取当前系统的公开业务设置(如注册是否开启、密码登录是否开启)。供前端页面动态渲染使用。</p>
<p className="mt-2">返回数据结构样例:</p>
<CodeBlock
code={`{
"error_msg": "",
"data": {
"site_name": "Antigravity Project",
"registration_enabled": true,
"password_login_enabled": true,
"password_register_enabled": true,
"oidc_login_enabled": true
}
}`}
language="json"
/>
<h3 id="4-2-admin-configs" className="text-base md:text-lg font-semibold text-foreground mt-6 mb-2">4.2 系统配置项 CRUD (管理员)</h3>
<p><strong>说明:</strong>用于在后台对 `system_configs` 配置进行动态变更,要求管理员权限会话调用。</p>
<ul className="list-disc pl-5 space-y-2">
<li><strong>获取配置列表:</strong>GET <code className="bg-muted px-1 rounded text-xs font-mono">/api/v1/admin/system-configs?type=system</code></li>
<li><strong>新建配置项:</strong>POST <code className="bg-muted px-1 rounded text-xs font-mono">/api/v1/admin/system-configs</code></li>
<li><strong>修改指定配置值:</strong>PUT <code className="bg-muted px-1 rounded text-xs font-mono">/api/v1/admin/system-configs/:key</code></li>
<li><strong>删除配置项:</strong>DELETE <code className="bg-muted px-1 rounded text-xs font-mono">/api/v1/admin/system-configs/:key</code></li>
</ul>
</div>
),
children: [
{ value: "4-1-public-config", title: "4.1 公共系统配置" },
{ value: "4-2-admin-configs", title: "4.2 系统配置项 CRUD (管理员)" },
]
}
]