Direct naar inhoud

Aan de slag

Codevoorbeelden

Kant-en-klare voorbeelden in curl, JavaScript, PHP en Python voor de meest gebruikte koppelingen.

Een kleine client

Deze helper zet de juiste headers, pakt data uit, herhaalt bij 429 en serverfouten en geeft een bruikbare fout bij 4xx. De andere JavaScript-voorbeelden gebruiken hem.

// factora.js — kleine client met foutafhandeling en 429-herhaling (Node 18+).
const BASE = 'https://factora.one/api/v1';

export async function factora(path, { method = 'GET', body, attempt = 0 } = {}) {
  const res = await fetch(BASE + path, {
    method,
    headers: {
      Authorization: `Bearer ${process.env.FACTORA_API_KEY}`,
      Accept: 'application/json',
      ...(body ? { 'Content-Type': 'application/json' } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
  });

  if ((res.status === 429 || res.status >= 500) && attempt < 4) {
    const wait = Number(res.headers.get('Retry-After')) || 2 ** attempt;
    await new Promise((resolve) => setTimeout(resolve, wait * 1000));
    return factora(path, { method, body, attempt: attempt + 1 });
  }

  const json = res.headers.get('content-type')?.includes('json') ? await res.json() : null;
  if (!res.ok) {
    throw Object.assign(new Error(json?.message ?? res.statusText), {
      status: res.status,
      errors: json?.errors,
      code: json?.error?.code,
    });
  }
  return json?.data ?? json;
}

Klant en factuur aanmaken en versturen

import { factora } from './factora.js';

const customer = await factora('/customers', {
  method: 'POST',
  body: { name: 'Jansen Bouw', email: 'info@jansenbouw.nl', city: 'Rotterdam' },
});

const invoice = await factora('/invoices', {
  method: 'POST',
  body: {
    customer_id: customer.id,
    invoice_date: new Date().toISOString().slice(0, 10),
    lines: [{ description: 'Website onderhoud', quantity: 2, unit_price: 7500, tax_rate: 21 }],
  },
});

await factora(`/invoices/${invoice.id}/send`, { method: 'POST' });
console.log(`Factuur ${invoice.invoice_number} verstuurd: € ${(invoice.total_amount / 100).toFixed(2)}`);

Alle pagina’s van een lijst ophalen

import { factora } from './factora.js';

// Alle onbetaalde, verzonden facturen ophalen.
async function allInvoices(query) {
  const items = [];
  for (let page = 1; ; page++) {
    const result = await factora(`/invoices?${query}&per_page=100&page=${page}`);
    items.push(...result.data);
    if (!result.next_page_url) return items;
  }
}

const open = await allInvoices('status=sent');
const total = open.reduce((sum, invoice) => sum + invoice.outstanding_amount, 0);
console.log(`${open.length} facturen, € ${(total / 100).toFixed(2)} openstaand`);

Betalingen registreren en betaallinks

# Deelbetaling van € 50,00 registreren
curl -X POST https://factora.one/api/v1/invoices/<invoice_id>/register-payment \
  -H "Authorization: Bearer $FACTORA_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"amount_cents": 5000, "paid_at": "2026-11-12"}'

# Openbare betaallink (Mollie/Stripe) aanmaken
curl -X POST https://factora.one/api/v1/invoices/<invoice_id>/payment-link \
  -H "Authorization: Bearer $FACTORA_API_KEY" \
  -H "Accept: application/json"

Een deelbetaling verhoogt paid_amount. Pas als het volledige bedrag binnen is, wordt de status paid. Een betaallink werkt alleen als online betalen in de organisatie aan staat.

Van offerte naar factuur

# Offerte accepteren en omzetten naar een factuur
curl -X POST https://factora.one/api/v1/quotes/<quote_id>/accept \
  -H "Authorization: Bearer $FACTORA_API_KEY" -H "Accept: application/json"

curl -X POST https://factora.one/api/v1/quotes/<quote_id>/convert \
  -H "Authorization: Bearer $FACTORA_API_KEY" -H "Accept: application/json"

PDF downloaden

curl https://factora.one/api/v1/invoices/<invoice_id>/pdf \
  -H "Authorization: Bearer $FACTORA_API_KEY" \
  -o factuur.pdf

Voeg ?inline=1 toe om de PDF in de browser te tonen in plaats van te downloaden.