Factures, solde et paiements
GET /invoices
Permissions : billing.invoices:read
| Paramètre | Type | Requis | Valeurs |
|---|---|---|---|
limit | entier | non, défaut 20 | 1 à 100 |
cursor | string | non | pagination.nextCursor de la page précédente |
status | string | non | UNPAID, PARTIALLY_PAID, PAID, OVERDUE, VOID, PARTIALLY_REFUNDED, REFUNDED |
DRAFT est accepté mais ne renvoie jamais rien : les brouillons ne sortent pas du tableau de bord.
curl -H "Authorization: Bearer $FRESHPERF_KEY" \ "https://api.freshperf.fr/v1/invoices?status=UNPAID&limit=20"
{ "data": [ { "code": "INV-202608-0082", "kind": "RENEWAL", "status": "PAID", "issuedAt": 1787727600380, "dueAt": 1788300000000, "paidAt": 1787727605569, "currency": "EUR", "totalCents": 360, "amountPaidCents": 360, "balanceDueCents": 0, "serviceCode": "SRV-TISZG5-6000", "orderNumber": "ORD-20260727-0001" } ], "pagination": { "nextCursor": "MTg4", "limit": 20 } }
| Champ | Type | Notes |
|---|---|---|
code | string | identifiant de toutes les routes de facture |
kind | string ou null | RENEWAL, UPGRADE, ONE_OFF, ADDON_ADDED, ADDON_REMOVED, ADMIN_RESIZE |
status | string | voir les valeurs du filtre ci-dessus |
issuedAt, dueAt | entier | millisecondes epoch |
paidAt | entier ou null | millisecondes epoch |
totalCents, amountPaidCents, balanceDueCents | entier | centimes, taxe comprise |
serviceCode | string ou null | le service facturé, quand la facture en concerne un |
orderNumber | string ou null | la commande d'origine |
GET /invoices/{code}
Permissions : billing.invoices:read
Reprend les champs ci-dessus, ajoute subtotalCents, discountCents, amountRefundedCents, et détaille :
Champ de lines[] | Type | Notes |
|---|---|---|
name | string | |
description | string ou null | |
quantity | entier | |
unitPriceCents, unitTaxCents, totalCents | entier | centimes |
periodStart, periodEnd | entier ou null | millisecondes epoch |
recurrence | string ou null |
Champ de payments[] | Type | Notes |
|---|---|---|
id | entier | |
status | string | PENDING, AUTHORIZED, CAPTURED, SETTLED, FAILED, CANCELLED, REFUNDED, NEEDS_REVIEW |
amountCents | entier | centimes |
currency | string ou null | |
provider | string ou null | le prestataire, ou BALANCE pour un paiement par solde |
method | string ou null | ex. CARD |
createdAt | entier | millisecondes epoch |
GET /invoices/{code}/pdf
Permissions : billing.invoices:read
Répond le fichier, pas du JSON.
| En-tête | Valeur |
|---|---|
Content-Type | application/pdf |
Content-Disposition | attachment; filename="INV-202608-0082.pdf" |
Cache-Control | private, no-store |
curl -H "Authorization: Bearer $FRESHPERF_KEY" \ -o facture.pdf \ https://api.freshperf.fr/v1/invoices/INV-202608-0082/pdf
| Erreur | Statut | Quand |
|---|---|---|
INVOICE_NOT_FOUND | 404 | code inconnu, ou facture d'un autre compte |
PDF_NOT_AVAILABLE | 503 | le document n'est pas encore rendu. Retry-After: 5 |
En erreur, le corps redevient l'enveloppe JSON habituelle.
POST /invoices/{code}/pay
Permissions : billing.invoices:pay, plus billing.saved_methods:charge avec saved_method.
En-tête obligatoire : Idempotency-Key.
Paie ce qui reste dû.
| Champ | Type | Requis | Valeurs | D'où il vient |
|---|---|---|---|---|
method | string | oui | balance, saved_method | - |
paymentMethodId | entier | oui si saved_method | > 0 | GET /payment-methods → id |
none n'est pas accepté ici : 400 VALIDATION_ERROR:method.
curl -X POST -H "Authorization: Bearer $FRESHPERF_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: pay-INV-202608-0082" \ -d '{"method":"balance"}' \ https://api.freshperf.fr/v1/invoices/INV-202608-0082/pay
{ "data": { "status": "CAPTURED", "paymentId": 244, "amountCents": 360, "invoiceCode": "INV-202608-0082", "balanceCents": 4640 } }
| Champ | Type | Notes |
|---|---|---|
status | string | NONE, FREE, ou une valeur de Payment.Status |
paymentId | entier ou null | |
amountCents | entier ou null | centimes débités |
invoiceCode | string ou null | le document réglé |
balanceCents | entier ou null | le solde après coup, seulement sur un paiement par solde |
| Erreur | Statut | Quand |
|---|---|---|
INVOICE_NOT_FOUND | 404 | code inconnu |
INVOICE_ALREADY_PAID | 400 | déjà réglée |
INVOICE_VOID, INVOICE_REFUNDED, INVOICE_NOT_ISSUED, INVOICE_BALANCE_ZERO | 400 | rien à payer sur ce document |
CURRENCY_UNSUPPORTED | 400 | devise non prise en charge |
INSUFFICIENT_BALANCE | 402 | solde trop court |
PAYMENT_DENIED | 402 | la banque a refusé |
PAYMENT_METHOD_NOT_FOUND | 404 | moyen inconnu du compte |
PAYMENT_METHOD_NOT_ACTIVE | 400 | moyen expiré ou bloqué |
API_KEY_SPENDING_CAP_EXCEEDED | 403 | le plafond de la clé ne couvre pas le montant |
PAYMENT_IN_PROGRESS | 409 | un autre paiement du même document tourne |
PAYMENT_RECORDED_MISMATCH | 409 | anomalie de rapprochement. Contactez le support |
GET /credit-notes
Permissions : billing.credit_notes:read
| Paramètre | Type | Requis | Valeurs |
|---|---|---|---|
limit | entier | non, défaut 20 | 1 à 100 |
cursor | string | non | curseur à décalage |
| Champ | Type | Notes |
|---|---|---|
code | string | AV-202608-0001 |
status | string | ISSUED ou VOID |
invoiceCode | string ou null | la facture corrigée |
currency | string ou null | |
totalCents | entier | centimes |
reason | string ou null | |
issuedAt | entier | millisecondes epoch |
GET /credit-notes/{code}/pdf
Permissions : billing.credit_notes:read
Mêmes en-têtes et mêmes erreurs que le PDF de facture, avec CREDIT_NOTE_NOT_FOUND en 404.
GET /balance
Permissions : billing.balance:read
{ "data": { "enabled": true, "balanceCents": 4400, "currency": "EUR", "autoRenewFromBalance": false } }
| Champ | Type | Notes |
|---|---|---|
enabled | booléen | false quand le solde prépayé n'est pas ouvert sur la plateforme |
balanceCents | entier | centimes disponibles |
currency | string ou null | ISO 4217 |
autoRenewFromBalance | booléen | le compte a opté pour payer ses renouvellements par le solde |
Le solde s'alimente depuis le tableau de bord. L'API le dépense, elle ne le recharge pas.
GET /balance/transactions
Permissions : billing.balance:read
| Paramètre | Type | Requis | Valeurs |
|---|---|---|---|
limit | entier | non, défaut 20 | 1 à 100 |
cursor | string | non | curseur à décalage |
{ "data": [ { "id": 62, "type": "RENEWAL_APPLIED", "amountCents": -300, "balanceAfterCents": 4400, "currency": "EUR", "reason": "Invoice INV-202608-0087", "relatedPaymentId": null, "createdAt": 1787907506000 } ] }
| Champ | Type | Notes |
|---|---|---|
id | entier | |
type | string ou null | voir le tableau ci-dessous |
amountCents | entier | signé : positif au crédit, négatif au débit |
balanceAfterCents | entier | le solde juste après ce mouvement |
reason | string ou null | libellé libre |
relatedPaymentId | entier ou null | renvoie à payments[].id d'une facture |
createdAt | entier | millisecondes epoch |
type | Sens |
|---|---|
TOPUP, TOPUP_CARD, TOPUP_PAYPAL, TOPUP_SAVED | rechargement, selon le moyen employé |
PAYMENT_APPLIED | le solde a payé une commande ou une facture |
RENEWAL_APPLIED | le solde a payé un renouvellement |
PAYMENT_REVERSED | un paiement par solde a été annulé |
REFUND_TO_BALANCE | un remboursement est revenu sur le solde |
REFERRAL_CREDIT | gain de parrainage |
ADMIN_CREDIT, ADMIN_DEBIT | geste commercial ou correction |
GET /payment-methods
Permissions : billing.payment_methods:read
Liste complète, sans pagination.
{ "data": [ { "id": 14, "type": "CARD", "status": "ACTIVE", "displayName": "MASTERCARD ••••0011", "brand": "MASTERCARD", "last4": "0011", "expMonth": 9, "expYear": 2028, "isDefault": true } ] }
| Champ | Type | Notes |
|---|---|---|
id | entier | à repasser en paymentMethodId |
type | string | CARD, SEPA_DIRECT_DEBIT, BANK_TRANSFER, PAYPAL, APPLE_PAY, GOOGLE_PAY, OTHER |
status | string | ACTIVE, INACTIVE, PENDING_VERIFICATION, EXPIRED, BLOCKED |
displayName | string ou null | libellé masqué. Une adresse PayPal y est partiellement cachée |
brand, last4 | string ou null | cartes |
expMonth, expYear | entier ou null | cartes |
isDefault | booléen | le moyen que account_default emploie |
Seul un moyen en ACTIVE est débitable. Ajouter ou retirer un moyen se fait dans le tableau de bord.
Ce que la clé a dépensé
GET /me et GET /me/key rendent key.spendingCapCents et key.spendingRemainingCents : le plafond de la clé sur 30 jours glissants et ce qu'il en reste. Le détail des débits se lit dans le journal de la clé, dans le tableau de bord.