Cost+Docs

C# / .NET

SDK officiel C#/.NET pour la passerelle de paiement Cost+

SDK officiel C#/.NET pour la passerelle de paiement Cost+. Simplifie le flux de redirection HPP (page de paiement hébergée), la signature de payload HMAC et la vérification des webhooks.

Fonctionnalités

  • Zéro dépendance — utilise uniquement System.Text.Json et System.Security.Cryptography intégrés
  • Cible .NET 8.0 avec les fonctionnalités C# 12 (records, file-scoped namespaces, pattern matching)
  • Types référence nullable activés partout
  • Génération de signature HMAC-SHA256 et vérification en temps constant
  • Mappage automatique snake_case/PascalCase entre l'API et le SDK
  • Analyse des webhooks + vérification des commandes via l'API
  • Surface API entièrement asynchrone

Prérequis

Installation

dotnet add package NoPayn

Ou en tant que référence de projet local :

dotnet add reference path/to/src/NoPayn/NoPayn.csproj

Démarrage rapide

1. Initialiser le client

using NoPayn;
using NoPayn.Models;

var nopayn = new NoPaynClient(new NoPaynConfig(
    ApiKey: "your-api-key",
    MerchantId: "your-project"
));

2. Créer un paiement et rediriger vers la HPP

var result = await nopayn.GeneratePaymentUrlAsync(new CreateOrderParams
{
    Amount = 1295,              // €12.95 in cents
    Currency = "EUR",
    MerchantOrderId = "ORDER-001",
    Description = "Premium Widget",
    ReturnUrl = "https://shop.example.com/success",
    FailureUrl = "https://shop.example.com/failure",
    WebhookUrl = "https://shop.example.com/webhook",
    Locale = "en-GB",
    ExpirationPeriod = "PT30M",
});

// Redirect the customer
// result.OrderUrl   → HPP (customer picks payment method)
// result.PaymentUrl → direct link to the first transaction's payment method
// result.Signature  → HMAC-SHA256 for verification
// result.OrderId    → NoPayn order UUID

3. Gérer le webhook

app.MapPost("/webhook", async (HttpContext ctx) =>
{
    using var reader = new StreamReader(ctx.Request.Body);
    var rawBody = await reader.ReadToEndAsync();
    var verified = await nopayn.VerifyWebhookAsync(rawBody);

    Console.WriteLine(verified.Order.Status); // "completed", "cancelled", etc.
    Console.WriteLine(verified.IsFinal);      // true when the order won't change

    if (verified.Order.Status == "completed")
    {
        // Fulfil the order
    }

    return Results.Ok();
});

Référence API

new NoPaynClient(config, httpClient?)

ParamètreTypeObligatoirePar défaut
ApiKeystringOui
MerchantIdstringOui
BaseUrlstringNonhttps://api.nopayn.co.uk

Un HttpClient optionnel peut être passé en second paramètre du constructeur pour une gestion HTTP personnalisée ou des tests.

client.CreateOrderAsync(params): Task<Order>

Crée une commande via POST /v1/orders/.

ParamètreTypeObligatoireDescription
AmountintOuiMontant dans la plus petite unité monétaire (centimes)
CurrencystringOuiCode ISO 4217 (EUR, GBP, USD, NOK, SEK)
MerchantOrderIdstring?NonVotre référence interne de commande
Descriptionstring?NonDescription de la commande
ReturnUrlstring?NonRedirection après paiement réussi
FailureUrlstring?NonRedirection en cas d'annulation/expiration/erreur
WebhookUrlstring?NonNotifications asynchrones de changement de statut
Localestring?NonLangue de la HPP (en-GB, de-DE, nl-NL, etc.)
PaymentMethodsIReadOnlyList<string>?NonFiltrer les méthodes HPP
ExpirationPeriodstring?NonDurée ISO 8601 (PT30M)

Méthodes de paiement disponibles : credit-card, apple-pay, google-pay, vipps-mobilepay

client.GetOrderAsync(orderId): Task<Order>

Récupère les détails de la commande via GET /v1/orders/{id}/.

client.CreateRefundAsync(orderId, amount, description?): Task<Refund>

Effectue un remboursement total ou partiel via POST /v1/orders/{id}/refunds/.

client.GeneratePaymentUrlAsync(params): Task<PaymentUrlResult>

Méthode utilitaire qui crée une commande et renvoie :

public record PaymentUrlResult(
    string OrderId,        // NoPayn order UUID
    string OrderUrl,       // HPP URL
    string? PaymentUrl,    // Direct payment URL (first transaction)
    string Signature,      // HMAC-SHA256 of amount:currency:orderId
    Order Order            // Full order object
);

client.GenerateSignature(amount, currency, orderId): string

Génère une signature HMAC-SHA256 hexadécimale.

client.VerifySignature(amount, currency, orderId, signature): bool

Vérification en temps constant d'une signature HMAC-SHA256.

client.VerifyWebhookAsync(rawBody): Task<VerifiedWebhook>

Analyse le corps du webhook, puis appelle GET /v1/orders/{id}/ pour vérifier le statut réel.

Utilitaires HMAC autonomes

using NoPayn;

var sig = NoPaynSignature.Generate("your-api-key", 1295, "EUR", "order-uuid");
var ok  = NoPaynSignature.Verify("your-api-key", 1295, "EUR", "order-uuid", sig);

Gestion des erreurs

using NoPayn.Exceptions;

try
{
    await nopayn.CreateOrderAsync(new CreateOrderParams { Amount = 100, Currency = "EUR" });
}
catch (ApiException ex)
{
    Console.Error.WriteLine(ex.StatusCode);  // 401, 400, etc.
    Console.Error.WriteLine(ex.ErrorBody);   // Raw API error response
}
catch (NoPaynException ex)
{
    Console.Error.WriteLine(ex.Message);     // Network or parsing error
}
ExceptionDescription
NoPaynExceptionException de base (réseau, parsing)
ApiExceptionErreur HTTP de l'API
WebhookExceptionPayload de webhook invalide

Statuts des commandes

StatutFinal ?Description
newNonCommande créée
processingNonPaiement en cours
completedOuiPaiement réussi — livrez les marchandises
cancelledOuiPaiement annulé par le client
expiredOuiLe lien de paiement a expiré
errorOuiErreur technique

Bonnes pratiques pour les webhooks

  1. Vérifiez toujours via l'API — le payload du webhook contient uniquement l'identifiant de la commande, jamais le statut. Le VerifyWebhookAsync() du SDK le fait automatiquement.
  2. Renvoyez HTTP 200 pour accuser réception. Tout autre code déclenche jusqu'à 10 tentatives (espacées de 2 minutes).
  3. Implémentez un polling de secours — pour les commandes de plus de 10 minutes qui n'ont pas atteint un statut final, interrogez GetOrderAsync() comme filet de sécurité.
  4. Soyez idempotent — vous pouvez recevoir le même webhook plusieurs fois.

Cartes de test

Utilisez ces cartes en mode test Cost+ (site web sandbox) :

CarteNuméroNotes
Visa (succès)4111 1111 1111 1111N'importe quel CVV
Mastercard (succès)5544 3300 0003 7N'importe quel CVV
Visa (refusée)4111 1111 1111 1105Do Not Honor
Visa (fonds insuffisants)4111 1111 1111 1151Insufficient Funds

Utilisez n'importe quelle date d'expiration future et n'importe quel CVC à 3 chiffres.

Application de démonstration

Une application de démonstration ASP.NET Core basée sur Docker est incluse dans le dépôt GitHub pour tester le flux de paiement complet.

Support

Besoin d'aide ? Contactez notre équipe de support à support@costplus.io.

On this page