Skip to content

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.

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 example
using:
- brandId=XXX
- merchantId=XXX

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 :

  1. le site marchand prépare un formulaire ou une requête HTTP
  2. ce formulaire est envoyé en POST vers l’endpoint de paiement Nepting
  3. Nepting affiche la page de paiement au client
  4. Nepting renvoie ensuite le client vers urlSuccess, urlError, urlRefused ou urlCancel
  5. en option, Nepting appelle aussi urlStatus en serveur à serveur

Endpoint de qualification :

POST https://qualif.nepting.com/epay/payment

Les champs comme brandId, merchantId, amount, transactionId, urlSuccess ou signature appartiennent donc tous à ce POST vers /epay/payment.

  1. brandId et merchantId sont des champs alpha et doivent être encodés en Base64 avant envoi.
  2. La signature se calcule sur les champs déjà encodés, pas sur les valeurs brutes.
  3. Pour cette intégration, merchantLabel doit être traité comme un champ obligatoire.
  4. Un champ seulement “facultatif” sur le papier peut rester nécessaire pour obtenir un comportement stable en qualification.
  5. 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.

Avant tout test réel, il faut disposer de :

  • brandId
  • merchantId
  • la clé de signature
  • l’URL de paiement de qualification : https://qualif.nepting.com/epay/payment

En qualification, la clé de test à utiliser est :

01234567890

Mais 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.

Il faut préparer au minimum :

  • urlSuccess
  • urlError
  • urlRefused

Optionnellement :

  • urlCancel
  • urlStatus

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 POST HTML ou HTTP vers https://qualif.nepting.com/epay/payment

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.

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.

Pour un flux ePay v2 exploitable, ces champs doivent être considérés comme obligatoires :

  • brandId
  • merchantId
  • merchantLabel
  • apiVersion avec la valeur 2.0
  • transactionId
  • amount
  • currencyCode
  • urlSuccess
  • urlError
  • urlRefused
  • signature

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 :

  • transactionType
  • currencyAlpha
  • currencyFraction
  • merchantDateTime
  • locale
  • urlCancel
  • cardHolderEmail
  • cardHolderHomePhone
  • cardHolderMobilePhone
  • cardHolderWorkPhone
  • billingAddress, billingZipCode, billingCity, billingState, billingCountry
  • shippingAddress, shippingZipCode, shippingCity, shippingState, shippingCountry

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=debitALivraison
  • currencyAlpha=EUR
  • currencyFraction=2
  • merchantDateTime=YYYYMMDD-HHmmss
  • locale=fr
  • urlCancel
  • cardHolderEmail
  • cardHolderHomePhone
  • cardHolderMobilePhone
  • cardHolderWorkPhone
  • billingAddress, billingZipCode, billingCity, billingState, billingCountry
  • shippingAddress, 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=1
  • enrolment=1
  • partialAmountEnabled=1

Ils doivent rester cohérents avec le besoin métier. Par exemple, enrolment=1 implique un enrôlement du moyen de paiement.

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"
}

Si un test renvoie immédiatement Error avant même l’affichage de la page de paiement :

  1. vérifier les champs obligatoires
  2. ajouter merchantLabel s’il manque
  3. passer à un payload de départ plus riche
  4. ne réintroduire urlStatus qu’une fois le reste validé

La signature ePay v2 suit cette logique :

  1. encoder en Base64 les champs alpha
  2. concaténer certains champs dans un ordre précis
  3. ajouter la clé secrète à la fin
  4. 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 | mopId

Si un champ facultatif est absent, il ne doit pas apparaître dans la concaténation.

Les valeurs utilisées dans la concaténation sont les valeurs déjà encodées pour les champs alpha.

Exemple :

  • merchantId utilisé dans la signature = version Base64 de merchantId
  • urlSuccess utilisé dans la signature = version Base64 de l’URL
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');
}

Pour une réponse v2, la vérification se fait sur :

merchantId | transactionId | result | secretKey

Pour urlStatus, vérifier la signature avant de décoder les champs Base64. Effectuer la vérification sur les valeurs reçues telles quelles.

Ces URLs servent au retour du client après le passage sur la page de paiement :

  • urlSuccess
  • urlError
  • urlRefused
  • urlCancel

Pour un premier test, urlSuccess, urlError et urlRefused doivent être présents. urlCancel est utile mais optionnelle.

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 :

  1. l’URL est joignable publiquement
  2. elle est déclarée chez Nepting
  3. le endpoint répond exactement dans le contrat attendu

Le endpoint urlStatus doit répondre rapidement, idéalement en moins de 3 secondes.

Formats de réponse attendus :

  • 204 No Content
  • ou 2xx avec Content-Type: application/json et ce body :
{
"status": "true"
}

Ne pas renvoyer :

  • une redirection 302
  • un 200 OK en texte libre
  • une page HTML complète

Pour le tout premier test de qualification :

  1. valider d’abord le flux avec les retours navigateur
  2. laisser urlStatus désactivé en local
  3. n’activer urlStatus qu’une fois la page de paiement atteinte et le callback prêt

Si Nepting renvoie immédiatement vers urlError sans afficher la page de paiement, procéder aux vérifications suivantes :

  1. brandId et merchantId sont bien ceux attendus par Nepting
  2. les champs alpha sont bien encodés en Base64
  3. la signature est calculée sur les valeurs encodées
  4. les champs obligatoires sont présents, notamment merchantLabel
  5. le payload n’est pas trop minimal

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.

Ce message n’est pas forcément la vraie cause du refus. Examiner en priorité :

  • result
  • extendedResult

Le ticket correspond au reçu bancaire. S’il n’existe pas, ce message peut simplement être un effet secondaire.

Si un payload strictement minimal reste rejeté, commencer par ajouter :

  • merchantLabel
  • transactionType
  • merchantDateTime
  • urlCancel
  • email, téléphones et adresses

Ajouter ensuite seulement les champs plus spécifiques comme :

  • enrolment
  • partialAmountEnabled
  • mopId

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 Error immédiat

Dans ce cas, faire confirmer :

  • le merchantId exact attendu
  • le rattachement au bon brandId
  • l’activation de l’application en qualification
  • les moyens de paiement autorisés sur ce merchant