Documentation

1Introduction

Pour créer un paiement via la plateforme, vous avez le choix entre la payment page integration, où le client est redirigé vers notre page de paiement, la iframe integration, où le formulaire de paiement est placé dans une iframe à l’aide de notre intégration JavaScript, ou la lightbox integration, afin d’obtenir une intégration transparente et conforme PCI DSS dans votre checkout.

L’objectif de l’intégration iframe est de permettre la collecte et la validation des informations de paiement avant que la commande proprement dite ne soit confirmée par le client. Par exemple, l’iframe peut être intégrée avant que la commande ne soit réellement finalisée dans l’application du marchand. Cela permet le processus suivant (simplifié) dans l’application du marchand :

  1. Le client saisit les informations de livraison et de facturation.

  2. L’utilisateur sélectionne le mode de paiement. L’application intègre l’iframe avec le formulaire permettant de collecter des informations de paiement supplémentaires. Le formulaire dépend du mode de paiement et éventuellement même du connecteur.

  3. L’application peut déclencher une validation des informations saisies.

  4. L’utilisateur peut confirmer la commande et l’application nous communique l’état final de la transaction. Ensuite, l’iframe est soumise avec JavaScript. L’iframe peut être masquée après la validation des données. La soumission déclenche une sortie du frame.

L’avantage de cette intégration par rapport à la page de paiement est que l’intégration est transparente et que le client ne remarque jamais que le site du marchand est quitté. De plus, les informations de paiement peuvent être saisies avant que la commande ne doive être finalisée. Cela implique que le numéro de commande peut être fourni après la collecte des informations de paiement. Cependant, l’intégration est plus compliquée que l’intégration de la page de paiement.

Seamless Iframe Integration
Figure 1. L’image montre un exemple d’intégration iframe transparente

2Détails de l’intégration iframe

Avant de commencer l’intégration de l’iframe, vous devriez :

  1. Créer un compte et vous inscrire.

  2. Créer un utilisateur d’application sous Account > Utilisateurs > Utilisateur d’application.

  3. Apprendre à vous authentifier et vous connecter à notre service web.

Note
Veuillez consulter notre dépôt github où nous proposons des SDK prêts à télécharger dans différents langages qui facilitent considérablement vos efforts d’intégration.

Nous vous proposons également un client API qui vous permet de tester les requêtes envoyées à l’API et de voir les réponses.

3Interactions système

iframe
Figure 2. Diagramme de séquence de l’intégration iframe

3.1Processus

Nous allons décrire ci-dessous le processus d’intégration en détail. Pour mieux le comprendre, consultez le diagramme des interactions système ci-dessus.

  1. Créez un objet transaction avec le Transaction Service. Pour créer un objet transaction, vous pouvez fournir toutes les informations dont vous disposez à ce stade. Plus vous fournissez d’informations, mieux nous pouvons prévalider les données et éventuellement exclure certains modes de paiement qui ne fonctionneront pas avec ces données. La plupart des données fournies peuvent être modifiées avant que la transaction ne soit réellement confirmée.

  2. Une fois l’objet transaction créé, les modes de paiement possibles peuvent être récupérés en utilisant récupérer les modes de paiement possibles sur le Transaction Service en fournissant le transactionId retourné par la requête initiale et le mode d’intégration iframe. La méthode retourne tous les modes de paiement qui sont actifs pour la transaction en cours. La méthode peut être utilisée pour vérifier si un mode particulier est actif ou pour afficher tous les modes disponibles. Cela dépend de l’application du marchand.

  3. Pour intégrer l’iframe dans le site web, une URL JavaScript doit être récupérée. Pour cela, la méthode de service construire l’URL JavaScript peut être utilisée. L’URL retournée par la méthode de service pointe vers le fichier JavaScript qui doit être intégré. Il suffit de l’intégrer une seule fois et non pour chaque mode de paiement. Le script peut être intégré à l’aide de la balise <script>.

  4. Une fois le JavaScript chargé, utilisez window.IframeCheckoutHandler(paymentMethodConfigurationId) pour créer un nouveau gestionnaire de checkout iframe, où paymentMethodConfigurationId est l’ID de la configuration du mode de paiement telle que retournée par récupérer les modes de paiement possibles. Ce gestionnaire peut être utilisé pour charger l’iframe. Pour charger l’iframe, appelez create(containerId)containerId est l’id de l’élément HTML dans lequel l’iframe doit être intégrée. Il est recommandé d’enregistrer un validationCallback avant la création de l’iframe, qui est appelé chaque fois que la validation est déclenchée sur le formulaire chargé dans l’iframe. Le validationCallback est défini sur le gestionnaire avec la méthode setValidationCallback(validationCallback). Le callback doit être utilisé pour afficher les messages d’erreur fournis en argument.

  5. Il est possible d’enregistrer des callbacks supplémentaires et optionnels sur le gestionnaire, avant la création de l’iframe. Le initializeCallback peut être utilisé pour enregistrer un gestionnaire qui est invoqué après l’initialisation de l’iframe. Le heightChangeCallback est invoqué chaque fois que la hauteur de l’iframe change. L’argument du callback est la hauteur en pixels. Les callbacks sont définis avec la méthode setInitializeCallback(initializeCallback) ou setHeightChangeCallback(heightChangeCallback) respectivement.

  6. Ajoutez un bouton qui déclenche la validation du formulaire dans l’iframe. Pour déclencher la validation, appelez la méthode validate() sur le gestionnaire de checkout iframe. Vous pouvez masquer l’iframe lorsque la validation s’est terminée sans erreur. Ne supprimez pas l’iframe. Les données stockées dans le frame seront utilisées plus tard.

  7. Une fois le formulaire validé et lorsque la transaction doit être finalisée, créez une commande dans votre application et confirmez la transaction avec la méthode confirm sur le Transaction Service. Vous devriez utiliser un appel Ajax car sinon l’iframe est rechargée et toutes les données sont perdues. Vous pouvez également mettre à jour la transaction avant de la confirmer. Par exemple, vous pouvez appliquer des frais supplémentaires en fonction du mode de paiement sélectionné ou modifier les frais de livraison ou l’adresse de livraison.

  8. La méthode submit() doit maintenant être appelée sur le gestionnaire de checkout iframe. Cela entraîne la soumission du formulaire dans l’iframe et la sortie de l’iframe, c’est-à-dire que le site du marchand est quitté. Le client est éventuellement invité à saisir des informations supplémentaires. Cela dépend du mode de paiement.

  9. Lorsque la transaction est authorized ou failed de notre côté, le client est redirigé vers la successUrl ou la failedUrl qui a été définie lors de la création de l’objet transaction.

  10. Écoutez la notification sur l’URL de webhook définie pour marquer la commande dans le système du marchand comme authorized ou failed. Cet écouteur de notification est important car le client peut fermer la fenêtre avant de revenir à l’application du marchand. L’état de la transaction peut être récupéré à tout moment via l’API.

3.2Action primaire remplacée

Certains modes de paiement nécessitent un processus plus complexe en plusieurs étapes. Par défaut, un bouton est inclus dans le formulaire de paiement pour naviguer à travers ces étapes. Il est toutefois possible de masquer ces boutons et d’utiliser le bouton de soumission principal de votre application pour déclencher les événements.

Pour gérer les actions primaires remplacées, enregistrez un callback sur le gestionnaire iframe avec setReplacePrimaryActionCallback(callback). Ce callback est invoqué avec le nouveau libellé en paramètre, avec lequel le bouton principal doit être mis à jour chaque fois que l’action primaire est remplacée. De plus, le bouton doit être modifié pour déclencher l’action trigger().

Lorsque le client a parcouru avec succès toutes les étapes nécessaires, le callback enregistré avec setResetPrimaryActionCallback(callback) est invoqué, ce qui doit entraîner la réinitialisation du bouton principal à son comportement par défaut, c’est-à-dire avoir le libellé initial et déclencher les actions validate() et submit().

Pour masquer les boutons dans le formulaire de paiement, définissez la configuration en conséquence avant de créer le gestionnaire de checkout iframe :

window.IframeCheckoutHandler.configure('replacePrimaryAction', true);

3.3Détails techniques

Les étapes décrites ci-dessus vont maintenant être expliquées un peu plus en détail, y compris les opérations API avec des exemples de requêtes.

3.3.1Configuration côté client

L’acceptation des paiements via iFrame offre un moyen transparent de collecter les informations de paiement de votre client. Cette méthode est non seulement intégrée de manière transparente, elle répond également à toutes les exigences PCI DSS pour les marchands afin de vous maintenir hors du périmètre autant que possible tout en obtenant un flux de checkout entièrement intégré.

Voir ci-dessous un exemple de configuration côté client où l’iframe sera placée à l’aide de la ressource JavaScript qui est fournie par la plateforme. La manière dont la { JavaScript URL } peut être résolue, où le paymentMethodConfigurationId peut être récupéré, etc. est montrée dans les exemples ci-dessous.

<ul id="payment-errors"></ul>
<div id="payment-form"></div>
<button id="pay-button">Pay</button>

<script src="jquery.js" type="text/javascript"></script>
<script src="{ JavaScript URL }" type="text/javascript"></script>
<script type="text/javascript">
// Set here the id of the payment method configuration the customer chose.
var paymentMethodConfigurationId = 1;

// Set here the id of the HTML element the payment iframe should be appended to.
var containerId = 'payment-form';

var handler = window.IframeCheckoutHandler(paymentMethodConfigurationId);

handler.setValidationCallback(
	function(validationResult){
		// Reset payment errors
		$('#payment-errors').html('');

		if (validationResult.success) {
			// Create the order within the shop and eventually update the transaction.
			$.ajax('http://your-shop-backend.com/create-order', {
				success: function(){
					handler.submit();
				}
			});
		} else {
			// Display errors to customer
			$.each(validationResult.errors, function(index, errorMessage){
				$('#payment-errors').append('<li>' + errorMessage + '</li>');
			});
		}
	});

//Set the optional initialize callback
handler.setInitializeCallback(function(){
		//Execute initialize code
	});

//Set the optional height change callback
handler.setHeightChangeCallback(function(height){
		//Execute code
	});

handler.create(containerId)


$('#pay-button').on('click', function(){
	handler.validate();
});
</script>

3.3.2Créer un objet transaction

Pour créer un objet transaction, vous devez utiliser l’opération de création de transaction. Vous y fournissez les détails du client dont vous disposez, y compris les lignes d’articles et les prix. Cela créera une transaction pending dans votre Space.

Note
Il est recommandé de fournir toutes les informations dont vous disposez sur l’acheteur. Plus nous avons d’informations, plus la sélection des modes de paiement possibles sera précise.

Requête

{
   "billingAddress":{
	  "city":"Winterthur",
	  "commercialRegisterNumber":"",
	  "country":"CH",
	  "dateOfBirth":"",
	  "emailAddress":"[email protected]",
	  "familyName":"Test",
	  "gender":"",
	  "givenName":"Sam",
	  "mobilePhoneNumber":"",
	  "organizationName":"Wallee AG",
	  "phoneNumber":"",
	  "postcode":"8400",
	  "salesTaxNumber":"",
	  "salutation":"",
	  "socialSecurityNumber":"",
	  "state":"",
	  "street":"General-Guisan-Strasse 47"
   },
   "currency":"EUR",
   "language":"de-CH",
   "lineItems":[
	  {
		 "amountIncludingTax":"11.87",
		 "name":"Barbell Pull Up Bar",
		 "quantity":"1",
		 "shippingRequired":"true",
		 "sku":"barbell-pullup",
		 "type":"PRODUCT",
		 "uniqueId":"barbell-pullup"
	  },
	  {
		 "amountIncludingTax":"559",
		 "name":"Rowing Machine",
		 "quantity":"1",
		 "shippingRequired":"true",
		 "sku":"rowing-machine",
		 "type":"PRODUCT",
		 "uniqueId":"rowing-machine"
	  },
	  {
		 "amountIncludingTax":"17.98",
		 "name":"Super Whey Protein",
		 "quantity":"4",
		 "shippingRequired":"true",
		 "sku":"super-whey",
		 "taxes":[
			{
			   "rate":"10",
			   "title":"VAT"
			},
			{
			   "rate":"3.5",
			   "title":"Supplement Fee"
			}
		 ],
		 "type":"PRODUCT",
		 "uniqueId":"super-whey"
	  },
	  {
		 "amountIncludingTax":"12.5",
		 "name":"Special Chär Test",
		 "quantity":"1",
		 "shippingRequired":"false",
		 "sku":"special-chär-test",
		 "type":"SHIPPING",
		 "uniqueId":"special-chär-test"
	  },
	  {
		 "amountIncludingTax":"12.5",
		 "name":"Standard Shipping",
		 "quantity":"1",
		 "shippingRequired":"false",
		 "sku":"standard-shipping",
		 "type":"SHIPPING",
		 "uniqueId":"standard-shipping"
	  },
	  {
		 "amountIncludingTax":"-10",
		 "name":"Spring Discount",
		 "quantity":"1",
		 "shippingRequired":"false",
		 "sku":"spring-discount",
		 "type":"DISCOUNT",
		 "uniqueId":"spring-discount"
	  }
   ],
   "merchantReference":"DEV-2630",
   "shippingAddress":{
	  "city":"Winterthur",
	  "commercialRegisterNumber":"",
	  "country":"CH",
	  "dateOfBirth":"",
	  "emailAddress":"[email protected]",
	  "familyName":"Test",
	  "gender":"",
	  "givenName":"Sam",
	  "mobilePhoneNumber":"",
	  "organizationName":"Wallee AG",
	  "phoneNumber":"",
	  "postcode":"8400",
	  "salesTaxNumber":"",
	  "salutation":"",
	  "socialSecurityNumber":"",
	  "state":"",
	  "street":"General-Guisan-Strasse 47"
   }
}

Réponse

La réponse que vous recevrez contient l'`id` (dans l’exemple ci-dessous 109472) qui sera désormais utilisé pour effectuer d’autres opérations avec cette transaction.

{
	"allowedPaymentMethodBrands": [],
	"allowedPaymentMethodConfigurations": [],
	"authorizationAmount": 603.85,
	"authorizationTimeoutOn": "2017-12-07T08:44:09.119Z",
	"autoConfirmationEnabled": true,
	"chargeRetryEnabled": true,
	"confirmedBy": 0,
	"createdBy": 0,
	"createdOn": "2017-12-07T08:14:09.119Z",
	"currency": "EUR",
	"customersPresence": "VIRTUAL_PRESENT",
	"endOfLife": "2017-12-21T08:14:09.119Z",
	"group": {
	  "id": 109478
	},
	"id": 109472,
	"language": "de-CH",
	"linkedSpaceId": 396,
	"metaData": {},
	"plannedPurgeDate": "2017-12-21T08:14:09.119Z",
	"refundedAmount": 0,
	"state": "PENDING",
	"timeZone": "Z",
	"version": 1
}

3.3.3Construire l’URL JavaScript

Pour obtenir l’URL du JavaScript, vous pouvez utiliser l’opération buildJavaScriptUrl afin d’obtenir une URL pointant vers le JavaScript qui doit être inclus dans votre checkout pour créer l’iframe. Insérez le JavaScript sur votre page où l’iframe doit être affichée, comme montré dans l’exemple côté client ci-dessus.

3.3.4Récupérer les modes de paiement possibles

Pour intégrer l’iframe de manière transparente dans votre checkout, vous devrez récupérer les modes de paiement possibles et afficher les options dans le checkout.

Cela retournera l'`id` du mode de paiement qui doit ensuite être défini dans le JavaScript en utilisant le paymentMethodConfigurationId.

Réponse

La réponse retourne les modes de paiement possibles pour le transactionId donné.

{
	"data": [{
		"dataCollectionType": "ONSITE",
		"description": {
			"en-US": ""
		},
		"id": 510,
		"linkedSpaceId": 396,
		"name": "Credit / Debit Card",
		"oneClickPaymentMode": "ALLOW",
		"paymentMethod": {
			"id": 1457546097597
		},
		"resolvedDescription": {
			"en-US": "Pay conveniently with your credit or debit card."
		},
		"resolvedImageUrl": "https://checkout.postfinance.ch/s/396/resource/icon/payment/method/credit-debit-card.svg",
		"resolvedTitle": {
			"en-US": "Credit / Debit Card"
		},
		"sortOrder": 1,
		"spaceId": 396,
		"state": "ACTIVE",
		"title": {
			"en-US": ""
		},
		"version": 2
	}],
	"hasMore": false,
	"limit": 1
}

3.3.5Mettre à jour les transactions

Les propriétés de la transaction peuvent être mises à jour tant qu’elle n’est pas dans l’état confirmed. Pour ce faire, utilisez l’opération update sur le service Transaction.

Note
Consultez la section Versionnage / verrouillage des objets qui décrit comment vous devez gérer la propriété version pour éviter les problèmes de verrouillage optimiste.

Requête

Dans l’exemple ci-dessous, nous allons mettre à jour les lignes d’articles et supprimer la ligne de remise que nous avons ajoutée dans l’exemple ci-dessus.

{
	"billingAddress": {
		"city": "Winterthur",
		"country": "CH",
		"emailAddress": "[email protected]",
		"familyName": "Test",
		"givenName": "Sam",
		"postcode": "8400",
		"street": "General-Guisan-Strasse 47"
	},
	"currency": "EUR",
	"id": 109472,
	"language": "de-CH",
	"lineItems": [
		{
			"amountIncludingTax": "11.87",
			"name": "Barbell Pull Up Bar",
			"quantity": "1",
			"sku": "barbell-pullup",
			"type": "PRODUCT",
			"uniqueId": "barbell-pullup"
		},
		{
			"amountIncludingTax": "559",
			"name": "Rowing Machine",
			"quantity": "1",
			"sku": "rowing-machine",
			"type": "PRODUCT",
			"uniqueId": "rowing-machine"
		},
		{
			"amountIncludingTax": "17.98",
			"name": "Super Whey Protein",
			"quantity": "4",
			"sku": "super-whey",
			"type": "PRODUCT",
			"uniqueId": "super-whey"
		},
		{
			"amountIncludingTax": "12.5",
			"name": "Special Chär Test",
			"quantity": "1",
			"sku": "special-chär-test",
			"type": "SHIPPING",
			"uniqueId": "special-chär-test"
		},
		{
			"amountIncludingTax": "12.5",
			"name": "Standard Shipping",
			"quantity": "1",
			"sku": "standard-shipping",
			"type": "SHIPPING",
			"uniqueId": "standard-shipping"
		}
	],
	"shippingAddress": {
		"city": "Winterthur",
		"country": "CH",
		"emailAddress": "[email protected]",
		"familyName": "Test",
		"givenName": "Sam",
		"postcode": "8400",
		"street": "General-Guisan-Strasse 47"
	},
	"version": 3
}

Réponse

La réponse contient l’objet transaction mis à jour.

{
	"currency": "EUR",
	"id": 109472,
	"language": "de-CH",
	"version": 3
}

3.3.6Confirmer la transaction

Si la propriété de confirmation automatique n’est pas définie, la transaction doit être confirmée. Nous recommandons d’effectuer cette étape dans tous les cas.

L’étape de confirmation de la transaction doit être effectuée une fois que les saisies du client ont été validées et que la commande en attente est créée dans votre application (voir l’étape 7 du processus ci-dessus). Vous pouvez utiliser l’opération de confirmation pour confirmer la transaction et également définir la merchant reference puisque vous disposez maintenant d’un numéro de commande dans votre application.

Requête

{
	"billingAddress": {
		"city": "Winterthur",
		"country": "CH",
		"emailAddress": "[email protected]",
		"familyName": "Test",
		"givenName": "Sam",
		"postcode": "8400",
		"street": "General-Guisan-Strasse 47"
	},
	"currency": "EUR",
	"id": 109472,
	"language": "de-CH",
	"lineItems": [
		{
			"amountIncludingTax": "11.87",
			"name": "Barbell Pull Up Bar",
			"quantity": "1",
			"sku": "barbell-pullup",
			"type": "PRODUCT",
			"uniqueId": "barbell-pullup"
		},
	 ],
	"merchantReference": "DEV-2630",
	"shippingAddress": {
		"city": "Winterthur",
		"country": "CH",
		"emailAddress": "[email protected]",
		"familyName": "Test",
		"givenName": "Sam",
		"postcode": "8400",
		"street": "General-Guisan-Strasse 47"
	},
	"version": 5
}

3.3.7Récupérer les mises à jour de la transaction

Pour être informé de l’état de la transaction, vous devriez enregistrer des notifications webhook de votre côté. Les webhooks vous informeront des changements d’état des entités sélectionnées et devraient déclencher le traitement ultérieur des résultats de la transaction par votre application.

Plus d’informations sur les webhooks, les écouteurs de webhooks et leur configuration sont disponibles dans la documentation des webhooks.

4Politique de sécurité

Si des restrictions de content security policy sont appliquées dans la boutique, pour que cette intégration fonctionne, les restrictions suivantes doivent être supprimées pour https://checkout.postfinance.ch :

  • URL pouvant être chargées comme sources valides pour JavaScript.

  • Autoriser les exécutions de scripts inline.

  • URL pouvant être chargées via les interfaces iframe.

  • URL pouvant être chargées via les interfaces de script.

Par exemple, l’en-tête suivant le permettrait en définissant la directive CSP: script-src pour autoriser le chargement des URL https://checkout.postfinance.ch comme sources valides pour JavaScript, la politique Unsafe inline script pour autoriser les exécutions de scripts inline, la directive CSP: frame-src pour autoriser le chargement des URL https://checkout.postfinance.ch via les interfaces iframe, la directive CSP: connect-src pour autoriser le chargement des URL https://checkout.postfinance.ch via les interfaces de script.

content-security-policy: script-src https://checkout.postfinance.ch 'unsafe-inline'; frame-src https://checkout.postfinance.ch; connect-src https://checkout.postfinance.ch;