# xend 在线加密 API

统一入口：`https://xend.xueyuanpie.com/api.php?act=<动作>`
响应：`{"code":"1"|"-1", "info":"<提示>", "data":{...}}`（`code=1` 成功）

鉴权：`x.upload` / `x.submit` / `download` 需要卡密令牌。
先用 `auth.verify` 换取 `token`，随后以 `auth_token` 字段或 `X-Auth-Token` 请求头携带。

---

## auth.verify — 卡密验证

```
POST /api.php?act=auth.verify
card_key=<卡密>
```
```json
{"code":"1","info":"卡密验证成功","data":{
  "token":"eyJjYXJkX2lkIjox...",
  "card_info":{"id":1,"card_key":"Z3YQ…","name":"api-test",
               "max_encrypt_times":10,"used_encrypt_times":1,
               "max_files_per_encrypt":20,"expire_time":"2026-11-12 11:01:09","status":"1"}}}
```

## auth.info — 令牌信息

```
GET /api.php?act=auth.info&auth_token=<token>
```

## x.versions — 引擎能力（公开）

```
GET /api.php?act=x.versions
```
```json
{"code":"1","info":"ok","data":{
  "engine":"xend","version":"1.0.0","mode":"service","available":true,
  "defaults":{"seed":0,"flatten":true,"opaque":true,"trygoto":true,"rename":true,"table_size":16}}}
```
`mode`：`service` = 经本机引擎微服务；`cli` = 直接调用 CLI；`none` = 不可用。

## x.upload — 上传源码

```
POST /api.php?act=x.upload
file=@demo.php            仅允许 .php/.php5/.phtml/.inc/.zip
auth_token=<token>
```
限制：单包 ≤ 5MB；PHP 文件数 ≤ 100（并受卡密 `max_files_per_encrypt` 约束）；文件名不得含中文。

```json
{"code":"1","info":"上传成功","data":{
  "space":"ff58eaa018ec0c4e2815f614ef0d93ba","file":"demo.php",
  "file_count":1,"price":0.1,"balance":100000,"engine":"1.0.0"}}
```

## x.submit — 调用离线引擎加密

```
POST /api.php?act=x.submit
space=<space>
auth_token=<token>
seed=20261013        可选，整数；0 或缺省 = 引擎按时间自取
table_size=16        可选，4-64，每张字符串表条目数
flatten=1            可选，0/false 关闭 L4 控制流扁平化
opaque=1             可选，0/false 关闭 L3 不透明谓词
trygoto=1            可选，0/false 关闭 L5 try/goto 模拟
rename=1             可选，0/false 关闭变量改名
```
```json
{"code":"1","info":"加密完成","data":{
  "space":"ff58…","stats":{"total":1,"encoded":1,"failed":0,"bytes":5622,"ms":11},
  "zip":"ff58….zip","zip_error":null,
  "options":{"seed":20261013,"flatten":true,"opaque":true,"trygoto":true,"rename":true,"table_size":16},
  "detail":[{"file":"demo.php","ok":true,"in":648,"out":5622,"ms":11}]}}
```
产物在写入前会做语法门禁；未通过的文件计入 `failed` 并在 `detail[].error` 给出原因。

## download — 下载产物

```
GET /api.php?act=download&type=xend&space=<space>&auth_token=<token>
```
返回 `application/octet-stream`：多文件为 ZIP，单文件且未打包时直接下发该文件。

---

## 错误码

| code | 含义 |
|---|---|
| `1` | 成功 |
| `-1` | 失败，`info` 为原因（鉴权失败 / 参数缺失 / 超限 / 引擎错误…） |

## 部署说明

| 组件 | 位置 |
|---|---|
| 引擎二进制 | `engine/xend`（动态链接 `engine/libxend.so`） |
| 引擎源码 | `engine/xend.c` `engine/xend.h` `engine/xend_cli.c` `engine/Makefile` |
| 引擎微服务 | `engine/server.php`，systemd 单元 `xend-engine.service`，监听 `127.0.0.1:8791` |
| 站点配置 | `config.php`（可被 `config.local.php` 覆盖） |
| 数据 | `data/xend.sqlite`（卡密/记录）、`data/records.json`（订单）、`data/encoder.log` |
| 后台 | `/jiucheng/`（账号见 `data/admin_initial_password.txt`） |

> PHP-FPM 的 `disable_functions` 在 MINIT 阶段生效，池级 `php_admin_value` 无法放开
> `proc_open`，因此站点侧统一走本机微服务；若环境本身允许 `proc_open`，
> `XendEngine` 会自动退化为直接调用 CLI，无需改配置。
