Introduction
Mercanet est une solution de paiement de commerce électronique multicanale sécurisée conforme à la norme PCI DSS. Elle vous permet d’accepter et de gérer des transactions de paiement en prenant en compte les règles métiers liées à votre activité (paiement à la livraison, paiement différé, paiement récurrent, paiement en plusieurs fois, …).
L’objectif du présent document est d’expliquer la mise en œuvre de la solution Paypage POST jusqu’au démarrage en production.
A qui s’adresse ce document
Ce document est destiné aux commerçants qui souhaitent souscrire à l’offre Mercanet et utiliser un connecteur basé sur des échanges HTTPS en mode POST entre leur site web et les serveurs de paiement Paypage POST.
C’est un guide d’implémentation qui s’adresse à votre équipe technique.
Pour avoir une vue d’ensemble de la solution Mercanet, nous vous conseillons de consulter les documents suivants :
- Présentation fonctionnelle
- Guide de configuration des fonctionnalités
Prérequis
Une connaissance élémentaire des standards relatifs aux langages de programmation Web pratiqués aujourd’hui, tels que Java, PHP ou .Net, est nécessaire pour développer la connexion à Paypage POST.
Gestion de la clé secrète
Lors de votre inscription, BNP Paribas met à disposition sur Mercanet Téléchargement (voir votre guide de démarrage rapide, annexe « Télécharger la clé secrète »), une clé secrète qui permet de sécuriser les échanges entre votre site et le serveur Mercanet.
Vous êtes responsable de sa conservation et devez prendre toutes les mesures pour :
- en restreindre l'accès ;
- la sauvegarder de manière chiffrée ;
- ne jamais la copier sur un disque non sécurisé ;
- ne jamais l'envoyer (e-mail, courrier) de manière non sécurisée.
La compromission de la clé secrète (et son utilisation par un tiers malveillant) perturberait le fonctionnement normal de votre boutique, et pourrait notamment générer des transactions et des opérations de caisse injustifiées (des remboursements par exemple).
C’est la même clé secrète qui est utilisée sur les différents connecteurs Paypage, Office (M2M), In-App et Walletpage.
Comprendre le paiement avec Paypage POST
Le principe général d’un processus de paiement est le suivant :
1. Lorsque le client procède au paiement, une requête de paiement doit être envoyée au connecteur Paypage POST. BNP Paribas vous fournit l’URL de ce connecteur. La requête est alors vérifiée, et chiffrée si elle est valable (elle est nommée RedirectionData dans le système). La requête est envoyée au moyen d’un formulaire en mode POST via HTTPS. Toute autre solution capable d’envoyer une requête de cette nature fonctionne également.
2. Paypage POST redirige l’application appelante vers les pages de paiement Mercanet. Le client doit saisir les informations du moyen de paiement pour que le serveur de paiement Mercanet prenne en charge la transaction. Il convient de noter que les détails du paiement peuvent être saisis directement sur le serveur qui propose le moyen de paiement (par exemple dans le cas de PayPal ou d’un mandat Sepa). À la fin du processus de paiement, qu’il soit réussi ou non, deux réponses sont créées et envoyées à l’adresse URL précisée lors du 1er flux.
Il y a deux notifications de réponses indépendantes :
3. Les réponses manuelles sont envoyées via la méthode HTTP(S) POST par le serveur de paiement à l’URL de réponse manuelle. Cette URL est précisée dans la requête de paiement et est utilisée lorsque le client clique sur le bouton « Continuer » de la page de paiement. Elle est la page de destination vers laquelle le client est redirigé à la fin du paiement. Comme il n’y a aucune garantie que le client clique sur ce bouton, vous n’avez aucune garantie de recevoir la réponse manuelle.
4. Les réponses automatiques sont envoyées indépendamment des réponses manuelles. Elles utilisent également les requêtes HTTP(S) POST envoyées par les serveurs de paiement Mercanet mais cette fois-ci moyennant l’URL de réponse automatique précisée dans la requête de paiement. Cela signifie que vous recevez la réponse dès que le paiement est effectué dans les pages de paiement Mercanet.
Démarrer avec Paypage POST en 5 étapes
Étape 1 : inscrire la boutique
Afin d’inscrire votre boutique, vous devez remplir le formulaire d’inscription envoyé par BNP Paribas et le retourner à ce dernier.
Lors de la saisie du formulaire, vous désignez un contact administratif et un contact technique afin que BNP Paribas puisse vous communiquer les informations nécessaires pour démarrer votre boutique.
BNP Paribas procède alors à l’enregistrement de la boutique et vous retourne votre identifiant commerçant (merchantId) ainsi que vos identifiants et mots de passe Merchant Extranet (récupération de la clé secrète et gestion de caisse).
L’inscription de la boutique n’est pas nécessaire pour commencer à intégrer le connecteur et à tester la connexion sur l’environnement de simulation. Vous pouvez ne demander l’inscription de votre boutique qu’au moment de faire les tests en production.
Étape 2 : effectuer un paiement
La requête paiement est envoyée depuis une page de votre site web vers le serveur Mercanet via un formulaire web avec la méthode POST.
Générer la requête de paiement
Trois données obligatoires sont renseignées dans la requête de paiement.
Nom de la donnée | Description |
---|---|
Data | Contient toutes les informations relatives à la transaction. |
InterfaceVersion | Définit la version de la requête et de la réponse échangée avec le serveur Mercanet. |
Seal | Utilisé pour valider l’intégrité des données échangées. La donnée Seal est calculée à l’aide de la donnée Data et de la clé secrète. |
Des données optionnelles supplémentaires sont disponibles :
Nom de la donnée | Description |
---|---|
Encode | Précise la méthode utilisée pour encoder la donnée Data. |
SealAlgorithm | Précise l’algorithme utilisé pour calculer la donnée Seal. |
Syntaxe de la donnée Data
La donnée Data est construite conformément au format suivant :
<nomChamp1>=<valeurChamp1>|<nomChamp2>=<valeurChamp2>|…|<nomChampN>=<valeurChampN>
Tous les champs nécessaires pour la transaction (voir les détails dans le dictionnaire de données) doivent être inclus dans la chaîne de caractères. L’ordre des champs n’a pas d’importance.
Exemple d’une requête de paiement de 55 euros :
amount=5500|currencyCode=978|merchantId=011223744550001|normalReturnUrl=http://www.normalreturnurl.com|transactionReference=534654|keyVersion=1
Il est possible d’avoir une liste de valeurs pour un même champ :
..|nomChamp=valeur1,valeur2, … ,valeurX|…
Exemple avec le champ paymentMeanBrandList valorisé avec VISA et MASTERCARD :
…|amount=5500|currencyCode=978|merchantId=011223744550001|normalReturnUrl=http://www.normalreturnurl.com|transactionReference=534654[paymentMeanBrandList=VISA,MASTERCARD|keyVersion=1|…
Si le champ est un container, vous devez utiliser un point entre le nom du container et le nom du champ :
..|Container.nomChamp1=valeurChamp1|container.nomChamp2=valeurChamp2|……
Exemple pour le champ customerContact contenant l’email moi@email.com et le nom et prénom Jean Dupont du client :
…|customerContact.email=moi@email.com|customerContact.firstname=Jean|customerContact.lastname=Dupont|…
Si un champ contient une liste d’objets complexes, sa représentation est construite conformément au format suivant :
..|<champ1>=<valeur1>| <nomObjet>.<nomItem= {<nomChampA1>=<valeurChampA1>,<nomChampA2>=<valeurChampA2>}, {<nomChampB1>=<valeurChampB1>,<nomChampB2>=<valeurChampB2>}, {<nomChampC1>=<valeurChampC1>,<nomChampC2>=<valeurChampC2>}| <nomChamp2>=<valeurChamp2>|……
Exemple d’une requête de paiement avec une liste d’objets complexes pour le champ shoppingCartDetail contenant trois produits nommés apple, mango et pear :
amount=5500|currencyCode=978|merchantId=011223744550001|normalReturnUrl=http://www.normalreturnurl.com
|transactionReference=534654|shoppingCartDetail.shoppingCartItemList={productName=apple,
productDescription=red},{productName=pear,productDescription=green},{productName=mango,productDescription=yellow}|keyVersion=1
Encodage de la donnée Data
Si la donnée Data comporte des caractères spéciaux (comme par exemple des caractères accentués) alors elle doit être encodée en base64 ou base64Url.
Présence des champs de la requête
Certains champs de la requête de paiement ne sont obligatoires que :
- lors de l'utilisation de certains moyens de paiement ; veuillez consulter le guide du moyen de paiement concerné pour savoir quels champs sont obligatoires ;
- en fonction de la configuration de votre boutique ; veuillez consulter le Guide de configuration des fonctionnalités pour savoir quels champs sont obligatoires ;
- dans certains cas d'usages (ex : paiement récurrent) ; veuillez consulter le Guide de configuration des fonctionnalités pour savoir quels champs sont obligatoires.
Ces champs sont désignés avec la mention « conditionnel ».
Sécuriser la requête
La requête contient les paramètres de la transaction et est envoyée par le navigateur Web du client. Il est théoriquement possible pour un pirate d’intercepter la demande et de la modifier avant l’envoi au serveur de paiement.
De ce fait, il est nécessaire de renforcer la sécurité pour assurer l’intégrité des paramètres de la transaction envoyée. Mercanet répond à ce besoin par un échange de signatures qui permet de vérifier :
- l’intégrité des messages requête et réponse ;
- l’authentification de l’émetteur et du destinataire car ils se partagent la même clé secrète.
Comment sécuriser la requête
La sécurisation de la requête est effectuée en calculant la valeur « hashée » conformément aux paramètres de la transaction (donnée Data). Ensuite, la clé secrète y est ajoutée. Toutes les chaînes de caractères sont converties en UTF-8 avant le « hashage ».
L’algorithme de « hashage » génère un résultat irréversible. Lorsqu’un tel message est reçu, le destinataire doit recalculer la valeur « hashée » pour la comparer à celle reçue. Toute différence indique que les données échangées ont été falsifiées ou que le destinataire et l’émetteur ne partagent pas la même clé secrète.
Le résultat doit être envoyé sous forme hexadécimale dans la donnée nommée Seal.
Calcul de la donnée Seal
Algorithme HMAC-SHA
La valeur de la donnée Seal est calculée comme suit :
- Contenu du champ Data envoyé dans le formulaire POST. Donnant la donnée data, mentionnée dans les exemples ci-dessous;
- Codage UTF-8 des données constituant le résultat de l’opération précédente
- HMAC avec chiffrement SHA256 des octets obtenus avec la clé secrète.
Cette procédure peut être résumée comme suit :
HMAC-SHA256( UTF-8(Data), UTF-8(secretKey))
Pour que le sceau soit calculé avec l'algorithme
HMAC-SHA-256, dont nous recommandons vivement l'utilisation, les
paramètres d'entrée de la requête doivent contenir le champ sealAlgorithm
avec la valeur suivante :
“HMAC-SHA-256”.
Exemples de code Hmac Sha256
- Exemple d’encodage Hmac Sha256 en Php 5
<?php … // Seal computation thanks to hash sorted data hash with merchant key $data_to_send= utf8_encode($data) $seal=hash_hmac('sha256', $data_to_send, $secretKey); … … ?>
data_to_send et secretKey doivent utiliser un jeu de caractères UTF-8. Référez-vous à la fonction utf8_encode pour la conversion de caractères ISO-8859-1 en UTF-8.
- Exemple d’encodage Hmac Sha256 en Java
import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class ExampleHMACSHA256 { /** * table to convert a nibble to a hex char. */ static final char[] hexChar = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f'}; /** * Fast convert a byte array to a hex string * with possible leading zero. * @param b array of bytes to convert to string * @return hex representation, two chars per byte. */ public static String encodeHexString ( byte[] b ) { StringBuffer sb = new StringBuffer( b.length * 2 ); for ( int i=0; i<b.length; i++ ) { // look up high nibble char sb.append( hexChar [( b[i] & 0xf0 ) >>> 4] ); // look up low nibble char sb.append( hexChar [b[i] & 0x0f] ); } return sb.toString(); } /** * Computes the seal * @param Data the parameters to cipher * @param secretKey the secret key to append to the parameters * @return hex representation of the seal, two chars per byte. */ public static String computeSeal(String data, String secretKey) throws Exception { Mac hmacSHA256 = Mac.getInstance("HmacSHA256"); SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"); hmacSHA256.init(keySpec); return encodeHexString(hmacSHA256.doFinal(data.getBytes())); } /** * @param args */ public static void main(String[] args) { try { System.out.println (computeSeal("parameters", "key")); } catch (Exception e) { e.printStackTrace(); } } }
- Exemple d’encodage Hmac Sha256 en .net
(Exemple effectué à l’aide d’un simple formulaire nommé « Form1 » contenant deux champs texte pour saisir data et txtSecretKey, ainsi qu’un autre champ pour afficher lblHEX).
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Security.Cryptography; namespace ExampleDotNET { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdGO_Click(object sender, EventArgs e) { String sChaine = data.Text; UTF8Encoding utf8 = new UTF8Encoding(); Byte[] encodedBytes = utf8.GetBytes(sChaine); byte[] shaResult; HMAC hmac = new HMAC.Create("HMACSHA256"); var key = "YourSecretKey"; hmac.Key = utf8.GetBytes(key); hmac.Initialize(); shaResult = hmac.ComputeHash(encodedBytes); lblHEX.Text = ByteArrayToHEX(shaResult); } private string ByteArrayToHEX(byte[] ba) { StringBuilder hex = new StringBuilder(ba.Length * 2); foreach (byte b in ba) hex.AppendFormat("{0:x2}", b); return hex.ToString(); } } }
Validation du calcul de seal
Une fois votre calcul de seal mis en place, voici un exemple de requête vous permettant de vérifier que vous retrouvez bien le bon seal :
automaticResponseURL=https://automatic-response-url.fr/|normalReturnURL=https://normal-return-url/|captureDay=0|captureMode=AUTHOR_CAPTURE|merchantId=011223344550000|amount=2500|orderId=ORD101|currencyCode=978|transactionReference=TREFEXA2012|keyVersion=1|transactionOrigin=SO_WEBAPPLI|returnContext=ReturnContext|orderChannel=INTERNET|customerContact.email=customer@email.com
Pour la requête ci-dessus, avec un algorithme de hachage SHA-256 et une clé secrète valant :
secret123
Le seal attendu est :
ac2332b57a674aba5b28a03dae677fa2f4c1ae8a349ebbdd6772a098c7f29861
Algorithme SHA-256
La valeur de la donnée Seal
est
calculée comme suit :
- concaténation de la donnée
Data
et de la clé secrète (encodée si l’option correspondante est choisie) ; - codage UTF-8 des données constituant le résultat de l’opération précédente ;
- « hashage » SHA256 des octets obtenus.
Cette procédure peut être résumée comme suit :
SHA256( UTF-8(Data+secretKey ) )
Exemples de code Sha256
- Exemple d’encodage Sha256 en Php 5
<?php
echo hash('sha256', $data.$secretKey);
?>
Le jeu de caractères UTF-8 doit être utilisé pour les données Data et secretKey. Pour effectuer une conversion de ISO-8859-1 à UTF-8, faites appel à la fonction utf8_encode.
- Exemple d’encodage Sha256 en Java
import java.security.MessageDigest;
public class ExampleSHA256 {
/**
* table to convert a nibble to a hex char.
*/
static final char[] hexChar = {
'0' , '1' , '2' , '3' ,
'4' , '5' , '6' , '7' ,
'8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f'};
/**
* Fast convert a byte array to a hex string
* with possible leading zero.
* @param b array of bytes to convert to string
* @return hex representation, two chars per byte.
*/
public static String encodeHexString ( byte[] b )
{
StringBuffer sb = new StringBuffer( b.length * 2 );
for ( int i=0; i<b.length; i++ )
{
// look up high nibble char
sb.append( hexChar [( b[i] & 0xf0 ) >>> 4] );
// look up low nibble char
sb.append( hexChar [b[i] & 0x0f] );
}
return sb.toString();
}
/**
* Computes the seal
* @param Data the parameters to cipher
* @param secretKey the secret key to append to the parameters
* @return hex representation of the seal, two chars per byte.
*/
public static String computeSeal(String Data, String secretKey) throws Exception
{
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update((Data+secretKey).getBytes("UTF-8"));
return encodeHexString(md.digest());
}
/**
* @param args
*/
public static void main(String[] args) {
try {
System.out.println (computeSeal("parameters", "key"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
- Exemple d’encodage Sha256 en .NET
Exemple complété à l’aide d’un simple formulaire appelé « Form 1 » contenant deux champs de texte à renseigner : data, txtSecretKey et un autre à afficher : lblHEX.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
namespace ExampleDotNET
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void cmdGO_Click(object sender, EventArgs e)
{
String sChaine = data.Text + txtSecretKey.Text;
UTF8Encoding utf8 = new UTF8Encoding();
Byte[] encodedBytes = utf8.GetBytes(sChaine);
byte[] shaResult;
SHA256 shaM = new SHA256Managed();
shaResult = shaM.ComputeHash(encodedBytes);
lblHEX.Text = ByteArrayToHEX(shaResult);
}
private string ByteArrayToHEX(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
}
}
Traiter les erreurs lors de l’initialisation du paiement
Tous les champs reçus par Paypage POST à travers le connecteur font l’objet d’une vérification individuelle. Le tableau ci-dessous présente la liste des messages d’erreur pouvant s’afficher lors de cette étape ainsi que les solutions à mettre en œuvre.
Message | Cause | Solution |
---|---|---|
Unknown version interface: <version> |
La valeur <version> dans le champ InterfaceVersion est inconnue. | Vérifier la version d’interface dans ce guide d’utilisation (la version actuelle est la version HP_2.44). |
Invalid keyword: <nomChamp>= <valeur Champ> |
Le champ <nomChamp> n’est pas prévu dans la requête de paiement. | Vérifier le nom des champs dans le chapitre ci-dessous et dans le dictionnaire de données. |
Invalid field size: <nomChamp>= <valeur Champ> |
Le champ <nomChamp> a une longueur incorrecte. | Vérifier la longueur du champ dans le dictionnaire de données. |
Invalid field value: <nomChamp >= <valeur Champ> |
La valeur du champ <nomChamp> est incorrecte. | Vérifier les valeurs possibles du champ dans le dictionnaire de données. |
Mandatory field missing: <nomChamp > |
Le champ <nomChamp> est manquant dans la requête de paiement. | Vérifier les champs obligatoires de la requête de paiement dans le chapitre ci-dessous. |
Unknown security version: <version> |
La valeur <version> du champ keyVersion est inconnue. | Vérifier les versions des clés disponibles dans Mercanet Téléchargement. |
Invalid signature |
La vérification du Seal de la requête de paiement a échoué. Cela peut être dû à un calcul incorrect de la donnée Seal ou à la falsification de certains champs après le calcul de la signature. | Vérifier que le calcul du Seal est effectué comme indiqué dans le chapitre précédent. Si c’est le cas, demander un changement de clé secrète via Mercanet Téléchargement car la requête a été falsifiée. |
Transaction already processed: <référence de la transaction> |
Une requête de paiement avec le même transactionReference a déjà été reçue et prise en charge par les serveurs Mercanet. | Vérifier si la valeur du champ transactionReference est unique pour la transaction concernée. |
<Autres messages> |
Dans le cas d’erreurs techniques, d’autres messages différents peuvent s’afficher. | Contacter le service d’assistance technique. |
Traiter la réponse aux erreurs d’initialisation du paiement
En cas d'erreur lors de l'initialisation du paiement, l'envoi d'une réponse manuelle et/ou automatique peut être activé en fonction de votre configuration. Vous devez pour cela contacter l'assistance technique qui activera cette fonctionnalité.
Deux types de réponse sont prévus. Bien que les protocoles, formats et contenus des deux réponses soient exactement les mêmes, elles doivent être gérées de manière différente car elles répondent à deux besoins différents.
Les réponses aux erreurs d’initialisation de paiement sont des réponses HTTP(S) POST envoyées aux URL renseignées au travers des champs manualErrorResponseInitPOST (optionnel) et automaticErrorResponseInitPOST (optionnel) précisées dans la requête.
Si vous souhaitez utiliser ces réponses, vous devez mettre en place le système permettant de les décoder, afin de connaître la raison de l’erreur rencontrée. Les deux données suivantes sont définies dans les réponses :
Nom du champ | Notes/règles |
---|---|
Data | Concaténation des champs en réponse |
Seal | Signature du message réponse |
La chaîne concaténée est structurée comme suit :
redirectionStatusCode | redirectionStatusMessage | merchantId | transactionReference | transactionId | transactionDate | transactionDateTime | amount | customerId | orderId | customerIpAddress
Voici un exemple de donnée Data :
redirectionStatusCode=12|redirectionStatusMessage=currencyCode contains invalid chars : [abc]|merchantId= 024729465300012|transactionReference= SIM20180118155728|transactionId=12345|transactionDate=20180412|transactionDateTime= 2018-04-12T10:14:31+02:00|amount=1000|customerId=CU-123|orderId=orderId1|customerIpAddress=127.0.0.1
Cette chaîne concaténée est convertie en UTF-8 avant le « hashage ».
Le sceau (donnée Seal) des 2 réponses est « hashé » avec le même algorithme utilisé en entrée et fourni dans le champ sealAlgorithm. Si aucune valeur n’a été définie, la valeur SHA-256 est utilisée par défaut.
Renseigner l’URL de la réponse manuelle aux erreurs d’initialisation du paiement
L’objectif principal de la réponse manuelle aux erreurs d’initialisation de paiement est de rediriger le client vers votre site web avec la raison de l’erreur pour que vous puissiez prendre la bonne décision le concernant. Par exemple, en cas d’erreur sur une donnée renseignée par le client, vous pouvez lui suggérer de retenter le paiement avec un format correct. Dans le cas d’une erreur sur une donnée indépendante du client, vous pouvez l’inviter à vous contacter pour résoudre la situation.
À la première étape, un bouton « Retour » est affiché sur la page d’erreur chez Mercanet avec un lien de redirection vers votre site. Lorsque le client clique sur ce bouton, le serveur Mercanet le redirige vers l’adresse URL contenue dans le champ manualErrorResponseInitPOST fourni dans la requête. La redirection est une requête HTTP(S) POST qui contient les données de la réponse, tels que décrits ci-dessus. Il est de votre responsabilité de récupérer ces paramètres et de vérifier la signature pour ainsi assurer l’intégrité des données de la réponse. De plus, vous avez la responsabilité d’afficher les messages pertinents (relatifs aux détails de la réponse) à votre client.
Il est important de noter qu’il est impossible de garantir la réception de la réponse, celle-ci étant envoyée par le navigateur web du client. Tout d’abord, le client a la possibilité de ne pas cliquer sur le lien. Ensuite, la connexion qu’il utilise peut tout simplement avoir un problème et bloquer l’envoi de cette réponse. Par conséquent, celle-ci ne peut pas constituer la base unique pour vos processus métier.
Renseigner l’URL de la réponse automatique aux erreurs d’initialisation du paiement
La réponse automatique est envoyée seulement si le champ automaticErrorResponseInitPOST a été envoyé dans la requête de paiement. Si tel est le cas, le serveur Mercanet envoie une réponse HTTP(S) POST à l’adresse URL reçue.
Les champs de la réponse automatique sont identiques à ceux de la réponse manuelle. La seule différence entre les deux procédures est que la réponse automatique est envoyée directement par le serveur Mercanet sans passer par le navigateur Web du client. Par conséquent, elle est bien plus fiable car elle est toujours envoyée. Le serveur Mercanet n’attend aucune réponse après l’envoi de la réponse automatique.
Il vous appartient de récupérer les différentes données de la réponse, vérifier la signature pour vous assurer de l’intégrité des champs de la réponse et, par conséquent, mettre à jour votre back office.
Résoudre les problèmes de réception des réponses aux erreurs d’initialisation
Comme pour les réponses manuelle et automatique de paiement, ces réponses peuvent être bloquées. Les mêmes conseils s’appliquent pour résoudre ces problèmes (voir chapitre [Résoudre les problèmes de réception des réponses]).
Récupérer les champs des réponses aux erreurs d’initialisation
Le contenu des réponses automatique et manuelle aux erreurs d’initialisation de Paypage est invariable. Quelle que soit l’erreur rencontrée lors de l’initialisation de paiement, la réponse contiendra les champs suivants :
Champ | Commentaires |
---|---|
redirectionStatusCode | |
redirectionStatusMessage | |
merchantId | idem requête |
transactionReference | |
transactionId | |
transactionDate | |
transactionDateTime | |
amount | idem requête |
customerId | idem requête |
orderId | idem requête |
customerIpAddress | idem requête |
Renseigner les champs de la requête
La requête et la réponse de la méthode paymentWebInit sont décrites sur cette page dédiée.
Paramétrer la requête de paiement
Voici un exemple de paramétrage de la requête de paiement pour chaque fonctionnalité disponible dans Paypage POST (le détail de ces fonctionnalités est décrit dans le guide de configuration des fonctionnalités).
Affichage dynamique des moyens de paiement
Il faut filtrer ceux qui s’afficheront dans la page de sélection des moyens de paiement grâce au champ paymentMeanBrandList :
..|paymentMeanBrandList=VISA,PAYPAL|..
Affichage du ticket par Mercanet
La page de confirmation du paiement, affichée par défaut par Mercanet peut être désactivée. Cette désactivation se fait par le champ paypageData.bypassReceiptPage :
..|paypageData.bypassReceiptPage=Y|..
Canal de paiement
Pour choisir votre canal de paiement, vous devez remplir le champ orderChannel dans la requête de paiement :
…|orderChannel= INTERNET|..
Paiement en fin de journée
Dans le cas d’un paiement en fin de journée, il suffit de remplir les champs captureMode et captureDay :
…|captureDay=0|captureMode=AUTHOR_CAPTURE|..
Paiement différé
Dans le cas d’un paiement à remiser N jours après l’acceptation en ligne, il suffit de remplir les champs captureMode et captureDay (3 jours dans notre exemple) :
…|captureDay=3|captureMode=AUTHOR_CAPTURE|..
Pour des cas de paiements différés plus complexes, notamment avec des envois multiples ou un envoi au-delà de 6 jours, veuillez vous référer au guide paiement multiple à l'expédition.
Paiement à l’expédition
Dans le cas d’un paiement à l’expédition, la transaction est envoyée en paiement lors votre validation, il faut juste remplir les champs captureMode et captureDay (3 jours de délai possible avant validation dans notre exemple) :
…|captureDay=3|captureMode=VALIDATION|..
Paiement en plusieurs fois
Dans le cas d’un paiement en plusieurs échéances liées à une même transaction, il faut renseigner le champ paymentPattern à INSTALMENT et fournir le détail des échéances dans le champ instalmentData (600€ payés en 3 échéances dans notre exemple) :
…|amount=60000|…|transactionReference=tref1|…|paymentPattern=INSTALMENT|instalmentData.number
=3|instalmentData.datesList=20170412,20170512,20170612|instalmentData.transactionReferencesList
=tref1,tref2,tref3|instalmentData.amountsList=10000,30000,20000|..
Paiement immédiat
Si vous souhaitez un paiement immédiat (disponible uniquement pour certains moyens de paiement), la transaction est payée lors de l’autorisation en ligne :
…|captureMode=IMMEDIATE|..
Acceptation multidevise
Dans le cas des transactions multidevises le code devise doit être spécifié dans la requête. C’est dans le contrat d’acquisition où est précisée la devise de règlement.
…|currencyCode=840|..
Règlement en devises
L’acceptation et le règlement sont effectués dans la même devise qui doit être spécifiée dans la requête. Le règlement en devises est une option du contrat d’acquisition.
…|currencyCode=826|..
Inscription et paiement OneClick
Pour un paiement OneClick, l’identifiant du wallet du client doit être renseigné dans le champ merchantWalletId.
…|merchantWalletId=1205987|..
Prestataire agissant pour le compte d’un commerçant
Il faut passer l’identifiant du prestataire dans la requête dans le champ intermediateServiceProvider et utiliser la clé secrète de ce dernier pour calculer la donnée Seal :
..|intermediateServiceProviderId=241591|..
Traiter la réponse
Deux types de réponse sont prévus. Bien que les protocoles, formats et contenus des deux réponses soient exactement les mêmes, elles doivent être gérées de manière différente car elles répondent à deux besoins différents.
Les réponses sont des réponses HTTP(S) POST envoyées aux URL normalReturnUrl (obligatoire - réponse manuelle) et automaticResponseUrl (optionnelle - réponse automatique) précisées dans la requête.
Vous devez mettre en place le système permettant de décoder ces réponses, afin de connaître le résultat de requête.
Les quatre données suivantes sont définies dans les réponses :
Données | Notes/règles |
---|---|
Data | Concaténation des champs en réponse. |
Encode | Type d’encodage utilisé pour la donnée Data. Ce champ est valorisé avec le champ responseEncoding de la requête. |
Seal | Signature du message réponse. |
InterfaceVersion | Version de l’interface du connecteur. |
Si la valeur du champ Encode est “base64” ou “base64url”, la donnée Data doit-être décodée en Base64/Base64Url pour retrouver la chaîne des champs concaténée. La chaîne concaténée est structurée comme suit : clé1=valeur1|clé2=valeur2… Le sceau (donnée Seal) des 2 réponses est « hashé » avec le même algorithme utilisé en entrée et fourni dans le champ sealAlgorithm. Si aucune valeur n’a été définie, la valeur SHA-256 est utilisée par défaut.
La valeur de la donnée Seal est calculée comme suit :
Pour l'algorithme HMAC-SHA :
- utilisation de la clé secrète partagée pour générer la variante HMAC du message ;
- utilisation de la donnée Data uniquement (encodée si l’option correspondante est choisie) ;
- codage UTF-8 des données constituant le résultat de l’opération précédente ;
- « Hashage » HMAC-SHA des octets obtenus.
Cette procédure peut être résumée comme suit :
HMAC-SHA256( UTF-8(Data), UTF-8(secretKey))
Exemple de Seal calculé avec une clé secrète égale à "secret123" et la donnée Data au format POST ci-dessous:
captureDay=0|captureMode=AUTHOR_CAPTURE|currencyCode=978|merchantId=039000254447216|orderChannel=INTERNET|responseCode=00|transactionDateTime=2022-11-14T11:21:12+01:00|transactionReference=SIM20221114112037|keyVersion=1|acquirerResponseCode=00|amount=1000|authorisationId=664865|guaranteeIndicator=N|panExpiryDate=202401|paymentMeanBrand=VISA|paymentMeanType=CARD|customerIpAddress=10.78.106.18|maskedPan=############0600|holderAuthentRelegation=N|holderAuthentStatus=NOT_PARTICIPATING|tokenPan=490700h719850600|transactionOrigin=SIMS|paymentPattern=ONE_SHOT|customerMobilePhone=null|mandateAuthentMethod=null|mandateUsage=null|transactionActors=null|mandateId=null|captureLimitDate=20221114|dccStatus=null|dccResponseCode=null|dccAmount=null|dccCurrencyCode=null|dccExchangeRate=null|dccExchangeRateValidity=null|dccProvider=null|statementReference=null|panEntryMode=MANUAL|walletType=null|holderAuthentMethod=NO_AUTHENT_METHOD|holderAuthentProgram=3DS_V2|paymentMeanId=null|instalmentNumber=null|instalmentDatesList=null|instalmentTransactionReferencesList=null|instalmentAmountsList=null|settlementMode=null|mandateCertificationType=null|valueDate=null|creditorId=null|acquirerResponseIdentifier=null|acquirerResponseMessage=null|paymentMeanTradingName=null|additionalAuthorisationNumber=null|issuerWalletInformation=null|s10TransactionId=6|s10TransactionIdDate=20221114|preAuthenticationColor=null|preAuthenticationInfo=null|preAuthenticationProfile=null|preAuthenticationThreshold=null|preAuthenticationValue=null|invoiceReference=null|s10transactionIdsList=null|cardProductCode=F|cardProductName=VISA CLASSIC|cardProductProfile=C|issuerCode=00000|issuerCountryCode=GRC|acquirerNativeResponseCode=00|settlementModeComplement=null|preAuthorisationProfile=null|preAuthorisationProfileValue=null|preAuthorisationRuleResultList=[{"ruleCode":"VI","ruleType":"NG","ruleWeight":"I","ruleSetting":"S","ruleResultIndicator":"0","ruleDetailedInfo":"TRANS=1:3;CUMUL=24999:200000"},{"ruleCode":"RCode","ruleType":"RType","ruleWeight":"RWeight","ruleSetting":"RSetting","ruleResultIndicator":"RIndicator","ruleDetailedInfo":"DetailedInfo"}]|preAuthenticationProfileValue=null|preAuthenticationRuleResultList=null|paymentMeanBrandSelectionStatus=NOT_APPLICABLE|transactionPlatform=PROD|avsAddressResponseCode=null|avsPostcodeResponseCode=null|customerCompanyName=null|customerBusinessName=null|customerLegalId=null|customerPositionOccupied=null|paymentAttemptNumber=1|holderContactEmail=null|installmentIntermediateServiceProviderOperationIdsList=null|holderAuthentType=null|acquirerContractNumber=3863090010|secureReference=null|authentExemptionReasonList=null|paymentAccountReference=a667b63d8bec4fb980106497c53e4|schemeTransactionIdentifier=b4e683c1a6ff4a09a0415116a0a25b401d38c19d24e643078d|guaranteeLimitDateTime=null|paymentMeanDataProvider=null|virtualCardIndicator=N|cardProductUsageLabel=CREDIT|authorisationTypeLabel=TRANSACTION DE PAIEMENT|authorMessageReference=272612|acceptanceSystemApplicationId=142000000001|challengeMode3DS=null|issuingCountryCode=GRC|abortedProcessingStep=null|abortedProcessingLocation=null
Le Seal que vous devez obtenir est c946655cce0059124b4ad3eb62c0922c51a0a7d8d28a3cf223e4c0da41bbc5b9
Exemple de Seal calculé avec une clé secrète égale à "secret123" et la donnée Data au format JSON ci-dessous:
{"keyVersion":1,"amount":44000,"captureDay":0,"captureMode":"AUTHOR_CAPTURE","currencyCode":"978","customerId":"40813","customerIpAddress":"213.118.246.190","merchantId":"225005049920001","orderAmount":44000,"orderChannel":"INTERNET","responseCode":"97","responseDescription":"Request time-out; transaction refused","transactionDateTime":"2023-03-15.00:39:04+0100","transactionReference":"dd88adfZ1027b40813f40813y1678837075","statementReference":"T7Ft4KKLRA2M11B9","s10TransactionId":"6","s10TransactionIdDate":"20230315","sealAlgorithm":"sha256","transactionPlatform":"PROD","paymentAttemptNumber":2,"preAuthorisationRuleResultList":[{"ruleCode":"VI","ruleType":"NG","ruleWeight":"I","ruleSetting":"S","ruleResultIndicator":"0","ruleDetailedInfo":"TRANS=1:3;CUMUL=24999:200000"},{"ruleCode":"RCode","ruleType":"RType","ruleWeight":"RWeight","ruleSetting":"RSetting","ruleResultIndicator":"RIndicator","ruleDetailedInfo":"DetailedInfo"}]}
Le Seal que vous devez obtenir est 77be1c230491c0d4eef6eaf910f635d42f55c90cd34c5a162c0ef6fcefb3f087
Pour l’algorithme SHA-256 (bien que celui-ci soit la valeur par défaut, cet algorithme n’est plus recommandé à ce jour) :
- concaténation de la donnée Data et de la clé secrète (encodée si l’option correspondante est choisie) ;
- codage UTF-8 des données constituant le résultat de l’opération précédente ;
- « Hashage » SHA256 des octets obtenus.
Cette procédure peut être résumée comme suit :
SHA256( UTF-8(Data+secretKey ) )
Exemple de Seal calculé avec une clé secrète égale à "secret123" et la donnée Data au format POST ci-dessous:
captureDay=0|captureMode=AUTHOR_CAPTURE|currencyCode=978|merchantId=039000254447216|orderChannel=INTERNET|responseCode=00|transactionDateTime=2022-11-14T11:21:12+01:00|transactionReference=SIM20221114112037|keyVersion=1|acquirerResponseCode=00|amount=1000|authorisationId=664865|guaranteeIndicator=N|panExpiryDate=202401|paymentMeanBrand=VISA|paymentMeanType=CARD|customerIpAddress=10.78.106.18|maskedPan=############0600|holderAuthentRelegation=N|holderAuthentStatus=NOT_PARTICIPATING|tokenPan=490700h719850600|transactionOrigin=SIMS|paymentPattern=ONE_SHOT|customerMobilePhone=null|mandateAuthentMethod=null|mandateUsage=null|transactionActors=null|mandateId=null|captureLimitDate=20221114|dccStatus=null|dccResponseCode=null|dccAmount=null|dccCurrencyCode=null|dccExchangeRate=null|dccExchangeRateValidity=null|dccProvider=null|statementReference=null|panEntryMode=MANUAL|walletType=null|holderAuthentMethod=NO_AUTHENT_METHOD|holderAuthentProgram=3DS_V2|paymentMeanId=null|instalmentNumber=null|instalmentDatesList=null|instalmentTransactionReferencesList=null|instalmentAmountsList=null|settlementMode=null|mandateCertificationType=null|valueDate=null|creditorId=null|acquirerResponseIdentifier=null|acquirerResponseMessage=null|paymentMeanTradingName=null|additionalAuthorisationNumber=null|issuerWalletInformation=null|s10TransactionId=6|s10TransactionIdDate=20221114|preAuthenticationColor=null|preAuthenticationInfo=null|preAuthenticationProfile=null|preAuthenticationThreshold=null|preAuthenticationValue=null|invoiceReference=null|s10transactionIdsList=null|cardProductCode=F|cardProductName=VISA CLASSIC|cardProductProfile=C|issuerCode=00000|issuerCountryCode=GRC|acquirerNativeResponseCode=00|settlementModeComplement=null|preAuthorisationProfile=null|preAuthorisationProfileValue=null|preAuthorisationRuleResultList=[{"ruleCode":"VI","ruleType":"NG","ruleWeight":"I","ruleSetting":"S","ruleResultIndicator":"0","ruleDetailedInfo":"TRANS=1:3;CUMUL=24999:200000"},{"ruleCode":"RCode","ruleType":"RType","ruleWeight":"RWeight","ruleSetting":"RSetting","ruleResultIndicator":"RIndicator","ruleDetailedInfo":"DetailedInfo"}]|preAuthenticationProfileValue=null|preAuthenticationRuleResultList=null|paymentMeanBrandSelectionStatus=NOT_APPLICABLE|transactionPlatform=PROD|avsAddressResponseCode=null|avsPostcodeResponseCode=null|customerCompanyName=null|customerBusinessName=null|customerLegalId=null|customerPositionOccupied=null|paymentAttemptNumber=1|holderContactEmail=null|installmentIntermediateServiceProviderOperationIdsList=null|holderAuthentType=null|acquirerContractNumber=3863090010|secureReference=null|authentExemptionReasonList=null|paymentAccountReference=a667b63d8bec4fb980106497c53e4|schemeTransactionIdentifier=b4e683c1a6ff4a09a0415116a0a25b401d38c19d24e643078d|guaranteeLimitDateTime=null|paymentMeanDataProvider=null|virtualCardIndicator=N|cardProductUsageLabel=CREDIT|authorisationTypeLabel=TRANSACTION DE PAIEMENT|authorMessageReference=272612|acceptanceSystemApplicationId=142000000001|challengeMode3DS=null|issuingCountryCode=GRC|abortedProcessingStep=null|abortedProcessingLocation=null
Le Seal que vous devez obtenir est 8fb7c5b7e972ed5a279629757aeae9885cdfc1fd888e6fc03114064e94bb2bf4
Exemple de Seal calculé avec une clé secrète égale à "secret123" et la donnée Data au format JSON ci-dessous:
{"keyVersion":1,"amount":44000,"captureDay":0,"captureMode":"AUTHOR_CAPTURE","currencyCode":"978","customerId":"40813","customerIpAddress":"213.118.246.190","merchantId":"225005049920001","orderAmount":44000,"orderChannel":"INTERNET","responseCode":"97","responseDescription":"Request time-out; transaction refused","transactionDateTime":"2023-03-15.00:39:04+0100","transactionReference":"dd88adfZ1027b40813f40813y1678837075","statementReference":"T7Ft4KKLRA2M11B9","s10TransactionId":"6","s10TransactionIdDate":"20230315","sealAlgorithm":"sha256","transactionPlatform":"PROD","paymentAttemptNumber":2,"preAuthorisationRuleResultList":[{"ruleCode":"VI","ruleType":"NG","ruleWeight":"I","ruleSetting":"S","ruleResultIndicator":"0","ruleDetailedInfo":"TRANS=1:3;CUMUL=24999:200000"},{"ruleCode":"RCode","ruleType":"RType","ruleWeight":"RWeight","ruleSetting":"RSetting","ruleResultIndicator":"RIndicator","ruleDetailedInfo":"DetailedInfo"}]}
Le Seal que vous devez obtenir est e9aa5be21186a9f9a417b82d1d450792851c849ccc8a2f85136897da29477975
Renseigner l’URL de la réponse manuelle
L’objectif principal de la réponse manuelle est de rediriger le client vers votre site Web avec le résultat du paiement pour que vous puissiez prendre la bonne décision le concernant. Par exemple, en cas d’erreur, vous pouvez suggérer de retenter le paiement. Dans le cas de paiement réussi, vous pouvez afficher un message de remerciement et commencer à expédier les marchandises.
À la dernière étape, un bouton « Continuer » est affiché sur la page de paiement chez Mercanet avec un lien de redirection vers votre site. Lorsque le client clique sur ce bouton, le serveur Mercanet le redirige vers l’adresse URL contenue dans le champ normalReturnUrl fourni dans la requête. La redirection est une requête HTTP(S) POST qui contient les données de la réponse, tels que décrits ci-dessus. Il est de votre responsabilité de récupérer ces paramètres et de vérifier la signature pour ainsi assurer l’intégrité des données de la réponse. De plus, vous êtes responsable d’afficher les messages pertinents (relatifs aux détails de la réponse) à votre client.
Ce champ normalReturnUrl est également utilisé pour tous les résultats de paiement (annulation, refus ...) afin de rediriger vers votre site.
Il est important de noter qu’il est impossible de garantir la réception de la réponse, celle-ci étant envoyée par le navigateur Web du client. Tout d’abord, le client a la possibilité de ne pas cliquer sur le lien. Ensuite, la connexion qu’il utilise peut tout simplement avoir un problème et bloquer l’envoi de cette réponse. Par conséquent, celle-ci ne peut pas constituer la base unique pour vos processus métier.
Renseigner l’URL de la réponse automatique
La réponse automatique est envoyée seulement si le champ automaticResponseUrl a été envoyé dans la requête de paiement. Si tel est le cas, le serveur Mercanet envoie une réponse HTTP(S) POST à l’adresse URL reçue.
Les champs de la réponse automatique sont identiques à ceux de la réponse manuelle. La seule différence entre les deux procédures est que la réponse automatique est envoyée directement par le serveur Mercanet sans passer par le navigateur Web du client. Par conséquent, elle est bien plus fiable car elle est toujours envoyée. Le serveur Mercanet n’attend aucune réponse après l’envoi de la réponse automatique.
Il vous appartient de récupérer les différentes données de la réponse, vérifier la signature pour vous assurer de l’intégrité des champs de la réponse et, par conséquent, mettre à jour votre back office.
La réponse automatique est transmise en fin de paiement. Toutefois, si votre client abandonne son achat, par exemple en quittant son navigateur, la réponse automatique est transmise lorsque la session utilisateur expire (au bout de 15 minutes d’inactivité). Par conséquent, si votre client abandonne son achat, vous recevrez uniquement la réponse automatique (pas la réponse manuelle), avec un code réponse renseigné à 97, environ 15 à 16 minutes après la redirection du client sur les pages de paiement.
Si une réponse automatique n’est pas reçue au bout de 16 minutes environ, vous pouvez obtenir le résultat d’un paiement en appelant la méthode getTransactionData de l’interface Office (M2M), ou en analysant le contenu du journal des transactions. Vous pouvez également rechercher une transaction et voir son état en utilisant Mercanet Back Office.
Choisir le format de la réponse : POST ou JSON
A partir de l'interfaceVersion
HP_3.0 Mercanet vous envoie la chaîne concaténée de la réponse (champ
Data) sous 2 formats au choix :
Le format POST
Ce format POST a la structure suivante : clé1=valeur1|clé2=valeur2…
Exemple d'une réponse en POST avec séparateur "pipe" entre les données
captureDay=0|captureMode=AUTHOR_CAPTURE|currencyCode=978|merchantId=039000254447216
|orderChannel=INTERNET|responseCode=00|transactionDateTime=2022-11-14T11:21:12+01:00|transactionReference=SIM20221114112037
|keyVersion=1|acquirerResponseCode=00|amount=1000|authorisationId=664865|guaranteeIndicator=N|panExpiryDate=202401
|paymentMeanBrand=VISA|paymentMeanType=CARD|customerIpAddress=10.78.106.18|maskedPan=############0600|holderAuthentRelegation=N
|holderAuthentStatus=NOT_PARTICIPATING|tokenPan=490700h719850600|transactionOrigin=SIMS|paymentPattern=ONE_SHOT
|customerMobilePhone=null|mandateAuthentMethod=null|mandateUsage=null|transactionActors=null|mandateId=null|captureLimitDate=20221114
|dccStatus=null|dccResponseCode=null|dccAmount=null|dccCurrencyCode=null|dccExchangeRate=null|dccExchangeRateValidity=null
|dccProvider=null|statementReference=null|panEntryMode=MANUAL|walletType=null|holderAuthentMethod=NO_AUTHENT_METHOD
|holderAuthentProgram=3DS_V2|paymentMeanId=null|instalmentNumber=null|instalmentDatesList=null|instalmentTransactionReferencesList=null
|instalmentAmountsList=null|settlementMode=null|mandateCertificationType=null|valueDate=null|creditorId=null
|acquirerResponseIdentifier=null|acquirerResponseMessage=null|paymentMeanTradingName=null|additionalAuthorisationNumber=null
|issuerWalletInformation=null|s10TransactionId=6|s10TransactionIdDate=20221114|preAuthenticationColor=null|preAuthenticationInfo=null
|preAuthenticationProfile=null|preAuthenticationThreshold=null|preAuthenticationValue=null|invoiceReference=null|s10transactionIdsList=null
|cardProductCode=F|cardProductName=VISA CLASSIC|cardProductProfile=C|issuerCode=00000|issuerCountryCode=GRC|acquirerNativeResponseCode=00
|settlementModeComplement=null|preAuthorisationProfile=null|preAuthorisationProfileValue=null
|preAuthorisationRuleResultList=[{"ruleCode":"VI","ruleType":"NG","ruleWeight":"I","ruleSetting":"S","ruleResultIndicator":"0","ruleDetailedInfo":"TRANS=1:3;CUMUL=24999:200000"},{"ruleCode":"RCode","ruleType":"RType","ruleWeight":"RWeight","ruleSetting":"RSetting","ruleResultIndicator":"RIndicator","ruleDetailedInfo":"DetailedInfo"}]
|preAuthenticationProfileValue=null|preAuthenticationRuleResultList=null|paymentMeanBrandSelectionStatus=NOT_APPLICABLE|transactionPlatform=PROD
|avsAddressResponseCode=null|avsPostcodeResponseCode=null|customerCompanyName=null|customerBusinessName=null|customerLegalId=null
|customerPositionOccupied=null|paymentAttemptNumber=1|holderContactEmail=null|installmentIntermediateServiceProviderOperationIdsList=null
|holderAuthentType=null|acquirerContractNumber=3863090010|secureReference=null|authentExemptionReasonList=null
|paymentAccountReference=a667b63d8bec4fb980106497c53e4|schemeTransactionIdentifier=b4e683c1a6ff4a09a0415116a0a25b401d38c19d24e643078d
|guaranteeLimitDateTime=null|paymentMeanDataProvider=null|virtualCardIndicator=N|cardProductUsageLabel=CREDIT|authorisationTypeLabel=TRANSACTION DE PAIEMENT
|authorMessageReference=272612|acceptanceSystemApplicationId=142000000001|challengeMode3DS=null|issuingCountryCode=GRC|abortedProcessingStep=null|abortedProcessingLocation=null
(voir § Syntaxe des listes d'objets complexes dans les réponses)
Le format JSON
Le format JSON a la structure suivante : { "clé1" : "valeur1", "clé2" : "valeur2", …}
Exemple d'une réponse en JSON
{
"keyVersion": 1, "acquirerResponseCode": "00", "acquirerResponseDescription": "Transaction approved or processed successfully",
"amount": 1000, "authorisationId": "858191", "captureDay": 0, "captureMode": "AUTHOR_CAPTURE", "cardScheme": "VISA",
"chargeAmount": 0, "currencyCode": "978", "customerIpAddress": "10.78.106.18", "guaranteeIndicator": "N",
"holderAuthentRelegation": "N", "holderAuthentStatus": "NOT_PARTICIPATING", "maskedPan": "############0600",
"merchantId": "039000254447216", "orderAmount": 1000, "orderChannel": "INTERNET", "panExpiryDate": "202401",
"paymentMeanBrand": "VISA", "paymentPattern": "ONE_SHOT", "responseCode": "00", "responseDescription": "Process succeeded",
"tokenPan": "490700h719850600", "transactionDateTime": "2022-11-14.11:19:39+0100", "transactionOrigin": "SIMS",
"transactionReference": "SIM20221114111757", "captureLimitDate": "20221114", "paymentMeanType": "CARD", "panEntryMode": "MANUAL",
"holderAuthentMethod": "NO_AUTHENT_METHOD", "holderAuthentProgram": "3DS_V2", "s10TransactionId": "5", "s10TransactionIdDate": "20221114",
"cardProductCode": "F", "cardProductName": "VISA CLASSIC", "cardProductProfile": "C", "issuerCode": "00000", "issuerCountryCode": "GRC",
"acquirerNativeResponseCode": "00", "sealAlgorithm": "sha256", "paymentMeanBrandSelectionStatus": "NOT_APPLICABLE",
"transactionPlatform": "PROD", "paymentAttemptNumber": 1, "acquirerContractNumber": "3863090010",
"schemeTransactionIdentifier": "79e70b862e5942ff86f31951235959a16f45f41f797f48129e",
"paymentAccountReference": "945dbb3e0b984bfc896a04c5bc273", "virtualCardIndicator": "N", "cardProductUsageLabel": "CREDIT",
"authorisationTypeLabel": "TRANSACTION DE PAIEMENT", "authorMessageReference": "179263", "acceptanceSystemApplicationId": "142000000001",
"issuingCountryCode": "GRC", "threeDLiabilityShift": "N", "threeDStatusCode": "NOT_PARTICIPATING", "threeDRelegationCode": "N",
"preAuthorisationRuleResultList":[
{"ruleCode":"VI","ruleType":"NG","ruleWeight":"I","ruleSetting":"S","ruleResultIndicator":"0","ruleDetailedInfo":"TRANS=1:3;CUMUL=24999:200000"},
{"ruleCode":"RCode","ruleType":"RType","ruleWeight":"RWeight","ruleSetting":"RSetting","ruleResultIndicator":"RIndicator","ruleDetailedInfo":"DetailedInfo"}
]
}
Comportement par défaut à partir de
l'interfaceVersion
HP_3.0
Le format de la réponse automatique et manuelle est déterminé par le connecteur qui a été utilisé lors des échanges HTTPS entre votre site Web et les serveurs de paiement Paypage
Interface Version | Connecteur | Format des réponses |
---|---|---|
IR_WS_3.x | JSON | JSON (JS_3.x) |
HP_3.x | POST | POST (HP_3.x) |
IR_WS_3.x | SOAP | POST (HP_3.x) |
Choisir les versions des réponses depuis la requête de paiement
Si vous souhaitez contourner ce comportement par défaut il est possible de renseigner depuis la requête de paiement les versions exactes des réponses automatiques et manuelles que vous utilisez.
Le champs de la requête de paiement qui permet de renseigner la version
de la réponse automatique est interfaceVersionAutomaticResponse
Le champs de la requête de paiement qui permet de renseigner la version
de la réponse manuelle est interfaceVersionNormalResponse
Ces deux nouveaux champs
interfaceVersionAutomaticResponse
et
interfaceVersionNormalResponse
sont facultatifs mais si
une des versions est renseignée l'autre devient obligatoire également.
Sinon la requête d'initialisation de paiement est en echec (code erreur
12).
Résoudre les problèmes de réception des réponses
Ci-dessous, vous trouverez une liste des problèmes les plus couramment observés qui bloquent la réception des réponses automatiques et manuelles. Assurez-vous de les avoir vérifiés avant d’appeler le service d’assistance technique.
- Vérifiez si les adresses URL de réponse sont fournies dans la requête et si elles sont valides. Pour ce faire, vous pouvez tout simplement les copier et coller dans votre navigateur.
- Les adresses URL fournies doivent être accessibles depuis l’extérieur, c'est-à-dire de l’Internet. Le contrôle d’accès (identifiant/mot de passe ou filtre IP) ou le pare-feu peuvent bloquer l’accès à votre serveur.
- L’accès aux adresses URL de réponse doit être confirmé dans le journal des notifications de votre serveur Web.
- Si vous utilisez un port non standard, il doit être compris entre 80 et 9999 pour assurer la compatibilité avec Mercanet.
- Il est impossible d’ajouter des paramètres de contexte aux adresses URL de réponse. Certains champs peuvent être néanmoins utilisés, par exemple, les champs orderID ou returnContext sont prévus pour les paramètres supplémentaires. Éventuellement, vous pouvez vous servir du champ sessionId pour retrouver les renseignements sur votre client à la fin du processus de paiement.
Dans certains cas d’erreurs, le serveur Mercanet n’est pas capable de signer le message de réponse. Cela s’applique, par exemple, à l’erreur « MerchantID inconnu » et au cas où la clé secrète est inconnue de Mercanet. Pour ces raisons, le serveur de paiement envoie une réponse sans signature dans le champ Seal.
Récupérer les champs des réponses
Le contenu des réponses Paypage automatiques et manuelles est identique. Le contenu peut varier en fonction du résultat (réussi ou autre).
La liste des champs de la réponse est disponible sur cette page.
Champs optionnels relatifs aux contrôles de fraude
- Contenu de preAuthenticationRuleResult
Champ | Version | Commentaires |
---|---|---|
ruleCode | HP_2.14 | |
ruleType | HP_2.14 | |
ruleWeight | HP_2.14 | |
ruleSetting | HP_2.14 | |
ruleResultIndicator | HP_2.14 | |
ruleDetailedInfo | HP_2.14 |
- Contenu de preAuthorisationRuleResult
Champ | Version | Commentaires |
---|---|---|
ruleCode | HP_2.14 | |
ruleType | HP_2.14 | |
ruleWeight | HP_2.14 | |
ruleSetting | HP_2.14 | |
ruleResultIndicator | HP_2.14 | |
ruleDetailedInfo | HP_2.14 |
Syntaxe des listes d'objets complexes dans les réponses
Le format d'une liste d'objets complexes dans les réponses automatiques et manuelles est défini comme suit (en gras) :
..|amount=1000|currencyCode=978|objectNameList=[{"field1":"value1a",
"field2":"value2a","field3":"value3a"…},{"field1":"value1b",
"field2":"value2b","field3":"value3b"}…]|transactionReference=1452687287828|..
- le contenu de la liste est enveloppé dans une paire de crochets [ ] ;
- chaque entrée de la liste est enveloppé dans une paire d'accolades { } ;
- chaque champ est représenté comme "nomChamp" = "valeurChamp" ;
- notez que le nom et la valeur du champ sont tous deux enveloppés dans une paire de doubles guillemets "" ;
- les paires de nom/valeur adjacentes sont séparés par une virgule.
Exemple du champ preAuthorisationRuleResultList
Détail des règles fraude exécutées en préautorisation (en gras)
..|amount=1000|currencyCode=978|preAuthorisationRuleResultList=[
{”ruleCode”:"SC",”ruleType”:"NG",”ruleWeight”:"I",”ruleSetting”:"S",
”ruleResultIndicator”:"0",“ruleDetailedInfo”:"TRANS=1:5;
CUMUL=1000:99999900"},{”ruleCode”:"GC",”ruleType”:"NG",”ruleWeight”:
"D",”ruleSetting”:"N",”ruleResultIndicator”:"0",“ruleDetailedInfo”:
""},{”ruleCode”:"CR",”ruleType”:"NG",”ruleWeight”:"D",”ruleSetting”
:"S",”ruleResultIndicator”:"N",“ruleDetailedInfo”:"CARD_COUNTRY=USA"}]
|transactionReference=1452687287828|..
Analyser la réponse de paiement
Si vous procédez à une authentification par sceau électronique (seal), vous devez impérativement vérifier que le sceau reçu correspond bien au sceau que vous recalculez avec les champs de la réponse.
Si le sceau reçu ne correspond pas au sceau que vous recalculez, l’état de la transaction est considéré comme inconnu : laissez la transaction en l’état, contactez le support et ne ré-exécutez pas la transaction de manière automatisée.
État | Champs de la réponse | Action à réaliser |
---|---|---|
Paiement accepté |
responseCode = 00 acquirerResponseCode = 00 garanteeIndicator = Y,N,U, vide |
Vous pouvez livrer la commande en fonction du niveau de garantie que vous souhaitez (champ garanteeIndicator). |
Refus Fraude Mercanet Go-No-Go |
responseCode = 05 complementaryCode = XX preAuthorisationRuleResultList |
Le paiement a été refusé par le moteur de fraude Mercanet que vous avez configuré. Ne livrez pas la marchandise. Analysez le détail des règles fraudes exécutées par Mercanet pour connaître la cause du refus (champ preAuthorisationRuleResultList). |
Refus Fraude Mercanet Business Score |
responseCode = 05 scoreColor = RED, BLACK scoreValue = X (score de la transaction) scoreThreshold = X,Y (seuil orange, seuil vert) |
Le paiement a été refusé par le moteur de fraude Mercanet que vous avez configuré Ne livrez pas la marchandise. Analysez le détail des règles fraudes exécutées par Mercanet pour connaître la cause du refus (champ preAuthorisationRuleResultList). |
Warning Fraude Mercanet Business Score |
responseCode = 05 scoreColor = ORANGE scoreValue = X (score de la transaction) scoreThreshold = X,Y (seuil orange, seuil vert) |
Le paiement a été autorisé par l’acquéreur mais le moteur de fraude Mercanet émet un warning par rapport aux règles que vous avez configurées. Analysez le détail des règles fraudes exécutées par Mercanet pour connaître la cause du warning (champ preAuthorisationRuleResultList). Si transaction non risquée alors acceptez-la avec la fonction acceptChallenge. Si transaction risquée alors refusez-la avec la fonction refuseChallenge. Les fonctions acceptChallenge et refuseChallenge sont disponibles sur le Merchant Extranet et les connecteurs Office (M2M) et Office Batch. |
Refus 3-D Secure |
reponseCode = 05 holderAuthenStatus = FAILURE |
L’authentification du client a échoué, ce n’est pas nécessairement un cas de fraude. Vous pouvez proposer à votre client de payer avec un autre moyen de paiement en générant une nouvelle requête. |
Refus bancaire acquéreur |
responseCode = 05 acquirerResponseCode = XX |
L’autorisation est refusée pour un motif non lié à la fraude. Vous pouvez proposer à votre client de payer avec un autre moyen de paiement en générant une nouvelle requête. |
Repli VADS | responseCode = 05 acquirerResponseCode = A1 |
Le paiement a été refusé par l'acquéreur car il manque les
données 3-D Secure dans la demande d'autorisation. Veuillez
retenter le paiement avec une cinématique
3-D Secure. |
Refus fraude acquéreur |
responseCode = 34 acquirerResponseCode = XX |
Autorisation refusée pour cause de fraude. Ne livrez pas la commande. |
Refus nombre max essais atteint |
responseCode = 75 acquirerResponseCode = XX |
L’acheteur a fait plusieurs tentatives toutes échouées car les informations saisies n’étaient pas correctes. Deux possibilités : Difficulté pour votre client pour renseigner les informations cartes. Tentative de carding (recherche de numéros de cartes possibles). Prenez contact avec votre client pour définir la suite à donner. |
Refus suite problème technique |
responseCode = 90, 99 acquirerResponseCode = 90 à 98 |
Problème technique temporaire lors du traitement de la transaction. Proposez à votre client de refaire un paiement ultérieurement. |
Abandon du paiement | responseCode = 97 acquirerResponseCode = non renseigné |
Ne livrez pas la commande |
Etape 3 : Tester sur l'environnement de recette
Une fois le développement de la connexion à Mercanet réalisé, vous pouvez effectuer un test sur le serveur Mercanet de recette :
Url : https://payment-webinit-mercanet.test.sips-services.com/paymentInit
Pour effectuer vos tests, utilisez la boutique et recette ainsi que les cartes mentionnées sur cette page :
merchantId | 211000021310001 |
scretKey | S9i8qClCnb2CZU3y3Vn0toIOgz3z_aBi79akR30vM9o |
keyVersion | 1 |
Cette boutique de test accepte uniquement la devise Euro.
Étape 4 : valider le passage en production
Une fois la connexion de votre site Web à Paypage POST testée, vous êtes à présent en mesure de valider la connexion à Paypage POST de production.
Au préalable, nous conseillons d’isoler votre site Web du public pour éviter que des clients ne génèrent des requêtes pendant cette phase de validation.
Si vous souhaitez personnaliser vos pages de paiement et de gestion de wallet, vous pouvez utiliser notre outil CustomPages, permettant de tester et visualiser le rendu des pages. Pour cela, merci de vous référer à la documentation CustomPages afin d’utiliser l’outil.
Pour basculer sur le serveur de production, vous devez changer l’URL pour vous connecter au serveur Mercanet de production en utilisant les identifiants merchantId, secretKey et keyVersion reçus lors l’inscription.
URL | https://payment-webinit.mercanet.com/paymentInit |
merchantId | Identifiant de la boutique reçu par mail |
SecretKey | Clé secrète que vous récupérez via l’extranet Mercanet Téléchargement |
keyVersion | Version clé secrète récupérée sur Mercanet Téléchargement (logiquement 1 pour la 1ère clé) |
Comment valider le bon fonctionnement en production
Immédiatement :
- faites une transaction avec une carte de paiement réelle (si possible la vôtre). Si la transaction est acceptée, elle sera envoyée en banque pour créditer votre compte commerçant et débiter le compte carte ;
- vérifiez que vos pages de paiement intègrent vos paramètres de personnalisation ;
- consultez la transaction via Mercanet Back Office à partir du transactionReference.
Le lendemain :
- vérifiez la présence de la transaction dans le journal des transactions ;
- vérifiez sur votre compte que l’opération a bien été créditée ;
- remboursez la transaction via Mercanet Back Office (optionnel).
Le surlendemain :
- vérifiez que l’opération de remboursement apparaît dans le journal des opérations ;
- vérifiez sur votre compte le débit suite au remboursement.
Cette procédure de validation est également applicable au moyen de paiement PayPal.
Étape 5 : démarrer en production
Une fois la validation du passage en production effectuée, ouvrez votre site au public pour permettre à vos clients d’acheter et de payer.
Dans la journée :
- surveillez le taux d’acceptation (nombre de responseCode 00 / nombre total de transactions).
- vérifiez la nature des refus non bancaires :
- problème technique : responseCode 90, 99 ;
- fraude : responseCode 34 ;
- nombre maximum de tentatives de paiement atteint : responseCode 75 ;
- abandon : responseCode 97.
Le lendemain :
- vérifiez dans le journal des transactions la présence de toutes les transactions traitées (acceptées et refusées) ;
- vérifiez, dans le journal des opérations, les opérations que vous avez effectuées ainsi que les remises (si vous avez choisi cette option du journal).