SDK Ruby
Ciblez l'URL de base de l'API la plus à jour
Nous vous encourageons à toujours cibler l'URL de base de l'API la plus à jour lors de l'envoi de requêtes à notre plateforme. Consultez notre guide dédié pour un aperçu complet.
Pour vous permettre une transition en douceur, les anciennes URL de base de l'API restent disponibles jusqu'à nouvel ordre.
Pour initier des paiements, vous devez connecter votre serveur à notre plateforme via l'une de nos modes d'intégration.
Notre bibliothèque SDK Ruby est la solution idéale pour se connecter à notre plateforme si vous préférez le faire avec votre propre système en utilisant le langage Ruby.
En choisissant le SDK Ruby, vous pouvez :
- Accéder à toutes les fonctionnalités de notre API RESTful de manière concise, pratique et personnalisable.
- Utiliser l'ensemble des modes d'intégration côté serveur de notre plateforme (Hosted Checkout Page / Hosted Tokenization Page / Server-to-server).
- Effectuer l'ensemble des appels API liés au traitement des paiements (comme CreateHostedCheckout, CreatePayment, RefundPayment et bien d'autres).
Pour tirer pleinement parti de ce SDK, assurez-vous de répondre à ces exigences :
- Ruby 2.7 ou supérieur
Installez la version la plus récente du SDK Ruby via GEM package manager en exécutant :
gem install onlinepayments-sdk-ruby
Retrouvez plus de détails sur GitHub. Consultez également tous les objets et propriétés SDK disponibles dans notre référence complète de l'API. Une fois que tout est prêt, lisez les chapitres suivants pour savoir comment préparer et utiliser le SDK.
Ce guide fournit un aperçu général des fonctionnalités du SDK. Pour voir comment elles fonctionnent plus en détail pour les différentes modes d'intégration, consultez les guides dédiés décrivant 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 :
- La création d'un compte de test/production.
- La création d'un fichier de configuration avec certaines propriétés.
---
onlinePayments.api.integrator: integrator
onlinePayments.api.endpoint.host: apiEndpoint
# The following keys are optional and use the given value by default.
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 un API Key et un API Secret pour le PSPID que vous souhaitez utiliser pour traiter vos transactions.
- Initialiser une instance de Client / MerchantClient en utilisant le couple API Key / API Secret pour configurer la connexion à notre plateforme de recette/production.
require 'onlinepayments/sdk' include OnlinePayments::SDK client = Factory.create_client_from_file(configuration_file_name, api_key, api_secret) merchant_client = client.merchant(merchant_id)
Le tableau suivant fournit un aperçu des arguments acceptés par les différentes instances :
Propriétés |
---|
|
Après l'initialisation, vous pouvez envoyer des demandes d'opérations à 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.direct.worldline-solutions.com/v2/
- environnement de production: https://payment.direct.worldline-solutions.com/v2/
Si vous êtes prêt à passer à l'environnement de production, remplacez le lien du endpoint apiEndpoint = 'https://payment.preprod.direct.worldline-solutions.com/' par le lien de l'environnement de production apiEndpoint = 'https://payment.direct.worldline-solutions.com/'
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.
Utilisation du 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 l'une 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 la méthode de paiement que vous souhaitez utiliser est activée dans votre compte de test/production. Vérifiez cela dans le Merchant Portal via Entreprise > Moyens de paiement.
Vous utilisez le Back Office ?
Vous pouvez vérifier le statut d'activation de la méthode de paiement via Configuration > Activation PM.
Consultez nos exemples de code sur GitHub et notre explorateur d'API pour découvrir ce qui est possible.
Ci-dessous, vous trouverez certaines des actions les plus courantes que vous pouvez effectuer :
- Créer de nouvelles transactions
- Obtenir le statut d'une 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 de MerchantClient pour l'une de nos modes d'intégration afin de créer une nouvelle transaction. Cela peut être fait de la manière suivante :
- Routage de l'appel à votre PSPID sur notre plateforme (pour Client).
- Demande de création d'une transaction 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 Direct.
Les sessions et les paiements n'ont pas d'impact sur d'autres sessions et paiements.
Ci-dessous, vous pouvez trouver des exemples de code relatifs à 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 ...
include OnlinePayments::SDK::Domain
order_hash = {
"order" => { "amountOfMoney" => { "currencyCode" => "EUR", "amount" => 123 } }
}
hosted_checkout_client = merchant_client.hosted_checkout
hosted_checkout = CreateHostedCheckoutRequest.new
hosted_checkout.from_hash(order_hash)
response = hosted_checkout_client.create_hosted_checkout(hosted_checkout)
Vous pouvez spécifier une return_url optionnelle, qui sera utilisée pour rediriger votre client vers votre site web.
La version la plus récente de notre SDK renvoie également l'URL complète dans le champ redirect_url, vous permettant d'éviter de concaténer l'URL de base "https://payment." avec partial_redirect_url. En savoir plus dans notre guide sur Hosted Checkout Page.
Hosted Tokenization Page
Pour utiliser cette méthode d'intégration, vous devez :
- Créer et télécharger un template comme décrit dans notre guide Hosted Tokenization Page. Il doit contenir au moins un objet Order.
# Initialisation ...
include OnlinePayments::SDK::Domain
request = CreateHostedTokenizationRequest.new()
request.from_hash({"variant" => "template.html"})
hosted_t_client = merchant_client.hosted_tokenization()
response = hosted_t_client.create_hosted_tokenization(request)
À partir de la response, récupérez hosted_tokenization_id et partial_redirect_url :
t_id = response.hosted_tokenization_id
url = response.partial_redirect_url
Utilisez la partial_redirect_url pour l'iframe et le hosted_tokenization_id ou token_id (voir ci-dessous) pour créer la tranasction via la méthode d'intégration Server-to-server.
Vous pouvez envoyer soit un tokenID soit un hosted_tokenizationId dans votre requête CreatePayment. Apprenez-en davantage sur l'utilisation de chaque option dans les chapitres dédiés de notre guide Hosted Tokenization Page :
"token = hosted_t_client.get_hosted_tokenization(t_id).token.id
# Hash with all needed data for payment request
payment_hash = {
"order => {
"amountOfMoney" => {
"currencyCode" => "EUR",
"amount" => 12300 } },
"CardPaymentMethodSpecificInput" => {
"token" => token } }
payment_request = CreatePaymentRequest.new_from_hash(payment_hash)
payment_response = merchant_client.payments.create_payment(payment_request)"
Vous pouvez également transmettre un tokenID à la place du hostedTokenizationId dans votre requête CreatePayment. Apprenez-en davantage sur l'utilisation de chaque option dans les chapitres dédiés de notre guide Hosted Tokenization Page :
Server-to-server
Une réponse minimale CreatePaymentRequest nécessite de définir au moins un objet Order et une méthode de paiement :
# Initialisation ...
include OnlinePayments::SDK::Domain
# Hash with all needed data for payment request
payment_hash = {
"order" => {"amountOfMoney" => {"currencyCode" => "EUR", "amount" => 125000}},
"cardPaymentMethodSpecificInput" => {
"card" => {
"cvv" => "123",
"cardNumber" => "5300000000000006",
"expiryDate" => "0124",
"cardholderName" => "John Doe"},
"paymentProductId" => 3}}
payment_request = CreatePaymentRequest.new_from_hash(payment_hash)
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 ci-dessus :
Les documents contiennent tous les détails cruciaux dont vous avez besoin pour tirer pleinement parti des modes d'intégration, incluant des cinématiques de paiement complètes, 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 via l'une de nos requêtes 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 de 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 correspondante.
Effectuer une opération de maintenance
Pour effectuer des opérations sur des transactions existantes (comme des captures ou des remboursements), utilisez respectivement notre appel API CapturePayment ou RefundPayment :
CapturePayment
# Initialisation ...
include OnlinePayments::SDK::Domain
payment_id = payment_response.payment.id
capture_request = CapturePaymentRequest.new
capture_request.from_hash({"amount" => 125000, "isFinal" => true})
merchant_client.payments.capture_payment(payment_id, capture_request)
RefundPayment
# Initialisation ...
include OnlinePayments::SDK::Domain
payment_id = payment_response.payment.id
refund_hash = { "amountOfMoney" => { "currencyCode" => "EUR", "amount" => 125000 } }
refund_request = RefundRequest.new_from_hash(refund_hash)
# Get RefundResponse object
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 à partir de hosted_checkout_client.create_hosted_checkout() ou merchant_client.payments().create_payment(payment_request) créé 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 HTTP status associé vous aide également à résoudre l'erreur.
Vous pouvez rencontrer deux types d'exceptions : exceptions de transaction et exceptions HTTP.
Exceptions de transaction
Ce type d'exception se réfère à des demandes de transaction qui sont techniquement correctes mais qui ont été rejetées par l'établissement é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 êtes censé fournir votre propre implémentation pour celles-ci ou les remplacer par une logique similaire :
-
def is_not_successful(*args, **kwargs) # Check if the transaction is successful # according to PaymentResponse properties # status_output.status_category and status_output.status_code. end
-
def handle_error(*args, **kwargs) # Process the transaction according to its status. end
Type d'exception / code réponse HTTP |
Extrait de code |
---|---|
Transaction rejetée / Divers (voir objet PaymentResponse) |
|
Remboursement refusé / Divers (voir objet PaymentResponse) |
|
Exceptions HTTP
Ce type d'exception se réfère à divers problèmes pouvant être 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 :
# Initialisation ...
include OnlinePayments::SDK::Domain
log = Logger.new(STDOUT)
# Hash with all needed data for payment request
payment_hash = {
"order" => {"amountOfMoney" => {"currencyCode" => "EUR", "amount" => 124000}},
"cardPaymentMethodSpecificInput" => {
"card" => {
"cvv" => "123",
"cardNumber" => "5300000000000006",
"expiryDate" => "0124",
"cardholderName" => "Ruby Ruby"},
"paymentProductId" => 3}}
payment_request = CreatePaymentRequest.new_from_hash(payment_hash)
begin
payment_response = merchant_client.payments().create_payment(payment_request)
rescue ApiException => e
# Refer to the list below to see how
# specific implementations of ApiException can be handled.
end
Type d'exception / Code réponse HTTP |
Extrait de code |
---|---|
ValidationException / 400 |
|
AuthorizationException / 403 |
|
IdempotenceException / 409 |
|
ReferenceException / 404/409/410 |
|
PlatformException / 500/502/503 |
|
ApiException / Autres codes |
|
CommunicationException / 300 sans body ou réponse non-JSON |
|
Code réponse HTTP
Toutes nos exceptions sont liées à un ou plusieurs codes réponse HTTP, indiquant la cause principale des erreurs possibles.
Code réponse | Description | Type d'exception |
---|---|---|
200 |
Success |
- |
201 |
Created |
- |
204 |
No content |
- |
Divers Le champ paymentResult est présent en réponse |
Paiement rejeté |
DeclinedPaymentException |
Divers Le champ payoutResult est présent en réponse |
Versement rejeté |
DeclinedPayoutException |
Divers |
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 réessayer plus tard |
PlatformException |
Other | 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.
- Obtenir les méthodes de paiement disponibles
- Envoyer des demandes idempotentes
- Utiliser le logging
- Gestion des pools de connexion
- Personnaliser la communication
- Webhooks
Obtenir les méthodes de paiement disponibles
Avant d'initier le processus de paiement, vous envoyez une requête GetPaymentProducts à notre plateforme. La réponse contient une liste de méthodes de paiement disponibles pour votre PSPID. Selon les préférences de vos clients, vous pouvez offrir une sélection sur notre Hosted Checkout Page ou sur l'environnement de votre propre boutique en ligne en utilisant des requêtes ultérieures CreatePayment.
# Initialisation...
include OnlinePayments::SDK::Merchant::Products
product_params = GetPaymentProductsParams.new
product_params.country_code = "FR"
product_params.currency_code = "EUR"
response = merchant_client.products.get_payment_products(product_params)
La réponse est une instance de GetPaymentsProductsResponse avec une liste de moyens de paiement disponibles.
Envoyer des demandes idempotentes
L'une des principales caractéristiques des API REST est sa capacité à détecter et à prévenir l'envoi accidentel de demandes en double. Le SDK vous facilite la tâche pour vous assurer que vous n'envoyez que des demandes uniques – idempotentes – à notre plateforme.
Utilisez l'argument supplémentaire context et définissez sa propriété nommée idempotence_key lors d'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 requêtes de cette manière à notre plateforme, nous vérifierons les éléments suivants :
- Si vous envoyez une requête suivante 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 du serveur RESTful retourne un code réponse 409. Ensuite, le SDK lance une IdempotenceException avec la clé d'idempotence originale et l'horodatage de la requête d'idempotence.
# Initialisation ...
context = CallContext.new(idempotence_key="your_key_for_payment")
payment_client = merchant_client.payments
begin
payment_response = payment_client.create_payment(payment_request, context)
rescue IdempotenceException => 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("Idempotent request: #{e.idempotence_request_timestamp}")
ensure
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
end
Si une clé d'idempotence est envoyée pour un appel qui ne supporte pas l'idempotence, l'API du serveur RESTful ignorera la clé et traitera la demande comme une demande initiale.
Utiliser le logging
Le SDK prend en charge le logging des requêtes, des réponses et des exceptions de la communication de l'API. Cela peut être utile pour le dépannage ou pour suivre les différentes étapes dans la cinématique de paiement.
Pour utiliser cette fonctionnalité de logging, vous devez implémenter la classe CommunicatorLogger. Le SDK Ruby fournit deux exemples d'implémentations pour le logging vers stdout (StdoutCommunicatorLogger) et le logging vers un logger (RubyCommunicatorLogger).
Jetez un œil à un exemple de code présentant le cas de l'ajout d'un logger :
# Initialisation...
logger = RubyCommunicatorLogger.new(Logger.new('logfile.log'), Logger::INFO)
client.enable_logging(logger)
# Do some calls ...
client.disable_logging()
Le SDK obfusque les données sensibles au sein des logs.
Gestion des pools de 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 Client créées comme évoqué dans le chapitre d'initialisation du SDK auront leur propre pool de connexions. Les instances 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 de Client avec ce Communicator.
require 'onlinepayments/sdk'
include OnlinePayments::SDK
# Create shared communicator.
communicator = Factory.create_communicator_from_file(
""payments_sdk.prp"", api_key, api_secret
)
# Create one or more clients using the shared communicator.
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 :
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é du Communicator est construite sur les classes suivantes : Authenticator, Connection, Marshaller et MetadataProvider, dont l'implémentation peut facilement être étendue ou remplacée.
Marshaller est utilisé pour sérialiser et désérialiser les objets de requête et de réponse vers et depuis JSON. Nous ne recommandons pas de modifier ce module. Les autres modules nécessaires pour communiquer avec la plateforme Direct sont les suivants :
- Connection pour une ou plusieurs connexions HTTP à notre serveur.
- Authenticator pour signer vos requêtes.
- MetadataProvider construisant l'entête avec les méta-donné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 MetadataProvider. Par exemple, l'extrait de code suivant vous permet d'utiliser votre propre implémentation de Communicator :
connection = YourConnection.new
communicator = Factory.create_communicator_from_file(configuration_file_name,
"api_key_id",
"secret_api_key",
connection: connection)
client = Factory.create_client_from_communicator(communicator)
Webhooks
La partie du SDK qui gère le support des webhooks s'appelle l'assistant webhooks. 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), ainsi que la désérialisation de ces corps en objets. Cela vous permet de vous concentrer sur l'essentiel, sans 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 le "WebhooksKey" / "WebhooksKeySecret" et vos points d'entrée 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é :
include OnlinePayments::SDK::Webhooks
key_store = InMemorySecretKeyStore.instance
key_store.store_secret_key(key_id, secret_key)
Vous pouvez ajouter ou supprimer des clés en utilisant les fonctions suivantes :
- L'identifiant de clé pour retourner la clé secrète correspondante
- Une fonction de rappel qui prend soit une erreur comme premier argument, soit la clé secrète pour l'identifiant de clé donné comme deuxième 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 identifiant de clé.
- key_store.remove_secret_key(key_id) pour supprimer la clé secrète stockée pour un identifiant de clé.
- key_store.clear() pour supprimer toutes les clés secrètes stockées.
Si vous avez besoin d'un stockage plus avancé, par exemple pour une base de données ou un système de fichiers, nous recommandons d'écrire votre propre implémentation.
Initialiser l'assistant webhooks
Incluez et initialisez l'assistant webhooks comme suit :
include OnlinePayments::SDK::Webhooks
include OnlinePayments::SDK::JSON
helper = WebhooksHelper.new(DefaultMarshaller.instance, InMemorySecretKeyStore.instance)
Utiliser l'assistant webhooks
Vous pouvez appeler un assistant webhooks pour désérialiser 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 chaîne de caractères. Il doit s'agir du corps brut tel que reçu par le système de webhooks.
- Une liste avec des objets contenant les en-têtes de requête tels que reçus par le système de webhooks. Chaque objet d'en-tête doit avoir des méthodes name et value qui retournent respectivement le nom et la valeur de l'en-tête.
begin
webhook_event = helper.unmarshal(body, headers)
rescue
# Process an exception
end
# Process event