En esta página
Listar
Lista facturas con filtros estrictos de estado y fecha, avanza con paginación por cursor y concilia los resultados sin páginas duplicadas.
Clave de API: Payment
Devuelve únicamente las facturas del comercio autenticado, dentro del entorno de la clave y de los proyectos que esta ve. El orden es created_at DESC y, a igualdad, invoice_id DESC.
Parámetros de consulta
| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
limit |
integer | 20 |
Tamaño de página, de 1 a 100. |
cursor |
string | — | El next_cursor opaco de la respuesta anterior. |
status |
string | — | Estado exacto en snake_case. Repite el parámetro para casar con varios estados; no envíes un valor separado por comas. |
external_order_id |
string | — | Identificador externo de pedido exacto, de hasta 128 caracteres. |
project_id |
string | — | Un identificador con prefijo prj_… visible para esta clave Payment. |
created_from |
Unix seconds | — | Límite inferior de created_at, inclusive. |
created_to |
Unix seconds | — | Límite superior de created_at, exclusivo. Debe ser posterior a created_from. |
Los parámetros desconocidos, los parámetros escalares repetidos, los estados duplicados y las mayúsculas incorrectas en un enum se rechazan en lugar de ignorarse en silencio. Un nombre que no esté en la tabla devuelve 400, así que un filtro que la API aceptó es un filtro que aplicó: una errata nunca te amplía el resultado sin avisar.
La tabla es también todo el juego de filtros. En las listas de la Merchant API no hay búsqueda por texto, ni parámetro de orden, ni paginación por offset.
Ejemplo
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
Ejemplos de código
Cada pestaña usa el SDK oficial de ese lenguaje. La firma, la serialización, los reintentos seguros y los errores tipados los resuelve el 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);
}
Respuesta (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…"
}
El elemento de la lista es deliberadamente compacto. Para pagos, transferencias, dirección de depósito y detalles de la página de pago, usa Obtener factura. La respuesta lleva Cache-Control: private, no-store.
Reglas de paginación
- No hay número de página ni
total_count: siguenext_cursorhasta que valganull. - El cursor es opaco, está protegido contra manipulación y vence a las 24 horas.
- Está ligado al recurso de facturas y al conjunto exacto de filtros. Mantén los filtros sin cambios entre páginas;
limitsí puede variar. - Un cursor ausente o final se representa con
next_cursor: null. - Si el cursor no es válido, ha vencido, se usa en otro recurso o se combina con filtros distintos, empieza de nuevo sin cursor.
Errores
Una clave Payout (rk_) se rechaza con 403 payment_key_required. Los filtros no válidos devuelven un 400 por campo; un cursor no válido devuelve 400 pagination_cursor_invalid. Un project_id fuera del alcance de la clave devuelve 404 sin revelar si existe. Consulta Códigos de error.