QUICK START
接入流程
推荐由你的服务端完成签名和下单。浏览器、APP、小程序只接收服务端返回的收银台地址,绝不能持有支付密钥。
- 1获取凭证
复制商户 PID 与支付对接密钥,启用套餐和支付通道。
- 2生成签名
服务端按 ASCII 键名排序,拼接参数与密钥并计算 MD5。
- 3创建订单
跳转
submit.php,或请求mapi.php获取支付链接。 - 4处理回调
验签、核对金额和订单状态,幂等更新后返回纯文本
success。
- 协议:HTTPS
- 编码:UTF-8
- 请求:
application/x-www-form-urlencoded - 金额单位:人民币元
- 签名:MD5(32 位小写)
AUTHENTICATION
商户凭证
pid商户 PID平台分配的对接标识,以后台显示值为准,当前通常为 M 开头。
pay_key支付对接密钥只用于支付签名和回调验签。密钥重置后,旧签名立即失效。
不要写进 HTML、JavaScript、APP 安装包、公开仓库或访问日志;不要将 key 返回给前端。生产环境请通过环境变量或密钥管理服务读取。
SIGNATURE
MD5 签名算法
- 排序
把本次实际发送的全部参数按参数名 ASCII 升序排列。
- 过滤
排除
sign、sign_type、路由参数a/c/m/s以及值为空字符串的参数。 - 拼接
按
key=value用&连接;值保持原样,签名前不要 URL 编码。 - 加密
在参数串末尾直接追加支付对接密钥,计算 32 位小写 MD5。
服务端以 application/x-www-form-urlencoded 解析后的值计算签名。验签前不会执行 HTML 转义、去除首尾空格、大小写转换、金额格式重写、JSON 转义或二次 URL 编解码。notify_url、return_url 可以携带查询参数,其中的原始 & 必须参与签名;不要改成 &。
- 排除
sign、sign_type、a、c、m、s。 - 排除值为''或
null的字段,其他已发送字段全部参与。 - 按参数名升序排列,按
参数名=原始参数值拼接并以&连接。 - 参数串末尾直接追加
pay_key,计算 32 位小写 MD5。 - 客户端必须先计算签名,再用
http_build_query或等价方法编码并发送。
money=0.01&name=测试商品&...&type=alipayYOUR_PAY_KEY末尾密钥前不增加 &key=,而是直接拼接密钥。可选参数只要非空且被发送,就必须参与签名。请求金额用什么字符串签名就发送什么字符串;回调中的 money 固定为两位小数,例如 1.00。
固定签名测试向量
先用下面的假凭证验证你的签名函数。只有得到相同结果,再替换成真实 PID 和密钥发起请求;该测试向量不能用于真实下单。
pay_key = test_pay_key_20260813
pid = M1234567890
type = alipay
out_trade_no = ORDER202608130001
notify_url = https://shop.example.com/pay/notify?channel=alipay&version=2
return_url = https://shop.example.com/pay/return?order=ORDER202608130001&source=pay
name = 测试订单
money = 1.00
expected_sign = beddd35092c3afea54c5218de0872502PAGE PAYMENT
页面跳转支付
https://pay.1kexiu.xyz/submit.php适合网页商城和发卡系统。建议用服务端生成的自动提交表单将用户浏览器跳转到此接口;成功后进入平台收银台,响应是 HTML,不是 JSON。
请求参数
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
pid | 必填 | String | 商户 PID,以后台 API 配置页显示值为准。 |
type | 必填 | String | 支付分类:alipay、wxpay、qqpay;需有对应启用通道。 |
out_trade_no | 必填 | String | 商户订单号,只允许字母、数字及 . _ - |,同一订单请保持唯一。 |
notify_url | 必填 | String | 服务端异步通知地址,必须可被公网访问;允许携带查询参数,原始 & 参与签名。 |
return_url | 必填 | String | 付款后的浏览器跳转地址;允许携带查询参数,不能代替异步通知。 |
name | 必填 | String | 商品或订单标题。 |
money | 必填 | String | 订单金额,单位元,必须大于 0,建议固定两位小数。 |
param | 选填 | String | 业务扩展参数,付款回调时原样返回;不要放敏感信息。 |
sign | 必填 | String | 按本文算法生成的 32 位小写 MD5。 |
sign_type | 必填 | String | 固定为 MD5。 |
<form id="payForm" action="https://pay.1kexiu.xyz/submit.php" method="post">
<input type="hidden" name="pid" value="YOUR_PID">
<input type="hidden" name="type" value="alipay">
<input type="hidden" name="out_trade_no" value="ORDER_202608130001">
<input type="hidden" name="notify_url" value="https://your-site.example/pay/notify">
<input type="hidden" name="return_url" value="https://your-site.example/pay/return">
<input type="hidden" name="name" value="测试商品">
<input type="hidden" name="money" value="0.01">
<input type="hidden" name="sign" value="SERVER_GENERATED_SIGN">
<input type="hidden" name="sign_type" value="MD5">
</form>
<script>document.getElementById('payForm').submit();</script>SERVER_GENERATED_SIGN 只是占位符不能把它原样提交。必须先在你的服务端按本文算法计算真实 sign,再渲染自动提交表单;可直接复用后文 PHP/Node.js/Python 的 makeSign 函数。
API PAYMENT
API 下单
https://pay.1kexiu.xyz/mapi.php适合服务端请求后自行处理支付链接或二维码。请求参数与 页面跳转支付一致,推荐使用 POST 表单编码。
return_url 在新版中必须传旧版文档曾把它标为选填,但新版核心下单服务会校验该字段;缺少时会返回“回调地址(return_url)不能为空”。
兼容参数
| 参数 | 必填 | 说明 |
|---|---|---|
clientip | 选填 | 付款用户 IP,兼容易支付客户端;发送非空值时必须参与签名。 |
device | 选填 | pc、mobile、wechat、alipay 或 qq;发送时参与签名。 |
成功响应
后台“API 返回模式”决定主要字段:payurl 为支付/收银台地址,qrcode 为可生成二维码的内容。接入端应兼容两者,优先处理实际非空字段。
{
"code": 1,
"msg": "下单成功",
"trade_no": "5090058146920009728",
"payurl": "https://pay.1kexiu.xyz/gateway/Submit/pay?trade_no=..."
}{
"code": 1,
"msg": "下单成功",
"trade_no": "5090058146920009728",
"qrcode": "https://qr.alipay.com/..."
}{
"code": -1,
"msg": "签名校验未通过,请检查签名算法、参与签名的参数原文和支付对接密钥(请求编号:xxxxxxxxxxxxxxxx)"
}签名失败时请保留响应中的请求编号,并向技术支持提供 PID、请求时间和脱敏后的参数名称列表。请勿发送支付对接密钥或完整回调 Token。
NOTIFICATION
支付回调
支付成功后,平台会向下单时的 notify_url 发送异步通知,并向 return_url 携带同步跳转参数。为兼容不同通道版本,接收端应同时读取 URL 查询参数和表单参数;只有异步通知可以作为可靠到账依据。
PHP 可使用 array_replace($_GET, $_POST) 合并回调字段,同名字段以 POST 为准。无论参数来自 GET 还是 POST,都必须使用框架解析后的原始字段值验签,不要先做 HTML 转义、trim 或金额格式化。
| 参数 | 类型 | 说明 |
|---|---|---|
pid | String | 商户 PID。 |
trade_no | String | 平台支付订单号。 |
out_trade_no | String | 你的商户订单号。 |
type | String | 支付分类。 |
name | String | 商品名称。 |
money | String | 商户订单金额,固定两位小数,例如 1.00。 |
trade_status | String | 只有精确等于 TRADE_SUCCESS 才表示成功。 |
param | String | 下单扩展参数;下单未传时可能不存在。 |
sign | String | 使用支付对接密钥按相同算法验签。 |
sign_type | String | 固定为 MD5。 |
使用收到的原始参数验签,失败立即拒绝。
核对 PID、订单号、订单金额与本地待支付记录。
以 trade_no 或 out_trade_no 加唯一约束,重复通知不能重复发货。
业务处理成功后返回纯文本小写 success,不要附加 HTML 或 JSON。
return_url 可能被用户关闭、重复访问或伪造。同步页只用于展示结果,必须以已验签的异步通知或主动查单结果更新订单。
<?php
$params = array_replace($_GET, $_POST); // POST 覆盖同名 GET
$clientSign = (string)($params['sign'] ?? '');
if ($clientSign === '' || !hash_equals(makeSign($params, getenv('DUOCAI_PAY_KEY')), $clientSign)) {
http_response_code(400);
exit('fail');
}
if (($params['trade_status'] ?? '') !== 'TRADE_SUCCESS') {
http_response_code(400);
exit('fail');
}
// 接下来必须在事务中:锁定本地订单,核对 pid/out_trade_no/money,
// 仅把“未支付”更新为“已支付”,重复通知直接返回 success,禁止重复发货。
// updateLocalOrderOnce($params);
exit('success');ORDER QUERY
订单查询
https://pay.1kexiu.xyz/api.php查询接口使用 pid 与支付对接密钥 key 鉴权,并只返回该 PID 自己的订单。推荐服务端使用 POST 表单,避免密钥出现在 URL、浏览器历史和代理日志中;GET 仅为兼容旧客户端保留。
act=query&pid=YOUR_PID&key=YOUR_PAY_KEY成功时返回 code=1、开通状态、余额、用户名及套餐支持的支付分类;可用于服务器端连通性检查。
act=order&pid=YOUR_PID&key=YOUR_PAY_KEY&out_trade_no=ORDER_NO可传 out_trade_no(商户订单号)或 trade_no(平台订单号),只会查询当前 PID 的订单。
act=orders&pid=YOUR_PID&key=YOUR_PAY_KEY&limit=20&page=1limit 范围 1–50,page 从 1 开始。不要用高频轮询替代异步回调。
curl --request POST 'https://pay.1kexiu.xyz/api.php' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'act=order' \
--data-urlencode 'pid=YOUR_PID' \
--data-urlencode 'key=YOUR_PAY_KEY' \
--data-urlencode 'out_trade_no=ORDER_NO'单笔订单成功响应示例
{
"code": 1,
"trade_no": "5090058146920009728",
"out_trade_no": "ORDER_202608130001",
"type": "alipay",
"money": "0.01",
"price": "0.01",
"status": 1,
"pay_time": "2026-08-26 12:00:00"
}act=query 的兼容响应包含 key这是为旧协议兼容保留的字段。查询接口只能由你的服务端调用,禁止把完整响应转发给浏览器、APP 或第三方日志平台。
TROUBLESHOOTING
错误处理与重试
接口的业务失败可能仍返回 HTTP 200。mapi.php 和 api.php 必须解析 JSON 并判断 code;submit.php 失败时可能返回带错误说明的 HTML 页面。
签名校验未通过最常见
确认使用支付对接密钥;按 ASCII 排序;空值、sign、sign_type 不参与;所有实际发送的非空参数都参与签名。重点检查回调 URL 中的 & 是否在签名前被错误转成 &,或是否发生 trim、金额格式化及二次 URL 编解码。
商户 PID 或支付对接密钥错误
仅用于 api.php 查单鉴权。确认传的是商户中心“API 配置”中的 PID 和“对接密钥(KEY)”,不是登录密码、软件密钥或下单签名 sign。
回调地址(return_url)不能为空
新版页面支付和 API 下单都需要传 return_url。它与 notify_url 是两个不同地址,且都应使用绝对 HTTPS URL。
当前商户无通道可用
检查套餐是否有效、所选 type 是否存在已启用通道、通道配置是否保存完整,以及通道限额/轮询配置。
商户余额不足无法发起支付
当前套餐存在费率且手续费余额不足。先在商户中心充值手续费余额,再重新发起。
订单号格式不正确 / 此订单已支付成功
out_trade_no 只使用字母、数字及 . _ - |;支付状态不确定时先查单,不要盲目更换订单号再次发货。
- 请求超时或响应无法解析时,保留原
out_trade_no。 - 调用订单查询接口确认是否已建单或已支付。
- 只有确认未支付且业务允许时再重试;回调处理始终保持幂等。
AI ASSISTED INTEGRATION
复制提示词,让 AI 按真实规则接入
把下面整段提示词复制给 ChatGPT、Codex、Claude、Cursor 或其他编程助手。提示词已经写明接口、签名、回调、查单、测试和交付要求,可减少 AI 猜错参数或直接提交占位签名的问题。
OFFICIAL SERVER DEMO
先跑通固定签名,再接进你的项目
一包包含 PHP 8+、Node.js 18+、Python 3.9+ 三套无框架示例,以及下单、查单、回调验签模板和离线签名测试。
2e133f7d2e80469a67830e7118b0d8651b3a76186d2ebffbf7e013a785adb9f8让 AI 使用 DUOCAI_PID 和 DUOCAI_PAY_KEY 环境变量。你只需在自己的服务器配置真实值,提示词和代码仓库中都不要出现明文密钥。
你是一名资深支付接口集成工程师。请在我现有的项目中完成 DuoCai码支付接入,并以 https://pay.1kexiu.xyz/docs/api 为接口规则来源。先只读检查项目已有的订单、支付、回调、数据库和配置实现,优先复用现有结构,禁止重写无关模块、升级框架或修改第三方依赖。
【我的接入目标】
1. 接口域名:https://pay.1kexiu.xyz
2. 商户 PID:从环境变量 DUOCAI_PID 读取。
3. 支付对接密钥:从环境变量 DUOCAI_PAY_KEY 读取。
4. 需要接入的支付分类:alipay、wxpay;如果项目还需要 qqpay,再一并支持。
5. 优先使用服务端 POST /mapi.php 创建订单并获取支付地址;如果现有项目必须让浏览器直接跳转,则使用服务端生成签名后的 POST /submit.php 自动提交表单。
6. 不要要求我把真实 PID 或密钥粘贴到聊天中,不要把密钥写入前端、APP、日志、异常信息或代码仓库。
【必须严格实现的签名规则】
1. 使用 application/x-www-form-urlencoded 解析后的原始字段值。
2. 排除 sign、sign_type、a、c、m、s。
3. 排除值为 null 或空字符串的字段;数字 0 和字符串 0 必须参与签名。
4. 其余实际发送的字段按参数名升序排序。
5. 按 参数名=原始参数值 拼接,字段之间使用 & 连接。
6. 在完整参数串末尾直接追加 DUOCAI_PAY_KEY 的值,不要追加 &key=,然后计算 UTF-8 字节的 32 位小写 MD5。
7. 必须先使用原始值计算签名,再进行表单 URL 编码并发送。
8. 签名前禁止执行 htmlspecialchars、htmlentities、trim、大小写转换、金额格式重写、JSON 转义、URL 重组或二次 urlencode/urldecode。
9. notify_url 和 return_url 可以携带多个查询参数;其中的原始 & 必须参与签名,不能改成 &。
10. 请求中的 money 按实际发送的原始字符串签名;回调中的 money 按平台实际返回值验签,通常为两位小数。
【创建订单】
使用 POST https://pay.1kexiu.xyz/mapi.php,Content-Type 为 application/x-www-form-urlencoded。至少发送:
pid、type、out_trade_no、notify_url、return_url、name、money、sign、sign_type=MD5。
param、clientip、device 等可选字段只要非空并实际发送,就必须参与签名。
return_url 在当前系统中为必填字段。
out_trade_no 必须唯一,只允许字母、数字和 . _ - |。
不要把 SERVER_GENERATED_SIGN 当作真实签名,它只是文档占位符。
接口业务失败可能仍返回 HTTP 200,所以必须解析 JSON 并判断 code。code=1 才表示下单成功。成功响应可能返回 payurl,也可能返回 qrcode;代码要兼容两者,优先使用实际非空字段,并保存平台 trade_no。不要只根据 HTTP 状态码判断成功。
如果使用 /submit.php,它返回 HTML 收银台页面,不是 JSON。签名必须仍在服务端生成,浏览器只能接收已经签好的自动提交表单,不能接触支付密钥。
【异步回调】
1. notify_url 接收端同时兼容 URL 查询参数和 POST 表单;PHP 可用 array_replace($_GET, $_POST),同名字段以 POST 为准,其他语言实现同等逻辑。
2. 使用收到的原始字段重新计算签名,并用安全比较函数核对 sign。
3. 验证 trade_status 必须等于 TRADE_SUCCESS。
4. 按 out_trade_no 查询本地订单,核对 pid、money、订单状态和平台 trade_no。
5. 使用数据库事务、行锁或唯一约束实现幂等:同一订单重复通知不能重复加款、发货或执行权益。
6. 业务处理成功后只返回纯文本 success;失败返回 fail 或非 2xx,不能误返回 success。
7. return_url 只用于浏览器展示,禁止仅凭同步跳转更新付款状态或发货。
【主动查单】
使用服务端 POST https://pay.1kexiu.xyz/api.php,表单参数使用 pid 和 key 鉴权,key 的值来自 DUOCAI_PAY_KEY,不使用下单 sign 代替 key。
单笔查单:act=order,加 out_trade_no 或 trade_no。
订单列表:act=orders,加 page 和 limit,limit 范围 1 至 50。
商户状态:act=query。
解析 JSON 并判断 code;单笔订单的 status=1 才表示支付成功。GET 查询仅为兼容旧客户端,不要在新代码中把密钥放进 URL。
【固定签名测试向量】
先为签名函数编写自动化测试,下面参数必须得到指定 MD5:
pay_key = test_pay_key_20260813
pid = M1234567890
type = alipay
out_trade_no = ORDER202608130001
notify_url = https://shop.example.com/pay/notify?channel=alipay&version=2
return_url = https://shop.example.com/pay/return?order=ORDER202608130001&source=pay
name = 测试订单
money = 1.00
expected_sign = beddd35092c3afea54c5218de0872502
测试还必须覆盖:空字符串、null、数字 0、money 分别为 1/1.0/1.00、中文商品名、空格、+、%、引号,以及 notify_url/return_url 含多个 &。同时验证签名后再做表单编码,确保实际发送字段与参与签名字段完全一致。
【实现与安全要求】
1. 先找到项目已有的订单模型、支付服务、回调路由和配置方式,做最小修改并保持现有代码风格。
2. PID 和密钥只从服务端环境变量或安全配置读取;日志不得记录密钥、完整签名原文或完整回调 Token。
3. 不关闭 TLS 证书验证,不使用浮点数直接比较金额;金额使用 decimal 或整数分,并按业务规则精确比较。
4. 请求超时或响应不确定时保留原 out_trade_no,先查单再决定是否重试,禁止生成新订单号后盲目重复下单。
5. 未经我明确确认,不进行真实付款、退款、发货或生产数据写入测试。可以先做固定向量、Mock 测试和无资金验证。
6. 如果现有项目规则与接口要求冲突,先指出具体文件和冲突原因,再给出保持兼容的最小修复,不要自行猜测。
【完成后请交付】
1. 说明修改了哪些文件、每个文件做了什么。
2. 给出需要配置的环境变量和部署步骤。
3. 给出签名、下单响应、回调幂等和主动查单的自动化测试结果。
4. 明确哪些内容已经实际验证、哪些因为没有真实付款而尚未验证。
5. 提供一个安全的联调检查清单;如果失败,输出脱敏后的参数名称、排序结果和请求编号,但绝不输出真实密钥。
现在请先检查我的项目结构和现有支付实现,然后直接完成最小范围接入。如果你不能直接读取或修改项目,就按我的技术栈输出可复制的完整文件,并明确每个文件的放置路径。CODE EXAMPLES
可直接改造的服务端示例
示例均完成“过滤 → 排序 → 拼接 → MD5”。请把凭证放入环境变量,生产环境不要关闭 TLS 证书校验。
<?php
$apiBase = 'https://pay.1kexiu.xyz';
$payKey = getenv('DUOCAI_PAY_KEY');
function makeSign(array $params, string $key): string {
unset($params['sign'], $params['sign_type'],
$params['a'], $params['c'], $params['m'], $params['s']);
$params = array_filter($params, fn($v) => $v !== '' && $v !== null);
ksort($params, SORT_STRING);
$pairs = [];
foreach ($params as $name => $value) {
$pairs[] = $name . '=' . $value;
}
return md5(implode('&', $pairs) . $key);
}
$params = [
'pid' => getenv('DUOCAI_PID'),
'type' => 'alipay',
'out_trade_no' => 'ORDER_' . date('YmdHis'),
'notify_url' => 'https://shop.example.com/pay/notify?channel=alipay&version=2',
'return_url' => 'https://shop.example.com/pay/return?order=ORDER_202608130001&source=pay',
'name' => '测试商品',
'money' => '0.01',
];
$params['sign'] = makeSign($params, $payKey);
$params['sign_type'] = 'MD5';
$ch = curl_init($apiBase . '/mapi.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
// 先用原始字段值签名,再编码发送;不要先对 URL 做 htmlspecialchars。
CURLOPT_POSTFIELDS => http_build_query($params),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 15,
]);
$result = json_decode(curl_exec($ch), true, 512, JSON_THROW_ON_ERROR);
curl_close($ch);
if (($result['code'] ?? -1) !== 1) {
throw new RuntimeException($result['msg'] ?? '下单失败');
}
// 优先使用实际存在的字段:payurl 或 qrcode
$paymentValue = $result['payurl'] ?? $result['qrcode'] ?? null;import crypto from 'node:crypto';
const apiBase = 'https://pay.1kexiu.xyz';
const payKey = process.env.DUOCAI_PAY_KEY;
function makeSign(params, key) {
const ignored = new Set(['sign', 'sign_type', 'a', 'c', 'm', 's']);
const source = Object.entries(params)
.filter(([name, value]) => !ignored.has(name) && value !== '' && value !== null && value !== undefined)
.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)
.map(([name, value]) => `${name}=${value}`)
.join('&') + key;
return crypto.createHash('md5').update(source, 'utf8').digest('hex');
}
const params = {
pid: process.env.DUOCAI_PID,
type: 'alipay',
out_trade_no: `ORDER_${Date.now()}`,
notify_url: 'https://shop.example.com/pay/notify?channel=alipay&version=2',
return_url: 'https://shop.example.com/pay/return?order=ORDER_202608130001&source=pay',
name: '测试商品',
money: '0.01'
};
params.sign = makeSign(params, payKey);
params.sign_type = 'MD5';
const response = await fetch(`${apiBase}/mapi.php`, {
method: 'POST',
headers: {'content-type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams(params)
});
const result = await response.json();
if (result.code !== 1) throw new Error(result.msg || '下单失败');
const paymentValue = result.payurl ?? result.qrcode;import hashlib
import os
import time
import requests
API_BASE = 'https://pay.1kexiu.xyz'
PAY_KEY = os.environ['DUOCAI_PAY_KEY']
def make_sign(params: dict, key: str) -> str:
ignored = {'sign', 'sign_type', 'a', 'c', 'm', 's'}
pairs = [f'{name}={value}' for name, value in sorted(params.items())
if name not in ignored and value is not None and value != '']
source = '&'.join(pairs) + key
return hashlib.md5(source.encode('utf-8')).hexdigest()
params = {
'pid': os.environ['DUOCAI_PID'],
'type': 'alipay',
'out_trade_no': f'ORDER_{int(time.time() * 1000)}',
'notify_url': 'https://shop.example.com/pay/notify?channel=alipay&version=2',
'return_url': 'https://shop.example.com/pay/return?order=ORDER_202608130001&source=pay',
'name': '测试商品',
'money': '0.01',
}
params['sign'] = make_sign(params, PAY_KEY)
params['sign_type'] = 'MD5'
response = requests.post(f'{API_BASE}/mapi.php', data=params, timeout=15)
response.raise_for_status()
result = response.json()
if result.get('code') != 1:
raise RuntimeError(result.get('msg', '下单失败'))
payment_value = result.get('payurl') or result.get('qrcode')下面的 SERVER_GENERATED_SIGN 必须先由你的 PHP/Node.js/Python 服务端代码计算,不能原样发送。
curl --request POST 'https://pay.1kexiu.xyz/mapi.php' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'pid=YOUR_PID' \
--data-urlencode 'type=alipay' \
--data-urlencode 'out_trade_no=ORDER_202608130001' \
--data-urlencode 'notify_url=https://shop.example.com/pay/notify?channel=alipay&version=2' \
--data-urlencode 'return_url=https://shop.example.com/pay/return?order=ORDER_202608130001&source=pay' \
--data-urlencode 'name=测试商品' \
--data-urlencode 'money=0.01' \
--data-urlencode 'sign=SERVER_GENERATED_SIGN' \
--data-urlencode 'sign_type=MD5'回调验签最小逻辑
params = merge_query_and_form_params(request)
if make_sign(params, PAY_KEY) != params.sign:
return "fail"
if params.trade_status != "TRADE_SUCCESS":
return "fail"
order = find_local_order(params.out_trade_no)
if order is null or order.pid != params.pid or order.money != params.money:
return "fail"
mark_paid_once(order, params.trade_no) // 必须幂等
return "success" // 纯文本GO LIVE