与 payeer 集成的完整 API 参考
每个商户账户在商户设置中都有三个凭证。请在服务器端使用它们——切勿在浏览器或移动客户端代码中使用。
您的商户账户标识符。在创建订单和查询订单时,将其作为 appid 参数发送。
您的秘密签名密钥。不作为请求参数发送。仅在服务器端用于:
一个独立的查询凭证,与您的应用 ID 一起用于通过 GET /api/order 进行只读订单查询。将其作为 key 查询参数与 appid 一起传递。
按照以下步骤接受您的第一笔付款。在使用正式密钥之前,先在沙盒测试环境中使用测试凭据开始。
所有端点都相对于您的网关源地址(此部署:https://payeer.online):
POST https://payeer.online/api/createorder — JSON API(推荐用于服务器端结账)GET …/api/createorder?… — 托管的 HTML 结账页面(最快尝试方式;轮询状态并重定向到 return_url)GET …/api/order — 查询订单状态| 模式 | 使用场景 | 返回内容 |
|---|---|---|
| POST JSON | 在您的网站或应用后端进行生产环境结账 | 包含 redirectUrl / selectUrl 的 JSON — 由您自行重定向付款人 |
| GET 链接 | 快速测试或简单的“立即付款”链接 | HTML 支付页面(二维码、轮询、自动重定向到 return_url) |
notify_url。保存的 URL 用于已支付订单的 Webhook(参见 回调通知)。如果两者都为空,则不发送 Webhook。POST /api/createorder(JSON)或打开 GET /api/createorder(托管页面),并包含 appid、clientip、action=createorder、amount、currency、paymentMethod 和 sign。将 clientip 设置为发起请求的机器的公网 IP(参见 身份验证)。redirectUrl 或 selectUrl(以存在的为准)。selectUrl 表示在支付前需要额外步骤(选择支付方式或加密货币);nextAction 描述了该步骤。如果两者都不存在,则使用此网关上的 /payment/{paymentId}。success 进行响应(参见 回调通知)。return_url 并包含 {paymentId} 占位符(参见
创建订单),例如
https://yoursite.com/success?paymentId={paymentId}。
支付完成后,客户会被重定向到您的页面,并且 {paymentId} 会被替换为真实的订单 ID。
从该 URL 中读取 paymentId 查询参数,然后在您的服务器上调用
查询订单 以同步最新状态,然后再显示成功消息:
GET /api/order?action=order&appid=YOUR_APPID&key=YOUR_KEY&paymentId=PAYMENT_ID_FROM_URL。
使用响应字段 status / status_str 更新您的本地订单。
Webhook 仍然是权威的异步通知;此模式用于在付款人到达您的返回页面时提供即时确认。
在您计算好 sign 后的最小化服务器端流程(参见 签名):
// 1. 创建订单(在您的服务器上运行;替换 YOUR_* 占位符)
const res = await fetch('https://payeer.online/api/createorder', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ appid, clientip, action: 'createorder', amount: 100, currency: 'CNY',
paymentMethod: 'alipay', clientOrderId: 'ORDER-001', return_url, notify_url, sign, sign_type: 'MD5' })
});
const { data } = await res.json();
// 2. 将付款人重定向到结账页面
const checkoutUrl = data.redirectUrl || data.selectUrl || `/payment/${data.paymentId}`;
// response.redirect(checkoutUrl) — 您的框架
// 3. Webhook 处理器(express 示例)
app.post('/api/notify', express.json(), (req, res) => {
const expected = signStr(req.body, process.env.API_KEY); // 与 #signature 相同的算法
if (expected !== req.body.sign) return res.status(400).send('invalid sign');
// 如果 req.body.status_str === 'paid',则更新您的订单
res.status(200).send('success'); // 必须是字符串 "success"
});
请参阅API 凭证获取您的 appid。创建订单请求还需要 clientip — 即发起 HTTP 请求的客户端的公网 IP(通常是您的后端服务器的出口 IP,或者当您通过浏览器代理时,付款方的 IP)。
clientip 必须与请求 IP 一致。 如果两者不一致,/api/createorder 将返回 HTTP 403 错误,并提示 请求 IP 与 clientip 不匹配。在反向代理后面时,请确保您的服务器转发了真实的客户端 IP,并在 clientip 中传递相同的值。
所有创建或修改数据的 API 请求都需要进行签名验证,以确保数据完整性并防止篡改。
签名使用所有请求参数(sign 和 sign_type 除外)以及您的 API 密钥(安全存储在服务器上)计算得出。
sign 和 sign_type 之外的所有参数key=value 对,用 & 连接| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
sign |
字符串 | 必填 | 所有参数的 MD5 签名(使用您的 API 密钥计算) |
sign_type |
字符串 | 可选 | 签名类型,目前仅支持 MD5(默认值:MD5) |
/api/createorder 的扁平化请求字段进行签名(而非嵌套的 JSON 对象)。空字符串包含在内;仅省略 null / undefined 字段。
createorder)给定 API 密钥 42ba8e8f-7cbb-4bf9-ba2a-57904f3d9451 和以下参数(在添加 sign 之前):
签名明文(排序后的 key=value,用 & 连接),然后追加 API 密钥并计算 MD5:
action=createorder&amount=100&appid=YOUR_APPID&clientOrderId=YOUR_ORDER_ID_123&clientip=127.0.0.1¤cy=CNY&description=Test order¬ify_url=https://example.com/api/notify&paymentMethod=alipay&return_url=https://example.com/payment/success?paymentId={paymentId}42ba8e8f-7cbb-4bf9-ba2a-57904f3d9451
sign = 9bb303e3116d862fbeb23bd8a8a8b07d
sign_type 会随请求发送,但不参与签名计算。JSON 中的数字 amount 按原样签名(例如 100,而非 100.00)。
在您的服务器上使用与请求中发送的相同扁平参数计算 sign:
import hashlib
API_KEY = 'YOUR_API_KEY'
def sign_createorder(params: dict) -> str:
filtered = {
k: v for k, v in params.items()
if k not in ('sign', 'sign_type') and v is not None
}
plain = '&'.join(f'{k}={filtered[k]}' for k in sorted(filtered))
return hashlib.md5((plain + API_KEY).encode('utf-8')).hexdigest().lower()
payload = {
'appid': 'YOUR_APPID',
'clientip': '127.0.0.1',
'action': 'createorder',
'amount': 100,
'currency': 'CNY',
'paymentMethod': 'alipay',
'description': 'Test order',
'clientOrderId': 'YOUR_ORDER_ID_123',
'return_url': 'https://example.com/payment/success?paymentId={paymentId}',
'notify_url': 'https://example.com/api/notify',
}
payload['sign'] = sign_createorder(payload)
payload['sign_type'] = 'MD5'
const crypto = require('crypto');
const API_KEY = 'YOUR_API_KEY';
function signCreateorder(params) {
const filtered = {};
for (const [k, v] of Object.entries(params)) {
if (k === 'sign' || k === 'sign_type') continue;
if (v === null || v === undefined) continue;
filtered[k] = v;
}
const plain = Object.keys(filtered).sort()
.map((k) => `${k}=${filtered[k]}`)
.join('&');
return crypto.createHash('md5').update(plain + API_KEY).digest('hex').toLowerCase();
}
const payload = {
appid: 'YOUR_APPID',
clientip: '127.0.0.1',
action: 'createorder',
amount: 100,
currency: 'CNY',
paymentMethod: 'alipay',
description: 'Test order',
clientOrderId: 'YOUR_ORDER_ID_123',
return_url: 'https://example.com/payment/success?paymentId={paymentId}',
notify_url: 'https://example.com/api/notify',
};
payload.sign = signCreateorder(payload);
payload.sign_type = 'MD5';
<?php
$apiKey = 'YOUR_API_KEY';
function sign_createorder(array $params, string $apiKey): string {
unset($params['sign'], $params['sign_type']);
$params = array_filter($params, fn($v) => $v !== null);
ksort($params);
$plain = implode('&', array_map(
fn($k) => $k . '=' . $params[$k],
array_keys($params)
));
return md5($plain . $apiKey);
}
$payload = [
'appid' => 'YOUR_APPID',
'clientip' => '127.0.0.1',
'action' => 'createorder',
'amount' => 100,
'currency' => 'CNY',
'paymentMethod' => 'alipay',
'description' => 'Test order',
'clientOrderId' => 'YOUR_ORDER_ID_123',
'return_url' => 'https://example.com/payment/success?paymentId={paymentId}',
'notify_url' => 'https://example.com/api/notify',
];
$payload['sign'] = sign_createorder($payload, $apiKey);
$payload['sign_type'] = 'MD5';
创建支付订单。响应中包含结账URL(redirectUrl / selectUrl)和/或QR码图片URL,具体取决于支付方式。
发送JSON格式的请求体,设置Content-Type: application/json。返回包含结账URL的JSON数据,供您的服务器重定向付款方。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
appid |
字符串 | 必填 | 您的应用ID |
clientip |
字符串 | 必填 | 您的客户端IP地址 |
action |
字符串 | 必填 | 必须为createorder |
amount |
数字 | 必填 | 订单金额(例如:100.00) |
currency |
字符串 | 必填 | 货币代码:CNY、USD或BDT(使用eps或paystation时需用BDT) |
paymentMethod |
字符串 | 必填 | 支付方式(参见支付方式章节) |
sign |
字符串 | 必填 | MD5签名(参见签名章节) |
sign_type |
字符串 | 可选 | 签名类型(默认值:MD5) |
description |
字符串 | 可选 | 订单描述 |
customerName |
字符串 | 可选 | 客户姓名 |
customerEmail |
字符串 | 可选 | 客户邮箱 |
customerPhone |
字符串 | 可选 | 客户电话号码 |
freekassaSystemId |
整数 | 可选 | 当paymentMethod=freekassa时:FreeKassa支付系统ID(i)。省略以延迟处理:响应中包含selectUrl和nextAction=freekassa_select,供付款方选择方式和FX报价。如果设置,则立即初始化FreeKassa。稍后通过POST /api/freekassa/confirm确认。 |
allowedPaymentMethods |
字符串 | 可选 | 当paymentMethod=select时:逗号分隔的网关代码,显示在付款方选择页面上(例如alipay,wxpay,freekassa)。省略则显示为订单货币和商户账户启用的所有方式。USD订单默认包含balance(已登录客户的账户余额);可通过例如allowedPaymentMethods=alipay,wxpay排除。包含在签名中。 |
lang |
字符串 | 可选 | 付款方选择页面UI的语言区域(例如en、zh、es)。默认值为en。当不是en时,selectUrl使用语言路径前缀(例如/zh/payment/{orderId}?step=select)。提供时包含在签名中。 |
return_url |
字符串 | 可选 | 支付完成后的返回URL(如果提供,将自动重定向)。您可以在URL中使用{paymentId}占位符,重定向时会被自动替换为实际支付ID。示例:https://example.com/success?paymentId={paymentId} |
notify_url |
字符串 | 可选 | 此订单的Webhook URL。如果省略,则使用商户设置中的默认回调URL。 |
clientOrderId |
string | 可选 | 商户自定义订单标识符。保存后会在响应中返回。当订单仍处于 pending(待处理)或 ready(就绪)状态时,若使用相同 clientOrderId 重复发起创建请求,将返回已有订单(幂等操作;可安全刷新 GET 支付链接)。订单进入 paid(已支付)、failed(失败)或 cancelled(已取消)状态后,可使用相同 clientOrderId 创建新订单。 |
clientip 参数必须与实际请求 IP 地址一致,否则请求将被拒绝(403 错误)。return_url 中使用 {paymentId} 占位符。支付完成后重定向时,系统会自动将其替换为实际支付 ID。notify_url 会覆盖系统设置;否则系统设置的默认值将保存在订单中。仅当保存的 URL 非空时才会发送 Webhook。clientOrderId:在订单状态为 pending 或 ready 时,重复 POST 或刷新带有相同 clientOrderId 的 GET 支付 URL 不会创建新订单。
data)| 字段 | 说明 |
|---|---|
paymentId / orderId |
网关订单标识符(两者值相同)。用于查询订单和 return_url 占位符。 |
redirectUrl |
将付款方直接引导至支付页面的 URL(网关页面、外部 PSP 或托管结账页面)。 |
selectUrl |
当付款方需先选择支付方式时出现(paymentMethod=select、延迟的 FreeKassa/NOWPayments)。此情况下通常与 redirectUrl 相同。 |
nextAction |
使用 selectUrl 时的提示信息,例如:payment_method_select、freekassa_select、nowpayments_select。 |
qrImageUrl |
二维码图片 URL(如适用;纯跳转方式可能为 null)。 |
status / statusString |
订单状态——参见订单状态。余额支付可能立即返回 paid(已支付)状态。 |
重定向规则:redirectUrl || selectUrl || /payment/{paymentId}。
sign 和 sign_type 除外)和您的 API 密钥计算。详情请参阅签名部分。
创建新的支付订单并接收 HTML 支付页面。该页面将每 4 秒自动轮询订单状态,3 分钟后超时,并在支付完成时自动重定向到 return_url。
注意:所有参数均作为查询参数(URL 参数)传递。参数与上述 POST 请求相同。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
appid |
字符串 | 必填 | 您的应用程序 ID |
clientip |
字符串 | 必填 | 您的客户端 IP 地址 |
action |
字符串 | 必填 | 必须为 createorder |
amount |
数字 | 必填 | 订单金额(例如 100.00) |
currency |
字符串 | 必填 | 货币代码:CNY、USD 或 BDT(与 eps 或 paystation 一起使用时使用 BDT) |
paymentMethod |
字符串 | 必填 | 支付方式(参见支付方式部分) |
sign |
字符串 | 必填 | MD5 签名(参见签名部分) |
sign_type |
字符串 | 可选 | 签名类型(默认:MD5) |
description |
字符串 | 可选 | 订单描述 |
customerName |
字符串 | 可选 | 客户姓名 |
customerEmail |
字符串 | 可选 | 客户邮箱 |
customerPhone |
字符串 | 可选 | 客户电话号码 |
freekassaSystemId |
整数 | 可选 | 当 paymentMethod=freekassa 时:FreeKassa 支付系统 ID(i)。省略以延迟处理:响应包含 selectUrl 和 nextAction=freekassa_select,供付款人选择方式和 FX 报价。如果设置,则立即初始化 FreeKassa。稍后通过 POST /api/freekassa/confirm 确认。 |
allowedPaymentMethods |
字符串 | 可选 | 当 paymentMethod=select 时:逗号分隔的网关代码,显示在付款人选择页面上(例如 alipay,wxpay,freekassa)。省略以显示为订单货币和商户账户启用的所有方式。USD 订单默认包含 balance(已登录客户账户余额);通过例如 allowedPaymentMethods=alipay,wxpay 排除。包含在签名中。 |
lang |
字符串 | 可选 | 付款人选择页面 UI 的区域设置(例如 en、zh、es)。默认 en。当不是 en 时,selectUrl 使用区域设置路径前缀(例如 /zh/payment/{orderId}?step=select)。 |
return_url
string
可选
支付完成后的返回URL(支付成功后页面将在1秒后自动跳转)。您可以在URL中使用{paymentId}占位符,跳转时系统会自动替换为实际支付ID。示例:https://example.com/success?paymentId={paymentId}
notify_url
string
可选
此订单的Webhook URL。如果省略,则使用商户设置中的默认回调URL。如果两者均为空,则不发送webhook。
clientOrderId
string
可选
客户自己的订单标识符。保存并在响应中返回。当提供此参数时,对于同一商户,如果订单仍处于pending或ready状态,重复的创建请求将返回现有订单(幂等;刷新GET支付链接是安全的)。在订单变为paid、failed或cancelled后,可以使用相同的clientOrderId创建新订单。
GET /api/createorder?appid=YOUR_APPID&clientip=127.0.0.1&action=createorder&amount=100¤cy=CNY&paymentMethod=alipay&description=Test+order&clientOrderId=YOUR_ORDER_ID_123&return_url=https%3A%2F%2Fexample.com%2Fsuccess%3FpaymentId%3D%7BpaymentId%7D¬ify_url=https://example.com/api/notify&sign=CALCULATED_SIGNATURE&sign_type=MD5
clientip参数必须与实际请求IP地址匹配,否则请求将被拒绝(403错误)。return_url中使用{paymentId}占位符。支付完成后跳转时,系统会自动将其替换为实际支付ID。notify_url会覆盖设置;否则,设置的默认值将存储在订单上。clientOrderId:使用相同的clientOrderId刷新此支付URL(或重复请求)时,只要状态为pending或ready,就不会创建新订单。返回一个HTML支付页面,包含:
return_urlreturn_url(延迟1秒后)sign和sign_type除外)和您的API密钥计算签名。详情请参阅签名部分。
查询单个订单详情或列出多个订单。
典型用途:当付款方通过 return_url 返回并携带 paymentId={paymentId} 后,使用解析出的 paymentId 调用此接口,在成功页面上同步订单状态(参见快速集成第7步)。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
appid |
字符串 | 必填 | 您的应用ID |
key |
字符串 | 必填 | 您的密钥(UUID格式) |
action |
字符串 | 必填 | order(单个)或 orders(列表) |
paymentId |
字符串 | 当action=order时必填 | 要查询的支付ID |
page |
数字 | 可选 | 页码(默认:1,仅用于action=orders) |
limit |
数字 | 可选 | 每页条数(最大:50,默认:10,仅用于action=orders) |
GET /api/order?action=order&appid=YOUR_APPID&key=YOUR_KEY&paymentId=abc123def456
当订单状态变为 paid 时,系统将自动向您指定的URL发送回调通知。
notify_url 可覆盖每个订单的webhook URL系统会向您的回调URL发送一个 POST 请求,包含以下参数:
| 参数 | 类型 | 描述 |
|---|---|---|
paymentId |
string | 唯一支付标识符 |
amount |
string | 订单金额(字符串形式,例如 "2.2") |
currency |
string | 货币代码:CNY、USD 或 BDT(使用 eps 或 paystation 时用 BDT) |
status |
string | 订单状态码:"2"(已支付) |
status_str |
string | 订单状态字符串:"paid" |
paymentMethod |
string | 使用的支付方式:alipay、wxpay、crypto、eps 或 paystation |
description |
string | 订单描述(如果提供) |
completedTime |
string | 支付完成时间,ISO 8601 格式(例如 "2025-12-01T02:32:05.877Z") |
createdAt |
string | 订单创建时间,ISO 8601 格式(例如 "2025-12-01T02:31:43.997Z") |
clientOrderId |
string | 客户端订单ID(如果在创建订单时提供) |
sign |
string | 用于验证回调真实性的MD5签名 |
sign_type |
string | 签名类型:MD5 |
您必须验证回调签名以确保请求的真实性。签名使用与API请求相同的算法计算:
sign 和 sign_type 之外的所有参数key=value 对,用 & 分隔sign 参数进行比较您的回调端点必须返回特定响应以确认成功接收:
"success"(不区分大小写)。响应体必须精确为 "success"(例如 "success"、"SUCCESS" 或 "Success")。任何其他响应都将被视为失败并触发重试。"success"(不区分大小写)将触发重试"success"成功响应示例:
"success" ✓"SUCCESS" ✓"Success" ✓失败响应示例(将触发重试):
{"code": 1, "message": "success"} ✗(不是字符串 "success")"ok" ✗(不是 "success")"received" ✗(不是 "success")系统对失败的回调实施自动重试机制:
"success"(不区分大小写)"success"(不区分大小写),将不再针对该订单发送后续回调"success",然后根据需要异步处理订单"success"(不区分大小写)订单具有以下状态值:
| 代码 | 字符串 | 描述 |
|---|---|---|
0 |
pending |
订单已创建,本地保存 |
1 |
ready |
订单已发送至支付提供商,二维码已生成 |
2 |
paid |
支付成功完成 |
3 |
failed |
支付失败 |
4 |
cancelled |
订单已取消 |
支持的支付方式及其货币兼容性:
| 方式 | 代码 | 支持的货币 | 描述 |
|---|---|---|---|
| 支付宝 | alipay |
CNY, USD | 支付宝移动支付 |
| 微信支付 | wxpay |
CNY, USD | 微信移动支付 |
| Heleket(加密货币) | heleket |
USD | 跳转到 Heleket 支付页面。Webhook:POST /api/gatewaynotification/heleket/webhook。 |
| 信用卡/借记卡 | eps |
BDT, USD | 支持信用卡/借记卡支付。 |
| 信用卡/借记卡 | paystation |
BDT, USD | PayStation(孟加拉国):通过 PayStation 结账支持卡和本地支付方式。美元订单按配置的美元→BDT 汇率以 BDT 计费。 |
| FreeKassa | freekassa |
RUB, USD, EUR, UAH, KZT | 两步流程:不带 freekassaSystemId 的 createorder 返回 selectUrl;付款人在网关页面选择方式(如有需要则获取 FX 报价),然后 POST /api/freekassa/confirm。列出 ID:/api/freekassa/currencies。通知:/api/gatewaynotification/freekassa/notify(响应 YES)。 |
| NOWPayments(加密货币) | nowpayments |
USD, EUR, GBP, BRL, NZD | 两步流程:createorder 返回 selectUrl;付款人在网关页面选择加密货币(通过 NOWPayments API 检查最低金额),然后确认创建带有 pay_currency 的发票。IPN:POST /api/gatewaynotification/nowpayments/ipn,需验证 x-nowpayments-sig。 |
| 余额 | balance |
CNY, USD | 从商户账户余额支付。即时结算;无跳转或二维码。响应包含 paidWithBalance: true 和 status=2(已支付)。 |
| 付款人选择(多网关) | select |
CNY, USD, BDT, EUR, GBP, BRL, NZD | 延迟流程:使用 paymentMethod=select 的 createorder 返回 selectUrl 和 nextAction=payment_method_select。可选的 lang(默认 en)设置付款人选择页面的语言和 URL 前缀(例如 /zh/payment/{orderId}?step=select)。付款人看到订单金额和每种方式的最低/最高限额,然后使用 paymentMethod 执行 POST ?step=confirm。美元订单还提供 balance:付款人必须在 /merchant/login 登录;资金从付款人的平台余额中扣除并记入商户。可选的 allowedPaymentMethods 限制列表。FreeKassa / NOWPayments 在确认后仍使用其二级选择页面。 |
alipay、wxpay 和 balancealipay、wxpay、eps、paystation、freekassa、heleket、nowpayments 和 balanceeps 和 paystationfreekassafreekassa 和 nowpaymentsnowpayments常见错误代码及其含义:
| 代码 | 描述 |
|---|---|
| 400 | 错误请求 - 参数无效或业务逻辑错误 |
| 401 | 未授权 - appid 或 apikey 无效 |
| 403 | 禁止访问 — clientip 与请求 IP 不匹配,或商户账户已被禁用 |
| 429 | 请求过多 - 超出速率限制 |
| 500 | 服务器内部错误 - 服务端错误 |