PayNL.RequestSigning 3.0.0

dotnet add package PayNL.RequestSigning --version 3.0.0                
NuGet\Install-Package PayNL.RequestSigning -Version 3.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PayNL.RequestSigning" Version="3.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add PayNL.RequestSigning --version 3.0.0                
#r "nuget: PayNL.RequestSigning, 3.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install PayNL.RequestSigning as a Cake Addin
#addin nuget:?package=PayNL.RequestSigning&version=3.0.0

// Install PayNL.RequestSigning as a Cake Tool
#tool nuget:?package=PayNL.RequestSigning&version=3.0.0                

Request Signing

This package adds functionality to sign & verify requests sent by the Pay. platform.



Installation

Simply download and restore nuget packages https://www.nuget.org/packages/PayNL.RequestSigning or install it from package manager

PM> Install-Package PayNL.RequestSigning

Usage

The RequestSigningService simplifies both signing and verifying requests, avoiding the need for manual class instantiation.

The constructor function of this service requires an array of SingingMethods that you wish to support. Each signing method has different needs and functionality, and which one(s) you opt to support falls under your discretion.

By providing the service with the array of these chosen methods, the service can handle the configuration and functionality. This decouples the setup process from your main application logic, allowing a more streamlined integration.

Verifying

The below code snippet shows the basis of verifying a request using this package:

public class ExampleController : ControllerBase
{
    [HttpPost]
    public async Task<string> ExampleControllerAction()
    {
        var signingService = new RequestSigningService(new List<IRequestSigningMethod>()
        {
            new HmacSignature(new SignatureKeyRepository()),
        });

        // Extracts callback data from request and verifies that it came from PAY
        var callBackContent = await signingService.VerifyAndDeserializeAsync(HttpContext.Request);
        
        // Do something with the callback data, method above throws if signature is invalid, so we can trust the data
        if (callBackContent.Type == "order")
        {
            var internalOrder = orderService.GetOrder(callBackContent.Object.OrderId);

            var newStatus = callBackContent.Object.Status;
            
            if (internalOrder.Status != newStatus)
            {
                internalOrder.Status = newStatus;
                orderService.UpdateOrder(internalOrder);
            }
        }
        
        return "TRUE";
    }
}

/// <summary>
///   A repository for finding signature keys by their ID. This is a simple in-memory implementation for demonstration purposes.
///   You can replace this with a database lookup or some other method of storing keys.
/// </summary>
public class SignatureKeyRepository : IHmacSignatureKeyRepository
{
    private readonly Dictionary<string, SignatureKey> _db = new()
    {
        { "AT-xxxx-1234", new SignatureKey() { Id = "AT-xxxx-1234", Secret = "faa4ce871adsfa463cd39166e4b265fc92b" } },
        { "SL-xxxx-1234", new SignatureKey() { Id = "SL-xxxx-1234", Secret = "69615asdfasz9839fe58e644asd8a853e9cb00" } }
    };
    
    public SignatureKey FindOneById(string keyId)
    {
        if (_db.TryGetValue(keyId, out var val)) { return val; }
        throw new KeyNotFoundException(keyId);
    }
    
    public bool TryFindOneById(string keyId, out SignatureKey key)
    {
        if (_db.TryGetValue(keyId, out var val))
        {
            key = val;
            return true;
        }

        key = null!;
        return false;
    }
}

Example

To view a local example run the project under PayNL.RequestSigning.TestServer and wait for it to start. Once it is running, run the console application under PayNL.RequestSigning.Sdk.Example and see the client sign its request, send it to the test server which signs it again and verifies its signature.

Demo

Start the demo app under PayNL.RequestSigning.Demo to view a simple example to illustrate the behaviour of the SDK, written in Blazor WASM.

This is a minimal example of how to incorporate this SDK into your project.

Exception handling

The request signing service and the underlying signing / verifying methods may throw exceptions when unexpected values are encountered, these are:

  • SignatureKeyNotFound, this exception must be thrown when the implementation of the ISignatureKeyRepository can not find the key based on the provided id;
  • UnknownSigningMethodException, this exception will be thrown by the singing / verifying methods when they are requested to sign / verify a request with an algorithm they do not support;
  • UnsupportedHashingAlgorithmException, this exception will be thrown by the RequestSigningService when it is requested to sign / verify a request with a method it doesn't support.
  • BodyDecodeException, this exception will be thrown if the body of the HttpMessage passed to the 'VerifyAndDecodeAsync' method is not in the expected format, if request is not GET.
  • QueryUrlDecodeException, this exception will be thrown if the query string of the HttpMessage passed to the 'VerifyAndDecodeAsync' method is not in the expected format, if request is GET.
  • InvalidSignatureException, this exception will be thrown if the process succeedes, but the resulting signature does not match the one provided by the request.

Supported Signing / Verifying methods

HMAC

The HmacSignature class enables the signing and verification of requests made with HMAC signatures. To utilize this class's method, a single argument is required for its constructor. This argument is of type IHmacSignatureKeyRepository.

Supported platforms

This library is built using .NET standard 2.0. This means that the package supports the following .NET implementations: | .NET implementation | Version support | | ------------- | ------------- | | .NET and .NET Core | 2.0, 2.1, 2.2, 3.0, 3.1, 5.0, 6.0, 7.0, 8.0 | | .NET Framework | 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 | | Mono | 5.4, 6.4 | | Universal Windows Platform | 10.0.16299, TBD | | Xamarin.iOS | 10.14, 12.16 | | Xamarin.Mac | 3.8, 5.16 | | Xamarin.Android | 8.0, 10.0 |

Source: https://docs.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.0 121 4/12/2024
2.1.0 126 4/10/2024
2.0.0 111 4/9/2024
1.1.0.1 118 4/8/2024
1.1.0 10,949 3/25/2024
1.0.0 4,634 1/4/2024

Added V3.0 support