merge: official v1.5.6 with multimodal storyboard enhancements
This commit is contained in:
@@ -3,7 +3,7 @@ set -eu
|
||||
|
||||
root_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
repo_dir=$(CDPATH= cd -- "$root_dir/.." && pwd)
|
||||
payment_plugins="official-payment-wechat-native official-payment-alipay-page official-payment-xunhupay official-payment-zhifufm"
|
||||
payment_plugins="official-payment-wechat-native official-payment-alipay-page official-payment-xunhupay official-payment-zhifufm official-payment-epay"
|
||||
payments_only=false
|
||||
default_payment_targets="linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64"
|
||||
|
||||
@@ -119,6 +119,7 @@ for target in $payment_targets; do
|
||||
build_payment_provider official-payment-alipay-page ./cmd/payment-alipay "$target_goos" "$target_goarch"
|
||||
build_payment_provider official-payment-xunhupay ./cmd/payment-xunhupay "$target_goos" "$target_goarch"
|
||||
build_payment_provider official-payment-zhifufm ./cmd/payment-zhifufm "$target_goos" "$target_goarch"
|
||||
build_payment_provider official-payment-epay ./cmd/payment-epay "$target_goos" "$target_goarch"
|
||||
done
|
||||
|
||||
package_plugin() {
|
||||
|
||||
Binary file not shown.
14
plugin-packages/minimax-hailuo-video-v2/README.md
Normal file
14
plugin-packages/minimax-hailuo-video-v2/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# MiniMax Hailuo Video V2 / H3 协议插件
|
||||
|
||||
该包贡献兼容旧渠道 ID `minimax-video` 的声明式 provider。画布、创作页和短剧生产只提交统一 `GenerationRequest`;插件将图片、视频和音频按显式 role 转成 MiniMax `content[]`。
|
||||
|
||||
重点修复:
|
||||
|
||||
- `resolution` 直接来自统一分辨率,不再遗漏。
|
||||
- 比例写入上游实际使用的 `ratio`;首尾帧模式强制 `adaptive`。
|
||||
- `watermark` 映射为 `aigc_watermark`。
|
||||
- `generateAudio` 映射为 `generate_audio`。
|
||||
- prompt 只放入 text block,不再同时发送顶层 prompt。
|
||||
- 首帧、尾帧和 reference image 依据 role 转换,不按 `0/1` 猜测。
|
||||
|
||||
完整字段见 [docs/interface.md](docs/interface.md)。
|
||||
671
plugin-packages/minimax-hailuo-video-v2/docs/interface.md
Normal file
671
plugin-packages/minimax-hailuo-video-v2/docs/interface.md
Normal file
@@ -0,0 +1,671 @@
|
||||
# MiniMax Hailuo Video V2 / H3 接口字段
|
||||
|
||||
## 入口和生命周期
|
||||
|
||||
- 创建:`POST /v2/video_generation`。
|
||||
- 查询:`GET /v2/query/video_generation/{taskId}`。
|
||||
- 鉴权:`Authorization: Bearer <apiKey>`。
|
||||
- 请求:JSON;结果:异步任务,完成后下载并持久化临时 URL。
|
||||
|
||||
## 请求字段
|
||||
|
||||
| 上游字段 | 类型 | 必填 | 统一来源 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `model` | string | 是 | `request.model` | Hailuo/MiniMax 视频模型 ID。 |
|
||||
| `content` | block[] | 是 | prompt + inputs | 第一个 block 为 text;媒体 block 依次按 order 输出。 |
|
||||
| `content[].type` | enum | 是 | media.kind | `text/image_url/video_url/audio_url`。 |
|
||||
| `content[].text` | string | 文本必填 | `request.prompt` | 不重复发送顶层 prompt。 |
|
||||
| `content[].image_url.url` | string | 图片 block 必填 | `media.value` | 由宿主保证公网 URL。 |
|
||||
| `content[].video_url.url` | string | 视频 block 必填 | `media.value` | 参考视频。 |
|
||||
| `content[].audio_url.url` | string | 音频 block 必填 | `media.value` | 参考音频/声音。 |
|
||||
| `content[].role` | string | 媒体必填 | `media.role` | `first_frame/last_frame/reference_image/reference_video/reference_audio/reference_voice`。 |
|
||||
| `images` | media[] | 否 | image content blocks | 图片按显式 role 与 order 映射,不使用数组下标猜测。 |
|
||||
| `videos` | media[] | 否 | video content blocks | 参考视频按 role 与 order 映射。 |
|
||||
| `audios` | media[] | 否 | audio content blocks | 参考音频或声音按 role 与 order 映射。 |
|
||||
| `duration` | integer | 是 | `request.duration` | 4-15 秒。 |
|
||||
| `resolution` | string | 否 | `request.resolution` | 默认 `768P`;实际枚举按模型 profile。 |
|
||||
| `ratio` | string | 否 | `request.aspectRatio` | 首尾帧模式为 `adaptive`,其余默认 `16:9`。 |
|
||||
| `aigc_watermark` | boolean | 否 | `request.watermark` | 是否带 AIGC 水印。 |
|
||||
| `generate_audio` | boolean | 否 | `request.generateAudio` | 模型支持时生成音频。 |
|
||||
| `seed` | integer | 否 | `providerOptions.minimax-video.seed` | 随机种子。 |
|
||||
| `prompt_optimizer` | boolean | 否 | `providerOptions.minimax-video.prompt_optimizer` | 提示词优化开关。 |
|
||||
|
||||
## 强校验
|
||||
|
||||
- 图片最多 9 张、视频最多 3 个、音频最多 3 个。
|
||||
- 首帧和尾帧各最多 1 张;尾帧不能脱离首帧。
|
||||
- 首尾帧模式不能混入 `reference_image/subject_reference/style_reference`。
|
||||
- duration 超出 4-15 秒直接失败,不静默裁剪。
|
||||
|
||||
## 中转兼容边界
|
||||
|
||||
本插件对应 MiniMax `/v2/video_generation` 原生线协议。NewAPI Channel 1、Channel 2 和自定义 OpenAI Videos 中转必须选择各自独立插件;不能只根据模型名包含 `H3` 自动切协议。
|
||||
|
||||
## 响应映射
|
||||
|
||||
- `task.id` / `task_id` / `id` 映射为统一任务 ID;查询响应缺省时保留已有任务 ID。
|
||||
- `task.status` / `status` 映射为 `pending/processing/succeeded/failed/cancelled`。
|
||||
- `task.content.url` / `content.url` / `video_url` / `file.url` 映射为统一视频结果。
|
||||
- 创建和查询响应优先读取 `task.error.message`,再读取 `task.message` / `base_resp.status_msg` / `message` / `error.message`;具体失败原因通过任务错误返回给用户。
|
||||
- `task.error.code` / `base_resp.status_code` / `error.code` 非成功值均判定为失败,即使响应 HTTP 状态为 200 或未提供任务状态。
|
||||
- 完成后的临时媒体地址由宿主立即下载并持久化。
|
||||
|
||||
例如,参考图片尺寸不符合要求时,上游返回 `task.error.code: "2013"` 和 `task.error.message: "content[1].image_url: media dimensions must be between 256 and 5760 pixels"`。任务应展示这条具体消息;只有上游未提供可读取的错误原因时,才使用通用失败提示。
|
||||
|
||||
<!-- YINGCE_MANIFEST_CONTRACT_START -->
|
||||
## Manifest 完整接口定义
|
||||
|
||||
以下 JSON 与插件包内实际 `manifest.json` 逐字段一致,覆盖插件身份、权限、配置、鉴权、参数、校验、创建、Agent、查询、取消、结果下载、响应和 Agent 响应映射。`documentation` 字段的值就是当前完整文档;为避免文档在自身内部无限递归,JSON 中仅用等义占位文本表示正文。
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "yingce.plugin/v2",
|
||||
"id": "minimax-hailuo-video-v2",
|
||||
"name": "MiniMax Hailuo Video V2 / H3",
|
||||
"version": "2.0.1",
|
||||
"author": "MiniMax / 影策",
|
||||
"description": "MiniMax / Hailuo V2 视频生成协议,保留首帧、尾帧、参考图、视频和音频角色语义。",
|
||||
"documentation": "<当前插件的完整 documentation,由 README.md 与 docs/interface.md 拼接而成;为避免 JSON 递归,此处不重复展开正文。>",
|
||||
"permissions": [
|
||||
"generation.run",
|
||||
"media.read"
|
||||
],
|
||||
"configuration": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "apiKey",
|
||||
"type": "secret",
|
||||
"label": "API Key",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"contributes": {
|
||||
"providers": [
|
||||
{
|
||||
"id": "minimax-video",
|
||||
"label": "MiniMax Hailuo Video V2 / H3",
|
||||
"capabilities": [
|
||||
"video"
|
||||
],
|
||||
"scopes": [
|
||||
"admin.system-channel",
|
||||
"user.custom-channel",
|
||||
"canvas",
|
||||
"creation",
|
||||
"agent"
|
||||
],
|
||||
"baseUrl": "https://api.minimax.io",
|
||||
"requiresPublicMediaUrls": true,
|
||||
"auth": {
|
||||
"type": "bearer",
|
||||
"field": "apiKey"
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "model",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"mapping": "model",
|
||||
"description": "MiniMax/Hailuo 视频模型 ID。"
|
||||
},
|
||||
{
|
||||
"name": "prompt",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"mapping": "content[type=text].text",
|
||||
"description": "仅写入 text content block,避免与顶层 prompt 重复。"
|
||||
},
|
||||
{
|
||||
"name": "images",
|
||||
"type": "media[]",
|
||||
"mapping": "content[type=image_url]",
|
||||
"description": "保留 first_frame、last_frame、reference_image 等 role。"
|
||||
},
|
||||
{
|
||||
"name": "videos",
|
||||
"type": "media[]",
|
||||
"mapping": "content[type=video_url]",
|
||||
"description": "映射为 reference_video。"
|
||||
},
|
||||
{
|
||||
"name": "audios",
|
||||
"type": "media[]",
|
||||
"mapping": "content[type=audio_url]",
|
||||
"description": "映射为 reference_audio/reference_voice。"
|
||||
},
|
||||
{
|
||||
"name": "duration",
|
||||
"type": "integer",
|
||||
"required": true,
|
||||
"values": [
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"15"
|
||||
],
|
||||
"mapping": "duration",
|
||||
"description": "4-15 秒。"
|
||||
},
|
||||
{
|
||||
"name": "resolution",
|
||||
"type": "string",
|
||||
"mapping": "resolution",
|
||||
"description": "如 768P、1080P、2K;按模型能力限制。"
|
||||
},
|
||||
{
|
||||
"name": "aspectRatio",
|
||||
"type": "string",
|
||||
"mapping": "ratio",
|
||||
"description": "首尾帧模式自动使用 adaptive;其他模式使用用户比例。"
|
||||
},
|
||||
{
|
||||
"name": "watermark",
|
||||
"type": "boolean",
|
||||
"mapping": "aigc_watermark",
|
||||
"description": "AIGC 水印。"
|
||||
},
|
||||
{
|
||||
"name": "generateAudio",
|
||||
"type": "boolean",
|
||||
"mapping": "generate_audio",
|
||||
"description": "模型支持时生成音频。"
|
||||
},
|
||||
{
|
||||
"name": "seed",
|
||||
"type": "integer",
|
||||
"mapping": "seed",
|
||||
"description": "providerOptions.minimax-video.seed。"
|
||||
},
|
||||
{
|
||||
"name": "prompt_optimizer",
|
||||
"type": "boolean",
|
||||
"mapping": "prompt_optimizer",
|
||||
"description": "providerOptions.minimax-video.prompt_optimizer。"
|
||||
}
|
||||
],
|
||||
"validations": [
|
||||
{
|
||||
"assert": {
|
||||
"$lte": [
|
||||
{
|
||||
"$len": {
|
||||
"$ref": "request.images"
|
||||
}
|
||||
},
|
||||
9
|
||||
]
|
||||
},
|
||||
"message": "MiniMax H3 最多支持 9 张图片"
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"$lte": [
|
||||
{
|
||||
"$len": {
|
||||
"$ref": "request.videos"
|
||||
}
|
||||
},
|
||||
3
|
||||
]
|
||||
},
|
||||
"message": "MiniMax H3 最多支持 3 个参考视频"
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"$lte": [
|
||||
{
|
||||
"$len": {
|
||||
"$ref": "request.audios"
|
||||
}
|
||||
},
|
||||
3
|
||||
]
|
||||
},
|
||||
"message": "MiniMax H3 最多支持 3 个参考音频"
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"$and": [
|
||||
{
|
||||
"$gte": [
|
||||
{
|
||||
"$ref": "request.duration"
|
||||
},
|
||||
4
|
||||
]
|
||||
},
|
||||
{
|
||||
"$lte": [
|
||||
{
|
||||
"$ref": "request.duration"
|
||||
},
|
||||
15
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"message": "MiniMax H3 duration 必须在 4-15 秒之间"
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"$lte": [
|
||||
{
|
||||
"$len": {
|
||||
"$filter": {
|
||||
"from": {
|
||||
"$ref": "request.images"
|
||||
},
|
||||
"as": "image",
|
||||
"where": {
|
||||
"$eq": [
|
||||
{
|
||||
"$ref": "image.role"
|
||||
},
|
||||
"first_frame"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
1
|
||||
]
|
||||
},
|
||||
"message": "MiniMax H3 最多只能有一个首帧"
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"$lte": [
|
||||
{
|
||||
"$len": {
|
||||
"$filter": {
|
||||
"from": {
|
||||
"$ref": "request.images"
|
||||
},
|
||||
"as": "image",
|
||||
"where": {
|
||||
"$eq": [
|
||||
{
|
||||
"$ref": "image.role"
|
||||
},
|
||||
"last_frame"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
1
|
||||
]
|
||||
},
|
||||
"message": "MiniMax H3 最多只能有一个尾帧"
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"$or": [
|
||||
{
|
||||
"$eq": [
|
||||
{
|
||||
"$len": {
|
||||
"$filter": {
|
||||
"from": {
|
||||
"$ref": "request.images"
|
||||
},
|
||||
"as": "image",
|
||||
"where": {
|
||||
"$eq": [
|
||||
{
|
||||
"$ref": "image.role"
|
||||
},
|
||||
"last_frame"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"$eq": [
|
||||
{
|
||||
"$len": {
|
||||
"$filter": {
|
||||
"from": {
|
||||
"$ref": "request.images"
|
||||
},
|
||||
"as": "image",
|
||||
"where": {
|
||||
"$eq": [
|
||||
{
|
||||
"$ref": "image.role"
|
||||
},
|
||||
"first_frame"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
1
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"message": "MiniMax H3 使用尾帧时必须同时提供首帧"
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"$not": {
|
||||
"$and": [
|
||||
{
|
||||
"$gt": [
|
||||
{
|
||||
"$len": {
|
||||
"$filter": {
|
||||
"from": {
|
||||
"$ref": "request.images"
|
||||
},
|
||||
"as": "image",
|
||||
"where": {
|
||||
"$in": [
|
||||
{
|
||||
"$ref": "image.role"
|
||||
},
|
||||
[
|
||||
"first_frame",
|
||||
"last_frame"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"$gt": [
|
||||
{
|
||||
"$len": {
|
||||
"$filter": {
|
||||
"from": {
|
||||
"$ref": "request.images"
|
||||
},
|
||||
"as": "image",
|
||||
"where": {
|
||||
"$in": [
|
||||
{
|
||||
"$ref": "image.role"
|
||||
},
|
||||
[
|
||||
"reference_image",
|
||||
"subject_reference",
|
||||
"style_reference"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"message": "MiniMax H3 首尾帧模式不能混入普通角色或风格参考图"
|
||||
}
|
||||
],
|
||||
"create": {
|
||||
"method": "POST",
|
||||
"path": "/v2/video_generation",
|
||||
"contentType": "application/json",
|
||||
"body": {
|
||||
"model": {
|
||||
"$ref": "request.model"
|
||||
},
|
||||
"content": {
|
||||
"$concatArrays": [
|
||||
[
|
||||
{
|
||||
"type": "text",
|
||||
"text": {
|
||||
"$ref": "request.prompt"
|
||||
}
|
||||
}
|
||||
],
|
||||
{
|
||||
"$map": {
|
||||
"from": {
|
||||
"$sortByOrder": {
|
||||
"$ref": "request.images"
|
||||
}
|
||||
},
|
||||
"as": "media",
|
||||
"in": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": {
|
||||
"$ref": "media.value"
|
||||
}
|
||||
},
|
||||
"role": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "media.role"
|
||||
},
|
||||
"reference_image"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$map": {
|
||||
"from": {
|
||||
"$sortByOrder": {
|
||||
"$ref": "request.videos"
|
||||
}
|
||||
},
|
||||
"as": "media",
|
||||
"in": {
|
||||
"type": "video_url",
|
||||
"video_url": {
|
||||
"url": {
|
||||
"$ref": "media.value"
|
||||
}
|
||||
},
|
||||
"role": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "media.role"
|
||||
},
|
||||
"reference_video"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$map": {
|
||||
"from": {
|
||||
"$sortByOrder": {
|
||||
"$ref": "request.audios"
|
||||
}
|
||||
},
|
||||
"as": "media",
|
||||
"in": {
|
||||
"type": "audio_url",
|
||||
"audio_url": {
|
||||
"url": {
|
||||
"$ref": "media.value"
|
||||
}
|
||||
},
|
||||
"role": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "media.role"
|
||||
},
|
||||
"reference_audio"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"duration": {
|
||||
"$ref": "request.duration"
|
||||
},
|
||||
"resolution": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "request.resolution"
|
||||
},
|
||||
"768P"
|
||||
]
|
||||
},
|
||||
"ratio": {
|
||||
"$if": {
|
||||
"condition": {
|
||||
"$gt": [
|
||||
{
|
||||
"$len": {
|
||||
"$filter": {
|
||||
"from": {
|
||||
"$ref": "request.images"
|
||||
},
|
||||
"as": "image",
|
||||
"where": {
|
||||
"$in": [
|
||||
{
|
||||
"$ref": "image.role"
|
||||
},
|
||||
[
|
||||
"first_frame",
|
||||
"last_frame"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
0
|
||||
]
|
||||
},
|
||||
"then": "adaptive",
|
||||
"else": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "request.aspectRatio"
|
||||
},
|
||||
"16:9"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"aigc_watermark": {
|
||||
"$ref": "request.watermark"
|
||||
},
|
||||
"generate_audio": {
|
||||
"$ref": "request.generateAudio"
|
||||
},
|
||||
"seed": {
|
||||
"$omitEmpty": {
|
||||
"$ref": "request.providerOptions.minimax-video.seed"
|
||||
}
|
||||
},
|
||||
"prompt_optimizer": {
|
||||
"$omitEmpty": {
|
||||
"$ref": "request.providerOptions.minimax-video.prompt_optimizer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"poll": {
|
||||
"method": "GET",
|
||||
"path": "/v2/query/video_generation/{{taskId}}"
|
||||
},
|
||||
"response": {
|
||||
"taskId": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "response.task.id"
|
||||
},
|
||||
{
|
||||
"$ref": "response.task_id"
|
||||
},
|
||||
{
|
||||
"$ref": "response.id"
|
||||
},
|
||||
{
|
||||
"$ref": "taskId"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "response.task.status"
|
||||
},
|
||||
{
|
||||
"$ref": "response.status"
|
||||
},
|
||||
"pending"
|
||||
]
|
||||
},
|
||||
"message": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "response.task.error.message"
|
||||
},
|
||||
{
|
||||
"$ref": "response.task.message"
|
||||
},
|
||||
{
|
||||
"$ref": "response.base_resp.status_msg"
|
||||
},
|
||||
{
|
||||
"$ref": "response.message"
|
||||
},
|
||||
{
|
||||
"$ref": "response.error.message"
|
||||
}
|
||||
]
|
||||
},
|
||||
"videos": {
|
||||
"$coalesce": [
|
||||
{
|
||||
"$ref": "response.task.content.url"
|
||||
},
|
||||
{
|
||||
"$ref": "response.content.url"
|
||||
},
|
||||
{
|
||||
"$ref": "response.video_url"
|
||||
},
|
||||
{
|
||||
"$ref": "response.file.url"
|
||||
}
|
||||
]
|
||||
},
|
||||
"errorPaths": [
|
||||
"task.error.code",
|
||||
"base_resp.status_code",
|
||||
"error.code"
|
||||
],
|
||||
"resultEphemeral": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
<!-- YINGCE_MANIFEST_CONTRACT_END -->
|
||||
609
plugin-packages/minimax-hailuo-video-v2/manifest.json
Normal file
609
plugin-packages/minimax-hailuo-video-v2/manifest.json
Normal file
File diff suppressed because one or more lines are too long
BIN
plugin-packages/official-payment-epay.yingce-plugin
Normal file
BIN
plugin-packages/official-payment-epay.yingce-plugin
Normal file
Binary file not shown.
3
plugin-packages/official-payment-epay/README.md
Normal file
3
plugin-packages/official-payment-epay/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 易支付
|
||||
|
||||
官方 `yingce.payment/v1` 支付插件。兼容常见易支付网关:V1/MD5 `mapi.php` 与 V2/RSA `/api/pay/create`,支持支付宝/微信/QQ 等通道。协议实现参考 [acg-faka](https://github.com/lizhipay/acg-faka)。
|
||||
4
plugin-packages/official-payment-epay/assets/icon.svg
Normal file
4
plugin-packages/official-payment-epay/assets/icon.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="易支付">
|
||||
<rect width="64" height="64" rx="14" fill="#1677ff"/>
|
||||
<path fill="#fff" d="M19 17h26v7H27v7h15v7H27v9h-8V17Zm22 0h6v30h-6V17Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 235 B |
BIN
plugin-packages/official-payment-epay/backend/provider
Executable file
BIN
plugin-packages/official-payment-epay/backend/provider
Executable file
Binary file not shown.
BIN
plugin-packages/official-payment-epay/backend/provider-darwin-amd64
Executable file
BIN
plugin-packages/official-payment-epay/backend/provider-darwin-amd64
Executable file
Binary file not shown.
BIN
plugin-packages/official-payment-epay/backend/provider-darwin-arm64
Executable file
BIN
plugin-packages/official-payment-epay/backend/provider-darwin-arm64
Executable file
Binary file not shown.
BIN
plugin-packages/official-payment-epay/backend/provider-linux-amd64
Executable file
BIN
plugin-packages/official-payment-epay/backend/provider-linux-amd64
Executable file
Binary file not shown.
BIN
plugin-packages/official-payment-epay/backend/provider-linux-arm64
Executable file
BIN
plugin-packages/official-payment-epay/backend/provider-linux-arm64
Executable file
Binary file not shown.
BIN
plugin-packages/official-payment-epay/backend/provider-windows-amd64.exe
Executable file
BIN
plugin-packages/official-payment-epay/backend/provider-windows-amd64.exe
Executable file
Binary file not shown.
BIN
plugin-packages/official-payment-epay/backend/provider-windows-arm64.exe
Executable file
BIN
plugin-packages/official-payment-epay/backend/provider-windows-arm64.exe
Executable file
Binary file not shown.
155
plugin-packages/official-payment-epay/docs/interface.md
Normal file
155
plugin-packages/official-payment-epay/docs/interface.md
Normal file
@@ -0,0 +1,155 @@
|
||||
## yingce.payment/v1
|
||||
|
||||
支持 `validate_config`、`create_order`、`query_order`、`close_order`、`verify_notification` 和 `download_trade_bill`,统一返回 JSON 响应。
|
||||
|
||||
易支付渠道协议全部封装在本插件内:V1 下单 `POST /mapi.php`(MD5),查单 `GET /api.php?act=order`;V2 下单 `POST /api/pay/create`(RSA,`method=jump`),异步通知为 form/JSON,成功应答 `success`。配置字段包括 `publicBaseUrl`、`pid`、`key`、`gateway`、`payType`、`version`、`checkoutMode`、`privateKey`、`platformPublicKey`。
|
||||
|
||||
必须显式填写可信 `gateway`,不默认向任何第三方网关发送商户信息。V1 查单严格校验商户(响应包含时)、订单号、正数金额、支付状态和成功流水号;不以请求中的订单号或零金额掩盖不完整响应。通知校验拒绝重复参数、无效签名、非正金额及缺失的成功流水号。支付地址只接受 HTTP(S) 与明确允许的微信、支付宝、QQ 支付协议,不接受任意本机协议或含用户名密码的地址。
|
||||
|
||||
V1 关单先查单:已支付订单返回付款凭据,未付款订单只关闭宿主本地记录,不能据此声称上游支付链接已失效。V2 当前仅实现下单和通知验签,未实现查单、刷新收银台和安全关单;`query_order` 返回 `epay_query_unsupported`,`close_order` 返回 `epay_close_unsupported`,不会把未知订单标成已关闭。启用 V2 前需接受这一限制并准备在网关人工核对订单;本次没有新增或猜测 V2 查单接口。交易账单下载返回 not found,不表示已完成对账。
|
||||
|
||||
<!-- YINGCE_MANIFEST_CONTRACT_START -->
|
||||
## Manifest 完整接口定义
|
||||
|
||||
以下 JSON 与插件包内实际 `manifest.json` 逐字段一致,覆盖插件身份、权限、配置、鉴权、参数、校验、创建、Agent、查询、取消、结果下载、响应和 Agent 响应映射。`documentation` 字段的值就是当前完整文档;为避免文档在自身内部无限递归,JSON 中仅用等义占位文本表示正文。
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "yingce.plugin/v1",
|
||||
"id": "official-payment-epay",
|
||||
"name": "易支付",
|
||||
"version": "1.0.9",
|
||||
"author": "Epay",
|
||||
"description": "易支付适配器,支持 V1/MD5 与 V2/RSA 的支付宝/微信/QQ 通道。",
|
||||
"enabled": true,
|
||||
"installable": true,
|
||||
"runtime": {
|
||||
"backend": "rpc",
|
||||
"backendEntry": "backend/provider"
|
||||
},
|
||||
"surfaces": [
|
||||
"wallet",
|
||||
"settings"
|
||||
],
|
||||
"permissions": [
|
||||
"payment.create",
|
||||
"payment.query",
|
||||
"payment.close",
|
||||
"payment.reconcile"
|
||||
],
|
||||
"configuration": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "publicBaseUrl",
|
||||
"type": "url",
|
||||
"label": "服务器公网地址",
|
||||
"required": true,
|
||||
"description": "用于确认回调可达;实际 notify_url 由宿主订单生成。"
|
||||
},
|
||||
{
|
||||
"name": "pid",
|
||||
"type": "string",
|
||||
"label": "商户号 (pid)",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "key",
|
||||
"type": "password",
|
||||
"label": "商户密钥 (key)",
|
||||
"required": false,
|
||||
"secret": true,
|
||||
"description": "V1/MD5 密钥;version=1 可留空。"
|
||||
},
|
||||
{
|
||||
"name": "gateway",
|
||||
"type": "url",
|
||||
"label": "支付网关",
|
||||
"required": true,
|
||||
"description": "显式填写可信易支付网关根地址,不要带 /mapi.php;不会默认向第三方网关发送商户信息。"
|
||||
},
|
||||
{
|
||||
"name": "payType",
|
||||
"type": "string",
|
||||
"label": "默认支付方式",
|
||||
"required": false,
|
||||
"default": "alipay",
|
||||
"values": [
|
||||
"alipay",
|
||||
"wxpay",
|
||||
"qqpay",
|
||||
"usdt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "version",
|
||||
"type": "string",
|
||||
"label": "接口版本",
|
||||
"required": false,
|
||||
"default": "0",
|
||||
"values": [
|
||||
"0",
|
||||
"1"
|
||||
],
|
||||
"description": "0=V1/MD5,1=V2/RSA。V2 仅支持下单和验签通知,暂不支持查单、刷新收银台及自动关单,启用前需确认此限制。"
|
||||
},
|
||||
{
|
||||
"name": "checkoutMode",
|
||||
"type": "string",
|
||||
"label": "收银方式",
|
||||
"required": false,
|
||||
"default": "redirect",
|
||||
"values": [
|
||||
"redirect",
|
||||
"qr_code"
|
||||
],
|
||||
"description": "redirect 跳转;qr_code 展示二维码载荷。"
|
||||
},
|
||||
{
|
||||
"name": "privateKey",
|
||||
"type": "textarea",
|
||||
"label": "V2 商户私钥",
|
||||
"required": false,
|
||||
"secret": true,
|
||||
"description": "仅 version=1,PEM 或裸 Base64。"
|
||||
},
|
||||
{
|
||||
"name": "platformPublicKey",
|
||||
"type": "textarea",
|
||||
"label": "V2 平台公钥",
|
||||
"required": false,
|
||||
"description": "仅 version=1,PEM 或裸 Base64。"
|
||||
}
|
||||
]
|
||||
},
|
||||
"contributes": {
|
||||
"paymentProviders": [
|
||||
{
|
||||
"id": "epay",
|
||||
"label": "易支付",
|
||||
"icon": "assets/icon.svg",
|
||||
"checkoutMode": "redirect",
|
||||
"identityFields": [
|
||||
"pid"
|
||||
],
|
||||
"expiryPolicy": {
|
||||
"defaultMinutes": 10,
|
||||
"minMinutes": 5,
|
||||
"maxMinutes": 1440
|
||||
},
|
||||
"notificationSuccess": {
|
||||
"status": 200,
|
||||
"contentType": "text/plain; charset=utf-8",
|
||||
"body": "success"
|
||||
},
|
||||
"notificationFailure": {
|
||||
"status": 400,
|
||||
"contentType": "text/plain; charset=utf-8",
|
||||
"body": "failure"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "<当前插件的完整 documentation,由 README.md 与 docs/interface.md 拼接而成;为避免 JSON 递归,此处不重复展开正文。>"
|
||||
}
|
||||
```
|
||||
<!-- YINGCE_MANIFEST_CONTRACT_END -->
|
||||
137
plugin-packages/official-payment-epay/manifest.json
Normal file
137
plugin-packages/official-payment-epay/manifest.json
Normal file
File diff suppressed because one or more lines are too long
@@ -118,7 +118,7 @@ if [ "$require_all" = true ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
for package_id in official-payment-wechat-native official-payment-alipay-page official-payment-xunhupay official-payment-zhifufm; do
|
||||
for package_id in official-payment-wechat-native official-payment-alipay-page official-payment-xunhupay official-payment-zhifufm official-payment-epay; do
|
||||
backend_dir="$root_dir/$package_id/backend"
|
||||
provider="$backend_dir/provider"
|
||||
package_file="$root_dir/$package_id.yingce-plugin"
|
||||
|
||||
Reference in New Issue
Block a user