Paiements
Intégration des paiements & Widget
L’intégration des paiements avec Wealth Reader se fait en deux phases : la préparation de l’intention immuable dans votre backend et l’assemblage du widget sécurisé dans le frontend.
La clé API (X-API-Key) ne devrait jamais apparaître dans le HTML, le JavaScript client, les journaux du navigateur ou les paramètres URL.
1. Annuaire des entités bancaires
Pour savoir quelles banques sont disponibles et obtenir leurs logos, noms et exigences, vous pouvez vérifier le point de terminaison de l’entité directement depuis son backend. Chaque entité est équipée de deux logos : logo, celui que Wealth Reader recommande d’afficher (son propre logo vectoriel lorsqu’il existe, sinon le logo du fournisseur, selon logo_source), et logo_fallback, celui du fournisseur, afin que son interface puisse l’utiliser si le premier ne se charge pas :
curl --request GET 'https://api.wealthreader.com/payments/entities/?country=ES'
Ce point de terminaison est public : N’envoyez pas X-API-Key. Cela ne change pas la réponse, cela consomme un appel de votre quota, et si les paiements étaient désactivés sur votre compte, cela transformerait une requête en fonctionnement en 503.
Il prend également en charge des paramètres de requête optionnels :
country: code ISO à deux lettres (par exempleES,FR,DE,IT,PT...). AvecALLou vide, il n’est pas filtré par pays.search(aliasq) : recherche textuelle par nom ou code (par exemplesantander,bbva).code- Récupère une entité spécifique par son code exact.payment_method: Filtrer par méthode prise en charge (par exemplesepa_credit_transfer).limitetoffset: pagination des résultats.
Exemple de réponse courte :
{
"success": true,
"total": 2,
"entities": [
{
"code": "santander-es",
"name": "Banco Santander",
"country": "ES",
"logo": "https://cdn.wealthreader.com/santander.svg",
"logo_fallback": "https://assets.exthand.com/bsdk/banks/logos/ES/santander.svg",
"logo_source": "wealthreader",
"payment_methods": ["sepa_credit_transfer", "instant_sepa_credit_transfer"],
"requires_debtor_iban": true
},
{
"code": "bbva-es",
"name": "BBVA",
"country": "ES",
"logo": "https://cdn.wealthreader.com/bbva.svg",
"logo_fallback": "https://assets.exthand.com/bsdk/banks/logos/PT/bbva.svg",
"logo_source": "wealthreader",
"payment_methods": ["sepa_credit_transfer", "instant_sepa_credit_transfer"],
"requires_debtor_iban": false
}
]
}
Modèle recommandé pour afficher le logo avec repli automatique :
<img src="https://cdn.wealthreader.com/santander.svg"
data-fallback="https://assets.exthand.com/bsdk/banks/logos/ES/santander.svg"
alt="Banco Santander" width="160" height="48"
onerror="if (this.dataset.fallback && this.src !== this.dataset.fallback) { this.src = this.dataset.fallback; } else { this.hidden = true; }">
Dans /payments/entities/ les deux champs sont toujours présents et sont null lorsqu’il n’y a pas de logo. Les institutions POST /payments/?action=profile-institutions et widget portent les mêmes logo et logo_fallback comme champs optionnels : ils manquent lorsqu’il n’y a pas de logo utilisable. Les logos ne pointent qu’à cdn.wealthreader.com ou assets.exthand.com; si votre page a un CSP, ajoutez les deux hôtes à img-src.
Profils gérés (comme la démonstration de don) : Si vous utilisez un profil préconfiguré comme
cruz_roja_demo, vérifiez les institutions et conditions définies par le serveur en appelantPOST /payments/?action=profile-institutionsavec le corps{"profile": "cruz_roja_demo"}.
2. Créer une intention de paiement en arrière-plan
Lorsque le client décide de payer à la caisse, son serveur génère une clé d’idempotence unique et demande la création immuable du paiement à l’API de Wealth Reader.
Modèle standard pour les commerçants (bénéficiaire propre)
Le commerçant spécifie son compte de recouvrement, le montant en centimes (amount_minor), la référence de paiement et l’origine web où le widget sera chargé :
: "${WR_API_KEY:?Defina WR_API_KEY en el entorno seguro de su backend}"
: "${WR_PAYMENT_IDEMPOTENCY_KEY:?Genere una clave UUID v4 o de alta entropía para este intento}"
curl --request POST 'https://api.wealthreader.com/payments/?action=create' \
--header 'Content-Type: application/json' \
--header "X-API-Key: ${WR_API_KEY}" \
--header "Idempotency-Key: ${WR_PAYMENT_IDEMPOTENCY_KEY}" \
--data '{
"amount_minor": 1500,
"currency": "EUR",
"beneficiary": {
"name": "Comercio Online S.L.",
"iban": "ES9121000418450200051332"
},
"reference": "Pedido #78901",
"customer_reference": "pedido-78901",
"allowed_origin": "https://tienda.example.com",
"allowed_institution_codes": ["santander-es", "bbva-es", "caixabank-es", "sabadell-es"],
"locale": "es"
}'
Note : allowed_institution_codes est optionnel. Si c’est omis, l’utilisateur pourra choisir parmi toutes les entités du catalogue.
Modèle avec profil géré (démonstration de don)
Si vous intégrez le profil géré cruz_roja_demo:
curl --request POST 'https://api.wealthreader.com/payments/?action=create' \
--header 'Content-Type: application/json' \
--header "X-API-Key: ${WR_API_KEY}" \
--header "Idempotency-Key: ${WR_PAYMENT_IDEMPOTENCY_KEY}" \
--data '{
"profile": "cruz_roja_demo",
"institution_code": "santander-es",
"amount_minor": 100,
"customer_reference": "donativo-demo-0042",
"allowed_origin": "https://tienda.example.com",
"locale": "es",
"expected_mode": "live"
}'
Réponse de l’API
L’API répond en confirmant l’intention immuable et en livrant les données pour initialiser le widget :
{
"success": true,
"payment": {
"id": "11111111-1111-4111-8111-111111111111",
"amount_minor": 1500,
"currency": "EUR",
"state": "ready",
"interaction_status": "not_started",
"payment_status": "not_initiated",
"payment_attestation": {
"mode": "live",
"provider_binding": "PROVIDER_BINDING"
},
"widget": {
"url": "https://widget.wealthreader.com/payments/",
"token": "SHORT_LIVED_WIDGET_TOKEN",
"expires_at": "2026-09-04T15:30:00+00:00"
}
}
}
Votre backend ne doit livrer au navigateur de l’utilisateur que les payment.id et payment.widget.token.
3. Monter le widget dans le frontend
Il existe deux façons de monter le widget dans votre interface web : en utilisant le script déclaratif officiel ou en utilisant l’API JavaScript programmatique.
Option A : via un script déclaratif (load-payments.js)
Intégrez le contenant et le chargeur sur votre page de paiement :
<div id="wr-payment-container"></div>
<script>
document.querySelector('#wr-payment-container').addEventListener(
'wealthreader:payment',
(event) => {
console.log('Evento de pago recibido:', event.detail.type, event.detail);
if (event.detail.type === 'payment_status') {
console.log('Estado actual:', event.detail.status);
}
if (event.detail.type === 'flow_closed') {
// La interacción del usuario ha finalizado.
// Consulte el estado financiero definitivo desde su backend.
}
}
);
</script>
<script
src="https://widget.wealthreader.com/js/load-payments.js"
data-target="#wr-payment-container"
data-payment-intent-id="11111111-1111-4111-8111-111111111111"
data-widget-token="SHORT_LIVED_WIDGET_TOKEN"
data-locale="es">
</script>
Option B : via JavaScript API (WealthReaderPayments.mount)
Si vous utilisez des frameworks comme React, Vue, Angular ou un flux SPA :
import { useEffect, useRef } from 'react';
// Cargue previamente https://widget.wealthreader.com/js/load-payments.js
const target = document.getElementById('wr-payment-container');
// Los eventos llegan como CustomEvent del DOM sobre el propio contenedor.
target.addEventListener('wealthreader:payment', (event) => {
const detail = event.detail;
if (detail.type === 'payment_status') {
console.log('Estado del pago:', detail.status);
}
if (detail.type === 'flow_closed') {
// Notificar al backend para comprobar la liquidación
}
});
window.WealthReaderPayments.mount({
target: target,
paymentIntentId: '11111111-1111-4111-8111-111111111111',
widgetToken: 'SHORT_LIVED_WIDGET_TOKEN',
locale: 'es'
});
mount() ne prend en charge aucun callback : ses clés sont target, paymentIntentId, widgetToken, locale, widgetOrigin et apiOrigin. Tout autre est silencieusement ignoré, donc un onEvent passé dans la configuration ne tomberait pas en panne et ne serait jamais exécuté. Écoutez toujours l’événement wealthreader:payment du conteneur.
Le widget obtient la configuration directement depuis les serveurs Wealth Reader avec le jeton à usage unique. Si la banque exige que le compte de débit soit identifié avant de rediriger, le widget demande l’IBAN du compte débité directement au payeur, sans que le commerçant ait à le traiter.
Événements principaux du Widget
type |
Signification |
|---|---|
ready |
Le widget a été initialisé et des informations immuables sont disponibles. |
authorization_started |
L’utilisateur a initié l’autorisation bancaire (redirigée vers SCA ou une application bancaire). |
processing |
L’authentification bancaire est terminée et le système traite l’opération. |
payment_status |
Signaler un changement de statut de paiement (pending, settled, rejected, etc.). |
height_changed |
Ajustement dynamique de la hauteur de l’iframe pour éviter les barres de défilement. |
flow_closed |
L’utilisateur a fermé le widget ou l’interaction technique a pris fin. |
L’événement flow_closed confirme uniquement la fermeture de la fenêtre et ne constitue pas une confirmation de paiement. Votre backend doit toujours vérifier le statut via l’appel serveur-à-serveur.
Étape suivante
Consultez Intentions et idempotence.