Python SDK
Pour créer des paiements, vous devez connecter votre serveur à notre plateforme via l'une de nos méthodes d'intégration.
Notre bibliothèque SDK Python est la solution idéale pour vous connecter à notre plateforme si vous préférez le faire avec votre propre système autonome en utilisant le langage Python.
En choisissant le SDK Python, vous pouvez :
- Accéder à toutes les fonctionnalités de notre API RESTful de manière compacte, pratique et personnalisable.
- Utiliser toutes les méthodes d'intégration côté serveur de notre plateforme (Hosted Checkout Page / Hosted Tokenization Page / Server-to-server).
- Effectuer tous les appels API liés au traitement des paiements (c'est-à-dire CreateHostedCheckout, CreatePayment, RefundPayment et bien d'autres).
Pour tirer pleinement parti de ce SDK, assurez-vous de remplir ces exigences :
- Python 3.7 et supérieur
Installez la dernière version du SDK Python en utilisant le gestionnaire de paquets PIP :
- Pour Python 3.7 ou supérieur, exécutez :
pip install onlinepayments-sdk-python3
Trouvez plus de détails sur GitHub (Python3). Consultez également tous les objets et propriétés SDK disponibles dans notre Documentation complète API Reference. Une fois que vous êtes prêt, lisez les chapitres suivants sur la préparation et l'utilisation du SDK.
Ce guide offre une vue d'ensemble générale sur les fonctionnalités du SDK. Pour voir comment elles fonctionnent précisément pour les différentes modes d'intégration, consultez les guides dédiés qui expliquent chaque étape avec des exemples de code complets :
Initialisation
Pour connecter votre système à notre plateforme en utilisant le SDK, vous devez d'abord l'initialiser.
L'initialisation du SDK nécessite de :
- Créer un compte test/production.
- Créer un fichier de propriétés.
[OnlinePaymentsSDK] onlinepayments.api.integrator=integrator onlinepayments.api.endpoint.host=ApiEndpoint ; Les clés suivantes sont optionnelles et utilisent par défaut la valeur indiquée. onlinepayments.api.endpoint.scheme=https onlinepayments.api.endpoint.port=-1 onlinepayments.api.connectTimeout=5 onlinepayments.api.socketTimeout=300 onlinepayments.api.maxConnections=10 onlinepayments.api.authorizationType=v1HMAC
- Créer une API Key et un API Secret pour le PSPID que vous souhaitez utiliser pour le traitement des transactions.
- Initialiser une instance de Client / MerchantClient en utilisant la API Key / API Secret pour établir la connexion à notre plateforme test/production.
from onlinepayments.sdk.factory import Factory client = Factory.create_client_from_file("payments_sdk.prp", apiKey, apiSecret) merchant_client = client.merchant(merchantId)
Où "payments_sdk.prp" est le nom d'un fichier avec des propriétés.
Le tableau suivant fournit un aperçu des arguments acceptés par chaque instance :
Propriétés |
---|
|
Après l'initialisation, vous pouvez envoyer des demandes à notre plateforme via votre PSPID. Apprenez comment le faire dans le prochain chapitre.
Comme nos SDK intègrent toujours la dernière version de notre API, vous pouvez omettre le paramètre "v2" dans votre code, comme montré dans l'exemple ci-dessus.
N'oubliez pas de prêter attention à la correspondance entre l'environnement et les clés. La API Key et le API Secret sont différents pour les environnements de test et de production.
Le chemin complet des endpoints API est
- environnement de test: https://payment.preprod.ca.cawl-solutions.fr/v2/
- environnement de production: https://payment.ca.cawl-solutions.fr/v2/
Si vous êtes prêt à passer à l'environnement de production, remplacez le lien du endpoint apiEndpoint = 'https://payment.preprod.ca.cawl-solutions.fr/' par le lien de l'environnement de production apiEndpoint = 'https://payment.cawl-solutions.fr/'
Pour les transactions sans impact financier, utilisez le endpoint de test. Les transactions seront envoyées à notre environnement de test, et donc à votre compte de test.
Pour les transactions avec impact financier, utilisez le endpoint de production. Les transactions seront envoyées à notre environnement de production, et donc à votre compte de production.
Utiliser le SDK
Après l'initialisation réussie de l'instance Client, vous avez un accès complet à notre API RESTful. Cela vous permet de :
- Envoyer des demandes pour de nouvelles transactions pour n'importe laquelle de nos modes d'intégration serveur.
- Obtenir le statut actuel de vos transactions.
- Effectuer des demandes de maintenance (captures, remboursements) sur des transactions existantes.
Assurez-vous que le moyen de paiement que vous souhaitez utiliser est actif pour votre PSPID. Vous pouvez vérifiez cela directement dans le Merchant Portal via le menu Entreprise > Moyens de paiement.
Consultez nos cas de test sur GitHub (Python3), y compris des exemples de code complets, et notre API Reference complète pour découvrir ce qui est possible.
Ci-dessous, vous pouvez trouver certaines des actions les plus courantes que vous pouvez effectuer :
- Créer de nouvelles transactions
- Obtenir le statut de la transaction
- Effectuer une opération de maintenance
Créer de nouvelles transactions
Pour créer une nouvelle transaction, vous pouvez utiliser une instance de Client ou MerchantClient pour l'une de nos méthodes d'intégration afin de créer une nouvelle transaction. Cela peut être fait par :
- L'acheminement de la requête vers votre PSPID sur notre plateforme (pour Client).
- La création d'une requête pour la méthode d'intégration respective.
L'instance du SDK ne garde une trace que des données utilisées pour l'initialiser. Elle ne suit ni les sessions actives ni les demandes précédentes. Votre système est responsable de la gestion des sessions et des paiements CAWL ecommerce.
Les sessions et paiements n'impactent pas les autres sessions et paiements.
Ci-dessous, vous pouvez trouver des exemples de code liés à des modes d'intégration particulières :
Hosted Checkout Page
Pour utiliser cette méthode d'intégration, vous devez créer un appel CreateHostedCheckoutRequest. Il doit contenir au moins un objet Order.
""" Initialisation... """
order_dict = {
"order": {"amountOfMoney": {"currencyCode": "EUR", "amount": 123}}
}
hosted_checkout_client = client.merchant(merchantId).hosted_checkout()
hosted_checkout_request = CreateHostedCheckoutRequest()
hosted_checkout_request.from_dictionary(order_dict)
hosted_checkout_response = hosted_checkout_client.create_hosted_checkout(
hosted_checkout_request
)
Vous pouvez spécifier un return_url facultatif, qui sera utilisé pour rediriger votre client vers votre site web.
Cette appel retourne une réponse CreateHostedCheckoutResponse. Conservez le hosted_checkout_id et le returnmac qu'il contient, ainsi que toute autre information pertinente pour vous. Vous aurez besoin de ces éléments pour les étapes décrites dans les chapitres suivants.
Cette réponse contient également une partial_redirect_url.
Vous devez concaténer l'URL de base "https://payment." avec partial_redirect_url selon la formule
https://payment. + partial_redirect_url
et effectuer une redirection de votre client vers cette URL. Une fois que le client visite le Hosted Checkout Page, le processus de paiement se poursuit à cet endroit.
La dernière version de notre SDK renvoie également le chemin complet dans redirect_url, vous permettant de ne pas concaténer l'URL de base "https://payment." avec partial_redirect_url. Découvrez-en plus dans notre guide Hosted Checkout Page.
Hosted Tokenization Page
Pour utiliser cette méthode d'intégration, vous devez
- Créer et télécharger un modèle comme décrit dans notre guide Hosted Tokenization Page.
from onlinepayments.sdk.domain.create_hosted_tokenization_request import CreateHostedTokenizationRequest
""" Initialization... """
request = CreateHostedTokenizationRequest()
request.from_dictionary(
{
"variant": "template.html"
})
hosted_t_client = client.merchant(merchantId).hosted_tokenization()
response = hosted_t_client.create_hosted_tokenization(request)
Utilisez le partial_redirect_url pour le iframe et le hosted_tokenization_id ou token_id (voir encadré) pour créer le paiement réel via la méthode d'intégration Server-to-server.
Vous pouvez envoyer soit le tokenID, soit le hostedTokenizationId dans votre requête CreatePayment. En savoir plus sur l'utilisation de l'une ou l'autre option dans les chapitres dédiés de notre guide Hosted Tokenization Page :
token = hosted_t_client.get_hosted_tokenization(t_id).token.id
# Dictionary with all needed data for payment request
payment_dict = {
"order": {"amountOfMoney": {"currencyCode": "EUR", "amount": 12300}},
"CardPaymentMethodSpecificInput": {
"token": token,
},
}
payment_request = CreatePaymentRequest().from_dictionary(payment_dict)
payment_response = merchant_client.payments().create_payment(payment_request)
Server-to-server
Une demande CreatePaymentRequest minimale nécessite que vous définissiez au moins un objet Order et une méthode de paiement :
""" Initialization... """
# Dictionary with all needed data for payment request
payment_dict = {
"order": {"amountOfMoney": {"currencyCode": "EUR", "amount": 125000}},
"cardPaymentMethodSpecificInput": {
"card": {
"cvv": "123",
"cardNumber": "5300000000000006",
"expiryDate": "0124",
"cardholderName": "John Doe"
},
"paymentProductId": 3
},
}
payment_request = CreatePaymentRequest()
payment_request.from_dictionary(payment_dict)
payment_response = merchant_client.payments().create_payment(payment_request)
Nous avons des guides dédiés pour chacune des modes d'intégration mentionnées :
Les documents contiennent tous les détails essentiels dont vous avez besoin pour tirer parti du plein potentiel des modes d'intégration, y compris les flux de transaction complets, des exemples de code et d'autres fonctionnalités utiles.
Obtenir le statut de la transaction
Notre API RESTful vous permet de demander le statut d'une transaction à tout moment en utilisant l'une de nos appels GET :
Une requête GetPaymentDetails ressemble à ceci :
response = merchant_client.payments().get_payment_details(payment_id)
Propriétés |
---|
string payment_id : La référence unique de votre transaction sur notre plateforme. Cette référence peut être récupérée à partir du hosted_checkout_client.create_hosted_checkout() ou merchant_client.payments().create_payment(payment_request) créé dans la section précédente. |
Pour plus d'informations sur les statuts, visitez la page de documentation des statuts.
Effectuer une opération de maintenance
Pour effectuer des actions de suivi sur des transactions existantes (comme les captures ou les remboursements), utilisez respectivement notre appel API CapturePayment ou RefundPayment :
CapturePayment
from onlinepayments.sdk.domain.capture_payment_request import CapturePaymentRequest
""" Initialisation... """
# Ici, vous obtenez payment_id que vous pouvez utiliser dans le code suivant
payment_id = payment_response.payment.id
capture_request = CapturePaymentRequest()
capture_request.from_dictionary({'amount': amount, 'isFinal': True})
merchant_client.payments().capture_payment(payment_id, capture_request)
RefundPayment
from onlinepayments.sdk.domain.refund_request import RefundRequest
""" Initialisation... """
payment_id = payment_response.payment.id
refund_dict = {"amountOfMoney": {"currencyCode": "EUR", "amount": 125000}}
refund_request = RefundRequest().from_dictionary(refund_dict)
# Obtenez l'objet RefundResponse
response = merchant_client.payments().refund_payment(payment_id, refund_request)
Propriétés |
---|
string payment_id : La référence unique de votre transaction sur notre plateforme. Cette référence peut être récupérée depuis hosted_checkout_client.create_hosted_checkout() ou merchant_client.payments().create_payment(payment_request) créées dans la section précédente. |
Gérer les exceptions
Si une transaction est rejetée, notre plateforme fournit des informations détaillées avec une instance Exception. Le code d'état HTTP associé vous aide également à résoudre l'erreur.
Vous pouvez rencontrer deux types d'exceptions : les exceptions de transaction et les exceptions HTTP.
Exceptions de transaction
Ce type d'exception se réfère aux demandes de transaction qui sont techniquement correctes, mais ont été rejetées par l'émetteur de votre client ou votre acquéreur. Si la transaction est retournée dans l'exception, cela signifie qu'elle a été créée dans nos systèmes mais n'a pas été traitée avec succès.
Les exemples de code suivants utilisent des méthodes implicites fournies à titre d'exemple. Vous devez fournir votre propre implémentation pour celles-ci ou les remplacer par une logique similaire :
-
def is_not_successful(*args, **kwargs) -> bool: """ Vérifiez si la transaction est réussie selon les propriétés de PaymentResponse status_output.status_category et status_output.status_code. """
-
def handle_error(*args, **kwargs) -> None: """ Traitez la transaction en fonction de son statut. """
Type d'exception / Code statut HTTP |
Exemple de code |
---|---|
Transactions rejetées / Divers(voir l'objet PaymentResponse) |
|
Remboursement rejeté / Divers(voir l'objet PaymentResponse) |
|
Exceptions HTTP
Ce type d'exception se réfère à divers problèmes causés par des erreurs techniques dans l'appel API ou la demande de paiement.
Vous pouvez combiner n'importe lequel des extraits de code suivants avec cette requête standard CreatePayment :
import logging as log
from onlinepayments.sdk.api_exception import ApiException
from onlinepayments.sdk.domain.create_payment_request import CreatePaymentRequest
""" Initialization... """
payment_dict = {
"order": {"amountOfMoney": {"currencyCode": "EUR", "amount": 125000}},
"cardPaymentMethodSpecificInput": {
"card": {
"cvv": "123",
"cardNumber": "5300000000000006",
"expiryDate": "0124",
"cardholderName": "John Doe"
},
"paymentProductId": 3
},
}
payment_request = CreatePaymentRequest()
payment_request.from_dictionary(payment_dict)
try:
payment_response = merchant_client.payments().create_payment(payment_request)
except ApiException as e:
# Refer to the list below to see how
# specific implementations of ApiException can be handled.
Type d'exception / Code statut HTTP |
Exemple de code |
---|---|
ValidationException / 400 |
|
AuthorizationException / 403 |
|
IdempotenceException / 409 |
|
ReferenceException / 404/409/410 |
|
PlatformException / 500/502/503 |
|
ApiException / Tout autre code |
|
CommunicationException / Codes 300 sans corps ou réponse non-JSON |
|
Codes réponse HTTP
Toutes nos exceptions sont liées à un ou plusieurs codes réponse HTTP, indiquant la cause principale de nombreuses erreurs possibles.
Code réponse | Description | Type d'exception |
---|---|---|
200 |
Success |
- |
201 |
Created |
- |
204 |
No content |
- |
Various CreatePaymentResult est présent dans la réponse |
Paiement rejeté |
DeclinedPaymentException |
Various |
Paiement rejeté |
DeclinedPayoutException |
Various |
Remboursement rejeté |
DeclinedRefundException |
400 |
Bad Request |
ValidationException |
403 |
Not Authorised |
AuthorizationException |
404 |
Not Found |
ReferenceException |
409 |
Conflict
|
IdempotenceException |
410 |
Gone |
ReferenceException |
500 |
Internal Server Error |
PlatformException |
502 | Bad Gateway Notre plateforme n'a pas pu traiter un message provenant d'un partenaire/acquéreur en aval |
PlatformException |
503 | Service Unavailable Le service que vous essayez d'atteindre est temporairement indisponible. Veuillez essayer à nouveau plus tard |
PlatformException |
Autre | Unexpected error Une erreur inattendue s'est produite |
ApiException |
Fonctionnalités supplémentaires
Le SDK a beaucoup plus à offrir. Jetez un œil aux fonctionnalités suivantes, car elles vous aideront à construire la solution parfaite.
- Obtenez les méthodes de paiement disponibles
- Envoyez des demandes idempotentes
- Utilisez la Logging
- Mise en commun des connexions
- Personnalisez la communication
- Webhooks
Obtenez les méthodes de paiement disponibles
Avant d'initier le processus de paiement réel, vous envoyez une requête GetPaymentProducts à notre plateforme. La réponse contient une liste des méthodes de paiement disponibles dans votre PSPID. En fonction des préférences de vos clients, vous pouvez offrir une sélection sur notre Hosted Checkout Page ou dans votre propre environnement de boutique en ligne en utilisant des demandes CreatePayment ultérieures.
from onlinepayments.sdk.merchant.products.get_payment_products_params import GetPaymentProductsParams
""" Initialization... """
product_params = GetPaymentProductsParams()
product_params.country_code = "FR"
product_params.currency_code = "EUR"
response = merchant_client.products().get_payment_products(product_params)
Réponse est une instance de GetPaymentsProductsResponse avec une liste des moyens de paiement disponibles.
Envoyez des demandes idempotentes
Une des principales fonctionnalités de l'API REST est sa capacité à détecter et prévenir l'envoi accidentel de requêtes (comme les demandes de paiement) en double. Le SDK vous simplifie la tâche pour vous assurer que vous envoyez uniquement des requêtes uniques – idempotentes – à notre plateforme.
Utilisez l'argument supplémentaire context et définissez sa propriété nommée idempotence_key pour une requête CreatePayment. Le SDK enverra un en-tête X-GCS-Idempotence-Key avec la clé d'idempotence comme valeur.
Si vous envoyez des demandes de cette manière à notre plateforme, nous vérifierons les éléments suivants :
- Si vous envoyez une requête ultérieure avec la même clé d'idempotence, la réponse contient un en-tête X-GCS-Idempotence-Request-Timestamp. Le SDK définira la propriété idempotence_request_timestamp de l'argument CallContext.
- Si la première requête n'est pas encore terminée, l'API RESTful Server renvoie un code de statut 409. Ensuite, le SDK déclenche une IdempotenceException avec la clé d'idempotence originale et le horodatage de la requête d'idempotence.
from onlinepayments.sdk.call_context import CallContext
from onlinepayments.sdk.idempotence_exception import IdempotenceException
""" Initialization... """
context = CallContext(idempotence_key="your_key_for_payment")
payment_client = merchant_client.payments()
try:
payment_request = CreatePaymentRequest()
# fill create payment request
payment_response = payment_client.create_payment(payment_request, context)
except IdempotenceException as e:
# a request with the same idempotence_key is still in progress, try again after a short pause
# e.idempotence_request_timestamp contains the value of the
# X-GCS-Idempotence-Request-Timestamp header
log.info(f"Idempotent request: {e.idempotence_request_timestamp}")
finally:
idempotence_timestamp = context.idempotence_request_timestamp
# idempotence_request_timestamp contains the value of the
# X-GCS-Idempotence-Request-Timestamp header
# if idempotence_timestamp is not empty, this was not the first request
Si une clé d'idempotence est envoyée pour un appel qui ne prend pas en charge l'idempotence, l'API RESTful Server ignorera la clé et traitera la demande comme une première demande.
Utiliser la Logging
Le SDK prend en charge la Logging des requêtes, des réponses et des exceptions de la communication avec l'API. Cela peut être utile pour le dépannage ou le suivi des étapes individuelles dans le flux de paiement.
Pour utiliser cette fonctionnalité de journalisation, vous devez implémenter la classe CommunicatorLogger. Le SDK Python propose une implémentation basée sur la méthode print (SysOutCommunicatorLogger), et une implémentation basée sur le Logger Python (PythonCommunicatorLogger).
Consultez un exemple de code présentant le cas de l'ajout d'un logger :
from onlinepayments.sdk.log.sys_out_communicator_logger import SysOutCommunicatorLogger
""" Initialisation... """
log_interface = SysOutCommunicatorLogger()
client.enable_logging(log_interface)
# Effectuer quelques appels ...
client.disable_logging()
Le SDK obscurcit les données sensibles dans le journal.
Mise en commun des connexions
Vous pouvez gérer vos ressources réseau en limitant le nombre de connexions possibles que le SDK crée et maintient. Les instances de Client créées comme discuté dans le chapitre initialisation du SDK auront leur propre pool de connexions. Les instances de Client créées avec le même objet Communicator partagent un pool de connexions.
Si vous utilisez plusieurs instances de Client pour partager un seul pool de connexions, assurez-vous de suivre ces étapes :
- Créez un Communicator partagé. Vous pouvez utiliser la classe Factory.
- Créez des instances Client avec ce Communicator.
from onlinepayments.sdk.factory import Factory
# Créer un communicateur partagé.
communicator = Factory.create_communicator_from_file(
"payments_sdk.prp", apiKey, apiSecret
)
# Créer un ou plusieurs clients utilisant le communicateur partagé.
client = Factory.create_client_from_communicator(communicator)
Personnaliser la communication
Un Client utilise un Communicator pour communiquer avec notre plateforme. Les implémentations de Communicator transforment un objet de requête en une requête HTTP et une réponse HTTP en un objet de réponse. Si nécessaire, vous pouvez étendre cette classe. Pour instancier un Client qui utilise votre propre implémentation de Communicator, vous pouvez utiliser l'extrait de code suivant :
from onlinepayments.sdk.factory import Factory
communicator = YourCommunicator()
client = Factory.create_client_from_communicator(communicator)
Cependant, pour la plupart des personnalisations, vous n'avez pas besoin d'étendre Communicator. La fonctionnalité de Communicator est construite sur les classes suivantes : Authenticator, Connection, Marshaller et IMetadataProvider, dont l'implémentation peut facilement être étendue ou remplacée.
Marshaller est utilisé pour convertir et reconvertir les objets de requête et de réponse vers et depuis JSON. Nous ne recommandons pas de changer ce module. Les autres modules nécessaires pour communiquer avec la plateforme CAWL ecommerce sont les suivants :
- Connection pour une ou plusieurs connexions HTTP à notre serveur
- Authenticator pour signer vos requêtes
- IMetadataProvider pour construire l'en-tête avec les métadonnées de votre serveur
Pour votre commodité, les méthodes Factory.create_communicator_from_configuration et Factory.create_communicator_from_file peuvent prendre des arguments optionnels pour définir les modules Connection, Authenticator, Marshaller ou IMetadataProvider. Par exemple, l'extrait de code suivant vous permet d'utiliser votre propre implémentation de Communicator :
connection = YourConnection()
communicator = Factory.create_communicator_from_file(configuration_file_name,
api_key_id = "api_key_id",
secret_api_key = "secret_api_key",
connection = connection)
client = Factory.create_client_from_communicator(communicator)
Webhooks
La partie du SDK qui gère la prise en charge des webhooks est appelée le webhooks helper. Elle gère de manière transparente à la fois la validation des signatures par rapport aux corps des événements envoyés par le système de webhooks (y compris la recherche de la clé secrète pour les ID de clé - à ne pas confondre avec la API Key et le API Secret), et le dégroupage de ces corps en objets. Cela vous permet de vous concentrer sur l'essentiel, sans avoir à passer par toutes les informations supplémentaires et à extraire celles souhaitées par vous-même. Pour en savoir plus sur les webhooks, lisez notre guide dédié.
Fournir des clés secrètes
Configurez les "WebhooksKey" / "WebhooksKeySecret" et les API endpoints de vos webhooks serveur dans le Merchant Portal:
key_id = "webhooks_key"
secret_key = "webhooks_key_secret"
Utilisez InMemorySecretKeyStore pour stocker une clé secrète pour un ID de clé :
from onlinepayments.sdk.webhooks.in_memory_secret_key_store import InMemorySecretKeyStore
key_store = InMemorySecretKeyStore()
key_store.store_secret_key(key_id, secret_key)
Vous pouvez ajouter ou supprimer des clés en utilisant les fonctions suivantes :
- L'ID de clé pour retourner la clé secrète.
- Une fonction de rappel qui prend soit une erreur comme premier argument, soit la clé secrète pour l'ID de clé donné comme second argument (dans ce cas, le premier argument doit être nul).
Le SDK fournit une implémentation pour cette fonction : webhooks.inMemorySecretKeyStore.get_secret_key. Cela permettra de récupérer les clés secrètes à partir d'un magasin de clés en mémoire.
Vous pouvez ajouter ou supprimer des clés en utilisant les fonctions suivantes :
- key_store.get_secret_key(key_id) pour obtenir la clé secrète stockée pour un ID de clé.
- key_store.remove_secret_key(key_id) pour supprimer la clé secrète stockée pour un ID de clé.
- key_store.clear() pour supprimer toutes les clés secrètes stockées.
Si vous avez besoin de stockage plus avancé, par exemple pour une base de données ou un système de fichiers, nous vous recommandons de rédiger votre propre implémentation.
Initialiser le helper de webhooks
Incluez et initialisez le helper de webhooks comme suit :
from onlinepayments.sdk.webhooks.webhooks_helper import WebhooksHelper
helper = WebhooksHelper(DefaultMarshaller.instance(), key_store)
Utiliser le helper de webhook
Vous pouvez appeler un helper de webhook pour décomposer les événements entrants, ce qui vous permet de traiter les données dans votre application. Il prend les arguments suivants :
- Le corps en tant que bytes. Il devrait s'agir du corps brut tel que reçu du système de webhooks.
- Une liste d'objets contenant les en-têtes de la requête tels que reçus du système de webhooks. Chaque objet d'en-tête doit avoir les propriétés name et value.
try:
webhook_event = helper.unmarshal(body, headers)
except:
# Traiter une exception
# Traiter l'événement