本页内容
列表
按严格的状态和日期筛选条件列出账单,用游标分页向前翻页,对账不产生重复页。
GET/v1/invoices
API 密钥: Payment
只返回已认证商户拥有、属于该 key 环境及可见项目的账单。结果按 created_at DESC、再按 invoice_id DESC 排序。
查询参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
limit |
integer | 20 |
每页大小,1 到 100 |
cursor |
string | — | 上一个响应中的不透明 next_cursor |
status |
string | — | 精确的 snake_case 状态。重复该参数可匹配任一给定状态;不要发送逗号分隔的值 |
external_order_id |
string | — | 精确的外部订单号,最长 128 字符 |
project_id |
string | — | 该 Payment key 可见的带前缀 prj_… ID |
created_from |
Unix 秒 | — | created_at 下限(含) |
created_to |
Unix 秒 | — | created_at 上限(不含)。必须晚于 created_from |
未知参数、重复的标量参数、重复状态和大小写错误的枚举值会被拒绝,而不是被静默忽略。表外的参数名一律 400,所以 API 收下的筛选条件就是它真正应用了的条件:写错一个名字,不会在你不知情的时候把结果放大。
这张表也就是筛选条件的全部。Merchant API 的列表没有全文搜索,没有排序参数,也没有 offset 分页。
示例
GET /v1/invoices?limit=50&status=paid&status=paid_over&created_from=1767225600 HTTP/1.1
Host: api.paymos.io
Authorization: HMAC-SHA256 pk_live_…:…
X-Request-Timestamp: 1767225660
代码示例
每个标签页使用该语言的官方 SDK。签名、序列化、安全重试和类型化错误都由 SDK 处理。
API_KEY_ID="pk_live_xxxxxxxxxxxx"
API_SECRET="sk_live_xxxxxxxxxxxx"
QUERY="?status=paid&limit=50"
TS=$(date +%s)
# No body: the hash slot is the EMPTY STRING, not sha256("") — its fixed
# e3b0c442… digest signs a different payload and the request is rejected. The
# query keeps its leading "?" exactly as transmitted.
SIGNATURE=$(printf '%s\n%s\n%s\n%s\n%s' "$TS" GET /v1/invoices "$QUERY" '' \
| openssl dgst -sha256 -hmac "$API_SECRET" -binary | base64)
curl -sS "https://api.paymos.io/v1/invoices$QUERY" \
-H "Authorization: HMAC-SHA256 $API_KEY_ID:$SIGNATURE" \
-H "X-Request-Timestamp: $TS"
import { Paymos } from '@paymos/sdk';
const paymos = new Paymos({
apiKey: process.env.PAYMOS_API_KEY,
apiSecret: process.env.PAYMOS_API_SECRET,
});
const page = await paymos.invoices.list({ status: ['paid', 'paid_over'], limit: 50 });
for await (const invoice of paymos.invoices.iterate({ status: ['paid'] }, 10)) {
console.log(invoice.invoiceId);
}
import os
from paymos import Paymos
paymos = Paymos(
api_key=os.environ["PAYMOS_API_KEY"],
api_secret=os.environ["PAYMOS_API_SECRET"],
)
page = paymos.invoices.list(status=["paid", "paid_over"], limit=50)
for invoice in paymos.invoices.iterate(10, status=["paid"]):
print(invoice["invoice_id"])
<?php
use Paymos\Client;
use Paymos\ClientConfig;
$paymos = new Client(new ClientConfig(
getenv('PAYMOS_API_KEY'),
getenv('PAYMOS_API_SECRET')
));
$page = $paymos->invoices()->listPage(array(
'status' => array('paid', 'paid_over'),
'limit' => 50,
));
foreach ($paymos->invoices()->iterate(array('status' => array('paid')), 10) as $invoice) {
echo $invoice['invoice_id'] . PHP_EOL;
}
package main
import (
"context"
"fmt"
"os"
paymos "github.com/Paymos-labs/go-sdk/v2"
)
func main() {
client, err := paymos.NewClient(os.Getenv("PAYMOS_API_KEY"), os.Getenv("PAYMOS_API_SECRET"))
if err != nil {
panic(err)
}
page, err := client.Invoices.List(context.Background(), paymos.InvoiceListParams{
Status: []paymos.InvoiceStatus{paymos.InvoicePaid, paymos.InvoicePaidOver},
Limit: 50,
})
if err != nil {
panic(err)
}
fmt.Println(len(page.Items), page.NextCursor)
iter := paymos.NewInvoiceIterator(client.Invoices, paymos.InvoiceListParams{
Status: []paymos.InvoiceStatus{paymos.InvoicePaid},
}, 10)
for {
invoice, ok, err := iter.Next(context.Background())
if err != nil {
panic(err)
}
if !ok {
break
}
fmt.Println(invoice.InvoiceID)
}
}
using Paymos;
using var paymos = new PaymosClient(
Environment.GetEnvironmentVariable("PAYMOS_API_KEY")!,
Environment.GetEnvironmentVariable("PAYMOS_API_SECRET")!);
var page = await paymos.Invoices.ListAsync(new InvoiceListOptions(
Status: [InvoiceStatus.Paid, InvoiceStatus.PaidOver],
Limit: 50));
await foreach (var invoice in paymos.Invoices.IterateAsync(
new InvoiceListOptions(Status: [InvoiceStatus.Paid]), maxPages: 10))
{
Console.WriteLine(invoice.InvoiceId);
}
import io.paymos.InvoiceListItem;
import io.paymos.InvoiceListOptions;
import io.paymos.InvoiceStatus;
import io.paymos.Page;
import io.paymos.PaymosClient;
import java.util.List;
PaymosClient paymos = new PaymosClient(
System.getenv("PAYMOS_API_KEY"),
System.getenv("PAYMOS_API_SECRET"));
Page<InvoiceListItem> page = paymos.invoices.list(InvoiceListOptions.builder()
.status(List.of(InvoiceStatus.PAID, InvoiceStatus.PAID_OVER))
.limit(50)
.build());
for (InvoiceListItem invoice : paymos.invoices.iterate(
InvoiceListOptions.builder().status(List.of(InvoiceStatus.PAID)).build(), 10)) {
System.out.println(invoice.invoiceId());
}
require 'paymos'
paymos = Paymos::Client.new(
api_key: ENV.fetch('PAYMOS_API_KEY'),
api_secret: ENV.fetch('PAYMOS_API_SECRET')
)
page = paymos.invoices.list(status: ['paid', 'paid_over'], limit: 50)
paymos.invoices.each(max_pages: 10, status: ['paid']) do |invoice|
puts invoice.invoice_id
end
use paymos::{InvoiceListParams, InvoiceStatus, PaymosClient};
let paymos = PaymosClient::new(
std::env::var("PAYMOS_API_KEY")?,
std::env::var("PAYMOS_API_SECRET")?,
)?;
let page = paymos
.invoices()
.list(&InvoiceListParams {
status: Some(vec![InvoiceStatus::Paid, InvoiceStatus::PaidOver]),
limit: Some(50),
..Default::default()
})
.await?;
println!("{} items, next_cursor={:?}", page.items.len(), page.next_cursor);
let mut pager = paymos.invoices().pager(
InvoiceListParams { status: Some(vec![InvoiceStatus::Paid]), ..Default::default() },
Some(10),
)?;
while let Some(invoice) = pager.next().await? {
println!("{}", invoice.invoice_id);
}
响应 (200 OK)
{
"items": [
{
"invoice_id": "inv_74BPZFhr9qy9Uz2fbRkdJX",
"project_id": "prj_7gK2mR9xQ4vN8cT1bY5dL3",
"external_order_id": "order-1042",
"client_id": "customer-42",
"status": "paid",
"is_final": true,
"is_test": false,
"amount": "49.95",
"currency": "USDT",
"network": "TRC20",
"created_at": 1767225600,
"expires_at": 1767227400,
"completed_at": 1767225908
}
],
"next_cursor": "CfDJ8JvN…"
}
列表项刻意保持精简。付款、转账、充值地址和收银台详情请用 获取账单。响应携带 Cache-Control: private, no-store。
分页规则
- 没有页码,也没有
total_count:跟随next_cursor直到它为null。 - 游标是不透明的,带防篡改保护,24 小时后过期。
- 游标绑定账单资源和精确的筛选条件。翻页之间保持筛选条件不变;
limit可以改。 - 缺失或终止的游标表示为
next_cursor: null。 - 如果游标无效、过期、用在其他资源上或搭配了不同的筛选条件,请不带游标重新开始。
错误
Payout(rk_)key 会被拒绝并返回 403 payment_key_required。无效筛选条件返回字段级 400;无效游标返回 400 pagination_cursor_invalid。超出 key 作用域的 project_id 返回 404,不透露其是否存在。见 错误码。