From 646d213d6138db2aa1a6465b676a5ea5b707eaf8 Mon Sep 17 00:00:00 2001 From: wallee-deployment-user Date: Mon, 22 Jan 2024 16:32:20 +0100 Subject: [PATCH] Release 7.0.3 --- LICENSE | 2 +- README.md | 50 +++++++++++++++++-- src/PostFinanceCheckout/Client/ApiClient.cs | 2 +- .../Client/Configuration.cs | 8 +-- .../PostFinanceCheckout.csproj | 6 +-- .../Service/WebhookEncryptionService.cs | 18 +++++-- .../Util/EncryptionUtil.cs | 2 +- 7 files changed, 69 insertions(+), 19 deletions(-) diff --git a/LICENSE b/LICENSE index 9debc6c..ac38c25 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2023 wallee AG + Copyright 2024 wallee AG Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 8c38d99..f7d5adf 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,13 @@ Install-Package BouncyCastle.Cryptography ## Installation ``` # Package Manager -Install-Package PostFinanceCheckout -Version 7.0.2 +Install-Package PostFinanceCheckout -Version 7.0.3 # .NET CLI -dotnet add package PostFinanceCheckout --version 7.0.2 +dotnet add package PostFinanceCheckout --version 7.0.3 # Paket CLI -paket add PostFinanceCheckout --version 7.0.2 +paket add PostFinanceCheckout --version 7.0.3 # PackageReference - + ``` Then include the DLL (under the `bin` folder) in the C# project, and use the namespaces: @@ -178,6 +178,48 @@ namespace PostFinanceCheckout.Test } } ``` +### Integrating Webhook Payload Signing Mechanism into webhook callback handler + +The HTTP request which is sent for a state change of an entity now includes an additional field `state`, which provides information about the update of the monitored entity's state. This enhancement is a result of the implementation of our webhook encryption mechanism. + +Payload field `state` provides direct information about the state update of the entity, making additional API calls to retrieve the entity state redundant. + +#### ⚠️ Warning: Generic Pseudocode + +> **The provided pseudocode is intentionally generic and serves to illustrate the process of enhancing your API to leverage webhook payload signing. It is not a complete implementation.** +> +> Please ensure that you adapt and extend this code to meet the specific needs of your application, including appropriate security measures and error handling. +For a detailed webhook payload signing mechanism understanding we highly recommend referring to our comprehensive +[Webhook Payload Signing Documentation](https://checkout.postfinance.ch/doc/webhooks#_webhook_payload_signing_mechanism). + +```csharp +... + [HttpPost("callback")] + public IActionResult HandleWebhook([FromBody] string requestPayload) + { + var signature = Request.Headers["x-signature"]; + + if (string.IsNullOrEmpty(signature)) + { + // Make additional API call to retrieve the entity state + // ... + } + else + { + if (webhookEncryptionService().isContentValid(signature, requestPayload)) + { + // Parse requestPayload to extract 'state' value + // Process entity's state change + // ... + } + } + + // Process the received webhook data + // ... + } +... +``` + ## License diff --git a/src/PostFinanceCheckout/Client/ApiClient.cs b/src/PostFinanceCheckout/Client/ApiClient.cs index ea4486e..9c5c08a 100644 --- a/src/PostFinanceCheckout/Client/ApiClient.cs +++ b/src/PostFinanceCheckout/Client/ApiClient.cs @@ -153,7 +153,7 @@ public Object CallApi( { Dictionary defaultHeaderParams = new Dictionary() { - {"x-meta-sdk-version", "7.0.2"}, + {"x-meta-sdk-version", "7.0.3"}, {"x-meta-sdk-language", "csharp"}, {"x-meta-sdk-provider", "PostFinance Checkout"}, {"x-meta-sdk-language-version", Environment.Version.ToString()} diff --git a/src/PostFinanceCheckout/Client/Configuration.cs b/src/PostFinanceCheckout/Client/Configuration.cs index 38a396b..ac0281c 100644 --- a/src/PostFinanceCheckout/Client/Configuration.cs +++ b/src/PostFinanceCheckout/Client/Configuration.cs @@ -21,7 +21,7 @@ public class Configuration : IReadableConfiguration /// Version of the package. /// /// Version of the package. - public const string Version = "7.0.2"; + public const string Version = "7.0.3"; /// /// Identifier for ISO 8601 DateTime Format @@ -94,7 +94,7 @@ public Configuration(string applicationUserID, string authenticationKey, RestCli _authenticationKey = authenticationKey; _applicationUserID = applicationUserID; _restClientOptions = restClientOptions; - UserAgent = "PostFinanceCheckout/7.0.2/csharp"; + UserAgent = "PostFinanceCheckout/7.0.3/csharp"; BasePath = "https://checkout.postfinance.ch:443/api"; DefaultHeader = new ConcurrentDictionary(); ApiKey = new ConcurrentDictionary(); @@ -355,8 +355,8 @@ public static String ToDebugReport() String report = "C# SDK (PostFinanceCheckout) Debug Report:\n"; report += " OS: " + System.Environment.OSVersion + "\n"; report += " .NET Framework Version: " + System.Environment.Version + "\n"; - report += " Version of the API: 7.0.2\n"; - report += " SDK Package Version: 7.0.2\n"; + report += " Version of the API: 7.0.3\n"; + report += " SDK Package Version: 7.0.3\n"; return report; } diff --git a/src/PostFinanceCheckout/PostFinanceCheckout.csproj b/src/PostFinanceCheckout/PostFinanceCheckout.csproj index e166f5a..ff51150 100644 --- a/src/PostFinanceCheckout/PostFinanceCheckout.csproj +++ b/src/PostFinanceCheckout/PostFinanceCheckout.csproj @@ -20,12 +20,12 @@ PostFinanceCheckout https://www.apache.org/licenses/LICENSE-2.0.txt https://github.com/pfpayments/csharp-sdk - 7.0.2 - 7.0.2 + 7.0.3 + 7.0.3 PostFinanceCheckout;payment;sdk;Payment Integration Library customweb - 7.0.2 + 7.0.3 git https://github.com/pfpayments/csharp-sdk.git PostFinanceCheckout diff --git a/src/PostFinanceCheckout/Service/WebhookEncryptionService.cs b/src/PostFinanceCheckout/Service/WebhookEncryptionService.cs index f9d47cb..f4227b4 100644 --- a/src/PostFinanceCheckout/Service/WebhookEncryptionService.cs +++ b/src/PostFinanceCheckout/Service/WebhookEncryptionService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -41,7 +42,7 @@ public interface IWebhookEncryptionService : IApiAccessor /// /// Verify content of a webhook. /// - /// Thrown when when private key can not be found + /// Thrown when when private key can not be found /// The content of the X-Signature header. /// The content body. /// true if the content body conforms with the signature header @@ -56,6 +57,9 @@ public interface IWebhookEncryptionService : IApiAccessor /// public partial class WebhookEncryptionService : IWebhookEncryptionService { + private static readonly ConcurrentDictionary cache = + new ConcurrentDictionary(); + private PostFinanceCheckout.Client.ExceptionFactory _exceptionFactory = (name, response) => null; /// @@ -172,7 +176,7 @@ public ApiResponse< WebhookEncryptionPublicKey > ReadWithHttpInfo (string id) /// /// Verify content of a webhook. /// - /// Thrown when when private key can not be found + /// Thrown when when private key can not be found /// The content of the X-Signature header. /// The content body. /// true if the content body conforms with the signature header @@ -187,10 +191,14 @@ public bool IsContentValid(string signatureHeader, string content) string publicKeyId = matcher.Groups[2].Value; string contentSignature = matcher.Groups[3].Value; - WebhookEncryptionPublicKey publicKey = Read(publicKeyId); - if (publicKey == null) + if (!cache.TryGetValue(publicKeyId, out WebhookEncryptionPublicKey publicKey)) { - throw new ApiException(404, "WebhookEncryptionKey not found"); + publicKey = Read(publicKeyId); + if (publicKey == null) + { + throw new ApiException(404, "WebhookEncryptionKey not found"); + } + cache.TryAdd(publicKey.Id, publicKey); } return EncryptionUtil.IsContentValid(content, contentSignature, publicKey, signatureAlgorithm); diff --git a/src/PostFinanceCheckout/Util/EncryptionUtil.cs b/src/PostFinanceCheckout/Util/EncryptionUtil.cs index 6797f8b..c0c3406 100644 --- a/src/PostFinanceCheckout/Util/EncryptionUtil.cs +++ b/src/PostFinanceCheckout/Util/EncryptionUtil.cs @@ -16,7 +16,7 @@ public static class EncryptionUtil /// /// IsContentValid Validate the content using the signature and public key. /// - /// Thrown when fails to make API call + /// Thrown when fails to make API call /// Content to verify. /// Base64 encoded signature of the content. /// The public key (WebhookEncryptionPublicKey)