...
Exemples d’implémentation
Trois étapes sont nécessaires :
Ancre | ||||
---|---|---|---|---|
|
Préparation de la page de collecte des données carte
Avant de présenter la page à ses acheteurs, le commerçant doit préparer les éléments qui serviront à envoyer la demande de token à Payline :
...
À noter que la chaîne de caractères chiffrée (obtenue à l’étape 5) doit être encodée en base64url (cf. https://fr.wikipedia.org/wiki/Base64#base64url).
Code serveur PHP
Préparer un hash de la clé d’accès :
Bloc de code | ||||
---|---|---|---|---|
| ||||
$aes256Key = hash("SHA256", $accessKey, true); |
...
La donnée accessKey représente la clé d’accès du commerçant
Chiffrer Pour chiffrer les données. Il , il faut d’abord concaténer les données avant de chiffrer la chaine de caractères obtenue :
...
Avec :
merchantId : identifiant Payline du commerçant
orderRef : référence unique de la commande en cours
contractNumber : numéro de contrat Payline sur lequel va porter le paiement.
Code serveur J2E
Préparer un hash de la clé d’accès :
Bloc de code | ||||
---|---|---|---|---|
| ||||
MessageDigest sha = MessageDigest.getInstance("SHA-256"); aes256Key = sha.digest(accessKey.getBytes("UTF-8")); |
La donnée accessKey représente la clé d’accès du commerçant.
Chiffrer les données. Il faut d’abord concaténer les données avant de chiffrer la chaîne de caractères obtenue :
Bloc de code | ||||
---|---|---|---|---|
| ||||
byte[] msgUtf8 = (merchantId+orderRef+ContractNumber).getBytes("UTF-8"); SecretKeySpec secretKeySpec = new SecretKeySpec(accessKeyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); byte[] ciphered = cipher.doFinal(msgUtf8); String crypted = Base64.encodeBase64URLSafeString(ciphered); |
Avec :
merchantId : identifiant Payline du commerçant ;
orderRef : référence unique de la commande en cours ;
contractNumber : numéro de contrat Payline sur lequel va porter le paiement.
Ancre | ||||
---|---|---|---|---|
|
Page de paiement
La page de paiement doit implémenter un fonctionnement qui garantit que le numéro de carte saisit par l’acheteur ne sera jamais stocké (ni par le navigateur de l’acheteur, ni par le serveur web du commerçant).
...
Exemple utilisable dans un formulaire du type :
Bloc de code | ||||
---|---|---|---|---|
| ||||
<form id="paymentForm" action="#" method="post"> <input type="hidden" name="data" id="data" size='255' value="<?php echo $crypted ?>" /> <input type="hidden" name="accessKeyRef" id="accessKeyRef" value="<?php echo $accessKeyRef ?>" /> <label for="">Numéro de carte</label> <input type="text" name="cardNumber" id="cardNumber"/> <label for="">Date d'expiration</label> <input type="text" name="cardExpirationDate" id="cardExpirationDate"/> <label for="">Cryptogramme</label> <input type="text" name="cardCvx" id="cardCvx"/> <br/> <input type="submit" class="btn btn-primary" value="Payer" /> </form> |
Avec :
crypted : données chiffrées préparées à l’étape précédente
accessKeyRef : référence de la clé d’accès commerçant
Ancre | ||||
---|---|---|---|---|
|
Traitement de la réponse
La réponse contient des données qu’il faut déchiffrer et décompresser, le tout étant codé en base64url.
...
Pour plus d’information sur l’API webservice, vous pouvez consulter la documentation associée.
Serveur PHP
Déchiffrer les données reçues :
Bloc de code | ||||
---|---|---|---|---|
| ||||
$zippedData = getDecrypt($data, $aes256Key); function getDecrypt($message, $key){ $message = base64_url_decode($message); $message = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $message, MCRYPT_MODE_ECB); $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); $len = strlen($message); $pad = ord($message[$len-1]); return substr($message, 0, $len-$pad); } |
...
La donnée data représente la valeur du paramètre ($_POST['data']) reçu en retour (cas où l’appel ne retourne pas une erreur).
Décompresser les données :
Bloc de code | ||||
---|---|---|---|---|
| ||||
$uncompressedData = gzdecode($zippedData); |
Découper le résultat pour récupérer le résultat de l’appel :
Bloc de code | ||||
---|---|---|---|---|
| ||||
$paylineDataResponse=explode(';', $uncompressedData); $cardToken = $paylineDataResponse[0]; $cardExpirationDate = $paylineDataResponse[1]; $cardVirtualCVV = $paylineDataResponse[2]; $orderReference = $paylineDataResponse[3]; … |
...
Serveur J2E
Déchiffrer les données reçues :
Bloc de code | ||||
---|---|---|---|---|
| ||||
byte[] decryptedMessage = new byte[0]; zippedData = AESEncryption.decrypt(aes256Key, data); public static final byte[] decrypt(final String key, final String message) { byte[] decrypt = new byte[0]; MessageDigest sha = MessageDigest.getInstance("SHA-256"); keyBytes = sha.digest(key.getBytes("UTF-8")); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); decrypt = cipher.doFinal(Base64.decodeBase64(message.getBytes("UTF-8"))); return finalDecrypt; } |
...
La donnée data représente la valeur du paramètre (request.getParameter("data")) reçu en retour (cas où l’appel ne retourne pas une erreur).
Décompresser les données :
Bloc de code | ||||
---|---|---|---|---|
| ||||
final StringBuffer outStr = new StringBuffer(); final ByteArrayInputStream gzipedStr = new ByteArrayInputStream(zippedData); final GZIPInputStream gis = new GZIPInputStream(gzipedStr); final BufferedReader bf = new BufferedReader(new InputStreamReader(gis)); String line; while ((line = bf.readLine()) != null) { outStr.append(line); } gis.close(); String uncompressedData = outStr.toString(); |
Découper le résultat pour récupérer le résultat de l’appel :
Bloc de code | ||||
---|---|---|---|---|
| ||||
String[] paylineDataResponse = uncompressedData.split(";"); String cardToken = paylineDataResponse[0]; String cardExpirationDate = paylineDataResponse[1]; String cardVirtualCVV = paylineDataResponse[2]; String orderReference = paylineDataResponse[3]; … |