API 참조

청구서 목록 조회

GET/v1/invoices

계약 v1 / 1.0.0 62 / 2026-10-10

이 페이지에서

후원이 아닌 청구서만 포함하며 최신 ID부터 정렬됩니다. 응답의 data에는 next_before가 없으므로 계속 조회하려면 마지막 항목 ID를 before로 전달하세요. 빈 페이지가 나오면 중단하세요.

키 권한: invoices / read / payments.

매개변수

매개변수입금필수설명
projectquery아니요프로젝트 ID입니다. 프로젝트 한정 키가 아니라면 모니터링 목록 조회나 생성에 필요합니다. 다른 작업에서 생략하면 해당 작업의 계정/프로젝트 맥락을 사용합니다. 명시적으로 지정하세요.
string
chainquery아니요네트워크 코드 필터입니다.
string
statusquery아니요청구서 상태입니다.
string pending, seen, paid, underpaid, partial, overpaid, expired, late, canceled
limitquery아니요페이지 크기: 최대 200개. 잘못된 값은 기본값을 사용하며 200을 넘으면 상한이 적용됩니다.
integer 기본값: 50; minimum: 1; maximum: 200
beforequery아니요next_before 또는 이전 페이지 마지막 항목의 ID에서 가져온 커서입니다. 최신 항목부터 정렬됩니다.
string minLength: 1

요청 예시

예제는 귀하의 계정에서 실제 작업을 수행합니다. 코드에 명시된 환경 변수를 설정하세요. 키를 비공개로 유지하세요. 쓰기 요청은 자동 재시도하지 않습니다.

Shell / cURL
#!/usr/bin/env bash
set -euo pipefail
: "${CRYPTANIO_PROJECT_ID:?Set CRYPTANIO_PROJECT_ID}"
: "${CRYPTANIO_API_KEY:?Set CRYPTANIO_API_KEY}"
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
transfer_status=0
http_status="$(curl \
  --silent --show-error --max-time 30 --request GET \
  --header "Authorization: Bearer $CRYPTANIO_API_KEY" \
  --header 'Accept: application/json' \
  --get \
  --data-urlencode "project=$CRYPTANIO_PROJECT_ID" \
  --data-urlencode 'limit=50' \
  "https://api.cryptanio.com/v1/invoices" \
  --output "$response_file" --write-out '%{http_code}')" || transfer_status=$?
if [[ "$http_status" == 2?? ]]; then
  cat "$response_file"
  exit "$transfer_status"
fi
printf 'HTTP %s\n' "$http_status" >&2
cat "$response_file" >&2
exit 1
예제 다운로드
Go
// Go; standard library only. Run: go run request.go
package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
    "time"
)

func env(name string) string {
    value := os.Getenv(name)
    if value == "" { fmt.Fprintln(os.Stderr, "Set", name); os.Exit(1) }
    return value
}
func run() error {
    path := "/v1/invoices"

    endpoint, err := url.Parse("https://api.cryptanio.com" + path)
    if err != nil { return err }
    query := endpoint.Query()
    query.Set("project", env("CRYPTANIO_PROJECT_ID"))
    query.Set("limit", "50")
    endpoint.RawQuery = query.Encode()

    request, err := http.NewRequest("GET", endpoint.String(), nil)
    if err != nil { return err }
    request.Header.Set("Authorization", "Bearer " + env("CRYPTANIO_API_KEY"))
    request.Header.Set("Accept", "application/json")
    client := &http.Client{Timeout: 30 * time.Second, CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
    response, err := client.Do(request)
    if err != nil { return err }
    defer response.Body.Close()
    if response.StatusCode < 200 || response.StatusCode >= 300 {
        body, err := io.ReadAll(response.Body)
        if err != nil { return err }
        return fmt.Errorf("HTTP %d: %s", response.StatusCode, body)
    }
    _, err = io.Copy(os.Stdout, response.Body)
    return err
}
func main() {
    if err := run(); err != nil { fmt.Fprintln(os.Stderr, err); os.Exit(1) }
}
예제 다운로드
Rust
// Cargo.toml dependencies:
// reqwest = { version = "=0.12.24", features = ["blocking", "json"] }
// serde_json = "=1.0.145"
use std::{error::Error, io, time::Duration};
use reqwest::{blocking::Client, redirect::Policy, Method, Url};

fn env(name: &str) -> Result<String, Box<dyn Error>> {
    let value = std::env::var(name)?;
    if value.is_empty() { return Err(format!("Set {name}").into()); }
    Ok(value)
}
fn run() -> Result<(), Box<dyn Error>> {
    let mut url = Url::parse("https://api.cryptanio.com")?;
    {
        let mut segments = url.path_segments_mut().map_err(|_| "Invalid base URL")?;
        segments.clear();
        segments.push("v1");
        segments.push("invoices");
    }
    url.query_pairs_mut()
        .append_pair("project", &env("CRYPTANIO_PROJECT_ID")?)
        .append_pair("limit", &"50".to_owned());
    let client = Client::builder().timeout(Duration::from_secs(30)).redirect(Policy::none()).build()?;
    let request = client.request(Method::GET, url)
        .header("Authorization", format!("Bearer {}", env("CRYPTANIO_API_KEY")?))
        .header("Accept", "application/json".to_owned());
    let mut response = request.send()?;
    let status = response.status();
    if !status.is_success() { return Err(format!("HTTP {}: {}", status.as_u16(), response.text()?).into()); }
    io::copy(&mut response, &mut io::stdout())?;
    Ok(())
}
fn main() {
    if let Err(error) = run() { eprintln!("{error}"); std::process::exit(1); }
}
예제 다운로드
PHP
<?php
// PHP 8 with the cURL extension. Run this on your server.
function env(string $name): string {
    $value = getenv($name);
    if ($value === false || $value === '') throw new RuntimeException('Set ' . $name);
    return $value;
}
try {
    $path = '/v1/invoices';

    $query = [
        'project' => env('CRYPTANIO_PROJECT_ID'),
        'limit' => '50',
    ];
    $url = 'https://api.cryptanio.com' . $path . ($query ? '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986) : '');
    $headers = [
        'Authorization: ' . 'Bearer ' . env('CRYPTANIO_API_KEY'),
        'Accept: ' . 'application/json',
    ];
    $curl = curl_init($url);
    curl_setopt_array($curl, [
        CURLOPT_CUSTOMREQUEST => 'GET',
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => false,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 30,
    ]);
    $response = curl_exec($curl);
    if ($response === false) throw new RuntimeException(curl_error($curl));
    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    if ($status < 200 || $status >= 300) throw new RuntimeException('HTTP ' . $status . ': ' . $response);
    echo $response;
} catch (Throwable $error) {
    fwrite(STDERR, $error->getMessage() . PHP_EOL);
    exit(1);
}
예제 다운로드
Python
# Python 3; standard library only.
import json
import os
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import quote, urlencode
from urllib.request import HTTPRedirectHandler, Request, build_opener

def env(name):
    result = os.environ.get(name)
    if not result:
        raise ValueError("Set " + name)
    return result

class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None

try:
    path = "/v1/invoices"

    query = {
        "project": env("CRYPTANIO_PROJECT_ID"),
        "limit": "50",
    }
    url = "https://api.cryptanio.com" + path + ("?" + urlencode(query) if query else "")
    headers = {
        "Authorization": "Bearer " + env("CRYPTANIO_API_KEY"),
        "Accept": "application/json",
    }
    data = None
    request = Request(url, data=data, headers=headers, method="GET")
    with build_opener(NoRedirect()).open(request, timeout=30) as response:
        if not 200 <= response.status < 300:
            raise ValueError("HTTP " + str(response.status))
        sys.stdout.buffer.write(response.read())
except HTTPError as error:
    print("HTTP " + str(error.code) + ": " + error.read().decode("utf-8", errors="replace"), file=sys.stderr)
    sys.exit(1)
except (ValueError, URLError, OSError) as error:
    print(str(error), file=sys.stderr)
    sys.exit(1)
예제 다운로드
Node.js
// Node.js 18+. Run on your server, never in a browser.
const env = name => {
  const result = process.env[name];
  if (!result) throw new Error(`Set ${name}`);
  return result;
};
try {
  let path = "/v1/invoices";

  const url = new URL(path, "https://api.cryptanio.com");
  url.searchParams.set("project", env("CRYPTANIO_PROJECT_ID"));
  url.searchParams.set("limit", "50");
  const headers = {
    "Authorization": "Bearer " + env("CRYPTANIO_API_KEY"),
    "Accept": "application/json",
  };
  const response = await fetch(url, {
    method: "GET", headers, redirect: "manual",
    signal: AbortSignal.timeout(30_000),
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
  if (response.body) {
    for await (const chunk of response.body) process.stdout.write(chunk);
  }
} catch (error) {
  console.error(error.message);
  process.exitCode = 1;
}
예제 다운로드

응답 및 오류

200 성공 응답.
필드유형필수설명
dataobject[]예
401 유효한 활성 API 키가 없습니다(unauthorized).
필드유형필수설명
errorobject예
401 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
403 키가 작업, 프로젝트, 서비스 또는 IP를 허용하지 않거나 이메일이 확인되지 않았습니다.
필드유형필수설명
errorobject예
403 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
429 요청이 너무 많습니다(rate_limited). Retry-After 이후 재시도하세요.
필드유형필수설명
errorobject예
429 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
500 내부 오류(internal).
필드유형필수설명
errorobject예
500 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
503 일시적 사용 불가(unavailable). 점진적 대기로 재시도하세요.
필드유형필수설명
errorobject예
503 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}

오류 처리 및 안전한 재시도

중첩 객체

InvoiceList

필드유형필수설명
dataobject[]예
Invoice

필드유형필수설명
checkout_urlstring아니요Cryptanio가 제공하는 결제 페이지입니다. 결제자가 방법을 선택하는 청구서의 생성과 재시도는 결제가 감지될 때까지 방법을 고를 수 있는 대화형 접근 링크를 반환합니다. 고정 방법 생성과 모든 GET 및 목록은 별도의 읽기 전용 링크를 반환합니다. 두 링크 모두 지정한 결제자에게만 공유하세요. 계정이나 API 키에 대한 접근 권한은 부여하지 않습니다. 브라우저 리디렉션이 아닌 청구서 API 또는 검증된 웹훅으로 결제를 확인하세요.
uri
idstring예불투명 식별자입니다. 문자열로 유지하세요.
minLength: 1
statusstring예pending은 결제 대기, seen은 감지됨, partial은 일부 결제, paid는 정산 완료입니다. underpaid/overpaid/late는 판단이 필요하며 expired는 기한 만료, canceled는 취소입니다.
pending, seen, paid, underpaid, partial, overpaid, expired, late, canceled
project_idstring예불투명 식별자입니다. 문자열로 유지하세요.
minLength: 1
referencestring아니요주문 참조입니다.
customerobject아니요
productobject아니요
payerobject아니요
metadataobject아니요최대 20쌍, JSON 8192바이트까지 허용됩니다. 비밀 값을 포함하지 마세요.
invoice_currencystring아니요주문 견적 통화입니다.
invoice_amountstring아니요정확한 소수 금액 문자열입니다. 부동 소수점을 사용하지 마세요.
pattern: ^[0-9]+(?:\.[0-9]+)?$
chainstring예네트워크 코드입니다.
assetstring예결제 자산입니다.
addressstring예결제 주소입니다.
payment_routeobject아니요자동 소스가 tag, memo, TON comment 또는 Solana Pay reference를 발급하면 블록체인 결제 식별값이 필수입니다. 수신 주소와 함께 보관하세요. 판매자의 주문 참조는 별도 필드입니다.
payment_uristring아니요수신자, 정확한 금액, 지원 토큰의 mint 및 필수 reference를 포함한 Solana Pay 전송 요청입니다. 결제 QR에는 수신 주소만 넣지 말고 이 URI를 인코딩하세요.
uri
amountstring | string예구매자가 실제로 보내야 하는 금액입니다. 청구서를 구분하기 위해 요청 금액과 다를 수 있습니다. 방법을 선택하기 전에는 비어 있습니다.
amount_rawstring | string예최소 단위의 정수 금액을 문자열로 표시합니다. 방법을 선택하기 전에는 비어 있습니다.
askedstring | string예처음 요청한 암호화폐 금액입니다. 방법을 선택하기 전에는 비어 있습니다.
decimalsinteger예자산의 소수 자릿수입니다.
minimum: 0
tolerancestring아니요최소 단위의 허용 오차이며 request.tolerance와 다릅니다.
pattern: ^[0-9]+$
sandboxboolean예테스트 청구서는 실제 블록체인 결제를 입증하지 않습니다.
needs_decisionboolean아니요부족 결제, 초과 결제 또는 지연 결제는 판단이 필요합니다.
paidstring아니요최소 단위의 수신 금액입니다.
pattern: ^[0-9]+$
tx_idstring아니요결제 트랜잭션 식별자입니다.
paid_atstring아니요RFC 3339 형식의 UTC 날짜 및 시간입니다.
date-time
expires_atstring예RFC 3339 형식의 UTC 날짜 및 시간입니다.
date-time
created_atstring예RFC 3339 형식의 UTC 날짜 및 시간입니다.
date-time
ID

불투명 식별자입니다. 형식은 보장되지 않으므로 숫자로 변환하지 마세요.

string 불투명 식별자입니다. 형식은 보장되지 않으며 숫자로 변환하지 마세요.

InvoiceStatus

pending은 결제 대기, seen은 감지됨, partial은 일부 결제, paid는 정산 완료입니다. underpaid/overpaid/late는 판단이 필요하며 expired는 기한 만료, canceled는 취소입니다.

string pending은 결제 대기, seen은 감지됨, partial은 일부 결제, paid는 정산 완료입니다. underpaid/overpaid/late는 판단이 필요하며 expired는 기한 만료, canceled는 취소입니다.

Customer

필드유형필수설명
idstring예귀하의 시스템에서 사용하는 고객 식별자입니다.
maxLength: 120
Product

필드유형필수설명
idstring아니요사용자 시스템의 제품 식별자입니다.
maxLength: 120
namestring아니요제품 이름입니다.
maxLength: 200
quantityinteger아니요수량입니다.
minimum: 1; maximum: 1000000
Payer

필드유형필수설명
commentstring예결제자 의견입니다.
maxLength: 500
InvoiceMetadata

최대 20쌍, JSON 8192바이트까지 허용됩니다. 비밀 값을 포함하지 마세요.

object 최대 20쌍, JSON 8192바이트까지 허용됩니다. 비밀 값을 포함하지 마세요.

Decimal

string

RawAmount

string

Error

필드유형필수설명
errorobject예