Référence de l’API

Obtenir une facture

GET/v1/invoices/{id}

Contrat v1 / 1.0.0 62 / 2026-10-10

Sur cette page

Lisez une facture d’un projet autorisé par la clé API.

Permissions de la clé : invoices / read / payments.

Paramètres

ParamètreEntrantObligatoireDescription
idpathOuiID de ressource opaque.
string minLength: 1

Exemples de requêtes

Les exemples réalisent une opération réelle dans votre compte. Définissez les variables d’environnement nommées dans le code. Gardez votre clé privée ; les requêtes d’écriture ne sont pas réessayées automatiquement.

Shell / cURL
#!/usr/bin/env bash
set -euo pipefail
: "${CRYPTANIO_RESOURCE_ID:?Set CRYPTANIO_RESOURCE_ID}"
: "${CRYPTANIO_API_KEY:?Set CRYPTANIO_API_KEY}"
urlencode() {
  local LC_ALL=C text="$1" char index
  for ((index=0; index<${#text}; index++)); do
    char="${text:index:1}"
    case "$char" in [a-zA-Z0-9.~_-]) printf '%s' "$char" ;; *) printf '%%%02X' "'$char" ;; esac
  done
}
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' \
  "https://api.cryptanio.com/v1/invoices/$(urlencode "$CRYPTANIO_RESOURCE_ID")" \
  --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
Télécharger l’exemple
Go
// Go; standard library only. Run: go run request.go
package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
    "strings"
    "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/{id}"
    path = strings.ReplaceAll(path, "{id}", url.PathEscape(env("CRYPTANIO_RESOURCE_ID")))
    endpoint, err := url.Parse("https://api.cryptanio.com" + path)
    if err != nil { return err }
    query := endpoint.Query()

    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) }
}
Télécharger l’exemple
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");
        segments.push(&env("CRYPTANIO_RESOURCE_ID")?);
    }
    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); }
}
Télécharger l’exemple
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/{id}';
    $path = str_replace('{id}', rawurlencode(env('CRYPTANIO_RESOURCE_ID')), $path);
    $query = [

    ];
    $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);
}
Télécharger l’exemple
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/{id}"
    path = path.replace("{id}", quote(env("CRYPTANIO_RESOURCE_ID"), safe=""))
    query = {

    }
    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)
Télécharger l’exemple
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/{id}";
  path = path.replace("{id}", encodeURIComponent(env("CRYPTANIO_RESOURCE_ID")));
  const url = new URL(path, "https://api.cryptanio.com");

  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;
}
Télécharger l’exemple

Réponses et erreurs

200 Réponse réussie.
ChampTypeObligatoireDescription
checkout_urlstringNonPage de paiement hébergée par Cryptanio. La création ou la nouvelle tentative d’une facture avec choix du moyen renvoie un lien d’accès interactif permettant ce choix jusqu’à la détection d’un paiement. La création à moyen fixe et tous les GET et listes renvoient un lien distinct en lecture seule. Ne partagez ces liens qu’avec le payeur prévu ; aucun ne donne accès au compte ni à la clé API. Confirmez le paiement via l’API des factures ou un webhook vérifié, jamais par une redirection du navigateur.
uri
idstringOuiIdentifiant opaque ; conservez-le sous forme de chaîne.
minLength: 1
statusstringOuipending attend le paiement ; seen détecté ; partial partiellement payé ; paid réglé ; underpaid/overpaid/late nécessitent une décision ; expired délai dépassé ; canceled annulé.
pending, seen, paid, underpaid, partial, overpaid, expired, late, canceled
project_idstringOuiIdentifiant opaque ; conservez-le sous forme de chaîne.
minLength: 1
referencestringNonRéférence de la commande.
customerobjectNon
productobjectNon
payerobjectNon
metadataobjectNonJusqu’à 20 paires, au maximum 8192 octets JSON. N’incluez pas de secrets.
invoice_currencystringNonDevise du prix indiqué pour la commande.
invoice_amountstringNonMontant décimal exact sous forme de chaîne ; n’utilisez pas de virgule flottante.
pattern: ^[0-9]+(?:\.[0-9]+)?$
chainstringOuiCode réseau.
assetstringOuiActif de paiement.
addressstringOuiAdresse de paiement.
payment_routeobjectNonIdentifiant de paiement sur la blockchain obligatoire lorsqu’une source automatique fournit un tag, un memo, un commentaire TON ou une référence Solana Pay. Conservez-le avec l’adresse de réception ; la référence de commande du commerçant est un champ distinct.
payment_uristringNonDemande de transfert Solana Pay avec le destinataire, le montant exact, le mint du jeton pris en charge et la référence obligatoire. Encodez cet URI dans le QR de paiement au lieu de la simple adresse de réception.
uri
amountstring | stringOuiMontant réel que l’acheteur doit envoyer ; il peut différer du montant demandé pour distinguer les factures. Vide tant qu’aucun moyen n’est choisi.
amount_rawstring | stringOuiMontant entier dans la plus petite unité, sous forme de chaîne. Vide tant qu’aucun moyen n’est choisi.
askedstring | stringOuiMontant en cryptomonnaie demandé à l’origine. Vide tant qu’aucun moyen n’est choisi.
decimalsintegerOuiNombre de décimales de l’actif.
minimum: 0
tolerancestringNonTolérance en plus petites unités ; contrairement à request.tolerance.
pattern: ^[0-9]+$
sandboxbooleanOuiUne facture de test ne prouve pas un paiement réel sur la blockchain.
needs_decisionbooleanNonUne décision est nécessaire pour les états underpaid, overpaid ou late.
paidstringNonMontant reçu en plus petites unités.
pattern: ^[0-9]+$
tx_idstringNonIdentifiant de la transaction de paiement.
paid_atstringNonDate et heure UTC selon RFC 3339.
date-time
expires_atstringOuiDate et heure UTC selon RFC 3339.
date-time
created_atstringOuiDate et heure UTC selon RFC 3339.
date-time
200 application/json
{
  "id": "2100",
  "status": "pending",
  "project_id": "2002",
  "reference": "order-42",
  "chain": "ethereum",
  "asset": "USDC",
  "address": "0x52908400098527886E0F7030069857D2E4169EE7",
  "amount": "12.5",
  "amount_raw": "12500000",
  "asked": "12.5",
  "decimals": 6,
  "sandbox": true,
  "expires_at": "2026-10-06T11:00:00Z",
  "created_at": "2026-10-06T10:00:00Z"
}
401 Aucune clé API active valide (unauthorized).
ChampTypeObligatoireDescription
errorobjectOui
401 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
403 La clé n’autorise pas l’opération, le projet, le service ou l’IP ; e-mail non confirmé.
ChampTypeObligatoireDescription
errorobjectOui
403 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
404 Objet introuvable dans le périmètre de la clé (not_found).
ChampTypeObligatoireDescription
errorobjectOui
404 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
429 Trop de requêtes (rate_limited) ; réessayez après Retry-After.
ChampTypeObligatoireDescription
errorobjectOui
429 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
500 Erreur interne (internal).
ChampTypeObligatoireDescription
errorobjectOui
500 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}
503 Indisponibilité temporaire (unavailable) ; réessayez avec un délai progressif.
ChampTypeObligatoireDescription
errorobjectOui
503 application/json
{
  "error": {
    "code": "forbidden",
    "message": "this API key is read-only"
  }
}

Gestion des erreurs et nouvelles tentatives sûres

Objets imbriqués

Invoice

ChampTypeObligatoireDescription
checkout_urlstringNonPage de paiement hébergée par Cryptanio. La création ou la nouvelle tentative d’une facture avec choix du moyen renvoie un lien d’accès interactif permettant ce choix jusqu’à la détection d’un paiement. La création à moyen fixe et tous les GET et listes renvoient un lien distinct en lecture seule. Ne partagez ces liens qu’avec le payeur prévu ; aucun ne donne accès au compte ni à la clé API. Confirmez le paiement via l’API des factures ou un webhook vérifié, jamais par une redirection du navigateur.
uri
idstringOuiIdentifiant opaque ; conservez-le sous forme de chaîne.
minLength: 1
statusstringOuipending attend le paiement ; seen détecté ; partial partiellement payé ; paid réglé ; underpaid/overpaid/late nécessitent une décision ; expired délai dépassé ; canceled annulé.
pending, seen, paid, underpaid, partial, overpaid, expired, late, canceled
project_idstringOuiIdentifiant opaque ; conservez-le sous forme de chaîne.
minLength: 1
referencestringNonRéférence de la commande.
customerobjectNon
productobjectNon
payerobjectNon
metadataobjectNonJusqu’à 20 paires, au maximum 8192 octets JSON. N’incluez pas de secrets.
invoice_currencystringNonDevise du prix indiqué pour la commande.
invoice_amountstringNonMontant décimal exact sous forme de chaîne ; n’utilisez pas de virgule flottante.
pattern: ^[0-9]+(?:\.[0-9]+)?$
chainstringOuiCode réseau.
assetstringOuiActif de paiement.
addressstringOuiAdresse de paiement.
payment_routeobjectNonIdentifiant de paiement sur la blockchain obligatoire lorsqu’une source automatique fournit un tag, un memo, un commentaire TON ou une référence Solana Pay. Conservez-le avec l’adresse de réception ; la référence de commande du commerçant est un champ distinct.
payment_uristringNonDemande de transfert Solana Pay avec le destinataire, le montant exact, le mint du jeton pris en charge et la référence obligatoire. Encodez cet URI dans le QR de paiement au lieu de la simple adresse de réception.
uri
amountstring | stringOuiMontant réel que l’acheteur doit envoyer ; il peut différer du montant demandé pour distinguer les factures. Vide tant qu’aucun moyen n’est choisi.
amount_rawstring | stringOuiMontant entier dans la plus petite unité, sous forme de chaîne. Vide tant qu’aucun moyen n’est choisi.
askedstring | stringOuiMontant en cryptomonnaie demandé à l’origine. Vide tant qu’aucun moyen n’est choisi.
decimalsintegerOuiNombre de décimales de l’actif.
minimum: 0
tolerancestringNonTolérance en plus petites unités ; contrairement à request.tolerance.
pattern: ^[0-9]+$
sandboxbooleanOuiUne facture de test ne prouve pas un paiement réel sur la blockchain.
needs_decisionbooleanNonUne décision est nécessaire pour les états underpaid, overpaid ou late.
paidstringNonMontant reçu en plus petites unités.
pattern: ^[0-9]+$
tx_idstringNonIdentifiant de la transaction de paiement.
paid_atstringNonDate et heure UTC selon RFC 3339.
date-time
expires_atstringOuiDate et heure UTC selon RFC 3339.
date-time
created_atstringOuiDate et heure UTC selon RFC 3339.
date-time
ID

Identifiant opaque. Son format n’est pas garanti ; ne le convertissez pas en nombre.

string Identifiant opaque. Son format n’est pas garanti ; ne le convertissez pas en nombre.

InvoiceStatus

pending attend le paiement ; seen détecté ; partial partiellement payé ; paid réglé ; underpaid/overpaid/late nécessitent une décision ; expired délai dépassé ; canceled annulé.

string pending attend le paiement ; seen détecté ; partial partiellement payé ; paid réglé ; underpaid/overpaid/late nécessitent une décision ; expired délai dépassé ; canceled annulé.

Customer

ChampTypeObligatoireDescription
idstringOuiIdentifiant du client dans votre système.
maxLength: 120
Product

ChampTypeObligatoireDescription
idstringNonIdentifiant du produit dans votre système.
maxLength: 120
namestringNonNom du produit.
maxLength: 200
quantityintegerNonQuantité.
minimum: 1 ; maximum: 1000000
Payer

ChampTypeObligatoireDescription
commentstringOuiCommentaire du payeur.
maxLength: 500
InvoiceMetadata

Jusqu’à 20 paires, au maximum 8192 octets JSON. N’incluez pas de secrets.

object Jusqu’à 20 paires, au maximum 8192 octets JSON. N’incluez pas de secrets.

Decimal

string

RawAmount

string

Error

ChampTypeObligatoireDescription
errorobjectOui