From 9e727719f25cb5952f364f3a07fda4b1803ca105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Favre?= Date: Wed, 3 Jun 2026 13:30:09 +0200 Subject: [PATCH 1/2] docs: refresh READMEs and extract changelog --- CHANGELOG.md | 61 +++++++++++++ README.md | 70 ++++----------- SaferPay.Test/Program.cs | 2 +- SaferPay.Test/README.md | 189 +++++++++------------------------------ 4 files changed, 121 insertions(+), 201 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c91c1a5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,61 @@ +# Changelog + +All notable changes to SaferPay.NetCore are documented here. + +## v1.52.02 ++ Multi-targeted the library to `.NET 8.0` and `.NET 10.0` ++ Added the `SaferPay.Tests` xUnit project (unit + sandbox integration coverage) ++ Documented the `Transaction/QueryPaymentMeans` and `Transaction/AdjustAmount` methods + +## v1.52.01 ++ Updated library target framework to `.NET 8.0` ++ Removed unsupported `.NET 6.0` and legacy test runtime targets ++ Improved overall package compatibility with current and future .NET runtimes ++ Fixed recursive `Dispose()` implementation causing `StackOverflowException` ++ Fixed missing `_jsonSerializerSettings` initialization in the 4-argument constructor ++ Improved `RestClient` lifecycle management to prevent socket/resource leaks under load ++ Fixed exception rethrow handling to preserve original stack traces ++ Normalized `CreditCardExpiration` year handling across constructor, setters and parsing ++ Fixed `CreditCardExpiration.Parse()` producing invalid `MMYYYY` values instead of `MMYY` ++ Improved `CreditCardExpiration.ToString()` formatting consistency ++ Updated package metadata and NuGet packaging configuration ++ Improved GitHub Actions build, validation and NuGet publishing workflow ++ Updated package validation and build pipeline for `.NET 8` ++ General reliability, maintainability and runtime compatibility improvements + +## v1.52 ++ Updated to use the latest version of the JSON API, `v1.52` ++ Added `Saferpay Management API`. ++ Added `PaymentPage GetConfigurations` method to Saferpay Management API ++ Added `WITH_SUCCESSFUL_THREE_DS_CHALLENGE` as a valid value for the field Condition ++ Added `MastercardTLID` to the `IssuerReference` container in the response ++ removed `PayerId` from the `PayPal` container + +## v1.51 ++ Updated to use the latest version of the JSON API, `v1.51` ++ added `PAYPAL` as valid value for field Type in `Alias/Insert` ++ added `ONLINE_CHALLENGED` as valid value for field Type of container `Check` in `Alias/Insert` ++ removed `OK_AUTHENTICATED` as valid value from field `Result` of container `CheckResult`. ++ removed `INVOICE` as valid value from `PaymentMethods` in `PaymentPage/Initialize` ++ added fields `Authenticated` and `AuthenticationType` to container `AuthenticationResult`. Removed field `Result` from container in return. ++ added field `FundingSource` to container `Card` ++ field `CountryCode` in container `ForeignRetailer` is now mandatory. + +## v1.50 ++ Updated to use the latest version of the JSON API, `v1.50` ++ Added value `ONLINE_STRONG` to Type in the `Check` container and added new container `ExternalThreeDS` in `Alias/InsertDirect` ++ Added `GIFTCARD` as valid value for the field `PaymentMethods` ++ Introduced a new function to provide Dynamic Currency Conversion (`DCC`) inquiry details for your customer: `Transaction\DccInquiry` ++ The payment methods `GIROPAY`, `PAYDIREKT`, `SOFORT` and `WLCRYPTOPAYMENTS` are no longer supported. ++ `Transaction/AuthorizeDirect` is extended with the new subcontainer `DCC`, which references the response from `Transaction/DccInquiry` and payer's decision whether he accepts or declines `DCC` offer ++ Added `WERO` as valid value for the field `PaymentMethods` ++ Added `HolderName` and `IBAN` to the BankAccount container in `PaymentPage/Assert` ++ `Transaction/RefundDirect` is extended with the new subcontainer `BankAccount`. This is a required container for PostFinance Instant Payout + +## v1.46 ++ Updated to use the latest version of the JSON API, `v1.46` ++ Added new subcontainer `ExternalThreeDS` to container `Authentication`. This affects the following requests: `Transaction/AuthorizeDirect` ++ Updated `AuthorizeDirect` method to use the new `ExternalThreeDS` subcontainer. + +## v1.45.01 ++ Added `REKA` as alternative payment method to `PaymentPagePaymentMethods`. diff --git a/README.md b/README.md index 4bedeef..30766df 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SaferPay.NetCore Json Api V1.52 -This repository is an implementation of the [SaferPay.Net](https://github.com/bmbsqd/saferpay-net) library, with updates to use **.NetCore 8.0** and **RestSharp** instead of HttpClient. All methods have been extended with sync and async calls. +This repository is an implementation of the [SaferPay.Net](https://github.com/bmbsqd/saferpay-net) library, with updates to use **.NET 8.0 / .NET 10.0** and **RestSharp** instead of HttpClient. All methods have been extended with sync and async calls. The implementation is based on the latest version of the JSON API, **v1.52**, which can be found at the following URL: http://saferpay.github.io/jsonapi/#ChapterTransaction @@ -19,7 +19,7 @@ https://test.saferpay.com/BO/Login ``` ### What's New -+ Upgrade to `.NetCore 8.0` ++ Multi-targets `.NET 8.0` and `.NET 10.0` + HttpClient has been replaced by `RestSharp` + Updated to use the latest version of the JSON API, `v1.52` + Replaced `BaseUri` with `SandBox` mode. BaseUri is now generated based on SandBox mode for testing or live environments. @@ -36,7 +36,7 @@ https://test.saferpay.com/BO/Login Implemented all methods: + **Payment Page Methods:** `Initialize`, `Assert` -+ **Transaction Methods:** `Initialize`, `Authorize`, `AuthorizeDirect`, `AuthorizeReferenced`, `Capture`, `MultipartCapture`, `AssertCapture`, `MultipartFinalize`, `Refund`, `AssertRefund`, `RefundDirect`, `Cancel`, `RedirectPayment`, `AssertRedirectPayment`, `Inquire`, `AlternativePayment`, `QueryAlternativePayment`, `DccInquiry` ++ **Transaction Methods:** `Initialize`, `Authorize`, `QueryPaymentMeans`, `AdjustAmount`, `AuthorizeDirect`, `AuthorizeReferenced`, `Capture`, `MultipartCapture`, `AssertCapture`, `MultipartFinalize`, `Refund`, `AssertRefund`, `RefundDirect`, `Cancel`, `RedirectPayment`, `AssertRedirectPayment`, `Inquire`, `AlternativePayment`, `QueryAlternativePayment`, `DccInquiry` + **Secure Card Data:** `Insert`, `AssertInsert`, `InsertDirect`, `Update`, `Delete`, `Inquire` + **Batch:** `Close` + **Omni Channel:** `InsertAlias`, `AcquireTransaction` @@ -173,57 +173,17 @@ if (result != null && result.IsSuccess) } ``` +### Tests + +The solution ships with two projects under the repository root: + ++ **`SaferPay.Tests`** : automated xUnit suite (`Unit` + sandbox `Integration` tests). Run it with: + ```bash + dotnet test SaferPay.Tests/SaferPay.Tests.csproj + ``` + Integration tests run against `test.saferpay.com` using the public Viwo sandbox account by default. Override it with the `SAFERPAY_CUSTOMER_ID`, `SAFERPAY_TERMINAL_ID`, `SAFERPAY_USERNAME` and `SAFERPAY_PASSWORD` environment variables, or set `SAFERPAY_SKIP_INTEGRATION=1` for a fully offline run. ++ **`SaferPay.Test`** : interactive console playground that demonstrates the API end to end. See [`SaferPay.Test/README.md`](SaferPay.Test/README.md). + ### Changelog -`v1.52.01` -+ Updated library target framework to `.NET 8.0` -+ Removed unsupported `.NET 6.0` and legacy test runtime targets -+ Improved overall package compatibility with current and future .NET runtimes -+ Fixed recursive `Dispose()` implementation causing `StackOverflowException` -+ Fixed missing `_jsonSerializerSettings` initialization in the 4-argument constructor -+ Improved `RestClient` lifecycle management to prevent socket/resource leaks under load -+ Fixed exception rethrow handling to preserve original stack traces -+ Normalized `CreditCardExpiration` year handling across constructor, setters and parsing -+ Fixed `CreditCardExpiration.Parse()` producing invalid `MMYYYY` values instead of `MMYY` -+ Improved `CreditCardExpiration.ToString()` formatting consistency -+ Updated package metadata and NuGet packaging configuration -+ Improved GitHub Actions build, validation and NuGet publishing workflow -+ Updated package validation and build pipeline for `.NET 8` -+ General reliability, maintainability and runtime compatibility improvements - -`v1.52` -+ Updated to use the latest version of the JSON API, `v1.52` -+ Added `Saferpay Management API`. -+ Added `PaymentPage GetConfigurations` method to Saferpay Management API -+ Added `WITH_SUCCESSFUL_THREE_DS_CHALLENGE` as a valid value for the field Condition -+ Added `MastercardTLID` to the `IssuerReference` container in the response -+ removed `PayerId` from the `PayPal` container - -`v1.51` -+ Updated to use the latest version of the JSON API, `v1.51` -+ added `PAYPAL` as valid value for field Type in `Alias/Insert` -+ added `ONLINE_CHALLENGED` as valid value for field Type of container `Check` in `Alias/Insert` -+ removed `OK_AUTHENTICATED` as valid value from field `Result` of container `CheckResult`. -+ removed `INVOICE` as valid value from `PaymentMethods` in `PaymentPage/Initialize` -+ added fields `Authenticated` and `AuthenticationType` to container `AuthenticationResult`. Removed field `Result` from container in return. -+ added field `FundingSource` to container `Card` -+ field `CountryCode` in container `ForeignRetailer` is now mandatory. - -`v1.50` -+ Updated to use the latest version of the JSON API, `v1.50` -+ Added value `ONLINE_STRONG` to Type in the `Check` container and added new container `ExternalThreeDS` in `Alias/InsertDirect` -+ Added `GIFTCARD` as valid value for the field `PaymentMethods` -+ Introduced a new function to provide Dynamic Currency Conversion (`DCC`) inquiry details for your customer: `Transaction\DccInquiry` -+ The payment methods `GIROPAY`, `PAYDIREKT`, `SOFORT` and `WLCRYPTOPAYMENTS` are no longer supported. -+ `Transaction/AuthorizeDirect` is extended with the new subcontainer `DCC`, which references the response from `Transaction/DccInquiry` and payer's decision whether he accepts or declines `DCC` offer -+ Added `WERO` as valid value for the field `PaymentMethods` -+ Added `HolderName` and `IBAN` to the BankAccount container in `PaymentPage/Assert` -+ `Transaction/RefundDirect` is extended with the new subcontainer `BankAccount`. This is a required container for PostFinance Instant Payout - -`v1.46` -+ Updated to use the latest version of the JSON API, `v1.46` -+ Added new subcontainer `ExternalThreeDS` to container `Authentication`. This affects the following requests: `Transaction/AuthorizeDirect` -+ Updated `AuthorizeDirect` method to use the new `ExternalThreeDS` subcontainer. - -`v1.45.01` -+ Added `REKA` as alternative payment method to `PaymentPagePaymentMethods`. +See [CHANGELOG.md](CHANGELOG.md) for the full version history. diff --git a/SaferPay.Test/Program.cs b/SaferPay.Test/Program.cs index cf8093f..2664a4c 100644 --- a/SaferPay.Test/Program.cs +++ b/SaferPay.Test/Program.cs @@ -3,7 +3,7 @@ using Console = Colorful.Console; Console.WriteAsciiStyled("SaferPay Test Console", new Colorful.StyleSheet(Color.Orange)); -Console.WriteLine("Json Api Version: 1.46", System.Drawing.Color.OrangeRed); +Console.WriteLine("Json Api Version: 1.52", System.Drawing.Color.OrangeRed); Console.WriteLine("By Viwo Dev"); Console.WriteLine("https://github.com/viwodev/SaferPay.NetCore"); Console.WriteLine(); diff --git a/SaferPay.Test/README.md b/SaferPay.Test/README.md index 9e08f51..e5cc60f 100644 --- a/SaferPay.Test/README.md +++ b/SaferPay.Test/README.md @@ -1,160 +1,59 @@ -# SaferPay.NetCore Json Api V1.36 - -This repository is an implementation of the `SaferPay.Net` library (`https://github.com/bmbsqd/saferpay-net`), with updates to use **.NetCore 6.0** and **RestSharp** instead of HttpClient, and all methods extented by sync and async call. - -The implementation is based on the latest version of the JSON API, v1.36, which can be found at the following URL: `http://saferpay.github.io/jsonapi/#ChapterTransaction`. - -You can find Test Cards and explanation of usage at `https://docs.saferpay.com/home/integration-guide/testing-and-go-live#visa-and-v-pay` - -### What's New -+ Upgrade to `.NetCore 6.0` -+ HttpClient has been replaced by `RestSharp` -+ Updated to use the latest version of the JSON API, `v1.36` -+ Replaced `BaseUri` with `SandBox` mode, and BaseUri is now generated based on SandBox mode for testing or live. -+ Updated and improved constructors for easier usage. -+ Added descriptions to Properties based on api document. -+ Converted string properties to Enum values. -+ Added Examples and Test Console App in Solution. -+ Added Interface Channels to ease of usage. -+ Added Extensions for most used methods directly use in client. -+ Added `IsSuccess` and `Error` properties in ResultObject. -+ Updated all enum values, models, interfaces. - -### Methods -+ Implemented all methods -+ Payment Page Methods : `Initialize`, `Assert` -+ Transaction Methods : `Initialize`, `Authorize`, `QueryPaymentMeans`, `AdjustAmount`, `AuthorizeDirect`, `AuthorizeReferenced`, `Capture`, `MultipartCapture`, `AssertCapture`, `MultipartFinalize`, `Refund`, `AssertRefund`, `RefundDirect`, `Cancel`, `RedirectPayment`, `AssertRedirectPayment`, `Inquire`, `AlternativePayment`, `QueryAlternativePayment` -+ Secure Card Data : `Insert`, `AssertInsert`, `InsertDirect`, `Update`, `Delete` -+ Batch : `Close` -+ Omni Channel : `InsertAlias`, `AcquireTransaction` - -### Global Settings and Usage (With Client Extensions) - -Define Settings; -```csharp -SaferPay.Config.Settings.Default.Username = "ApiUserName"; -SaferPay.Config.Settings.Default.Password = "ApiPassword"; -SaferPay.Config.Settings.Default.TerminalId = "TerminalId"; -SaferPay.Config.Settings.Default.CustomerId = "CustomerId"; -SaferPay.Config.Settings.Default.SandBox = true; -``` +# SaferPay.NetCore Test & Examples (Json Api V1.52) -Get Client Instance; -```csharp -ISaferPayClient Client = SaferPay.Config.Settings.Client(); -``` +This folder is the **interactive console playground** for [SaferPay.NetCore](../README.md), +built against the JSON API **v1.52** and targeting **.NET 8.0 / .NET 10.0**. -Initialize request for Payment Page; -```csharp -string OrderID = "123456"; +It is meant for exploring the library by hand, not as the automated test suite. +For unit and integration tests, see the [`SaferPay.Tests`](../SaferPay.Tests) project. -InitializePaymentPageRequest req = new InitializePaymentPageRequest(); -req.TerminalId = TestConfig.TerminalId; -req.Payment = new Payment(123.45M, "TRY", OrderID); -req.ReturnUrl = $"{TestConfig.WebPage}payment-page?orderId={OrderID}"; -``` +> For the full API reference, supported methods and usage snippets, read the +> [root README](../README.md). This page only documents how to run the test artifacts. -Call Api Async; -```csharp -var result = await Client.InitializePaymentPageAsync(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); -} -else if (result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); -} -else -{ - // Error - Console.Write("Error !"); -} -``` +## Console playground (`SaferPay.Test`) + +A small console app that wires up an `ISaferPayClient` against the SaferPay sandbox +and lets you trigger requests from a menu (Payment Page, Transaction, Secure Card Data, …). +The bundled `success.html` / `failed.html` pages stand in for return URLs. + +Run it from the repository root: -Call Api Sync; -```csharp -var result = Client.InitializePaymentPage(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); -} else if(result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); -} else -{ - // Error - Console.Write("Error !"); -} +```bash +dotnet run --project SaferPay.Test ``` - -### Basic Usage With Interface Channels +Sandbox credentials live in [`TestConfig.cs`](TestConfig.cs) and point at the public +Viwo test account (`test.saferpay.com`). Replace them with your own to test a real account. +You can find test cards and usage details at +. -Initialize the ApiClient; -```csharp -ISaferPayClient Client = new SaferPayClient("CustomerId", "TerminalId", "UserName", "PassWord", true); -``` +### Test pages -Get Interface Channel to use, example based on Transaction; -```csharp -ITransaction payment = Client.Transaction; -``` +| Purpose | URL | +| --- | --- | +| Create test account | | +| Login test account | | -Created Credit Card request; -```csharp -string OrderID = "123456"; +## Automated tests (`SaferPay.Tests`) -InitializeRequest req = new InitializeRequest(TestConfig.TerminalId, 123.45M, "TRY", OrderID, $"{TestConfig.WebPage}transaction?orderId={OrderID}").SetCard("9010004150000009", 12, 30, "123", "Card Holder Name"); -``` +The [`SaferPay.Tests`](../SaferPay.Tests) xUnit project holds the real test suite: -Call Api Async; -```csharp -var result = await payment.InitializeAsync(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); -} -else if (result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); -} -else -{ - // Error - Console.Write("Error !"); -} ++ **Unit** : request/response building, routing, extensions, settings, value types (offline). ++ **Integration** : exercises the live HTTP pipeline against the SaferPay sandbox. + +Run everything from the repository root: + +```bash +dotnet test SaferPay.Tests/SaferPay.Tests.csproj ``` -Call Api Sync; -```csharp -var result = payment.Initialize(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); -} else if(result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); -} else -{ - // Error - Console.Write("Error !"); -} -``` \ No newline at end of file +Integration tests use the public Viwo sandbox account by default. Override or skip them +with environment variables: + +| Variable | Purpose | +| --- | --- | +| `SAFERPAY_CUSTOMER_ID` | Override sandbox Customer Id | +| `SAFERPAY_TERMINAL_ID` | Override sandbox Terminal Id | +| `SAFERPAY_USERNAME` | Override sandbox API username | +| `SAFERPAY_PASSWORD` | Override sandbox API password | +| `SAFERPAY_SKIP_INTEGRATION` | Set to `1` to skip integration tests (fully offline run) | From 8ee9e5559ef2ecfdac6417cfae40dcedbf9bac87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Favre?= Date: Wed, 3 Jun 2026 13:49:53 +0200 Subject: [PATCH 2/2] docs: restructure README --- README.md | 216 ++++++++++++++-------------------------- SaferPay.Test/README.md | 31 ++---- 2 files changed, 80 insertions(+), 167 deletions(-) diff --git a/README.md b/README.md index 30766df..8941a2f 100644 --- a/README.md +++ b/README.md @@ -1,189 +1,121 @@ -# SaferPay.NetCore Json Api V1.52 +# SaferPay.NetCore (Json Api V1.52) -This repository is an implementation of the [SaferPay.Net](https://github.com/bmbsqd/saferpay-net) library, with updates to use **.NET 8.0 / .NET 10.0** and **RestSharp** instead of HttpClient. All methods have been extended with sync and async calls. +An implementation of the [SaferPay.Net](https://github.com/bmbsqd/saferpay-net) library, updated to target **.NET 8.0 / .NET 10.0** and to use **RestSharp** instead of HttpClient. Every method is available in both sync and async form. -The implementation is based on the latest version of the JSON API, **v1.52**, which can be found at the following URL: http://saferpay.github.io/jsonapi/#ChapterTransaction +It tracks the JSON API **v1.52** ([reference](http://saferpay.github.io/jsonapi/#ChapterTransaction)). Test cards and usage are documented on the [SaferPay integration guide](https://docs.saferpay.com/home/integration-guide/testing-and-go-live#visa-and-v-pay). -You can find Test Cards and explanation of usage at: https://docs.saferpay.com/home/integration-guide/testing-and-go-live#visa-and-v-pay +## What's New -### Test Pages - -**Create Test Account** -``` -https://test.saferpay.com/BO/SignUp -``` - -**Login Test Account** -``` -https://test.saferpay.com/BO/Login -``` - -### What's New + Multi-targets `.NET 8.0` and `.NET 10.0` -+ HttpClient has been replaced by `RestSharp` -+ Updated to use the latest version of the JSON API, `v1.52` -+ Replaced `BaseUri` with `SandBox` mode. BaseUri is now generated based on SandBox mode for testing or live environments. -+ Updated and improved constructors for easier usage. -+ Added descriptions to Properties based on the API documentation. -+ Converted string properties to Enum values. -+ Added Examples and Test Console App in the Solution. -+ Added Interface Channels for ease of usage. -+ Added Extensions for the most used methods for direct use in the client. -+ Added `IsSuccess` and `Error` properties in ResultObject. -+ Updated all enum values, models, and interfaces. - -### Methods -Implemented all methods: - -+ **Payment Page Methods:** `Initialize`, `Assert` -+ **Transaction Methods:** `Initialize`, `Authorize`, `QueryPaymentMeans`, `AdjustAmount`, `AuthorizeDirect`, `AuthorizeReferenced`, `Capture`, `MultipartCapture`, `AssertCapture`, `MultipartFinalize`, `Refund`, `AssertRefund`, `RefundDirect`, `Cancel`, `RedirectPayment`, `AssertRedirectPayment`, `Inquire`, `AlternativePayment`, `QueryAlternativePayment`, `DccInquiry` ++ `HttpClient` replaced by `RestSharp` ++ Tracks the latest JSON API, `v1.52` ++ `BaseUri` replaced by a `SandBox` flag (the base URL is derived from it) ++ Simpler constructors and property descriptions taken from the API docs ++ String properties converted to enums ++ Interface channels and extension methods for the most common calls ++ `IsSuccess` and `Error` on every result object ++ Example console app included in the solution + +## Methods + ++ **Payment Page:** `Initialize`, `Assert` ++ **Transaction:** `Initialize`, `Authorize`, `QueryPaymentMeans`, `AdjustAmount`, `AuthorizeDirect`, `AuthorizeReferenced`, `Capture`, `MultipartCapture`, `AssertCapture`, `MultipartFinalize`, `Refund`, `AssertRefund`, `RefundDirect`, `Cancel`, `RedirectPayment`, `AssertRedirectPayment`, `Inquire`, `AlternativePayment`, `QueryAlternativePayment`, `DccInquiry` + **Secure Card Data:** `Insert`, `AssertInsert`, `InsertDirect`, `Update`, `Delete`, `Inquire` + **Batch:** `Close` + **Omni Channel:** `InsertAlias`, `AcquireTransaction` -+ **Saferpay Management API:** `Licensing CustomerLicense`, `PaymentPageConfig GetConfigurations`, `SaferpayFieldsAccessToken CreateAccessToken`, `SaferpayFieldsAccessToken DeleteAccessToken`, `SecurePayGate Create SingleUsePaymentLink`, `SecurePayGate SingleUsePaymentLink`, `SecurePayGate Delete SingleUsePaymentLink`, `Terminal GetTerminal`, `Terminals GetTerminals`, `TransactionReporting GetTransactions` ++ **Management API:** `Licensing CustomerLicense`, `PaymentPageConfig GetConfigurations`, `SaferpayFieldsAccessToken CreateAccessToken`, `SaferpayFieldsAccessToken DeleteAccessToken`, `SecurePayGate Create/Get/Delete SingleUsePaymentLink`, `Terminal GetTerminal`, `Terminals GetTerminals`, `TransactionReporting GetTransactions` -### Global Settings and Usage (With Client Extensions) +## Usage -Define Settings; -```csharp -SaferPay.Config.Settings.Default.Username = "ApiUserName"; -SaferPay.Config.Settings.Default.Password = "ApiPassword"; -SaferPay.Config.Settings.Default.TerminalId = "TerminalId"; -SaferPay.Config.Settings.Default.CustomerId = "CustomerId"; -SaferPay.Config.Settings.Default.SandBox = true; -``` +### 1. Create a client -Get Client Instance; -```csharp -ISaferPayClient Client = SaferPay.Config.Settings.Client(); -``` +Either configure the global settings and pull a client from them: -Initialize request for Payment Page; ```csharp -string OrderID = "123456"; +SaferPay.Config.Settings.Default.CustomerId = "CustomerId"; +SaferPay.Config.Settings.Default.TerminalId = "TerminalId"; +SaferPay.Config.Settings.Default.Username = "ApiUserName"; +SaferPay.Config.Settings.Default.Password = "ApiPassword"; +SaferPay.Config.Settings.Default.SandBox = true; -InitializePaymentPageRequest req = new InitializePaymentPageRequest(); -req.TerminalId = TestConfig.TerminalId; -req.Payment = new Payment(123.45M, "TRY", OrderID); -req.ReturnUrl = $"{TestConfig.WebPage}payment-page?orderId={OrderID}"; +ISaferPayClient client = SaferPay.Config.Settings.Client(); ``` -Call Api Async; -```csharp -var result = await Client.InitializePaymentPageAsync(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); -} -else if (result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); -} -else -{ - // Error - Console.Write("Error !"); -} -``` +Or build one directly: -Call Api Sync; ```csharp -var result = Client.InitializePaymentPage(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); -} else if(result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); -} else -{ - // Error - Console.Write("Error !"); -} +ISaferPayClient client = new SaferPayClient("CustomerId", "TerminalId", "UserName", "Password", sandBox: true); ``` - -### Basic Usage With Interface Channels +### 2. Build a request - -Initialize the ApiClient; ```csharp -ISaferPayClient Client = new SaferPayClient("CustomerId", "TerminalId", "UserName", "PassWord", true); +string orderId = "123456"; + +var request = new InitializePaymentPageRequest +{ + TerminalId = TestConfig.TerminalId, + Payment = new Payment(123.45M, "TRY", orderId), + ReturnUrl = $"{TestConfig.WebPage}payment-page?orderId={orderId}", +}; ``` -Get Interface Channel to use, example based on Transaction; +### 3. Send it (async or sync) + ```csharp -ITransaction payment = Client.Transaction; +var result = await client.InitializePaymentPageAsync(request); +// sync equivalent: +// var result = client.InitializePaymentPage(request); ``` -Created Credit Card request; -```csharp -string OrderID = "123456"; +### 4. Handle the result -InitializeRequest req = new InitializeRequest(TestConfig.TerminalId, 123.45M, "TRY", OrderID, $"{TestConfig.WebPage}transaction?orderId={OrderID}").SetCard("9010004150000009", 12, 30, "123", "Card Holder Name"); -``` +Every call returns a result exposing `IsSuccess`, the typed response and an `Error` object: -Call Api Async; ```csharp -var result = await payment.InitializeAsync(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); +if (result != null && result.IsSuccess) { + Console.WriteLine(result.Json()); // success } -else if (result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); +else if (result != null) { + Console.WriteLine(result.Error.Json()); // API returned an error } -else -{ - // Error - Console.Write("Error !"); +else { + Console.WriteLine("Request failed."); // null / transport error } ``` -Call Api Sync; +### Interface channels + +Each API group is also reachable as a typed channel on the client, which keeps related calls together: + ```csharp -var result = payment.Initialize(req); -if (result != null && result.IsSuccess) -{ - // Success - Console.Write("Response Successful : "); - Console.WriteLine(result.Json()); -} else if(result != null) -{ - // Failed - Console.Write("Response Failed : "); - Console.WriteLine(result.Error.Json()); -} else -{ - // Error - Console.Write("Error !"); -} +ITransaction transaction = client.Transaction; + +var request = new InitializeRequest( + TestConfig.TerminalId, 123.45M, "TRY", orderId, + $"{TestConfig.WebPage}transaction?orderId={orderId}") + .SetCard("9010004150000009", 12, 30, "123", "Card Holder Name"); + +var result = await transaction.InitializeAsync(request); +// sync: transaction.Initialize(request); ``` -### Tests +The result is handled exactly as shown in step 4. + +## Tests -The solution ships with two projects under the repository root: +The solution ships two test projects at the repository root: + ++ **`SaferPay.Tests`** : automated xUnit suite (`Unit` + sandbox `Integration`). Run it with: -+ **`SaferPay.Tests`** : automated xUnit suite (`Unit` + sandbox `Integration` tests). Run it with: ```bash dotnet test SaferPay.Tests/SaferPay.Tests.csproj ``` - Integration tests run against `test.saferpay.com` using the public Viwo sandbox account by default. Override it with the `SAFERPAY_CUSTOMER_ID`, `SAFERPAY_TERMINAL_ID`, `SAFERPAY_USERNAME` and `SAFERPAY_PASSWORD` environment variables, or set `SAFERPAY_SKIP_INTEGRATION=1` for a fully offline run. + + Integration tests hit `test.saferpay.com` with the public Viwo sandbox account by default. Override it with the `SAFERPAY_CUSTOMER_ID`, `SAFERPAY_TERMINAL_ID`, `SAFERPAY_USERNAME` and `SAFERPAY_PASSWORD` environment variables, or set `SAFERPAY_SKIP_INTEGRATION=1` for a fully offline run. + + **`SaferPay.Test`** : interactive console playground that demonstrates the API end to end. See [`SaferPay.Test/README.md`](SaferPay.Test/README.md). -### Changelog +## Changelog See [CHANGELOG.md](CHANGELOG.md) for the full version history. diff --git a/SaferPay.Test/README.md b/SaferPay.Test/README.md index e5cc60f..a179472 100644 --- a/SaferPay.Test/README.md +++ b/SaferPay.Test/README.md @@ -1,19 +1,12 @@ # SaferPay.NetCore Test & Examples (Json Api V1.52) -This folder is the **interactive console playground** for [SaferPay.NetCore](../README.md), -built against the JSON API **v1.52** and targeting **.NET 8.0 / .NET 10.0**. +The two test projects for [SaferPay.NetCore](../README.md), built against the JSON API **v1.52** and targeting **.NET 8.0 / .NET 10.0**. -It is meant for exploring the library by hand, not as the automated test suite. -For unit and integration tests, see the [`SaferPay.Tests`](../SaferPay.Tests) project. - -> For the full API reference, supported methods and usage snippets, read the -> [root README](../README.md). This page only documents how to run the test artifacts. +For the full API reference and usage snippets, read the [root README](../README.md). This page only covers how to run the test artifacts. ## Console playground (`SaferPay.Test`) -A small console app that wires up an `ISaferPayClient` against the SaferPay sandbox -and lets you trigger requests from a menu (Payment Page, Transaction, Secure Card Data, …). -The bundled `success.html` / `failed.html` pages stand in for return URLs. +A small console app that wires up an `ISaferPayClient` against the SaferPay sandbox and lets you trigger requests from a menu (Payment Page, Transaction, Secure Card Data, ...). The bundled `success.html` / `failed.html` pages stand in for return URLs. Run it from the repository root: @@ -21,24 +14,13 @@ Run it from the repository root: dotnet run --project SaferPay.Test ``` -Sandbox credentials live in [`TestConfig.cs`](TestConfig.cs) and point at the public -Viwo test account (`test.saferpay.com`). Replace them with your own to test a real account. - -You can find test cards and usage details at -. - -### Test pages - -| Purpose | URL | -| --- | --- | -| Create test account | | -| Login test account | | +Sandbox credentials live in [`TestConfig.cs`](TestConfig.cs) and point at the public Viwo test account. Replace them with your own to test a real account. ## Automated tests (`SaferPay.Tests`) The [`SaferPay.Tests`](../SaferPay.Tests) xUnit project holds the real test suite: -+ **Unit** : request/response building, routing, extensions, settings, value types (offline). ++ **Unit** : request/response building, routing, extensions, settings and value types (offline). + **Integration** : exercises the live HTTP pipeline against the SaferPay sandbox. Run everything from the repository root: @@ -47,8 +29,7 @@ Run everything from the repository root: dotnet test SaferPay.Tests/SaferPay.Tests.csproj ``` -Integration tests use the public Viwo sandbox account by default. Override or skip them -with environment variables: +Integration tests use the public Viwo sandbox account by default. Override or skip them with environment variables: | Variable | Purpose | | --- | --- |