与 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)和/或二维码图片 URL。
发送一个 JSON 请求体,Content-Type 为 application/json。返回包含结账 URL 的 JSON,供您的服务端重定向付款方。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
appid |
string | 必填 | 您的应用 ID |
clientip |
string | 必填 | 您的客户端 IP 地址 |
action |
string | 必填 | 必须为 createorder |
amount |
number | 必填 | 订单金额(例如 100.00) |
currency |
string | 必填 | 货币代码:CNY、USD 或 BDT(BDT 需配合 eps、paystation 或 aamarpay 使用) |
paymentMethod |
string | 必填 | 支付方式(参见“支付方式”部分) |
sign |
string | 必填 | MD5 签名(参见“签名”部分) |
sign_type |
string | 可选 | 签名类型(默认:MD5) |
description |
string | 可选 | 订单描述 |
customerName |
string | 可选 | 客户姓名 |
customerEmail |
string | 可选 | 客户邮箱 |
customerPhone |
string | 可选 | 客户手机号 |
freekassaSystemId |
integer | 可选 | 当 paymentMethod=freekassa 时:FreeKassa 支付系统 ID(i)。省略 则延迟初始化:响应中会包含 selectUrl 和 nextAction=freekassa_select,供付款方选择方式并获取 FX 报价。如已设置,则立即初始化 FreeKassa。后续需通过 POST /api/freekassa/confirm 确认。 |
allowedPaymentMethods |
string | 可选 | 当 paymentMethod=select 时:以逗号分隔的网关代码,显示在付款方选择页面上(例如 alipay,wxpay,freekassa)。省略则显示该订单货币和商户账户下所有已启用的方式。USD 订单默认包含 balance(已登录客户的账户余额);如需排除,可设置 allowedPaymentMethods=alipay,wxpay。此参数参与签名。 |
lang |
string | 可选 | 付款方选择页面 UI 的语言(例如 en、zh、es)。默认 en。当不为 en 时,selectUrl 会使用语言路径前缀(例如 /zh/payment/{orderId}?step=select)。提供时参与签名。 |
return_url |
string | 可选 | 支付完成后的返回 URL(如果提供,将自动重定向)。您可以在 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 创建新订单。 |
clientip 参数必须与实际请求 IP 一致,否则请求会被拒绝(403 错误)。return_url 中使用 {paymentId} 占位符。支付完成重定向时,系统会自动将其替换为实际的支付 ID。notify_url 会覆盖设置中的默认值;否则订单会沿用设置中的默认值。仅当保存的 URL 非空时才会发送 webhook。clientOrderId:在订单状态为 pending 或 ready 时,重复 POST 或刷新 GET 支付 URL(使用相同 clientOrderId)不会创建新订单。
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 |
string | 必填 | 您的应用ID |
clientip |
string | 必填 | 您的客户端IP地址 |
action |
string | 必填 | 必须为 createorder |
amount |
number | 必填 | 订单金额(例如:100.00) |
currency |
string | 必填 | 货币代码:CNY、USD 或 BDT(BDT 需配合 eps、paystation 或 aamarpay 使用) |
paymentMethod |
string | 必填 | 支付方式(见支付方式章节) |
sign |
string | 必填 | MD5签名(见签名章节) |
sign_type |
string | 可选 | 签名类型(默认:MD5) |
description |
string | 可选 | 订单描述 |
customerName |
string | 可选 | 客户姓名 |
customerEmail |
string | 可选 | 客户邮箱 |
customerPhone |
string | 可选 | 客户电话号码 |
freekassaSystemId |
integer | 可选 | 当 paymentMethod=freekassa 时:FreeKassa 支付系统 ID(i)。省略则延迟处理:响应将包含 selectUrl 和 nextAction=freekassa_select,供付款人选择支付方式及外汇报价。若设置,则立即初始化 FreeKassa。后续通过 POST /api/freekassa/confirm 确认。 |
allowedPaymentMethods |
string | 可选 | 当 paymentMethod=select 时:逗号分隔的网关代码,用于在付款人选择页面上显示(例如 alipay,wxpay,freekassa)。省略则显示该订单货币和商户账户启用的所有支付方式。USD订单默认包含 balance(已登录客户账户余额);可通过 allowedPaymentMethods=alipay,wxpay 排除。需参与签名。 |
lang |
string | 可选 | 付款人选择页面的语言区域(例如 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 或 aamarpay 配合使用) |
status |
string | 订单状态代码:"2"(已支付) |
status_str |
string | 订单状态字符串:"paid" |
paymentMethod |
string | 使用的支付方式:alipay、wxpay、crypto、eps、paystation 或 aamarpay |
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 结账支持银行卡和本地支付方式。USD 订单按配置的 USD→BDT 汇率以 BDT 计费。 |
| aamarpay | aamarpay |
BDT, USD | aamarpay(孟加拉国):跳转结账。BDT 按原样发送。USD 使用系统 USD→BDT 汇率(与 EPS/PayStation 相同)本地转换并以 BDT 计费。回调:/api/gatewaynotification/aamarpay/return/success(通过 Search Transaction 验证)。 |
| FreeKassa | freekassa |
RUB, USD, EUR, UAH, KZT | 两步流程:不带 freekassaSystemId 的 createorder 返回 selectUrl;付款人在网关页面选择支付方式(如需则进行外汇报价),然后 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。USD 订单还提供 balance:付款人必须在 /merchant/login 登录;资金从付款人的平台余额中扣除并记入商户。可选 allowedPaymentMethods 限制列表。FreeKassa / NOWPayments 在确认后仍使用其二级选择页面。 |
alipay、wxpay 和 balancealipay、wxpay、eps、paystation、aamarpay、freekassa、heleket、nowpayments 和 balanceeps、paystation 和 aamarpayfreekassafreekassa 和 nowpaymentsnowpayments常见错误代码及其含义:
| 代码 | 描述 |
|---|---|
| 400 | 错误请求 - 参数无效或业务逻辑错误 |
| 401 | 未授权 - appid 或 apikey 无效 |
| 403 | 禁止访问 — clientip 与请求 IP 不匹配,或商户账户已被禁用 |
| 429 | 请求过多 - 超出速率限制 |
| 500 | 服务器内部错误 - 服务端错误 |