Menu

Blaya Developers

Télécharger le contrat OpenAPI 3.1

API V1 · version 2026-09-18 · sandbox

Ajoutez le paiement sécurisé pour freelances à votre logiciel — gratuitement. Le client paie 3 % TTC, le freelance reçoit 100 % du montant de sa prestation. Le paiement se déroule sur le checkout hébergé Blaya.

Ouvrir ma sandbox

Un exemple exécutable

Télécharger le quickstart Node.js

Node.js 24.19 ou supérieur. Définissez BLAYA_BASE_URL, BLAYA_TEST_KEY et BLAYA_FREELANCER_EMAIL dans l’environnement privé de votre serveur, puis exécutez node partner-quickstart.mjs. N’insérez jamais la clé dans votre frontend. Les références facultatives BLAYA_EXTERNAL_REFERENCE et BLAYA_FREELANCER_REFERENCE doivent rester stables lors des reprises.

La première exécution invite le freelance. Après sa connexion, son MFA et son autorisation, la suivante crée une demande fictive de 100 € et lit son état persistant. Elle ne débite aucune carte. Si le prestataire ou le KYC bloque le paiement test, ce blocage reste visible : ne forcez pas le statut.

1. Authentification serveur

Créez une clé avec MFA récente. Elle n’est affichée qu’une fois. Stockez-la dans votre gestionnaire de secrets. Limitez ses droits ; créez une nouvelle clé puis révoquez l’ancienne pour effectuer une rotation.

Authorization: Bearer $BLAYA_TEST_KEY
Blaya-Version: 2026-09-18
Content-Type: application/json
Idempotency-Key: unique-operation-id

120 appels par minute et par partenaire. Les clés ne fonctionnent que dans leur environnement. Aucune clé live n’est disponible.

2. Inviter un freelance

POST /api/v1/freelancers
{"email":"freelancer@example.invalid","external_reference":"vendor-42","locale":"fr"}

Droit freelancers:write. GET /api/v1/freelancers/{id} retourne le statut courant. Conservez l’id retourné et le lien onboarding_url. Le freelance se connecte ou s’inscrit avec cette adresse vérifiée puis autorise votre logiciel dans Intégrations. Aucun compte Stripe supplémentaire n’est créé. Une invitation ne prouve pas que le compte existe ou que le KYC est terminé.

3. Créer un paiement

POST /api/v1/payment-requests
{"freelancer_id":"UUID_FROM_STEP_2","amount":10000,"currency":"EUR","description":"Website design","external_reference":"invoice-104","locale":"fr"}

Droit requests:write. Montant entier en centimes : 10000 = 100 €. Redirigez le navigateur vers checkout_url, sans iframe. Le checkout vérifie le bénéficiaire, le KYC, les limites, les frais et l’authentification bancaire avec le moteur commun. Une demande créée ou un retour navigateur ne prouve jamais un paiement.

GET /api/v1/payment-requests/{id}

Droit requests:read. Consultez payment_state et release_state. Un transfert confirmé ne signifie pas un virement bancaire confirmé. Les dates J7/J30 partent de la capture.

Contexte client facultatif

Vous pouvez ajouter client: {name, email, reference?} à la création d’une demande. Ce contexte est chiffré et visible uniquement par le freelance dans son espace privé. Il ne vérifie pas le payeur, ne préremplit pas un email considéré comme validé, ne déclenche aucun débit et n’est jamais inclus dans les webhooks. Le client confirme ses propres informations au checkout.

4. Documents privés

Droit documents:write. POST /api/v1/documents transmet les octets PDF/JPEG/PNG (10 Mio maximum) avec Content-Type, X-Freelancer-ID, X-Document-ID (UUID), X-Document-Batch (UUID), X-File-Name encodé en URI et Idempotency-Key.

Interrogez GET /api/v1/documents/{id}. Attendez clean puis POST au même endpoint avec {"action":"confirm"}. Ajoutez ensuite document_ids à la création de la demande (3 maximum). Une panne de scan conserve la quarantaine ; action retry permet une reprise bornée. Vous ne pouvez consulter que le statut de vos propres dépôts, jamais les documents privés déjà présents chez le freelance.

5. Webhooks signés

Dans l’espace partenaire, configurez une URL HTTPS publique avec une authentification MFA récente. Le secret est affiché une seule fois et se renouvelle à chaque enregistrement. Configurez votre récepteur avant de reprendre les livraisons. Les endpoints privés, les paramètres d’URL, les redirections et les ports autres que 443 sont refusés.

Blaya-Signature: t=TIMESTAMP,v1=HEX_HMAC_SHA256
Blaya-Event-ID: UUID

HMAC input = TIMESTAMP + "." + RAW_REQUEST_BODY

Vérifiez en temps constant la signature, refusez un timestamp décalé de plus de 300 secondes, puis dédupliquez l’id de l’événement. Répondez 2xx après persistance durable, avant le travail lent. Une réponse 3xx est un échec. Ne déduisez pas l’ordre des événements de leur ordre d’arrivée ; GET /api/v1/payment-requests/{id} donne l’état courant.

payment.created · payment.captured · release.scheduled · release.extended · claim.opened · claim.resolved · transfer.completed · refund.completed

GET /api/v1/events/{id} (droit events:read) retourne le corps de l’événement. Aucun document, email client, donnée KYC ou identifiant PSP n’est inclus. L’espace partenaire permet le test, l’inspection, la pause, la rotation et la relivraison sous MFA. Une relivraison conserve l’identifiant et les octets du corps.

8 tentatives automatiques maximum par série, avec délais de 30 s, 2 min, 10 min, 1 h, 6 h, 12 h puis 24 h. Après 8 échecs consécutifs, l’endpoint est suspendu et son administrateur est averti. Un timeout reste inconnu. Les reprises manuelles sont bornées à 40 tentatives cumulées par événement/endpoint. En mode mock, un récepteur local vérifie la signature ; aucune livraison HTTPS externe n’est revendiquée.

Idempotence et erreurs

Conservez une clé stable par écriture et réessayez avec exactement les mêmes données après timeout. La même clé avec un contenu différent renvoie 409. external_reference est unique par partenaire. Les réponses n’exposent ni clés PSP, ni données KYC, ni document brut.

  • 401 invalid_api_key
  • 403 api_key_or_scope_invalid
  • 404 not_found
  • 409 idempotency_conflict / freelancer_onboarding_required / document_not_ready
  • 422 invalid_input / total_limit
  • 429 rate_limited
  • 503 provider_unavailable

Utilisez le code machine et la référence requestId pour le support. Ne journalisez jamais l’en-tête Authorization ni le corps d’un document.

Scénarios de recette

  1. Vérifiez une demande répétée avec la même clé : un seul identifiant ; un contenu différent doit renvoyer 409.
  2. Révoquez une clé puis vérifiez le refus des nouveaux appels. Retirez l’autorisation du logiciel côté freelance : les nouvelles demandes sont bloquées, les anciennes restent suivies.
  3. Depuis le dashboard, envoyez un événement test, vérifiez la signature et sa déduplication, puis testez un refus HTTP et la reprise. Une relivraison garde le même événement.
  4. Avec un compte de paiement test éligible, parcourez le checkout, l’authentification bancaire, puis le suivi client. Vérifiez capture, prolongation, réclamation et résolution dans leurs parcours autorisés. Les tests serveur isolés couvrent les échéances concurrentes ; aucune API partenaire ne permet de modifier l’horloge ou de forcer un transfert.

Changelog

2026-09-18 · V1 sandbox

Première version du contrat public : invitations et consentement, demandes et pièces privées, statuts, contexte client facultatif, événements signés et dashboard. Une version non reconnue renvoie une erreur ; aucune clé live n’est émise par cette version.