ePay
Cette page décrit le mode ePay v2 en redirection. Elle est pensée pour être directement exploitable en qualification, sans devoir recroiser d’autres documents.
Pour les agents de coding
Section titled “Pour les agents de coding”Le plus simple consiste à télécharger llm-epay.txt et à le placer dans le projet cible. Ce fichier est une version condensée, en anglais, pensée pour les agents de coding.
Ensuite, il suffit de demander à l’agent de lire ou d’ingérer ce fichier avant de lancer l’implémentation. Exemple de demande :
Read and ingest llm-epay.txt.
Then build me a SvelteKit ePay payment module exampleusing:- brandId=XXX- merchantId=XXXFlux HTTP
Section titled “Flux HTTP”Dans cette page, le mot payload désigne le corps du POST envoyé à Nepting pour démarrer le paiement.
Le flux à retenir est le suivant :
- le site marchand prépare un formulaire ou une requête HTTP
- ce formulaire est envoyé en
POSTvers l’endpoint de paiement Nepting - Nepting affiche la page de paiement au client
- Nepting renvoie ensuite le client vers
urlSuccess,urlError,urlRefusedouurlCancel - en option, Nepting appelle aussi
urlStatusen serveur à serveur
Endpoint de qualification :
POST https://qualif.nepting.com/epay/paymentLes champs comme brandId, merchantId, amount, transactionId, urlSuccess ou signature appartiennent donc tous à ce POST vers /epay/payment.
Ce qu’il faut retenir
Section titled “Ce qu’il faut retenir”brandIdetmerchantIdsont des champs alpha et doivent être encodés en Base64 avant envoi.- La signature se calcule sur les champs déjà encodés, pas sur les valeurs brutes.
- Pour cette intégration,
merchantLabeldoit être traité comme un champ obligatoire. - Un champ seulement “facultatif” sur le papier peut rester nécessaire pour obtenir un comportement stable en qualification.
- Un payload très minimal peut être techniquement cohérent mais rester rejeté en qualif. Un payload plus riche fait mieux ressortir les vrais problèmes.
Prérequis
Section titled “Prérequis”Côté Nepting
Section titled “Côté Nepting”Avant tout test réel, il faut disposer de :
brandIdmerchantId- la clé de signature
- l’URL de paiement de qualification :
https://qualif.nepting.com/epay/payment
En qualification, la clé de test à utiliser est :
01234567890Mais cette clé ne suffit pas à elle seule. Il faut aussi que le merchantId et l’application soient bien activés côté Nepting pour ePay.
Côté marchand
Section titled “Côté marchand”Il faut préparer au minimum :
urlSuccessurlErrorurlRefused
Optionnellement :
urlCancelurlStatus
Règle d’architecture
Section titled “Règle d’architecture”La signature doit être calculée côté serveur. Il ne faut pas exposer la clé secrète dans le navigateur.
Toute stack convient si elle sait :
- encoder des chaînes UTF-8 en Base64
- calculer un SHA-256 avec une sortie Base64
- faire un
POSTHTML ou HTTP vershttps://qualif.nepting.com/epay/payment
À propos de urlStatus
Section titled “À propos de urlStatus”Ne pas activer urlStatus dans un premier test local si l’URL n’est pas :
- publique
- déclarée chez Nepting
- capable de répondre dans le format attendu
Pour un premier diagnostic, il est souvent plus simple de tester d’abord sans urlStatus.
Payload du POST vers /epay/payment
Section titled “Payload du POST vers /epay/payment”Le payload décrit dans cette section correspond aux champs envoyés dans le corps de la requête POST vers l’endpoint de paiement Nepting.
Champs obligatoires
Section titled “Champs obligatoires”Pour un flux ePay v2 exploitable, ces champs doivent être considérés comme obligatoires :
brandIdmerchantIdmerchantLabelapiVersionavec la valeur2.0transactionIdamountcurrencyCodeurlSuccessurlErrorurlRefusedsignature
Champs facultatifs mais fortement recommandés
Section titled “Champs facultatifs mais fortement recommandés”Même s’ils ne sont pas toujours strictement requis, ces champs améliorent nettement les chances d’atteindre directement la page de paiement en qualification :
transactionTypecurrencyAlphacurrencyFractionmerchantDateTimelocaleurlCancelcardHolderEmailcardHolderHomePhonecardHolderMobilePhonecardHolderWorkPhonebillingAddress,billingZipCode,billingCity,billingState,billingCountryshippingAddress,shippingZipCode,shippingCity,shippingState,shippingCountry
Payload conseillé pour le premier test
Section titled “Payload conseillé pour le premier test”Pour un premier test qui doit atteindre la page de paiement, le plus pragmatique est de partir sur un payload plus riche que le strict minimum.
Champs recommandés en plus des obligatoires :
transactionType=debitALivraisoncurrencyAlpha=EURcurrencyFraction=2merchantDateTime=YYYYMMDD-HHmmsslocale=frurlCancelcardHolderEmailcardHolderHomePhonecardHolderMobilePhonecardHolderWorkPhonebillingAddress,billingZipCode,billingCity,billingState,billingCountryshippingAddress,shippingZipCode,shippingCity,shippingState,shippingCountry
Champs à expliciter selon le besoin métier
Section titled “Champs à expliciter selon le besoin métier”Ces champs font partie d’un payload qui a bien fonctionné en qualification, mais ils ne sont pas universellement requis :
displayMerchantLabel=1enrolment=1partialAmountEnabled=1
Ils doivent rester cohérents avec le besoin métier. Par exemple, enrolment=1 implique un enrôlement du moyen de paiement.
Exemple de payload brut
Section titled “Exemple de payload brut”Les valeurs ci-dessous sont avant encodage Base64 des champs alpha.
{ "brandId": "102", "merchantId": "992781110633", "merchantLabel": "Planet Monetic ePay Test", "apiVersion": "2.0", "transactionId": "PM202603290001", "transactionType": "debitALivraison", "amount": "5000", "currencyCode": "978", "currencyAlpha": "EUR", "currencyFraction": "2", "merchantDateTime": "20260329-151611", "locale": "fr", "urlSuccess": "https://merchant.example/epay/returns/success", "urlError": "https://merchant.example/epay/returns/error", "urlRefused": "https://merchant.example/epay/returns/refused", "urlCancel": "https://merchant.example/epay/returns/cancel", "cardHolderEmail": "dev@nepting.com", "cardHolderHomePhone": "33-600050000", "cardHolderMobilePhone": "33-600050000", "cardHolderWorkPhone": "33-600050000", "billingAddress": "18 rue auguste comte", "billingZipCode": "34000", "billingCity": "Montpellier", "billingState": "OCC", "billingCountry": "250", "shippingAddress": "18 rue auguste comte", "shippingZipCode": "34000", "shippingCity": "Montpellier", "shippingState": "OCC", "shippingCountry": "250"}Règle pratique
Section titled “Règle pratique”Si un test renvoie immédiatement Error avant même l’affichage de la page de paiement :
- vérifier les champs obligatoires
- ajouter
merchantLabels’il manque - passer à un payload de départ plus riche
- ne réintroduire
urlStatusqu’une fois le reste validé
Signature
Section titled “Signature”Principe
Section titled “Principe”La signature ePay v2 suit cette logique :
- encoder en Base64 les champs alpha
- concaténer certains champs dans un ordre précis
- ajouter la clé secrète à la fin
- calculer un SHA-256 avec une sortie Base64
Champs utilisés pour la signature de requête
Section titled “Champs utilisés pour la signature de requête”Ordre de concaténation :
merchantId | transactionId | amount | currencyCode | urlSuccess | urlError | urlRefused | urlCancel | urlStatus | mopIdSi un champ facultatif est absent, il ne doit pas apparaître dans la concaténation.
Point critique
Section titled “Point critique”Les valeurs utilisées dans la concaténation sont les valeurs déjà encodées pour les champs alpha.
Exemple :
merchantIdutilisé dans la signature = version Base64 demerchantIdurlSuccessutilisé dans la signature = version Base64 de l’URL
Exemple TypeScript
Section titled “Exemple TypeScript”import { createHash } from 'node:crypto';
const alphaFields = new Set([ 'brandId', 'merchantId', 'transactionId', 'transactionType', 'merchantLabel', 'currencyAlpha', 'urlSuccess', 'urlError', 'urlRefused', 'urlCancel', 'urlStatus', 'apiVersion', 'locale']);
function encodeAlpha(value: string) { return Buffer.from(value, 'utf8').toString('base64');}
function signRequest(payload: Record<string, string>, secretKey: string) { const encoded = Object.fromEntries( Object.entries(payload).map(([key, value]) => [ key, alphaFields.has(key) ? encodeAlpha(value) : value ]) );
const orderedKeys = [ 'merchantId', 'transactionId', 'amount', 'currencyCode', 'urlSuccess', 'urlError', 'urlRefused', 'urlCancel', 'urlStatus', 'mopId' ];
const source = [ ...orderedKeys.flatMap((key) => (encoded[key] ? [encoded[key]] : [])), secretKey ].join('|');
return createHash('sha256').update(source, 'utf8').digest('base64');}Signature de réponse navigateur
Section titled “Signature de réponse navigateur”Pour une réponse v2, la vérification se fait sur :
merchantId | transactionId | result | secretKeyCas de urlStatus
Section titled “Cas de urlStatus”Pour urlStatus, vérifier la signature avant de décoder les champs Base64. Effectuer la vérification sur les valeurs reçues telles quelles.
Retours navigateur et URL Status
Section titled “Retours navigateur et URL Status”Retours navigateur
Section titled “Retours navigateur”Ces URLs servent au retour du client après le passage sur la page de paiement :
urlSuccessurlErrorurlRefusedurlCancel
Pour un premier test, urlSuccess, urlError et urlRefused doivent être présents. urlCancel est utile mais optionnelle.
urlStatus
Section titled “urlStatus”urlStatus est un callback serveur à serveur. Il ne joue pas le même rôle que les URLs de retour navigateur.
Avant activation, vérifier trois points :
- l’URL est joignable publiquement
- elle est déclarée chez Nepting
- le endpoint répond exactement dans le contrat attendu
Contrat de réponse recommandé
Section titled “Contrat de réponse recommandé”Le endpoint urlStatus doit répondre rapidement, idéalement en moins de 3 secondes.
Formats de réponse attendus :
204 No Content- ou
2xxavecContent-Type: application/jsonet ce body :
{ "status": "true"}Ce qu’il faut éviter
Section titled “Ce qu’il faut éviter”Ne pas renvoyer :
- une redirection
302 - un
200 OKen texte libre - une page HTML complète
Stratégie de test
Section titled “Stratégie de test”Pour le tout premier test de qualification :
- valider d’abord le flux avec les retours navigateur
- laisser
urlStatusdésactivé en local - n’activer
urlStatusqu’une fois la page de paiement atteinte et le callback prêt
Troubleshooting
Section titled “Troubleshooting”Symptôme : retour immédiat sur Error
Section titled “Symptôme : retour immédiat sur Error”Si Nepting renvoie immédiatement vers urlError sans afficher la page de paiement, procéder aux vérifications suivantes :
brandIdetmerchantIdsont bien ceux attendus par Nepting- les champs alpha sont bien encodés en Base64
- la signature est calculée sur les valeurs encodées
- les champs obligatoires sont présents, notamment
merchantLabel - le payload n’est pas trop minimal
Symptôme : page Nepting affichée
Section titled “Symptôme : page Nepting affichée”Si la page de paiement s’affiche, cela veut généralement dire que :
- le transport est bon
- la signature de requête est acceptable
- le couple merchant/app n’est pas rejeté immédiatement
À partir de là, les erreurs suivantes sont plutôt des erreurs de paiement ou de scénario.
Ticket non disponible
Section titled “Ticket non disponible”Ce message n’est pas forcément la vraie cause du refus. Examiner en priorité :
resultextendedResult
Le ticket correspond au reçu bancaire. S’il n’existe pas, ce message peut simplement être un effet secondaire.
Quand enrichir le payload
Section titled “Quand enrichir le payload”Si un payload strictement minimal reste rejeté, commencer par ajouter :
merchantLabeltransactionTypemerchantDateTimeurlCancel- email, téléphones et adresses
Ajouter ensuite seulement les champs plus spécifiques comme :
enrolmentpartialAmountEnabledmopId
Quand suspecter la configuration Nepting
Section titled “Quand suspecter la configuration Nepting”Le sujet est probablement côté Nepting si :
- la signature semble correcte
- le Base64 est correct
- le payload est riche
- et pourtant le merchant retombe encore en
Errorimmédiat
Dans ce cas, faire confirmer :
- le
merchantIdexact attendu - le rattachement au bon
brandId - l’activation de l’application en qualification
- les moyens de paiement autorisés sur ce merchant