[
  {
    "path": ".editorconfig",
    "content": "# editorconfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# Default settings:\n# A newline ending every file\n# Use 4 spaces as indentation\n[*]\ninsert_final_newline = true\nindent_style = space\nindent_size = 4\ntrim_trailing_whitespace = true\n\n[project.json]\nindent_size = 2\n\n# Generated code\n[*{_AssemblyInfo.cs,.notsupported.cs}]\ngenerated_code = true\n\n# C# files\n[*.cs]\n# New line preferences\ncsharp_new_line_before_open_brace = none\ncsharp_new_line_before_else = false\ncsharp_new_line_before_catch = false\ncsharp_new_line_before_finally = false\ncsharp_new_line_before_members_in_object_initializers = false\ncsharp_new_line_before_members_in_anonymous_types = false\ncsharp_new_line_between_query_expression_clauses = false\n\n# Indentation preferences\ncsharp_indent_block_contents = true\ncsharp_indent_braces = false\ncsharp_indent_case_contents = true\ncsharp_indent_case_contents_when_block = true\ncsharp_indent_switch_labels = true\ncsharp_indent_labels = one_less_than_current\n\n# avoid this. unless absolutely necessary\ndotnet_style_qualification_for_field = false:suggestion\ndotnet_style_qualification_for_property = false:suggestion\ndotnet_style_qualification_for_method = false:suggestion\ndotnet_style_qualification_for_event = false:suggestion\n\n# only use var when it's obvious what the variable type is\ncsharp_style_var_for_built_in_types = false:none\ncsharp_style_var_when_type_is_apparent = false:none\ncsharp_style_var_elsewhere = false:suggestion\n\n# use language keywords instead of BCL types\ndotnet_style_predefined_type_for_locals_parameters_members = true:error\ndotnet_style_predefined_type_for_member_access = true:error\n\n# name all constant fields using PascalCase\ndotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion\ndotnet_naming_rule.constant_fields_should_be_pascal_case.symbols  = constant_fields\ndotnet_naming_rule.constant_fields_should_be_pascal_case.style    = pascal_case_style\n\ndotnet_naming_symbols.constant_fields.applicable_kinds   = field\ndotnet_naming_symbols.constant_fields.required_modifiers = const\n\ndotnet_naming_style.pascal_case_style.capitalization = pascal_case\n\n# Code style defaults\ncsharp_using_directive_placement = outside_namespace:warning\ndotnet_sort_system_directives_first = true\ncsharp_preserve_single_line_blocks = true\ncsharp_preserve_single_line_statements = false\n\n# Expression-level preferences\ndotnet_style_object_initializer = true:suggestion\ndotnet_style_collection_initializer = true:suggestion\ndotnet_style_explicit_tuple_names = true:suggestion\ndotnet_style_coalesce_expression = true:suggestion\ndotnet_style_null_propagation = true:suggestion\n\n# Expression-bodied members\ncsharp_style_expression_bodied_methods = true:none\ncsharp_style_expression_bodied_constructors = false:none\ncsharp_style_expression_bodied_operators = false:none\ncsharp_style_expression_bodied_properties = true:none\ncsharp_style_expression_bodied_indexers = true:none\ncsharp_style_expression_bodied_accessors = true:none\n\n# Pattern matching\ncsharp_style_pattern_matching_over_is_with_cast_check = true:error\ncsharp_style_pattern_matching_over_as_with_null_check = true:error\ncsharp_style_inlined_variable_declaration = true:error\n\n# Null checking preferences\ncsharp_style_throw_expression = true:suggestion\ncsharp_style_conditional_delegate_call = true:suggestion\n\n# Space preferences\ncsharp_space_after_cast = false\ncsharp_space_after_colon_in_inheritance_clause = true\ncsharp_space_after_comma = true\ncsharp_space_after_dot = false\ncsharp_space_after_keywords_in_control_flow_statements = true\ncsharp_space_after_semicolon_in_for_statement = true\ncsharp_space_around_binary_operators = before_and_after\ncsharp_space_around_declaration_statements = do_not_ignore\ncsharp_space_before_colon_in_inheritance_clause = true\ncsharp_space_before_comma = false\ncsharp_space_before_dot = false\ncsharp_space_before_open_square_brackets = false\ncsharp_space_before_semicolon_in_for_statement = false\ncsharp_space_between_empty_square_brackets = false\ncsharp_space_between_method_call_empty_parameter_list_parentheses = false\ncsharp_space_between_method_call_name_and_opening_parenthesis = false\ncsharp_space_between_method_call_parameter_list_parentheses = false\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses = false\ncsharp_space_between_method_declaration_name_and_open_parenthesis = false\ncsharp_space_between_method_declaration_parameter_list_parentheses = false\ncsharp_space_between_parentheses = false\ncsharp_space_between_square_brackets = false\n\n# C++ Files\n[*.{cpp,h,in}]\ncurly_bracket_next_line = true\nindent_brace_style = Allman\n\n# Xml project files\n[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]\nindent_size = 2\n\n[*.{csproj,vbproj,proj,nativeproj,locproj}]\ncharset = utf-8\n\n# Xml build files\n[*.builds]\nindent_size = 2\n\n# Xml files\n[*.{xml,stylecop,resx,ruleset}]\nindent_size = 2\n\n# Xml config files\n[*.{props,targets,config,nuspec}]\nindent_size = 2\n\n# YAML config files\n[*.{yml,yaml}]\nindent_size = 2\n\n# Shell scripts\n[*.sh]\nend_of_line = lf\n[*.{cmd,bat}]\nend_of_line = crlf\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n\n# Standard to msysgit\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [Viincenttt]"
  },
  {
    "path": ".github/workflows/dotnetcore.yml",
    "content": "name: Run automated tests\n\non: [push]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Setup .NET Core\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: '10.0.x'\n      - name: Install dependencies\n        run: dotnet restore\n      - name: Build unit test project\n        run: dotnet build tests/Mollie.Tests.Unit --configuration Release --no-restore\n      - name: Run unit tests\n        run: dotnet test tests/Mollie.Tests.Unit --no-restore --verbosity normal\n      - name: Build integration test project\n        run: dotnet build tests/Mollie.Tests.Integration --configuration Release --no-restore\n      - name: Run integration tests\n        run: dotnet test tests/Mollie.Tests.Integration --filter \"TestCategory!=LocalIntegrationTests\" --no-restore --verbosity normal\n        env:\n          Mollie__ApiKey: ${{ secrets.Mollie__ApiKey }}\n          Mollie__AccessKey: ${{ secrets.Mollie__AccessKey }}\n          Mollie__ClientId: ${{ secrets.Mollie__ClientId }}\n          Mollie__ClientSecret: ${{ secrets.Mollie__ClientSecret }}\n\n  publish:\n    runs-on: ubuntu-latest\n    needs: build\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Setup .NET Core\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: '10.0.x'\n      - name: Install dependencies\n        run: dotnet restore\n      - name: Prepare strong-name signing key\n        shell: bash\n        run: |\n          if [ -z \"${{ secrets.MOLLIE_STRONG_NAME_KEY_BASE64 }}\" ]; then\n            echo \"MOLLIE_STRONG_NAME_KEY_BASE64 secret is not set.\"\n            exit 1\n          fi\n          mkdir -p \"$RUNNER_TEMP/signing\"\n          echo \"${{ secrets.MOLLIE_STRONG_NAME_KEY_BASE64 }}\" | base64 --decode > \"$RUNNER_TEMP/signing/mollie.snk\"\n          chmod 600 \"$RUNNER_TEMP/signing/mollie.snk\"\n          echo \"MOLLIE_STRONG_NAME_KEY_FILE=$RUNNER_TEMP/signing/mollie.snk\" >> \"$GITHUB_ENV\"\n      - name: Build Mollie.Api\n        run: dotnet build src/Mollie.Api/Mollie.Api.csproj --configuration Release --no-restore /p:MollieStrongNameKeyFile=\"$MOLLIE_STRONG_NAME_KEY_FILE\"\n      - name: Build Mollie.Api.AspNet\n        run: dotnet build src/Mollie.Api.AspNet/Mollie.Api.AspNet.csproj --configuration Release --no-restore /p:MollieStrongNameKeyFile=\"$MOLLIE_STRONG_NAME_KEY_FILE\"\n      - name: Pack Mollie.Api\n        run: dotnet pack src/Mollie.Api/Mollie.Api.csproj --configuration Release --no-restore --no-build --output ./nupkgs /p:MollieStrongNameKeyFile=\"$MOLLIE_STRONG_NAME_KEY_FILE\"\n      - name: Pack Mollie.Api.AspNet\n        run: dotnet pack src/Mollie.Api.AspNet/Mollie.Api.AspNet.csproj --configuration Release --no-restore --no-build --output ./nupkgs /p:MollieStrongNameKeyFile=\"$MOLLIE_STRONG_NAME_KEY_FILE\"\n      - name: Push to NuGet\n        run: dotnet nuget push ./nupkgs/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings \n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# NuGet Packages\n*.nupkg\n*.snupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n\n# Windows Azure Build Output\ncsx/\n*.build.csdef\n\n# Windows Azure Emulator\nefc/\nrfc/\n\n# Windows Store app package directory\nAppPackages/\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.snk\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\n\n# FAKE - F# Make\n.fake/\n\n# =========================\n# Operating System Files\n# =========================\n\n# OSX\n# =========================\n\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n# Windows\n# =========================\n\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n# Custom\n**/.idea/\n"
  },
  {
    "path": "AGENTS.md",
    "content": "# Agents Guide — Mollie API Client for .NET\n\nThis document describes the project structure, conventions, and guidelines for AI agents working in this codebase.\n\n---\n\n## Project Overview\n\nThis is an open-source .NET library that wraps the [Mollie REST API](https://docs.mollie.com/). It is published as two NuGet packages:\n\n| Package | Path | Purpose |\n|---|---|---|\n| `Mollie.Api` | `src/Mollie.Api` | Core API client library targeting `netstandard2.0` and `net8.0` |\n| `Mollie.Api.AspNet` | `src/Mollie.Api.AspNet` | ASP.NET-specific webhook helpers |\n\nTests live under `tests/` and samples under `samples/Mollie.WebApplication.Blazor`.\n\n---\n\n## Solution Structure\n\n```\nsrc/\n  Mollie.Api/\n    Client/          # One concrete client class per Mollie API resource\n    Client/Abstract/ # One interface per client\n    Models/          # Request and response record types, grouped by resource\n    JsonConverters/  # Custom System.Text.Json converters\n    Framework/       # Auth, idempotency, retry policies, JSON service\n    Extensions/      # Extension methods (IEnumerable, Dictionary helpers)\n    Options/         # MollieOptions, MollieClientOptions\n    DependencyInjection.cs\n  Mollie.Api.AspNet/\n    Webhooks/        # Model binders and signature filter\ntests/\n  Mollie.Tests.Unit/\n    Client/          # One test class per client\n    Models/          # Serialisation/deserialisation tests\n    Framework/\n  Mollie.Tests.Integration/\nsamples/\n  Mollie.WebApplication.Blazor/\n```\n\n---\n\n## Key Conventions\n\n### Language & Target\n\n- **C# 12** (`LangVersion` is set to `12`). Use modern language features such as `required` members, primary constructors, collection expressions, and `record` types where appropriate.\n- The library targets **`netstandard2.0`** (via PolySharp for back-fill) and **`net8.0`**.\n- Nullable reference types are **enabled** (`<Nullable>enable</Nullable>`). Always annotate nullability correctly.\n\n### Naming\n\n| Artifact | Convention | Example |\n|---|---|---|\n| Client interface | `I{Resource}Client` | `IPaymentClient` |\n| Client class | `{Resource}Client` | `PaymentClient` |\n| Request model | `{Resource}Request` | `PaymentRequest` |\n| Update request | `{Resource}UpdateRequest` | `PaymentUpdateRequest` |\n| Response model | `{Resource}Response` | `PaymentResponse` |\n| List response | `ListResponse<{Resource}Response>` | `ListResponse<PaymentResponse>` |\n| Test class | `{Resource}ClientTests` | `PaymentClientTests` |\n\n### Client Pattern\n\nEvery API resource follows this pattern:\n\n1. **Interface** in `Client/Abstract/I{Resource}Client.cs` — inherits `IBaseMollieClient`, all public methods documented with XML `<summary>` / `<param>` / `<returns>` comments.\n2. **Implementation** in `Client/{Resource}Client.cs` — inherits `BaseMollieClient`, implements the interface.\n3. **Two constructors** on every concrete client:\n   - `(string apiKey, HttpClient? httpClient = null)` — for manual instantiation.\n   - `[ActivatorUtilitiesConstructor] (MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)` — used by DI.\n4. **Register** the new client pair in `DependencyInjection.cs` via `RegisterMollieApiClient<IFooClient, FooClient>`.\n\n```csharp\n// Typical method signature\npublic async Task<FooResponse> GetFooAsync(\n    string fooId,\n    bool testmode = false,\n    CancellationToken cancellationToken = default) {\n\n    ValidateRequiredUrlParameter(nameof(fooId), fooId);\n    var queryParameters = BuildQueryParameters(testmode: testmode);\n    return await GetAsync<FooResponse>(\n        $\"foos/{fooId}{queryParameters.ToQueryString()}\",\n        cancellationToken: cancellationToken).ConfigureAwait(false);\n}\n```\n\nKey rules:\n- Always call `ValidateRequiredUrlParameter` for ID path segments.\n- Always call `ValidateApiKeyIsOauthAccesstoken()` when a parameter requires an OAuth token (e.g., `profileId`, `testmode`, `applicationFee`).\n- Always pass `cancellationToken` through and call `.ConfigureAwait(false)` on every `await`.\n- Use the protected helpers `GetAsync`, `PostAsync`, `PatchAsync`, `DeleteAsync`, `GetListAsync` from `BaseMollieClient` — never call `HttpClient` directly.\n- Build query strings using the `BuildQueryParameters` helper and the `ToQueryString()` extension method.\n\n### Model Pattern\n\n- **Request** and **Response** types are `record` types.\n- Required fields are annotated with the `required` keyword.\n- Optional fields are nullable (`string?`, `DateTime?`, etc.).\n- All properties have XML `<summary>` documentation comments.\n- Use `[JsonPropertyName(\"...\")]` only when the JSON key differs from the C# property name.\n- Use `[JsonConverter(typeof(RawJsonConverter))]` for `Metadata` fields that hold raw JSON.\n- JSON is handled by `System.Text.Json` — do **not** add a dependency on `Newtonsoft.Json`.\n- Response models that implement `IEntity` expose an `Id` property.\n- Embedded resources are placed in a nested `{Resource}EmbeddedResponse` type annotated with `[JsonPropertyName(\"_embedded\")]`.\n- HAL-style link objects are placed in a nested `{Resource}ResponseLinks` type annotated with `[JsonPropertyName(\"_links\")]` and typed as `UrlObjectLink<T>`.\n\n### Extensions\n\nUse the dictionary/list extension helpers in `Mollie.Api.Extensions` for building query parameters:\n\n```csharp\nresult.AddValueIfNotNullOrEmpty(\"include\", someValue);\nresult.AddValueIfTrue(\"testmode\", testmode);\nincludeList.AddValueIfTrue(\"details.qrCode\", includeQrCode);\nreturn includeList.ToIncludeParameter();\n```\n\n---\n\n## Testing\n\n### Framework & Libraries\n\n| Library | Purpose |\n|---|---|\n| **xUnit** | Test runner |\n| **Shouldly** | Fluent assertions (`value.ShouldBe(...)`) |\n| **RichardSzalay.MockHttp** | Mock `HttpClient` responses |\n| **Moq** | Mocking dependencies when needed |\n\n### Unit Test Conventions\n\n- Every client class has a corresponding `{Resource}ClientTests` class in `tests/Mollie.Tests.Unit/Client/`.\n- All test classes inherit `BaseClientTests` which provides `CreateMockHttpMessageHandler(...)`.\n- Follow the **Given / When / Then** (or **Arrange / Act / Assert**) comment pattern within each test.\n- Tests are `async Task` with the `[Fact]` or `[Theory]` attribute.\n- Never hit real Mollie endpoints in unit tests — use `MockHttpMessageHandler` to return canned JSON.\n- Store expected JSON response strings as `private const string` fields in the test class.\n- Use `mockHttp.VerifyNoOutstandingExpectation()` to assert all expected HTTP calls were made.\n\n```csharp\n[Fact]\npublic async Task GetFooAsync_WithValidId_ResponseIsDeserializedCorrectly() {\n    // Given\n    const string fooId = \"foo_123\";\n    const string jsonResponse = \"{ ... }\";\n    var mockHttp = CreateMockHttpMessageHandler(\n        HttpMethod.Get,\n        $\"{BaseMollieClient.DefaultBaseApiEndPoint}foos/{fooId}\",\n        jsonResponse);\n    var client = new FooClient(\"test_api_key\", mockHttp.ToHttpClient());\n\n    // When\n    FooResponse result = await client.GetFooAsync(fooId);\n\n    // Then\n    result.Id.ShouldBe(fooId);\n    mockHttp.VerifyNoOutstandingExpectation();\n}\n```\n\n---\n\n## Adding a New API Resource\n\nFollow these steps in order:\n\n1. **Response model** — `src/Mollie.Api/Models/{Resource}/Response/{Resource}Response.cs`\n2. **Request model** (if applicable) — `src/Mollie.Api/Models/{Resource}/Request/{Resource}Request.cs`\n3. **Interface** — `src/Mollie.Api/Client/Abstract/I{Resource}Client.cs`\n4. **Implementation** — `src/Mollie.Api/Client/{Resource}Client.cs`\n5. **Register in DI** — add `RegisterMollieApiClient<I{Resource}Client, {Resource}Client>` to `DependencyInjection.cs`\n6. **Unit tests** — `tests/Mollie.Tests.Unit/Client/{Resource}ClientTests.cs`\n7. **Sample page** (optional) — add a Blazor page under `samples/Mollie.WebApplication.Blazor/Pages/{Resource}/`\n\n---\n\n## Authentication\n\n- **API key** authentication: string starting with `live_` or `test_`.\n- **OAuth** (access token) authentication: string starting with `access_`.\n- The `IMollieSecretManager` abstraction allows custom multi-tenant scenarios.\n- `BaseMollieClient.ValidateApiKeyIsOauthAccesstoken()` enforces that OAuth-only parameters are not used with a plain API key.\n\n---\n\n## Error Handling\n\n- HTTP errors are thrown as `MollieApiException` which contains a `MollieErrorMessage` with `Status`, `Title`, and `Detail`.\n- Callers should catch `MollieApiException` to handle Mollie-specific API errors.\n\n---\n\n## Idempotency\n\n- Every HTTP request automatically gets a random `Idempotency-Key` header (UUID).\n- Callers can supply a custom key via `client.WithIdempotencyKey(\"my-key\")` which returns an `IDisposable` scope.\n\n---\n\n## Style & Formatting\n\n- Braces on the **same line** for namespace, class, and method declarations (Allman is **not** used).\n- Indentation: **tabs** (4-space visual width as configured in the IDE).\n- Opening braces for single-statement `if`/`foreach` blocks are optional but generally omitted for single-line bodies.\n- `var` is used where the type is obvious from the right-hand side.\n- `ConfigureAwait(false)` on every `await` inside library code.\n- XML documentation on all public members.\n\n"
  },
  {
    "path": "Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n    <!-- Package identity -->\n    <Version>4.19.0.0</Version>\n    <AssemblyVersion>4.19.0.0</AssemblyVersion>\n    <FileVersion>4.19.0.0</FileVersion>\n    <PackageVersion>4.19.0.0</PackageVersion>\n    <Authors>Vincent Kok</Authors>\n    <Company>Vincent Kok</Company>\n    <Product>Mollie Payment API</Product>\n    <PackageTags>Mollie;Payment;Payments;Webhook</PackageTags>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <!-- Package metadata & license -->\n    <PackageProjectUrl>https://github.com/Viincenttt/MollieApi</PackageProjectUrl>\n    <RepositoryUrl>https://github.com/Viincenttt/MollieApi.git</RepositoryUrl>\n    <RepositoryType>git</RepositoryType>\n    <PackageReadmeFile>README.md</PackageReadmeFile>\n    <PackageLicenseFile>LICENSE</PackageLicenseFile>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <!-- Build & symbols -->\n    <DebugType>portable</DebugType>\n    <EmbedUntrackedSources>true</EmbedUntrackedSources>\n    <IncludeSymbols>true</IncludeSymbols>\n    <SymbolPackageFormat>snupkg</SymbolPackageFormat>\n    <!-- Suppress warnings for missing XML documentation comments on public members -->\n    <NoWarn>$(NoWarn);CS1591</NoWarn>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <!-- Release strong-name signing; key material should come from CI secrets. -->\n    <MollieStrongNameKeyFile Condition=\"'$(MollieStrongNameKeyFile)' == ''\">$(MOLLIE_STRONG_NAME_KEY_FILE)</MollieStrongNameKeyFile>\n    <MollieStrongNamePublicKeyFile Condition=\"'$(MollieStrongNamePublicKeyFile)' == ''\">$(MSBuildThisFileDirectory)mollie.publickey.txt</MollieStrongNamePublicKeyFile>\n    <MollieStrongNamePublicKey Condition=\"'$(MollieStrongNamePublicKey)' == '' and Exists('$(MollieStrongNamePublicKeyFile)')\">$([System.Text.RegularExpressions.Regex]::Replace($([System.IO.File]::ReadAllText('$(MollieStrongNamePublicKeyFile)')), '[^0-9a-fA-F]', ''))</MollieStrongNamePublicKey>\n    <MollieStrongNamePublicKey Condition=\"'$(MollieStrongNamePublicKey)' == ''\">$(MOLLIE_STRONG_NAME_PUBLIC_KEY)</MollieStrongNamePublicKey>\n    <SignAssembly Condition=\"'$(Configuration)' == 'Release' and '$(MollieStrongNameKeyFile)' != '' and Exists('$(MollieStrongNameKeyFile)')\">true</SignAssembly>\n    <AssemblyOriginatorKeyFile Condition=\"'$(SignAssembly)' == 'true'\">$(MollieStrongNameKeyFile)</AssemblyOriginatorKeyFile>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 Vincent Kok\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "MollieApi.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.29920.165\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Mollie.Api\", \"src/Mollie.Api\\Mollie.Api.csproj\", \"{DBA9DC3A-D562-4D15-A7FB-B0A1DC3E517B}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Mollie.Tests.Integration\", \"tests/Mollie.Tests.Integration\\Mollie.Tests.Integration.csproj\", \"{27DA8118-1976-4B2D-B578-BC3EB91FC39F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Mollie.Tests.Unit\", \"tests/Mollie.Tests.Unit\\Mollie.Tests.Unit.csproj\", \"{EA502BEF-EA42-45D0-BCC8-F0C28C7A4C41}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Mollie.WebApplication.Blazor\", \"samples\\Mollie.WebApplication.Blazor\\Mollie.WebApplication.Blazor.csproj\", \"{ECE7EA04-09CA-44A4-8CD4-622A4631BF85}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"tests\", \"tests\", \"{17397A2E-2BA0-418C-928E-D4E8511A3C67}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"samples\", \"samples\", \"{6E02EF59-F625-492C-9950-B8AEF7852D65}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Mollie.Api.AspNet\", \"src\\Mollie.Api.AspNet\\Mollie.Api.AspNet.csproj\", \"{8982D24F-AC99-43A1-A429-3BCCC96FA110}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{DBA9DC3A-D562-4D15-A7FB-B0A1DC3E517B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{DBA9DC3A-D562-4D15-A7FB-B0A1DC3E517B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{DBA9DC3A-D562-4D15-A7FB-B0A1DC3E517B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{DBA9DC3A-D562-4D15-A7FB-B0A1DC3E517B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{27DA8118-1976-4B2D-B578-BC3EB91FC39F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{27DA8118-1976-4B2D-B578-BC3EB91FC39F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{27DA8118-1976-4B2D-B578-BC3EB91FC39F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{27DA8118-1976-4B2D-B578-BC3EB91FC39F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{EA502BEF-EA42-45D0-BCC8-F0C28C7A4C41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{EA502BEF-EA42-45D0-BCC8-F0C28C7A4C41}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{EA502BEF-EA42-45D0-BCC8-F0C28C7A4C41}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{EA502BEF-EA42-45D0-BCC8-F0C28C7A4C41}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{ECE7EA04-09CA-44A4-8CD4-622A4631BF85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{ECE7EA04-09CA-44A4-8CD4-622A4631BF85}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{ECE7EA04-09CA-44A4-8CD4-622A4631BF85}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{ECE7EA04-09CA-44A4-8CD4-622A4631BF85}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8982D24F-AC99-43A1-A429-3BCCC96FA110}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8982D24F-AC99-43A1-A429-3BCCC96FA110}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8982D24F-AC99-43A1-A429-3BCCC96FA110}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8982D24F-AC99-43A1-A429-3BCCC96FA110}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {EA1EE69B-285E-4518-8936-DB1278A71882}\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{27DA8118-1976-4B2D-B578-BC3EB91FC39F} = {17397A2E-2BA0-418C-928E-D4E8511A3C67}\n\t\t{EA502BEF-EA42-45D0-BCC8-F0C28C7A4C41} = {17397A2E-2BA0-418C-928E-D4E8511A3C67}\n\t\t{ECE7EA04-09CA-44A4-8CD4-622A4631BF85} = {6E02EF59-F625-492C-9950-B8AEF7852D65}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "README.md",
    "content": "# Mollie Api Client for .NET\n[![NuGet](https://img.shields.io/nuget/v/Mollie.Api.svg)](https://www.nuget.org/packages/Mollie.Api)\n![Build](https://github.com/Viincenttt/MollieApi/workflows/Run%20automated%20tests/badge.svg)\n[![GitHub Repo stars](https://img.shields.io/github/stars/Viincenttt/MollieApi)](https://github.com/Viincenttt/MollieApi/stargazers)\n[![GitHub contributors](https://img.shields.io/github/contributors/Viincenttt/MollieApi)](https://github.com/Viincenttt/MollieApi/graphs/contributors)\n[![GitHub last commit](https://img.shields.io/github/last-commit/Viincenttt/MollieApi)](https://github.com/Viincenttt/MollieApi)\n[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Viincenttt/MollieApi)](https://github.com/Viincenttt/MollieApi/graphs/commit-activity)\n[![open issues](https://img.shields.io/github/issues/Viincenttt/MollieApi)](https://github.com/Viincenttt/MollieApi/issues)\n[![Read the Wiki](https://img.shields.io/badge/docs-Wiki-blue)](https://github.com/Viincenttt/MollieApi/wiki)\n\nEasily integrate the [Mollie payment provider](https://www.mollie.com) into your .NET application.\n\nFull documentation of this library is available on the [Wiki](https://github.com/Viincenttt/MollieApi/wiki) — including usage examples, API references, and integration tips.\n\nMollie offers excellent [API documentation](https://docs.mollie.com/) that we highly recommend reviewing before using this library. If you encounter any issues or have feature requests, feel free to [open an issue](https://github.com/Viincenttt/MollieApi/issues). \n\n> 💬 **Need help with integration?**  \n> I’m happy to assist you with your implementation or questions. Feel free to [connect with me on LinkedIn](https://www.linkedin.com/in/vincent-kok-4aa44211/) — I’d love to help!\n\nHave feedback or ideas? Join the [official Mollie Developer Discord](https://discord.gg/Pdy49HxCWZ) or [open an issue](https://github.com/Viincenttt/MollieApi/issues).\n\n---\n\n## 📚 Table of Contents\n- [Sponsor This Project](#-sponsor-this-project)\n- [Full documentation](#-full-documentation)\n- [Getting Started](#-getting-started)\n  - [Dependency Injection](#dependency-injection)\n  - [Manual Instantiation](#manual-instantiation)\n  - [Create a Payment in under a minute](#-create-a-payment-in-under-a-minute)\n  - [Example Project (Blazor)](#-blazor-example-project)\n- [Supported APIs](#-supported-apis)\n- [Contributions](#-contributions)\n- [Supported .NET Versions](#-supported-net-versions)\n\n---\n\n## 💖 Sponsor This Project\nThis project is proudly sponsored by Mollie — thank you for supporting open source and developer tooling!\n\nIf this library has helped you or saved you time, please consider [sponsoring me on GitHub](https://github.com/sponsors/Viincenttt) as well.\nYour support helps me keep improving the library and providing integration help to the community!\n\n---\n\n## 📖 Full Documentation\nLooking for the full API docs, usage examples, and advanced guides?\n\n👉 **Check out the full Wiki here:**  \n➡️ [https://github.com/Viincenttt/MollieApi/wiki](https://github.com/Viincenttt/MollieApi/wiki)\nYou'll find:\n- Getting started walkthroughs\n- All supported APIs and code samples\n- Best practices for integration\n\n--- \n\n## 🛠 Getting started\nInstall via NuGet:\n```bash\nInstall-Package Mollie.Api\n```\n\n### Dependency Injection\nYou can register all API client interfaces using the built-in DI extension:\n```csharp\nbuilder.Services.AddMollieApi(options => {\n    options.ApiKey = builder.Configuration[\"Mollie:ApiKey\"];\n    options.RetryPolicy = MollieHttpRetryPolicies.TransientHttpErrorRetryPolicy();\n});\n```\nEach API (e.g. payments, customers, mandates) has its own dedicated API client class and interface:\n* `IPaymentClient`, `PaymentClient`\n* `ICustomerClient`, `CustomerClient`\n* `ISubscriptionClient`, `SubscriptionClient`\n* `IMandateClient`, `MandateClient`\n* ... and more\n\nAfter registering via DI, inject the interface you need in your services or controllers.\n\n### Manual Instantiation\nIf you prefer not to use DI, you can manually instantiate a client:\n``` csharp\nusing IPaymentClient paymentClient = new PaymentClient(\"{yourApiKey}\", new HttpClient());\n```\nIf you do not provide a HttpClient, one will be created automatically — in that case, remember to dispose the client properly.\n\n### 🚀 Create a Payment in under a minute\nHere’s a quick example of how to create an **iDEAL** payment for €100:\n```csharp\nusing IPaymentClient paymentClient = new PaymentClient(\"{yourApiKey}\", new HttpClient());\n\nvar paymentRequest = new PaymentRequest {\n    Amount = new Amount(Currency.EUR, 100.00m),\n    Description = \"The .NET library makes creating payments so easy!\",\n    RedirectUrl = \"https://github.com/Viincenttt/MollieApi\",\n    Method = PaymentMethod.Ideal\n};\n\nPaymentResponse paymentResponse = await paymentClient.CreatePaymentAsync(paymentRequest);\n// Redirect your user to the checkout URL\nstring checkoutUrl = paymentResponse.Links.Checkout.Href;\n```\n\n### Webhooks\nMollie offers two different webhook systems:\n- [Classic Webhooks](https://docs.mollie.com/reference/webhooks)\n- [Next-gen Webhooks (beta)](https://docs.mollie.com/reference/webhooks-new)\nBoth systems are supported through the Mollie.Api.AspNet NuGet package included in this library.\n\nInstall via NuGet:\n```bash\nInstall-Package Mollie.Api.AspNet \n```\n\nThe Mollie.Api.AspNet NuGet package has built in attributes that automatically parse and validate incoming objects in your ASP.NET application. For example:\n```C#\n[HttpPost(\"full/specific\")]\n[ServiceFilter(typeof(MollieSignatureFilter))]\npublic Task<ActionResult> WebhookWithSpecificType([FromMollieWebhook] FullWebhookEventResponse<PaymentLinkResponse> data) {\n    return Task.FromResult<ActionResult>(Ok());\n}\n```\n\nFor more information about webhooks, take a look at the [full webhook documentation](https://github.com/Viincenttt/MollieApi/wiki/01.-Getting-started#webhooks) on the Wiki page.\n\n### 🧪 Blazor Example Project\nWant to see the library in action? Check out the full-featured .NET Blazor example project, which demonstrates real-world usage of several APIs:\n* Payments\n* Payment links\n* Orders\n* Customers\n* Mandates\n* Subscriptions\n* Payment Methods\n* Terminals\n* Webhooks\n\n🔗 [View the Example Project on GitHub](https://github.com/Viincenttt/MollieApi/tree/development/samples/Mollie.WebApplication.Blazor)\n> It’s a great starting point if you’re new to Mollie or want to explore advanced scenarios like multi-step checkouts or managing recurring payments.\n\n---\n\n## 📦 Supported API's\nThis library currently supports the following API's:\n- [Payment API](https://github.com/Viincenttt/MollieApi/wiki/02.-Payment-API)\n- [PaymentMethod API](https://github.com/Viincenttt/MollieApi/wiki/03.-Payment-method-API)\n- [PaymentLink API](https://github.com/Viincenttt/MollieApi/wiki/14.-Payment-link-Api)\n- [Customer API](https://github.com/Viincenttt/MollieApi/wiki/05.-Customer-API)\n- [Mandate API](https://github.com/Viincenttt/MollieApi/wiki/06.-Mandate-API)\n- [Subscription API](https://github.com/Viincenttt/MollieApi/wiki/07.-Subscription-API)\n- [Refund API](https://github.com/Viincenttt/MollieApi/wiki/04.-Refund-API)\n- [Connect API](https://github.com/Viincenttt/MollieApi/wiki/10.-Connect-Api)\n- Chargeback API (documentation coming soon)\n- Invoice API (documentation coming soon)\n- Permissions API (documentation coming soon)\n- [Profile API](https://github.com/Viincenttt/MollieApi/wiki/11.-Profile-Api)\n- [Organizations API](https://github.com/Viincenttt/MollieApi/wiki/09.-Organization-API)\n- [Order API](https://github.com/Viincenttt/MollieApi/wiki/08.-Order-API)\n- [Capture API](https://github.com/Viincenttt/MollieApi/wiki/12.-Captures-API)\n- [Onboarding API](https://github.com/Viincenttt/MollieApi/wiki/13.-Onboarding-Api)\n- [Balances API](https://github.com/Viincenttt/MollieApi/wiki/15.-Balances-Api)\n- Terminal API (documentation coming soon)\n- ClientLink API (documentation coming soon)\n- Wallet API (documentation coming soon)\n- Client API (documentation coming soon)\n- Capability API (documentation coming soon)\n- [Webhooks API](https://github.com/Viincenttt/MollieApi/wiki/19.-Webhook-Api) \n- [WebhooksEvents API](https://github.com/Viincenttt/MollieApi/wiki/20.-Webhook-Api)\n- [Balance transfer API](https://github.com/Viincenttt/MollieApi/wiki/21.-Balance-transfer-Api) \n\n---\n\n## 🤝 Contributions\nSpotted a bug or want to add a new feature? Contributions are welcome! Please target the latest `development` branch and include a clear description of your changes.\n\n---\n\n## ✅ Supported .NET Versions\nThis library targets [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0), making it compatible with a wide range of platforms:\n| .NET implementation  | Version support |\n| ------------- | ------------- |\n| .NET and .NET Core | 2.0, 2.1, 2.2, 3.0, 3.1, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 |\n| .NET Framework  | 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1  |\n| Mono | 5.4, 6.4  |\n| Universal Windows Platform | 10.0.16299, TBD |\n| Xamarin.iOS | 10.14, 12.16 |\n| Xamarin.Mac | 3.8, 5.16 |\n| Xamarin.Android | 8.0, 10.0 |\n| Unity | 2018.1 |\n\n> ⚠️ Note: This library uses the required keyword in some model classes. Your project must target **C# 11 or higher**.\n\n"
  },
  {
    "path": "mollie.publickey.txt",
    "content": "002400000480000014020000060200000024000052534131001000000100010015769730260dcfc1911c5d3c54057de5037b99dc84a12ae40ee60b78a7068d46bf356eb20795f859c31dee9603c911573b823aac81d589b4f6bd3f7ad10635d1f7a13c0fb37a679e2ee582408c059fc644c3d49da3023adba8096cfd8921db2c159d0e0ee9b1230cd032ca5366bbb249c0aa9a1843b1769d9732a00e07575c47c525d9a76df3f25c0bd44cdf3a8e98f3618dd9d2d4c332756e7f374cae03e3b1f932e5b2a7cc2042a8b526033b20ffcaa38cbfc29d0c675678d09b2f9edef74767607ebffef5046c3b62e70427754a2fb8790d387dbd0acbba7f587f55716ff50099e9252511eec42260cf39155e1efaea273e5ddcd3051b08c089fbf577cc8c33da86c908d49067cf40f90fbbad68a42dfccc72fec62b43815877c6732e0c7957d044e167bc2848852f8eaa5e1772f735fb9694ab74c9f2ea1fc49de061e3531d6d13dcaad4256f9497cf2e1383d9134d007b058668b1bab9173e146d064a5231eec739a12462a0fbef1a46e2b812a24c6bbc746227bdb390bfed1e0e3d54aecd55ea42249f197664ab20f35a597b53a7f0dc82b03f8ac1be78cab67830a67e30bb514e426355f172d9d56f02bf6d6c4c61cbc650dcbcff74ee129e56ecfdae9bdfd544f55aaee2eb7971b959990f5907ccbeeb14c96817b3d9609e7a529c41560a02a42145bf130be56c047f2bef0eee6f47a6ca8e2c863bda70674c2f43a3\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/App.razor",
    "content": "﻿<Router AppAssembly=\"@typeof(App).Assembly\">\n    <Found Context=\"routeData\">\n        <RouteView RouteData=\"@routeData\" DefaultLayout=\"@typeof(MainLayout)\"/>\n        <FocusOnNavigate RouteData=\"@routeData\" Selector=\"h1\"/>\n    </Found>\n    <NotFound>\n        <PageTitle>Not found</PageTitle>\n        <LayoutView Layout=\"@typeof(MainLayout)\">\n            <p role=\"alert\">Sorry, there's nothing at this address.</p>\n        </LayoutView>\n    </NotFound>\n</Router>"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Framework/StaticStringListBuilder.cs",
    "content": "﻿using System.Reflection;\n\nnamespace Mollie.WebApplication.Blazor.Framework;\n\npublic static class StaticStringListBuilder {\n    public static IEnumerable<string> GetStaticStringList(Type type) {\n        foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Static | BindingFlags.Public)) {\n            string? value = fieldInfo.GetValue(null)?.ToString();\n            if (value != null) {\n                yield return value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Framework/Validators/DecimalPlacesAttribute.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing System.Globalization;\n\nnamespace Mollie.WebApplication.Blazor.Framework.Validators;\n\npublic class DecimalPlacesAttribute : ValidationAttribute {\n    private int _decimalPlaces { get; }\n\n    public DecimalPlacesAttribute(int decimalPlaces) {\n        _decimalPlaces = decimalPlaces;\n    }\n\n    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) {\n        if (value == null) {\n            return new ValidationResult(\"Value is null\");\n        }\n\n        decimal amount = (decimal)value;\n        string text = amount.ToString(CultureInfo.InvariantCulture);\n        int dotIndex = text.IndexOf('.');\n        var decimals = text.Length - dotIndex - 1;\n        var places = _decimalPlaces switch\n        {\n            0 => \"without decimal places\",\n            1 => \"with one decimal place\",\n            _ => $\"with {_decimalPlaces} decimal places\"\n        };\n        return dotIndex < 0 || dotIndex != text.LastIndexOf('.') || decimals != _decimalPlaces\n            ? new ValidationResult(ErrorMessage ?? $\"Please enter an amount {places}\")\n            : ValidationResult.Success;\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Framework/Validators/StaticStringListAttribute.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing System.Reflection;\n\nnamespace Mollie.WebApplication.Blazor.Framework.Validators;\n\npublic class StaticStringListAttribute : ValidationAttribute {\n    private readonly Type _staticClass;\n\n    public StaticStringListAttribute(Type staticClass) {\n        _staticClass = staticClass;\n    }\n\n    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) {\n        IEnumerable<string?> validValues = _staticClass\n            .GetFields(BindingFlags.Static | BindingFlags.Public)\n            .Select(x => x.GetValue(null)?.ToString());\n\n        if (validValues.Contains(value)) {\n            return ValidationResult.Success;\n        }\n\n        return new ValidationResult($\"The value \\\"{value}\\\" is invalid\");\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Customer/CreateCustomerModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace Mollie.WebApplication.Blazor.Models.Customer;\n\npublic class CreateCustomerModel {\n    [Required]\n    public required string Name { get; set; }\n\n    [EmailAddress]\n    public required string Email { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Mandate/CreateMandateModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace Mollie.WebApplication.Blazor.Models.Mandate;\n\npublic class CreateMandateModel {\n    [Required]\n    public required string ConsumerName { get; set; }\n\n    [Required]\n    public required string ConsumerAccount { get; set; }\n\n    [Required]\n    public required string ConsumerBic { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Order/CreateOrderBillingAddressModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace Mollie.WebApplication.Blazor.Models.Order;\n\npublic class CreateOrderBillingAddressModel {\n    [Required]\n    public required string GivenName { get; set; }\n\n    [Required]\n    public required string FamilyName { get; set; }\n\n    [Required]\n    [EmailAddress]\n    public required string Email { get; set; }\n\n    [Required]\n    public required string StreetAndNumber { get; set; }\n\n    [Required]\n    public required string City { get; set; }\n\n    [Required]\n    [MaxLength(2)]\n    public required string Country { get; set; }\n\n    [Required]\n    public required string PostalCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Order/CreateOrderLineModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Mollie.WebApplication.Blazor.Framework.Validators;\n\nnamespace Mollie.WebApplication.Blazor.Models.Order;\n\npublic class CreateOrderLineModel {\n    [Required]\n    public string Name { get; set; } = string.Empty;\n\n    [Required]\n    [Range(1, 100, ErrorMessage = \"Please enter a quantity between 0.01 and 1000\")]\n    public int Quantity { get; set; }\n\n    [Required]\n    [Range(0.01, 10000, ErrorMessage = \"Please enter a unit price between 0.01 and 10000\")]\n    [DecimalPlaces(2)]\n    public decimal UnitPrice { get; set; }\n\n    public decimal TotalAmount { get; set; }\n\n    [Range(0.01, 100, ErrorMessage = \"Please enter a vat rate between 0.01 and 100\")]\n    [DecimalPlaces(2)]\n    public decimal VatRate { get; set; }\n    public decimal VatAmount { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Order/CreateOrderModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Mollie.Api.Models;\nusing Mollie.WebApplication.Blazor.Framework.Validators;\n\nnamespace Mollie.WebApplication.Blazor.Models.Order;\n\npublic class CreateOrderModel {\n    [Required]\n    public string? OrderNumber { get; set; }\n\n    [Required]\n    public string? Locale { get; set; }\n\n    [Required]\n    public decimal? Amount { get; set; }\n\n    [Required]\n    [StaticStringList(typeof(Currency))]\n    public required string Currency { get; set; }\n\n    [Required]\n    [Url]\n    public required string RedirectUrl { get; set; }\n\n    public List<CreateOrderLineModel>? Lines { get; set; } = new();\n\n    public required CreateOrderBillingAddressModel BillingAddress { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Payment/CreatePaymentModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Mollie.Api.Models;\nusing Mollie.WebApplication.Blazor.Framework.Validators;\n\nnamespace Mollie.WebApplication.Blazor.Models.Payment;\n\npublic class CreatePaymentModel {\n    [Required]\n    [Range(0.01, 1000, ErrorMessage = \"Please enter an amount between 0.01 and 1000\")]\n    [DecimalPlaces(2)]\n    public required decimal Amount { get; set; }\n\n    [Required]\n    [StaticStringList(typeof(Currency))]\n    public required string Currency { get; set; }\n\n    [Required]\n    [Url]\n    public required string RedirectUrl { get; set; }\n\n    [Url]\n    public string? WebhookUrl { get; set; }\n\n    [Required]\n    public required string Description { get; set; }\n\n    [Required]\n    public required string SequenceType { get; set; }\n\n    public string? CustomerId { get; set; }\n\n    public string? MandateId { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/PaymentLink/CreatePaymentModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Mollie.Api.Models;\nusing Mollie.WebApplication.Blazor.Framework.Validators;\n\nnamespace Mollie.WebApplication.Blazor.Models.PaymentLink;\n\npublic class CreatePaymentLinkModel {\n    [Required]\n    [Range(0.01, 1000, ErrorMessage = \"Please enter an amount between 0.01 and 1000\")]\n    [DecimalPlaces(2)]\n    public required decimal Amount { get; set; }\n\n    [Required]\n    [StaticStringList(typeof(Currency))]\n    public required string Currency { get; set; }\n\n    [Required]\n    [Url]\n    public required string RedirectUrl { get; set; }\n\n    [Url]\n    public string? WebhookUrl { get; set; }\n\n    [Required]\n    public required string Description { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Subscription/CreateSubscriptionModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Mollie.Api.Models;\nusing Mollie.WebApplication.Blazor.Framework.Validators;\n\nnamespace Mollie.WebApplication.Blazor.Models.Subscription;\n\npublic class CreateSubscriptionModel {\n    [Required]\n    [Range(0.01, 1000, ErrorMessage = \"Please enter an amount between 0.01 and 1000\")]\n    [DecimalPlaces(2)]\n    public required decimal Amount { get; set; }\n\n    [Required]\n    [StaticStringList(typeof(Currency))]\n    public required string Currency { get; set; }\n\n    [Range(1, 10)]\n    public int? Times { get; set; }\n\n    [Range(1, 20, ErrorMessage = \"Please enter a interval number between 1 and 20\")]\n    [Required]\n    [Display(Name = \"Interval amount\")]\n    public int? IntervalAmount { get; set; }\n\n    [Required]\n    [Display(Name = \"Interval period\")]\n    public required IntervalPeriod IntervalPeriod { get; set; }\n\n    [Required]\n    public required string Description { get; set; }\n\n    public string? MandateId { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Subscription/IntervalPeriod.cs",
    "content": "﻿namespace Mollie.WebApplication.Blazor.Models.Subscription;\n\npublic enum IntervalPeriod {\n    Months,\n    Weeks,\n    Days\n}"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Models/Webhook/CreateWebhookModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace Mollie.WebApplication.Blazor.Models.Webhook;\n\npublic class CreateWebhookModel {\n    [Required]\n    public required string Name { get; set; }\n\n    [Required]\n    [Url]\n    public required string Url { get; set; }\n\n    public required List<string> EventTypes { get; set; } = new();\n\n    public bool Testmode { get; set; } = true;\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Mollie.WebApplication.Blazor.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n    <PropertyGroup>\n        <TargetFramework>net10.0</TargetFramework>\n        <Nullable>enable</Nullable>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <UserSecretsId>51758f49-d7ec-4044-8cd9-95cf49d0f3cf</UserSecretsId>\n    </PropertyGroup>\n\n    <ItemGroup>\n      <ProjectReference Include=\"..\\..\\src\\Mollie.Api.AspNet\\Mollie.Api.AspNet.csproj\" />\n      <ProjectReference Include=\"..\\..\\src\\Mollie.Api\\Mollie.Api.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Customer/Create.razor",
    "content": "﻿@page \"/customer/create\"\n\n@using Mollie.WebApplication.Blazor.Models.Customer\n@using Mollie.Api.Client\n@using Mollie.Api.Models.Customer.Request\n\n@inject ICustomerClient CustomerClient\n@inject NavigationManager NavigationManager\n\n<h3>Create new customer</h3>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n<EditForm Model=\"_customer\" OnValidSubmit=\"@OnSave\" class=\"col-md-6\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <div class=\"form-group\">\n        <label for=\"name\">Name</label>\n        <InputText\n            id=\"name\"\n            class=\"form-control\"\n            @bind-Value=\"_customer.Name\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"email\">E-mail</label>\n        <InputText\n            id=\"email\"\n            class=\"form-control\"\n            @bind-Value=\"_customer.Email\">\n        </InputText>\n    </div>\n\n    <input type=\"submit\" name=\"Save\" value=\"Save\" class=\"btn btn-primary mt-2\"/>\n</EditForm>\n\n@code {\n    private MollieApiException? _apiException;\n\n    private CreateCustomerModel _customer = new() {\n        Name = \"Customer name\",\n        Email = \"customer@customer.customer\"\n    };\n\n    private async Task OnSave() {\n        try {\n            _apiException = null;\n\n            await CustomerClient.CreateCustomerAsync(new CustomerRequest() {\n                Name = _customer.Name,\n                Email = _customer.Email\n            });\n\n            NavigationManager.NavigateTo(\"/customer/overview\");\n        }\n        catch (MollieApiException e) {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Customer/Overview.razor",
    "content": "﻿@page \"/customer/overview\"\n@using Mollie.Api.Models.Customer.Response\n@using Mollie.Api.Models.List.Response\n\n@inject ICustomerClient CustomerClient\n\n<h3>Customers</h3>\n\n@if (_customers == null) {\n    <p>Loading...</p>\n}\nelse {\n    <div class=\"clearfix\">\n        <a href=\"/customer/create\" class=\"btn btn-primary float-right\">Create new customer</a>\n    </div>\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Name</th>\n            <th scope=\"col\">Email</th>\n            <th scope=\"col\">Locale</th>\n            <th scope=\"col\">Actions</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (CustomerResponse customer in _customers.Items) {\n            <tr>\n                <td>@customer.Id</td>\n                <td>@customer.CreatedAt</td>\n                <td>@customer.Name</td>\n                <td><a href=\"mailto:@customer.Email\">@customer.Email</a></td>\n                <td>@customer.Locale</td>\n                <td>\n                    <a href=\"/customer/@customer.Id/mandate/overview\" class=\"btn btn-outline-secondary\">View mandates</a>\n                    <a href=\"/customer/@customer.Id/subscription/overview\" class=\"btn btn-outline-secondary\">View subscriptions</a>\n                </td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_customers.Links.Previous\"\n        Next=\"_customers.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<CustomerResponse>? _customers;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _customers = await CustomerClient.GetCustomerListAsync();\n        }\n        else {\n            _customers = await CustomerClient.GetCustomerListAsync(new UrlObjectLink<ListResponse<CustomerResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Error.cshtml",
    "content": "﻿@page\n@model Mollie.WebApplication.Blazor.Pages.ErrorModel\n\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"/>\n    <title>Error</title>\n    <link href=\"~/css/bootstrap/bootstrap.min.css\" rel=\"stylesheet\"/>\n    <link href=\"~/css/site.css\" rel=\"stylesheet\" asp-append-version=\"true\"/>\n</head>\n\n<body>\n<div class=\"main\">\n    <div class=\"content px-4\">\n        <h1 class=\"text-danger\">Error.</h1>\n        <h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n        @if (Model.ShowRequestId) {\n            <p>\n                <strong>Request ID:</strong> <code>@Model.RequestId</code>\n            </p>\n        }\n\n        <h3>Development Mode</h3>\n        <p>\n            Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.\n        </p>\n        <p>\n            <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n            It can result in displaying sensitive information from exceptions to end users.\n            For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n            and restarting the app.\n        </p>\n    </div>\n</div>\n</body>\n\n</html>"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Error.cshtml.cs",
    "content": "﻿using System.Diagnostics;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.AspNetCore.Mvc.RazorPages;\n\nnamespace Mollie.WebApplication.Blazor.Pages;\n\n[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n[IgnoreAntiforgeryToken]\npublic class ErrorModel : PageModel {\n    public string? RequestId { get; set; }\n\n    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n\n    public void OnGet() {\n        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Index.razor",
    "content": "﻿@page \"/\"\n\n<PageTitle>Mollie Example Project</PageTitle>\n\n<section class=\"jumbotron text-center\">\n    <div class=\"container\">\n        <h1 class=\"jumbotron-heading\">Mollie API Demo application</h1>\n        <p class=\"lead text-muted\">\n            Welcome to the Mollie API demo application. This is a sample application that demonstrates how to create payments, customers, subscriptions and much more.\n        </p>\n        <p>\n            <a href=\"/payment/create\" class=\"btn btn-primary my-2\">Create new payment</a>\n            <a href=\"/order/create\" class=\"btn btn-primary my-2\">Create new order</a>\n        </p>\n    </div>\n</section>"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Mandate/Create.razor",
    "content": "﻿@page \"/customer/{customerId}/mandate/create\"\n@using Mollie.WebApplication.Blazor.Models.Mandate\n@using Mollie.Api.Client\n@using Mollie.Api.Models.Mandate.Request\n@using Mollie.Api.Models.Mandate.Request.PaymentSpecificParameters\n\n@inject IMandateClient MandateClient\n@inject NavigationManager NavigationManager\n\n<h3>Create new mandate</h3>\n\n<div class=\"alert alert-info\">\n    <p>\n        A mandate is used to get started with recurring payments. A mandate is similar to a regular payment, but the customer is shown information about your organization,\n        and the customer needs to complete the payment with the account or card that will be used for recurring charges in the future.\n    </p>\n    <p>\n        After the first payment is completed succesfully, the customer’s account or card will immediately be chargeable on-demand, or periodically through subscriptions.\n    </p>\n</div>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n<EditForm Model=\"_mandate\" OnValidSubmit=\"@OnSave\" class=\"col-md-6\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <div class=\"form-group\">\n        <label for=\"consumer-name\">Consumer name</label>\n        <InputText\n            id=\"consumer-name\"\n            class=\"form-control\"\n            @bind-Value=\"_mandate.ConsumerName\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"consumer-account\">Consumer account</label>\n        <InputText\n            id=\"consumer-account\"\n            class=\"form-control\"\n            @bind-Value=\"_mandate.ConsumerAccount\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"consumer-bic\">Consumer BIC</label>\n        <InputText\n            id=\"consumer-bic\"\n            class=\"form-control\"\n            @bind-Value=\"_mandate.ConsumerBic\">\n        </InputText>\n    </div>\n\n    <input type=\"submit\" name=\"Save\" value=\"Save\" class=\"btn btn-primary mt-2\"/>\n</EditForm>\n\n@code {\n    private MollieApiException? _apiException;\n\n    [Parameter]\n    public required string CustomerId { get; set; }\n\n    private CreateMandateModel _mandate = new() {\n        ConsumerName = \"Consumer name\",\n        ConsumerAccount = string.Empty,\n        ConsumerBic = string.Empty\n    };\n\n    private async Task OnSave() {\n        try {\n            _apiException = null;\n\n            await MandateClient.CreateMandateAsync(CustomerId, new SepaDirectDebitMandateRequest {\n                Method = PaymentMethod.DirectDebit,\n                ConsumerName = _mandate.ConsumerName,\n                ConsumerAccount = _mandate.ConsumerAccount,\n                ConsumerBic = _mandate.ConsumerBic\n            });\n\n            NavigationManager.NavigateTo($\"/customer/{CustomerId}/mandate/overview\");\n        }\n        catch (MollieApiException e) {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Mandate/Overview.razor",
    "content": "﻿@page \"/customer/{customerId}/mandate/overview\"\n@using Mollie.Api.Models.List.Response\n@using Mollie.Api.Models.Mandate.Response\n\n@inject IMandateClient MandateClient\n\n<h3>Mandates</h3>\n\n@if (_mandates == null) {\n    <p>Loading...</p>\n}\nelse {\n    <div class=\"clearfix\">\n        <a href=\"/customer/@CustomerId/mandate/create\" class=\"btn btn-primary float-right\">Create new mandate</a>\n    </div>\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Status</th>\n            <th scope=\"col\">Actions</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (MandateResponse mandate in _mandates.Items) {\n            <tr>\n                <td>@mandate.Id</td>\n                <td>@mandate.CreatedAt</td>\n                <td>@mandate.Status</td>\n                <td>&nbsp;</td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_mandates.Links.Previous\"\n        Next=\"_mandates.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    public required string CustomerId { get; set; }\n\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<MandateResponse>? _mandates;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _mandates = await MandateClient.GetMandateListAsync(CustomerId);\n        }\n        else {\n            _mandates = await MandateClient.GetMandateListAsync(new UrlObjectLink<ListResponse<MandateResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Order/Components/OrderAddressEditor.razor",
    "content": "﻿@using Mollie.WebApplication.Blazor.Models.Order\n\n<div class=\"form-group\">\n    <label for=\"given-name\">Given name</label>\n    <InputText\n        id=\"given-name\"\n        class=\"form-control\"\n        @bind-Value=\"Address.GivenName\">\n    </InputText>\n</div>\n\n<div class=\"form-group\">\n    <label for=\"family-name\">Family name</label>\n    <InputText\n        id=\"family-name\"\n        class=\"form-control\"\n        @bind-Value=\"Address.FamilyName\">\n    </InputText>\n</div>\n\n<div class=\"form-group\">\n    <label for=\"email\">E-mail</label>\n    <InputText\n        id=\"email\"\n        class=\"form-control\"\n        @bind-Value=\"Address.Email\">\n    </InputText>\n</div>\n\n<div class=\"form-group\">\n    <label for=\"street-and-number\">Street and number</label>\n    <InputText\n        id=\"street-and-number\"\n        class=\"form-control\"\n        @bind-Value=\"Address.StreetAndNumber\">\n    </InputText>\n</div>\n\n<div class=\"form-group\">\n    <label for=\"postal-code\">Postal code</label>\n    <InputText\n        id=\"postal-code\"\n        class=\"form-control\"\n        @bind-Value=\"Address.PostalCode\">\n    </InputText>\n</div>\n\n<div class=\"form-group\">\n    <label for=\"city\">City</label>\n    <InputText\n        id=\"city\"\n        class=\"form-control\"\n        @bind-Value=\"Address.City\">\n    </InputText>\n</div>\n\n<div class=\"form-group\">\n    <label for=\"country\">Country</label>\n    <InputText\n        id=\"country\"\n        class=\"form-control\"\n        maxlength=\"2\"\n        @bind-Value=\"Address.Country\">\n    </InputText>\n</div>\n\n@code {\n    [Parameter, EditorRequired]\n    public required CreateOrderBillingAddressModel Address { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Order/Components/OrderLineEditor.razor",
    "content": "﻿@using Mollie.WebApplication.Blazor.Models.Order\n\n<EditForm Model=\"_newOrderLineModel\" OnValidSubmit=\"@OnAddOrderLine\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <table class=\"table table-striped\">\n        <thead>\n            <tr>\n                <th scope=\"col\">Name</th>\n                <th scope=\"col\">Quantity</th>\n                <th scope=\"col\">Unit price</th>\n                <th scope=\"col\">Total amount</th>\n                <th scope=\"col\">Vat rate</th>\n                <th scope=\"col\">Vat amount</th>\n                <th scope=\"col\">Actions</th>\n            </tr>\n        </thead>\n        <tbody>\n            @foreach (CreateOrderLineModel orderLine in OrderLines) {\n                <tr>\n                    <td>@orderLine.Name</td>\n                    <td>@orderLine.Quantity</td>\n                    <td>€ @orderLine.UnitPrice</td>\n                    <td>€ @orderLine.TotalAmount</td>\n                    <td>@orderLine.VatRate %</td>\n                    <td>€ @orderLine.VatAmount</td>\n                    <td>\n                        <button\n                            class=\"btn btn-outline-secondary\"\n                            type=\"button\"\n                            @onclick=\"() => OnRemoveOrderLine(orderLine)\">\n                            Remove\n                        </button>\n                    </td>\n                </tr>\n            }\n            <tr>\n                <td>\n                    <InputText\n                        id=\"new-order-line-name\"\n                        class=\"form-control\"\n                        placeholder=\"Name\"\n                        @bind-Value=\"_newOrderLineModel.Name\">\n                    </InputText>\n                </td>\n                <td>\n                    <InputNumber\n                        id=\"new-order-line-quantity\"\n                        class=\"form-control\"\n                        placeholder=\"quantity\"\n                        @bind-Value=\"_newOrderLineModel.Quantity\">\n                    </InputNumber>\n                </td>\n                <td>\n                    <InputNumber\n                        id=\"new-order-line-unit-price\"\n                        class=\"form-control\"\n                        placeholder=\"Unit price\"\n                        @bind-Value=\"_newOrderLineModel.UnitPrice\">\n                    </InputNumber>\n                </td>\n                <td></td>\n                <td>\n                    <InputNumber\n                        id=\"new-order-line-vat-rate\"\n                        class=\"form-control\"\n                        placeholder=\"Vat rate\"\n                        @bind-Value=\"_newOrderLineModel.VatRate\">\n                    </InputNumber>\n                </td>\n                <td></td>\n                <td>\n                    <button name=\"add-order-line\" class=\"btn btn-outline-secondary\" type=\"submit\">Add</button>\n                </td>\n            </tr>\n        </tbody>\n    </table>\n</EditForm>\n\n\n@code {\n    [Parameter, EditorRequired]\n    public required IList<CreateOrderLineModel> OrderLines { get; set; }\n\n    private CreateOrderLineModel _newOrderLineModel = new ();\n\n    private void OnAddOrderLine() {\n        decimal totalAmount = _newOrderLineModel.Quantity * _newOrderLineModel.UnitPrice;\n        decimal vatAmount = (_newOrderLineModel.VatRate / (100 + _newOrderLineModel.VatRate)) * totalAmount;\n        _newOrderLineModel.VatAmount = Math.Round(vatAmount, 2);\n        _newOrderLineModel.TotalAmount = totalAmount;\n        OrderLines.Add(_newOrderLineModel);\n\n        _newOrderLineModel = new CreateOrderLineModel();\n    }\n\n    private void OnRemoveOrderLine(CreateOrderLineModel orderLine) {\n        OrderLines.Remove(orderLine);\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Order/Create.razor",
    "content": "﻿@page \"/order/create\"\n\n@using Mollie.WebApplication.Blazor.Pages.Order.Components\n@using Mollie.WebApplication.Blazor.Models.Order\n@using System.Globalization\n@using Mollie.Api.Client\n@using Mollie.Api.Models.Order.Request\n\n@inject IOrderClient OrderClient\n@inject NavigationManager NavigationManager\n\n<h3>Create new order</h3>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n<EditForm Model=\"_order\" OnValidSubmit=\"@OnSave\" class=\"col-md-6\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <div class=\"form-group\">\n        <label for=\"order-number\">Order number</label>\n        <InputText\n            id=\"order-number\"\n            class=\"form-control\"\n            @bind-Value=\"_order.OrderNumber\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"locale\">Locale</label>\n        <InputSelect\n            id=\"locale\"\n            class=\"form-control\"\n            @bind-Value=\"_order.Locale\">\n            @foreach (string locale in StaticStringListBuilder.GetStaticStringList(typeof(Locale))) {\n                <option value=\"@locale\">@locale</option>\n            }\n        </InputSelect>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"currency\">Currency</label>\n        <InputSelect\n            id=\"currency\"\n            class=\"form-control\"\n            @bind-Value=\"_order.Currency\">\n            @foreach (string currency in StaticStringListBuilder.GetStaticStringList(typeof(Currency))) {\n                <option value=\"@currency\">@currency</option>\n            }\n        </InputSelect>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"redirect-url\">Redirect url</label>\n        <InputText\n            id=\"redirect-url\"\n            class=\"form-control\"\n            @bind-Value=\"_order.RedirectUrl\">\n        </InputText>\n    </div>\n\n    <h5 class=\"mt-3\">Billing address</h5>\n    <OrderAddressEditor Address=\"_order.BillingAddress\"></OrderAddressEditor>\n\n    <h5 class=\"mt-3\">Order lines</h5>\n    <OrderLineEditor OrderLines=\"_order.Lines\"></OrderLineEditor>\n\n    <input type=\"submit\" name=\"Save\" value=\"Save\" class=\"btn btn-primary mt-2\"/>\n</EditForm>\n\n@code {\n    private MollieApiException? _apiException;\n\n    private readonly CreateOrderModel _order = new() {\n        OrderNumber = \"Order number\",\n        Locale = Locale.nl_NL,\n        Amount = 100m,\n        Currency = \"EUR\",\n        RedirectUrl = \"https://www.mollie.com/\",\n        Lines = new List<CreateOrderLineModel> {\n            new() {\n                Name = \"Chocolates\",\n                UnitPrice = 100.00m,\n                Quantity = 1,\n                TotalAmount = 100.00m,\n                VatRate = 21.00m,\n                VatAmount = 17.36m\n            }\n        },\n        BillingAddress = new CreateOrderBillingAddressModel {\n            City = \"Amsterdam\",\n            Country = \"NL\",\n            Email = \"customer@customer.customer\",\n            FamilyName = \"Mollie\",\n            GivenName = \"Mollie\",\n            PostalCode = \"1015 CW\",\n            StreetAndNumber = \"Keizersgracht 126\"\n        }\n    };\n\n    private async Task OnSave() {\n        try {\n            _apiException = null;\n\n            await OrderClient.CreateOrderAsync(new OrderRequest {\n                OrderNumber = _order.OrderNumber!,\n                Locale = _order.Locale!,\n                Amount = new Amount(_order.Currency, _order.Lines!.Sum(lines => lines.TotalAmount)),\n                RedirectUrl = _order.RedirectUrl,\n                BillingAddress = new OrderAddressDetails {\n                    GivenName = _order.BillingAddress.GivenName,\n                    FamilyName = _order.BillingAddress.FamilyName,\n                    Email = _order.BillingAddress.Email,\n                    StreetAndNumber = _order.BillingAddress.StreetAndNumber,\n                    PostalCode = _order.BillingAddress.PostalCode,\n                    City = _order.BillingAddress.City,\n                    Country = _order.BillingAddress.Country\n                },\n                Lines = _order.Lines!.Select(line => new OrderLineRequest {\n                    Name = line.Name,\n                    Quantity = line.Quantity,\n                    UnitPrice = new Amount(_order.Currency, line.UnitPrice),\n                    TotalAmount = new Amount(_order.Currency, line.TotalAmount),\n                    VatRate = line.VatRate.ToString(CultureInfo.InvariantCulture),\n                    VatAmount = new Amount(_order.Currency, line.VatAmount)\n                })\n            });\n\n            NavigationManager.NavigateTo(\"/order/overview\");\n        }\n        catch (MollieApiException e) {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Order/Overview.razor",
    "content": "﻿@page \"/order/overview\"\n@using Mollie.Api.Models.Order.Response\n@using Mollie.Api.Models.List.Response\n\n@inject IOrderClient OrderClient\n\n<h3>Orders</h3>\n\n@if (_orders == null) {\n    <p>Loading...</p>\n}\nelse {\n    <div class=\"clearfix\">\n        <a href=\"/order/create\" class=\"btn btn-primary float-right\">Create new order</a>\n    </div>\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Amount</th>\n            <th scope=\"col\">Status</th>\n            <th scope=\"col\">Method</th>\n            <th scope=\"col\">Metadata</th>\n            <th scope=\"col\">Actions</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (OrderResponse order in _orders.Items) {\n            <tr>\n                <td>@order.Id</td>\n                <td>@order.CreatedAt</td>\n                <td>@order.Amount.ToString()</td>\n                <td>@order.Status</td>\n                <td>@order.Method</td>\n                <td>@order.Metadata</td>\n                <td>\n                    @if (order.Status == OrderStatus.Created && order.Links.Checkout != null) {\n                        <a href=\"@order.Links.Checkout.Href\" class=\"btn btn-outline-secondary\" target=\"_blank\">Pay</a>\n                    }\n                </td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_orders.Links.Previous\"\n        Next=\"_orders.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<OrderResponse>? _orders;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _orders = await OrderClient.GetOrderListAsync();\n        }\n        else {\n            _orders = await OrderClient.GetOrderListAsync(new UrlObjectLink<ListResponse<OrderResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Payment/Create.razor",
    "content": "﻿@page \"/payment/create\"\n\n@using Mollie.Api.Models.Payment.Request\n@using Mollie.WebApplication.Blazor.Models.Payment\n@using Mollie.Api.Client\n\n@inject IPaymentClient PaymentClient\n@inject NavigationManager NavigationManager\n\n<h3>Create new payment</h3>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n<EditForm Model=\"_model\" OnValidSubmit=\"@OnSave\" class=\"col-md-6\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <div class=\"form-group\">\n        <label for=\"amount\">Amount</label>\n        <InputNumber\n            id=\"amount\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Amount\">\n        </InputNumber>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"currency\">Currency</label>\n        <InputSelect\n            id=\"currency\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Currency\">\n            @foreach (string currency in StaticStringListBuilder.GetStaticStringList(typeof(Currency))) {\n                <option value=\"@currency\">@currency</option>\n            }\n        </InputSelect>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"redirect-url\">Redirect url</label>\n        <InputText\n            id=\"redirect-url\"\n            class=\"form-control\"\n            @bind-Value=\"_model.RedirectUrl\">\n        </InputText>\n    </div>\n\n        <div class=\"form-group\">\n            <label for=\"webhook-url\">Webhook url</label>\n            <InputText\n                id=\"webhook-url\"\n                class=\"form-control\"\n                @bind-Value=\"_model.WebhookUrl\">\n            </InputText>\n        </div>\n\n    <div class=\"form-group\">\n        <label for=\"description\">Description</label>\n        <InputText\n            id=\"description\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Description\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"sequence-type\">Sequence type</label>\n        <InputSelect\n            id=\"sequence-type\"\n            class=\"form-control\"\n            @bind-Value=\"_model.SequenceType\">\n            @foreach (string sequenceType in StaticStringListBuilder.GetStaticStringList(typeof(SequenceType))) {\n                <option value=\"@sequenceType\">@sequenceType</option>\n            }\n        </InputSelect>\n    </div>\n\n    @if (_model.SequenceType == SequenceType.First || _model.SequenceType == SequenceType.Recurring)\n    {\n        <div class=\"form-group\">\n            <label for=\"customer\">Customer</label>\n            <InputText\n                id=\"customer\"\n                class=\"form-control\"\n                @bind-Value=\"_model.CustomerId\">\n            </InputText>\n        </div>\n\n        @if (_model.SequenceType == SequenceType.Recurring)\n        {\n            <div class=\"form-group\">\n                <label for=\"mandate\">Mandate</label>\n                <InputText\n                    id=\"mandate\"\n                    class=\"form-control\"\n                    @bind-Value=\"_model.MandateId\">\n                </InputText>\n            </div>\n        }\n    }\n\n    <input type=\"submit\" name=\"Save\" value=\"Save\" class=\"btn btn-primary mt-2\"/>\n</EditForm>\n\n@code {\n    private MollieApiException? _apiException;\n\n    private CreatePaymentModel _model = new() {\n        Amount = 10.00m,\n        Currency = \"EUR\",\n        RedirectUrl = \"https://www.mollie.com/\",\n        WebhookUrl = null,\n        Description = \"A payment from the example application\",\n        SequenceType = SequenceType.OneOff\n    };\n\n    private async Task OnSave() {\n        try {\n            _apiException = null;\n\n            await PaymentClient.CreatePaymentAsync(new PaymentRequest {\n                Amount = new Amount(_model.Currency, _model.Amount),\n                RedirectUrl = _model.RedirectUrl,\n                WebhookUrl = _model.WebhookUrl,\n                Description = _model.Description,\n                CustomerId = _model.CustomerId,\n                SequenceType = _model.SequenceType,\n                MandateId = _model.MandateId\n            });\n\n            NavigationManager.NavigateTo(\"/payment/overview\");\n        }\n        catch (MollieApiException e) {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Payment/Overview.razor",
    "content": "﻿@page \"/payment/overview\"\n@using Mollie.Api.Models.List.Response\n\n@inject IPaymentClient PaymentClient\n\n<h3>Payments</h3>\n\n@if (_payments == null) {\n    <p>Loading...</p>\n}\nelse {\n    <div class=\"clearfix\">\n        <a href=\"/payment/create\" class=\"btn btn-primary float-right\">Create new payment</a>\n    </div>\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Amount</th>\n            <th scope=\"col\">Status</th>\n            <th scope=\"col\">Method</th>\n            <th scope=\"col\">Metadata</th>\n            <th scope=\"col\">Actions</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (PaymentResponse payment in _payments.Items) {\n            <tr>\n                <td>@payment.Id</td>\n                <td>@payment.CreatedAt</td>\n                <td>@payment.Amount.ToString()</td>\n                <td>@payment.Status</td>\n                <td>@payment.Method</td>\n                <td>@payment.Metadata</td>\n                <td>\n                    @{\n                        string? checkoutUrl = GetCheckoutUrl(payment);\n                    }\n                    @if (checkoutUrl != null)\n                    {\n                        <a href=\"@checkoutUrl\" class=\"btn btn-outline-secondary\" target=\"_blank\">Pay</a>\n                    }\n                </td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_payments.Links.Previous\"\n        Next=\"_payments.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<PaymentResponse>? _payments;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _payments = await PaymentClient.GetPaymentListAsync();\n        }\n        else {\n            _payments = await PaymentClient.GetPaymentListAsync(new UrlObjectLink<ListResponse<PaymentResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n\n    private string? GetCheckoutUrl(PaymentResponse payment) {\n        if (payment.Status != PaymentStatus.Open && payment.Status != PaymentStatus.Pending)\n        {\n            return null;\n        }\n\n        return payment.Links.Checkout?.Href ?? payment.Links.ChangePaymentState?.Href;\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/PaymentLink/Create.razor",
    "content": "﻿@page \"/paymentlink/create\"\n\n@using Mollie.Api.Models.PaymentLink.Request\n@using Mollie.WebApplication.Blazor.Models.PaymentLink\n@using Mollie.Api.Client\n\n@inject IPaymentLinkClient PaymentLinkClient\n@inject NavigationManager NavigationManager\n\n<h3>Create new payment link</h3>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n<EditForm Model=\"_model\" OnValidSubmit=\"@OnSave\" class=\"col-md-6\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <div class=\"form-group\">\n        <label for=\"amount\">Amount</label>\n        <InputNumber\n            id=\"amount\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Amount\">\n        </InputNumber>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"currency\">Currency</label>\n        <InputSelect\n            id=\"currency\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Currency\">\n            @foreach (string currency in StaticStringListBuilder.GetStaticStringList(typeof(Currency))) {\n                <option value=\"@currency\">@currency</option>\n            }\n        </InputSelect>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"redirect-url\">Redirect url</label>\n        <InputText\n            id=\"redirect-url\"\n            class=\"form-control\"\n            @bind-Value=\"_model.RedirectUrl\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"redirect-url\">Webhook url</label>\n        <InputText\n            id=\"redirect-url\"\n            class=\"form-control\"\n            @bind-Value=\"_model.WebhookUrl\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"description\">Description</label>\n        <InputText\n            id=\"description\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Description\">\n        </InputText>\n    </div>\n\n    <input type=\"submit\" name=\"Save\" value=\"Save\" class=\"btn btn-primary mt-2\"/>\n</EditForm>\n\n@code {\n    private MollieApiException? _apiException;\n\n    private CreatePaymentLinkModel _model = new() {\n        Amount = 10.00m,\n        Currency = \"EUR\",\n        RedirectUrl = \"https://www.mollie.com/\",\n        WebhookUrl = null,\n        Description = \"A payment link from the example application\"\n    };\n\n    private async Task OnSave() {\n        try {\n            _apiException = null;\n\n            await PaymentLinkClient.CreatePaymentLinkAsync(new PaymentLinkRequest {\n                Amount = new Amount(_model.Currency, _model.Amount),\n                RedirectUrl = _model.RedirectUrl,\n                WebhookUrl = _model.WebhookUrl,\n                Description = _model.Description\n            });\n\n            NavigationManager.NavigateTo(\"/paymentlink/overview\");\n        }\n        catch (MollieApiException e) {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/PaymentLink/Overview.razor",
    "content": "﻿@page \"/paymentlink/overview\"\n@using Mollie.Api.Models.List.Response\n@using Mollie.Api.Models.PaymentLink.Response\n\n@inject IPaymentLinkClient PaymentClient\n\n<h3>Payment Links</h3>\n\n@if (_paymentLinks == null) {\n    <p>Loading...</p>\n}\nelse {\n    <div class=\"clearfix\">\n        <a href=\"/paymentlink/create\" class=\"btn btn-primary float-right\">Create new payment link</a>\n    </div>\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Amount</th>\n            <th scope=\"col\">Actions</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (PaymentLinkResponse paymentLink in _paymentLinks.Items) {\n            <tr>\n                <td>@paymentLink.Id</td>\n                <td>@paymentLink.CreatedAt</td>\n                <td>@paymentLink.Amount?.ToString() ?? @paymentLink.MinimumAmount?.ToString()</td>\n                <td>\n                    <a href=\"@paymentLink.Links.PaymentLink.Href\" class=\"btn btn-outline-secondary\" target=\"_blank\">Pay</a>\n                </td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_paymentLinks.Links.Previous\"\n        Next=\"_paymentLinks.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<PaymentLinkResponse>? _paymentLinks;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _paymentLinks = await PaymentClient.GetPaymentLinkListAsync();\n        }\n        else {\n            _paymentLinks = await PaymentClient.GetPaymentLinkListAsync(new UrlObjectLink<ListResponse<PaymentLinkResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/PaymentMethod/Overview.razor",
    "content": "﻿@page \"/payment-method/overview\"\n@using Mollie.Api.Models.List.Response\n@using Mollie.Api.Models.PaymentMethod.Response\n\n@inject IPaymentMethodClient PaymentMethodClient\n\n<h3>Payment methods</h3>\n\n@if (_paymentMethods == null) {\n    <p>Loading...</p>\n}\nelse {\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">Description</th>\n            <th scope=\"col\">Size1x</th>\n            <th scope=\"col\">Size2x</th>\n            <th scope=\"col\">Svg</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (PaymentMethodResponse paymentMethod in _paymentMethods.Items) {\n            <tr>\n                <td>@paymentMethod.Description</td>\n                <td><img src=\"@paymentMethod.Image.Size1x\" alt=\"@paymentMethod.Description\" /></td>\n                <td><img src=\"@paymentMethod.Image.Size2x\" alt=\"@paymentMethod.Description\" /></td>\n                <td><img src=\"@paymentMethod.Image.Svg\" alt=\"@paymentMethod.Description\" /></td>\n            </tr>\n        }\n        </tbody>\n    </table>\n}\n\n\n@code {\n    private ListResponse<PaymentMethodResponse>? _paymentMethods;\n\n    protected override async Task OnInitializedAsync() {\n        _paymentMethods = await PaymentMethodClient.GetPaymentMethodListAsync();\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Subscription/Create.razor",
    "content": "﻿@page \"/customer/{customerId}/subscription/create\"\n\n@using Mollie.WebApplication.Blazor.Models.Subscription\n@using Mollie.Api.Client\n@using Mollie.Api.Models.Subscription.Request\n\n@inject ISubscriptionClient SubscriptionClient\n@inject NavigationManager NavigationManager\n\n<h3>Create new subscription</h3>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n<EditForm Model=\"_model\" OnValidSubmit=\"@OnSave\" class=\"col-md-6\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <div class=\"form-group\">\n        <label for=\"description\">Description</label>\n        <InputText\n            id=\"description\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Description\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"mandate-id\">Mandate id</label>\n        <InputText\n            id=\"mandate-id\"\n            class=\"form-control\"\n            @bind-Value=\"_model.MandateId\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"amount\">Amount</label>\n        <InputNumber\n            id=\"amount\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Amount\">\n        </InputNumber>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"currency\">Currency</label>\n        <InputSelect\n            id=\"currency\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Currency\">\n            @foreach (string currency in StaticStringListBuilder.GetStaticStringList(typeof(Currency))) {\n                <option value=\"@currency\">@currency</option>\n            }\n        </InputSelect>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"times\">Times</label>\n        <InputNumber\n            id=\"times\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Times\">\n        </InputNumber>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"interval-amount\">Interval amount</label>\n        <InputNumber\n            id=\"interval-amount\"\n            class=\"form-control\"\n            @bind-Value=\"_model.IntervalAmount\">\n        </InputNumber>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"interval-period\">Interval period</label>\n        <InputSelect\n            id=\"interval-period\"\n            class=\"form-control\"\n            @bind-Value=\"_model.IntervalPeriod\">\n            @foreach (string intervalPeriod in Enum.GetNames(typeof(IntervalPeriod))) {\n                <option value=\"@intervalPeriod\">@intervalPeriod</option>\n            }\n        </InputSelect>\n    </div>\n\n    <input type=\"submit\" name=\"Save\" value=\"Save\" class=\"btn btn-primary mt-2\"/>\n</EditForm>\n\n@code {\n    private MollieApiException? _apiException;\n\n    [Parameter]\n    public required string CustomerId { get; set; }\n\n    private CreateSubscriptionModel _model = new() {\n        Amount = 10.00m,\n        Currency = Currency.EUR,\n        IntervalPeriod = IntervalPeriod.Days,\n        Times = 5,\n        IntervalAmount = 2,\n        Description = \"A subscription created by the example application\",\n    };\n\n    private async Task OnSave() {\n        try {\n            _apiException = null;\n\n            await SubscriptionClient.CreateSubscriptionAsync(CustomerId, new SubscriptionRequest {\n                Amount = new Amount(_model.Currency, _model.Amount),\n                Interval = $\"{_model.IntervalAmount} {_model.IntervalPeriod.ToString().ToLower()}\",\n                Times = _model.Times,\n                Description = _model.Description,\n                MandateId = _model.MandateId\n            });\n\n            NavigationManager.NavigateTo($\"/customer/{CustomerId}/subscription/overview\");\n        }\n        catch (MollieApiException e) {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Subscription/Overview.razor",
    "content": "﻿@page \"/customer/{customerId}/subscription/overview\"\n@using Mollie.Api.Models.List.Response\n@using Mollie.Api.Models.Subscription.Response\n\n@inject ISubscriptionClient SubscriptionClient\n\n<h3>Subscriptions</h3>\n\n@if (_subscriptions == null) {\n    <p>Loading...</p>\n}\nelse {\n    <div class=\"clearfix\">\n        <a href=\"/customer/@CustomerId/subscription/create\" class=\"btn btn-primary float-right\">Create new subscription</a>\n    </div>\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Description</th>\n            <th scope=\"col\">MandateId</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Amount</th>\n            <th scope=\"col\">Mode</th>\n            <th scope=\"col\">Status</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (SubscriptionResponse subscription in _subscriptions.Items) {\n            <tr>\n                <td>@subscription.Id</td>\n                <td>@subscription.Description</td>\n                <td>@subscription.MandateId</td>\n                <td>@subscription.CreatedAt</td>\n                <td>@subscription.Amount.ToString()</td>\n                <td>@subscription.Mode</td>\n                <td>@subscription.Status</td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_subscriptions.Links.Previous\"\n        Next=\"_subscriptions.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    public required string CustomerId { get; set; }\n\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<SubscriptionResponse>? _subscriptions;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _subscriptions = await SubscriptionClient.GetSubscriptionListAsync(CustomerId);\n        }\n        else {\n            _subscriptions = await SubscriptionClient.GetSubscriptionListAsync(new UrlObjectLink<ListResponse<SubscriptionResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Terminal/Overview.razor",
    "content": "﻿@page \"/terminal/overview\"\n@using Mollie.Api.Models.List.Response\n@using Mollie.Api.Models.Terminal.Response\n\n@inject ITerminalClient TerminalClient\n\n<h3>Terminals</h3>\n\n@if (_terminals == null) {\n    <p>Loading...</p>\n}\nelse {\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Status</th>\n            <th scope=\"col\">Brand</th>\n            <th scope=\"col\">Model</th>\n            <th scope=\"col\">Serialnumber</th>\n            <th scope=\"col\">Currency</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (TerminalResponse terminal in _terminals.Items) {\n            <tr>\n                <td>@terminal.Id</td>\n                <td>@terminal.CreatedAt</td>\n                <td>@terminal.Status</td>\n                <td>@terminal.Brand</td>\n                <td>@terminal.Model</td>\n                <td>@terminal.SerialNumber</td>\n                <td>@terminal.Currency</td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_terminals.Links.Previous\"\n        Next=\"_terminals.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<TerminalResponse>? _terminals;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _terminals = await TerminalClient.GetTerminalListAsync();\n        }\n        else {\n            _terminals = await TerminalClient.GetTerminalListAsync(new UrlObjectLink<ListResponse<TerminalResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Webhook/Components/EventTypeEditor.razor",
    "content": "﻿@using Mollie.Api.Models.Webhook\n\n<EditForm Model=\"EventTypes\" OnValidSubmit=\"@OnAddEventType\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">Event</th>\n            <th scope=\"col\">Actions</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (string eventType in EventTypes) {\n            <tr>\n                <td>@eventType</td>\n                <td>\n                    <button\n                        class=\"btn btn-outline-secondary\"\n                        type=\"button\"\n                        @onclick=\"() => OnRemoveEventType(eventType)\">\n                        Remove\n                    </button>\n                </td>\n            </tr>\n        }\n        <tr>\n            <td>\n                <InputSelect\n                    id=\"event-types\"\n                    class=\"form-control\"\n                    @bind-Value=\"_selectedEventType\">\n                    @foreach (string eventType in StaticStringListBuilder.GetStaticStringList(typeof(WebhookEventTypes))) {\n                        <option value=\"@eventType\">@eventType</option>\n                    }\n                </InputSelect>\n            </td>\n            <td>\n                <button name=\"add-event-type\" class=\"btn btn-outline-secondary\" type=\"submit\">Add</button>\n            </td>\n        </tr>\n        </tbody>\n    </table>\n</EditForm>\n\n@code {\n    [Parameter, EditorRequired]\n    public required IList<string> EventTypes { get; set; }\n\n    private string? _selectedEventType = WebhookEventTypes.PaymentLinkPaid;\n\n    private void OnAddEventType() {\n        if (_selectedEventType == null)\n        {\n            return;\n        }\n\n        if (EventTypes.Any(x => x == _selectedEventType))\n        {\n            return;\n        }\n\n        EventTypes.Add(_selectedEventType);\n    }\n\n    private void OnRemoveEventType(string eventType)\n    {\n        EventTypes.Remove(eventType);\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Webhook/Create.razor",
    "content": "﻿@page \"/webhook/create\"\n\n@using Mollie.WebApplication.Blazor.Models.Webhook\n@using Mollie.Api.Models.Webhook.Request\n@using Mollie.Api.Models.Webhook\n@using Mollie.Api.Client\n@using Mollie.WebApplication.Blazor.Pages.Webhook.Components\n\n@inject IWebhookClient WebhookClient\n@inject NavigationManager NavigationManager\n\n<h3>Create new webhook</h3>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n<EditForm Model=\"_model\" OnValidSubmit=\"@OnSave\" class=\"col-md-6\">\n    <DataAnnotationsValidator />\n    <ValidationSummary />\n\n    <div class=\"form-group\">\n        <label for=\"name\">Name</label>\n        <InputText\n            id=\"name\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Name\">\n        </InputText>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"url\">Url</label>\n        <InputText\n            id=\"url\"\n            class=\"form-control\"\n            @bind-Value=\"_model.Url\">\n        </InputText>\n    </div>\n\n    <EventTypeEditor EventTypes=\"_model.EventTypes\"></EventTypeEditor>\n\n    <div class=\"form-group\">\n        <InputCheckbox\n            id=\"test-mode\"\n            @bind-Value=\"_model.Testmode\">\n        </InputCheckbox>\n        <label for=\"test-mode\">Test mode</label>\n    </div>\n\n    <input type=\"submit\" name=\"Save\" value=\"Save\" class=\"btn btn-primary mt-2\"/>\n</EditForm>\n\n@code {\n    private MollieApiException? _apiException;\n\n    private CreateWebhookModel _model = new() {\n        Name = \"Test webhook\",\n        Url = \"https://example.com/webhook\",\n        EventTypes = [WebhookEventTypes.PaymentLinkPaid],\n        Testmode = true\n    };\n\n    private async Task OnSave() {\n        try {\n            _apiException = null;\n\n            await WebhookClient.CreateWebhookAsync(new WebhookRequest {\n                Name = _model.Name,\n                Url = _model.Url,\n                EventTypes = _model.EventTypes,\n                Testmode = _model.Testmode\n            });\n\n            NavigationManager.NavigateTo(\"/webhook/overview\");\n        }\n        catch (MollieApiException e) {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/Webhook/Overview.razor",
    "content": "﻿@page \"/webhook/overview\"\n@using Mollie.Api.Client\n@using Mollie.Api.Models.List.Response\n@using Mollie.Api.Models.Webhook.Response\n\n@inject IWebhookClient WebhookClient\n\n<h3>Webhooks</h3>\n\n<ApiExceptionDisplay Exception=\"_apiException\"></ApiExceptionDisplay>\n\n@if (_webhooks == null) {\n    <p>Loading...</p>\n}\nelse {\n    <div class=\"clearfix\">\n        <a href=\"/webhook/create\" class=\"btn btn-primary float-right\">Create new webhook</a>\n    </div>\n\n    <table class=\"table table-striped\">\n        <thead>\n        <tr>\n            <th scope=\"col\">#</th>\n            <th scope=\"col\">Name</th>\n            <th scope=\"col\">Date created</th>\n            <th scope=\"col\">Status</th>\n            <th scope=\"col\">Event types</th>\n            <th scope=\"col\">Url</th>\n            <th scope=\"col\">Actions</th>\n        </tr>\n        </thead>\n        <tbody>\n        @foreach (WebhookResponse webhook in _webhooks.Items) {\n            <tr>\n                <td>@webhook.Id</td>\n                <td>@webhook.Name</td>\n                <td>@webhook.CreatedAt</td>\n                <td>@webhook.Status</td>\n                <td>\n                    @foreach(string eventType in webhook.EventTypes) {\n                        <span class=\"badge bg-secondary\">@eventType</span>\n                    }\n                </td>\n                <td>@webhook.Url</td>\n                <td>\n                    <button\n                        class=\"btn btn-outline-secondary\"\n                        @onclick=\"@(async () => await TestWebhook(webhook.Id))\">\n                        Test webhook\n                    </button>\n                    <button\n                        class=\"btn btn-outline-danger\"\n                        @onclick=\"@(async () => await DeleteWebhook(webhook.Id))\">\n                        Delete webhook\n                    </button>\n                </td>\n            </tr>\n        }\n        </tbody>\n    </table>\n\n    <OverviewNavigation\n        Previous=\"_webhooks.Links.Previous\"\n        Next=\"_webhooks.Links.Next\">\n    </OverviewNavigation>\n}\n\n@code {\n    [Parameter]\n    [SupplyParameterFromQuery]\n    public string? Url { get; set; }\n\n    private ListResponse<WebhookResponse>? _webhooks;\n    private MollieApiException? _apiException;\n\n    protected override async Task OnParametersSetAsync() {\n        await LoadData();\n    }\n\n    private async Task LoadData() {\n        if (string.IsNullOrEmpty(Url)) {\n            _webhooks = await WebhookClient.GetWebhookListAsync(testmode: true);\n        }\n        else {\n            _webhooks = await WebhookClient.GetWebhookListAsync(new UrlObjectLink<ListResponse<WebhookResponse>>() {\n                Href = Url,\n                Type = \"application/json\"\n            });\n        }\n    }\n\n    private async Task TestWebhook(string webhookId)\n    {\n        try\n        {\n            await WebhookClient.TestWebhookAsync(webhookId, testmode: true);\n        }\n        catch (MollieApiException e)\n        {\n            _apiException = e;\n        }\n    }\n\n    private async Task DeleteWebhook(string webhookId)\n    {\n        try\n        {\n            await WebhookClient.DeleteWebhookAsync(webhookId, testmode: true);\n            await LoadData();\n        }\n        catch (MollieApiException e)\n        {\n            _apiException = e;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Pages/_Host.cshtml",
    "content": "﻿@page \"/\"\n@using Microsoft.AspNetCore.Components.Web\n@namespace Mollie.WebApplication.Blazor.Pages\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n    <base href=\"~/\"/>\n    <link rel=\"stylesheet\" href=\"css/bootstrap/bootstrap.min.css\"/>\n    <link href=\"css/site.css\" rel=\"stylesheet\"/>\n    <link href=\"Mollie.WebApplication.Blazor.styles.css\" rel=\"stylesheet\"/>\n    <link rel=\"icon\" type=\"image/png\" href=\"favicon.png\"/>\n    <component type=\"typeof(HeadOutlet)\" render-mode=\"ServerPrerendered\"/>\n</head>\n<body>\n<component type=\"typeof(App)\" render-mode=\"ServerPrerendered\"/>\n\n<div id=\"blazor-error-ui\">\n    <environment include=\"Staging,Production\">\n        An error has occurred. This application may no longer respond until reloaded.\n    </environment>\n    <environment include=\"Development\">\n        An unhandled exception has occurred. See browser dev tools for details.\n    </environment>\n    <a href=\"\" class=\"reload\">Reload</a>\n    <a class=\"dismiss\">🗙</a>\n</div>\n\n<script src=\"_framework/blazor.server.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Program.cs",
    "content": "using Mollie.Api;\nusing Mollie.Api.AspNet;\nusing Mollie.Api.Framework;\nusing Mollie.WebApplication.Blazor.Webhooks.Nextgen.MinimalApi;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\nbuilder.Services.AddRazorPages();\nbuilder.Services.AddServerSideBlazor();\nbuilder.Services.AddMollieApi(options => {\n    options.ApiKey = builder.Configuration[\"Mollie:ApiKey\"]!;\n    options.RetryPolicy = MollieHttpRetryPolicies.TransientHttpErrorRetryPolicy();\n});\nbuilder.Services.AddMollieWebhook(options => {\n    options.Secret = builder.Configuration[\"Mollie:WebhookSecret\"]!;\n});\n\nvar app = builder.Build();\n\n// Configure the HTTP request pipeline.\nif (!app.Environment.IsDevelopment()) {\n    app.UseExceptionHandler(\"/Error\");\n    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.\n    app.UseHsts();\n}\n\napp.UseHttpsRedirection();\n\napp.UseStaticFiles();\n\napp.UseRouting();\napp.MapControllers();\napp.MapBlazorHub();\napp.MapFallbackToPage(\"/_Host\");\nWebhookHandler.RegisterEndpoints(app);\n\napp.Run();\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:46697\",\n      \"sslPort\": 44312\n    }\n  },\n  \"profiles\": {\n    \"Watch\": {\n      \"commandName\": \"Executable\",\n      \"workingDirectory\": \"$(ProjectDir)\",\n      \"executablePath\": \"dotnet.exe\",\n      \"commandLineArgs\": \"watch run debug --launch-profile https\"\n    },\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"https://localhost:7212;http://localhost:5088\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }    \n  }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Shared/ApiExceptionDisplay.razor",
    "content": "﻿@using Mollie.Api.Client\n\n@if (Exception != null) {\n    <div class=\"alert alert-danger\" role=\"alert\">\n        A Mollie API exception has occured: StatusCode=@Exception.Details.Status Title=@Exception.Details.Title Detail=@Exception.Details.Detail\n    </div>\n}\n\n@code {\n    [Parameter, EditorRequired]\n    public MollieApiException? Exception { get; set; }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Shared/MainLayout.razor",
    "content": "﻿@inherits LayoutComponentBase\n\n<PageTitle>Mollie.WebApplication.Blazor</PageTitle>\n\n<div class=\"page\">\n    <div class=\"sidebar\">\n        <NavMenu/>\n    </div>\n\n    <main>\n        <article class=\"content px-4\">\n            @Body\n        </article>\n    </main>\n</div>"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Shared/MainLayout.razor.css",
    "content": ".page {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n}\n\nmain {\n    flex: 1;\n}\n\n.sidebar {\n    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);\n}\n\n.top-row {\n    background-color: #f7f7f7;\n    border-bottom: 1px solid #d6d5d5;\n    justify-content: flex-end;\n    height: 3.5rem;\n    display: flex;\n    align-items: center;\n}\n\n    .top-row ::deep a, .top-row .btn-link {\n        white-space: nowrap;\n        margin-left: 1.5rem;\n    }\n\n    .top-row a:first-child {\n        overflow: hidden;\n        text-overflow: ellipsis;\n    }\n\n@media (max-width: 640.98px) {\n    .top-row:not(.auth) {\n        display: none;\n    }\n\n    .top-row.auth {\n        justify-content: space-between;\n    }\n\n    .top-row a, .top-row .btn-link {\n        margin-left: 0;\n    }\n}\n\n@media (min-width: 641px) {\n    .page {\n        flex-direction: row;\n    }\n\n    .sidebar {\n        width: 250px;\n        height: 100vh;\n        position: sticky;\n        top: 0;\n    }\n\n    .top-row {\n        position: sticky;\n        top: 0;\n        z-index: 1;\n    }\n\n    .top-row, article {\n        padding-left: 2rem !important;\n        padding-right: 1.5rem !important;\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Shared/NavMenu.razor",
    "content": "﻿<div class=\"top-row ps-3 navbar navbar-dark\">\n    <div class=\"container-fluid\">\n        <a class=\"navbar-brand\" href=\"\">Mollie Example App</a>\n        <button title=\"Navigation menu\" class=\"navbar-toggler\" @onclick=\"ToggleNavMenu\">\n            <span class=\"navbar-toggler-icon\"></span>\n        </button>\n    </div>\n</div>\n\n<div class=\"@NavMenuCssClass nav-scrollable\" @onclick=\"ToggleNavMenu\">\n    <nav class=\"flex-column\">\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"\" Match=\"NavLinkMatch.All\">\n                <span class=\"oi oi-home\" aria-hidden=\"true\"></span> Home\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"payment/overview\">\n                <span class=\"oi oi-euro\" aria-hidden=\"true\"></span> Payments\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"paymentlink/overview\">\n                <span class=\"oi oi-link-intact\" aria-hidden=\"true\"></span> Payment Links\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"order/overview\">\n                <span class=\"oi oi-cart\" aria-hidden=\"true\"></span> Orders\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"payment-method/overview\">\n                <span class=\"oi oi-list\" aria-hidden=\"true\"></span> Payment methods\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"customer/overview\">\n                <span class=\"oi oi-person\" aria-hidden=\"true\"></span> Customers\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"terminal/overview\">\n                <span class=\"oi oi-phone\" aria-hidden=\"true\"></span> Terminals\n            </NavLink>\n        </div>\n\n        <div class=\"nav-item px-3\">\n            <NavLink class=\"nav-link\" href=\"webhook/overview\">\n                <span class=\"oi oi-pulse\" aria-hidden=\"true\"></span> Webhooks\n            </NavLink>\n        </div>\n    </nav>\n</div>\n\n@code {\n    private bool _collapseNavMenu = true;\n\n    private string NavMenuCssClass => _collapseNavMenu ? \"collapse\" : string.Empty;\n\n    private void ToggleNavMenu() {\n        _collapseNavMenu = !_collapseNavMenu;\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Shared/NavMenu.razor.css",
    "content": ".navbar-toggler {\n    background-color: rgba(255, 255, 255, 0.1);\n}\n\n.top-row {\n    height: 3.5rem;\n    background-color: rgba(0,0,0,0.4);\n}\n\n.navbar-brand {\n    font-size: 1.1rem;\n}\n\n.oi {\n    width: 2rem;\n    font-size: 1.1rem;\n    vertical-align: text-top;\n    top: -2px;\n}\n\n.nav-item {\n    font-size: 0.9rem;\n    padding-bottom: 0.5rem;\n}\n\n    .nav-item:first-of-type {\n        padding-top: 1rem;\n    }\n\n    .nav-item:last-of-type {\n        padding-bottom: 1rem;\n    }\n\n    .nav-item ::deep a {\n        color: #d7d7d7;\n        border-radius: 4px;\n        height: 3rem;\n        display: flex;\n        align-items: center;\n        line-height: 3rem;\n    }\n\n.nav-item ::deep a.active {\n    background-color: rgba(255,255,255,0.25);\n    color: white;\n}\n\n.nav-item ::deep a:hover {\n    background-color: rgba(255,255,255,0.1);\n    color: white;\n}\n\n@media (min-width: 641px) {\n    .navbar-toggler {\n        display: none;\n    }\n\n    .collapse {\n        /* Never collapse the sidebar for wide screens */\n        display: block;\n    }\n    \n    .nav-scrollable {\n        /* Allow sidebar to scroll for tall menus */\n        height: calc(100vh - 3.5rem);\n        overflow-y: auto;\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Shared/OverviewNavigation.razor",
    "content": "﻿@using Mollie.Api.Models.Url\n\n@inject NavigationManager NavManager\n\n@if (Previous != null) {\n    <a class=\"btn btn-primary\" href=\"@GetCurrentUrlWithoutQueryParameters?Url=@Previous.Href\">&lt;&lt; Previous</a>\n}\n\n@if (Next != null) {\n    <a class=\"btn btn-primary\" href=\"@GetCurrentUrlWithoutQueryParameters?Url=@Next.Href\">Next &gt;&gt;</a>\n}\n\n@code {\n    [Parameter, EditorRequired]\n    public UrlLink? Previous { get; set; }\n\n    [Parameter, EditorRequired]\n    public UrlLink? Next { get; set; }\n\n    private string GetCurrentUrlWithoutQueryParameters => NavManager.Uri.Split('?')[0];\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Webhooks/Classic/PaymentController.cs",
    "content": "﻿using Microsoft.AspNetCore.Mvc;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models.Payment.Response;\n\nnamespace Mollie.WebApplication.Blazor.Webhooks.Classic;\n\n[ApiController]\n[Route(\"api/webhook/classic/controllers\")]\npublic class PaymentController : ControllerBase {\n    private readonly ILogger<PaymentController> _logger;\n    private readonly IPaymentClient _paymentClient;\n\n    public PaymentController(ILogger<PaymentController> logger, IPaymentClient paymentClient) {\n        _logger = logger;\n        _paymentClient = paymentClient;\n    }\n\n    [HttpPost]\n    public async Task<ActionResult> Webhook([FromForm] string id) {\n        PaymentResponse payment = await _paymentClient.GetPaymentAsync(id);\n        _logger.LogInformation(\"Webhook called for PaymentId={PaymentId}, PaymentStatus={Status}\",\n            id,\n            payment.Status);\n\n        return Ok();\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Webhooks/Nextgen/Controllers/PaymentLinkController.cs",
    "content": "using Microsoft.AspNetCore.Mvc;\nusing Mollie.Api.AspNet.Webhooks.Authorization;\nusing Mollie.Api.AspNet.Webhooks.ModelBinding;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing Mollie.Api.Models.WebhookEvent.Response;\n\nnamespace Mollie.WebApplication.Blazor.Webhooks.Nextgen.Controllers;\n\n[ApiController]\n[Route(\"api/webhook/nextgen/controllers\")]\npublic class PaymentLinkController : ControllerBase {\n    // Example of full webhook event with specific data entity type, such as PaymentLinkResponse\n    [HttpPost(\"full/specific\")]\n    [ServiceFilter(typeof(MollieSignatureFilter))]\n    public Task<ActionResult> WebhookWithSpecificType([FromMollieWebhook] FullWebhookEventResponse<PaymentLinkResponse> data) {\n        return Task.FromResult<ActionResult>(Ok());\n    }\n\n    // Example of full webhook event with generic data entity type\n    [HttpPost(\"full/generic\")]\n    [ServiceFilter(typeof(MollieSignatureFilter))]\n    public Task<ActionResult> WebhookWithGenericType([FromMollieWebhook] FullWebhookEventResponse data) {\n        return Task.FromResult<ActionResult>(Ok());\n    }\n\n    // Example of a simple webhook event response, that does not include the entity data\n    [HttpPost(\"simple\")]\n    [ServiceFilter(typeof(MollieSignatureFilter))]\n    public Task<ActionResult> WebhookWithGenericType([FromMollieWebhook] SimpleWebhookEventResponse data) {\n        return Task.FromResult<ActionResult>(Ok());\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/Webhooks/Nextgen/MinimalApi/WebhookHandler.cs",
    "content": "using Mollie.Api.AspNet.Webhooks.Authorization;\nusing Mollie.Api.AspNet.Webhooks.ModelBinding;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing Mollie.Api.Models.WebhookEvent.Response;\n\nnamespace Mollie.WebApplication.Blazor.Webhooks.Nextgen.MinimalApi;\n\npublic static class WebhookHandler {\n\n    public static void RegisterEndpoints(IEndpointRouteBuilder app) {\n        // Example of full webhook event with specific data entity type, such as PaymentLinkResponse\n        app\n            .MapPost(\"api/webhook/nextgen/minimalapi/full/specific\",\n                (MollieModelBinder<FullWebhookEventResponse<PaymentLinkResponse>> data) => {\n                    if (data.Model == null) {\n                        return Results.BadRequest();\n                    }\n\n                    return Results.Ok();\n                })\n            .AddEndpointFilter<MollieSignatureEndpointFilter>();\n\n        // Example of full webhook event with generic data entity type\n        app\n            .MapPost(\"api/webhook/nextgen/minimalapi/full/generic\",\n                (MollieModelBinder<FullWebhookEventResponse> data) => {\n                    if (data.Model == null) {\n                        return Results.BadRequest();\n                    }\n\n                    return Results.Ok();\n                })\n            .AddEndpointFilter<MollieSignatureEndpointFilter>();\n\n        // Example of a simple webhook event response, that does not include the entity data\n        app\n            .MapPost(\"api/webhook/nextgen/minimalapi/simple\",\n                (MollieModelBinder<SimpleWebhookEventResponse> data) => Results.Ok())\n            .AddEndpointFilter<MollieSignatureEndpointFilter>();\n    }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/_Imports.razor",
    "content": "﻿@using System.Net.Http\n@using Microsoft.AspNetCore.Authorization\n@using Microsoft.AspNetCore.Components.Authorization\n@using Microsoft.AspNetCore.Components.Forms\n@using Microsoft.AspNetCore.Components.Routing\n@using Microsoft.AspNetCore.Components.Web\n@using Microsoft.AspNetCore.Components.Web.Virtualization\n@using Microsoft.JSInterop\n@using Mollie.WebApplication.Blazor\n@using Mollie.WebApplication.Blazor.Shared\n@using Mollie.WebApplication.Blazor.Framework\n\n@using Mollie.Api.Client.Abstract\n@using Mollie.Api.Models.List\n@using Mollie.Api.Models.Url\n@using Mollie.Api.Models\n@using Mollie.Api.Models.Payment\n@using Mollie.Api.Models.Payment.Response\n@using Mollie.Api.Models.Customer;\n@using Mollie.Api.Models.Subscription;\n@using Mollie.Api.Models.Mandate;\n@using Mollie.Api.Models.PaymentMethod;\n@using Mollie.Api.Models.Order;\n@using Mollie.Api.Models.Terminal;"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/appsettings.Development.json",
    "content": "{\n  \"DetailedErrors\": true,\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/appsettings.json",
    "content": "{\n    \"Mollie\": {\n        \"ApiKey\": \"<Enter your API key here>\",\n        \"WebhookSecret\": \"<Your next-gen webhook secret here>\"\n    },\n    \"Logging\": {\n        \"LogLevel\": {\n            \"Default\": \"Information\",\n            \"Microsoft.AspNetCore\": \"Warning\"\n        }\n    },\n    \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/wwwroot/css/open-iconic/FONT-LICENSE",
    "content": "SIL OPEN FONT LICENSE Version 1.1\n\nCopyright (c) 2014 Waybury\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded,\nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/wwwroot/css/open-iconic/ICON-LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Waybury\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/wwwroot/css/open-iconic/README.md",
    "content": "[Open Iconic v1.1.1](https://github.com/iconic/open-iconic)\n===========\n\n### Open Iconic is the open source sibling of [Iconic](https://github.com/iconic/open-iconic). It is a hyper-legible collection of 223 icons with a tiny footprint&mdash;ready to use with Bootstrap and Foundation. [View the collection](https://github.com/iconic/open-iconic)\n\n\n\n## What's in Open Iconic?\n\n* 223 icons designed to be legible down to 8 pixels\n* Super-light SVG files - 61.8 for the entire set\n* SVG sprite&mdash;the modern replacement for icon fonts\n* Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats\n* Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats\n* PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px.\n\n\n## Getting Started\n\n#### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](https://github.com/iconic/open-iconic) and [Reference](https://github.com/iconic/open-iconic) sections.\n\n### General Usage\n\n#### Using Open Iconic's SVGs\n\nWe like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute).\n\n```\n<img src=\"/open-iconic/svg/icon-name.svg\" alt=\"icon name\">\n```\n\n#### Using Open Iconic's SVG Sprite\n\nOpen Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack.\n\nAdding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `<svg>` *tag and a unique class name for each different icon in the* `<use>` *tag.*\n\n```\n<svg class=\"icon\">\n  <use xlink:href=\"open-iconic.svg#account-login\" class=\"icon-account-login\"></use>\n</svg>\n```\n\nSizing icons only needs basic CSS. All the icons are in a square format, so just set the `<svg>` tag with equal width and height dimensions.\n\n```\n.icon {\n  width: 16px;\n  height: 16px;\n}\n```\n\nColoring icons is even easier. All you need to do is set the `fill` rule on the `<use>` tag.\n\n```\n.icon-account-login {\n  fill: #f00;\n}\n```\n\nTo learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/).\n\n#### Using Open Iconic's Icon Font...\n\n\n##### …with Bootstrap\n\nYou can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}`\n\n\n```\n<link href=\"/open-iconic/font/css/open-iconic-bootstrap.css\" rel=\"stylesheet\">\n```\n\n\n```\n<span class=\"oi oi-icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n##### …with Foundation\n\nYou can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}`\n\n```\n<link href=\"/open-iconic/font/css/open-iconic-foundation.css\" rel=\"stylesheet\">\n```\n\n\n```\n<span class=\"fi-icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n##### …on its own\n\nYou can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}`\n\n```\n<link href=\"/open-iconic/font/css/open-iconic.css\" rel=\"stylesheet\">\n```\n\n```\n<span class=\"oi\" data-glyph=\"icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n\n## License\n\n### Icons\n\nAll code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT).\n\n### Fonts\n\nAll fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web).\n"
  },
  {
    "path": "samples/Mollie.WebApplication.Blazor/wwwroot/css/site.css",
    "content": "@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');\n\nhtml, body {\n    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n}\n\nh1:focus {\n    outline: none;\n}\n\na, .btn-link {\n    color: #0071c1;\n}\n\n.btn-primary {\n    color: #fff;\n    background-color: #1b6ec2;\n    border-color: #1861ac;\n}\n\n.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {\n  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;\n}\n\n.content {\n    padding-top: 1.1rem;\n}\n\n.valid.modified:not([type=checkbox]) {\n    outline: 1px solid #26b050;\n}\n\n.invalid {\n    outline: 1px solid red;\n}\n\n.validation-message {\n    color: red;\n}\n\n#blazor-error-ui {\n    background: lightyellow;\n    bottom: 0;\n    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);\n    display: none;\n    left: 0;\n    padding: 0.6rem 1.25rem 0.7rem 1.25rem;\n    position: fixed;\n    width: 100%;\n    z-index: 1000;\n}\n\n    #blazor-error-ui .dismiss {\n        cursor: pointer;\n        position: absolute;\n        right: 0.75rem;\n        top: 0.5rem;\n    }\n\n.blazor-error-boundary {\n    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;\n    padding: 1rem 1rem 1rem 3.7rem;\n    color: white;\n}\n\n    .blazor-error-boundary::after {\n        content: \"An error has occurred.\"\n    }\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IBalanceClient.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Balance.Response;\nusing Mollie.Api.Models.Balance.Response.BalanceReport;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IBalanceClient : IBaseMollieClient {\n        /// <summary>\n        /// Retrieve a single balance object by its balance identifier.\n        /// </summary>\n        /// <param name=\"balanceId\">The balance identifier to retrieve</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<BalanceResponse> GetBalanceAsync(string balanceId, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a single balance object using an URL\n        /// </summary>\n        /// <param name=\"url\">The URL of the balance object</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<BalanceResponse> GetBalanceAsync(UrlObjectLink<BalanceResponse> url, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve the primary balance. This is the balance of your account’s primary currency, where all payments are\n        /// settled to by default.\n        /// </summary>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<BalanceResponse> GetPrimaryBalanceAsync(CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve all the organization’s balances, including the primary balance, ordered from newest to oldest.\n        /// </summary>\n        /// <param name=\"from\">Offset the result set to the balance with this ID. The balance with this ID is included\n        /// in the result set as well.</param>\n        /// <param name=\"limit\">The number of balances to return (with a maximum of 250).</param>\n        /// <param name=\"currency\">Currency filter that will make it so only balances in given currency are returned.\n        /// For example EUR.</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        /// <returns></returns>\n        Task<ListResponse<BalanceResponse>> GetBalanceListAsync(\n            string? from = null, int? limit = null, string? currency = null, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve all the organization’s balances by URL\n        /// </summary>\n        /// <param name=\"url\">The URL of the balance objects</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<ListResponse<BalanceResponse>> GetBalanceListAsync(\n            UrlObjectLink<ListResponse<BalanceResponse>> url, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// With the Get balance report endpoint you can retrieve a summarized report for all movements on a given\n        /// balance within a given timeframe.\n        /// </summary>\n        /// <param name=\"balanceId\">The balance id for which to retrieve a report</param>\n        /// <param name=\"from\">he start date of the report, in YYYY-MM-DD format. The from date is ‘inclusive’, and in\n        /// Central European Time. This means a report with for example from: 2020-01-01 will include movements of\n        /// 2020-01-01 0:00:00 CET and onwards.</param>\n        /// <param name=\"until\">The end date of the report, in YYYY-MM-DD format. The until date is ‘exclusive’, and\n        /// in Central European Time. This means a report with for example until: 2020-02-01 will include movements up\n        /// until 2020-01-31 23:59:59 CET.</param>\n        /// <param name=\"grouping\">You can retrieve reports in two different formats: status-balances and\n        /// transaction-categories</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<BalanceReportResponse> GetBalanceReportAsync(\n            string balanceId, DateTime from, DateTime until, string? grouping = null, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// With the Get primary balance report endpoint you can retrieve a summarized report for all movements on your\n        /// primary balance within a given timeframe.\n        /// </summary>\n        /// <param name=\"from\">The start date of the report, in YYYY-MM-DD format. The from date is ‘inclusive’, and in\n        /// Central European Time. This means a report with for example from: 2020-01-01 will include movements of\n        /// 2020-01-01 0:00:00 CET and onwards.</param>\n        /// <param name=\"until\">The end date of the report, in YYYY-MM-DD format. The until date is ‘exclusive’, and in\n        /// Central European Time. This means a report with for example until: 2020-02-01 will include movements up\n        /// until 2020-01-31 23:59:59 CET.</param>\n        /// <param name=\"grouping\">You can retrieve reports in two different formats: status-balances and\n        /// transaction-categories</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<BalanceReportResponse> GetPrimaryBalanceReportAsync(\n            DateTime from, DateTime until, string? grouping = null, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// With the List balance transactions endpoint you can retrieve a list of all the movements on your balance.\n        /// This includes payments, refunds, chargebacks, and settlements.\n        /// </summary>\n        /// <param name=\"balanceId\">The balance id for which to retrieve a report</param>\n        /// <param name=\"from\">Offset the result set to the balance transactions with this ID. The balance transaction\n        /// with this ID is included in the result set as well.</param>\n        /// <param name=\"limit\">The number of balance transactions to return (with a maximum of 250).</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<ListResponse<BalanceTransactionResponse>> GetBalanceTransactionListAsync(\n            string balanceId, string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// With the List primary balance transactions endpoint you can retrieve a list of all the movements on your\n        /// primary balance. This includes payments, refunds, chargebacks, and settlements.\n        /// </summary>\n        /// <param name=\"from\">Offset the result set to the balance transactions with this ID. The balance transaction\n        /// with this ID is included in the result set as well.</param>\n        /// <param name=\"limit\">The number of balance transactions to return (with a maximum of 250).</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<ListResponse<BalanceTransactionResponse>> GetPrimaryBalanceTransactionListAsync(\n            string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a list of balance transactions by URL\n        /// </summary>\n        /// <param name=\"url\">The URL from which to retrieve the balance transactions</param>\n        /// <param name=\"cancellationToken\">Optional cancellation token</param>\n        Task<ListResponse<BalanceTransactionResponse>> GetBalanceTransactionListAsync(\n            UrlObjectLink<ListResponse<BalanceTransactionResponse>> url, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IBalanceTransferClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.BalanceTransfer.Request;\nusing Mollie.Api.Models.BalanceTransfer.Response;\nusing Mollie.Api.Models.List.Response;\n\nnamespace Mollie.Api.Client.Abstract;\n\npublic interface IBalanceTransferClient {\n    /// <summary>\n    /// This API endpoint allows you to create a balance transfer from your organization's balance to a connected\n    /// organization's balance, or vice versa. You can also create a balance transfer between two connected\n    /// organizations. To create a balance transfer, you must be authenticated as the source organization, and the\n    /// destination organization must be a connected organization that has authorized the balance-transfers.write\n    /// scope for your organization.\n    /// </summary>\n    Task<BalanceTransferResponse> CreateBalanceTransferAsync(\n        BalanceTransferRequest request, CancellationToken cancellationToken = default);\n\n    /// <summary>\n    /// Returns a paginated list of balance transfers associated with your organization. These may be a balance transfer\n    /// that was received or sent from your balance, or a balance transfer that you initiated on behalf of your clients.\n    /// If no balance transfers are available, the resulting array will be empty. This request should never throw an error.\n    /// </summary>\n    Task<ListResponse<BalanceTransferResponse>> GetBalanceTransferListAsync(\n        string? from = null, int? limit = null, SortDirection? sort = null, bool testmode = false, CancellationToken cancellationToken = default);\n\n    /// <summary>\n    /// Retrieve a single Connect balance transfer object by its ID.\n    /// </summary>\n    Task<BalanceTransferResponse> GetBalanceTransferAsync(\n        string balanceTransferId, bool testmode = false, CancellationToken cancellationToken = default);\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IBaseMollieClient.cs",
    "content": "﻿using System;\n\nnamespace Mollie.Api.Client.Abstract\n{\n    public interface IBaseMollieClient : IDisposable\n    {\n        IDisposable WithIdempotencyKey(string value);\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ICapabilityClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Capability.Response;\nusing Mollie.Api.Models.List.Response;\n\nnamespace Mollie.Api.Client.Abstract;\n\npublic interface ICapabilityClient {\n    Task<ListResponse<CapabilityResponse>> GetCapabilitiesListAsync(CancellationToken cancellationToken = default);\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ICaptureClient.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Mollie.Api.Models.Capture.Request;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\nusing System.Threading;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface ICaptureClient : IBaseMollieClient {\n        Task<CaptureResponse> GetCaptureAsync(string paymentId, string captureId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<CaptureResponse> GetCaptureAsync(UrlObjectLink<CaptureResponse> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<CaptureResponse>> GetCaptureListAsync(string paymentId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<CaptureResponse>> GetCaptureListAsync(UrlObjectLink<ListResponse<CaptureResponse>> url, CancellationToken cancellationToken = default);\n        Task<CaptureResponse> CreateCapture(string paymentId, CaptureRequest captureRequest, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IChargebackClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IChargebackClient : IBaseMollieClient {\n        Task<ChargebackResponse> GetChargebackAsync(string paymentId, string chargebackId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<ChargebackResponse>> GetChargebackListAsync(string paymentId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<ChargebackResponse>> GetChargebackListAsync(string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<ChargebackResponse>> GetChargebackListAsync(UrlObjectLink<ListResponse<ChargebackResponse>> url, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IClientClient.cs",
    "content": "﻿using System.Threading.Tasks;\nusing Mollie.Api.Models.Client.Response;\nusing Mollie.Api.Models.List.Response;\nusing System.Threading;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IClientClient : IBaseMollieClient\n    {\n        Task<ClientResponse> GetClientAsync(\n            string clientId, bool embedOrganization = false, bool embedOnboarding = false, bool embedCapabilities = false, CancellationToken cancellationToken = default);\n\n        Task<ListResponse<ClientResponse>> GetClientListAsync(\n            string? from = null, int? limit = null, bool embedOrganization = false, bool embedOnboarding = false, bool embedCapabilities = false, CancellationToken cancellationToken = default);\n    }\n}\n\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IClientLinkClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.ClientLink.Request;\nusing Mollie.Api.Models.ClientLink.Response;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IClientLinkClient {\n        Task<ClientLinkResponse> CreateClientLinkAsync(ClientLinkRequest request, CancellationToken cancellationToken = default);\n\n        string GenerateClientLinkWithParameters(\n            string clientLinkUrl,\n            string state,\n            List<string> scopes,\n            bool forceApprovalPrompt = false);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IConnectClient.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Connect.Request;\nusing Mollie.Api.Models.Connect.Response;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IConnectClient : IDisposable\n    {\n        /// <summary>\n        ///     Constructs the Authorize URL for the Authorize endpoint from the parameters\n        /// </summary>\n        /// <param name=\"state\">A random string generated by your app to prevent CSRF attacks.</param>\n        /// <param name=\"scopes\">\n        ///     A space separated list of permissions your app requires. Refer to OAuth: Permissions for more\n        ///     information about the available scopes.\n        /// </param>\n        /// <param name=\"redirectUri\">\n        ///     The URL the merchant is sent back to once the request has been authorized. If given, it must\n        ///     match the URL you set when registering your app.\n        /// </param>\n        /// <param name=\"forceApprovalPrompt\">\n        ///     This parameter can be set to force, to force showing the consent screen to the\n        ///     merchant, even when it is not necessary\n        /// </param>\n        /// <param name=\"locale\">\n        ///     Allows you to preset the language to be used in the login / sign up / authorize flow if the merchant is not known by Mollie.\n        ///     When this parameter is omitted, the browser language will be used instead.\n        ///     You can provide any ISO 15897 locale, but the authorize flow currently only supports the following languages:\n        ///     Possible values: en_US nl_NL nl_BE fr_FR fr_BE de_DE es_ES it_IT\n        /// </param>\n        ///  <param name=\"landingPage\">\n        ///     Allows you to specify if Mollie should show the login or the signup page, when the merchant is not logged in at Mollie.\n        ///     Defaults to the login page. Defaults to login.\n        /// </param>\n        /// <returns>The url to the mollie consent screen.</returns>\n        string GetAuthorizationUrl(\n            string state,\n            List<string> scopes,\n            string? redirectUri = null,\n            bool forceApprovalPrompt = false,\n            string? locale = null,\n            string? landingPage = null);\n\n        /// <summary>\n        /// Exchange the auth code received at the Authorize endpoint for an actual access token, with which you can\n        /// communicate with the Mollie API. Or Refresh the accestoken\n        /// </summary>\n        /// <param name=\"request\"></param>\n        /// <param name=\"cancellationToken\"></param>\n        /// <returns>An token object.</returns>\n        Task<TokenResponse> GetAccessTokenAsync(TokenRequest request, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Revoke an access- or a refresh token. Once revoked the token can not be used anymore.\n        /// </summary>\n        /// <param name=\"request\"></param>\n        /// <param name=\"cancellationToken\"></param>\n        /// <returns></returns>\n        Task RevokeTokenAsync(RevokeTokenRequest request, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ICustomerClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Customer.Request;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface ICustomerClient : IBaseMollieClient {\n        Task<CustomerResponse> CreateCustomerAsync(CustomerRequest request, CancellationToken cancellationToken = default);\n        Task<CustomerResponse> UpdateCustomerAsync(string customerId, CustomerRequest request, CancellationToken cancellationToken = default);\n        Task DeleteCustomerAsync(string customerId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<CustomerResponse> GetCustomerAsync(string customerId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<CustomerResponse> GetCustomerAsync(UrlObjectLink<CustomerResponse> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<CustomerResponse>> GetCustomerListAsync(UrlObjectLink<ListResponse<CustomerResponse>> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<CustomerResponse>> GetCustomerListAsync(string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<PaymentResponse>> GetCustomerPaymentListAsync(string customerId, string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<PaymentResponse> CreateCustomerPayment(string customerId, PaymentRequest paymentRequest, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IInvoiceClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Invoice.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IInvoiceClient : IBaseMollieClient {\n        Task<InvoiceResponse> GetInvoiceAsync(string invoiceId, CancellationToken cancellationToken = default);\n        Task<InvoiceResponse> GetInvoiceAsync(UrlObjectLink<InvoiceResponse> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<InvoiceResponse>> GetInvoiceListAsync(\n            string? reference = null, int? year = null, string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<InvoiceResponse>> GetInvoiceListAsync(UrlObjectLink<ListResponse<InvoiceResponse>> url, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IMandateClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Mandate.Request;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IMandateClient : IBaseMollieClient {\n        Task<MandateResponse> GetMandateAsync(string customerId, string mandateId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<MandateResponse>> GetMandateListAsync(string customerId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<MandateResponse> CreateMandateAsync(string customerId, MandateRequest request, CancellationToken cancellationToken = default);\n        Task<ListResponse<MandateResponse>> GetMandateListAsync(UrlObjectLink<ListResponse<MandateResponse>> url, CancellationToken cancellationToken = default);\n        Task<MandateResponse> GetMandateAsync(UrlObjectLink<MandateResponse> url, CancellationToken cancellationToken = default);\n        Task RevokeMandate(string customerId, string mandateId, bool testmode = false, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IOnboardingClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Onboarding.Request;\nusing Mollie.Api.Models.Onboarding.Response;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IOnboardingClient : IBaseMollieClient {\n        Task<OnboardingStatusResponse> GetOnboardingStatusAsync(CancellationToken cancellationToken = default);\n\n        Task SubmitOnboardingDataAsync(SubmitOnboardingDataRequest request, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IOrderClient.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Order.Request.ManageOrderLines;\nusing Mollie.Api.Models.Order.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    [Obsolete(\"Mollie no longer recommends using the Orders API. Please refer to the Payments API instead.\")]\n    public interface IOrderClient : IBaseMollieClient {\n        Task<OrderResponse> CreateOrderAsync(OrderRequest orderRequest, CancellationToken cancellationToken = default);\n        Task<OrderResponse> GetOrderAsync(\n            string orderId, bool embedPayments = false, bool embedRefunds = false, bool embedShipments = false, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<OrderResponse> GetOrderAsync(UrlObjectLink<OrderResponse> url, CancellationToken cancellationToken = default);\n        Task<OrderResponse> UpdateOrderAsync(string orderId, OrderUpdateRequest orderUpdateRequest, CancellationToken cancellationToken = default);\n        Task<OrderResponse> UpdateOrderLinesAsync(string orderId, string orderLineId, OrderLineUpdateRequest orderLineUpdateRequest, CancellationToken cancellationToken = default);\n        Task<OrderResponse> ManageOrderLinesAsync(string orderId, ManageOrderLinesRequest manageOrderLinesRequest, CancellationToken cancellationToken = default);\n        Task CancelOrderAsync(string orderId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<OrderResponse>> GetOrderListAsync(\n            string? from = null, int? limit = null, string? profileId = null, bool testmode = false, SortDirection? sort = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<OrderResponse>> GetOrderListAsync(UrlObjectLink<ListResponse<OrderResponse>> url, CancellationToken cancellationToken = default);\n        Task CancelOrderLinesAsync(string orderId, OrderLineCancellationRequest cancelationRequest, CancellationToken cancellationToken = default);\n        Task<PaymentResponse> CreateOrderPaymentAsync(string orderId, OrderPaymentRequest createOrderPaymentRequest, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IOrganizationClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Organization;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IOrganizationClient : IBaseMollieClient {\n        Task<OrganizationResponse> GetCurrentOrganizationAsync(CancellationToken cancellationToken = default);\n        Task<OrganizationResponse> GetOrganizationAsync(string organizationId, CancellationToken cancellationToken = default);\n        Task<ListResponse<OrganizationResponse>> GetOrganizationListAsync(string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<OrganizationResponse>> GetOrganizationListAsync(UrlObjectLink<ListResponse<OrganizationResponse>> url, CancellationToken cancellationToken = default);\n        Task<OrganizationResponse> GetOrganizationAsync(UrlObjectLink<OrganizationResponse> url, CancellationToken cancellationToken = default);\n        Task<PartnerResponse> GetPartnerStatusAsync(CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IPaymentClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IPaymentClient : IBaseMollieClient {\n\n        /// <summary>\n        /// Create a payment object.\n        /// </summary>\n        /// <param name=\"paymentRequest\">The payment request object containing the payment details</param>\n        /// <param name=\"includeQrCode\">Include a QR code object for the payment. Only available for iDEAL, Bancontact and bank transfer payments.</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>The payment object created by Mollie. Once the payment is created, redirect the user to Links.Checkout.Redirect</returns>\n        Task<PaymentResponse> CreatePaymentAsync(\n            PaymentRequest paymentRequest,\n            bool includeQrCode = false,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        ///\tRetrieve a single payment object by its payment identifier.\n        /// </summary>\n        /// <param name=\"paymentId\">The payment's ID, for example tr_7UhSN1zuXS.</param>\n        /// <param name=\"testmode\">Oauth - Optional – Set this to true to get a payment made in test mode. If you omit\n        /// this parameter, you can only retrieve live mode payments.</param>\n        /// <param name=\"includeQrCode\">Include a QR code object. Only available for iDEAL, Bancontact and bank transfer\n        /// payments.</param>\n        /// <param name=\"includeRemainderDetails\">Include the Payment method-specific response parameters of the\n        /// ‘remainder payment’ as well. This applies to gift card and voucher payments where only part of the payment\n        /// was completed with gift cards or vouchers, and the remainder was completed with a regular payment method.\n        /// </param>\n        /// <param name=\"embedRefunds\">Include all refunds created for the payment.</param>\n        /// <param name=\"embedChargebacks\"> Include all chargebacks issued for the payment.</param>\n        /// <param name=\"cancellationToken\">A cancellation token that can be used to cancel the request.</param>\n        /// <returns></returns>\n        Task<PaymentResponse> GetPaymentAsync(\n            string paymentId,\n            bool testmode = false,\n            bool includeQrCode = false,\n            bool includeRemainderDetails = false,\n            bool embedRefunds = false,\n            bool embedChargebacks = false,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Some payment methods are cancellable for an amount of time, usually until the next day. Or as long as the\n        /// payment status is open. Payments may be cancelled manually from the Dashboard, or automatically by using\n        /// this endpoint.\n        /// </summary>\n        /// <param name=\"paymentId\"></param>\n        /// <param name=\"testmode\">Oauth - Optional – Set this to true to cancel a test mode payment.</param>\n        /// <param name=\"cancellationToken\">A cancellation token that can be used to cancel the request.</param>\n        /// <returns></returns>\n        Task CancelPaymentAsync(\n            string paymentId,\n            bool testmode = false,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Releases the full remaining authorized amount. Call this endpoint when you will not be making any additional\n        /// captures. Payment authorizations may also be released manually from the Mollie Dashboard.\n        /// </summary>\n        /// <param name=\"paymentId\">Provide the ID of the related payment.</param>\n        /// <param name=\"testmode\">Oauth - Optional – Set this to true to release the authorization of a test mode payment.</param>\n        /// <param name=\"cancellationToken\"></param>\n        /// <returns></returns>\n        Task ReleasePaymentAuthorization(\n            string paymentId, bool testmode = false, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve all payments created with the current payment profile, ordered from newest to oldest.\n        /// </summary>\n        /// <param name=\"from\">Used for pagination. Offset the result set to the payment with this ID. The payment with\n        /// this ID is included in the result set as well.</param>\n        /// <param name=\"limit\">The number of payments to return (with a maximum of 250).</param>\n        /// <param name=\"profileId\">The website profile’s unique identifier, for example pfl_3RkSN1zuPE. Omit this\n        /// parameter to retrieve all payments across all profiles.</param>\n        /// <param name=\"testmode\">Set this to true to only retrieve payments made in test mode. By default, only live\n        /// payments are returned.</param>\n        /// <param name=\"includeQrCode\">Include a QR code object for each payment that supports it. Only available for\n        /// iDEAL, Bancontact and bank transfer payments.</param>\n        /// <param name=\"embedRefunds\">Include any refunds created for the payments.</param>\n        /// <param name=\"embedChargebacks\">Include any chargebacks issued for the payments.</param>\n        /// <param name=\"sort\">Used for setting the direction of the results based on the from parameter. Can be set\n        /// to desc or asc. Default is desc.</param>\n        /// <param name=\"cancellationToken\">A cancellation token that can be used to cancel the request.</param>\n        /// <returns></returns>\n\t\tTask<ListResponse<PaymentResponse>> GetPaymentListAsync(\n            string? from = null,\n            int? limit = null,\n            string? profileId = null,\n            bool testmode = false,\n            bool includeQrCode = false,\n            bool embedRefunds = false,\n            bool embedChargebacks = false,\n            SortDirection? sort = null,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a list of payments by URL\n        /// </summary>\n        /// <param name=\"url\">The URL from which to retrieve the payments</param>\n        /// <param name=\"cancellationToken\">A cancellation token that can be used to cancel the request.</param>\n        /// <returns>A list of paginated payments</returns>\n        Task<ListResponse<PaymentResponse>> GetPaymentListAsync(\n            UrlObjectLink<ListResponse<PaymentResponse>> url,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a single payment by URL\n        /// </summary>\n        /// <param name=\"url\">The URL from which to retrieve the payment</param>\n        /// <param name=\"cancellationToken\">A cancellation token that can be used to cancel the request.</param>\n        /// <returns>The found payment</returns>\n        Task<PaymentResponse> GetPaymentAsync(\n            UrlObjectLink<PaymentResponse> url,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// This endpoint can be used to update some details of a created payment.\n        /// </summary>\n        /// <param name=\"paymentId\">The payment id to update</param>\n        /// <param name=\"paymentUpdateRequest\">The payment parameters to update</param>\n        /// <param name=\"cancellationToken\">A cancellation token that can be used to cancel the request.</param>\n        /// <returns>The changed payment</returns>\n        /// <remarks>Updating the payment details will not result in a webhook call</remarks>\n        Task<PaymentResponse> UpdatePaymentAsync(\n            string paymentId,\n            PaymentUpdateRequest paymentUpdateRequest,\n            CancellationToken cancellationToken = default);\n    }\n}\n\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IPaymentLinkClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.PaymentLink.Request;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IPaymentLinkClient : IBaseMollieClient {\n        /// <summary>\n        /// Create a new payment link\n        /// </summary>\n        /// <param name=\"paymentLinkRequest\">The payment link request</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        /// <returns></returns>\n        Task<PaymentLinkResponse> CreatePaymentLinkAsync(\n            PaymentLinkRequest paymentLinkRequest,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Update a payment link\n        /// </summary>\n        /// <param name=\"paymentLinkId\">Provide the ID of the item you want to perform this operation on.</param>\n        /// <param name=\"paymentLinkUpdateRequest\">The request body</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        /// <returns>The updated payment link response</returns>\n        Task<PaymentLinkResponse> UpdatePaymentLinkAsync(\n            string paymentLinkId,\n            PaymentLinkUpdateRequest paymentLinkUpdateRequest,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Payment links for which no payments have been made yet can be deleted entirely. This can be useful for\n        /// removing payment links that have been incorrectly configured or that are no longer relevant.\n        /// </summary>\n        /// <param name=\"paymentLinkId\">Provide the ID of the item you want to perform this operation on.</param>\n        /// <param name=\"profileId\">The website profile’s unique identifier, for example pfl_3RkSN1zuPE.</param>\n        /// <param name=\"testmode\">Most API credentials are specifically created for either live mode or test mode.\n        /// In those cases the testmode query parameter can be omitted. For organization-level credentials such as\n        /// OAuth access tokens, you can enable test mode by setting the testmode query parameter to true.</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        /// <returns></returns>\n        Task DeletePaymentLinkAsync(\n            string paymentLinkId,\n            string? profileId = null,\n            bool testmode = false,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        ///\tRetrieve a single payment link object by its token.\n        /// </summary>\n        /// <param name=\"paymentLinkId\">The payment link to retrieve</param>\n        /// <param name=\"testmode\">Oauth - Optional – Set this to true to get a payment links made in test mode. If you omit\n        /// this parameter, you can only retrieve live mode payments.</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        Task<PaymentLinkResponse> GetPaymentLinkAsync(\n            string paymentLinkId,\n            bool testmode = false,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve all payment links created with the current payment link profile, ordered from newest to oldest.\n        /// </summary>\n        /// <param name=\"from\">Used for pagination. Offset the result set to the payment link with this ID. The payment\n        /// link with this ID is included in the result set as well.</param>\n        /// <param name=\"limit\">The number of payment links to return (with a maximum of 250).</param>\n        /// <param name=\"profileId\">The website profile’s unique identifier, for example pfl_3RkSN1zuPE. Omit this\n        /// parameter to retrieve the payment links of all profiles of the current organization.</param>\n        /// <param name=\"testmode\">Set this to true to only retrieve payment links made in test mode. By default, only\n        /// live payment links are returned.</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        /// <returns></returns>\n\t\tTask<ListResponse<PaymentLinkResponse>> GetPaymentLinkListAsync(\n            string? from = null,\n            int? limit = null,\n            string? profileId = null,\n            bool testmode = false,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a list of payment links by URL\n        /// </summary>\n        /// <param name=\"url\">The URL from which to retrieve the payment links</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        /// <returns></returns>\n        Task<ListResponse<PaymentLinkResponse>> GetPaymentLinkListAsync(\n            UrlObjectLink<ListResponse<PaymentLinkResponse>> url,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a single payment link by URL\n        /// </summary>\n        /// <param name=\"url\">The URL from which to retrieve the payment link</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        /// <returns></returns>\n        Task<PaymentLinkResponse> GetPaymentLinkAsync(\n            UrlObjectLink<PaymentLinkResponse> url,\n            CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve the list of payments for a specific payment link.\n        /// </summary>\n        /// <param name=\"paymentLinkId\">Provide the ID of the item you want to perform this operation on.</param>\n        /// <param name=\"from\">Provide an ID to start the result set from the item with the given ID and onwards. This\n        /// allows you to paginate the result set.</param>\n        /// <param name=\"limit\">The maximum number of items to return. Defaults to 50 items.</param>\n        /// <param name=\"testmode\">Most API credentials are specifically created for either live mode or test mode. In\n        /// those cases the testmode query parameter can be omitted. For organization-level credentials such as OAuth access\n        /// tokens, you can enable test mode by setting the testmode query parameter to true. Test entities cannot be\n        /// retrieved when the endpoint is set to live mode, and vice versa.</param>\n        /// <param name=\"sort\">Used for setting the direction of the result set. Defaults to descending order, meaning\n        /// the results are ordered from newest to oldest.</param>\n        /// <param name=\"cancellationToken\">Token to cancel the operation</param>\n        /// <returns></returns>\n        Task<ListResponse<PaymentResponse>> GetPaymentLinkPaymentListAsync(\n            string paymentLinkId,\n            string? from = null,\n            int? limit = null,\n            bool testmode = false,\n            SortDirection? sort = null,\n            CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IPaymentMethodClient.cs",
    "content": "﻿﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.PaymentMethod.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IPaymentMethodClient : IBaseMollieClient {\n        Task<PaymentMethodResponse> GetPaymentMethodAsync(\n            string paymentMethod,\n            bool includeIssuers = false,\n            string? locale = null,\n            string? profileId = null,\n            bool testmode = false,\n            string? currency = null,\n            CancellationToken cancellationToken = default);\n\n        Task<ListResponse<PaymentMethodResponse>> GetAllPaymentMethodListAsync(\n            string? locale = null,\n            Amount? amount = null,\n            bool includeIssuers = false,\n            bool includePricing = false,\n            string? profileId = null,\n            bool testmode = false,\n            CancellationToken cancellationToken = default);\n\n        Task<ListResponse<PaymentMethodResponse>> GetPaymentMethodListAsync(\n            string? sequenceType = null,\n            string? locale = null,\n            Amount? amount = null,\n            bool includeIssuers = false,\n            string? profileId = null,\n            bool testmode = false,\n            Resource? resource = null,\n            string? billingCountry = null,\n            string? includeWallets = null,\n            CancellationToken cancellationToken = default);\n\n        Task<PaymentMethodResponse> GetPaymentMethodAsync(UrlObjectLink<PaymentMethodResponse> url,\n            CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IPermissionClient.cs",
    "content": "﻿﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Permission.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IPermissionClient : IBaseMollieClient {\n        Task<PermissionResponse> GetPermissionAsync(string permissionId,\n            CancellationToken cancellationToken = default);\n        Task<PermissionResponse> GetPermissionAsync(UrlObjectLink<PermissionResponse> url,\n            CancellationToken cancellationToken = default);\n        Task<ListResponse<PermissionResponse>> GetPermissionListAsync(\n            CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IProfileClient.cs",
    "content": "﻿﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.PaymentMethod.Response;\nusing Mollie.Api.Models.Profile.Request;\nusing Mollie.Api.Models.Profile.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IProfileClient : IBaseMollieClient {\n        Task<ProfileResponse> CreateProfileAsync(ProfileRequest request, CancellationToken cancellationToken = default);\n        Task<ProfileResponse> GetProfileAsync(string profileId, CancellationToken cancellationToken = default);\n        Task<ProfileResponse> GetProfileAsync(UrlObjectLink<ProfileResponse> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<ProfileResponse>> GetProfileListAsync(string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<ProfileResponse>> GetProfileListAsync(UrlObjectLink<ListResponse<ProfileResponse>> url, CancellationToken cancellationToken = default);\n        Task<ProfileResponse> UpdateProfileAsync(string profileId, ProfileRequest request, CancellationToken cancellationToken = default);\n        Task DeleteProfileAsync(string profileId, CancellationToken cancellationToken = default);\n        Task<ProfileResponse> GetCurrentProfileAsync(CancellationToken cancellationToken = default);\n        Task<PaymentMethodResponse> EnablePaymentMethodAsync(string profileId, string paymentMethod, CancellationToken cancellationToken = default);\n        Task<PaymentMethodResponse> EnablePaymentMethodAsync(string paymentMethod, CancellationToken cancellationToken = default);\n        Task DisablePaymentMethodAsync(string profileId, string paymentMethod, CancellationToken cancellationToken = default);\n        Task DisablePaymentMethodAsync(string paymentMethod, CancellationToken cancellationToken = default);\n        Task<EnableGiftCardIssuerResponse> EnableGiftCardIssuerAsync(string profileId, string issuer, CancellationToken cancellationToken = default);\n        Task<EnableGiftCardIssuerResponse> EnableGiftCardIssuerAsync(string issuer, CancellationToken cancellationToken = default);\n        Task DisableGiftCardIssuerAsync(string profileId, string issuer, CancellationToken cancellationToken = default);\n        Task DisableGiftCardIssuerAsync(string issuer, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IRefundClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Order.Response;\nusing Mollie.Api.Models.Refund.Request;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IRefundClient : IBaseMollieClient {\n        Task<RefundResponse> CreatePaymentRefundAsync(string paymentId, RefundRequest refundRequest, CancellationToken cancellationToken = default);\n        Task<RefundResponse> GetPaymentRefundAsync(string paymentId, string refundId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task CancelPaymentRefundAsync(string paymentId, string refundId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<RefundResponse>> GetPaymentRefundListAsync(string paymentId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<OrderRefundResponse> CreateOrderRefundAsync(string orderId, OrderRefundRequest createOrderRefundRequest, CancellationToken cancellationToken = default);\n        Task<ListResponse<RefundResponse>> GetOrderRefundListAsync(string orderId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<RefundResponse>> GetRefundListAsync(UrlObjectLink<ListResponse<RefundResponse>> url, CancellationToken cancellationToken = default);\n        Task<RefundResponse> GetRefundAsync(UrlObjectLink<RefundResponse> url, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ISalesInvoiceClient.cs",
    "content": "﻿using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.SalesInvoice.Request;\nusing Mollie.Api.Models.SalesInvoice.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract;\n\npublic interface ISalesInvoiceClient : IDisposable {\n    Task<SalesInvoiceResponse> CreateSalesInvoiceAsync(\n        SalesInvoiceRequest salesInvoiceRequest, CancellationToken cancellationToken = default);\n    Task<ListResponse<SalesInvoiceResponse>> GetSalesInvoiceListAsync(\n        string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default);\n    Task<ListResponse<SalesInvoiceResponse>> GetSalesInvoiceListAsync(\n        UrlObjectLink<ListResponse<SalesInvoiceResponse>> url, CancellationToken cancellationToken = default);\n    Task<SalesInvoiceResponse> GetSalesInvoiceAsync(\n        string salesInvoiceId, bool testmode = false, CancellationToken cancellationToken = default);\n    Task<SalesInvoiceResponse> GetSalesInvoiceAsync(\n        UrlObjectLink<SalesInvoiceResponse> url, CancellationToken cancellationToken = default);\n    Task<SalesInvoiceResponse> UpdateSalesInvoiceAsync(\n        string salesInvoiceId, SalesInvoiceUpdateRequest salesInvoiceRequest, CancellationToken cancellationToken = default);\n    Task DeleteSalesInvoiceAsync(string salesInvoiceId, bool testmode = false, CancellationToken cancellationToken = default);\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ISessionClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Session.Request;\nusing Mollie.Api.Models.Session.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface ISessionClient : IBaseMollieClient {\n\n        /// <summary>\n        /// Create a new Session.\n        /// </summary>\n        /// <param name=\"request\">The Session request object containing the Session details</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>The Session object created by Mollie</returns>\n        Task<SessionResponse> CreateSessionAsync(SessionRequest request, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a single Session by its ID.\n        /// </summary>\n        /// <param name=\"sessionId\">The Session ID of the Session to retrieve</param>\n        /// <param name=\"testmode\">Indicates whether the Session is in test mode or not</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>The Session object retrieved by Mollie</returns>\n        Task<SessionResponse> GetSessionAsync(string sessionId, bool testmode = false, CancellationToken cancellationToken = default);\n\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ISettlementClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface ISettlementClient : IBaseMollieClient {\n        Task<SettlementResponse> GetSettlementAsync(string settlementId, CancellationToken cancellationToken = default);\n        Task<SettlementResponse> GetNextSettlement(CancellationToken cancellationToken = default);\n        Task<SettlementResponse> GetOpenSettlement(CancellationToken cancellationToken = default);\n        Task<ListResponse<SettlementResponse>> GetSettlementListAsync(string? reference = null, string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<SettlementResponse>> GetSettlementListAsync(UrlObjectLink<ListResponse<SettlementResponse>> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<PaymentResponse>> GetSettlementPaymentListAsync(string settlementId, string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<PaymentResponse>> GetSettlementPaymentListAsync(UrlObjectLink<ListResponse<PaymentResponse>> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<RefundResponse>> GetSettlementRefundListAsync(string settlementId, string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<RefundResponse>> GetSettlementRefundListAsync(UrlObjectLink<ListResponse<RefundResponse>> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<ChargebackResponse>> GetSettlementChargebackListAsync(string settlementId, string? from = null, int? limit = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<ChargebackResponse>> GetSettlementChargebackListAsync(UrlObjectLink<ListResponse<ChargebackResponse>> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<CaptureResponse>> GetSettlementCaptureListAsync(string settlementId, string? offset = null, int? count = null, CancellationToken cancellationToken = default);\n        Task<ListResponse<CaptureResponse>> GetSettlementCaptureListAsync(UrlObjectLink<ListResponse<CaptureResponse>> url, CancellationToken cancellationToken = default);\n        Task<SettlementResponse> GetSettlementAsync(UrlObjectLink<SettlementResponse> url, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IShipmentClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Shipment.Request;\nusing Mollie.Api.Models.Shipment.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IShipmentClient : IBaseMollieClient {\n        Task<ShipmentResponse> CreateShipmentAsync(string orderId, ShipmentRequest shipmentRequest, CancellationToken cancellationToken = default);\n        Task<ShipmentResponse> GetShipmentAsync(string orderId, string shipmentId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ShipmentResponse> GetShipmentAsync(UrlObjectLink<ShipmentResponse> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<ShipmentResponse>> GetShipmentListAsync(string orderId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<ShipmentResponse>> GetShipmentListAsync(UrlObjectLink<ListResponse<ShipmentResponse>> url, CancellationToken cancellationToken = default);\n        Task<ShipmentResponse> UpdateShipmentAsync(string orderId, string shipmentId, ShipmentUpdateRequest shipmentUpdateRequest, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ISubscriptionClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Subscription.Request;\nusing Mollie.Api.Models.Subscription.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface ISubscriptionClient : IBaseMollieClient {\n        /// <summary>\n        /// Cancel an existing subscription. Canceling a subscription has no effect on the mandates of the customer.\n        /// </summary>\n        /// <param name=\"customerId\">The customer ID of the customer to which the subscription belongs</param>\n        /// <param name=\"subscriptionId\">The subscription ID of the subscription to cancel</param>\n        /// <param name=\"testmode\">Indicates whether the subscription is in test mode or not</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request. Cancelling the token might not cancel the subscription</param>\n        Task CancelSubscriptionAsync(string customerId, string subscriptionId, bool testmode = false, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Create a new subscription for a customer.\n        /// </summary>\n        /// <param name=\"customerId\">The customer ID of the customer to which the subscription belongs</param>\n        /// <param name=\"request\">The subscription request object containing the subscription details</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>The subscription object created by Mollie</returns>\n        Task<SubscriptionResponse> CreateSubscriptionAsync(string customerId, SubscriptionRequest request, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve a single subscription by its ID and the ID of its parent customer.\n        /// </summary>\n        /// <param name=\"customerId\">The customer ID of the customer to which the subscription belongs</param>\n        /// <param name=\"subscriptionId\">The subscription ID of the subscription to retrieve</param>\n        /// <param name=\"testmode\">Indicates whether the subscription is in test mode or not</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>The subscription object retrieved by Mollie</returns>\n        Task<SubscriptionResponse> GetSubscriptionAsync(string customerId, string subscriptionId, bool testmode = false, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Retrieve all subscriptions of a customer.\n        /// </summary>\n        /// <param name=\"customerId\">The customer ID of the customer to which the subscription belongs</param>\n        /// <param name=\"from\">The cursor to start pagination from</param>\n        /// <param name=\"limit\">The maximum number of subscriptions to return</param>\n        /// <param name=\"profileId\">The profile ID to filter subscriptions by</param>\n        /// <param name=\"testmode\">Indicates whether the subscription is in test mode or not</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>A list of paginated subscriptions</returns>\n        Task<ListResponse<SubscriptionResponse>> GetSubscriptionListAsync(string customerId, string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<SubscriptionResponse>> GetSubscriptionListAsync(UrlObjectLink<ListResponse<SubscriptionResponse>> url, CancellationToken cancellationToken = default);\n        /// <summary>\n        /// Get all subscriptions\n        /// </summary>\n        /// <param name=\"from\">The cursor to start pagination from</param>\n        /// <param name=\"limit\">The maximum number of subscriptions to return</param>\n        /// <param name=\"profileId\">The profile ID to filter subscriptions by</param>\n        /// <param name=\"testmode\">Indicates whether the subscription is in test mode or not</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>A list of paginated subscriptions</returns>\n        Task<ListResponse<SubscriptionResponse>> GetAllSubscriptionList(string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<SubscriptionResponse> GetSubscriptionAsync(UrlObjectLink<SubscriptionResponse> url, CancellationToken cancellationToken = default);\n\n        /// <summary>\n        /// Update an existing subscription.\n        /// </summary>\n        /// <param name=\"customerId\">The customer ID of the customer to which the subscription belongs</param>\n        /// <param name=\"subscriptionId\">The subscription ID of the subscription to update</param>\n        /// <param name=\"request\">The subscription update request</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>The updated subscription object</returns>\n        /// <remarks>Canceled subscriptions cannot be updated</remarks>\n        Task<SubscriptionResponse> UpdateSubscriptionAsync(string customerId, string subscriptionId, SubscriptionUpdateRequest request, CancellationToken cancellationToken = default);\n        /// <summary>\n        /// Retrieve all payments of a specific subscription.\n        /// </summary>\n        /// <param name=\"customerId\">The customer ID of the customer to which the subscription belongs</param>\n        /// <param name=\"subscriptionId\">The subscription ID of the subscription to retrieve payments for</param>\n        /// <param name=\"from\">The cursor to start pagination from</param>\n        /// <param name=\"limit\">The maximum number of payments to return</param>\n        /// <param name=\"testmode\">Indicates whether the subscription is in test mode or not</param>\n        /// <param name=\"cancellationToken\">Token to cancel the request</param>\n        /// <returns>A list of paginated payments</returns>\n        Task<ListResponse<PaymentResponse>> GetSubscriptionPaymentListAsync(string customerId, string subscriptionId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/ITerminalClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Terminal.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client.Abstract\n{    /// <summary>\n     /// Calls in this class are documented in https://docs.mollie.com/reference/v2/terminals-api/overview\n     /// </summary>\n    public interface ITerminalClient : IBaseMollieClient {\n        Task<TerminalResponse> GetTerminalAsync(string terminalId, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<TerminalResponse> GetTerminalAsync(UrlObjectLink<TerminalResponse> url, CancellationToken cancellationToken = default);\n        Task<ListResponse<TerminalResponse>> GetTerminalListAsync(string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default);\n        Task<ListResponse<TerminalResponse>> GetTerminalListAsync(UrlObjectLink<ListResponse<TerminalResponse>> url, CancellationToken cancellationToken = default);\n     }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IWalletClient.cs",
    "content": "﻿using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.Wallet.Request;\nusing Mollie.Api.Models.Wallet.Response;\n\nnamespace Mollie.Api.Client.Abstract {\n    public interface IWalletClient : IBaseMollieClient {\n        Task<ApplePayPaymentSessionResponse> RequestApplePayPaymentSessionAsync(ApplePayPaymentSessionRequest request, CancellationToken cancellationToken = default);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IWebhookClient.cs",
    "content": "using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Models.Webhook.Request;\nusing Mollie.Api.Models.Webhook.Response;\n\nnamespace Mollie.Api.Client.Abstract;\n\npublic interface IWebhookClient : IBaseMollieClient {\n    Task<WebhookResponse> CreateWebhookAsync(WebhookRequest request, CancellationToken cancellationToken = default);\n\n    Task<ListResponse<WebhookResponse>> GetWebhookListAsync(string? from = null, int? limit = null,\n        bool testmode = false, CancellationToken cancellationToken = default);\n\n    Task<ListResponse<WebhookResponse>> GetWebhookListAsync(\n        UrlObjectLink<ListResponse<WebhookResponse>> url, CancellationToken cancellationToken = default);\n\n    Task<WebhookResponse> GetWebhookAsync(string webhookId, bool testmode = false,\n        CancellationToken cancellationToken = default);\n\n    Task<WebhookResponse> UpdateWebhookAsync(string webhookId, WebhookRequest request, CancellationToken cancellationToken = default);\n\n    Task DeleteWebhookAsync(string webhookId, bool testmode = false, CancellationToken cancellationToken = default);\n\n    Task TestWebhookAsync(string webhookId, bool testmode = false, CancellationToken cancellationToken = default);\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/Abstract/IWebhookEventClient.cs",
    "content": "using System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.WebhookEvent.Response;\n\nnamespace Mollie.Api.Client.Abstract;\n\npublic interface IWebhookEventClient : IBaseMollieClient {\n    Task<FullWebhookEventResponse<T>> GetWebhookEventAsync<T>(string webhookEventId, bool testmode = false,\n        CancellationToken cancellationToken = default) where T : IEntity;\n\n    Task<FullWebhookEventResponse> GetWebhookEventAsync(string webhookEventId, bool testmode = false,\n        CancellationToken cancellationToken = default);\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/BalanceClient.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Balance.Response;\nusing Mollie.Api.Models.Balance.Response.BalanceReport;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class BalanceClient : BaseMollieClient, IBalanceClient {\n        public BalanceClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public BalanceClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<BalanceResponse> GetBalanceAsync(string balanceId, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(balanceId), balanceId);\n            return await GetAsync<BalanceResponse>($\"balances/{balanceId}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<BalanceResponse> GetBalanceAsync(UrlObjectLink<BalanceResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<BalanceResponse> GetPrimaryBalanceAsync(CancellationToken cancellationToken = default) {\n            return await GetAsync<BalanceResponse>(\"balances/primary\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<BalanceResponse>> GetBalanceListAsync(\n            string? from = null, int? limit = null, string? currency = null, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildListBalanceQueryParameters(currency);\n            return await GetListAsync<ListResponse<BalanceResponse>>(\n                $\"balances\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<BalanceResponse>> GetBalanceListAsync(\n            UrlObjectLink<ListResponse<BalanceResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<BalanceReportResponse> GetBalanceReportAsync(\n            string balanceId, DateTime from, DateTime until, string? grouping = null, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(balanceId), balanceId);\n            var queryParameters = BuildGetBalanceReportQueryParameters(from, until, grouping);\n            return await GetAsync<BalanceReportResponse>(\n                $\"balances/{balanceId}/report{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<BalanceReportResponse> GetPrimaryBalanceReportAsync(\n            DateTime from, DateTime until, string? grouping = null, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildGetBalanceReportQueryParameters(from, until, grouping);\n            return await GetAsync<BalanceReportResponse>(\n                $\"balances/primary/report{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<BalanceTransactionResponse>> GetBalanceTransactionListAsync(\n            string balanceId, string? from = null, int? limit = null, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(balanceId), balanceId);\n            return await GetListAsync<ListResponse<BalanceTransactionResponse>>(\n                    $\"balances/{balanceId}/transactions\", from, limit, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<BalanceTransactionResponse>> GetPrimaryBalanceTransactionListAsync(\n            string? from = null, int? limit = null, CancellationToken cancellationToken = default) {\n            return await GetListAsync<ListResponse<BalanceTransactionResponse>>(\n                    $\"balances/primary/transactions\", from, limit, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<BalanceTransactionResponse>> GetBalanceTransactionListAsync(\n            UrlObjectLink<ListResponse<BalanceTransactionResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        private Dictionary<string, string> BuildGetBalanceReportQueryParameters(DateTime from, DateTime until, string? grouping = null) {\n            var result = new Dictionary<string, string>();\n            result.AddValueIfNotNullOrEmpty(\"from\", from.ToString(\"yyyy-MM-dd\"));\n            result.AddValueIfNotNullOrEmpty(\"until\", until.ToString(\"yyyy-MM-dd\"));\n            result.AddValueIfNotNullOrEmpty(\"grouping\", grouping);\n            return result;\n        }\n\n        private Dictionary<string, string> BuildListBalanceQueryParameters(string? currency) {\n            var result = new Dictionary<string, string>();\n            result.AddValueIfNotNullOrEmpty(\"currency\", currency);\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/BalanceTransferClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.BalanceTransfer.Request;\nusing Mollie.Api.Models.BalanceTransfer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client;\n\npublic class BalanceTransferClient : BaseMollieClient, IBalanceTransferClient {\n    public BalanceTransferClient(string oauthAccessToken, HttpClient? httpClient = null)\n        : base(oauthAccessToken, httpClient)\n    {\n    }\n\n    [ActivatorUtilitiesConstructor]\n    public BalanceTransferClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n        : base(options, mollieSecretManager, httpClient)\n    {\n    }\n\n    public async Task<BalanceTransferResponse> CreateBalanceTransferAsync(\n        BalanceTransferRequest request, CancellationToken cancellationToken = default) {\n        return await PostAsync<BalanceTransferResponse>(\n                \"connect/balance-transfers\", request, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<ListResponse<BalanceTransferResponse>> GetBalanceTransferListAsync(\n        string? from = null, int? limit = null, SortDirection? sort = null, bool testmode = false, CancellationToken cancellationToken = default) {\n        var queryParameters = BuildQueryParameters(testmode: testmode, sort: sort);\n        return await GetListAsync<ListResponse<BalanceTransferResponse>>(\n                \"connect/balance-transfers\", from, limit, queryParameters, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<BalanceTransferResponse> GetBalanceTransferAsync(\n        string balanceTransferId, bool testmode = false, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(balanceTransferId), balanceTransferId);\n        var queryParameters = BuildQueryParameters(testmode: testmode);\n        return await GetAsync<BalanceTransferResponse>(\n                $\"connect/balance-transfers/{balanceTransferId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/BaseMollieClient.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Reflection;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework;\nusing Mollie.Api.Framework.Authentication;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Framework.Idempotency;\nusing Mollie.Api.Models.Error;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\n\nnamespace Mollie.Api.Client {\n    public abstract class BaseMollieClient : IBaseMollieClient {\n        public const string DefaultBaseApiEndPoint = \"https://api.mollie.com/v2/\";\n\n        private readonly string _apiEndpoint = DefaultBaseApiEndPoint;\n        private readonly IMollieSecretManager _mollieSecretManager;\n        private readonly MollieClientOptions _options;\n        private readonly HttpClient _httpClient;\n        private readonly JsonConverterService _jsonConverterService;\n\n        private readonly AsyncLocalVariable<string> _idempotencyKey = new (null);\n\n        private readonly bool _createdHttpClient;\n\n        protected BaseMollieClient(string apiKey, HttpClient? httpClient = null) {\n            if (string.IsNullOrWhiteSpace(apiKey)) {\n                throw new ArgumentNullException(nameof(apiKey), \"Mollie API key cannot be empty\");\n            }\n\n            _jsonConverterService = new JsonConverterService();\n            _createdHttpClient = httpClient == null;\n            _httpClient = httpClient ?? new HttpClient();\n            _mollieSecretManager = new DefaultMollieSecretManager(apiKey);\n            _options = new MollieClientOptions {\n                ApiKey = apiKey\n            };\n        }\n\n        protected BaseMollieClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null) {\n            _jsonConverterService = new JsonConverterService();\n            _createdHttpClient = httpClient == null;\n            _httpClient = httpClient ?? new HttpClient();\n            _mollieSecretManager = mollieSecretManager;\n            _options = options;\n            _apiEndpoint = options.ApiBaseUrl;\n        }\n\n        protected BaseMollieClient(HttpClient? httpClient = null, string apiEndpoint = DefaultBaseApiEndPoint) {\n            _apiEndpoint = apiEndpoint;\n            _jsonConverterService = new JsonConverterService();\n            _createdHttpClient = httpClient == null;\n            _httpClient = httpClient ?? new HttpClient();\n            _mollieSecretManager = new DefaultMollieSecretManager(string.Empty);\n            _options = new() {\n                ApiKey = string.Empty\n            };\n        }\n\n        public IDisposable WithIdempotencyKey(string value) {\n            _idempotencyKey.Value = value;\n            return _idempotencyKey;\n        }\n\n        private async Task<T> SendHttpRequest<T>(\n            HttpMethod httpMethod, string relativeUri, object? data = null, CancellationToken cancellationToken = default) {\n            HttpRequestMessage httpRequest = CreateHttpRequest(httpMethod, relativeUri);\n            if (data != null) {\n                if (data is ITestModeRequest testModeRequest) {\n                    testModeRequest.Testmode ??= _options.Testmode;\n                }\n\n                if (data is IProfileRequest profileRequest) {\n                    profileRequest.ProfileId ??= _options.ProfileId;\n                }\n\n                var jsonData = _jsonConverterService.Serialize(data);\n                var content = new StringContent(jsonData, Encoding.UTF8, \"application/json\");\n                httpRequest.Content = content;\n            }\n\n            var response = await _httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);\n            return await ProcessHttpResponseMessage<T>(response).ConfigureAwait(false);\n        }\n\n        protected async Task<T> GetListAsync<T>(\n            string relativeUri, string? from, int? limit, IDictionary<string, string>? otherParameters = null, CancellationToken cancellationToken = default) {\n            string url = relativeUri + BuildListQueryString(from, limit, otherParameters);\n            return await SendHttpRequest<T>(HttpMethod.Get, url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        protected async Task<T> GetAsync<T>(string relativeUri, CancellationToken cancellationToken = default) {\n            return await SendHttpRequest<T>(HttpMethod.Get, relativeUri, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        protected async Task<T> GetAsync<T>(UrlObjectLink<T> urlObject, CancellationToken cancellationToken = default) {\n            ValidateUrlLink(urlObject);\n            return await GetAsync<T>(urlObject.Href, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        protected async Task<T> PostAsync<T>(\n            string relativeUri, object? data, CancellationToken cancellationToken = default) {\n            return await SendHttpRequest<T>(HttpMethod.Post, relativeUri, data, cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        protected async Task<T> PatchAsync<T>(string relativeUri, object? data, CancellationToken cancellationToken = default) {\n            return await SendHttpRequest<T>(new HttpMethod(\"PATCH\"), relativeUri, data, cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        protected async Task DeleteAsync(string relativeUri, object? data = null, CancellationToken cancellationToken = default) {\n            await SendHttpRequest<object>(HttpMethod.Delete, relativeUri, data, cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        private async Task<T> ProcessHttpResponseMessage<T>(HttpResponseMessage response) {\n            var resultContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);\n\n            if (response.IsSuccessStatusCode) {\n                resultContent = string.IsNullOrEmpty(resultContent) ? \"{}\" : resultContent;\n                return _jsonConverterService.Deserialize<T>(resultContent)!;\n            }\n\n            MollieErrorMessage errorDetails = ParseMollieErrorMessage(response.StatusCode, resultContent);\n            throw new MollieApiException(errorDetails);\n        }\n\n        protected void ValidateApiKeyIsOauthAccesstoken(bool isConstructor = false) {\n            string apiKey = _mollieSecretManager.GetBearerToken();\n            if (!apiKey.StartsWith(\"access_\")) {\n                if (isConstructor) {\n                    throw new InvalidOperationException(\n                        \"The provided token isn't an oauth token. Are you trying to use oauth specific clients using an API key?\");\n                }\n\n                throw new InvalidOperationException(\n                    \"The provided token isn't an oauth token. Are you trying to use oauth specific parameters such as ProfileId or TestMode using an API key?\");\n            }\n        }\n\n        private void ValidateUrlLink(UrlLink urlObject) {\n            // Make sure the URL is not empty\n            if (string.IsNullOrEmpty(urlObject.Href)) {\n                throw new ArgumentException($\"Url object is null or href is empty: {urlObject}\");\n            }\n\n            // Don't execute any requests that don't point to the Mollie API URL for security reasons\n            if (!urlObject.Href.Contains(_apiEndpoint)) {\n                throw new ArgumentException($\"Url does not point to the Mollie API: {urlObject.Href}\");\n            }\n        }\n\n        protected virtual HttpRequestMessage CreateHttpRequest(HttpMethod method, string relativeUri, HttpContent? content = null) {\n            var httpRequest = new HttpRequestMessage(method, new Uri(new Uri(_apiEndpoint), relativeUri));\n            httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(\"application/json\"));\n            httpRequest.Headers.Authorization = new AuthenticationHeaderValue(\"Bearer\", _mollieSecretManager.GetBearerToken());\n            httpRequest.Headers.Add(\"User-Agent\", GetUserAgent());\n            var idemPotencyKey = _idempotencyKey.Value ?? Guid.NewGuid().ToString();\n            httpRequest.Headers.Add(\"Idempotency-Key\", idemPotencyKey);\n            httpRequest.Content = content;\n\n            return httpRequest;\n        }\n\n        private string BuildListQueryString(string? from, int? limit, IDictionary<string, string>? otherParameters = null) {\n            var queryParameters = new Dictionary<string, string>();\n            queryParameters.AddValueIfNotNullOrEmpty(nameof(from), from);\n            queryParameters.AddValueIfNotNullOrEmpty(nameof(limit), Convert.ToString(limit));\n\n            if (otherParameters != null) {\n                foreach (var parameter in otherParameters) {\n                    queryParameters.AddValueIfNotNullOrEmpty(parameter.Key, parameter.Value);\n                }\n            }\n\n            return queryParameters.ToQueryString();\n        }\n\n        private string GetUserAgent() {\n            const string packageName = \"Mollie.Api.NET\";\n            string versionNumber = typeof(BaseMollieClient).GetTypeInfo().Assembly.GetName().Version?.ToString() ?? \"unknown\";\n            string userAgent = $\"{packageName}/{versionNumber}\";\n\n            if (!string.IsNullOrEmpty(_options.CustomUserAgent)) {\n                userAgent = $\"{userAgent} {_options.CustomUserAgent}\";\n            }\n\n            return userAgent;\n        }\n\n        private MollieErrorMessage ParseMollieErrorMessage(HttpStatusCode responseStatusCode, string responseBody) {\n            try {\n                return _jsonConverterService.Deserialize<MollieErrorMessage>(responseBody)!;\n            }\n            catch (JsonException) {\n                return new MollieErrorMessage {\n                    Title = \"Unknown error\",\n                    Status = (int)responseStatusCode,\n                    Detail = responseBody\n                };\n            }\n        }\n\n        protected void ValidateRequiredUrlParameter(string parameterName, string parameterValue) {\n            if (string.IsNullOrWhiteSpace(parameterValue)) {\n                throw new ArgumentException($\"Required URL argument '{parameterName}' is null or empty\");\n            }\n        }\n\n        protected Dictionary<string, string> BuildQueryParameters(\n            string? profileId = null, bool testmode = false, SortDirection? sort = null) {\n            var result = new Dictionary<string, string>();\n            result.AddValueIfTrue(nameof(testmode), testmode || _options.Testmode == true);\n            result.AddValueIfNotNullOrEmpty(nameof(profileId), profileId ?? _options.ProfileId);\n            result.AddValueIfNotNullOrEmpty(nameof(sort), sort?.ToString()?.ToLowerInvariant());\n            return result;\n        }\n\n        protected TestmodeModel? CreateTestmodeModel(bool testmode) {\n            return TestmodeModel.Create(testmode || _options.Testmode == true);\n        }\n\n        public void Dispose() {\n            if (_createdHttpClient) {\n                _httpClient.Dispose();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/CapabilityClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Capability.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client;\n\npublic class CapabilityClient : BaseMollieClient, ICapabilityClient {\n    public CapabilityClient(string oauthAccessToken, HttpClient? httpClient = null)\n        : base(oauthAccessToken, httpClient)\n    {\n    }\n\n    [ActivatorUtilitiesConstructor]\n    public CapabilityClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n        : base(options, mollieSecretManager, httpClient)\n    {\n    }\n\n    public async Task<ListResponse<CapabilityResponse>> GetCapabilitiesListAsync(CancellationToken cancellationToken = default) {\n        return await GetListAsync<ListResponse<CapabilityResponse>>(\n                \"capabilities\", from: null, limit: null, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/CaptureClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Capture.Request;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client\n{\n    public class CaptureClient : BaseMollieClient, ICaptureClient {\n        public CaptureClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public CaptureClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<CaptureResponse> GetCaptureAsync(\n            string paymentId, string captureId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            ValidateRequiredUrlParameter(nameof(captureId), captureId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<CaptureResponse>(\n                    $\"payments/{paymentId}/captures/{captureId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<CaptureResponse> GetCaptureAsync(\n            UrlObjectLink<CaptureResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<CaptureResponse>> GetCaptureListAsync(\n            string paymentId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<ListResponse<CaptureResponse>>(\n                    $\"payments/{paymentId}/captures{queryParameters.ToQueryString()}\",\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<CaptureResponse>> GetCaptureListAsync(UrlObjectLink<ListResponse<CaptureResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<CaptureResponse> CreateCapture(string paymentId, CaptureRequest captureRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            return await PostAsync<CaptureResponse>(\n                    $\"payments/{paymentId}/captures\", captureRequest,\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/ChargebackClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class ChargebackClient : BaseMollieClient, IChargebackClient {\n        public ChargebackClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public ChargebackClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<ChargebackResponse> GetChargebackAsync(string paymentId, string chargebackId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            ValidateRequiredUrlParameter(nameof(chargebackId), chargebackId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<ChargebackResponse>(\n                    $\"payments/{paymentId}/chargebacks/{chargebackId}{queryParameters.ToQueryString()}\",\n                    cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ChargebackResponse>> GetChargebackListAsync(string paymentId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetListAsync<ListResponse<ChargebackResponse>>(\n                    $\"payments/{paymentId}/chargebacks\", from, limit, queryParameters, cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ChargebackResponse>> GetChargebackListAsync(string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildQueryParameters(profileId, testmode);\n            return await GetListAsync<ListResponse<ChargebackResponse>>(\n                \"chargebacks\", null, null, queryParameters, cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ChargebackResponse>> GetChargebackListAsync(UrlObjectLink<ListResponse<ChargebackResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/ClientClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Client.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class ClientClient : OauthBaseMollieClient, IClientClient {\n        public ClientClient(string oauthAccessToken, HttpClient? httpClient = null)\n            : base(oauthAccessToken, httpClient)\n        {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public ClientClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient)\n        {\n        }\n\n        public async Task<ClientResponse> GetClientAsync(\n            string clientId,\n            bool embedOrganization = false,\n            bool embedOnboarding = false,\n            bool embedCapabilities = false,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(clientId), clientId);\n            var queryParameters = BuildQueryParameters(embedOrganization, embedOnboarding, embedCapabilities);\n            return await GetAsync<ClientResponse>(\n                $\"clients/{clientId}{queryParameters.ToQueryString()}\",\n                cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ClientResponse>> GetClientListAsync(\n            string? from = null,\n            int? limit = null,\n            bool embedOrganization = false,\n            bool embedOnboarding = false,\n            bool embedCapabilities = false,\n            CancellationToken cancellationToken = default) {\n            var queryParameters = BuildQueryParameters(embedOrganization, embedOnboarding, embedCapabilities);\n            return await GetListAsync<ListResponse<ClientResponse>>(\n                \"clients\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        private Dictionary<string, string> BuildQueryParameters(\n            bool embedOrganization = false, bool embedOnboarding = false, bool embedCapabilities = false) {\n            var result = new Dictionary<string, string>();\n            result.AddValueIfNotNullOrEmpty(\"embed\", BuildEmbedParameter(embedOrganization, embedOnboarding, embedCapabilities));\n            return result;\n        }\n\n        private string BuildEmbedParameter(\n            bool embedOrganization = false, bool embedOnboarding = false, bool embedCapabilities = false) {\n            var includeList = new List<string>();\n            includeList.AddValueIfTrue(\"organization\", embedOrganization);\n            includeList.AddValueIfTrue(\"onboarding\", embedOnboarding);\n            includeList.AddValueIfTrue(\"capabilities\", embedCapabilities);\n            return includeList.ToIncludeParameter();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/ClientLinkClient.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.ClientLink.Request;\nusing Mollie.Api.Models.ClientLink.Response;\nusing System.Threading;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class ClientLinkClient : OauthBaseMollieClient, IClientLinkClient\n    {\n        private readonly string _clientId;\n\n        public ClientLinkClient(string clientId, string oauthAccessToken, HttpClient? httpClient = null)\n            : base(oauthAccessToken, httpClient)\n        {\n            _clientId = clientId;\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public ClientLinkClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n            if (string.IsNullOrWhiteSpace(options.ClientId)) {\n                throw new ArgumentNullException(nameof(options.ClientId));\n            }\n\n            _clientId = options.ClientId!;\n        }\n\n        public async Task<ClientLinkResponse> CreateClientLinkAsync(ClientLinkRequest request, CancellationToken cancellationToken = default)\n        {\n            return await PostAsync<ClientLinkResponse>(\n                    \"client-links\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public string GenerateClientLinkWithParameters(\n            string clientLinkUrl,\n            string state,\n            List<string> scopes,\n            bool forceApprovalPrompt = false)\n        {\n            var parameters = new Dictionary<string, string> {\n                {\"client_id\", _clientId},\n                {\"state\", state},\n                {\"scope\", string.Join(\" \", scopes)},\n                {\"approval_prompt\", forceApprovalPrompt ? \"force\" : \"auto\"}\n            };\n\n            return clientLinkUrl + parameters.ToQueryString();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/ConnectClient.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Models.Connect.Request;\nusing Mollie.Api.Models.Connect.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class ConnectClient : BaseMollieClient, IConnectClient {\n        public const string DefaultAuthorizeEndpoint = \"https://my.mollie.com/oauth2/authorize\";\n        public const string DefaultTokenEndpoint = \"https://api.mollie.com/oauth2/\";\n\n        private readonly string _authorizeEndPoint;\n        private readonly string _tokenEndPoint;\n\n        private readonly string _clientId;\n        private readonly string _clientSecret;\n\n        public ConnectClient(string? clientId, string? clientSecret, HttpClient? httpClient = null)\n            : base(httpClient, DefaultTokenEndpoint) {\n            if (string.IsNullOrWhiteSpace(clientId)) {\n                throw new ArgumentNullException(nameof(clientId));\n            }\n\n            if (string.IsNullOrWhiteSpace(clientSecret)) {\n                throw new ArgumentNullException(nameof(clientSecret));\n            }\n\n            _clientSecret = clientSecret!;\n            _clientId = clientId!;\n            _authorizeEndPoint = DefaultAuthorizeEndpoint;\n            _tokenEndPoint = DefaultTokenEndpoint;\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public ConnectClient(MollieClientOptions options, HttpClient? httpClient = null)\n            : base(httpClient, options.ConnectTokenEndPoint) {\n            if (string.IsNullOrWhiteSpace(options.ClientId)) {\n                throw new ArgumentNullException(nameof(options.ClientId));\n            }\n\n            if (string.IsNullOrWhiteSpace(options.ClientSecret)) {\n                throw new ArgumentNullException(nameof(options.ClientSecret));\n            }\n\n            _clientSecret = options.ClientSecret!;\n            _clientId = options.ClientId!;\n            _authorizeEndPoint = options.ConnectOAuthAuthorizeEndPoint;\n            _tokenEndPoint = options.ConnectTokenEndPoint;\n        }\n\n        public string GetAuthorizationUrl(\n            string state,\n            List<string> scopes,\n            string? redirectUri = null,\n            bool forceApprovalPrompt = false,\n            string? locale = null,\n            string? landingPage = null) {\n\n            var parameters = new Dictionary<string, string> {\n                {\"client_id\", _clientId},\n                {\"state\", state},\n                {\"scope\", string.Join(\" \", scopes)},\n                {\"response_type\", \"code\"},\n                {\"approval_prompt\", forceApprovalPrompt ? \"force\" : \"auto\"}\n            };\n            parameters.AddValueIfNotNullOrEmpty(\"redirect_uri\", redirectUri);\n            parameters.AddValueIfNotNullOrEmpty(\"locale\", locale);\n            parameters.AddValueIfNotNullOrEmpty(\"landing_page\", landingPage);\n\n            return _authorizeEndPoint + parameters.ToQueryString();\n        }\n\n        public async Task<TokenResponse> GetAccessTokenAsync(\n            TokenRequest request, CancellationToken cancellationToken = default) {\n            return await PostAsync<TokenResponse>(\n                \"tokens\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task RevokeTokenAsync(\n            RevokeTokenRequest request, CancellationToken cancellationToken = default) {\n            await DeleteAsync(\n                \"tokens\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        protected override HttpRequestMessage CreateHttpRequest(\n            HttpMethod method, string relativeUri, HttpContent? content = null) {\n            var httpRequest = new HttpRequestMessage(method, new Uri(new Uri(_tokenEndPoint), relativeUri));\n            httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(\"application/json\"));\n            httpRequest.Headers.Authorization = new AuthenticationHeaderValue(\"Basic\", Base64Encode($\"{_clientId}:{_clientSecret}\"));\n            httpRequest.Content = content;\n\n            return httpRequest;\n        }\n\n        private string Base64Encode(string value) {\n            var bytes = Encoding.UTF8.GetBytes(value);\n            return Convert.ToBase64String(bytes);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/CustomerClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Customer.Request;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class CustomerClient : BaseMollieClient, ICustomerClient {\n        public CustomerClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public CustomerClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<CustomerResponse> CreateCustomerAsync(\n            CustomerRequest request, CancellationToken cancellationToken = default) {\n            return await PostAsync<CustomerResponse>(\n                \"customers\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<CustomerResponse> UpdateCustomerAsync(\n            string customerId, CustomerRequest request, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            return await PostAsync<CustomerResponse>(\n                $\"customers/{customerId}\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task DeleteCustomerAsync(\n            string customerId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            var data = CreateTestmodeModel(testmode);\n            await DeleteAsync(\n                $\"customers/{customerId}\", data, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<CustomerResponse> GetCustomerAsync(\n            string customerId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<CustomerResponse>(\n                $\"customers/{customerId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<CustomerResponse> GetCustomerAsync(UrlObjectLink<CustomerResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<CustomerResponse>> GetCustomerListAsync(UrlObjectLink<ListResponse<CustomerResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<CustomerResponse>> GetCustomerListAsync(\n            string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetListAsync<ListResponse<CustomerResponse>>(\n                    \"customers\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentResponse>> GetCustomerPaymentListAsync(\n            string customerId, string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            var queryParameters = BuildQueryParameters(profileId, testmode);\n            return await GetListAsync<ListResponse<PaymentResponse>>(\n                $\"customers/{customerId}/payments\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<PaymentResponse> CreateCustomerPayment(\n            string customerId, PaymentRequest paymentRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            return await PostAsync<PaymentResponse>(\n                $\"customers/{customerId}/payments\", paymentRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/InvoiceClient.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Invoice.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class InvoiceClient : OauthBaseMollieClient, IInvoiceClient {\n        public InvoiceClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public InvoiceClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<InvoiceResponse> GetInvoiceAsync(\n            string invoiceId, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(invoiceId), invoiceId);\n            return await GetAsync<InvoiceResponse>(\n                $\"invoices/{invoiceId}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<InvoiceResponse> GetInvoiceAsync(\n            UrlObjectLink<InvoiceResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<InvoiceResponse>> GetInvoiceListAsync(\n            string? reference = null, int? year = null, string? from = null, int? limit = null, CancellationToken cancellationToken = default) {\n            var parameters = new Dictionary<string, string>();\n            parameters.AddValueIfNotNullOrEmpty(nameof(reference), reference);\n            parameters.AddValueIfNotNullOrEmpty(nameof(year), Convert.ToString(year));\n\n            return await GetListAsync<ListResponse<InvoiceResponse>>(\n                    \"invoices\", from, limit, parameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<InvoiceResponse>> GetInvoiceListAsync(\n            UrlObjectLink<ListResponse<InvoiceResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/MandateClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Mandate.Request;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class MandateClient : BaseMollieClient, IMandateClient {\n        public MandateClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public MandateClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<MandateResponse> GetMandateAsync(\n            string customerId, string mandateId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            ValidateRequiredUrlParameter(nameof(mandateId), mandateId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<MandateResponse>(\n                $\"customers/{customerId}/mandates/{mandateId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<MandateResponse>> GetMandateListAsync(\n            string customerId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetListAsync<ListResponse<MandateResponse>>(\n                    $\"customers/{customerId}/mandates\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<MandateResponse> CreateMandateAsync(\n            string customerId, MandateRequest request, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            return await PostAsync<MandateResponse>(\n                $\"customers/{customerId}/mandates\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<MandateResponse>> GetMandateListAsync(\n            UrlObjectLink<ListResponse<MandateResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<MandateResponse> GetMandateAsync(\n            UrlObjectLink<MandateResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task RevokeMandate(\n            string customerId, string mandateId, bool testmode = false, CancellationToken cancellationToken = default) {\n            var data = CreateTestmodeModel(testmode);\n            await DeleteAsync($\"customers/{customerId}/mandates/{mandateId}\", data, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/MollieApiException.cs",
    "content": "﻿using System;\nusing Mollie.Api.Models.Error;\n\nnamespace Mollie.Api.Client {\n    public class MollieApiException : Exception {\n        public MollieErrorMessage Details { get; set; }\n\n        public MollieApiException(MollieErrorMessage details) : base(details.ToString()) {\n            Details = details;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/OauthBaseMollieClient.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class OauthBaseMollieClient : BaseMollieClient {\n        protected OauthBaseMollieClient(string oauthAccessToken, HttpClient? httpClient = null)\n            : base(oauthAccessToken, httpClient) {\n            ValidateApiKeyIsOauthAccesstoken(oauthAccessToken);\n        }\n\n        protected OauthBaseMollieClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n            ValidateApiKeyIsOauthAccesstoken(mollieSecretManager.GetBearerToken());\n        }\n\n        private void ValidateApiKeyIsOauthAccesstoken(string oauthAccessToken) {\n            if (string.IsNullOrWhiteSpace(oauthAccessToken)) {\n                throw new ArgumentNullException(nameof(oauthAccessToken), \"Mollie API key cannot be empty\");\n            }\n\n            ValidateApiKeyIsOauthAccesstoken(true);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/OnboardingClient.cs",
    "content": "﻿using Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models.Onboarding.Request;\nusing Mollie.Api.Models.Onboarding.Response;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing System.Threading;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class OnboardingClient : BaseMollieClient, IOnboardingClient {\n        public OnboardingClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public OnboardingClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<OnboardingStatusResponse> GetOnboardingStatusAsync(\n            CancellationToken cancellationToken = default) {\n            return await GetAsync<OnboardingStatusResponse>(\n                \"onboarding/me\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task SubmitOnboardingDataAsync(\n            SubmitOnboardingDataRequest request, CancellationToken cancellationToken = default) {\n            await PostAsync<object>(\n                \"onboarding/me\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/OrderClient.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Order.Request.ManageOrderLines;\nusing Mollie.Api.Models.Order.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    [Obsolete(\"Mollie no longer recommends using the Orders API. Please refer to the Payments API instead.\")]\n    public class OrderClient : BaseMollieClient, IOrderClient {\n        public OrderClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public OrderClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<OrderResponse> CreateOrderAsync(\n\n            OrderRequest orderRequest, CancellationToken cancellationToken = default) {\n            return await PostAsync<OrderResponse>(\"orders\", orderRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<OrderResponse> GetOrderAsync(\n            string orderId, bool embedPayments = false, bool embedRefunds = false, bool embedShipments = false, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            queryParameters.AddValueIfNotNullOrEmpty(\"embed\", BuildEmbedParameter(embedPayments, embedRefunds, embedShipments));\n\n            return await GetAsync<OrderResponse>(\n                $\"orders/{orderId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<OrderResponse> GetOrderAsync(\n            UrlObjectLink<OrderResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<OrderResponse> UpdateOrderAsync(\n            string orderId, OrderUpdateRequest orderUpdateRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            return await PatchAsync<OrderResponse>(\n                $\"orders/{orderId}\", orderUpdateRequest, cancellationToken: cancellationToken\n                ).ConfigureAwait(false);\n        }\n\n        public async Task<OrderResponse> UpdateOrderLinesAsync(\n            string orderId, string orderLineId, OrderLineUpdateRequest orderLineUpdateRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            ValidateRequiredUrlParameter(nameof(orderLineId), orderLineId);\n            return await PatchAsync<OrderResponse>(\n                $\"orders/{orderId}/lines/{orderLineId}\", orderLineUpdateRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<OrderResponse> ManageOrderLinesAsync(\n            string orderId, ManageOrderLinesRequest manageOrderLinesRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            return await PatchAsync<OrderResponse>(\n                $\"orders/{orderId}/lines\", manageOrderLinesRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task CancelOrderAsync(\n            string orderId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            var data = CreateTestmodeModel(testmode);\n            await DeleteAsync(\n                $\"orders/{orderId}\", data, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<OrderResponse>> GetOrderListAsync(\n            string? from = null, int? limit = null, string? profileId = null, bool testmode = false, SortDirection? sort = null, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildQueryParameters(profileId, testmode, sort);\n            return await GetListAsync<ListResponse<OrderResponse>>(\n                \"orders\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<OrderResponse>> GetOrderListAsync(\n            UrlObjectLink<ListResponse<OrderResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task CancelOrderLinesAsync(\n            string orderId, OrderLineCancellationRequest cancelationRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            await DeleteAsync($\"orders/{orderId}/lines\", cancelationRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<PaymentResponse> CreateOrderPaymentAsync(\n            string orderId, OrderPaymentRequest createOrderPaymentRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            return await PostAsync<PaymentResponse>(\n                $\"orders/{orderId}/payments\", createOrderPaymentRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        private string BuildEmbedParameter(bool embedPayments = false, bool embedRefunds = false, bool embedShipments = false) {\n            var includeList = new List<string>();\n            includeList.AddValueIfTrue(\"payments\", embedPayments);\n            includeList.AddValueIfTrue(\"refunds\", embedRefunds);\n            includeList.AddValueIfTrue(\"shipments\", embedShipments);\n            return includeList.ToIncludeParameter();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/OrganizationClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Organization;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class OrganizationClient : OauthBaseMollieClient, IOrganizationClient {\n        public OrganizationClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public OrganizationClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<OrganizationResponse> GetCurrentOrganizationAsync(CancellationToken cancellationToken = default) {\n            return await GetAsync<OrganizationResponse>($\"organizations/me\", cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<OrganizationResponse> GetOrganizationAsync(string organizationId, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(organizationId), organizationId);\n            return await GetAsync<OrganizationResponse>($\"organizations/{organizationId}\", cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<OrganizationResponse> GetOrganizationAsync(UrlObjectLink<OrganizationResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<OrganizationResponse>> GetOrganizationListAsync(string? from = null, int? limit = null, CancellationToken cancellationToken = default) {\n            return await GetListAsync<ListResponse<OrganizationResponse>>(\"organizations\", from, limit, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<OrganizationResponse>> GetOrganizationListAsync(UrlObjectLink<ListResponse<OrganizationResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<PartnerResponse> GetPartnerStatusAsync(CancellationToken cancellationToken = default) {\n            return await GetAsync<PartnerResponse>($\"organizations/me/partner\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/PaymentClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class PaymentClient : BaseMollieClient, IPaymentClient {\n\n\t    public PaymentClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { }\n\n        [ActivatorUtilitiesConstructor]\n        public PaymentClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<PaymentResponse> CreatePaymentAsync(\n            PaymentRequest paymentRequest,\n            bool includeQrCode = false,\n            CancellationToken cancellationToken = default) {\n            if (!string.IsNullOrWhiteSpace(paymentRequest.ProfileId) || paymentRequest.Testmode.HasValue || paymentRequest.ApplicationFee != null) {\n                ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            var queryParameters = BuildQueryParameters(\n                includeQrCode: includeQrCode);\n\n            return await PostAsync<PaymentResponse>(\n                $\"payments{queryParameters.ToQueryString()}\",\n                paymentRequest,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<PaymentResponse> GetPaymentAsync(\n            string paymentId,\n            bool testmode = false,\n            bool includeQrCode = false,\n            bool includeRemainderDetails = false,\n            bool embedRefunds = false,\n            bool embedChargebacks = false,\n            CancellationToken cancellationToken = default) {\n\n\t        if (testmode) {\n\t            ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n\n            var queryParameters = BuildQueryParameters(\n                testmode: testmode,\n                includeQrCode: includeQrCode,\n                includeRemainderDetails: includeRemainderDetails,\n                embedRefunds: embedRefunds,\n                embedChargebacks: embedChargebacks\n            );\n\t\t\treturn await GetAsync<PaymentResponse>(\n                $\"payments/{paymentId}{queryParameters.ToQueryString()}\",\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n\t\t}\n\n\t\tpublic async Task CancelPaymentAsync(\n            string paymentId,\n            bool testmode = false,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n\n            var data = CreateTestmodeModel(testmode);\n\t\t    await DeleteAsync(\n                $\"payments/{paymentId}\",\n                data,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n\t\t}\n\n        public async Task ReleasePaymentAuthorization(\n            string paymentId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            await PostAsync<object>(\n                $\"payments/{paymentId}/release-authorization{queryParameters.ToQueryString()}\",\n                null,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<PaymentResponse> GetPaymentAsync(\n            UrlObjectLink<PaymentResponse> url,\n            CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentResponse>> GetPaymentListAsync(\n            UrlObjectLink<ListResponse<PaymentResponse>> url,\n            CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentResponse>> GetPaymentListAsync(\n            string? from = null,\n            int? limit = null,\n            string? profileId = null,\n            bool testmode = false,\n            bool includeQrCode = false,\n            bool embedRefunds = false,\n            bool embedChargebacks = false,\n            SortDirection? sort = null,\n            CancellationToken cancellationToken = default) {\n\n\t        if (!string.IsNullOrWhiteSpace(profileId) || testmode) {\n\t            ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            var queryParameters = BuildQueryParameters(\n                profileId: profileId,\n                testmode: testmode,\n                includeQrCode: includeQrCode,\n                embedRefunds: embedRefunds,\n                embedChargebacks: embedChargebacks,\n                sort: sort);\n\n            return await GetListAsync<ListResponse<PaymentResponse>>(\n                $\"payments\",\n                from,\n                limit,\n                queryParameters,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n\t\t}\n\n        public async Task<PaymentResponse> UpdatePaymentAsync(\n            string paymentId,\n            PaymentUpdateRequest paymentUpdateRequest,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n\n            return await PatchAsync<PaymentResponse>(\n                $\"payments/{paymentId}\",\n                paymentUpdateRequest,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        private Dictionary<string, string> BuildQueryParameters(\n            string? profileId = null,\n            bool testmode = false,\n            bool includeQrCode = false,\n            bool includeRemainderDetails = false,\n            bool embedRefunds = false,\n            bool embedChargebacks = false,\n            SortDirection? sort = null) {\n\n            var result = base.BuildQueryParameters(profileId, testmode);\n            result.AddValueIfNotNullOrEmpty(\"include\", BuildIncludeParameter(includeQrCode, includeRemainderDetails));\n            result.AddValueIfNotNullOrEmpty(\"embed\", BuildEmbedParameter(embedRefunds, embedChargebacks));\n            result.AddValueIfNotNullOrEmpty(nameof(sort), sort?.ToString()?.ToLowerInvariant());\n            return result;\n        }\n\n        private string BuildIncludeParameter(bool includeQrCode = false, bool includeRemainderDetails = false) {\n            var includeList = new List<string>();\n            includeList.AddValueIfTrue(\"details.qrCode\", includeQrCode);\n            includeList.AddValueIfTrue(\"details.remainderDetails\", includeRemainderDetails);\n            return includeList.ToIncludeParameter();\n        }\n\n        private string BuildEmbedParameter(bool embedRefunds = false, bool embedChargebacks = false)\n        {\n            var embedList = new List<string>();\n            embedList.AddValueIfTrue(\"refunds\", embedRefunds);\n            embedList.AddValueIfTrue(\"chargebacks\", embedChargebacks);\n            return embedList.ToIncludeParameter();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/PaymentLinkClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.PaymentLink.Request;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class PaymentLinkClient : BaseMollieClient, IPaymentLinkClient {\n        public PaymentLinkClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { }\n\n        [ActivatorUtilitiesConstructor]\n        public PaymentLinkClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager,\n            HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<PaymentLinkResponse> CreatePaymentLinkAsync(\n            PaymentLinkRequest paymentLinkRequest,\n            CancellationToken cancellationToken = default) {\n            if (!string.IsNullOrWhiteSpace(paymentLinkRequest.ProfileId) || paymentLinkRequest.Testmode.HasValue) {\n                ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            return await PostAsync<PaymentLinkResponse>(\n                $\"payment-links\",\n                paymentLinkRequest,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<PaymentLinkResponse> UpdatePaymentLinkAsync(\n            string paymentLinkId,\n            PaymentLinkUpdateRequest paymentLinkUpdateRequest,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentLinkId), paymentLinkId);\n\n            if (paymentLinkUpdateRequest.Testmode.HasValue) {\n                ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            string relativeUri = $\"payment-links/{paymentLinkId}\";\n            return await PatchAsync<PaymentLinkResponse>(\n                relativeUri,\n                paymentLinkUpdateRequest,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task DeletePaymentLinkAsync(\n            string paymentLinkId,\n            string? profileId = null,\n            bool testmode = false,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentLinkId), paymentLinkId);\n            var queryParameters = BuildQueryParameters(profileId);\n            var data = CreateTestmodeModel(testmode);\n            string relativeUri = $\"payment-links/{paymentLinkId}{queryParameters.ToQueryString()}\";\n            await DeleteAsync(\n                relativeUri,\n                data,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<PaymentLinkResponse> GetPaymentLinkAsync(\n            string paymentLinkId,\n            bool testmode = false,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentLinkId), paymentLinkId);\n            if (testmode) {\n                ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            var queryParameters = BuildQueryParameters(\n                testmode: testmode);\n\n            return await GetAsync<PaymentLinkResponse>(\n                $\"payment-links/{paymentLinkId}{queryParameters.ToQueryString()}\",\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<PaymentLinkResponse> GetPaymentLinkAsync(\n            UrlObjectLink<PaymentLinkResponse> url,\n            CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentLinkResponse>> GetPaymentLinkListAsync(\n            UrlObjectLink<ListResponse<PaymentLinkResponse>> url,\n            CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentLinkResponse>> GetPaymentLinkListAsync(\n            string? from = null,\n            int? limit = null,\n            string? profileId = null,\n            bool testmode = false,\n            CancellationToken cancellationToken = default) {\n            if (!string.IsNullOrWhiteSpace(profileId) || testmode) {\n                ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            var queryParameters = BuildQueryParameters(\n                profileId: profileId,\n                testmode: testmode);\n\n            return await GetListAsync<ListResponse<PaymentLinkResponse>>(\n                \"payment-links\",\n                from,\n                limit,\n                queryParameters,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentResponse>> GetPaymentLinkPaymentListAsync(\n            string paymentLinkId,\n            string? from = null,\n            int? limit = null,\n            bool testmode = false,\n            SortDirection? sort = null,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentLinkId), paymentLinkId);\n            if (testmode) {\n                ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            var queryParameters = BuildQueryParameters(\n                testmode: testmode,\n                sort: sort);\n\n            return await GetListAsync<ListResponse<PaymentResponse>>(\n                $\"payment-links/{paymentLinkId}/payments\",\n                from,\n                limit,\n                queryParameters,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/PaymentMethodClient.cs",
    "content": "﻿﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.PaymentMethod.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client\n{\n    public class PaymentMethodClient : BaseMollieClient, IPaymentMethodClient\n    {\n        public PaymentMethodClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public PaymentMethodClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<PaymentMethodResponse> GetPaymentMethodAsync(\n            string paymentMethod,\n            bool includeIssuers = false,\n            string? locale = null,\n            string? profileId = null,\n            bool testmode = false,\n            string? currency = null,\n            CancellationToken cancellationToken = default) {\n\n            ValidateRequiredUrlParameter(nameof(paymentMethod), paymentMethod);\n\n            Dictionary<string, string> queryParameters = BuildQueryParameters(\n                locale: locale,\n                currency: currency,\n                profileId: profileId,\n                testmode: testmode,\n                includeIssuers: includeIssuers);\n\n            return await GetAsync<PaymentMethodResponse>(\n                $\"methods/{paymentMethod.ToLower()}{queryParameters.ToQueryString()}\",\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentMethodResponse>> GetAllPaymentMethodListAsync(\n            string? locale = null,\n            Amount? amount = null,\n            bool includeIssuers = false,\n            bool includePricing = false,\n            string? profileId = null,\n            bool testmode = false,\n            CancellationToken cancellationToken = default) {\n\n            Dictionary<string, string> queryParameters = BuildQueryParameters(\n               locale: locale,\n               amount: amount,\n               includeIssuers: includeIssuers,\n               includePricing: includePricing,\n               profileId: profileId,\n               testmode: testmode);\n\n            return await GetListAsync<ListResponse<PaymentMethodResponse>>(\n                \"methods/all\", null, null, queryParameters,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentMethodResponse>> GetPaymentMethodListAsync(\n            string? sequenceType = null,\n            string? locale = null,\n            Amount? amount = null,\n            bool includeIssuers = false,\n            string? profileId = null,\n            bool testmode = false,\n            Resource? resource = null,\n            string? billingCountry = null,\n            string? includeWallets = null,\n            CancellationToken cancellationToken = default) {\n\n            Dictionary<string, string> queryParameters = BuildQueryParameters(\n               sequenceType: sequenceType,\n               locale: locale,\n               amount: amount,\n               includeIssuers: includeIssuers,\n               resource: resource,\n               profileId: profileId,\n               testmode: testmode,\n               billingCountry: billingCountry,\n               includeWallets: includeWallets);\n\n            return await GetListAsync<ListResponse<PaymentMethodResponse>>(\n                \"methods\", null, null, queryParameters,\n                cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<PaymentMethodResponse> GetPaymentMethodAsync(\n            UrlObjectLink<PaymentMethodResponse> url,\n            CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        private Dictionary<string, string> BuildQueryParameters(\n            string? sequenceType = null,\n            string? locale = null,\n            Amount? amount = null,\n            bool includeIssuers = false,\n            bool includePricing = false,\n            string? profileId = null,\n            bool testmode = false,\n            Resource? resource = null,\n            string? currency = null,\n            string? billingCountry = null,\n            string? includeWallets = null) {\n\n            var result = base.BuildQueryParameters(profileId, testmode);\n            result.AddValueIfNotNullOrEmpty(nameof(sequenceType), sequenceType?.ToLower());\n            result.AddValueIfNotNullOrEmpty(nameof(locale), locale);\n            result.AddValueIfNotNullOrEmpty(\"amount[currency]\", amount?.Currency);\n            result.AddValueIfNotNullOrEmpty(\"amount[value]\", amount?.Value);\n            result.AddValueIfNotNullOrEmpty(\"include\", BuildIncludeParameter(includeIssuers, includePricing));\n            result.AddValueIfNotNullOrEmpty(nameof(resource), resource?.ToString()?.ToLower());\n            result.AddValueIfNotNullOrEmpty(nameof(currency), currency);\n            result.AddValueIfNotNullOrEmpty(nameof(billingCountry), billingCountry);\n            result.AddValueIfNotNullOrEmpty(nameof(includeWallets), includeWallets);\n            return result;\n        }\n\n        private string BuildIncludeParameter(bool includeIssuers = false, bool includePricing = false) {\n            var includeList = new List<string>();\n            includeList.AddValueIfTrue(\"issuers\", includeIssuers);\n            includeList.AddValueIfTrue(\"pricing\", includePricing);\n            return includeList.ToIncludeParameter();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/PermissionClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Permission.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class PermissionClient : OauthBaseMollieClient, IPermissionClient {\n        public PermissionClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public PermissionClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<PermissionResponse> GetPermissionAsync(\n            string permissionId, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(permissionId), permissionId);\n            return await GetAsync<PermissionResponse>(\n                $\"permissions/{permissionId}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<PermissionResponse> GetPermissionAsync(\n            UrlObjectLink<PermissionResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PermissionResponse>> GetPermissionListAsync(\n            CancellationToken cancellationToken = default) {\n            return await GetListAsync<ListResponse<PermissionResponse>>(\n                \"permissions\", null, null, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/ProfileClient.cs",
    "content": "﻿﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.PaymentMethod.Response;\nusing Mollie.Api.Models.Profile.Request;\nusing Mollie.Api.Models.Profile.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class ProfileClient : BaseMollieClient, IProfileClient {\n        public ProfileClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public ProfileClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<ProfileResponse> CreateProfileAsync(\n            ProfileRequest request, CancellationToken cancellationToken = default) {\n            return await PostAsync<ProfileResponse>(\n                \"profiles\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ProfileResponse> GetProfileAsync(\n            string profileId, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(profileId), profileId);\n            return await GetAsync<ProfileResponse>(\n                $\"profiles/{profileId}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ProfileResponse> GetProfileAsync(\n            UrlObjectLink<ProfileResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ProfileResponse> GetCurrentProfileAsync(CancellationToken cancellationToken = default) {\n            return await GetAsync<ProfileResponse>(\n                \"profiles/me\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ProfileResponse>> GetProfileListAsync(\n            string? from = null, int? limit = null, CancellationToken cancellationToken = default) {\n            return await GetListAsync<ListResponse<ProfileResponse>>(\n                \"profiles\", from, limit, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ProfileResponse>> GetProfileListAsync(\n            UrlObjectLink<ListResponse<ProfileResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ProfileResponse> UpdateProfileAsync(\n            string profileId, ProfileRequest request, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(profileId), profileId);\n            return await PatchAsync<ProfileResponse>(\n                $\"profiles/{profileId}\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<PaymentMethodResponse> EnablePaymentMethodAsync(\n            string profileId, string paymentMethod, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(profileId), profileId);\n            ValidateRequiredUrlParameter(nameof(paymentMethod), paymentMethod);\n            return await PostAsync<PaymentMethodResponse>(\n                $\"profiles/{profileId}/methods/{paymentMethod}\", null, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<PaymentMethodResponse> EnablePaymentMethodAsync(\n            string paymentMethod, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentMethod), paymentMethod);\n            return await PostAsync<PaymentMethodResponse>(\n                $\"profiles/me/methods/{paymentMethod}\", null, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task DisablePaymentMethodAsync(\n            string profileId, string paymentMethod, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(profileId), profileId);\n            ValidateRequiredUrlParameter(nameof(paymentMethod), paymentMethod);\n            await DeleteAsync($\"profiles/{profileId}/methods/{paymentMethod}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task DisablePaymentMethodAsync(string paymentMethod, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentMethod), paymentMethod);\n            await DeleteAsync($\"profiles/me/methods/{paymentMethod}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task DeleteProfileAsync(string profileId, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(profileId), profileId);\n            await DeleteAsync($\"profiles/{profileId}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<EnableGiftCardIssuerResponse> EnableGiftCardIssuerAsync(\n            string profileId, string issuer, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(profileId), profileId);\n            ValidateRequiredUrlParameter(nameof(issuer), issuer);\n            return await PostAsync<EnableGiftCardIssuerResponse>(\n                $\"profiles/{profileId}/methods/giftcard/issuers/{issuer}\", null, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<EnableGiftCardIssuerResponse> EnableGiftCardIssuerAsync(\n            string issuer, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(issuer), issuer);\n            return await PostAsync<EnableGiftCardIssuerResponse>(\n                $\"profiles/me/methods/giftcard/issuers/{issuer}\", null, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task DisableGiftCardIssuerAsync(\n            string profileId, string issuer, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(profileId), profileId);\n            ValidateRequiredUrlParameter(nameof(issuer), issuer);\n            await DeleteAsync(\n                $\"profiles/{profileId}/methods/giftcard/issuers/{issuer}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task DisableGiftCardIssuerAsync(\n            string issuer, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(issuer), issuer);\n            await DeleteAsync(\n                $\"profiles/me/methods/giftcard/issuers/{issuer}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/RefundClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing System.Threading;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Order.Response;\nusing Mollie.Api.Models.Refund.Request;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class RefundClient : BaseMollieClient, IRefundClient {\n        public RefundClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public RefundClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<RefundResponse> CreatePaymentRefundAsync(\n            string paymentId, RefundRequest refundRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n\n            if (refundRequest.Testmode.HasValue)\n            {\n                ValidateApiKeyIsOauthAccesstoken();\n            }\n\n            return await PostAsync<RefundResponse>(\n                $\"payments/{paymentId}/refunds\", refundRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<RefundResponse>> GetRefundListAsync(\n            string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n\n            return await GetListAsync<ListResponse<RefundResponse>>(\n                \"refunds\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<RefundResponse>> GetPaymentRefundListAsync(\n            string paymentId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n\n            return await GetListAsync<ListResponse<RefundResponse>>(\n                $\"payments/{paymentId}/refunds\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<RefundResponse>> GetRefundListAsync(UrlObjectLink<ListResponse<RefundResponse>> url, CancellationToken cancellationToken = default)\n        {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<RefundResponse> GetRefundAsync(UrlObjectLink<RefundResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<RefundResponse> GetPaymentRefundAsync(\n            string paymentId, string refundId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            ValidateRequiredUrlParameter(nameof(refundId), refundId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<RefundResponse>(\n                $\"payments/{paymentId}/refunds/{refundId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task CancelPaymentRefundAsync(\n            string paymentId, string refundId, bool testmode = default, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(paymentId), paymentId);\n            ValidateRequiredUrlParameter(nameof(refundId), refundId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            await DeleteAsync($\"payments/{paymentId}/refunds/{refundId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<OrderRefundResponse> CreateOrderRefundAsync(\n            string orderId, OrderRefundRequest createOrderRefundRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            return await PostAsync<OrderRefundResponse>(\n                $\"orders/{orderId}/refunds\", createOrderRefundRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<RefundResponse>> GetOrderRefundListAsync(\n            string orderId, string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetListAsync<ListResponse<RefundResponse>>(\n                $\"orders/{orderId}/refunds\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/SalesInvoiceClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.SalesInvoice.Request;\nusing Mollie.Api.Models.SalesInvoice.Response;\nusing Mollie.Api.Options;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Client;\n\npublic class SalesInvoiceClient : BaseMollieClient, ISalesInvoiceClient {\n    public SalesInvoiceClient(string apiKey, HttpClient? httpClient = null)\n        : base(apiKey, httpClient) { }\n\n    [ActivatorUtilitiesConstructor]\n    public SalesInvoiceClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n        : base(options, mollieSecretManager, httpClient) {\n    }\n\n    public async Task<SalesInvoiceResponse> CreateSalesInvoiceAsync(\n        SalesInvoiceRequest salesInvoiceRequest, CancellationToken cancellationToken = default) {\n        return await PostAsync<SalesInvoiceResponse>($\"sales-invoices\", salesInvoiceRequest, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<ListResponse<SalesInvoiceResponse>> GetSalesInvoiceListAsync(\n        string? from = null, int? limit = null, bool testmode = false, CancellationToken cancellationToken = default) {\n        var queryParameters = BuildQueryParameters(testmode: testmode);\n        return await GetListAsync<ListResponse<SalesInvoiceResponse>>(\"sales-invoices\", from, limit, queryParameters, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<ListResponse<SalesInvoiceResponse>> GetSalesInvoiceListAsync(\n        UrlObjectLink<ListResponse<SalesInvoiceResponse>> url, CancellationToken cancellationToken = default) {\n        return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n    }\n\n    public async Task<SalesInvoiceResponse> GetSalesInvoiceAsync(\n        string salesInvoiceId, bool testmode = false, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(salesInvoiceId), salesInvoiceId);\n        var queryParameters = BuildQueryParameters(testmode: testmode);\n        return await GetAsync<SalesInvoiceResponse>($\"sales-invoices/{salesInvoiceId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<SalesInvoiceResponse> GetSalesInvoiceAsync(\n        UrlObjectLink<SalesInvoiceResponse> url, CancellationToken cancellationToken = default) {\n        return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n    }\n\n    public async Task<SalesInvoiceResponse> UpdateSalesInvoiceAsync(\n        string salesInvoiceId, SalesInvoiceUpdateRequest salesInvoiceRequest, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(salesInvoiceId), salesInvoiceId);\n        return await PatchAsync<SalesInvoiceResponse>($\"sales-invoices/{salesInvoiceId}\", salesInvoiceRequest, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task DeleteSalesInvoiceAsync(string salesInvoiceId, bool testmode = false, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(salesInvoiceId), salesInvoiceId);\n        var data = CreateTestmodeModel(testmode);\n        await DeleteAsync($\"sales-invoices/{salesInvoiceId}\", data, cancellationToken: cancellationToken).ConfigureAwait(false);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/SessionClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Session.Request;\nusing Mollie.Api.Models.Session.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class SessionClient : BaseMollieClient, ISessionClient {\n        public SessionClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public SessionClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<SessionResponse> GetSessionAsync(\n            string sessionId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(sessionId), sessionId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<SessionResponse>(\n                    $\"sessions/{sessionId}{queryParameters.ToQueryString()}\",\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SessionResponse> CreateSessionAsync(\n            SessionRequest request, CancellationToken cancellationToken = default) {\n            return await PostAsync<SessionResponse>(\n                    $\"sessions\", request,\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/SettlementClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class SettlementClient : BaseMollieClient, ISettlementClient {\n        public SettlementClient(string oauthAccessToken, HttpClient? httpClient = null) : base(oauthAccessToken, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public SettlementClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<SettlementResponse> GetSettlementAsync(\n            string settlementId, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(settlementId), settlementId);\n            return await GetAsync<SettlementResponse>(\n                $\"settlements/{settlementId}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SettlementResponse> GetNextSettlement(CancellationToken cancellationToken = default) {\n            return await GetAsync<SettlementResponse>(\n                \"settlements/next\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SettlementResponse> GetOpenSettlement(CancellationToken cancellationToken = default) {\n            return await GetAsync<SettlementResponse>(\n                $\"settlements/open\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<SettlementResponse>> GetSettlementListAsync(\n            string? reference = null, string? offset = null, int? count = null, CancellationToken cancellationToken = default) {\n            var queryString = !string.IsNullOrWhiteSpace(reference) ? $\"?reference={reference}\" : string.Empty;\n            return await GetListAsync<ListResponse<SettlementResponse>>(\n                $\"settlements{queryString}\", offset, count, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<SettlementResponse>> GetSettlementListAsync(\n            UrlObjectLink<ListResponse<SettlementResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentResponse>> GetSettlementPaymentListAsync(\n            string settlementId, string? offset = null, int? count = null, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(settlementId), settlementId);\n            return await GetListAsync<ListResponse<PaymentResponse>>(\n                $\"settlements/{settlementId}/payments\", offset, count, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentResponse>> GetSettlementPaymentListAsync(\n            UrlObjectLink<ListResponse<PaymentResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<RefundResponse>> GetSettlementRefundListAsync(\n            string settlementId, string? offset = null, int? count = null, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(settlementId), settlementId);\n            return await GetListAsync<ListResponse<RefundResponse>>(\n                $\"settlements/{settlementId}/refunds\", offset, count, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<RefundResponse>> GetSettlementRefundListAsync(\n            UrlObjectLink<ListResponse<RefundResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ChargebackResponse>> GetSettlementChargebackListAsync(\n            string settlementId, string? offset = null, int? count = null, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(settlementId), settlementId);\n            return await GetListAsync<ListResponse<ChargebackResponse>>(\n                $\"settlements/{settlementId}/chargebacks\", offset, count, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ChargebackResponse>> GetSettlementChargebackListAsync(\n            UrlObjectLink<ListResponse<ChargebackResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<CaptureResponse>> GetSettlementCaptureListAsync(\n            string settlementId, string? offset = null, int? count = null, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(settlementId), settlementId);\n            return await GetListAsync<ListResponse<CaptureResponse>>(\n                $\"settlements/{settlementId}/captures\", offset, count, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<CaptureResponse>> GetSettlementCaptureListAsync(\n            UrlObjectLink<ListResponse<CaptureResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SettlementResponse> GetSettlementAsync(\n            UrlObjectLink<SettlementResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/ShipmentClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Shipment.Request;\nusing Mollie.Api.Models.Shipment.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client\n{\n    public class ShipmentClient : BaseMollieClient, IShipmentClient {\n        public ShipmentClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public ShipmentClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<ShipmentResponse> CreateShipmentAsync(\n            string orderId, ShipmentRequest shipmentRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            return await PostAsync<ShipmentResponse>(\n                    $\"orders/{orderId}/shipments\", shipmentRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ShipmentResponse> GetShipmentAsync(\n            string orderId, string shipmentId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            ValidateRequiredUrlParameter(nameof(shipmentId), shipmentId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<ShipmentResponse>(\n                    $\"orders/{orderId}/shipments/{shipmentId}{queryParameters.ToQueryString()}\",\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ShipmentResponse> GetShipmentAsync(\n            UrlObjectLink<ShipmentResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ShipmentResponse>> GetShipmentListAsync(\n            string orderId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<ListResponse<ShipmentResponse>>(\n                    $\"orders/{orderId}/shipments{queryParameters.ToQueryString()}\",\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<ShipmentResponse>> GetShipmentListAsync(\n            UrlObjectLink<ListResponse<ShipmentResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ShipmentResponse> UpdateShipmentAsync(\n            string orderId, string shipmentId, ShipmentUpdateRequest shipmentUpdateRequest, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(orderId), orderId);\n            ValidateRequiredUrlParameter(nameof(shipmentId), shipmentId);\n            return await PatchAsync<ShipmentResponse>(\n                $\"orders/{orderId}/shipments/{shipmentId}\", shipmentUpdateRequest, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/SubscriptionClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Subscription.Request;\nusing Mollie.Api.Models.Subscription.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class SubscriptionClient : BaseMollieClient, ISubscriptionClient {\n        public SubscriptionClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public SubscriptionClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<ListResponse<SubscriptionResponse>> GetSubscriptionListAsync(\n            string customerId, string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            var queryParameters = BuildQueryParameters(profileId, testmode);\n            return await GetListAsync<ListResponse<SubscriptionResponse>>(\n                    $\"customers/{customerId}/subscriptions\", from, limit, queryParameters,\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<SubscriptionResponse>> GetAllSubscriptionList(\n            string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildQueryParameters(profileId, testmode);\n            return await GetListAsync<ListResponse<SubscriptionResponse>>(\n                    \"subscriptions\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<SubscriptionResponse>> GetSubscriptionListAsync(\n            UrlObjectLink<ListResponse<SubscriptionResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SubscriptionResponse> GetSubscriptionAsync(\n            UrlObjectLink<SubscriptionResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SubscriptionResponse> GetSubscriptionAsync(\n            string customerId, string subscriptionId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            ValidateRequiredUrlParameter(nameof(subscriptionId), subscriptionId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<SubscriptionResponse>(\n                    $\"customers/{customerId}/subscriptions/{subscriptionId}{queryParameters.ToQueryString()}\",\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SubscriptionResponse> CreateSubscriptionAsync(\n            string customerId, SubscriptionRequest request, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            return await PostAsync<SubscriptionResponse>(\n                    $\"customers/{customerId}/subscriptions\", request,\n                    cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task CancelSubscriptionAsync(\n            string customerId, string subscriptionId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            ValidateRequiredUrlParameter(nameof(subscriptionId), subscriptionId);\n            var data = CreateTestmodeModel(testmode);\n            await DeleteAsync(\n                $\"customers/{customerId}/subscriptions/{subscriptionId}\", data,\n                cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<SubscriptionResponse> UpdateSubscriptionAsync(\n            string customerId, string subscriptionId, SubscriptionUpdateRequest request, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            ValidateRequiredUrlParameter(nameof(subscriptionId), subscriptionId);\n            return await PatchAsync<SubscriptionResponse>(\n                $\"customers/{customerId}/subscriptions/{subscriptionId}\", request,\n                cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<PaymentResponse>> GetSubscriptionPaymentListAsync(\n            string customerId, string subscriptionId, string? from = null, int? limit = null, bool testmode = false,\n            CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(customerId), customerId);\n            ValidateRequiredUrlParameter(nameof(subscriptionId), subscriptionId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetListAsync<ListResponse<PaymentResponse>>(\n                    $\"customers/{customerId}/subscriptions/{subscriptionId}/payments\", from, limit,\n                    queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/TerminalClient.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Terminal.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class TerminalClient : BaseMollieClient, ITerminalClient\n    {\n        public TerminalClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) { }\n\n        [ActivatorUtilitiesConstructor]\n        public TerminalClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<TerminalResponse> GetTerminalAsync(\n            string terminalId, bool testmode = false, CancellationToken cancellationToken = default) {\n            ValidateRequiredUrlParameter(nameof(terminalId), terminalId);\n            var queryParameters = BuildQueryParameters(testmode: testmode);\n            return await GetAsync<TerminalResponse>(\n                $\"terminals/{terminalId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<TerminalResponse> GetTerminalAsync(\n            UrlObjectLink<TerminalResponse> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken).ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<TerminalResponse>> GetTerminalListAsync(\n            string? from = null, int? limit = null, string? profileId = null, bool testmode = false, CancellationToken cancellationToken = default) {\n            var queryParameters = BuildQueryParameters(profileId, testmode);\n            return await GetListAsync<ListResponse<TerminalResponse>>(\n                \"terminals\", from, limit, queryParameters, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n\n        public async Task<ListResponse<TerminalResponse>> GetTerminalListAsync(\n            UrlObjectLink<ListResponse<TerminalResponse>> url, CancellationToken cancellationToken = default) {\n            return await GetAsync(url, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/WalletClient.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models.Wallet.Request;\nusing Mollie.Api.Models.Wallet.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client {\n    public class WalletClient : BaseMollieClient, IWalletClient {\n        public WalletClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n        }\n\n        [ActivatorUtilitiesConstructor]\n        public WalletClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n            : base(options, mollieSecretManager, httpClient) {\n        }\n\n        public async Task<ApplePayPaymentSessionResponse> RequestApplePayPaymentSessionAsync(\n            ApplePayPaymentSessionRequest request, CancellationToken cancellationToken = default) {\n            return await PostAsync<ApplePayPaymentSessionResponse>(\n                \"wallets/applepay/sessions\", request, cancellationToken: cancellationToken)\n                .ConfigureAwait(false);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/WebhookClient.cs",
    "content": "using System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Api.Models.Webhook.Request;\nusing Mollie.Api.Models.Webhook.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client;\n\npublic class WebhookClient : BaseMollieClient, IWebhookClient {\n    public WebhookClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n    }\n\n    [ActivatorUtilitiesConstructor]\n    public WebhookClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n        : base(options, mollieSecretManager, httpClient) {\n    }\n\n    public async Task<WebhookResponse> CreateWebhookAsync(WebhookRequest request, CancellationToken cancellationToken = default) {\n        return await PostAsync<WebhookResponse>(\"webhooks\", request, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<ListResponse<WebhookResponse>> GetWebhookListAsync(string? from = null, int? limit = null,\n        bool testmode = false, CancellationToken cancellationToken = default) {\n        var queryParameters = BuildQueryParameters(testmode: testmode);\n        return await GetListAsync<ListResponse<WebhookResponse>>(\n                \"webhooks\", from, limit, queryParameters, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<ListResponse<WebhookResponse>> GetWebhookListAsync(\n        UrlObjectLink<ListResponse<WebhookResponse>> url, CancellationToken cancellationToken = default) {\n        return await GetAsync(url, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<WebhookResponse> GetWebhookAsync(string webhookId, bool testmode = false, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(webhookId), webhookId);\n        var queryParameters = BuildQueryParameters(testmode: testmode);\n\n        return await GetAsync<WebhookResponse>($\"webhooks/{webhookId}{queryParameters.ToQueryString()}\", cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<WebhookResponse> UpdateWebhookAsync(string webhookId, WebhookRequest request, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(webhookId), webhookId);\n\n        return await PatchAsync<WebhookResponse>($\"webhooks/{webhookId}\", request, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task DeleteWebhookAsync(string webhookId, bool testmode = false, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(webhookId), webhookId);\n        var data = CreateTestmodeModel(testmode);\n        await DeleteAsync($\"webhooks/{webhookId}\", data, cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task TestWebhookAsync(string webhookId, bool testmode = false, CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(webhookId), webhookId);\n        var queryParameters = BuildQueryParameters(testmode: testmode);\n\n        await PostAsync<object>($\"webhooks/{webhookId}/ping{queryParameters.ToQueryString()}\", null,\n            cancellationToken: cancellationToken);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Client/WebhookEventClient.cs",
    "content": "using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.WebhookEvent.Response;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Api.Client;\n\npublic class WebhookEventClient : BaseMollieClient, IWebhookEventClient {\n    public WebhookEventClient(string apiKey, HttpClient? httpClient = null) : base(apiKey, httpClient) {\n    }\n\n    [ActivatorUtilitiesConstructor]\n    public WebhookEventClient(MollieClientOptions options, IMollieSecretManager mollieSecretManager, HttpClient? httpClient = null)\n        : base(options, mollieSecretManager, httpClient) {\n    }\n\n    public async Task<FullWebhookEventResponse> GetWebhookEventAsync(string webhookEventId, bool testmode = false,\n        CancellationToken cancellationToken = default) {\n        ValidateRequiredUrlParameter(nameof(webhookEventId), webhookEventId);\n        var queryParameters = BuildQueryParameters(testmode);\n\n        return await GetAsync<FullWebhookEventResponse>($\"events/{webhookEventId}{queryParameters.ToQueryString()}\",\n                cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<FullWebhookEventResponse<T>> GetWebhookEventAsync<T>(string webhookEventId, bool testmode = false,\n        CancellationToken cancellationToken = default) where T : IEntity {\n        ValidateRequiredUrlParameter(nameof(webhookEventId), webhookEventId);\n        var queryParameters = BuildQueryParameters(testmode);\n\n        return await GetAsync<FullWebhookEventResponse<T>>($\"events/{webhookEventId}{queryParameters.ToQueryString()}\",\n                cancellationToken: cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    private Dictionary<string, string> BuildQueryParameters(bool testmode = false) {\n        var result = new Dictionary<string, string>();\n        result.AddValueIfTrue(\"testmode\", testmode);\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/DependencyInjection.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework.Authentication;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Mollie.Api.Options;\nusing Polly;\n\nnamespace Mollie.Api {\n    public static class DependencyInjection {\n        public static IServiceCollection AddMollieApi(\n            this IServiceCollection services,\n            Action<MollieOptions> mollieOptionsDelegate) {\n\n            MollieOptions mollieOptions = new();\n            mollieOptionsDelegate.Invoke(mollieOptions);\n\n            if (mollieOptions.CustomMollieSecretManager != null) {\n                services.AddScoped(typeof(IMollieSecretManager), mollieOptions.CustomMollieSecretManager);\n            }\n            else {\n                services.AddScoped<IMollieSecretManager, DefaultMollieSecretManager>(_ =>\n                    new DefaultMollieSecretManager(mollieOptions.ApiKey));\n            }\n\n            MollieClientOptions mollieClientOptions = new() {\n                ApiKey = mollieOptions.ApiKey,\n                ClientId = mollieOptions.ClientId,\n                ClientSecret = mollieOptions.ClientSecret,\n                CustomUserAgent = mollieOptions.CustomUserAgent,\n                Testmode = mollieOptions.Testmode,\n                ProfileId = mollieOptions.ProfileId,\n                ApiBaseUrl = mollieOptions.ApiBaseUrl,\n                ConnectTokenEndPoint = mollieOptions.ConnectTokenEndPoint,\n                ConnectOAuthAuthorizeEndPoint = mollieOptions.ConnectOAuthAuthorizeEndPoint\n            };\n            services.AddSingleton(mollieClientOptions);\n\n            RegisterMollieApiClient<IBalanceClient, BalanceClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ICaptureClient, CaptureClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IChargebackClient, ChargebackClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IConnectClient, ConnectClient>(services,  mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ICustomerClient, CustomerClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IInvoiceClient, InvoiceClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IMandateClient, MandateClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IOnboardingClient, OnboardingClient>(services, mollieOptions.RetryPolicy);\n#pragma warning disable CS0618\n            RegisterMollieApiClient<IOrderClient, OrderClient>(services, mollieOptions.RetryPolicy);\n#pragma warning restore CS0618\n            RegisterMollieApiClient<IOrganizationClient, OrganizationClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IPaymentClient, PaymentClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IPaymentLinkClient, PaymentLinkClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IPaymentMethodClient, PaymentMethodClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IPermissionClient, PermissionClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IProfileClient, ProfileClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IRefundClient, RefundClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ISettlementClient, SettlementClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ISessionClient, SessionClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IShipmentClient, ShipmentClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ISubscriptionClient, SubscriptionClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ITerminalClient, TerminalClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IClientLinkClient, ClientLinkClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IWalletClient, WalletClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IClientClient, ClientClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ICapabilityClient, CapabilityClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<ISalesInvoiceClient, SalesInvoiceClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IWebhookClient, WebhookClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IWebhookEventClient, WebhookEventClient>(services, mollieOptions.RetryPolicy);\n            RegisterMollieApiClient<IBalanceTransferClient, BalanceTransferClient>(services, mollieOptions.RetryPolicy);\n\n            return services;\n        }\n\n        static void RegisterMollieApiClient<TInterface, TImplementation>(\n            IServiceCollection services,\n            IAsyncPolicy<HttpResponseMessage>? retryPolicy = null)\n            where TInterface : class\n            where TImplementation : class, TInterface {\n\n            IHttpClientBuilder clientBuilder = services.AddHttpClient<TInterface, TImplementation>();\n            if (retryPolicy != null) {\n                clientBuilder.AddPolicyHandler(retryPolicy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Extensions/DateTimeExtensions.cs",
    "content": "﻿using System;\n\nnamespace Mollie.Api.Extensions {\n    internal static class DateTimeExtensions {\n        public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)\n        {\n            if (timeSpan == TimeSpan.Zero) {\n                return dateTime;\n            }\n\n            if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) {\n                return dateTime;\n            } \n            \n            return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));\n        }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Extensions/DictionaryExtensions.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\n\nnamespace Mollie.Api.Extensions {\n    internal static class DictionaryExtensions {\n        public static string ToQueryString(this IDictionary<string, string> parameters) {\n            if (!parameters.Any()) {\n                return string.Empty;\n            }\n\n            return \"?\" + string.Join(\"&\", parameters.Select(x => $\"{WebUtility.UrlEncode(x.Key)}={WebUtility.UrlEncode(x.Value)}\"));\n        }\n\n        public static void AddValueIfNotNullOrEmpty(this IDictionary<string, string> dictionary, string key, string? value) {\n            if (!string.IsNullOrEmpty(value)) {\n                dictionary.Add(key, value!);\n            }\n        }\n\n        public static void AddValueIfTrue(this IDictionary<string, string> dictionary, string key, bool value) {\n            if (value) {\n                dictionary.Add(key, bool.TrueString.ToLower());\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Extensions/HttpClientExtensions.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Mollie.Api.Extensions {\n    internal static class HttpClientExtensions {\n        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string requestUri, HttpContent content) {\n            return client.PatchAsync(CreateUri(requestUri), content);\n        }\n\n        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent content) {\n            return client.PatchAsync(requestUri, content, CancellationToken.None);\n        }\n\n        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken) {\n            return client.PatchAsync(CreateUri(requestUri), content, cancellationToken);\n        }\n\n        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken) {\n            return client.SendAsync(new HttpRequestMessage(new HttpMethod(\"PATCH\"), requestUri) { Content = content }, cancellationToken);\n        }\n\n        private static Uri CreateUri(string uri) {\n            return new Uri(uri, UriKind.RelativeOrAbsolute);\n        }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Extensions/ListExtensions.cs",
    "content": "﻿using System.Collections.Generic;\nnamespace Mollie.Api.Extensions {\n    internal static class ListExtensions {\n        public static string ToIncludeParameter(this List<string> includeList) {\n            return string.Join(\",\", includeList);\n        }\n\n        public static void AddValueIfTrue(this List<string> list, string valueToAdd, bool valueToCheck) {\n            if (valueToCheck) {\n                list.Add(valueToAdd);\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Authentication/Abstract/IMollieSecretManager.cs",
    "content": "﻿namespace Mollie.Api.Framework.Authentication.Abstract;\n\npublic interface IMollieSecretManager {\n    public string GetBearerToken();\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Authentication/DefaultMollieSecretManager.cs",
    "content": "﻿using Mollie.Api.Framework.Authentication.Abstract;\nnamespace Mollie.Api.Framework.Authentication;\n\npublic class DefaultMollieSecretManager(string apiKey) : IMollieSecretManager {\n    public string GetBearerToken() => apiKey;\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Factories/BalanceReportResponseFactory.cs",
    "content": "using System;\nusing Mollie.Api.Models.Balance.Response.BalanceReport;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories;\n\nnamespace Mollie.Api.Framework.Factories {\n    internal class BalanceReportResponseFactory : ITypeFactory<BalanceReportResponse> {\n        public BalanceReportResponse Create(string? reportGrouping) {\n            switch (reportGrouping) {\n                case ReportGrouping.StatusBalances:\n                    return Activator.CreateInstance<StatusBalanceReportResponse>();\n                case ReportGrouping.TransactionCategories:\n                    return Activator.CreateInstance<TransactionCategoriesReportResponse>();\n                default:\n                    return Activator.CreateInstance<BalanceReportResponse>();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Factories/BalanceTransactionFactory.cs",
    "content": "﻿using System;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific;\n\nnamespace Mollie.Api.Framework.Factories {\n    internal class BalanceTransactionFactory : ITypeFactory<BalanceTransactionResponse> {\n        public BalanceTransactionResponse Create(string? type) {\n            if (string.IsNullOrEmpty(type)) {\n                return Activator.CreateInstance<BalanceTransactionResponse>();\n            }\n\n            switch (type) {\n                case BalanceTransactionContextType.Payment:\n                case BalanceTransactionContextType.UnauthorizedDirectDebit:\n                case BalanceTransactionContextType.FailedPayment:\n                case BalanceTransactionContextType.ChargebackReversal:\n                case BalanceTransactionContextType.ApplicationFee:\n                case BalanceTransactionContextType.SplitPayment:\n                    return Activator.CreateInstance<PaymentBalanceTransactionResponse>();\n                case BalanceTransactionContextType.Capture:\n                    return Activator.CreateInstance<CaptureBalanceTransactionResponse>();\n                case BalanceTransactionContextType.Refund:\n                case BalanceTransactionContextType.ReturnedRefund:\n                case BalanceTransactionContextType.PlatformPaymentRefund:\n                    return Activator.CreateInstance<RefundBalanceTransactionResponse>();\n                case BalanceTransactionContextType.Chargeback:\n                case BalanceTransactionContextType.PlatformPaymentChargeback:\n                    return Activator.CreateInstance<ChargebackBalanceTransactionResponse>();\n                case BalanceTransactionContextType.OutgoingTransfer:\n                case BalanceTransactionContextType.CanceledOutgoingTransfer:\n                case BalanceTransactionContextType.ReturnedTransfer:\n                    return Activator.CreateInstance<SettlementBalanceTransactionResponse>();\n                case BalanceTransactionContextType.InvoiceCompensation:\n                    return Activator.CreateInstance<InvoiceBalanceTransactionResponse>();\n                default:\n                    return Activator.CreateInstance<BalanceTransactionResponse>();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Factories/ITypeFactory.cs",
    "content": "namespace Mollie.Api.Framework.Factories;\n\ninternal interface ITypeFactory<T> {\n    T Create(string? type);\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Factories/MandateResponseFactory.cs",
    "content": "﻿using System;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Mandate.Response.PaymentSpecificParameters;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Framework.Factories;\n\ninternal class MandateResponseFactory : ITypeFactory<MandateResponse> {\n    public MandateResponse Create(string? paymentMethod) {\n            if (string.IsNullOrEmpty(paymentMethod)) {\n                return Activator.CreateInstance<MandateResponse>();\n            }\n\n            switch (paymentMethod) {\n                case PaymentMethod.PayPal:\n                    return Activator.CreateInstance<PayPalMandateResponse>();\n                case PaymentMethod.DirectDebit:\n                    return Activator.CreateInstance<SepaDirectDebitMandateResponse>();\n                case PaymentMethod.CreditCard:\n                    return Activator.CreateInstance<CreditCardMandateResponse>();\n                default:\n                    return Activator.CreateInstance<MandateResponse>();\n            }\n        }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Factories/PaymentResponseFactory.cs",
    "content": "﻿using System;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Payment.Response.PaymentSpecificParameters;\n\nnamespace Mollie.Api.Framework.Factories {\n    internal class PaymentResponseFactory : ITypeFactory<PaymentResponse> {\n        public PaymentResponse Create(string? paymentMethod) {\n            if (string.IsNullOrEmpty(paymentMethod)) {\n                return Activator.CreateInstance<PaymentResponse>();\n            }\n\n            switch (paymentMethod) {\n                case PaymentMethod.BankTransfer:\n                    return Activator.CreateInstance<BankTransferPaymentResponse>();\n                case PaymentMethod.CreditCard:\n                    return Activator.CreateInstance<CreditCardPaymentResponse>();\n                case PaymentMethod.Ideal:\n                    return Activator.CreateInstance<IdealPaymentResponse>();\n                case PaymentMethod.Giropay:\n                    return Activator.CreateInstance<GiropayPaymentResponse>();\n                case PaymentMethod.Eps:\n                    return Activator.CreateInstance<EpsPaymentResponse>();\n                case PaymentMethod.Bancontact:\n                    return Activator.CreateInstance<BancontactPaymentResponse>();\n                case PaymentMethod.PayPal:\n                    return Activator.CreateInstance<PayPalPaymentResponse>();\n                case PaymentMethod.PaySafeCard:\n                    return Activator.CreateInstance<PaySafeCardPaymentResponse>();\n                case PaymentMethod.Sofort:\n                    return Activator.CreateInstance<SofortPaymentResponse>();\n                case PaymentMethod.Belfius:\n                    return Activator.CreateInstance<BelfiusPaymentResponse>();\n                case PaymentMethod.DirectDebit:\n                    return Activator.CreateInstance<SepaDirectDebitResponse>();\n                case PaymentMethod.Kbc:\n                    return Activator.CreateInstance<KbcPaymentResponse>();\n                case PaymentMethod.GiftCard:\n                    return Activator.CreateInstance<GiftcardPaymentResponse>();\n                case PaymentMethod.IngHomePay:\n                    return Activator.CreateInstance<IngHomePayPaymentResponse>();\n                case PaymentMethod.PointOfSale:\n                    return Activator.CreateInstance<PointOfSalePaymentResponse>();\n                default:\n                    return Activator.CreateInstance<PaymentResponse>();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/Idempotency/AsyncLocalVariable.cs",
    "content": "﻿using System;\nusing System.Threading;\n\nnamespace Mollie.Api.Framework.Idempotency\n{\n    internal class AsyncLocalVariable<T> : IDisposable where T : class\n    {\n        private readonly AsyncLocal<T?> _asyncLocal = new();\n\n        public T? Value\n        {\n            get => _asyncLocal.Value;\n            set => _asyncLocal.Value = value;\n        }\n\n        public AsyncLocalVariable(T? value)\n        {\n            _asyncLocal.Value = value;\n        }\n\n        public void Dispose()\n        {\n            _asyncLocal.Value = null;\n        }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Framework/JsonConverterService.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing System.Text.Json.Serialization.Metadata;\nusing Mollie.Api.Framework.Factories;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models.Balance.Response.BalanceReport;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Payment.Response;\n\nnamespace Mollie.Api.Framework;\n\ninternal class JsonConverterService\n{\n    private readonly JsonSerializerOptions _defaultJsonDeserializerOptions;\n\n    public JsonConverterService()\n    {\n        _defaultJsonDeserializerOptions = CreateDefaultJsonDeserializerOptions();\n    }\n\n    public string Serialize(object objectToSerialize)\n    {\n        var options = new JsonSerializerOptions\n        {\n            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\n            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,\n            WriteIndented = false,\n            AllowTrailingCommas = true,\n        };\n\n        options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));\n\n        return JsonSerializer.Serialize(objectToSerialize, options);\n    }\n\n    public T? Deserialize<T>(string json)\n    {\n        return JsonSerializer.Deserialize<T>(json, _defaultJsonDeserializerOptions);\n    }\n\n    public object? Deserialize(string json, Type type)\n    {\n        return JsonSerializer.Deserialize(json, type, _defaultJsonDeserializerOptions);\n    }\n\n    /// <summary>\n    /// Creates the default Json serializer options for System.Text.Json parsing.\n    /// </summary>\n    private JsonSerializerOptions CreateDefaultJsonDeserializerOptions()\n    {\n        var options = new JsonSerializerOptions\n        {\n            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,\n            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\n            UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip,\n            AllowTrailingCommas = true,\n            TypeInfoResolver = new DefaultJsonTypeInfoResolver\n            {\n                Modifiers =\n                {\n                    static typeInfo =>\n                    {\n                        if (typeInfo.Kind != JsonTypeInfoKind.Object) {\n                            return;\n                        }\n\n                        foreach (JsonPropertyInfo propertyInfo in typeInfo.Properties)\n                        {\n                            // Strip IsRequired constraint from every property.\n                            propertyInfo.IsRequired = false;\n                        }\n                    }\n                }\n            }\n        };\n\n        options.Converters.Add(new JsonStringEnumConverter());\n        options.Converters.Add(new PolymorphicConverter<PaymentResponse>(new PaymentResponseFactory(), \"method\"));\n        options.Converters.Add(new PolymorphicConverter<MandateResponse>(new MandateResponseFactory(), \"method\"));\n        options.Converters.Add(new PolymorphicConverter<BalanceReportResponse>(new BalanceReportResponseFactory(), \"grouping\"));\n        options.Converters.Add(new PolymorphicConverter<BalanceTransactionResponse>(new BalanceTransactionFactory(), \"type\"));\n\n        return options;\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Framework/MollieHttpRetryPolicies.cs",
    "content": "﻿using System;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Polly;\nusing Polly.Extensions.Http;\nusing Polly.Retry;\n\nnamespace Mollie.Api.Framework {\n    public static class MollieHttpRetryPolicies {\n        /// <summary>\n        /// Retry policy to automatically retry transient errors.\n        /// Transient errors are network failures, http 5xx and http 408 errors.\n        /// </summary>\n        public static IAsyncPolicy<HttpResponseMessage> TransientHttpErrorRetryPolicy(int numberOfRetries = 3) {\n            return HttpPolicyExtensions\n                .HandleTransientHttpError()\n                .WaitAndRetryAsync(numberOfRetries, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,\n                    retryAttempt)));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/CollectionToCommaSeparatedListConverter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.JsonConverters;\n\ninternal class CollectionToCommaSeparatedListConverter : JsonConverter<IList<string>> {\n    public override IList<string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {\n        throw new NotImplementedException();\n    }\n\n    public override void Write(Utf8JsonWriter writer, IList<string> value, JsonSerializerOptions options) {\n        if (value.Count == 0) {\n            writer.WriteStringValue(string.Empty);\n            return;\n        }\n\n        string commaSeparated = string.Join(\",\", value);\n        writer.WriteStringValue(commaSeparated);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/DateJsonConverter.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.JsonConverters;\n\n/// <summary>\n/// Custom converter to handle date format yyyy-MM-dd in System.Text.Json.\n/// </summary>\ninternal class DateJsonConverter : JsonConverter<DateTime?>\n{\n    private const string Format = \"yyyy-MM-dd\";\n\n    public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (reader.TokenType != JsonTokenType.Null) {\n            return null;\n        }\n\n        var value = reader.GetString();\n        if (value == null) {\n            throw new JsonException(\"Expected date string value.\");\n        }\n\n        return DateTime.ParseExact(value, Format, null);\n    }\n\n    public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)\n    {\n        if (value == null) {\n            writer.WriteNullValue();\n        } else {\n            writer.WriteStringValue(value.Value.ToString(Format));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/Iso8601DateTimeConverter.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.JsonConverters {\n    internal class Iso8601DateTimeConverter : JsonConverter<DateTime>\n    {\n        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n        {\n            return DateTime.Parse(reader.GetString()!);\n        }\n\n        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)\n        {\n            writer.WriteStringValue(value.ToUniversalTime().ToString(\"yyyy'-'MM'-'dd'T'HH':'mm':'ssK\"));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/ListResponseJsonConverter.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.JsonConverters;\n\ninternal class ListResponseConverter : JsonConverter<object>\n{\n    public override bool CanConvert(Type typeToConvert)\n    {\n        // Check if the target type is assignable from IList (List<T> implements IList)\n        return typeof(IList).IsAssignableFrom(typeToConvert);\n    }\n\n    public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (reader.TokenType == JsonTokenType.Null)\n        {\n            return null;\n        }\n\n        using JsonDocument document = JsonDocument.ParseValue(ref reader);\n        JsonElement root = document.RootElement;\n\n        if (root.ValueKind == JsonValueKind.Object) {\n            var enumerator = root.EnumerateObject();\n            if (enumerator.MoveNext()) {\n                var firstProperty = enumerator.Current;\n                if (firstProperty.Value.ValueKind == JsonValueKind.Array) {\n                    var arrayJson = firstProperty.Value.GetRawText();\n                    return JsonSerializer.Deserialize(arrayJson, typeToConvert, options);\n                }\n            }\n        }\n\n        return null;\n    }\n\n    public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)\n    {\n        throw new NotImplementedException(\"Not implemented\");\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/MicrosecondEpochConverter.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.JsonConverters {\n    internal class MicrosecondEpochConverter : JsonConverter<DateTime>\n    {\n        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n        {\n            var longValue = reader.GetInt64();\n            return DateTimeOffset.FromUnixTimeMilliseconds(longValue).UtcDateTime;\n        }\n\n        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/PolymorphicConverter.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.Framework.Factories;\n\nnamespace Mollie.Api.JsonConverters;\n\ninternal class PolymorphicConverter<T> : JsonConverter<T> {\n    private readonly ITypeFactory<T> _typeFactory;\n    private readonly string _typeFieldName;\n\n    public PolymorphicConverter(ITypeFactory<T> typeFactory, string typeFieldName)\n    {\n        _typeFactory = typeFactory;\n        _typeFieldName = typeFieldName;\n    }\n\n    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {\n        // Parse the current JSON object into a JsonDocument for easy querying\n        using JsonDocument document = JsonDocument.ParseValue(ref reader);\n        JsonElement root = document.RootElement;\n\n        // Try to get the \"method\" property value\n        string? type = null;\n        if (root.TryGetProperty(_typeFieldName, out JsonElement typeProperty))\n        {\n            type = typeProperty.GetString();\n        }\n\n        // Use the factory to create the right PaymentResponse instance\n        T response = _typeFactory.Create(type);\n\n        // Deserialize the JSON into the created instance, using the root element JSON\n        // Since System.Text.Json cannot deserialize into existing objects directly,\n        // we re-serialize the root JSON and deserialize again into the correct type.\n\n        var json = root.GetRawText();\n\n        // Create new options without this converter to avoid stack overflow\n        JsonSerializerOptions newOptions = new(options);\n        newOptions.Converters.Remove(this);\n\n        var result = (T)JsonSerializer.Deserialize(json, response!.GetType(), newOptions)!;\n\n        return result;\n    }\n\n    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)\n    {\n        JsonSerializer.Serialize(writer, value, value!.GetType(), options);\n    }\n}\n\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/RawJsonConverter.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.JsonConverters;\n\ninternal class RawJsonConverter : JsonConverter<string>\n{\n    public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {\n        using JsonDocument document = JsonDocument.ParseValue(ref reader);\n        if (document.RootElement.ValueKind == JsonValueKind.Null)\n        {\n            return null;\n        }\n\n        if (document.RootElement.ValueKind == JsonValueKind.String)\n        {\n            return document.RootElement.GetString();\n        }\n\n        return document.RootElement.GetRawText();\n    }\n\n    public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)\n    {\n        if (string.IsNullOrEmpty(value))\n        {\n            writer.WriteNullValue();\n            return;\n        }\n\n        if (IsValidJson(value!))\n        {\n            writer.WriteRawValue(value!);\n        }\n        else\n        {\n            writer.WriteStringValue(value);\n        }\n    }\n\n    private bool IsValidJson(string strInput)\n    {\n        strInput = strInput.Trim();\n        if ((strInput.StartsWith(\"{\") && strInput.EndsWith(\"}\")) ||\n            (strInput.StartsWith(\"[\") && strInput.EndsWith(\"]\")))\n        {\n            try\n            {\n                JsonDocument.Parse(strInput);\n                return true;\n            }\n            catch (JsonException)\n            {\n                return false;\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n        else\n        {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/SettlementPeriodConverter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.Models.Settlement.Response;\n\nnamespace Mollie.Api.JsonConverters;\n\ninternal class SettlementPeriodConverter : JsonConverter<Dictionary<int, Dictionary<int, SettlementPeriod>>> {\n    public override Dictionary<int, Dictionary<int, SettlementPeriod>>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {\n        // If we have no periods, Mollie returns a empty array instead of an object\n        if (reader.TokenType == JsonTokenType.StartArray) {\n            reader.Skip();\n            return new Dictionary<int, Dictionary<int, SettlementPeriod>>();\n        }\n\n        var result = new Dictionary<int, Dictionary<int, SettlementPeriod>>();\n        using JsonDocument doc = JsonDocument.ParseValue(ref reader);\n        foreach (var property in doc.RootElement.EnumerateObject()) {\n            int month = int.Parse(property.Name);\n            var monthPeriods = new Dictionary<int, SettlementPeriod>();\n\n            foreach (var period in property.Value.EnumerateObject()) {\n                int day = int.Parse(period.Name);\n                var settlementPeriod = JsonSerializer.Deserialize<SettlementPeriod>(period.Value.GetRawText(), options)!;\n                monthPeriods[day] = settlementPeriod;\n            }\n\n            result[month] = monthPeriods;\n        }\n\n        return result;\n    }\n\n    public override void Write(Utf8JsonWriter writer, Dictionary<int, Dictionary<int, SettlementPeriod>> value, JsonSerializerOptions options) {\n        throw new NotImplementedException();\n    }\n}\n\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/StringToDecimalConverter.cs",
    "content": "using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.JsonConverters;\n\ninternal class StringToDecimalConverter : JsonConverter<decimal> {\n    public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {\n        if (reader.TokenType == JsonTokenType.Null) {\n            throw new JsonException(\"Cannot convert null to decimal.\");\n        }\n\n        if (reader.TokenType == JsonTokenType.String) {\n            string value = reader.GetString() ?? \"0\";\n            if (decimal.TryParse(value, out decimal result)) {\n                return result;\n            }\n        }\n        else if (reader.TokenType == JsonTokenType.Number) {\n            return reader.GetDecimal();\n        }\n\n        throw new JsonException($\"Unable to convert \\\"{reader.GetString()}\\\" to {typeToConvert.Name}.\");\n    }\n\n    public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) {\n        writer.WriteStringValue(value.ToString(\"G\", System.Globalization.CultureInfo.InvariantCulture));\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/JsonConverters/WebhookEventEntityJsonConverter.cs",
    "content": "using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Balance.Response;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.Invoice.Response;\nusing Mollie.Api.Models.Issuer.Response;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Order.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.SalesInvoice.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Shipment.Response;\nusing Mollie.Api.Models.Subscription.Response;\nusing Mollie.Api.Models.Terminal.Response;\n\nnamespace Mollie.Api.JsonConverters;\n\ninternal class WebhookEventEntityJsonConverter : JsonConverter<object> {\n    public override bool CanConvert(Type typeToConvert)\n    {\n        return typeof(IEntity).IsAssignableFrom(typeToConvert);\n    }\n\n    public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (reader.TokenType == JsonTokenType.Null)\n        {\n            return null;\n        }\n\n        using JsonDocument document = JsonDocument.ParseValue(ref reader);\n        JsonElement root = document.RootElement;\n\n        if (root.ValueKind == JsonValueKind.Object) {\n            var enumerator = root.EnumerateObject();\n            if (enumerator.MoveNext()) {\n                var firstProperty = enumerator.Current;\n                if (firstProperty.Value.ValueKind == JsonValueKind.Object) {\n                    typeToConvert = GetEntityTypeFromJson(firstProperty, typeToConvert);\n\n                    var arrayJson = firstProperty.Value.GetRawText();\n                    return JsonSerializer.Deserialize(arrayJson, typeToConvert, options);\n                }\n            }\n        }\n\n        return null;\n    }\n\n    public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)\n    {\n        throw new NotImplementedException(\"Not implemented\");\n    }\n\n    private Type GetEntityTypeFromJson(JsonProperty entityRoot, Type typeToConvert)\n    {\n        if (typeToConvert != typeof(IEntity)) {\n            return typeToConvert;\n        }\n\n        if (entityRoot.Value.TryGetProperty(\"resource\", out JsonElement resourceProperty))\n        {\n            string? resource = resourceProperty.GetString();\n\n            switch (resource) {\n                case \"balance\": return typeof(BalanceResponse);\n                case \"capture\": return typeof(CaptureResponse);\n                case \"chargeback\": return typeof(ChargebackResponse);\n                case \"customer\": return typeof(CustomerResponse);\n                case \"invoice\": return typeof(InvoiceResponse);\n                case \"issuer\": return typeof(IssuerResponse);\n                case \"mandate\": return typeof(MandateResponse);\n                case \"order\": return typeof(OrderResponse);\n                case \"refund\": return typeof(RefundResponse);\n                case \"settlement\": return typeof(SettlementResponse);\n                case \"shipment\": return typeof(ShipmentResponse);\n                case \"subscription\": return typeof(SubscriptionResponse);\n                case \"terminal\": return typeof(TerminalResponse);\n                case \"payment\": return typeof(PaymentResponse);\n                case \"payment-link\": return typeof(PaymentLinkResponse);\n                case \"sales-invoice\": return typeof(SalesInvoiceResponse);\n                default:\n                    throw new JsonException(\n                        $\"Unable to convert embedded JSON to entity type. Resource '{resource}' is not supported or recognized.\");\n            }\n        }\n\n        throw new JsonException(\"Unable to convert embedded JSON to entity type. No resource property found\");\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/AddressObject.cs",
    "content": "﻿namespace Mollie.Api.Models {\n    public record AddressObject {\n        /// <summary>\n        /// The card holder’s street and street number.\n        /// </summary>\n        public string? StreetAndNumber { get; set; }\n\n        /// <summary>\n        /// Any additional addressing details, for example an apartment number.\n        /// </summary>\n        public string? StreetAdditional { get; set; }\n\n        /// <summary>\n        /// The card holder’s postal code.\n        /// </summary>\n        public string? PostalCode { get; set; }\n\n        /// <summary>\n        /// The card holder’s city.\n        /// </summary>\n        public string? City { get; set; }\n\n        /// <summary>\n        /// The card holder’s region.\n        /// </summary>\n        public string? Region { get; set; }\n\n        /// <summary>\n        /// The card holder’s country in ISO 3166-1 alpha-2 format.\n        /// </summary>\n        public string? Country { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Amount.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models {\n    /// <summary>\n    /// The amount of a payment, refund, or chargeback.\n    /// </summary>\n    public record Amount {\n        private static readonly IDictionary<string, string> CurrenciesWithAlternativeDecimalPrecision =\n            new Dictionary<string, string>() {\n                { \"JPY\", \"0\" },\n                { \"ISK\", \"0\" },\n            };\n\n        /// <summary>\n        /// An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on your account.\n        /// </summary>\n        public required string Currency { get; set; }\n\n        /// <summary>\n        /// An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on your account.\n        /// </summary>\n        public required string Value { get; set; }\n\n        /// <summary>\n        /// Constructor for constructing based on a string value\n        /// </summary>\n        /// <param name=\"currency\">An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on your account.</param>\n        /// <param name=\"value\">A string containing an exact monetary amount in the given currency.</param>\n        [JsonConstructor]\n        [SetsRequiredMembers]\n        public Amount(string currency, string value) {\n            Currency = currency;\n            Value = value;\n        }\n\n        /// <summary>\n        /// Constructor for constructing based on a decimal value\n        /// </summary>\n        /// <param name=\"currency\">An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on your account.</param>\n        /// <param name=\"value\">The amount in the specified currency.</param>\n        [SetsRequiredMembers]\n        public Amount(string currency, decimal value) {\n            Currency = currency;\n            Value = ConvertDecimalAmountToStringAmount(currency, value);\n        }\n\n        /// <summary>\n        /// Implicit cast operator from Amount to decimal.\n        /// </summary>\n        /// <param name=\"amount\"></param>\n        public static implicit operator decimal(Amount amount)\n            => decimal.TryParse(amount.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var a) ? a : throw new InvalidCastException($\"Cannot convert {amount.Value} to decimal\");\n\n        /// <summary>\n        /// Implicit cast operator from Amount? to decimal?.\n        /// </summary>\n        /// <param name=\"amount\"></param>\n        public static implicit operator decimal?(Amount? amount)\n            => amount == null ? null : (decimal)amount;\n\n        private static string ConvertDecimalAmountToStringAmount(string currency, decimal value) {\n            if (CurrenciesWithAlternativeDecimalPrecision.TryGetValue(currency, out string? format)) {\n                return value.ToString(format, CultureInfo.InvariantCulture);\n            }\n\n            return value.ToString(\"0.00\", CultureInfo.InvariantCulture);\n        }\n\n        public override string ToString() {\n            return $\"{Value} {Currency}\";\n        }\n\n        public override int GetHashCode() {\n            unchecked {\n                return (Currency.GetHashCode() * 397) ^ Value.GetHashCode();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/ApplicationFee.cs",
    "content": "﻿namespace Mollie.Api.Models {\n\tpublic record ApplicationFee {\n\t\t/// <summary>\n\t\t///\tThe amount in EURO that the app wants to charge, e.g. 10.00 if the app would want to charge €10.00.\n\t\t/// </summary>\n\t\tpublic required Amount Amount { get; set; }\n\n\t\t/// <summary>\n\t\t///\tThe description of the application fee. This will appear on settlement reports to the merchant and to you.\n\t\t/// </summary>\n\t\tpublic required string Description { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/BalanceReportAmount.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport {\n    public record BalanceReportAmount {\n        public required Amount Amount { get; set; }\n\n        public override string ToString() {\n            return Amount.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/BalanceReportAmountWithSubtotals.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Balance.Response.BalanceReport {\n    public record BalanceReportAmountWithSubtotals : BalanceReportAmount {\n        public required IEnumerable<BalanceReportSubtotals> Subtotals { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/BalanceReportLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Balance.Response.BalanceReport {\n    public record BalanceReportLinks {\n        /// <summary>\n        /// The API resource URL of the balance report itself.\n        /// </summary>\n        public required UrlObjectLink<BalanceReportResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL to the order retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/BalanceReportResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Balance.Response.BalanceReport {\n    public record BalanceReportResponse {\n        /// <summary>\n        /// Indicates the response contains a balance report object. Will always contain balance-report for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The ID of a Balance this report is generated for.\n        /// </summary>\n        public required string BalanceId { get; set; }\n\n        /// <summary>\n        /// The time zone used for the from and until parameters. Currently only time zone Europe/Amsterdam is supported.\n        /// </summary>\n        public required string TimeZone { get; set; }\n\n        /// <summary>\n        /// The start date of the report, in YYYY-MM-DD format. The from date is ‘inclusive’, and in Central European Time.\n        /// This means a report with for example from: 2020-01-01 will include movements of 2020-01-01 0:00:00 CET and onwards.\n        /// </summary>\n        public required DateTime From { get; set; }\n\n        /// <summary>\n        /// The end date of the report, in YYYY-MM-DD format. The until date is ‘exclusive’, and in Central European Time.\n        /// This means a report with for example until: 2020-02-01 will include movements up until 2020-01-31 23:59:59 CET.\n        /// </summary>\n        public required DateTime Until { get; set; }\n\n        /// <summary>\n        /// You can retrieve reports in two different formats. With the status-balances format, transactions are grouped by status\n        /// (e.g. pending, available), then by direction of movement (e.g. moved from pending to available), then by transaction type,\n        /// and then by other sub-groupings where available (e.g. payment method).\n        /// <para>With the transaction-categories format, transactions are grouped by transaction type, then by direction of movement, and\n        /// then again by other sub-groupings where available.</para>\n        /// <para>Both reporting formats will always contain opening and closing amounts that correspond to the start and end dates of the report.\n        /// Possible values: status-balances transaction-categories</para>\n        /// </summary>\n        public required string Grouping { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the balance report.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required BalanceReportLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/BalanceReportSubtotals.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Balance.Response.BalanceReport {\n    public record BalanceReportSubtotals {\n        public string? TransactionType { get; set; }\n        public string? Method { get; set; }\n        public string? PrepaymentPartType { get; set; }\n        public required string FeeType { get; set; }\n        public required int Count { get; set; }\n        public required Amount Amount { get; set; }\n        public IEnumerable<BalanceReportSubtotals>? Subtotals { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/ReportGrouping.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport {\n    public static class ReportGrouping {\n        public const string StatusBalances = \"status-balances\";\n        public const string TransactionCategories = \"transaction-categories\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/StatusBalance/StatusBalanceAvailableBalance.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance {\n    public record StatusBalanceAvailableBalance {\n        public required BalanceReportAmount Open { get; set; }\n        public required BalanceReportAmount Close { get; set; }\n        public required BalanceReportAmountWithSubtotals MovedFromPending { get; set; }\n        public required BalanceReportAmountWithSubtotals ImmediatelyAvailable { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/StatusBalance/StatusBalanceReportResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance {\n    public record StatusBalanceReportResponse : BalanceReportResponse {\n        public required StatusBalancesTotal Totals { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/StatusBalance/StatusBalancesPendingBalance.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance {\n    public record StatusBalancesPendingBalance {\n        public required BalanceReportAmount Open { get; set; }\n        public required BalanceReportAmount Close { get; set; }\n        public required BalanceReportAmountWithSubtotals Pending { get; set; }\n        public required BalanceReportAmountWithSubtotals MovedToAvailable { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/StatusBalance/StatusBalancesTotal.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance {\n    public record StatusBalancesTotal {\n        public required StatusBalancesPendingBalance PendingBalance { get; set; }\n        public required StatusBalanceAvailableBalance AvailableBalance { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/TransactionCategories/TransactionCategoriesReportResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories {\n    public record TransactionCategoriesReportResponse : BalanceReportResponse {\n        public required TransactionCategoriesTotal Totals { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/TransactionCategories/TransactionCategoriesSummaryBalances.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories {\n    public record TransactionCategoriesSummaryBalances {\n        public required BalanceReportAmount Pending { get; set; }\n        public required BalanceReportAmount Available { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/TransactionCategories/TransactionCategoriesTotal.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories {\n    public record TransactionCategoriesTotal {\n        public required TransactionCategoriesSummaryBalances Open { get; set; }\n        public required TransactionCategoriesSummaryBalances Close { get; set; }\n        public required TransactionCategoriesTransaction Payments { get; set; }\n        public required TransactionCategoriesTransaction Refunds { get; set; }\n        public required TransactionCategoriesTransaction Chargebacks { get; set; }\n        public required TransactionCategoriesTransaction Capital { get; set; }\n        public required TransactionCategoriesTransaction Transfers { get; set; }\n        [JsonPropertyName(\"fee-prepayments\")]\n        public required TransactionCategoriesTransaction FeePrepayments { get; set; }\n        public required TransactionCategoriesTransaction Corrections { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceReport/Specific/TransactionCategories/TransactionCategoriesTransaction.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories {\n    public record TransactionCategoriesTransaction {\n        public required BalanceReportAmountWithSubtotals Pending { get; set; }\n        public required BalanceReportAmountWithSubtotals MovedToAvailable { get; set; }\n        public required BalanceReportAmountWithSubtotals ImmediatelyAvailable { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Balance.Response {\n    public class BalanceResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a balance object. Will always contain balance for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The identifier uniquely referring to this balance. Mollie assigns this identifier at balance creation time. For example bal_gVMhHKqSSRYJyPsuoPNFH.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The balance’s date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// The balance’s ISO 4217 currency code.\n        /// </summary>\n        public required string Currency { get; set; }\n\n        /// <summary>\n        /// The status of the balance.\n        /// </summary>\n        public required BalanceResponseStatus Status { get; set; }\n\n        /// <summary>\n        /// The frequency at which the available amount on the balance will be settled to the configured transfer destination.\n        /// See transferDestination.\n        /// </summary>\n        public required string TransferFrequency { get; set; }\n\n        /// <summary>\n        /// The minimum amount configured for scheduled automatic settlements. As soon as the amount on the balance exceeds this threshold,\n        /// the complete balance will be paid out to the transferDestination according to the configured transferFrequency.\n        /// </summary>\n        public required Amount TransferThreshold { get; set; }\n\n        /// <summary>\n        /// The transfer reference set to be included in all the transfers for this balance. Either a string or null.\n        /// </summary>\n        public string? TransferReference { get; set; }\n\n        /// <summary>\n        /// The destination where the available amount will be automatically transferred to according to the configured transferFrequency.\n        /// </summary>\n        public required BalanceTransferDestination TransferDestination { get; set; }\n\n        /// <summary>\n        /// The amount directly available on the balance, e.g. {\"currency\":\"EUR\", \"value\":\"100.00\"}.\n        /// </summary>\n        public required Amount AvailableAmount { get; set; }\n\n        /// <summary>\n        /// The total amount that is queued to be transferred to your balance. For example, a credit card payment can take a few days to clear.\n        /// </summary>\n        public required Amount PendingAmount { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the balance. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required BalanceResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Balance.Response {\n    public class BalanceResponseLinks {\n        /// <summary>\n        /// The API resource URL of the balance itself.\n        /// </summary>\n        public required UrlObjectLink<BalanceResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL to the order retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceResponseStatus.cs",
    "content": "﻿using System.Runtime.Serialization;\n\nnamespace Mollie.Api.Models.Balance.Response {\n    public enum BalanceResponseStatus {\n        [EnumMember(Value = \"active\")] Active,\n        [EnumMember(Value = \"inactive\")] Inactive\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/BalanceTransactionContextType.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceTransaction {\n    public static class BalanceTransactionContextType {\n        public const string Payment = \"payment\";\n        public const string Capture = \"capture\";\n        public const string UnauthorizedDirectDebit = \"unauthorized-direct-debit\";\n        public const string FailedPayment = \"failed-payment\";\n        public const string Refund = \"refund\";\n        public const string ReturnedRefund = \"returned-refund\";\n        public const string Chargeback = \"chargeback\";\n        public const string ChargebackReversal = \"chargeback-reversal\";\n        public const string OutgoingTransfer = \"outgoing-transfer\";\n        public const string CanceledOutgoingTransfer = \"canceled-outgoing-transfer\";\n        public const string ReturnedTransfer = \"returned-transfer\";\n        public const string InvoiceCompensation = \"invoice-compensation\";\n        public const string BalanceCorrection = \"balance-correction\";\n        public const string ApplicationFee = \"application-fee\";\n        public const string SplitPayment = \"split-payment\";\n        public const string PlatformPaymentRefund = \"platform-payment-refund\";\n        public const string PlatformPaymentChargeback = \"platform-payment-chargeback\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/BalanceTransactionResponse.cs",
    "content": "﻿using System;\n\nnamespace Mollie.Api.Models.Balance.Response.BalanceTransaction {\n    public class BalanceTransactionResponse {\n        /// <summary>\n        /// Indicates the response contains a balance transaction object. Will always contain balance_transaction\n        /// for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The identifier uniquely referring to this balance transaction. Mollie assigns this identifier at\n        /// transaction creation time. For example baltr_QM24QwzUWR4ev4Xfgyt29d.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The type of movement, for example payment or refund. See Mollie docs for a full list of values\n        /// </summary>\n        public required string Type { get; set; }\n\n        /// <summary>\n        /// The final amount that was moved to or from the balance, e.g. {\"currency\":\"EUR\", \"value\":\"100.00\"}.\n        /// If the transaction moves funds away from the balance, for example when it concerns a refund, the\n        /// amount will be negative.\n        /// </summary>\n        public required Amount ResultAmount { get; set; }\n\n        /// <summary>\n        /// The amount that was to be moved to or from the balance, excluding deductions. If the transaction\n        /// moves funds away from the balance, for example when it concerns a refund, the amount will be negative.\n        /// </summary>\n        public required Amount InitialAmount { get; set; }\n\n        /// <summary>\n        /// The total amount of deductions withheld from the movement. For example, if a €10,00 payment comes in\n        /// with a €0,29 fee, the deductions amount will be {\"currency\":\"EUR\", \"value\":\"-0.29\"}. When moving funds\n        /// to a balance, we always round the deduction to a ‘real’ amount. Any differences between these realtime\n        /// rounded amounts and the final invoice will be compensated when the invoice is generated.\n        /// </summary>\n        public required Amount Deductions { get; set; }\n\n        /// <summary>\n        /// The date and time of the movement, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/Specific/CaptureBalanceTransactionResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific {\n    public class CaptureBalanceTransactionResponse : BalanceTransactionResponse {\n        public required CaptureTransactionContext Context { get; set; }\n    }\n\n    public class CaptureTransactionContext {\n        public required string PaymentId { get; set; }\n        public required string CaptureId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/Specific/ChargebackBalanceTransactionResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific {\n    public class ChargebackBalanceTransactionResponse : BalanceTransactionResponse {\n        public required ChargebackTransactionContext Context { get; set; }\n    }\n\n    public class ChargebackTransactionContext {\n        public required string PaymentId { get; set; }\n        public required string ChargebackId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/Specific/InvoiceBalanceTransactionResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific {\n    public class InvoiceBalanceTransactionResponse : BalanceTransactionResponse {\n        public required InvoiceTransactionContext Context { get; set; }\n    }\n\n    public class InvoiceTransactionContext {\n        public required string InvoiceId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/Specific/PaymentBalanceTransactionResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific {\n    public class PaymentBalanceTransactionResponse : BalanceTransactionResponse {\n        public required PaymentTransactionContext Context { get; set; }\n    }\n\n    public class PaymentTransactionContext {\n        public required string PaymentId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/Specific/RefundBalanceTransactionResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific {\n    public class RefundBalanceTransactionResponse : BalanceTransactionResponse {\n        public required RefundTransactionContext Context { get; set; }\n    }\n\n    public class RefundTransactionContext {\n        public required string PaymentId { get; set; }\n        public required string RefundId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransaction/Specific/SettlementBalanceTransactionResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific {\n    public class SettlementBalanceTransactionResponse : BalanceTransactionResponse {\n        public required SettlementTransactionContext Context { get; set; }\n    }\n\n    public class SettlementTransactionContext {\n        public required string TransferId { get; set; }\n        public required string SettlementId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Balance/Response/BalanceTransferDestination.cs",
    "content": "namespace Mollie.Api.Models.Balance.Response {\n    public class BalanceTransferDestination {\n        /// <summary>\n        /// The default destination of automatic scheduled transfers. Currently only bank-account is supported.\n        /// </summary>\n        public required string Type { get; set; }\n\n        /// <summary>\n        /// The configured bank account number of the beneficiary the balance amount is to be transferred to.\n        /// </summary>\n        public required string BankAccount { get; set; }\n\n        /// <summary>\n        /// The full name of the beneficiary the balance amount is to be transferred to.\n        /// </summary>\n        public required string BeneficiaryName { get; set; }\n\n        public override string ToString() {\n            return $\"{Type} - {BankAccount} - {BeneficiaryName}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/BalanceTransfer/BalanceTransferParty.cs",
    "content": "﻿namespace Mollie.Api.Models.BalanceTransfer;\n\npublic record BalanceTransferParty {\n    /// <summary>\n    /// Defines the type of the party. At the moment, only organization is supported.\n    /// </summary>\n    public required string Type { get; set; }\n\n    /// <summary>\n    /// Identifier of the party. For example, this contains the organization token if the type is organization.\n    /// </summary>\n    public required string Id { get; set; }\n\n    /// <summary>\n    /// The transfer description for the transfer party. This is the description that will appear in the financial reports of the party.\n    /// </summary>\n    public required string Description { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/BalanceTransfer/Request/BalanceTransferRequest.cs",
    "content": "﻿using System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.BalanceTransfer.Request;\n\npublic record BalanceTransferRequest : ITestModeRequest {\n    /// <summary>\n    /// The amount to be transferred, e.g. {\"currency\":\"EUR\", \"value\":\"1000.00\"} if you would like to transfer €1000.00.\n    /// </summary>\n    public required Amount Amount { get; set; }\n\n    /// <summary>\n    /// A party involved in the balance transfer, either the sender or the receiver.\n    /// </summary>\n    public required BalanceTransferParty Source { get; set; }\n\n    /// <summary>\n    /// A party involved in the balance transfer, either the sender or the receiver.\n    /// </summary>\n    public required BalanceTransferParty Destination { get; set; }\n\n    /// <summary>\n    /// The transfer description for initiating party.\n    /// </summary>\n    public required string Description { get; set; }\n\n    /// <summary>\n    /// The type of the transfer. Different fees may apply to different types of transfers.\n    /// </summary>\n    public string? Category { get; set; }\n\n    /// <summary>\n    /// A JSON object that you can attach to a balance transfer. This can be useful for storing additional\n    /// information about the transfer in a structured format. Maximum size is approximately 1KB.\n    /// </summary>\n    [JsonConverter(typeof(RawJsonConverter))]\n    public string? Metadata { get; set; }\n\n    /// <summary>\n    /// Whether to create the entity in test mode or live mode. You can enable test mode by setting testmode to true.\n    /// </summary>\n    public bool? Testmode { get; set; }\n\n    public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n        Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/BalanceTransfer/Response/BalanceTransferResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models.Payment.Response;\n\nnamespace Mollie.Api.Models.BalanceTransfer.Response;\n\npublic record BalanceTransferResponse {\n    /// <summary>\n    /// Indicates the response contains a balance transfer object. Will always contain the string\n    /// connect-balance-transfer for this endpoint.\n    /// </summary>\n    public required string Resource { get; set; }\n\n    /// <summary>\n    /// The identifier uniquely referring to this balance transfer. Mollie assigns this identifier at balance transfer\n    /// creation time. Mollie will always refer to the balance transfer by this ID. Example: cbtr_j8NvRAM2WNZtsykpLEX8J.\n    /// </summary>\n    public required string Id { get; set; }\n\n    /// <summary>\n    /// The amount to be transferred, e.g. {\"currency\":\"EUR\", \"value\":\"1000.00\"} if you would like to transfer €1000.00.\n    /// </summary>\n    public required Amount Amount { get; set; }\n\n    /// <summary>\n    /// A party involved in the balance transfer, either the sender or the receiver.\n    /// </summary>\n    public required BalanceTransferParty Source { get; set; }\n\n    /// <summary>\n    /// A party involved in the balance transfer, either the sender or the receiver.\n    /// </summary>\n    public required BalanceTransferParty Destination { get; set; }\n\n    /// <summary>\n    /// The transfer description for initiating party.\n    /// </summary>\n    public required string Description { get; set; }\n\n    /// <summary>\n    /// The status of the transfer.\n    /// </summary>\n    public required string Status { get; set; }\n\n    /// <summary>\n    /// The reason for the current status of the transfer, if applicable\n    /// </summary>\n    public required StatusReason StatusReason { get; set; }\n\n    /// <summary>\n    /// The entity's date and time of creation, in ISO 8601 format.\n    /// </summary>\n    public required DateTime CreatedAt { get; set; }\n\n    /// <summary>\n    /// The date and time when the transfer was completed, in ISO 8601 format.\n    /// This parameter is omitted if the transfer is not executed (yet).\n    /// </summary>\n    public DateTime? ExecutedAt { get; set; }\n\n    /// <summary>\n    /// Whether this entity was created in live mode or in test mode.\n    /// </summary>\n    public required Mode Mode { get; set; }\n\n    /// <summary>\n    /// A JSON object that you can attach to a balance transfer. This can be useful for storing additional\n    /// information about the transfer in a structured format. Maximum size is approximately 1KB.\n    /// </summary>\n    [JsonConverter(typeof(RawJsonConverter))]\n    public string? Metadata { get; set; }\n\n    public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n        Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/BalanceTransfer/Response/BalanceTransferStatusReason.cs",
    "content": "﻿namespace Mollie.Api.Models.BalanceTransfer.Response;\n\npublic class BalanceTransferStatusReason {\n    /// <summary>\n    /// A machine-readable code that indicates the reason for the transfer's status.\n    /// </summary>\n    public required string Code { get; set; }\n\n    /// <summary>\n    /// A description of the status reason, localized according to the transfer.\n    /// </summary>\n    public required string Message { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capability/CapabilityRequirementStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Capability;\n\npublic static class CapabilityRequirementStatus {\n    public const string CurrentlyDue = \"currently-due\";\n    public const string PastDue = \"past-due\";\n    public const string Requested = \"requested\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capability/CapabilityStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Capability;\n\npublic static class CapabilityStatus {\n    public const string Unrequested = \"unrequested\";\n    public const string Enabled = \"enabled\";\n    public const string Disabled = \"disabled\";\n    public const string Pending = \"pending\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capability/CapabilityStatusReason.cs",
    "content": "﻿namespace Mollie.Api.Models.Capability;\n\npublic static class CapabilityStatusReason {\n    public const string RequirementPastDue = \"requirement-past-due\";\n    public const string OnboardingInformtionNeeded = \"onboarding-information-needed\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capability/Response/CapabilityRequirement.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Capability.Response;\n\npublic record CapabilityRequirement {\n    /// <summary>\n    /// The name of this requirement, referring to the task to be fulfilled by the organization to enable or re-enable\n    /// the capability. The name is unique among other requirements of the same capability.\n    /// </summary>\n    public required string Id { get; set; }\n\n    /// <summary>\n    /// The status of the requirement depends on its due date. If no due date is given, the status will be requested.\n    /// A list of possible values can be found in the Mollie.Api.Models.Capability.CapabilityRequirementStatus class.\n    /// </summary>\n    public required string Status { get; set; }\n\n    /// <summary>\n    /// Due date until the requirement must be fulfilled, if any\n    /// </summary>\n    public DateTime? DueDate { get; set; }\n\n    /// <summary>\n    /// Related links\n    /// </summary>\n    [JsonPropertyName(\"_links\")]\n    public required CapabilityRequirementLinks Links { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capability/Response/CapabilityRequirementLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Capability.Response;\n\npublic record CapabilityRequirementLinks {\n    /// <summary>\n    /// If known, a deep link to the Mollie dashboard of the client, where the requirement can be fulfilled.\n    /// For example, where necessary documents are to be uploaded.\n    /// </summary>\n    public required UrlLink Dashboard { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capability/Response/CapabilityResponse.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Capability.Response;\n\npublic record CapabilityResponse {\n    /// <summary>\n    /// Always the word capability for this resource type.\n    /// </summary>\n    public required string Resource { get; set; }\n\n    /// <summary>\n    /// A unique name for this capability like payments / settlements.\n    /// </summary>\n    public required string Name { get; set; }\n\n    /// <summary>\n    /// The status of the capability. A list of possible values can be found in the\n    /// Mollie.Api.Models.Capability.CapabilityStatus class.\n    /// </summary>\n    public required string Status { get; set; }\n\n    /// <summary>\n    /// The reason the capability is in this status. A list of possible values can be found in the\n    /// Mollie.Api.Models.Capability.CapabilityStatusReason class.\n    /// </summary>\n    public required string StatusReason { get; set; }\n\n    /// <summary>\n    /// The requirements that need to be fulfilled before the capability can be enabled.\n    /// </summary>\n    public required IEnumerable<CapabilityRequirement> Requirements { get; set; }\n\n    /// <summary>\n    /// Related links\n    /// </summary>\n    public required CapabilityResponseLinks Links { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capability/Response/CapabilityResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Capability.Response;\n\npublic record CapabilityResponseLinks {\n    public required UrlLink Documentation { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capture/CaptureMode.cs",
    "content": "﻿namespace Mollie.Api.Models.Capture {\n    public static class CaptureMode {\n        public const string Automatic = \"automatic\";\n        public const string Manual = \"manual\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Capture/Request/CaptureRequest.cs",
    "content": "﻿using System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Capture.Request {\n    public record CaptureRequest : ITestModeRequest {\n        /// <summary>\n        /// The amount to capture.\n        /// </summary>\n        public Amount? Amount { get; set; }\n\n        /// <summary>\n        /// The description of the capture you are creating.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, for example a string or a JSON object. We will save the data alongside the capture.\n        /// Whenever you fetch the capture with our API, we will also include the metadata. You can use up to\n        /// approximately 1kB.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this capture for a test payment\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n\n        public override string ToString() {\n            return $\"Amount: {Amount} Description: {Description}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capture/Response/CaptureResponse.cs",
    "content": "using System;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Capture.Response\n{\n    public record CaptureResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a capture object. Will always contain capture for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The capture’s unique identifier, for example cpt_4qqhO89gsT.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The mode used to create this capture.\n        /// Possible values: live test\n        /// </summary>\n        public required string Mode { get; set; }\n\n        /// <summary>\n        /// The amount captured.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The capture’s status.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// This optional field will contain the amount that will be settled to your account, converted to the currency your account is settled in. It follows the same syntax as the amount property.\n        /// </summary>\n        public required Amount SettlementAmount { get; set; }\n\n        /// <summary>\n        /// The unique identifier of the payment this capture was created for, for example: tr_7UhSN1zuXS\n        /// </summary>\n        public required string PaymentId { get; set; }\n\n        /// <summary>\n        /// The unique identifier of the shipment that triggered the creation of this capture, for example: shp_3wmsgCJN4U\n        /// </summary>\n        public required string ShipmentId { get; set; }\n\n        /// <summary>\n        /// The unique identifier of the settlement this capture was settled with, for example: stl_jDk30akdN\n        /// </summary>\n        public required string SettlementId { get; set; }\n\n        /// <summary>\n        /// The capture’s date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon payment creation. Metadata can be used to link an order to a payment.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon capture creation. Metadata can for example be used to link an bookkeeping ID to a capture.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required CaptureResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Capture/Response/CaptureResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Shipment.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Capture.Response {\n    public record CaptureResponseLinks {\n        /// <summary>\n        /// The API resource URL of the capture itself.\n        /// </summary>\n        public required UrlObjectLink<CaptureResponse> Self { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the payment the capture belongs to.\n        /// </summary>\n        public required UrlObjectLink<PaymentResponse> Payment { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the shipment that triggered the capture to be created.\n        /// </summary>\n        public required UrlObjectLink<ShipmentResponse> Shipment { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the settlement this capture has been settled with. Not present if not yet settled.\n        /// </summary>\n        public required UrlObjectLink<SettlementResponse> Settlement { get; set; }\n\n        /// <summary>\n        /// The URL to the order retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Chargeback/Response/ChargebackResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Chargeback.Response {\n    public record ChargebackResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a chargeback object. Will always contain the string chargeback for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n\t\t/// <summary>\n\t\t/// The chargeback's unique identifier, for example chb_n9z0tp.\n\t\t/// </summary>\n\t\tpublic required string Id { get; set; }\n\n        /// <summary>\n        /// The amount charged back.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// This optional field will contain the amount that will be deducted from your account, converted to the currency\n        /// your account is settled in. It follows the same syntax as the amount property.\n        /// </summary>\n        public Amount? SettlementAmount { get; set; }\n\n        /// <summary>\n        /// The date and time the chargeback was issued, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// The date and time the chargeback was reversed, in ISO 8601 format.\n        /// </summary>\n        public DateTime? ReversedAt { get; set; }\n\n        /// <summary>\n        /// The id of the payment this chargeback belongs to.\n        /// </summary>\n\t\tpublic required string PaymentId { get; set; }\n\n\t\t/// <summary>\n        /// The reason given for a Chargeback, this can help determine the cost for the chargeback\n        /// </summary>\n        public ChargebackResponseReason? Reason { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the chargeback. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required ChargebackResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Chargeback/Response/ChargebackResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Chargeback.Response {\n    public record ChargebackResponseLinks {\n        /// <summary>\n        /// The API resource URL of the chargeback itself.\n        /// </summary>\n        public required UrlObjectLink<ChargebackResponse> Self { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the payment this chargeback belongs to.\n        /// </summary>\n        public required UrlObjectLink<PaymentResponse> Payment { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the settlement this payment has been settled with. Not present if not yet settled.\n        /// </summary>\n        public UrlObjectLink<SettlementResponse>? Settlement { get; set; }\n\n        /// <summary>\n        /// The URL to the chargeback retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Chargeback/Response/ChargebackResponseReason.cs",
    "content": "namespace Mollie.Api.Models.Chargeback.Response {\n    public record ChargebackResponseReason {\n        /// <summary>\n        /// The reason for the chargeback, these are documented here on Mollie's website https://help.mollie.com/hc/en-us/articles/115000309865-Why-did-my-direct-debit-payment-fail-\n        /// </summary>\n        public required string Code { get; set; }\n        /// <summary>\n        /// an accompanying note to the code\n        /// </summary>\n        public required string Description { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Client/Response/ClientCommissionResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Client.Response {\n    public record ClientCommissionResponse {\n        /// <summary>\n        /// The commission count.\n        /// </summary>\n        public int Count { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Client/Response/ClientEmbeddedResponse.cs",
    "content": "using Mollie.Api.Models.Capability.Response;\nusing Mollie.Api.Models.Onboarding.Response;\nusing Mollie.Api.Models.Organization;\n\nnamespace Mollie.Api.Models.Client.Response {\n    public record ClientEmbeddedResponse {\n\n        public OrganizationResponse? Organization { get; set; }\n\n        public OnboardingStatusResponse? Onboarding { get; set; }\n\n        public CapabilityResponse? Capabilities { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Client/Response/ClientResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Client.Response {\n    public record ClientResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a client object. Will always contain the string client for this resource type.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The identifier uniquely referring to this client. Example: org_12345678.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The commission object.\n        /// </summary>\n        public ClientCommissionResponse? Commission { get; set; }\n\n        /// <summary>\n        /// The date and time the client organization was created.\n        /// </summary>\n        public required DateTime OrganizationCreatedAt { get; set; }\n\n        [JsonPropertyName(\"_embedded\")]\n        public ClientEmbeddedResponse? Embedded { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the order line. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required ClientResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Client/Response/ClientResponseLinks.cs",
    "content": "using Mollie.Api.Models.Onboarding.Response;\nusing Mollie.Api.Models.Organization;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Client.Response {\n    public record ClientResponseLinks {\n        /// <summary>\n        /// The API resource URL of the client itself.\n        /// </summary>\n        public required UrlObjectLink<ClientResponse> Self { get; set; }\n\n        /// <summary>\n        /// A link pointing to the product page in your web shop of the product sold.\n        /// </summary>\n        public required UrlObjectLink<OrganizationResponse> Organization { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the client's onboarding status.\n        /// </summary>\n        public required UrlObjectLink<OnboardingStatusResponse> Onboarding { get; set; }\n\n        /// <summary>\n        /// The URL to the client retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/ClientLink/Request/ClientLinkOwner.cs",
    "content": "﻿namespace Mollie.Api.Models.ClientLink.Request\n{\n    public record ClientLinkOwner\n    {\n        /// <summary>\n        /// The email address of your customer.\n        /// </summary>\n        public required string Email { get; set; }\n\n        /// <summary>\n        /// The given name (first name) of your customer.\n        /// </summary>\n        public required string GivenName { get; set; }\n\n        /// <summary>\n        /// The family name (surname) of your customer.\n        /// </summary>\n        public required string FamilyName { get; set; }\n\n        /// <summary>\n        /// Allows you to preset the language to be used in the login / authorize flow. When this parameter is\n        /// omitted, the browser language will be used instead. You can provide any xx_XX format ISO 15897 locale,\n        /// but the authorize flow currently only supports the following languages:\n        /// en_US nl_NL nl_BE fr_FR fr_BE de_DE es_ES it_IT\n        /// </summary>\n        public string? Locale { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/ClientLink/Request/ClientLinkRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.ClientLink.Request\n{\n    public record ClientLinkRequest\n    {\n        /// <summary>\n        /// Personal data of your customer which is required for this endpoint.\n        /// </summary>\n        public required ClientLinkOwner Owner { get; set; }\n\n        /// <summary>\n        /// Name of the organization.\n        /// </summary>\n        public required string Name { get; set; }\n\n        /// <summary>\n        /// Address of the organization. Note that the country parameter\n        /// must always be provided.\n        /// </summary>\n        public required AddressObject Address { get; set; }\n\n        /// <summary>\n        /// The Chamber of Commerce (or local equivalent) registration number\n        /// of the organization.\n        /// </summary>\n        public string? RegistrationNumber { get; set; }\n\n        /// <summary>\n        /// The VAT number of the organization, if based in the European Union\n        /// or the United Kingdom.\n        /// </summary>\n        public string? VatNumber { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/ClientLink/Response/ClientLinkResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.ClientLink.Response {\n    public record ClientLinkResponse : IEntity {\n        public required string Id { get; set; }\n\n        public required string Resource { get; set; }\n\n        [JsonPropertyName(\"_links\")]\n        public required ClientLinkResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/ClientLink/Response/ClientLinkResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.ClientLink.Response {\n    public record ClientLinkResponseLinks {\n        public required UrlLink ClientLink { get; set; }\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/CompanyEntityType.cs",
    "content": "﻿namespace Mollie.Api.Models {\n    public static class CompanyEntityType {\n        public const string LimitedCompany = \"limited-company\";\n        public const string PublicLimitedCompany = \"public-limited-company\";\n        public const string EntrepreneurialCompany = \"entrepreneurial-company\";\n        public const string LimitedPartnershipLimitedCompany = \"limited-partnership-limited-company\";\n        public const string LimitedPartnership = \"limited-partnership\";\n        public const string GeneralPartnership = \"general-partnership\";\n        public const string RegisteredSoleTrader = \"registered-sole-trader\";\n        public const string SoleTrader = \"sole-trader\";\n        public const string CivilLawPartnership = \"civil-law-partnership\";\n        public const string PublicInstitution = \"public-institution\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/CompanyObject.cs",
    "content": "﻿namespace Mollie.Api.Models {\n    public record CompanyObject {\n        /// <summary>\n        /// Organization’s registration number.\n        /// </summary>\n        public string? RegistrationNumber { get; set; }\n        \n        /// <summary>\n        /// Organization’s VAT number.\n        /// </summary>\n        public string? VatNumber { get; set; }\n        \n        /// <summary>\n        /// Organization’s entity type.\n        /// The Mollie.Api.Models.CompanyEntityType class contains a full list of possible values\n        /// </summary>\n        public string? EntityType { get; set; }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Connect/Request/AppPermissions.cs",
    "content": "namespace Mollie.Api.Models.Connect.Request {\n    public static class AppPermissions {\n        public const string BalancesRead = \"balances.read\";\n        public const string BalancesTransfersRead = \"balance-transfers.read\";\n        public const string BalancesTransfersWrite = \"balance-transfers.write\";\n        public const string CustomersRead = \"customers.read\";\n        public const string CustomersWrite = \"customers.write\";\n        public const string ExternalAccountsRead = \"external-accounts.read\";\n        public const string ExternalAccountsWrite = \"external-accounts.write\";\n        public const string InvoicesRead = \"invoices.read\";\n        public const string MandatesRead = \"mandates.read\";\n        public const string MandatesWrite = \"mandates.write\";\n        public const string OnboardingRead = \"onboarding.read\";\n        public const string OnboardingWrite = \"onboarding.write\";\n        public const string OrdersRead = \"orders.read\";\n        public const string OrdersWrite = \"orders.write\";\n        public const string OrganizationRead = \"organizations.read\";\n        public const string OrganizationWrite = \"organizations.write\";\n        public const string PaymentLinksRead = \"payment-links.read\";\n        public const string PaymentLinksWrite = \"payment-links.write\";\n        public const string PaymentsRead = \"payments.read\";\n        public const string PaymentsWrite = \"payments.write\";\n        public const string PersonsRead = \"persons.read\";\n        public const string PersonsWrite = \"persons.write\";\n        public const string ProfilesRead = \"profiles.read\";\n        public const string ProfilesWrite = \"profiles.write\";\n        public const string RefundsRead = \"refunds.read\";\n        public const string RefundsWrite = \"refunds.write\";\n        public const string SettlementsRead = \"settlements.read\";\n        public const string ShipmentsRead = \"shipments.read\";\n        public const string ShipmentsWrite = \"shipments.write\";\n        public const string SubscriptionsRead = \"subscriptions.read\";\n        public const string SubscriptionsWrite = \"subscriptions.write\";\n        public const string TerminalsRead = \"terminals.read\";\n        public const string TerminalsWrite = \"terminals.write\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Connect/Request/RevokeTokenRequest.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Connect.Request {\n    public record RevokeTokenRequest {\n        /// <summary>\n        /// Type of the token you want to revoke.\n        /// </summary>\n        [JsonPropertyName(\"token_type_hint\")]\n        public required string TokenTypeHint { get; set; }\n\n        /// <summary>\n        /// The token you want to revoke\n        /// </summary>\n        public required string Token { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Connect/Request/TokenRequest.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Connect.Request {\n    public record TokenRequest {\n        /// <param name=\"code\">This can be an authorization code or a refresh token. The correct grant type will be automatically selected</param>\n        /// <param name=\"redirectUri\">The URL the merchant is sent back to once the request has been authorized. It must match the URL you set when registering your app. </param>\n        public TokenRequest(string code, string redirectUri) {\n            if (code.StartsWith(\"refresh_\")) {\n                GrantType = \"refresh_token\";\n                RefreshToken = code;\n            }\n            else {\n                GrantType = \"authorization_code\";\n                Code = code;\n            }\n            RedirectUri = redirectUri;\n        }\n\n        /// <summary>\n        ///     If you wish to exchange your auth code for an access token, use grant type authorization_code. If you wish to renew\n        ///     your access token with your refresh token, use grant type refresh_token.\n        ///     Possible values: authorization_code refresh_token\n        /// </summary>\n        [JsonPropertyName(\"grant_type\")]\n        public string GrantType { get; }\n\n        /// <summary>\n        ///     Optional – The auth code you've received when creating the authorization. Only use this field when using grant type\n        ///     authorization_code.\n        /// </summary>\n        public string? Code { get; set; }\n\n        /// <summary>\n        ///     Optional – The refresh token you've received when creating the authorization. Only use this field when using grant\n        ///     type refresh_token.\n        /// </summary>\n        [JsonPropertyName(\"refresh_token\")]\n        public string? RefreshToken { get; set; }\n\n        /// <summary>\n        ///     The URL the merchant is sent back to once the request has been authorized. It must match the URL you set when\n        ///     registering your app.\n        /// </summary>\n        [JsonPropertyName(\"redirect_uri\")]\n        public string? RedirectUri { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Connect/Request/TokenType.cs",
    "content": "﻿namespace Mollie.Api.Models.Connect.Request {\n    public static class TokenType {\n        public const string AccessToken = \"access_token\";\n        public const string RefreshToken = \"refresh_token\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Connect/Response/TokenResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Connect.Response {\n    public record TokenResponse {\n        /// <summary>\n        ///     The access token, with which you will be able to access the Mollie API on the merchant's behalf.\n        /// </summary>\n        [JsonPropertyName(\"access_token\")]\n        public required string AccessToken { get; set; }\n\n        /// <summary>\n        ///     The refresh token, with which you will be able to retrieve new access tokens on this endpoint. Please note that the\n        ///     refresh token does not expire.\n        /// </summary>\n        [JsonPropertyName(\"refresh_token\")]\n        public required string RefreshToken { get; set; }\n\n        /// <summary>\n        ///     The number of seconds left before the access token expires. Be sure to renew your access token before this reaches\n        ///     zero.\n        /// </summary>\n        [JsonPropertyName(\"expires_in\")]\n        public required int ExpiresIn { get; set; }\n\n        /// <summary>\n        ///     As per OAuth standards, the provided access token can only be used with bearer authentication.\n        ///     Possible values: bearer\n        /// </summary>\n        [JsonPropertyName(\"token_type\")]\n        public required string TokenType { get; set; }\n\n        /// <summary>\n        ///     A space separated list of permissions. Please refer to OAuth: Permissions for the full permission list.\n        /// </summary>\n        public required string Scope { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Currency.cs",
    "content": "﻿namespace Mollie.Api.Models {\n    public static class Currency {\n        public const string AUD = nameof(AUD);\n        public const string BGN = nameof(BGN);\n        public const string CAD = nameof(CAD);\n        public const string HRK = nameof(HRK);\n        public const string CZK = nameof(CZK);\n        public const string DKK = nameof(DKK);\n        public const string HKD = nameof(HKD);\n        public const string HUF = nameof(HUF);\n        public const string ISK = nameof(ISK);\n        public const string ILS = nameof(ILS);\n        public const string JPY = nameof(JPY);\n        public const string NOK = nameof(NOK);\n        public const string PLN = nameof(PLN);\n        public const string GBP = nameof(GBP);\n        public const string RON = nameof(RON);\n        public const string SEK = nameof(SEK);\n        public const string CHF = nameof(CHF);\n        public const string USD = nameof(USD);\n        public const string EUR = nameof(EUR);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Customer/Request/CustomerRequest.cs",
    "content": "﻿using System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Customer.Request {\n    public record CustomerRequest : ITestModeRequest {\n        /// <summary>\n        /// The full name of the customer.\n        /// </summary>\n        public string? Name { get; set; }\n\n        /// <summary>\n        /// The email address of the customer.\n        /// </summary>\n        public string? Email { get; set; }\n\n        /// <summary>\n        /// Allows you to preset the language to be used in the payment screens shown to the consumer. When this parameter is not\n        /// provided, the browser language will be used instead in the payment flow (which is usually more accurate).\n        /// </summary>\n        public string? Locale { get; set; }\n\n        /// <summary>\n        /// Optional - Provide any data you like in JSON notation, and we will save the data alongside the customer. Whenever\n        /// you fetch the customer with our API, we'll also include the metadata. You can use up to 1kB of JSON.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this customer a test customer.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Customer/Response/CustomerResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Customer.Response {\n    public record CustomerResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a customer object. Will always contain customer for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The customer's unique identifier, for example cst_4pmbK7CqtT.\n        /// Store this identifier for later recurring payments.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The mode used to create this payment. Mode determines whether a payment is real or a test payment.\n        /// </summary>\n        public Mode Mode { get; set; }\n\n        /// <summary>\n        /// Name of your customer.\n        /// </summary>\n        public string? Name { get; set; }\n\n        /// <summary>\n        /// E-mailaddress of your customer.\n        /// </summary>\n        public string? Email { get; set; }\n\n        /// <summary>\n        /// Allows you to preset the language to be used in the payment screens shown to the consumer. If this parameter was not\n        /// provided when the customer was created, the browser language will be used instead in the payment flow (which is usually\n        /// more accurate).\n        /// </summary>\n        public string? Locale { get; set; }\n\n        /// <summary>\n        /// Optional metadata. Use this if you want Mollie to store additional info.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// DateTime when user was created.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the customer. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required CustomerResponseLinks Links { get; set; }\n\n        public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n            return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Customer/Response/CustomerResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Subscription.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Customer.Response {\n    public record CustomerResponseLinks {\n        /// <summary>\n        /// The API resource URL of the customer itself.\n        /// </summary>\n        public required UrlObjectLink<CustomerResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL of the customer's dashboard in the Mollie administration panel.\n        /// </summary>\n        public required UrlLink Dashboard { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the subscriptions belonging to the Customer, if there are no subscriptions this parameter is omitted.\n        /// </summary>\n        public UrlObjectLink<ListResponse<SubscriptionResponse>>? Subscriptions { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the payments belonging to the Customer, if there are no payments this parameter is omitted.\n        /// </summary>\n        public UrlObjectLink<ListResponse<PaymentResponse>>? Payments { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the mandates belonging to the Customer, if there are no mandates this parameter is omitted.\n        /// </summary>\n        public UrlObjectLink<ListResponse<MandateResponse>>? Mandates { get; set; }\n\n        /// <summary>\n        /// The URL to the customer retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Error/MollieErrorMessage.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Error {\n    public record MollieErrorMessage {\n        public int Status { get; set; }\n        public required string Title { get; set; }\n        public required string Detail { get; set; }\n\n        /// <summary>\n        /// The errors that are returned by the Connect client have a different format for some reason\n        /// In order to use the same object, we just map private properties to the public properties\n        /// that are used by the public api\n        /// </summary>\n        [JsonPropertyName(\"error\")]\n        [JsonInclude]\n        private string Error { init { Title = value; } }\n\n        [JsonPropertyName(\"error_description\")]\n        [JsonInclude]\n        private string ErrorDescription { init { Detail = value; } }\n\n        public override string ToString() {\n            return $\"{Title} - {Detail}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/IEntity.cs",
    "content": "namespace Mollie.Api.Models;\n\npublic interface IEntity {\n    public string Resource { get; set; }\n    public string Id { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/IProfileRequest.cs",
    "content": "﻿namespace Mollie.Api.Models;\n\npublic interface IProfileRequest {\n    string? ProfileId { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/ITestModeRequest.cs",
    "content": "﻿namespace Mollie.Api.Models;\n\npublic interface ITestModeRequest {\n    bool? Testmode { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Invoice/Response/InvoiceLine.cs",
    "content": "﻿namespace Mollie.Api.Models.Invoice.Response {\n\tpublic record InvoiceLine {\n\t\t/// <summary>\n\t\t/// The administrative period (YYYY) on which the line should be booked.\n\t\t/// </summary>\n\t\tpublic required string Period { get; set; }\n\n\t\t/// <summary>\n\t\t/// Description of the product.\n\t\t/// </summary>\n\t\tpublic required string Description { get; set; }\n\n\t\t/// <summary>\n\t\t/// Number of products invoiced (usually number of payments).\n\t\t/// </summary>\n\t\tpublic required int Count { get; set; }\n\n\t\t/// <summary>\n\t\t/// Optional – VAT percentage rate that applies to this product.\n\t\t/// </summary>\n\t\tpublic required decimal VatPercentage { get; set; }\n\n\t\t/// <summary>\n\t\t/// Amount excluding VAT.\n\t\t/// </summary>\n\t\tpublic required Amount Amount { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Invoice/Response/InvoiceResponse.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Invoice.Response {\n\tpublic record InvoiceResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains an invoice object. Will always contain invoice for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n\t\t/// <summary>\n\t\t/// The invoice's unique identifier, for example inv_FrvewDA3Pr.\n\t\t/// </summary>\n\t\tpublic required string Id { get; set; }\n\n\t\t/// <summary>\n\t\t/// The reference number of the invoice. An example value would be: 2016.10000.\n\t\t/// </summary>\n\t\tpublic required string Reference { get; set; }\n\n\t\t/// <summary>\n\t\t/// Optional – The VAT number to which the invoice was issued to (if applicable).\n\t\t/// </summary>\n\t\tpublic string? VatNumber { get; set; }\n\n\t\t/// <summary>\n\t\t/// Status of the invoices - See the Mollie.Api.Models.Invoice.InvoiceStatus class for\n\t\t/// a full list of known values\n\t\t/// </summary>\n\t\tpublic required string Status { get; set; }\n\n\t\t/// <summary>\n\t\t/// The invoice date (in YYYY-MM-DD format).\n\t\t/// </summary>\n\t\tpublic required string IssuedAt { get; set; }\n\n\t\t/// <summary>\n\t\t/// Optional – The date on which the invoice was paid (in YYYY-MM-DD format). Only for paid invoices.\n\t\t/// </summary>\n\t\tpublic string? PaidAt { get; set; }\n\n\t\t/// <summary>\n\t\t/// Optional – The date on which the invoice is due (in YYYY-MM-DD format). Only for due invoices.\n\t\t/// </summary>\n\t\tpublic string? DueAt { get; set; }\n\n        /// <summary>\n        /// Total amount of the invoice excluding VAT, e.g. {\"currency\":Currency.EUR, \"value\":\"100.00\"}.\n        /// </summary>\n        public required Amount NetAmount { get; set; }\n\n        /// <summary>\n        /// VAT amount of the invoice. Only for merchants registered in the Netherlands. For EU merchants, VAT\n        /// will be shifted to recipient; article 44 and 196 EU VAT Directive 2006/112. For merchants outside the\n        /// EU, no VAT will be charged.\n        /// </summary>\n        public required Amount VatAmount { get; set; }\n\n        /// <summary>\n        /// Total amount of the invoice including VAT.\n        /// </summary>\n        public required Amount GrossAmount { get; set; }\n\n        /// <summary>\n        /// The collection of products which make up the invoice.\n        /// </summary>\n        public required List<InvoiceLine> Lines { get; set; }\n\n\t\t/// <summary>\n\t\t/// Useful URLs to related resources.\n\t\t/// </summary>\n\t\t[JsonPropertyName(\"_links\")]\n\t\tpublic required InvoiceResponseLinks Links { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Invoice/Response/InvoiceResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Invoice.Response {\n\tpublic record InvoiceResponseLinks {\n        /// <summary>\n        /// The API resource URL of the invoice itself.\n        /// </summary>\n        public required UrlObjectLink<InvoiceResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL to the PDF version of the invoice. The URL will expire after 60 minutes.\n        /// </summary>\n\t\tpublic UrlLink? Pdf { get; set; }\n\n        /// <summary>\n        /// The URL to the invoice retrieval endpoint documentation.\n        /// </summary>\n\t\tpublic required UrlLink Documentation { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Invoice/Response/InvoiceStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Invoice.Response {\n\tpublic static class InvoiceStatus {\n\t\tpublic const string Open = \"open\";\n\t\tpublic const string Paid = \"paid\";\n\t\tpublic const string Overdue = \"overdue\";\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Issuer/Response/IssuerResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Issuer.Response {\n    public record IssuerResponse : IEntity {\n        /// <summary>\n        /// Contains \"issuer\"\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        ///     The issuer's unique identifier, for example ideal_ABNANL2A. When creating a payment, specify this ID as the issuer\n        ///     parameter to forward\n        ///     the consumer to their banking environment directly.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        ///     The issuer's full name, for example 'ABN AMRO'.\n        /// </summary>\n        public required string Name { get; set; }\n\n        /// <summary>\n        ///     Different Issuer Image icons (iDEAL).\n        /// </summary>\n        public required IssuerResponseImage Image { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Issuer/Response/IssuerResponseImage.cs",
    "content": "﻿namespace Mollie.Api.Models.Issuer.Response {\n\t/// <summary>\n\t/// URLs of images representing the issuer.\n\t/// </summary>\n\tpublic record IssuerResponseImage {\n\t\tpublic required string Size1x { get; set; }\n\t\tpublic required string Size2x { get; set; }\n\t\tpublic required string Svg { get; set; }\n\n\t\tpublic override string ToString() {\n\t\t\treturn Size1x;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/List/Response/ListResponse.cs",
    "content": "﻿using System.Collections.Generic;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.List.Response {\n    public record ListResponse<T> where T : class {\n        public int Count { get; set; }\n\n        [JsonConverter(typeof(ListResponseConverter))]\n        [JsonPropertyName(\"_embedded\")]\n        public required List<T> Items { get; set; }\n\n        [JsonPropertyName(\"_links\")]\n        public required ListResponseLinks<T> Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/List/Response/ListResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.List.Response {\n    /// <summary>\n    /// Links to help navigate through the lists of objects, based on the given offset.\n    /// </summary>\n    public record ListResponseLinks<T> where T : class {\n        /// <summary>\n        /// The URL to the current set of payments.\n        /// </summary>\n        public required UrlObjectLink<ListResponse<T>> Self { get; set; }\n\n        /// <summary>\n        /// The previous set of objects, if available.\n        /// </summary>\n        public UrlObjectLink<ListResponse<T>>? Previous { get; set; }\n\n        /// <summary>\n        /// The next set of objects, if available.\n        /// </summary>\n        public UrlObjectLink<ListResponse<T>>? Next { get; set; }\n\n        /// <summary>\n        /// The URL to the payments list endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Request/MandateRequest.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.Framework;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Mandate.Request {\n    public record MandateRequest : ITestModeRequest {\n        /// <summary>\n        /// Payment method of the mandate - Possible values: `directdebit` `paypal`\n        /// </summary>\n        public required string Method { get; set; }\n\n        /// <summary>\n        /// Required - Name of consumer you add to the mandate\n        /// </summary>\n        public required string ConsumerName { get; set; }\n\n        /// <summary>\n        /// Optional - The date when the mandate was signed.\n        /// </summary>\n        [JsonConverter(typeof(DateJsonConverter))]\n        public DateTime? SignatureDate { get; set; }\n\n        /// <summary>\n        /// Optional - A custom reference\n        /// </summary>\n        public string? MandateReference { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this mandate a test mandate.\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Request/PaymentSpecificParameters/PayPalMandateRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Mandate.Request.PaymentSpecificParameters\n{\n    public record PayPalMandateRequest : MandateRequest\n    {\n        public PayPalMandateRequest() {\n            Method = Payment.PaymentMethod.PayPal;\n        }\n\n        /// <summary>\n        /// Required For Paypal - The consumer's email address.\n        /// </summary>\n        public required string ConsumerEmail { get; set; }\n\n        /// <summary>\n        /// Required for `paypal` mandates - The billing agreement ID given by PayPal.\n        /// </summary>\n        public required string PaypalBillingAgreementId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Request/PaymentSpecificParameters/SepaDirectDebitMandateRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Mandate.Request.PaymentSpecificParameters\n{\n    public record SepaDirectDebitMandateRequest : MandateRequest\n    {\n        public SepaDirectDebitMandateRequest() {\n            Method = Payment.PaymentMethod.DirectDebit;\n        }\n\n        /// <summary>\n        /// Required for `directdebit` mandates - Consumer's IBAN account\n        /// </summary>\n        public required string ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Optional - The consumer's bank's BIC / SWIFT code.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Response/MandateResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Mandate.Response {\n    public record MandateResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a mandate object. Will always contain mandate for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// Unique identifier of you mandate.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// Whether this entity was created in live mode or in test mode.\n        /// </summary>\n        public required Mode Mode { get; set; }\n\n        /// <summary>\n        /// Current status of mandate - See the Mollie.Api.Models.Mandate.MandateStatus class for a full\n        /// list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// Payment method of the mandate - See the Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        public required string Method { get; set; }\n\n        /// <summary>\n        /// The mandate’s custom reference, if this was provided when creating the mandate.\n        /// </summary>\n        public string? MandateReference { get; set; }\n\n        /// <summary>\n        /// The signature date of the mandate in YYYY-MM-DD format.\n        /// </summary>\n        public string? SignatureDate { get; set; }\n\n        /// <summary>\n        /// The identifier referring to the customer this mandate was linked to.\n        /// </summary>\n        public required string CustomerId { get; set; }\n\n        /// <summary>\n        /// DateTime when mandate was created.\n        /// </summary>\n        public DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the mandate. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required MandateResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Response/MandateResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Mandate.Response {\n    public record MandateResponseLinks {\n        /// <summary>\n        /// The API resource URL of the mandate itself.\n        /// </summary>\n        public required UrlObjectLink<MandateResponse> Self { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the customer the mandate is for.\n        /// </summary>\n        public required UrlObjectLink<CustomerResponse> Customer { get; set; }\n\n        /// <summary>\n        /// The URL to the mandate retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Response/MandateStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Mandate.Response {\n    public static class MandateStatus {\n        public const string Valid = \"valid\";\n        public const string Invalid = \"invalid\";\n        public const string Pending = \"pending\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Response/PaymentSpecificParameters/CreditCardMandateResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Mandate.Response.PaymentSpecificParameters;\n\npublic record CreditCardMandateResponse : MandateResponse {\n    public required CreditCardMandateResponseDetails Details { get; set; }\n}\n\npublic record CreditCardMandateResponseDetails {\n    /// <summary>\n    /// The credit card holder's name.\n    /// </summary>\n    public string? CardHolder { get; set; }\n\n    /// <summary>\n    /// The last four digits of the credit card number.\n    /// </summary>\n    public string? CardNumber { get; set; }\n\n    /// <summary>\n    /// The credit card's label. Note that not all labels can be acquired through Mollie.\n    /// </summary>\n    public string? CardLabel { get; set; }\n\n    /// <summary>\n    /// Unique alphanumeric representation of credit card, usable for identifying returning customers.\n    /// </summary>\n    public string? CardFingerprint { get; set; }\n\n    /// <summary>\n    /// Expiry date of the credit card card in YYYY-MM-DD format.\n    /// </summary>\n    public string? CardExpiryDate { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Response/PaymentSpecificParameters/PayPalMandateResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Mandate.Response.PaymentSpecificParameters;\n\npublic record PayPalMandateResponse : MandateResponse {\n    public required PayPalMandateResponseDetails Details { get; set; }\n}\n\npublic record PayPalMandateResponseDetails {\n    /// <summary>\n    /// Only available if the payment has been completed – The consumer's name.\n    /// </summary>\n    public string? ConsumerName { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed – The consumer's IBAN.\n    /// </summary>\n    public string? ConsumerAccount { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mandate/Response/PaymentSpecificParameters/SepaDirectDebitMandateResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Mandate.Response.PaymentSpecificParameters;\n\npublic record SepaDirectDebitMandateResponse : MandateResponse {\n    public required SepaDirectDebitMandateResponseDetails Details { get; set; }\n}\n\npublic record SepaDirectDebitMandateResponseDetails {\n    /// <summary>\n    /// Only available if the payment has been completed – The consumer's name.\n    /// </summary>\n    public string? ConsumerName { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed – The consumer's IBAN.\n    /// </summary>\n    public string? ConsumerAccount { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed – The consumer's bank's BIC.\n    /// </summary>\n    public string? ConsumerBic { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Mode.cs",
    "content": "﻿using System.Runtime.Serialization;\n\nnamespace Mollie.Api.Models {\n    public enum Mode {\n        [EnumMember(Value = \"live\")] Live,\n        [EnumMember(Value = \"test\")] Test\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Onboarding/Request/OnboardingOrganizationRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Onboarding.Request {\n    /// <summary>\n    /// Data of the organization you want to provide.\n    /// </summary>\n    public record OnboardingOrganizationRequest {\n        /// <summary>\n        /// Name of the organization.\n        /// </summary>\n        public string? Name { get; set; }\n\n        /// <summary>\n        /// Address of the organization.\n        /// </summary>\n        public AddressObject? Address { get; set; }\n        \n        /// <summary>\n        /// The Chamber of Commerce (or local equivalent) registration number of the organization.\n        /// </summary>\n        public string? RegistrationNumber { get; set; }\n        \n        /// <summary>\n        /// The VAT number of the organization, if based in the European Union or the United Kingdom.\n        /// </summary>\n        public string? VatNumber { get; set; }\n        \n        /// <summary>\n        /// The organization’s VAT regulation, if based in the European Union. Either shifted (VAT is shifted)\n        /// or dutch (Dutch VAT rate) is accepted.\n        /// </summary>\n        public string? VatRegulation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Onboarding/Request/OnboardingProfileRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Onboarding.Request {\n    /// <summary>\n    /// Data of the payment profile you want to provide.\n    /// </summary>\n    public record OnboardingProfileRequest {\n        /// <summary>\n        /// The profile’s name should reflect the tradename or brand name of the profile’s website or application.\n        /// </summary>\n        public string? Name { get; set; }\n\n        /// <summary>\n        /// The URL to the profile’s website or application. The URL must be compliant to RFC3986 with the exception\n        /// that we only accept URLs with http:// or https:// schemes and domains that contain a TLD. URLs containing \n        /// an @ are not allowed.\n        /// </summary>\n        public string? Url { get; set; }\n\n        /// <summary>\n        /// The email address associated with the profile’s tradename or brand.\n        /// </summary>\n        public string? Email { get; set; }\n\n        /// <summary>\n        /// A description of what kind of goods and/or products will be offered via the payment profile.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The phone number associated with the profile’s trade name or brand. Must be in the E.164 format. For example \n        /// +31208202070.\n        /// </summary>\n        public string? Phone { get; set; }\n\n        /// <summary>\n        /// The industry associated with the profile’s trade name or brand. Please refer to the documentation of the business category\n        /// for more information on which values are accepted.\n        /// </summary>\n        public string? BusinessCategory { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Onboarding/Request/SubmitOnboardingDataRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Onboarding.Request {\n    public record SubmitOnboardingDataRequest {\n        /// <summary>\n        /// Data of the organization you want to provide.\n        /// </summary>\n        public OnboardingOrganizationRequest? Organization { get; set; }\n\n        /// <summary>\n        /// Data of the payment profile you want to provide.\n        /// </summary>\n        public OnboardingProfileRequest? Profile { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Onboarding/Response/OnboardingStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Onboarding.Response {\n    /// <summary>\n    /// The current status of the organization’s onboarding process\n    /// </summary>\n    public static class OnboardingStatus {\n        /// <summary>\n        /// The onboarding is not completed and the merchant needs to provide (more) information\n        /// </summary>\n        public const string NeedsData = \"needs-data\";\n\n        /// <summary>\n        /// The merchant provided all information and Mollie needs to check this\n        /// </summary>\n        public const string InReview = \"in-review\";\n\n        /// <summary>\n        /// The onboarding is completed\n        /// </summary>\n        public const string Completed = \"completed\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Onboarding/Response/OnboardingStatusResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\nusing System;\n\nnamespace Mollie.Api.Models.Onboarding.Response {\n    public record OnboardingStatusResponse {\n        /// <summary>\n        /// Indicates the response contains an onboarding object. Will always contain onboarding for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The name of the organization.\n        /// </summary>\n        public string? Name { get; set; }\n\n        /// <summary>\n        /// The sign up date and time of the organization.\n        /// </summary>\n        public DateTime SignedUpAt { get; set; }\n\n        /// <summary>\n        /// The current status of the organization’s onboarding process. See the Mollie.Api.Models.Onboarding.Response.OnboardingStatus\n        /// class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// Whether or not the organization can receive payments.\n        /// </summary>\n        public bool CanReceivePayments { get; set; }\n\n        /// <summary>\n        /// Whether or not the organization can receive settlements.\n        /// </summary>\n        public bool CanReceiveSettlements { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the organization. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required OnboardingStatusResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Onboarding/Response/OnboardingStatusResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Organization;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Onboarding.Response {\n    /// <summary>\n    /// An object with several URL objects relevant to the onboarding status. Every URL object will contain an href and a type field.\n    /// </summary>\n    public record OnboardingStatusResponseLinks {\n        /// <summary>\n        /// The API resource URL of this endpoint itself.\n        /// </summary>\n        public required UrlLink Self { get; set; }\n\n        /// <summary>\n        /// The URL of the onboarding process in Mollie Dashboard. You can redirect your customer to here for e.g. completing the onboarding process.\n        /// </summary>\n        public required UrlLink Dashboard { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the organization.\n        /// </summary>\n        public UrlObjectLink<OrganizationResponse>? Organization { get; set; }\n\n        /// <summary>\n        /// The URL to the onboarding status retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/OrderAddressDetails.cs",
    "content": "﻿namespace Mollie.Api.Models.Order {\n    public record OrderAddressDetails : AddressObject {\n        /// <summary>\n        /// The person’s organization, if applicable.\n        /// </summary>\n        public string? OrganizationName { get; set; }\n\n        /// <summary>\n        /// The title of the person, for example Mr. or Mrs..\n        /// </summary>\n        public string? Title { get; set; }\n\n        /// <summary>\n        /// The given name (first name) of the person.\n        /// </summary>\n        public string? GivenName { get; set; }\n\n        /// <summary>\n        /// The family name (surname) of the person.\n        /// </summary>\n        public string? FamilyName { get; set; }\n\n        /// <summary>\n        /// The email address of the person.\n        /// </summary>\n        public string? Email { get; set; }\n\n        /// <summary>\n        /// The phone number of the person. Some payment methods require this information. If you have it, you\n        /// should pass it so that your customer does not have to enter it again in the checkout. Must be in\n        /// the E.164 format. For example +31208202070.\n        /// </summary>\n        public string? Phone { get; set; }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManageOrderLinesAddOperation.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public record ManageOrderLinesAddOperation : ManageOrderLinesOperation {\n        public required ManageOrderLinesAddOperationData Data { get; set; }\n\n        public ManageOrderLinesAddOperation() {\n            Operation = OrderLineOperation.Add;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManageOrderLinesAddOperationData.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public record ManageOrderLinesAddOperationData : OrderLineRequest;\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManageOrderLinesCancelOperation.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public record ManageOrderLinesCancelOperation : ManageOrderLinesOperation {\n        public required ManagerOrderLinesCancelOperationData Data { get; set; }\n\n        public ManageOrderLinesCancelOperation() {\n            Operation = OrderLineOperation.Cancel;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManageOrderLinesOperation.cs",
    "content": "using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    [JsonPolymorphic(TypeDiscriminatorPropertyName = \"operation\")]\n    [JsonDerivedType(typeof(ManageOrderLinesAddOperation), OrderLineOperation.Add)]\n    [JsonDerivedType(typeof(ManageOrderLinesCancelOperation), OrderLineOperation.Cancel)]\n    [JsonDerivedType(typeof(ManageOrderLinesUpdateOperation), OrderLineOperation.Update)]\n    public abstract record ManageOrderLinesOperation {\n        /// <summary>\n        /// Operation type. Either `add`, `update`, or `cancel`.\n        /// </summary>\n        [JsonIgnore]\n        public string Operation { get; protected set; } = string.Empty;\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManageOrderLinesRequest.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public record ManageOrderLinesRequest : ITestModeRequest {\n        /// <summary>\n        /// List of operations to be processed.\n        /// </summary>\n        public required IList<ManageOrderLinesOperation> Operations { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManageOrderLinesUpdateOperation.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public record ManageOrderLinesUpdateOperation : ManageOrderLinesOperation {\n        public required ManageOrderLinesUpdateOperationData Data { get; set; }\n\n        public ManageOrderLinesUpdateOperation() {\n            Operation = OrderLineOperation.Update;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManageOrderLinesUpdateOperationData.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public record ManageOrderLinesUpdateOperationData : OrderLineUpdateRequest {\n        public required string Id { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/ManagerOrderLinesCancelOperationData.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public record ManagerOrderLinesCancelOperationData : OrderLineDetails;\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/ManageOrderLines/OrderLineOperation.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.ManageOrderLines {\n    public static class OrderLineOperation {\n        public const string Add = \"add\";\n        public const string Update = \"update\";\n        public const string Cancel = \"cancel\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderLineCancellationRequest.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Order.Request {\n    public record OrderLineCancellationRequest : ITestModeRequest {\n        public required IEnumerable<OrderLineDetails> Lines { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderLineDetails.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request {\n    public record OrderLineDetails {\n        public required string Id { get; set; }\n        public int? Quantity { get; set; }\n        public Amount? Amount { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderLineDetailsType.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request {\n    public static class OrderLineDetailsType {\n        public const string Physical = \"physical\";\n        public const string Discount = \"discount\";\n        public const string Digital = \"digital\";\n        public const string ShippingFee = \"shipping_fee\";\n        public const string StoreCredit = \"gift_card\";\n        public const string GiftCard = \"gift_card\";\n        public const string Surcharge = \"surcharge\";\n        public const string Tip = \"tip\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderLineRequest.cs",
    "content": "﻿using Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Order.Request {\n    public record OrderLineRequest {\n        /// <summary>\n        /// The type of product bought, for example, a physical or a digital product. See the\n        /// Mollie.Api.Models.Order.OrderLineDetailsType class for a full list of known values.\n        /// </summary>\n        public string? Type { get; set; }\n\n        /// <summary>\n        /// The category of product bought. See the Mollie.Api.Models.Order.OrderLineDetailsCategory class\n        /// for a full list of known values\n        /// </summary>\n        public string? Category { get; set; }\n\n        /// <summary>\n        /// A description of the order line, for example LEGO 4440 Forest Police Station.\n        /// </summary>\n        public required string Name { get; set; }\n\n        /// <summary>\n        /// The number of items in the order line.\n        /// </summary>\n        public required int Quantity { get; set; }\n\n        /// <summary>\n        /// The price of a single item in the order line.\n        /// </summary>\n        public required Amount UnitPrice { get; set; }\n\n        /// <summary>\n        /// Any discounts applied to the order line. For example, if you have a two-for-one sale, you should pass the\n        /// amount discounted as a positive amount.\n        /// </summary>\n        public Amount? DiscountAmount { get; set; }\n\n        /// <summary>\n        /// The total amount of the line, including VAT and discounts. Adding all totalAmount values together should\n        /// result in the same amount as the amount top level property.\n        /// </summary>\n        public required Amount TotalAmount { get; set; }\n\n        /// <summary>\n        /// The VAT rate applied to the order line, for example \"21.00\" for 21%. The vatRate should be passed as a\n        /// string and not as a float to ensure the correct number of decimals are passed.\n        /// </summary>\n        public required string VatRate { get; set; }\n\n        /// <summary>\n        /// The amount of value-added tax on the line. The totalAmount field includes VAT, so the vatAmount can be\n        /// calculated with the formula totalAmount × (vatRate / (100 + vatRate)). Any deviations from this will\n        /// result in an error.\n        /// </summary>\n        public required Amount VatAmount { get; set; }\n\n        /// <summary>\n        /// The SKU, EAN, ISBN or UPC of the product sold. The maximum character length is 64.\n        /// </summary>\n        public string? Sku { get; set; }\n\n        /// <summary>\n        /// A link pointing to an image of the product sold.\n        /// </summary>\n        public string? ImageUrl { get; set; }\n\n        /// <summary>\n        /// A link pointing to the product page in your web shop of the product sold.\n        /// </summary>\n        public string? ProductUrl { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon line creation.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderLineUpdateRequest.cs",
    "content": "﻿using System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Order.Request {\n    public record OrderLineUpdateRequest : ITestModeRequest {\n        /// <summary>\n        /// A description of the order line, for example LEGO 4440 Forest Police Station.\n        /// </summary>\n        public string? Name { get; set; }\n\n        /// <summary>\n        /// A link pointing to an image of the product sold.\n        /// </summary>\n        public string? ImageUrl { get; set; }\n\n        /// <summary>\n        /// A link pointing to the product page in your web shop of the product sold.\n        /// </summary>\n        public string? ProductUrl { get; set; }\n\n        /// <summary>\n        /// The SKU, EAN, ISBN or UPC of the product sold. The maximum character length is 64.\n        /// </summary>\n        public string? Sku { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, for example a string or a JSON object. We will\n        /// save the data alongside the order line. Whenever you fetch the order with our API,\n        /// we'll also include the metadata. You can use up to approximately 1kB.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// The number of items in the order line.\n        /// </summary>\n        public int? Quantity { get; set; }\n\n        /// <summary>\n        /// The price of a single item including VAT in the order line.\n        /// </summary>\n        public Amount? UnitPrice { get; set; }\n\n        /// <summary>\n        /// Any discounts applied to the order line. For example, if you have a two-for-one sale, you should pass the\n        /// amount discounted as a positive amount.\n        /// </summary>\n        public Amount? DiscountAmount { get; set; }\n\n        /// <summary>\n        /// The total amount of the line, including VAT and discounts. Adding all totalAmount values together should\n        /// result in the same amount as the amount top level property.\n        /// </summary>\n        public Amount? TotalAmount { get; set; }\n\n        /// <summary>\n        /// The amount of value-added tax on the line. The totalAmount field includes VAT, so the vatAmount can be\n        /// calculated with the formula totalAmount × (vatRate / (100 + vatRate)).\n        /// </summary>\n        public Amount? VatAmount { get; set; }\n\n        /// <summary>\n        /// The VAT rate applied to the order line, for example \"21.00\" for 21%. The vatRate should be passed as a\n        /// string and not as a float to ensure the correct number of decimals are passed.\n        /// </summary>\n        public string? VatRate { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderPaymentRequest.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Order.Request {\n    public record OrderPaymentRequest : ITestModeRequest {\n        /// <summary>\n        /// Normally, a payment method selection screen is shown. However, when using this parameter, your customer will skip the\n        /// selection screen and will be sent directly to the chosen payment method. The parameter enables you to fully integrate\n        /// the payment method selection into your website, however note Mollie’s country based conversion optimization is lost.\n        /// See the Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        [JsonIgnore]\n        public string? Method {\n            get => Methods?.FirstOrDefault();\n            set {\n                if (value == null) {\n                    Methods = null;\n                }\n                else {\n                    Methods = new List<string>();\n                    Methods.Add(value);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Normally, a payment method screen is shown. However, when using this parameter, you can choose a specific payment method\n        /// and your customer will skip the selection screen and is sent directly to the chosen payment method. The parameter\n        /// enables you to fully integrate the payment method selection into your website.\n        /// You can also specify the methods in an array.By doing so we will still show the payment method selection screen but will\n        /// only show the methods specified in the array. For example, you can use this functionality to only show payment methods\n        /// from a specific country to your customer.\n        /// </summary>\n        [JsonPropertyName(\"method\")]\n        public IList<string>? Methods { get; set; }\n\n        /// <summary>\n        /// The ID of the Customer for whom the payment is being created. This is used for recurring payments\n        /// and single click payments.\n        /// </summary>\n        public string? CustomerId { get; set; }\n\n        /// <summary>\n        /// When creating recurring payments, the ID of a specific Mandate may be supplied to indicate which\n        /// of the consumer’s accounts should be credited.\n        /// </summary>\n        public string? MandateId { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this payment a test payment.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Adding an Application Fee allows you to charge the merchant a small sum for the payment and transfer\n        /// this to your own account.\n        /// </summary>\n        public ApplicationFee? ApplicationFee { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderRefundRequest.cs",
    "content": "﻿using System.Collections.Generic;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Order.Request {\n    public record OrderRefundRequest : ITestModeRequest {\n        /// <summary>\n        /// An array of objects containing the order line details you want to create a refund for. If you send\n        /// an empty array, the entire order will be refunded.\n        /// </summary>\n        public required IEnumerable<OrderLineDetails> Lines { get; set; }\n\n        /// <summary>\n        /// The description of the refund you are creating. This will be shown to the consumer on their card or\n        /// bank statement when possible. Max. 140 characters.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon line creation.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.Json;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models.Order.Request.PaymentSpecificParameters;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.Framework;\n\nnamespace Mollie.Api.Models.Order.Request {\n    public record OrderRequest : ITestModeRequest, IProfileRequest {\n        /// <summary>\n        /// The total amount of the order, including VAT and discounts. This is the amount that will be charged\n        /// to your customer.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The order number. For example, 16738. We recommend that each order should have a unique order number.\n        /// </summary>\n        public required string OrderNumber { get; set; }\n\n        /// <summary>\n        /// The lines in the order. Each line contains details such as a description of the item ordered, its\n        /// price et cetera.\n        /// </summary>\n        public required IEnumerable<OrderLineRequest> Lines { get; set; }\n\n        /// <summary>\n        /// The billing person and address for the order.\n        /// </summary>\n        public OrderAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The shipping address for the order. See Order address details for the exact fields needed. If omitted,\n        /// it is assumed to be identical to the billingAddress.\n        /// </summary>\n        public OrderAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// The date of birth of your customer. Some payment methods need this value and if you have it, you should\n        /// send it so that your customer does not have to enter it again later in the checkout process.\n        /// </summary>\n        [JsonConverter(typeof(DateJsonConverter))]\n        public DateTime? ConsumerDateOfBirth { get; set; }\n\n        /// <summary>\n        /// The URL your customer will be redirected to after the payment process.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The URL your consumer will be redirected to when the consumer explicitly cancels the payment. If this URL\n        /// is not provided, the consumer will be redirected to the redirectUrl instead — see above.\n        ///\n        /// Mollie will always give you status updates via webhooks, including for the canceled status. This parameter\n        /// is therefore entirely optional, but can be useful when implementing a dedicated consumer-facing flow to handle\n        /// payment cancellations.\n        ///\n        /// The parameter can be omitted for orders with payment.sequenceType set to recurring.\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        /// <summary>\n        /// Set the webhook URL, where we will send order status changes to.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Allows you to preset the language to be used in the hosted payment pages shown to the consumer.\n        /// </summary>\n        public required string Locale { get; set; }\n\n        /// <summary>\n        /// Normally, a payment method selection screen is shown. However, when using this parameter, your customer\n        /// will skip the selection screen and will be sent directly to the chosen payment method. The parameter enables\n        /// you to fully integrate the payment method selection into your website. See the\n        /// Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        [JsonIgnore]\n        public string? Method {\n            get => Methods?.FirstOrDefault();\n            set {\n                if (value == null) {\n                    Methods = null;\n                }\n                else {\n                    Methods = new List<string>();\n                    Methods.Add(value);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Normally, a payment method screen is shown. However, when using this parameter, you can choose a specific payment method\n        /// and your customer will skip the selection screen and is sent directly to the chosen payment method. The parameter\n        /// enables you to fully integrate the payment method selection into your website.\n        /// You can also specify the methods in an array.By doing so we will still show the payment method selection screen but will\n        /// only show the methods specified in the array. For example, you can use this functionality to only show payment methods\n        /// from a specific country to your customer.\n        /// </summary>\n        [JsonPropertyName(\"method\")]\n        public IList<string>? Methods { get; set; }\n\n        /// <summary>\n        /// Optional - Any payment specific properties can be passed here.\n        /// </summary>\n        public OrderPaymentParameters? Payment { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, and we will save the data alongside the subscription. Whenever you fetch the subscription\n        /// with our API, we’ll also include the metadata. You can use up to 1kB of JSON.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// The date the order should expire in YYYY-MM-DD format. The minimum date is tomorrow and the maximum date is 100 days\n        /// after tomorrow.\n        /// </summary>\n        [JsonConverter(typeof(DateJsonConverter))]\n        public DateTime? ExpiresAt { get; set; }\n\n        /// <summary>\n        /// For digital goods, you must make sure to apply the VAT rate from your customer’s country in most jurisdictions. Use\n        /// this parameter to restrict the payment methods available to your customer to methods from the billing country only.\n        /// </summary>\n        public bool? ShopperCountryMustMatchBillingCountry { get; set; }\n\n        /// <summary>\n        ///\tOauth only - The payment profile's unique identifier, for example pfl_3RkSN1zuPE.\n        /// </summary>\n        public string? ProfileId { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this payment a test payment.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/OrderUpdateRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request {\n    public record OrderUpdateRequest : ITestModeRequest {\n        /// <summary>\n        /// The billing person and address for the order. See Order address details for the\n        /// exact fields needed.\n        /// </summary>\n        public OrderAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The shipping address for the order. See Order address details for the exact\n        /// fields needed.\n        /// </summary>\n        public OrderAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// The order number. For example, 16738. We recommend that each order should have a unique order number.\n        /// </summary>\n        public string? OrderNumber { get; set; }\n\n        /// <summary>\n        /// The URL your customer will be redirected to after the payment process. Updating this field is only possible\n        /// when the payment is not yet finalized.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The URL your consumer will be redirected to when the consumer explicitly cancels the order. If this URL\n        /// is not provided, the consumer will be redirected to the redirectUrl instead — see above. Updating this\n        /// field is only possible when the payment is not yet finalized.\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        /// <summary>\n        /// Set the webhook URL, where we will send order status changes to. The webhookUrl must be reachable from\n        /// Mollie’s point of view, so you cannot use localhost. If you want to use webhook during development on\n        /// localhost, you should use a tool like ngrok to have the webhooks delivered to your local machine.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/ApplePaySpecificParameters.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record ApplePaySpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// Optional - The Apple Pay Payment Token object (encoded as JSON) that is part of the result of authorizing a payment\n        /// request. The token contains the payment information needed to authorize the payment.\n        /// </summary>\n        public string? ApplePayPaymentToken { get; set; }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/BillieSpecificParameters.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record BillieSpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// Billie is a B2B payment method, thus it requires some extra information to identify the business\n        /// that is creating the order. It is recommended to include these parameters as part of the create\n        /// order request for a seamless flow, otherwise the customer will be asked to fill the missing fields\n        /// at the Billie’s checkout page.\n        /// </summary>\n        public CompanyObject? Company { get; set; }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/CreditCardSpecificParameters.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record CreditCardSpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// The card token you get from Mollie Components. The token contains the card information\n        /// (such as card holder, card number and expiry date) needed to complete the payment.\n        /// </summary>\n        public string? CardToken { get; set; }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/GiftcardSpecificParameters.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record GiftcardSpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// The gift card brand to use for the payment. These issuers are not dynamically available through the Issuers API, \n        /// but can be retrieved by using the issuers include in the Methods API. If you need a brand not in the list, contact\n        /// our support department. If only one issuer is activated on your account, you can omit this parameter.\n        /// </summary>\n        public string? Issuer { get; set; }\n\n        /// <summary>\n        /// The card number on the gift card.\n        /// </summary>\n        public string? VoucherNumber { get; set; }\n\n        /// <summary>\n        /// The PIN code on the gift card. Only required if there is a PIN code printed on the gift card.\n        /// </summary>\n        public string? VoucherPin { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/IDealSpecificParameters.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record IDealSpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// Optional - iDEAL issuer id. The id could for example be ideal_INGBNL2A. The returned paymentUrl will then directly\n        /// point to the ING web site.\n        /// </summary>\n        public string? Issuer { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/KbcSpecificParameters.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters { \n    public record KbcSpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// The issuer to use for the KBC/CBC payment. These issuers are not dynamically available through the Issuers API, \n        /// but can be retrieved by using the issuers include in the Methods API. See the Mollie.Api.Models.Payment.Request.KbcIssuer \n        /// class for a full list of known values.\n        /// </summary>\n        public string? Issuer { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/KlarnaSpecificParameters.cs",
    "content": "namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record KlarnaSpecificParameters<T> : OrderPaymentParameters where T : class {\n        public T? ExtraMerchantData { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/OrderPaymentParameters.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record OrderPaymentParameters {\n        public string? CustomerId { get; set; }\n        /// <summary>\n        /// See the Mollie.Api.Models.Payment.SequenceType class for a full list of known values.\n        /// </summary>\n        public string? SequenceType { get; set; }\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Adding an application fee allows you to charge the merchant for the payment and transfer this to your own account.\n        /// </summary>\n        public ApplicationFee? ApplicationFee { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/PaySafeCardSpecificParameters.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record PaySafeCardSpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// Used for consumer identification. For example, you could use the consumer’s IP address.\n        /// </summary>\n        public string? CustomerReference { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Request/PaymentSpecificParameters/SepaDirectDebitSpecificParameters.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Request.PaymentSpecificParameters {\n    public record SepaDirectDebitSpecificParameters : OrderPaymentParameters {\n        /// <summary>\n        /// Optional - IBAN of the account holder.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderEmbeddedResponse.cs",
    "content": "using System.Collections.Generic;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Shipment.Response;\n\nnamespace Mollie.Api.Models.Order.Response {\n\n    public record OrderEmbeddedResponse {\n\n        public IEnumerable<PaymentResponse>? Payments { get; set; }\n\n        public IEnumerable<RefundResponse>? Refunds { get; set; }\n\n        public IEnumerable<ShipmentResponse>? Shipments { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderLineResponse.cs",
    "content": "﻿using System;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Order.Response {\n    public record OrderLineResponse {\n        /// <summary>\n        /// The order line’s unique identifier, for example odl_dgtxyl.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// Indicates the response contains an order line object. Will always contain orderline for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The ID of the order the line belongs too, for example ord_kEn1PlbGa.\n        /// </summary>\n        public required string OrderId { get; set; }\n\n        /// <summary>\n        /// The type of product bought, for example, a physical or a digital product. See the\n        /// Mollie.Api.Models.Order.OrderLineDetailsType class for a full list of known values.\n        /// </summary>\n        public string? Type { get; set; }\n\n        /// <summary>\n        /// A description of the order line, for example LEGO 4440 Forest Police Station.\n        /// </summary>\n        public required string Name { get; set; }\n\n        /// <summary>\n        /// Status of the order line - See the Mollie.Api.Models.Order.OrderLineStatus class for\n        /// a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// Whether or not the order line can be (partially) canceled.\n        /// </summary>\n        public required bool IsCancelable { get; set; }\n\n        /// <summary>\n        /// The number of items in the order line.\n        /// </summary>\n        public required int Quantity { get; set; }\n\n        /// <summary>\n        /// The number of items that are shipped for this order line.\n        /// </summary>\n        public required int QuantityShipped { get; set; }\n\n        /// <summary>\n        /// The total amount that is shipped for this order line.\n        /// </summary>\n        public required Amount AmountShipped { get; set; }\n\n        /// <summary>\n        /// The number of items that are refunded for this order line.\n        /// </summary>\n        public required int QuantityRefunded { get; set; }\n\n        /// <summary>\n        /// The total amount that is refunded for this order line.\n        /// </summary>\n        public required Amount AmountRefunded { get; set; }\n\n        /// <summary>\n        /// The number of items that are canceled in this order line.\n        /// </summary>\n        public required int QuantityCanceled { get; set; }\n\n        /// <summary>\n        /// The total amount that is canceled in this order line.\n        /// </summary>\n        public required Amount AmountCanceled { get; set; }\n\n        /// <summary>\n        /// The number of items that can still be shipped for this order line.\n        /// </summary>\n        public required int ShippableQuantity { get; set; }\n\n        /// <summary>\n        /// The number of items that can still be refunded for this order line.\n        /// </summary>\n        public required int RefundableQuantity { get; set; }\n\n        /// <summary>\n        /// The number of items that can still be canceled for this order line.\n        /// </summary>\n        public required int CancelableQuantity { get; set; }\n\n        /// <summary>\n        /// The price of a single item in the order line.\n        /// </summary>\n        public required Amount UnitPrice { get; set; }\n\n        /// <summary>\n        /// Any discounts applied to the order line. For example, if you have a two-for-one sale, you should pass the\n        /// amount discounted as a positive amount.\n        /// </summary>\n        public Amount? DiscountAmount { get; set; }\n\n        /// <summary>\n        /// The total amount of the line, including VAT and discounts. Adding all totalAmount values together should\n        /// result in the same amount as the amount top level property.\n        /// </summary>\n        public required Amount TotalAmount { get; set; }\n\n        /// <summary>\n        /// The VAT rate applied to the order line, for example \"21.00\" for 21%. The vatRate should be passed as a\n        /// string and not as a float to ensure the correct number of decimals are passed.\n        /// </summary>\n        public required string VatRate { get; set; }\n\n        /// <summary>\n        /// The amount of value-added tax on the line. The totalAmount field includes VAT, so the vatAmount can be\n        /// calculated with the formula totalAmount × (vatRate / (100 + vatRate)). Any deviations from this will\n        /// result in an error.\n        /// </summary>\n        public required Amount VatAmount { get; set; }\n\n        /// <summary>\n        /// The SKU, EAN, ISBN or UPC of the product sold. The maximum character length is 64.\n        /// </summary>\n        public string? Sku { get; set; }\n\n        /// <summary>\n        /// The order line’s date and time of creation\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the order line. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required OrderLineResponseLinks Links { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon line creation.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderLineResponseLinks.cs",
    "content": "using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Order.Response {\n    public record OrderLineResponseLinks {\n        /// <summary>\n        /// A link pointing to the product page in your web shop of the product sold.\n        /// </summary>\n        public UrlLink? ProductUrl { get; set; }\n\n        /// <summary>\n        /// A link pointing to an image of the product sold.\n        /// </summary>\n        public UrlLink? ImageUrl { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderLineStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Response {\n    public static class OrderLineStatus {\n        public const string Created = \"created\";\n        public const string Paid = \"paid\";\n        public const string Authorized = \"authorized\";\n        public const string Canceled = \"canceled\";\n        public const string Shipping = \"shipping\";\n        public const string Completed = \"completed\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderRefundResponse.cs",
    "content": "﻿using System.Collections.Generic;\nusing Mollie.Api.Models.Refund.Response;\n\nnamespace Mollie.Api.Models.Order.Response {\n    public record OrderRefundResponse : RefundResponse {\n        /// <summary>\n        /// The unique identifier of the order this refund was created for. For example: ord_stTC2WHAuS.\n        /// </summary>\n        public required string OrderId { get; set; }\n\n        /// <summary>\n        /// An array of order line objects as described in Get order. Only available if the refund was created via the\n        /// Create Order Refund API.\n        /// </summary>\n        public required IEnumerable<OrderLineResponse> Lines { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Order.Response {\n    public record OrderResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains an order object. Will always contain order for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The order’s unique identifier, for example ord_vsKJpSsabw.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The profile the order was created on, for example pfl_v9hTwCvYqw.\n        /// </summary>\n        public required string ProfileId { get; set; }\n\n        /// <summary>\n        /// The payment method last used when paying for the order - See the\n        /// Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        public string? Method { get; set; }\n\n        /// <summary>\n        /// For digital goods, you must make sure to apply the VAT rate from your customer's country in most jurisdictions.\n        /// You can use this parameter to restrict the payment methods available to your customer to methods from the billing\n        /// country only.\n        /// </summary>\n        public bool ShopperCountryMustMatchBillingCountry { get; set; }\n\n        /// <summary>\n        /// The mode used to create this order.\n        /// </summary>\n        public Mode Mode { get; set; }\n\n        /// <summary>\n        /// The total amount of the order, including VAT and discounts.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The amount captured, thus far. The captured amount will be settled to your account.\n        /// </summary>\n        public Amount? AmountCaptured { get; set; }\n\n        /// <summary>\n        /// The total amount refunded, thus far.\n        /// </summary>\n        public Amount? AmountRefunded { get; set; }\n\n        /// <summary>\n        /// The status of the order - See the Mollie.Api.Models.Order.OrderStatus class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// Whether or not the order can be (partially) canceled.\n        /// </summary>\n        public required bool IsCancelable { get; set; }\n\n        /// <summary>\n        /// The person and the address the order is billed to. See below.\n        /// </summary>\n        public OrderAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The date of birth of your customer, if available.\n        /// </summary>\n        public DateTime? ConsumerDateOfBirth { get; set; }\n\n        /// <summary>\n        /// Your order number that was used when creating the order.\n        /// </summary>\n        public required string OrderNumber { get; set; }\n\n        /// <summary>\n        /// The person and the address the order is billed to. See below.\n        /// </summary>\n        public OrderAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// The locale used during checkout.\n        /// </summary>\n        public required string Locale { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, for example a string or a JSON object. We will save the data\n        /// alongside the order. Whenever you fetch the order with our API, we’ll also include the\n        /// metadata. You can use up to approximately 1kB.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// The URL your customer will be redirected to after completing or canceling the payment process.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The optional redirect URL you provided during payment creation. Consumer that explicitly cancel the\n        /// order will be redirected to this URL if provided, or otherwise to the redirectUrl instead — see above.\n        ///\n        /// Mollie will always give you status updates via webhooks, including for the canceled status. This parameter\n        /// is therefore entirely optional, but can be useful when implementing a dedicated consumer-facing flow to\n        /// handle order cancellations.\n        ///\n        /// The URL will be null for recurring orders.\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        /// <summary>\n        /// The URL Mollie will call as soon an important status change on the order takes place.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// The order’s date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// The date and time the order will expire, in ISO 8601 format. Note that you have until this date to fully ship the\n        /// order.\n        /// </summary>\n        public DateTime? ExpiresAt { get; set; }\n\n        /// <summary>\n        /// If the order is expired, the time of expiration will be present in ISO 8601 format.\n        /// </summary>\n        public DateTime? ExpiredAt { get; set; }\n\n        /// <summary>\n        /// If the order has been paid, the time of payment will be present in ISO 8601 format.\n        /// </summary>\n        public DateTime? PaidAt { get; set; }\n\n        /// <summary>\n        /// If the order has been authorized, the time of authorization will be present in ISO 8601 format.\n        /// </summary>\n        public DateTime? AuthorizedAt { get; set; }\n\n        /// <summary>\n        /// If the order has been canceled, the time of cancellation will be present in ISO 8601 format.\n        /// </summary>\n        public DateTime? CanceledAt { get; set; }\n\n        /// <summary>\n        /// If the order is completed, the time of completion will be present in ISO 8601 format.\n        /// </summary>\n        public DateTime? CompletedAt { get; set; }\n\n        public required IEnumerable<OrderLineResponse> Lines { get; set; }\n\n        [JsonPropertyName(\"_embedded\")]\n        public OrderEmbeddedResponse? Embedded { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the order. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required OrderResponseLinks Links { get; set; }\n\n        public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n            return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Order.Response {\n    public record OrderResponseLinks {\n        /// <summary>\n        /// The API resource URL of the order itself.\n        /// </summary>\n        public required UrlObjectLink<OrderResponse> Self { get; set; }\n\n        /// <summary>\n        /// A link to the Mollie dashboard page.\n        /// </summary>\n        public required UrlLink Dashboard { get; set; }\n\n        /// <summary>\n        /// The URL your customer should visit to make the payment for the order.\n        /// This is where you should redirect the customer to after creating the order.\n        /// </summary>\n        public UrlLink? Checkout { get; set; }\n\n        /// <summary>\n        /// The URL to the order retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Order/Response/OrderStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Order.Response {\n    public static class OrderStatus {\n        public const string Created = \"created\";\n        public const string Paid = \"paid\";\n        public const string Authorized = \"authorized\";\n        public const string Canceled = \"canceled\";\n        public const string Shipping = \"shipping\";\n        public const string Completed = \"completed\";\n        public const string Expired = \"expired\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Organization/OrganizationResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Organization {\n    public record OrganizationResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a organization object.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        ///     The organization's identifier, for example org_1234567.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The organization's official name.\n        /// </summary>\n        public required string Name { get; set; }\n\n        /// <summary>\n        /// The organization's email.\n        /// </summary>\n        public required string Email { get; set; }\n\n        /// <summary>\n        /// The preferred locale of the merchant which has been set in Mollie Dashboard.\n        /// </summary>\n        public required string Locale { get; set; }\n\n        /// <summary>\n        /// The address of the organization.\n        /// </summary>\n        public required AddressObject Address { get; set; }\n\n        /// <summary>\n        /// The registration number of the organization at the (local) chamber of commerce.\n        /// </summary>\n        public required string RegistrationNumber { get; set; }\n\n        /// <summary>\n        /// The VAT number of the organization, if based in the European Union. The VAT number has been checked with the VIES by Mollie.\n        /// </summary>\n        public string? VatNumber { get; set; }\n\n        /// <summary>\n        /// The organization’s VAT regulation, if based in the European Union. Either shifted (VAT is shifted) or dutch (Dutch VAT rate).\n        /// </summary>\n        public string? VatRegulation { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the organization. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required OrganizationResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Organization/OrganizationResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.Invoice.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Profile.Response;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Organization {\n    public record OrganizationResponseLinks {\n        /// <summary>\n        /// The API resource URL of the organization itself.\n        /// </summary>\n        public required UrlObjectLink<OrganizationResponse> Self { get; set; }\n\n        /// <summary>\n        /// The API resource URL where the organization’s chargebacks can be retrieved.\n        /// </summary>\n        public UrlObjectLink<ListResponse<ChargebackResponse>>? Chargebacks { get; set; }\n\n        /// <summary>\n        /// The API resource URL where the organization’s customers can be retrieved.\n        /// </summary>\n        public UrlObjectLink<ListResponse<CustomerResponse>>? Customers { get; set; }\n\n        /// <summary>\n        /// The API resource URL where the organization’s invoices can be retrieved.\n        /// </summary>\n        public UrlObjectLink<ListResponse<InvoiceResponse>>? Invoices { get; set; }\n\n        /// <summary>\n        /// The API resource URL where the organization’s payments can be retrieved.\n        /// </summary>\n        public UrlObjectLink<ListResponse<PaymentResponse>>? Payments { get; set; }\n\n        /// <summary>\n        /// The API resource URL where the organization’s profiles can be retrieved.\n        /// </summary>\n        public UrlObjectLink<ListResponse<ProfileResponse>>? Profiles { get; set; }\n\n        /// <summary>\n        /// The API resource URL where the organization’s refunds can be retrieved.\n        /// </summary>\n        public UrlObjectLink<ListResponse<RefundResponse>>? Refunds { get; set; }\n\n        /// <summary>\n        /// The API resource URL where the organization’s settlements can be retrieved.\n        /// </summary>\n        public UrlObjectLink<ListResponse<SettlementResponse>>? Settlements { get; set; }\n\n        /// <summary>\n        /// The URL to the organization dashboard\n        /// </summary>\n        public required UrlLink Dashboard { get; set; }\n\n        /// <summary>\n        /// The URL to the payment method retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Organization/PartnerResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Organization;\n\npublic record PartnerResponse {\n    /// <summary>\n    /// Indicates the response contains a partner status object. Will always contain the string partner for this endpoint.\n    /// </summary>\n    public required string Resource { get; set; }\n\n    /// <summary>\n    /// Indicates the type of partner. Will be null if the currently authenticated organization is not enrolled as a partner.\n    /// Use the Mollie.Api.Models.Organization.PartnerTypes class for a full list of known values.\n    /// </summary>\n    public string? PartnerType { get; set; }\n\n    /// <summary>\n    /// Whether the current organization is receiving commissions.\n    /// </summary>\n    public required bool IsCommissionPartner { get; set; }\n\n    /// <summary>\n    /// Array of User-Agent token objects. Present if the organization is a partner of type useragent, or if they were in the past.\n    /// </summary>\n    public IEnumerable<UserAgentToken> UserAgentTokens { get; set; } = new List<UserAgentToken>();\n\n    /// <summary>\n    /// The date the partner contract was signed, in ISO 8601 format. Omitted if no contract has been signed (yet).\n    /// </summary>\n    public DateTimeOffset? PartnerContractSignedAt { get; set; }\n\n    /// <summary>\n    /// Whether an update to the partner contract is available and requiring the organization's agreement.\n    /// </summary>\n    public required bool PartnerContractUpdateAvailable  { get; set; }\n\n    /// <summary>\n    /// The expiration date of the signed partner contract, in ISO 8601 format. Omitted if contract has no expiration date (yet).\n    /// </summary>\n    public DateTimeOffset? PartnerContractExpiresAt  { get; set; }\n\n    /// <summary>\n    /// An object with several relevant URLs. Every URL object will contain an href and a type field.\n    /// </summary>\n    [JsonPropertyName(\"_links\")]\n    public required PartnerResponseLinks Links { get; set; }\n}\n\npublic record PartnerResponseLinks {\n    /// <summary>\n    /// In v2 endpoints, URLs are commonly represented as objects with an href and type field.\n    /// </summary>\n    public required UrlLink Self { get; set; }\n\n    /// <summary>\n    /// The URL that can be used to have new organizations sign up and be automatically linked to this partner.\n    /// Will be omitted if the partner is not of type signuplink.\n    /// </summary>\n    public UrlLink? Signuplink { get; set; }\n\n    /// <summary>\n    /// In v2 endpoints, URLs are commonly represented as objects with an href and type field.\n    /// </summary>\n    public required UrlLink Documentation { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Organization/PartnerTypes.cs",
    "content": "﻿namespace Mollie.Api.Models.Organization;\n\npublic static class PartnerTypes {\n    public const string OAuth = \"oauth\";\n    public const string SignupLink = \"signuplink\";\n    public const string Useragent = \"useragent\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Organization/UserAgentToken.cs",
    "content": "﻿using System;\n\nnamespace Mollie.Api.Models.Organization;\n\npublic record UserAgentToken {\n    /// <summary>\n    /// The unique User-Agent token.\n    /// </summary>\n    public required string Token { get; set; }\n\n    /// <summary>\n    /// The date from which the token is active, in ISO 8601 format.\n    /// </summary>\n    public required DateTimeOffset StartsAt { get; set; }\n\n    /// <summary>\n    /// The date until when the token will be active, in ISO 8601 format. Will be null if the token does not\n    /// have an end date (yet).\n    /// </summary>\n    public DateTimeOffset? EndsAt { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/EntryMode.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment;\n\npublic static class EntryMode {\n    public const string Moto = \"moto\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Locale.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment {\n    public static class Locale {\n        public static string de_DE = \"de_DE\";\n        public static string en_US = \"en_US\";\n        public static string es_ES = \"es_ES\";\n        public static string fr_FR = \"fr_FR\";\n        public static string nl_BE = \"nl_BE\";\n        public static string fr_BE = \"fr_BE\";\n        public static string nl_NL = \"nl_NL\";\n        public static string en_GB = \"en_GB\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/PaymentAddressDetails.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment;\n\npublic record PaymentAddressDetails : AddressObject {\n    /// <summary>\n    /// The person’s organization, if applicable.\n    /// </summary>\n    public string? OrganizationName { get; set; }\n\n    /// <summary>\n    /// The title of the person, for example Mr. or Mrs..\n    /// </summary>\n    public string? Title { get; set; }\n\n    /// <summary>\n    /// The given name (first name) of the person.\n    /// </summary>\n    public string? GivenName { get; set; }\n\n    /// <summary>\n    /// The family name (surname) of the person.\n    /// </summary>\n    public string? FamilyName { get; set; }\n\n    /// <summary>\n    /// The email address of the person.\n    /// </summary>\n    public string? Email { get; set; }\n\n    /// <summary>\n    /// The phone number of the person. Some payment methods require this information. If you have it, you\n    /// should pass it so that your customer does not have to enter it again in the checkout. Must be in\n    /// the E.164 format. For example +31208202070.\n    /// </summary>\n    public string? Phone { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/PaymentLine.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Payment;\n\npublic record PaymentLine {\n    /// <summary>\n    /// The type of product purchased. For example, a physical or a digital product.\n    /// Use the Mollie.Api.Models.Order.Request.OrderLineDetailsType class for a full list of known values.\n    /// </summary>\n    public required string Type { get; set; }\n\n    /// <summary>\n    /// A description of the line item. For example LEGO 4440 Forest Police Station.\n    /// </summary>\n    public required string Description { get; set; }\n\n    /// <summary>\n    /// The number of items.\n    /// </summary>\n    public required int Quantity { get; set; }\n\n    /// <summary>\n    /// The unit for the quantity. For example pcs, kg, or cm.\n    /// </summary>\n    public string? QuantityUnit { get; set; }\n\n    /// <summary>\n    /// The price of a single item including VAT. The unit price can be zero in case of free items.\n    /// </summary>\n    public required Amount UnitPrice { get; set; }\n\n    /// <summary>\n    /// Any line-specific discounts, as a positive amount. Not relevant if the line itself is already a discount type.\n    /// </summary>\n    public Amount? DiscountAmount { get; set; }\n\n    /// <summary>\n    /// The total amount of the line, including VAT and discounts.\n    /// </summary>\n    public required Amount TotalAmount { get; set; }\n\n    /// <summary>\n    /// The VAT rate applied to the line, for example 21.00 for 21%. The vatRate should be passed as a string and not\n    /// as a float, to ensure the correct number of decimals are passed.\n    /// </summary>\n    public string? VatRate { get; set; } // TODO: make it decimal?\n\n    /// <summary>\n    /// The amount of value-added tax on the line. The totalAmount field includes VAT, so the vatAmount can be\n    /// calculated with the formula totalAmount × (vatRate / (100 + vatRate)).\n    /// </summary>\n    public Amount? VatAmount { get; set; }\n\n    /// <summary>\n    /// An array with the voucher categories, in case of a line eligible for a voucher. See the Integrating\n    /// Vouchers guide for more information. Use the Mollie.Api.Models.VoucherCategory class for a full list of known values.\n    /// </summary>\n    public IEnumerable<string>? Categories { get; set; }\n\n    /// <summary>\n    /// The SKU, EAN, ISBN or UPC of the product sold.\n    /// </summary>\n    public string? Sku { get; set; }\n\n    /// <summary>\n    /// A link pointing to an image of the product sold.\n    /// </summary>\n    public string? ImageUrl { get; set; }\n\n    /// <summary>\n    /// A link pointing to the product page in your web shop of the product sold.\n    /// </summary>\n    public string? ProductUrl { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/PaymentMethod.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment {\n    public static class PaymentMethod {\n        public const string Bancontact = \"bancontact\";\n        public const string BankTransfer = \"banktransfer\";\n        public const string Belfius = \"belfius\";\n        public const string CreditCard = \"creditcard\";\n        public const string DirectDebit = \"directdebit\";\n        public const string Eps = \"eps\";\n        public const string GiftCard = \"giftcard\";\n        public const string Giropay = \"giropay\";\n        public const string Ideal = \"ideal\";\n        public const string IngHomePay = \"inghomepay\";\n        public const string Kbc = \"kbc\";\n        public const string PayPal = \"paypal\";\n        public const string PaySafeCard = \"paysafecard\";\n        public const string Sofort = \"sofort\";\n        public const string Refund = \"refund\";\n        public const string KlarnaPayLater = \"klarnapaylater\";\n        public const string KlarnaPayNow  = \"klarnapaynow \";\n        public const string KlarnaSliceIt = \"klarnasliceit\";\n        public const string KlarnaOne = \"klarna\";\n        public const string Przelewy24 = \"przelewy24\";\n        public const string ApplePay = \"applepay\";\n        public const string MealVoucher = \"mealvoucher\";\n        public const string In3 = \"in3\";\n        public const string PointOfSale = \"pointofsale\";\n        public const string Billie = \"billie\";\n        public const string Trustly = \"trustly\";\n        public const string Twint = \"twint\";\n        public const string Satispay = \"satispay\";\n        public const string Riverty = \"riverty\";\n        public const string Blik = \"blik\";\n        public const string BancomatPay = \"bancomat_pay\";\n        public const string BacsDirectDebit = \"bacs\";\n        public const string Alma = \"alma\";\n        public const string GooglePay = \"googlepay\";\n        public const string Voucher = \"voucher\";\n        public const string MbWay = \"mbway\";\n        public const string Multibanco = \"multibanco\";\n        public const string Swish = \"swish\";\n        public const string MobilePay = \"mobilepay\";\n        public const string MyBank = \"mybank\";\n        public const string PayByBank = \"paybybank\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/PaymentStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment {\n    public static class PaymentStatus {\n        public const string Open = \"open\";\n        public const string Canceled = \"canceled\";\n        public const string Pending = \"pending\";\n        public const string Authorized = \"authorized\";\n        public const string Expired = \"expired\";\n        public const string Failed = \"failed\";\n        public const string Paid = \"paid\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentRequest.cs",
    "content": "﻿using System;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.Json;\n\nnamespace Mollie.Api.Models.Payment.Request {\n    public record PaymentRequest : ITestModeRequest, IProfileRequest\n    {\n        /// <summary>\n        /// The amount that you want to charge, e.g. {\"currency\":\"EUR\", \"value\":\"100.00\"} if you would want to charge €100.00.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The description of the payment you’re creating. This will be shown to the consumer on their card or bank statement\n        /// when possible. We truncate the description automatically according to the limits of the used payment method. The\n        /// description is also visible in any exports you generate. We recommend you use a unique identifier so that you can\n        /// always link the payment to the order.This is particularly useful for bookkeeping.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// Required - The URL the consumer will be redirected to after the payment process. It could make sense for the\n        /// redirectURL to contain a unique\n        /// identifier – like your order ID – so you can show the right page referencing the order when the consumer returns.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The URL your consumer will be redirected to when the consumer explicitly cancels the payment. If this URL is not\n        /// provided, the consumer will be redirected to the redirectUrl instead &#x2014; see above.\n        /// <para>Mollie will always give you status updates via webhooks, including for the canceled status. This parameter is\n        /// therefore entirely optional, but can be useful when implementing a dedicated consumer-facing flow to handle payment\n        /// cancellations.</para>\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        /// <summary>\n        /// Set the webhook URL, where we will send payment status updates to.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Optionally provide the order lines for the payment. Each line contains details such as a description of the item ordered and its price.\n        /// All lines must have the same currency as the payment.\n        /// </summary>\n        public List<PaymentLine>? Lines { get; set; }\n\n        /// <summary>\n        /// The customer's billing address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The customer's shipping address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// Allows you to preset the language to be used in the payment screens shown to the consumer. Setting a locale is highly\n        /// recommended and will greatly improve your conversion rate. When this parameter is omitted, the browser language will\n        /// be used instead if supported by the payment method. You can provide any ISO 15897 locale, but our payment screen currently\n        /// only supports the following languages: en_US nl_NL nl_BE fr_FR fr_BE de_DE de_AT de_CH es_ES ca_ES pt_PT it_IT nb_NO\n        /// sv_SE fi_FI da_DK is_IS hu_HU pl_PL lv_LV lt_LT\n        /// </summary>\n        public string? Locale { get; set; }\n\n        /// <summary>\n        /// Normally, a payment method selection screen is shown. However, when using this parameter, your customer will skip the\n        /// selection screen and will be sent directly to the chosen payment method. The parameter enables you to fully integrate\n        /// the payment method selection into your website, however note Mollie’s country based conversion optimization is lost.\n        /// See the Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        [JsonIgnore]\n        public string? Method {\n            get => Methods?.FirstOrDefault();\n            set {\n                if (value == null) {\n                    Methods = null;\n                }\n                else {\n                    Methods = new List<string>();\n                    Methods.Add(value);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Only relevant for iDEAL, KBC/CBC, gift card, and voucher payments.\n        /// Some payment methods are a network of connected banks or card issuers. In these cases, after selecting the payment method,\n        /// the customer may still need to select the appropriate issuer before the payment can proceed.\n        /// </summary>\n        public string? Issuer { get; set; }\n\n        /// <summary>\n        /// Normally, a payment method screen is shown. However, when using this parameter, you can choose a specific payment method\n        /// and your customer will skip the selection screen and is sent directly to the chosen payment method. The parameter\n        /// enables you to fully integrate the payment method selection into your website.\n        /// You can also specify the methods in an array.By doing so we will still show the payment method selection screen but will\n        /// only show the methods specified in the array. For example, you can use this functionality to only show payment methods\n        /// from a specific country to your customer.\n        /// </summary>\n        [JsonPropertyName(\"method\")]\n        public IList<string>? Methods { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, for example a string or a JSON object. We will save the data alongside the payment. Whenever\n        /// you fetch the payment with our API, we’ll also include the metadata. You can use up to approximately 1kB.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// Indicate which type of payment this is in a recurring sequence. If set to first, a first payment is created for the\n        /// customer, allowing the customer to agree to automatic recurring charges taking place on their account in the future.\n        /// If set to recurring, the customer’s card is charged automatically. Defaults to oneoff, which is a regular non-recurring\n        /// payment(see also: Recurring). See the Mollie.Api.Models.Payment.SequenceType class for a full list of known values.\n        /// </summary>\n        public string? SequenceType { get; set; }\n\n        /// <summary>\n        /// The ID of the Customer for whom the payment is being created. This is used for recurring payments and single click payments.\n        /// </summary>\n        public string? CustomerId { get; set; }\n\n        /// <summary>\n        /// When creating recurring payments, the ID of a specific Mandate may be supplied to indicate which of the consumer’s accounts\n        /// should be credited.\n        /// </summary>\n        public string? MandateId { get; set; }\n\n\t\t/// <summary>\n\t\t///\tOauth only - The payment profile's unique identifier, for example pfl_3RkSN1zuPE. This field is mandatory.\n\t\t/// </summary>\n\t\tpublic string? ProfileId { get; set; }\n\n        /// <summary>\n        /// The date by which the payment should be completed in YYYY-MM-DD format\n        /// </summary>\n        [JsonConverter(typeof(DateJsonConverter))]\n        public DateTime? DueDate { get; set; }\n\n\t\t/// <summary>\n\t\t///\tOauth only - Optional – Set this to true to make this payment a test payment.\n\t\t/// </summary>\n\t\tpublic bool? Testmode { get; set; }\n\n\t\t/// <summary>\n\t\t///\tOauth only - Optional – Adding an Application Fee allows you to charge the merchant a small sum for the payment and transfer\n\t\t/// this to your own account.\n\t\t/// </summary>\n\t\tpublic ApplicationFee? ApplicationFee { get; set; }\n\n        /// <summary>\n        /// Oauth only - Optional - An optional routing configuration which enables you to route a successful payment, or part of the payment, to one or more connected accounts.\n        /// Additionally, you can schedule (parts of) the payment to become available on the connected account on a future date.\n        /// </summary>\n        [JsonPropertyName(\"routing\")]\n        public IList<PaymentRoutingRequest>? Routings { get; set; }\n\n        /// <summary>\n        /// For digital goods in most jurisdictions, you must apply the VAT rate from your customer’s country. Choose the VAT rates\n        /// you have used for the order to ensure your customer’s country matches the VAT country. Use this parameter to restrict the\n        /// payment methods available to your customer to those from a single country. If available, the credit card method will still\n        /// be offered, but only cards from the allowed country are accepted.\n        /// </summary>\n        public string? RestrictPaymentMethodsToCountry { get; set; }\n\n        /// <summary>\n        /// Indicates whether the capture will be scheduled automatically or not. Set to manual to capture the payment manually using the\n        /// Create capture endpoint. Set to automatic by default, which indicates the payment will be captured automatically, without\n        /// having to separately request it. Setting automatic without a captureDelay will result in a regular payment.\n        /// See the Mollie.Api.Models.Capture.CaptureMode class for a full list of known values.\n        /// </summary>\n        public string? CaptureMode { get; set; }\n\n        /// <summary>\n        /// Interval to wait before the payment is captured, for example 8 hours or 2 days. In order to schedule an automatic capture,\n        /// the captureMode must be set to either automatic or be omitted.\n        /// Possible values: ... hours ... days\n        /// </summary>\n        public string? CaptureDelay { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n\n        public override string ToString() {\n            return $\"Method: {Method} - Amount: {Amount}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentRoutingRequest.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Payment.Request;\n\npublic record PaymentRoutingRequest\n{\n    /// <summary>\n    /// If more than one routing object is given, the routing objects must indicate what portion of the total payment amount is being routed.\n    /// </summary>\n    public Amount? Amount { get; set; }\n\n    /// <summary>\n    /// The destination of this portion of the payment.\n    /// </summary>\n    public required RoutingDestination Destination { get; set; }\n\n    /// <summary>\n    /// Optionally, schedule this portion of the payment to be transferred to its destination on a later date. If no date is given, the funds become available to the balance as soon as the payment succeeds.\n    /// </summary>\n    [JsonConverter(typeof(DateJsonConverter))]\n    public DateTime? ReleaseDate { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/ApplePayPaymentRequest.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public record ApplePayPaymentRequest : PaymentRequest {\n        public ApplePayPaymentRequest()\n        {\n            Method = PaymentMethod.ApplePay;\n        }\n\n        [SetsRequiredMembers]\n        public ApplePayPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.ApplePay;\n        }\n\n        /// <summary>\n        /// Optional - The Apple Pay Payment Token object (encoded as JSON) that is part of the result of authorizing a payment\n        /// request. The token contains the payment information needed to authorize the payment.\n        /// </summary>\n        public string? ApplePayPaymentToken { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/BankTransferPaymentRequest.cs",
    "content": "using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public record BankTransferPaymentRequest : PaymentRequest {\n        public BankTransferPaymentRequest() {\n            Method = PaymentMethod.BankTransfer;\n        }\n\n        [SetsRequiredMembers]\n        public BankTransferPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.BankTransfer;\n        }\n\n        /// <summary>\n        /// Optional - Consumer's e-mail address, to automatically send the bank transfer details to. Please note: the payment\n        /// instructions will be sent immediately when creating the payment. if you don't specify the locale parameter, the\n        /// email will be sent in English, as we haven't yet been able to detect the consumer's browser language.\n        /// </summary>\n        public string? BillingEmail { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/CreditCardPaymentRequest.cs",
    "content": "using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public record CreditCardPaymentRequest : PaymentRequest {\n        public CreditCardPaymentRequest() {\n            Method = PaymentMethod.CreditCard;\n        }\n\n        [SetsRequiredMembers]\n        public CreditCardPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.CreditCard;\n        }\n\n        /// <summary>\n        /// The card token you get from Mollie Components. The token contains the card information\n        /// (such as card holder, card number and expiry date) needed to complete the payment.\n        /// </summary>\n        public string? CardToken { get; set; }\n\n        /// <summary>\n        /// Beta feature: The entrymode of the payment. See the Mollie.Api.Models.Payment.EntryMode class for a full\n        /// list of known values\n        /// </summary>\n        public string? EntryMode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/GiftcardPaymentRequest.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public record GiftcardPaymentRequest : PaymentRequest {\n        public GiftcardPaymentRequest() {\n            Method = PaymentMethod.GiftCard;\n        }\n\n        [SetsRequiredMembers]\n        public GiftcardPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.GiftCard;\n        }\n\n        /// <summary>\n        /// The card number on the gift card.\n        /// </summary>\n        public string? VoucherNumber { get; set; }\n\n        /// <summary>\n        /// The PIN code on the gift card. Only required if there is a PIN code printed on the gift card.\n        /// </summary>\n        public string? VoucherPin { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/IDealPaymentRequest.cs",
    "content": "using System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    [Obsolete(\"Ideal no longer has specific parameters, so this class is identical to PaymentRequest\")]\n    public record IdealPaymentRequest : PaymentRequest {\n        public IdealPaymentRequest() {\n            Method = PaymentMethod.Ideal;\n        }\n\n        [SetsRequiredMembers]\n        public IdealPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.Ideal;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/KbcIssuer.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public static class KbcIssuer {\n        public const string Kbc = \"kbc\";\n        public const string Cbc = \"cbc\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/KbcPaymentRequest.cs",
    "content": "﻿using System;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    [Obsolete(\"Kbc no longer has specific parameters, so this class is identical to PaymentRequest\")]\n    public record KbcPaymentRequest : PaymentRequest {\n        public KbcPaymentRequest() {\n            Method = PaymentMethod.Kbc;\n        }\n\n        [SetsRequiredMembers]\n        public KbcPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.Kbc;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/PayPalPaymentRequest.cs",
    "content": "using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public record PayPalPaymentRequest : PaymentRequest {\n        public PayPalPaymentRequest() {\n            Method = PaymentMethod.PayPal;\n        }\n\n        [SetsRequiredMembers]\n        public PayPalPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.PayPal;\n        }\n\n        /// <summary>\n        /// The unique ID you have used for the PayPal fraud library. You should include this if you use PayPal\n        /// for an on-demand payment. The maximum character length is 32.\n        /// Please refer to the Recurring payments guide for more information on how to implement the fraud library.\n        /// </summary>\n        public string? SessionId { get; set; }\n\n        /// <summary>\n        /// Indicate if you�re about to deliver digital goods, like for example a license. Setting this parameter can\n        /// have consequences for your Seller Protection by PayPal. Please see PayPal�s help article about Seller\n        /// Protection for more information.\n        /// </summary>\n        public bool? DigitalGoods { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/PaySafeCardPaymentRequest.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public record PaySafeCardPaymentRequest : PaymentRequest {\n        public PaySafeCardPaymentRequest() {\n            Method = PaymentMethod.PaySafeCard;\n        }\n\n        [SetsRequiredMembers]\n        public PaySafeCardPaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.PaySafeCard;\n        }\n\n        /// <summary>\n        /// Used for consumer identification. For example, you could use the consumer’s IP address.\n        /// </summary>\n        public string? CustomerReference { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/PointOfSalePaymentRequest.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters;\n\npublic record PointOfSalePaymentRequest : PaymentRequest {\n    public PointOfSalePaymentRequest() {\n        Method = PaymentMethod.PointOfSale;\n    }\n\n    [SetsRequiredMembers]\n    public PointOfSalePaymentRequest(PaymentRequest paymentRequest, string terminalId) : base(paymentRequest) {\n        Method = PaymentMethod.PointOfSale;\n        TerminalId = terminalId;\n    }\n\n    /// <summary>\n    /// The ID of the terminal device where you want to initiate the payment on\n    /// </summary>\n    public required string TerminalId { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/Przelewy24PaymentRequest.cs",
    "content": "using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters\n{\n    public record Przelewy24PaymentRequest : PaymentRequest\n    {\n        public Przelewy24PaymentRequest()\n        {\n            Method = PaymentMethod.Przelewy24;\n        }\n\n        [SetsRequiredMembers]\n        public Przelewy24PaymentRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.Przelewy24;\n        }\n\n        /// <summary>\n        /// Consumer�s email address, this is required for Przelewy24 payments.\n        /// </summary>\n        public string? BillingEmail { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentSpecificParameters/SepaDirectDebitRequest.cs",
    "content": "using System.Diagnostics.CodeAnalysis;\n\nnamespace Mollie.Api.Models.Payment.Request.PaymentSpecificParameters {\n    public record SepaDirectDebitRequest : PaymentRequest {\n        public SepaDirectDebitRequest() {\n            Method = PaymentMethod.DirectDebit;\n        }\n\n        [SetsRequiredMembers]\n        public SepaDirectDebitRequest(PaymentRequest paymentRequest) : base(paymentRequest) {\n            Method = PaymentMethod.DirectDebit;\n        }\n\n        /// <summary>\n        /// Optional - Beneficiary name of the account holder.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Optional - IBAN of the account holder.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Request/PaymentUpdateRequest.cs",
    "content": "﻿using System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Payment.Request {\n    public record PaymentUpdateRequest : ITestModeRequest {\n        /// <summary>\n        /// The description of the payment. This will be shown to your customer on their card or bank statement\n        /// when possible. We truncate the description automatically according to the limits of the used payment\n        /// method. The description is also visible in any exports you generate. We recommend you use a unique\n        /// identifier so that you can always link the payment to the order in your back office.This is particularly\n        /// useful for bookkeeping.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The URL your customer will be redirected to after the payment process. It could make sense for the redirectUrl\n        /// to contain a unique identifier – like your order ID – so you can show the right page referencing the order\n        /// when your customer returns. Updating this field is only possible when the payment is not yet finalized.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// Can be updated while the payment is in an open state.\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        /// <summary>\n        /// Set the webhook URL, where we will send payment status updates to.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, for example a string or a JSON object. We will save the data alongside the payment. Whenever\n        /// you fetch the payment with our API, we’ll also include the metadata. You can use up to approximately 1kB.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// Can be updated while no payment method has been chosen yet.\n        /// See the Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        public string? Method { get; set; }\n\n        /// <summary>\n        /// Allows you to preset the language to be used in the payment screens shown to the consumer. Setting a locale is highly\n        /// recommended and will greatly improve your conversion rate. When this parameter is omitted, the browser language will\n        /// be used instead if supported by the payment method. You can provide any ISO 15897 locale, but our payment screen currently\n        /// only supports the following languages: en_US nl_NL nl_BE fr_FR fr_BE de_DE de_AT de_CH es_ES ca_ES pt_PT it_IT nb_NO\n        /// sv_SE fi_FI da_DK is_IS hu_HU pl_PL lv_LV lt_LT\n        /// </summary>\n        public string? Locale { get; set; }\n\n        /// <summary>\n        /// For digital goods in most jurisdictions, you must apply the VAT rate from your customer’s country. Choose the VAT rates\n        /// you have used for the order to ensure your customer’s country matches the VAT country. Use this parameter to restrict the\n        /// payment methods available to your customer to those from a single country. If available, the credit card method will still\n        /// be offered, but only cards from the allowed country are accepted.\n        /// </summary>\n        public string? RestrictPaymentMethodsToCountry { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this payment a test payment.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Resource.cs",
    "content": "﻿using System.Runtime.Serialization;\n\nnamespace Mollie.Api.Models.Payment\n{\n    public enum Resource\n    {\n        [EnumMember(Value = \"orders\")] Orders,\n        [EnumMember(Value = \"payments\")] Payments\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentEmbeddedResponse.cs",
    "content": "﻿using System.Collections.Generic;\nusing Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.Refund.Response;\n\nnamespace Mollie.Api.Models.Payment.Response {\n    public record PaymentEmbeddedResponse {\n        public IEnumerable<RefundResponse>? Refunds { get; set; }\n        public IEnumerable<ChargebackResponse>? Chargebacks { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Payment.Response {\n    public record PaymentResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a payment object. Will always contain payment for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The identifier uniquely referring to this payment. Mollie assigns this identifier randomly at payment creation\n        /// time. For example tr_7UhSN1zuXS. Its ID will always be used by Mollie to refer to a certain payment.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The mode used to create this payment. Mode determines whether a payment is real or a test payment.\n        /// </summary>\n        public required Mode Mode { get; set; }\n\n        /// <summary>\n        /// The payment's date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// The payment's status. Please refer to the page about statuses for more info about which statuses occur at what\n        /// point. See the Mollie.Api.Models.Payment.PaymentStatus class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// This object offers details about the status of a payment. Currently it is only available for point-of-sale payments.\n        /// </summary>\n        public StatusReason? StatusReason { get; set; }\n\n        /// <summary>\n        /// Whether or not the payment can be canceled.\n        /// </summary>\n        public bool? IsCancelable { get; set; }\n\n        /// <summary>\n        /// The date and time the payment became authorized, in ISO 8601 format. This parameter is omitted if the payment is not authorized (yet).\n        /// </summary>\n        public DateTime? AuthorizedAt { get; set; }\n\n        /// <summary>\n        /// The date and time the payment became paid, in ISO 8601 format. Null is returned if the payment isn't completed\n        /// (yet).\n        /// </summary>\n        public DateTime? PaidAt { get; set; }\n\n        /// <summary>\n        /// The date and time the payment was cancelled, in ISO 8601 format. Null is returned if the payment isn't cancelled\n        /// (yet).\n        /// </summary>\n        public DateTime? CanceledAt { get; set; }\n\n        /// <summary>\n        /// The date and time the payment was expired, in ISO 8601 format. Null is returned if the payment did not expire\n        /// (yet).\n        /// </summary>\n        public DateTime? ExpiresAt { get; set; }\n\n        /// <summary>\n        /// The time until the payment will expire in ISO 8601 duration format.\n        /// </summary>\n        public DateTime? ExpiredAt { get; set; }\n\n        /// <summary>\n        /// The date and time the payment failed, in ISO 8601 format. This parameter is omitted if the payment did not fail (yet).\n        /// </summary>\n        public DateTime? FailedAt { get; set; }\n\n        /// <summary>\n        /// The amount of the payment, e.g. {\"currency\":\"EUR\", \"value\":\"100.00\"} for a €100.00 payment.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// Only available when refunds are available for this payment – The total amount in EURO that is already refunded. For\n        /// some payment methods, this\n        /// amount may be higher than the payment amount, for example to allow reimbursement of the costs for a return shipment\n        /// to the consumer.\n        /// </summary>\n        public Amount? AmountRefunded { get; set; }\n\n        /// <summary>\n        /// Only available when refunds are available for this payment – The remaining amount in EURO that can be refunded.\n        /// </summary>\n        public Amount? AmountRemaining { get; set; }\n\n        /// <summary>\n        /// The total amount that is already captured for this payment. Only available when this payment supports captures.\n        /// </summary>\n        public Amount? AmountCaptured { get; set; }\n\n        /// <summary>\n        /// The total amount that was charged back for this payment. Only available when the total charged back amount is not zero.\n        /// </summary>\n        public Amount? AmountChargedBack { get; set; }\n\n        /// <summary>\n        /// A short description of the payment. The description will be shown on the consumer's bank or card statement when\n        /// possible.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The URL the consumer will be redirected to after completing or cancelling the payment process.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The optional redirect URL you provided during payment creation. Consumer that explicitly cancel the payment\n        /// will be redirected to this URL if provided, or otherwise to the redirectUrl instead — see above.\n        ///\n        /// Mollie will always give you status updates via webhooks, including for the canceled status. This parameter\n        /// is therefore entirely optional, but can be useful when implementing a dedicated consumer-facing flow to\n        /// handle payment cancellations.\n        ///\n        /// The URL will be null for recurring payments.\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        /// <summary>\n        /// The URL Mollie will call as soon an important status change takes place.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Optionally provide the order lines for the payment. Each line contains details such as a description of the item ordered and its price.\n        /// All lines must have the same currency as the payment.\n        /// </summary>\n        public List<PaymentLine>? Lines { get; set; }\n\n        /// <summary>\n        /// The customer's billing address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The customer's shipping address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// An optional routing configuration that you provided, which enables you to route a successful payment, or part of the payment, to one or more connected accounts.\n        /// Additionally, you can schedule (parts of) the payment to become available on the connected account on a future date.\n        /// </summary>\n        [JsonPropertyName(\"routing\")]\n        public IList<PaymentRoutingResponse>? Routings { get; set; }\n\n        /// <summary>\n        /// The payment method used for this payment, either forced on creation by specifying the method parameter, or chosen\n        /// by the consumer our payment method selection screen. See the Mollie.Api.Models.Payment.PaymentMethod class for a\n        /// full list of known values.\n        /// </summary>\n        public string? Method { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon payment creation. Metadata can be used to link an order to a payment.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// The consumer's locale, either forced on creation by specifying the locale parameter, or detected by us during\n        /// checkout.\n        /// </summary>\n        public string? Locale { get; set; }\n\n        /// <summary>\n        /// The customer’s ISO 3166-1 alpha-2 country code, detected by us during checkout. For example: BE.\n        /// </summary>\n        public string? CountryCode { get; set; }\n\n        /// <summary>\n        /// The identifier referring to the profile this payment was created on. For example, pfl_QkEhN94Ba.\n        /// </summary>\n        public required string ProfileId { get; set; }\n\n        /// <summary>\n        /// This optional field will contain the amount that will be settled to your account, converted to the currency your\n        /// account is settled in. It follows the same syntax as the amount property.\n        /// </summary>\n        public Amount? SettlementAmount { get; set; }\n\n        /// <summary>\n        /// The identifier referring to the settlement this payment belongs to. For example, stl_BkEjN2eBb.\n        /// </summary>\n        public string? SettlementId { get; set; }\n\n        /// <summary>\n        /// The customerid of this payment\n        /// </summary>\n        public string? CustomerId { get; set; }\n\n        /// <summary>\n        /// Indicates which type of payment this is in a recurring sequence. Set to first for first payments that allow the customer to agree\n        /// to automatic recurring charges taking place on their account in the future. Set to recurring for payments where the customer’s card\n        /// is charged automatically. See the Mollie.Api.Models.Payment.SequenceType class for a full list of known values.\n        /// </summary>\n        public required string SequenceType { get; set; }\n\n        /// <summary>\n        /// Only available for recurring payments – If the payment is a recurring payment, this field will hold the ID of the\n        /// mandate used to authorize the recurring payment.\n        /// </summary>\n        public string? MandateId { get; set; }\n\n        /// <summary>\n        /// Only available for recurring payments – When implementing the Subscriptions API, any recurring charges resulting\n        /// from the subscription will hold the ID of the subscription that triggered the payment.\n        /// </summary>\n        public string? SubscriptionId { get; set; }\n\n        /// <summary>\n        /// If the payment was created for an order, the ID of that order will be part of the response.\n        /// </summary>\n        public string? OrderId { get; set; }\n\n        /// <summary>\n        /// The application fee, if the payment was created with one.\n        /// </summary>\n        public ApplicationFee? ApplicationFee { get; set; }\n\n        /// <summary>\n        /// Indicates whether the capture will be scheduled automatically or not. Set to manual for payments that can be captured\n        /// manually using the Create capture endpoint. Set to automatic by default, which indicates the payment will be captured\n        /// automatically, without having to separately request it.\n        /// </summary>\n        public string? CaptureMode { get; set; }\n\n        /// <summary>\n        /// Indicates the interval to wait before the payment is captured, for example 8 hours or 2 days. The capture delay will be\n        /// added to the date and time the payment became authorized.\n        /// </summary>\n        public string? CaptureDelay { get; set; }\n\n        /// <summary>\n        /// Indicates the datetime on which the merchant has to have captured the payment, before we can no longer guarantee a\n        /// successful capture, in ISO 8601 format. This parameter is omitted if the payment is not authorized (yet).\n        /// </summary>\n        public DateTime? CaptureBefore { get; set; }\n\n        [JsonPropertyName(\"_embedded\")]\n        public PaymentEmbeddedResponse? Embedded { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the payment. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public PaymentResponseLinks Links { get; set; } = null!;\n\n        public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n            return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n        }\n\n        public override string ToString() {\n            return $\"Id: {Id} - Status: {Status} - Method: {Method} - Amount: {Amount}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Order.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Subscription.Response;\nusing Mollie.Api.Models.Terminal.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Payment.Response {\n    public record PaymentResponseLinks {\n        /// <summary>\n        /// The API resource URL of the payment itself.\n        /// </summary>\n        public required UrlObjectLink<PaymentResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL your customer should visit to make the payment. This is where you should redirect the consumer to.\n        /// </summary>\n        public UrlLink? Checkout { get; set; }\n\n        /// <summary>\n        /// The deeplink URL to the app of the payment method. Currently only available for bancontact.\n        /// </summary>\n        public UrlLink? MobileAppCheckout { get; set; }\n\n        /// <summary>\n        /// Direct link to the payment in the Mollie Dashboard.\n        /// </summary>\n        public required UrlLink Dashboard { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the refunds that belong to this payment.\n        /// </summary>\n        public UrlLink? Refunds { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the chargebacks that belong to this payment.\n        /// </summary>\n        public UrlObjectLink<ListResponse<ChargebackResponse>>? Chargebacks { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the captures that belong to this payment.\n        /// </summary>\n        public UrlLink? Captures { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the settlement this payment has been settled with. Not present if not yet settled.\n        /// </summary>\n        public UrlObjectLink<SettlementResponse>? Settlement { get; set; }\n\n        /// <summary>\n        /// The URL to the payment retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the mandate linked to this payment. Not present if a one-off payment.\n        /// </summary>\n        public UrlObjectLink<MandateResponse>? Mandate { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the subscription this payment is part of. Not present if not a subscription payment.\n        /// </summary>\n        public UrlObjectLink<SubscriptionResponse>? Subscription { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the customer this payment belongs to. Not present if not linked to a customer.\n        /// </summary>\n        public UrlObjectLink<CustomerResponse>? Customer { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the order this payment was created for. Not present if not created for an order.\n        /// </summary>\n        public UrlObjectLink<OrderResponse>? Order { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the terminal this payment was created for. Not present if not created for a terminal.\n        /// </summary>\n        public UrlObjectLink<TerminalResponse>? Terminal { get; set; }\n\n        /// <summary>\n        /// Recurring payments do not have a checkout URL, because these payments are executed without any user interaction.\n        /// This link is included for test mode recurring payments, and allows you to set the final payment state for such payments.\n        /// </summary>\n        public UrlLink? ChangePaymentState { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentRoutingResponse.cs",
    "content": "﻿using System;\n\nnamespace Mollie.Api.Models.Payment.Response\n{\n    public record PaymentRoutingResponse\n    {\n\n        /// <summary>\n        /// Indicates the response contains a routing object. Will always contain route for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The identifier uniquely referring to this route. Mollie assigns this identifier randomly at payment creation\n        /// time. For example rt_k6cjd01h. Its ID will always be used by Mollie to refer to a certain route.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// If more than one routing object is given, the routing objects must indicate what portion of the total payment amount is being routed.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The destination of this portion of the payment.\n        /// </summary>\n        public required RoutingDestination Destination { get; set; }\n\n        /// <summary>\n        /// Optional property you provided to schedule this portion of the payment to be transferred to its destination on a later date.\n        /// If no date is given, the funds become available to the balance as soon as the payment succeeds.\n        /// </summary>\n        public DateTime? ReleaseDate { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/BancontactPaymentResponse.cs",
    "content": "﻿using System;\n\nnamespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record BancontactPaymentResponse : PaymentResponse {\n        public required BancontactPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record BancontactPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment is completed - The last four digits of the card number.\n        /// </summary>\n        public string? CardNumber { get; set; }\n\n        /// <summary>\n        /// Only available if the payment is completed - Unique alphanumeric representation of card, usable for\n        /// identifying returning customers. This field is deprecated as of November 28th, 2019. The fingerprint\n        /// is now unique per transaction what makes it not usefull anymore for identifying returning customers.\n        /// Use the consumerAccount field instead.\n        /// </summary>\n        [Obsolete(@\"This field is deprecated as of November 28th, 2019. The fingerprint is now unique per\ntransaction what makes it not usefull anymore for identifying returning customers. Use the consumerAccount field instead.\")]\n        public string? CardFingerprint { get; set; }\n\n        /// <summary>\n        /// Only available if requested during payment creation - The QR code that can be scanned by the mobile\n        /// Bancontact application. This enables the desktop to mobile feature.\n        /// </summary>\n        public QrCode? QrCode { get; set; }\n\n        /// <summary>\n        /// Only available if the payment is completed – The consumer’s bank account. This may be an IBAN, or it may be a domestic account number.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment is completed – The consumer’s name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment is completed – The consumer’s bank’s BIC / SWIFT code.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n\n        /// <summary>\n        /// The reason why the payment did not succeed. Only available when there's a reason known.\n        /// </summary>\n        public string? FailureReason { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/BankTransferPaymentResponse.cs",
    "content": "using Mollie.Api.Models.Url;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record BankTransferPaymentResponse : PaymentResponse, IJsonOnDeserialized {\n        public required BankTransferPaymentResponseDetails? Details { get; set; }\n\n        /// <summary>\n        /// For bank transfer payments, the _links object will contain some additional URL objects relevant to the payment.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public new required BankTransferPaymentResponseLinks Links { get; set; }\n\n        public void OnDeserialized() {\n            base.Links = Links;\n        }\n    }\n\n    public record BankTransferPaymentResponseDetails {\n        /// <summary>\n        /// The name of the bank the consumer should wire the amount to.\n        /// </summary>\n        public required string BankName { get; set; }\n\n        /// <summary>\n        ///  The IBAN the consumer should wire the amount to.\n        /// </summary>\n        public required string BankAccount { get; set; }\n\n        /// <summary>\n        /// The BIC of the bank the consumer should wire the amount to.\n        /// </summary>\n        public required string BankBic { get; set; }\n\n        /// <summary>\n        /// The reference the consumer should use when wiring the amount. Note you should not apply any formatting here; show\n        /// it to the consumer as-is.\n        /// </summary>\n        public required string TransferReference { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed � The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed � The consumer's bank account. This may be an IBAN, or it may be a\n        /// domestic account number.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed � The consumer's bank's BIC / SWIFT code.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n\n        /// <summary>\n        /// Only available if filled out in the API or by the consumer � The email address which the consumer asked the payment\n        /// instructions to be sent to.\n        /// </summary>\n        public string? BillingEmail { get; set; }\n\n        /// <summary>\n        /// Include a QR code object. Only available for iDEAL, Bancontact and bank transfer payments.\n        /// </summary>\n        public QrCode? QrCode { get; set; }\n    }\n\n    public record BankTransferPaymentResponseLinks : PaymentResponseLinks {\n        /// <summary>\n        /// A link to a hosted payment page where your customer can check the status of their payment.\n        /// </summary>\n        public required UrlLink Status { get; set; }\n\n        /// <summary>\n        /// A link to a hosted payment page where your customer can finish the payment using an alternative payment method also\n        /// activated on your website profile.\n        /// </summary>\n        public required UrlLink PayOnline { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/BelfiusPaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record BelfiusPaymentResponse : PaymentResponse {\n        public required BelfiusPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record BelfiusPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's bank's BIC.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/CreditCardPaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record CreditCardPaymentResponse : PaymentResponse {\n        /// <summary>\n        /// An object with credit card details.\n        /// </summary>\n        public CreditCardPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record CreditCardPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed - Unique alphanumeric representation of card, usable for identifying\n        /// returning customers.\n        /// </summary>\n        public string? CardFingerprint { get; set; }\n\n        /// <summary>\n        /// The last four digits of the card number.\n        /// </summary>\n        public string? CardNumber { get; set; }\n\n        /// <summary>\n        /// The card holder's name.\n        /// </summary>\n        public string? CardHolder { get; set; }\n\n        /// <summary>\n        /// Not always available. – The card's target audience. See the Mollie.Api.Models.Payment.Response.CreditCardAudience\n        /// class for a full list of known values\n        /// </summary>\n        public string? CardAudience { get; set; }\n\n        /// <summary>\n        /// The card's label. Note that not all labels can be acquired through Mollie. See the\n        /// Mollie.Api.Models.Payment.Response.CreditCardLabel class for a full list of known values\n        /// </summary>\n        public string? CardLabel { get; set; }\n\n        /// <summary>\n        /// The ISO 3166-1 alpha-2 country code of the country the card was issued in. For example: BE.\n        /// </summary>\n        public string? CardCountryCode { get; set; }\n\n        /// <summary>\n        /// The expiry date (MM/YY) of the card as displayed on the card.\n        /// </summary>\n        public string? CardExpiryDate { get; set; }\n\n        /// <summary>\n        /// The card type. See the Mollie.Api.Models.Payment.Response.CreditCardFunding class for a full list of known\n        /// values.\n        /// </summary>\n        public string? CardFunding { get; set; }\n\n        /// <summary>\n        /// Only available if the payment succeeded. – The payment's security type. See the\n        /// Mollie.Api.Models.Payment.Response.CreditCardSecurity class for a full list of known values\n        /// </summary>\n        public string? CardSecurity { get; set; }\n\n        /// <summary>\n        /// Only available if the payment succeeded. – The fee region for the payment. See your credit card addendum for\n        /// details. intra-eu for consumer cards from the EU, and other for all other cards. See the\n        /// Mollie.Api.Models.Payment.Response.CreditCardFeeRegion class for a full list of known values\n        /// </summary>\n        public string? FeeRegion { get; set; }\n\n        /// <summary>\n        /// The first6 and last4 digits of the card number.\n        /// </summary>\n        public string? CardMaskedNumber { get; set; }\n\n        /// <summary>\n        /// The outcome of authentication attempted on transactions enforced by 3DS (ie valid only for oneoff and\n        /// first).\n        /// </summary>\n        public string? Card3dsEci { get; set; }\n\n        /// <summary>\n        /// The first6 digit of the card bank identification number.\n        /// </summary>\n        public string? CardBin { get; set; }\n\n        /// <summary>\n        /// The issuer of the Card.\n        /// </summary>\n        public string? CardIssuer { get; set; }\n\n        /// <summary>\n        /// Only available for failed payments. Contains a failure reason code. See the\n        /// Mollie.Api.Models.Payment.Response.CreditCardFailureReason class for a full list of known values\n        /// </summary>\n        public string? FailureReason { get; set; }\n\n        /// <summary>\n        /// A localized message that can be shown to your customer, depending on the failureReason\n        /// </summary>\n        public string? FailureMessage { get; set; }\n\n        /// <summary>\n        /// The wallet used when creating the payment.\n        /// </summary>\n        public string? Wallet { get; set; }\n\n        /// <summary>\n        /// Beta feature: The entrymode of the payment. See the Mollie.Api.Models.Payment.EntryMode class for a full\n        /// list of known values\n        /// </summary>\n        public string? EntryMode { get; set; }\n    }\n\n    /// <summary>\n    /// The card's target audience.\n    /// </summary>\n    public static class CreditCardAudience {\n        public const string Consumer = \"consumer\";\n        public const string Business = \"business\";\n    }\n\n    /// <summary>\n    /// Only available if the payment has been completed – The type of security used during payment processing.\n    /// </summary>\n    public static class CreditCardSecurity {\n        public const string Normal = \"normal\";\n        public const string Secure3D = \"3dsecure\";\n    }\n\n    /// <summary>\n    /// Only available if the payment has been completed – The fee region for the payment: intra-eu for consumer cards from the EU, and\n    /// other for all other cards.\n    /// </summary>\n    public static class CreditCardFeeRegion {\n        public const string AmericanExpress = \"american-express\";\n        public const string AmexIntraEea = \"amex-intra-eea\";\n        public const string CarteBancaire = \"carte-bancaire\";\n        public const string IntraEu = \"intra-eu\";\n        public const string IntraEuCorporate = \"intra-eu-corporate\";\n        public const string Domestic  = \"domestic\";\n        public const string Maestro = \"maestro\";\n        public const string Other = \"other\";\n    }\n\n    /// <summary>\n    /// Only available for failed payments. Contains a failure reason code.\n    /// </summary>\n    public static class CreditCardFailureReason {\n        public const string InvalidCardNumber = \"invalid_card_number\";\n        public const string InvalidCvv = \"invalid_cvv\";\n        public const string InvalidCardHolderName = \"invalid_card_holder_name\";\n        public const string CardExpired = \"card_expired\";\n        public const string CardDeclined = \"card_declined\";\n        public const string InvalidCardType = \"invalid_card_type\";\n        public const string RefusedByIssuer = \"refused_by_issuer\";\n        public const string InsufficientFunds = \"insufficient_funds\";\n        public const string InactiveCard = \"inactive_card\";\n        public const string UnknownReason = \"unknown_reason\";\n        public const string PossibleFraud = \"possible_fraud\";\n        public const string AuthenticationFailed = \"authentication_failed\";\n        public const string AuthenticationRequired = \"authentication_required\";\n        public const string AuthenticationAbandoned = \"authentication_abandoned\";\n        public const string AuthenticationUnavailableAcs = \"authentication_unavailable_acs\";\n    }\n\n    /// <summary>\n    /// The card's label. Note that not all labels can be acquired through Mollie.\n    /// </summary>\n    public static class CreditCardLabel {\n        public const string AmericanExpress = \"American Express\";\n        public const string CartaSi = \"Carta si\";\n        public const string CarteBleue = \"Carte Bleue\";\n        public const string Dankort = nameof(Dankort);\n        public const string DinersClub = \"Diners Club\";\n        public const string Discover = nameof(Discover);\n        public const string Jcb = \"JCB\";\n        public const string Laser = nameof(Laser);\n        public const string Maestro = nameof(Maestro);\n        public const string Mastercard = nameof(Mastercard);\n        public const string Unionpay = nameof(Unionpay);\n        public const string Visa = nameof(Visa);\n        public const string Vpay = nameof(Vpay);\n    }\n\n    /// <summary>\n    /// The card type.\n    /// </summary>\n    public static class CreditCardFunding {\n        public const string Debit = \"debit\";\n        public const string Credit = \"credit\";\n        public const string Prepaid = \"prepaid\";\n        public const string DeferredDebit = \"deferred-debit\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/EpsPaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record EpsPaymentResponse : PaymentResponse {\n        /// <summary>\n        /// An object with the consumer bank account details.\n        /// </summary>\n        public required EpsPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record EpsPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's bank's BIC.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/GiftcardPaymentResponse.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record GiftcardPaymentResponse : PaymentResponse {\n        /// <summary>\n        /// An object with payment details.\n        /// </summary>\n        public required GiftcardPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record GiftcardPaymentResponseDetails {\n        /// <summary>\n        /// The voucher number, with the last four digits masked. When multiple gift cards are used, this is the first voucher\n        /// number. Example: 606436353088147****.\n        /// </summary>\n        public string? VoucherNumber { get; set; }\n\n        /// <summary>\n        /// A list of details of all giftcards that are used for this payment. Each object will contain the following properties.\n        /// </summary>\n        public List<Giftcard>? Giftcards { get; set; }\n\n        /// <summary>\n        /// Only available if another payment method was used to pay the remainder amount – The amount that was paid with\n        /// another payment method for the remainder amount.\n        /// </summary>\n        public Amount? RemainderAmount { get; set; }\n\n        /// <summary>\n        /// Only available if another payment method was used to pay the remainder amount – The payment method that was used to\n        /// pay the remainder amount.\n        /// </summary>\n        public string? RemainderMethod { get; set; }\n    }\n\n    public record Giftcard {\n        /// <summary>\n        /// The ID of the gift card brand that was used during the payment.\n        /// </summary>\n        public required string Issuer { get; set; }\n\n        /// <summary>\n        /// The amount in EUR that was paid with this gift card.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The voucher number, with the last four digits masked. Example: 606436353088147****\n        /// </summary>\n        public required string VoucherNumber { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/GiropayPaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record GiropayPaymentResponse : PaymentResponse {\n        /// <summary>\n        /// An object with the consumer bank account details.\n        /// </summary>\n        public required GiropayPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record GiropayPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's bank's BIC.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/IdealPaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record IdealPaymentResponse : PaymentResponse {\n        /// <summary>\n        /// An object with the consumer bank account details.\n        /// </summary>\n        public required IdealPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record IdealPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's bank's BIC.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n\n        /// <summary>\n        /// Include a QR code object. Only available for iDEAL, Bancontact and bank transfer payments.\n        /// </summary>\n        public QrCode? QrCode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/IngHomePayPaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record IngHomePayPaymentResponse : PaymentResponse {\n        /// <summary>\n        /// An object with payment details.\n        /// </summary>\n        public required IngHomePayPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record IngHomePayPaymentResponseDetails {\n        /// <summary>\n        /// Only available one banking day after the payment has been completed – The consumer’s name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available one banking day after the payment has been completed – The consumer’s IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available one banking day after the payment has been completed – BBRUBEBB.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/KbcPaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record KbcPaymentResponse : PaymentResponse {\n        public required KbcPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record KbcPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer's bank's BIC.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/PayPalPaymentResponse.cs",
    "content": "using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record PayPalPaymentResponse : PaymentResponse {\n        public PayPalPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record PayPalPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer’s first and last name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed – The consumer’s email address.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// PayPal’s reference for the transaction, for instance 9AL35361CF606152E.\n        /// </summary>\n        [JsonPropertyName(\"paypalReference\")]\n        public string? PayPalReference { get; set; }\n\n        /// <summary>\n        /// ID for the consumer's PayPal account, for instance WDJJHEBZ4X2LY.\n        /// </summary>\n        public string? PaypalPayerId { get; set; }\n\n        /// <summary>\n        /// Indicates if the payment is eligible for PayPal's Seller Protection. This parameter is omitted if we did not\n        /// received the information from PayPal. See the Mollie.Api.Models.Payment.Response.PayPalSellerProtection class\n        /// for a full list of known values.\n        /// </summary>\n        public string? SellerProtection { get; set; }\n\n        /// <summary>\n        /// The shipping address details.\n        /// </summary>\n        public AddressObject? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// The amount of fee PayPal will charge for this transaction. This field is omitted if PayPal will not charge a fee\n        /// for this transaction.\n        /// </summary>\n        public Amount? PaypalFee { get; set; }\n    }\n\n    public static class PayPalSellerProtection {\n        public const string Eligible = nameof(Eligible);\n        public const string Ineligible = nameof(Ineligible);\n        public const string PartiallyEligibleInrOnly = \"Partially Eligible - INR Only\";\n        public const string PartiallyEligibleUnauthOnly = \"Partially Eligible - Unauth Only\";\n        public const string PartiallyEligible = nameof(PartiallyEligible);\n        public const string None = nameof(None);\n        public const string ActiveFraudControlUnauthPremiumEligible = \"Active Fraud Control - Unauth Premium Eligible\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/PaySafeCardPaymentResponse.cs",
    "content": "namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record PaySafeCardPaymentResponse : PaymentResponse {\n        public required PaySafeCardPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record PaySafeCardPaymentResponseDetails {\n        /// <summary>\n        /// The consumer identification supplied when the payment was created.\n        /// </summary>\n        public string? CustomerReference { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/PointOfSalePaymentResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters;\n\npublic record PointOfSalePaymentResponse : PaymentResponse {\n    /// <summary>\n    /// An object with payment details.\n    /// </summary>\n    public required PointOfSalePaymentResponseDetails? Details { get; set; }\n}\n\npublic record PointOfSalePaymentResponseDetails {\n    /// <summary>\n    /// The identifier referring to the terminal this payment was created for. For example, term_utGtYu756h.\n    /// </summary>\n    public required string TerminalId { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed - The last four digits of the card number.\n    /// </summary>\n    public string? CardNumber { get; set; }\n\n    /// <summary>\n    /// The first 6 digits &amp; last 4 digits of the customer's masked card number.\n    /// </summary>\n    public string? MaskedNumber { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed - Unique alphanumeric representation of card, usable for\n    /// identifying returning customers.\n    /// </summary>\n    public string? CardFingerprint { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed and if the data is available - The card’s target audience.\n    ///\n    /// Check the Mollie.Api.Models.Payment.Response.CreditCardAudience class for a full list of known values.\n    /// </summary>\n    public string? CardAudience { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed - The card’s label. Note that not all labels can be\n    /// processed through Mollie.\n    ///\n    ///  Check the Mollie.Api.Models.Payment.Response.CreditCardLabel class for a full list of known values.\n    /// </summary>\n    public string? CardLabel { get; set; }\n\n    /// <summary>\n    /// The card funding type, if known. Possible values: credit, debit\n    /// </summary>\n    public string? CardFunding { get; set; }\n\n    /// <summary>\n    /// Only available if the payment has been completed - The ISO 3166-1 alpha-2 country code of the country\n    /// the card was issued in. For example: BE.\n    /// </summary>\n    public string? CardCountryCode { get; set; }\n\n    /// <summary>\n    /// The applicable card fee region. For example, intra-eea applies to consumer cards from the European Economic\n    /// Area (EEA). See the Mollie.Api.Models.Payment.Response.CreditCardFeeRegion class for a full list of known values\n    /// </summary>\n    public string? FeeRegion { get; set; }\n\n    /// <summary>\n    /// The Point of sale receipt object.\n    /// </summary>\n    public PointOfSaleReceipt? Receipt { get; set; }\n\n    /// <summary>\n    /// Beta feature: The entrymode of the payment. See the Mollie.Api.Models.Payment.EntryMode class for a full\n    /// list of known values\n    /// </summary>\n    public string? EntryMode { get; set; }\n}\n\npublic record PointOfSaleReceipt {\n    /// <summary>\n    /// A unique code provided by the cardholder’s bank to confirm that the transaction was successfully approved.\n    /// </summary>\n    public string? AuthorizationCode { get; set; }\n\n    /// <summary>\n    /// The unique number that identifies a specific payment application on a chip card.\n    /// </summary>\n    public string? ApplicationIdentifier { get; set; }\n\n    /// <summary>\n    /// The method by which the card was read by the terminal.\n    /// See the Mollie.Api.Models.Payment.Response.PaymentSpecificParameters.CardReadMethod class for a full list of known values\n    /// </summary>\n    public string? CardReadMethod { get; set; }\n\n    /// <summary>\n    /// The method used to verify the cardholder's identity.\n    /// See the Mollie.Api.Models.Payment.Response.PaymentSpecificParameters.CardVerificationMethod class for a full list of known values\n    /// </summary>\n    public string? CardVerificationMethod { get; set; }\n}\n\n/// <summary>\n/// The method by which the card was read by the terminal.\n/// </summary>\npublic static class CardReadMethod {\n    public const string IntegratedCircuitCard = \"integrated-circuit-card\";\n    public const string MagneticStripeReader = \"magnetic-stripe-reader\";\n    public const string NearFieldCommunication = \"near-field-communication\";\n    public const string Contactless  = \"contactless \";\n    public const string Manual  = \"manual \";\n}\n\n/// <summary>\n/// the method used to verify the cardholder's identity.\n/// </summary>\npublic static class CardVerificationMethod {\n    public const string NoCvmRequired = \"no-cvm-required\";\n    public const string OnlinePin = \"online-pin\";\n    public const string Signature = \"signature\";\n    public const string SignatureAndOnlinePin = \"signature-and-online-pin\";\n    public const string OnlinePinAndSignature = \"online-pin-and-signature\";\n    public const string None = \"none\";\n    public const string Failed = \"failed\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/SepaDirectDebitResponse.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record SepaDirectDebitResponse : PaymentResponse {\n        public required SepaDirectDebitResponseDetails? Details { get; set; }\n    }\n\n    public record SepaDirectDebitResponseDetails {\n        /// <summary>\n        /// Transfer reference used by Mollie to identify this payment.\n        /// </summary>\n        public string? TransferReference { get; set; }\n\n        /// <summary>\n        /// The creditor identifier indicates who is authorized to execute the payment. In this case, it is a reference to\n        /// Mollie.\n        /// </summary>\n        public string? CreditorIdentifier { get; set; }\n\n        /// <summary>\n        /// Optional – The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Optional – The consumer's IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Optional – The consumer's bank's BIC.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n\n        /// <summary>\n        /// Estimated date the payment is debited from the consumer's bank account, in YYYY-MM-DD format.\n        /// </summary>\n        public string? DueDate { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been verified – Date the payment has been signed by the consumer, in YYYY-MM-DD format.\n        /// format.\n        /// </summary>\n        public string? SignatureDate { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has failed – The official reason why this payment has failed. A detailed description\n        /// of each reason is available on the website of the European Payments Council.\n        /// </summary>\n        public string? BankReasonCode { get; set; }\n\n        /// <summary>\n        ///     Only available if the payment has failed – A textual desciption of the failure reason.\n        /// </summary>\n        public string? BankReason { get; set; }\n\n        /// <summary>\n        ///     Only available for batch transactions – The original end-to-end identifier that you've specified in your batch.\n        /// </summary>\n        public string? EndToEndIdentifier { get; set; }\n\n        /// <summary>\n        ///     Only available for batch transactions – The original mandate reference that you've specified in your batch.\n        /// </summary>\n        public string? MandateReference { get; set; }\n\n        /// <summary>\n        ///     Only available for batch transactions – The original batch reference that you've specified in your batch.\n        /// </summary>\n        public string? BatchReference { get; set; }\n\n        /// <summary>\n        ///     Only available for batch transactions – The original file reference that you've specified in your batch.\n        /// </summary>\n        public string? FileReference { get; set; }\n\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/PaymentSpecificParameters/SofortPaymentResponse.cs",
    "content": "namespace Mollie.Api.Models.Payment.Response.PaymentSpecificParameters {\n    public record SofortPaymentResponse : PaymentResponse {\n        public required SofortPaymentResponseDetails? Details { get; set; }\n    }\n\n    public record SofortPaymentResponseDetails {\n        /// <summary>\n        /// Only available if the payment has been completed - The consumer's name.\n        /// </summary>\n        public string? ConsumerName { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed - The consumer's IBAN.\n        /// </summary>\n        public string? ConsumerAccount { get; set; }\n\n        /// <summary>\n        /// Only available if the payment has been completed - The consumer's bank's BIC.\n        /// </summary>\n        public string? ConsumerBic { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/Response/QrCode.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment.Response {\n    public record QrCode {\n        /// <summary>\n        ///     Height of the image in pixels.\n        /// </summary>\n        public required int Height { get; set; }\n\n        /// <summary>\n        ///     Width of the image in pixels.\n        /// </summary>\n        public required int Width { get; set; }\n\n        /// <summary>\n        ///     The URI you can use to display the QR code. Note that we can send both data URIs as well as links to HTTPS images.\n        ///     You should support both.\n        /// </summary>\n        public required string Src { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/RoutingDestination.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment\n{\n    public record RoutingDestination\n    {\n        /// <summary>\n        /// The type of destination. Currently only the destination type organization is supported.\n        /// </summary>\n        public required string Type { get; set; }\n\n        /// <summary>\n        /// Required for destination type organization.The ID of the connected organization the funds should be routed\n        /// to, for example org_12345. Please note that me or the ID of the current organization are not accepted as an\n        /// organizationId. After all portions of the total payment amount have been routed, the amount left will be\n        /// routed to the current organization automatically.\n        /// </summary>\n        public string? OrganizationId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Payment/SequenceType.cs",
    "content": "﻿namespace Mollie.Api.Models.Payment {\n    public static class SequenceType {\n        public const string OneOff = \"oneoff\";\n        public const string First = \"first\";\n        public const string Recurring = \"recurring\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentLink/Request/PaymentLinkRequest.cs",
    "content": "﻿using Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\nusing System;\nusing System.Collections.Generic;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Models.PaymentLink.Request {\n    public record PaymentLinkRequest : ITestModeRequest, IProfileRequest\n    {\n        /// <summary>\n        /// This description will also be used as the payment description and will be shown to your customer on their card or bank\n        /// statement when possible.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// The amount that you want to charge, e.g. {\"currency\":\"EUR\", \"value\":\"1000.00\"} if you would want to charge €1000.00.\n        /// </summary>\n        public Amount? Amount { get; set; }\n\n        /// <summary>\n        /// The minimum amount of the payment link. This property is only allowed when there is no amount provided.\n        /// The customer will be prompted to enter a value greater than or equal to the minimum amount.\n        /// </summary>\n        public Amount? MinimumAmount { get; set; }\n\n        /// <summary>\n        /// Optional - The URL your customer will be redirected to after completing the payment process.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// Set the webhook URL, where we will send payment status updates to.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Optionally provide the order lines for the payment. Each line contains details such as a description of the item ordered and its price.\n        /// All lines must have the same currency as the payment.\n        /// </summary>\n        public List<PaymentLine>? Lines { get; set; }\n\n        /// <summary>\n        /// The customer's billing address details. We advise to provide these details to improve fraud protection and conversion.\n        /// </summary>\n        public PaymentAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The customer's shipping address details. We advise to provide these details to improve fraud protection and conversion.\n        /// </summary>\n        public PaymentAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        ///\tOauth only - The website profile’s unique identifier, for example pfl_3RkSN1zuPE. This field is mandatory.\n        /// </summary>\n        public string? ProfileId { get; set; }\n\n        /// <summary>\n        /// Indicates whether the payment link is reusable. If this field is set to true, customers can make multiple\n        /// payments using the same link. If no value is specified, the field defaults to false, allowing only a single\n        /// payment per link.\n        /// </summary>\n        public bool? Reusable { get; set; }\n\n        /// <summary>\n        /// The expiry date of the payment link in ISO 8601 format. For example: 2021-12-24T12:00:16+01:00.\n        /// </summary>\n        [JsonConverter(typeof(Iso8601DateTimeConverter))]\n        public DateTime? ExpiresAt { get; set; }\n\n        /// <summary>\n        /// An array of payment methods that are allowed to be used for this payment link. When this parameter is not\n        /// provided or is an empty array, all enabled payment methods will be available.\n        /// See the Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        public IEnumerable<string>? AllowedMethods { get; set; }\n\n        /// <summary>\n        /// With Mollie Connect you can charge fees on payment links that your app is processing on behalf of other\n        /// Mollie merchants.\n        ///\n        /// If you use OAuth to create payment links on a connected merchant's account, you can charge\n        /// a fee using this applicationFee parameter. If a payment on the payment link succeeds, the fee will be\n        /// deducted from the merchant's balance and sent to your own account balance.\n        /// </summary>\n        public ApplicationFee? ApplicationFee { get; set; }\n\n        /// <summary>\n        /// If set to first, a payment mandate is established right after a payment is made by the customer.\n        /// Defaults to oneoff, which is a regular payment link and will not establish a mandate after payment.\n        /// The mandate ID can be retrieved by making a call to the Payment Link Payments Endpoint.\n        /// See the Mollie.Api.Models.Payment.SequenceType class for a full list of known values.\n        /// </summary>\n        public string? SequenceType { get; set; }\n\n        /// <summary>\n        /// The ID of the customer the payment link is being created for. If a value is not provided, the customer\n        /// will be required to input relevant information which will be used to establish a mandate after the payment\n        /// is made.\n        /// </summary>\n        public string? CustomerId { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to only retrieve payment links made in test mode. By default, only\n        /// live payment links are returned.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public override string ToString() {\n            return $\"Amount: {Amount} - Description: {Description}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentLink/Request/PaymentLinkUpdateRequest.cs",
    "content": "﻿using System.Collections.Generic;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Models.PaymentLink.Request;\n\npublic record PaymentLinkUpdateRequest : ITestModeRequest {\n    /// <summary>\n    /// A short description of the payment link. The description is visible in the Dashboard and will be shown on the\n    /// customer's bank or card statement when possible.\n    ///\n    /// Updating the description does not affect any previously existing payments created for this payment link.\n    /// </summary>\n    public required string Description { get; set; }\n\n    /// <summary>\n    /// The minimum amount of the payment link. This property is only allowed when there is no amount provided.\n    /// The customer will be prompted to enter a value greater than or equal to the minimum amount.\n    /// </summary>\n    public Amount? MinimumAmount { get; set; }\n\n    /// <summary>\n    /// Whether the payment link is archived. Customers will not be able to complete payments on archived payment links.\n    /// </summary>\n    public required bool Archived { get; set; }\n\n    /// <summary>\n    /// An array of payment methods that are allowed to be used for this payment link. When this parameter is not\n    /// provided or is an empty array, all enabled payment methods will be available.\n    /// See the Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n    /// </summary>\n    public IEnumerable<string>? AllowedMethods { get; set; }\n\n    /// <summary>\n    /// Optionally provide the order lines for the payment. Each line contains details such as a description of the item ordered and its price.\n    /// All lines must have the same currency as the payment.\n    /// </summary>\n    public List<PaymentLine>? Lines { get; set; }\n\n    /// <summary>\n    /// The customer's billing address details. We advise to provide these details to improve fraud protection and conversion.\n    /// </summary>\n    public PaymentAddressDetails? BillingAddress { get; set; }\n\n    /// <summary>\n    /// The customer's shipping address details. We advise to provide these details to improve fraud protection and conversion.\n    /// </summary>\n    public PaymentAddressDetails? ShippingAddress { get; set; }\n\n    /// <summary>\n    ///\tOauth only - Optional – Most API credentials are specifically created for either live mode or test mode.\n    /// For organization-level credentials such as OAuth access tokens, you can enable test mode by setting testmode\n    /// to true.\n    ///\n    /// Test entities cannot be retrieved when the endpoint is set to live mode, and vice versa.\n    /// </summary>\n    public bool? Testmode { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentLink/Response/PaymentLinkResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Mollie.Api.Models.Payment;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.PaymentLink.Response\n{\n    public record PaymentLinkResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a payment object. Will always contain payment-link for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The identifier uniquely referring to this payment link. Mollie assigns this identifier at creation time.\n        /// For example pl_4Y0eZitmBnQ6IDoMqZQKh. Its ID will always be used by Mollie to refer to a certain payment link.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The mode used to create this payment link. Mode determines whether a payment link is real (live mode) or a test payment link.\n        /// </summary>\n        public Mode Mode { get; set; }\n\n        /// <summary>\n        /// A short description of the payment link. The description is visible in the Dashboard and will be shown on the\n        /// customer’s bank or card statement when possible. This description will eventual been used as payment description.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// The amount of the payment link, e.g. {\"currency\":\"EUR\", \"value\":\"100.00\"} for a €100.00 payment link.\n        /// </summary>\n        public Amount? Amount { get; set; }\n\n        /// <summary>\n        /// The minimum amount of the payment link. This property is only allowed when there is no amount provided.\n        /// The customer will be prompted to enter a value greater than or equal to the minimum amount.\n        /// </summary>\n        public Amount? MinimumAmount { get; set; }\n\n        /// <summary>\n        /// Whether the payment link is archived. Customers will not be able to complete payments on archived payment links.\n        /// </summary>\n        public required bool Archived { get; set; }\n\n        /// <summary>\n        /// The URL your customer will be redirected to after completing the payment process.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The URL Mollie will call as soon an important status change takes place.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Optionally provide the order lines for the payment. Each line contains details such as a description of the item ordered and its price.\n        /// All lines must have the same currency as the payment.\n        /// </summary>\n        public List<PaymentLine>? Lines { get; set; }\n\n        /// <summary>\n        /// The customer's billing address details. We advise to provide these details to improve fraud protection and conversion.\n        /// </summary>\n        public PaymentAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The customer's shipping address details. We advise to provide these details to improve fraud protection and conversion.\n        /// </summary>\n        public PaymentAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// The identifier referring to the profile this payment link was created on. For example, pfl_QkEhN94Ba.\n        /// </summary>\n        public string? ProfileId { get; set; }\n\n        /// <summary>\n        /// Indicates whether the payment link is reusable. If this field is set to true, customers can make multiple\n        /// payments using the same link. If no value is specified, the field defaults to false, allowing only a single\n        /// payment per link.\n        /// </summary>\n        public bool? Reusable { get; set; }\n\n        /// <summary>\n        /// The payment link’s date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public DateTime? CreatedAt { get; set; }\n\n        /// <summary>\n        /// The date and time the payment link became paid, in ISO 8601 format.\n        /// </summary>\n        public DateTime? PaidAt { get; set; }\n\n        /// <summary>\n        /// The date and time the payment link last status change, in ISO 8601 format.\n        /// </summary>\n        public DateTime? UpdatedAt { get; set; }\n\n        /// <summary>\n        /// The expiry date and time of the payment link, in ISO 8601 format.\n        /// </summary>\n        public DateTime? ExpiresAt { get; set; }\n\n        /// <summary>\n        /// An array of payment methods that are allowed to be used for this payment link. When this parameter is not\n        /// provided or is an empty array, all enabled payment methods will be available.\n        /// See the Mollie.Api.Models.Payment.PaymentMethod class for a full list of known values.\n        /// </summary>\n        public IEnumerable<string>? AllowedMethods { get; set; }\n\n        /// <summary>\n        /// With Mollie Connect you can charge fees on payment links that your app is processing on behalf of other\n        /// Mollie merchants.\n        ///\n        /// If you use OAuth to create payment links on a connected merchant's account, you can charge\n        /// a fee using this applicationFee parameter. If a payment on the payment link succeeds, the fee will be\n        /// deducted from the merchant's balance and sent to your own account balance.\n        /// </summary>\n        public ApplicationFee? ApplicationFee { get; set; }\n\n        /// <summary>\n        /// If set to first, a payment mandate is established right after a payment is made by the customer.\n        /// Defaults to oneoff, which is a regular payment link and will not establish a mandate after payment.\n        /// The mandate ID can be retrieved by making a call to the Payment Link Payments Endpoint.\n        /// See the Mollie.Api.Models.Payment.SequenceType class for a full list of known values.\n        /// </summary>\n        public string? SequenceType { get; set; }\n\n        /// <summary>\n        /// Only relevant when sequenceType is set to first. The ID of the customer the payment link is being created\n        /// for. If a value is not provided, the customer will be required to input relevant information which will\n        /// be used to establish a mandate after the payment\n        /// is made.\n        /// </summary>\n        public string? CustomerId { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the payment. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required PaymentLinkResponseLinks Links { get; set; }\n\n        public override string ToString()\n        {\n            return $\"Id: {Id} - Description: {Description} - Amount: {Amount}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentLink/Response/PaymentLinkResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.PaymentLink.Response {\n    public record PaymentLinkResponseLinks {\n        /// <summary>\n        /// The API resource URL of the payment link itself.\n        /// </summary>\n        public required UrlObjectLink<PaymentLinkResponse> Self { get; set; }\n\n        /// <summary>\n        /// Direct link to the payment link.\n        /// </summary>\n        public required UrlLink PaymentLink { get; set; }\n\n        /// <summary>\n        ///The URL to the payment link retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentMethod/Response/FixedPricingResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.PaymentMethod.Response\n{\n    public record FixedPricingResponse {\n        /// <summary>\n        /// The ISO 4217 currency code.\n        /// </summary>\n        public required string Currency { get; set; }\n\n        /// <summary>\n        /// A string containing the exact amount in the given currency.\n        /// </summary>\n        [JsonConverter(typeof(StringToDecimalConverter))]\n        public required decimal Value { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentMethod/Response/PaymentMethodResponse.cs",
    "content": "﻿using System.Collections.Generic;\nusing Mollie.Api.Models.Issuer.Response;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.PaymentMethod.Response {\n    public record PaymentMethodResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a method object. Will always contain method for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The unique identifier of the payment method. When used during payment creation, the payment method selection screen will be skipped.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The full name of the payment method.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// Minimum payment amount required to use this payment method.\n        /// </summary>\n        public required Amount MinimumAmount { get; set; }\n\n        /// <summary>\n        /// Maximum payment amount allowed when using this payment method. (Could be null)\n        /// </summary>\n        public required Amount MaximumAmount { get; set; }\n\n        /// <summary>\n        /// URLs of images representing the payment method.\n        /// </summary>\n        public required PaymentMethodResponseImage Image { get; set; }\n\n        /// <summary>\n        /// The payment method's activation status for this profile.\n        /// See the <see cref=\"PaymentMethodStatus\"/> class for possible values.\n        /// </summary>\n        public string? Status { get; set; }\n\n\t\t/// <summary>\n\t\t///\tList of Issuers\n\t\t/// </summary>\n\t\tpublic List<IssuerResponse>? Issuers { get; set; }\n\n        /// <summary>\n        /// Pricing set of the payment method what will be include if you add the parameter.\n        /// </summary>\n        public List<PricingResponse>? Pricing { get; set; }\n\n\t\t/// <summary>\n\t\t/// An object with several URL objects relevant to the payment method. Every URL object will contain an href and a type field.\n\t\t/// </summary>\n\t\t[JsonPropertyName(\"_links\")]\n        public required PaymentMethodResponseLinks Links { get; set; }\n\n        public override string ToString() {\n            return Description;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentMethod/Response/PaymentMethodResponseImage.cs",
    "content": "﻿namespace Mollie.Api.Models.PaymentMethod.Response {\n    /// <summary>\n    /// URLs of images representing the payment method.\n    /// </summary>\n    public record PaymentMethodResponseImage {\n        /// <summary>\n        /// The URL for a payment method icon of 55x37 pixels.\n        /// </summary>\n        public required string Size1x { get; set; }\n\n        /// <summary>\n        /// The URL for a payment method icon of 110x74 pixels. Use this for high resolution screens.\n        /// </summary>\n        public required string Size2x { get; set; }\n\n        /// <summary>\n        /// The URL for a payment method icon in vector format. Usage of this format is preferred since it can scale to any desired size.\n        /// </summary>\n        public required string Svg { get; set; }\n\n        public override string ToString() {\n            return Size1x;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentMethod/Response/PaymentMethodResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.PaymentMethod.Response {\n    public record PaymentMethodResponseLinks {\n        /// <summary>\n        /// The API resource URL of the payment method itself.\n        /// </summary>\n        public required UrlObjectLink<PaymentMethodResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL to the payment method retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentMethod/Response/PaymentMethodStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.PaymentMethod.Response;\n\n/// <summary>\n/// The payment method's activation status for this profile.\n/// </summary>\npublic static class PaymentMethodStatus {\n    public const string Activated = \"activated\";\n    public const string PendingBoarding = \"pending-boarding\";\n    public const string PendingReview = \"pending-review\";\n    public const string PendingExternal = \"pending-external\";\n    public const string Rejected = \"rejected\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/PaymentMethod/Response/PricingResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.PaymentMethod.Response\n{\n    public record PricingResponse {\n        /// <summary>\n        /// The area or product-type where the pricing is applied for, translated in the optional locale passed.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// The fixed price per transaction\n        /// </summary>\n        public required FixedPricingResponse Fixed { get; set; }\n\n        /// <summary>\n        /// A string containing the percentage what will be charged over the payment amount besides the fixed price.\n        /// </summary>\n        [JsonConverter(typeof(StringToDecimalConverter))]\n        public required decimal Variable { get; set; }\n\n        /// <summary>\n        /// This value is only available for credit card rates. It will correspond with the regions as documented in\n        /// the Payments API. See the Mollie.Api.Models.Payment.Response.CreditCardFeeRegion class for a full list of\n        /// known values.\n        /// </summary>\n        public required string? FeeRegion { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Permission/Response/PermissionResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Permission.Response {\n    public record PermissionResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a permission object.\n        /// Possible values: permission\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The permission's identifier. See OAuth: Permissions for more details about the available permissions.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// A short description of what the permission allows.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// Whether this permission is granted to the app by the organization or not.\n        /// </summary>\n        public bool Granted { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the permission. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required PermissionResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Permission/Response/PermissionResponseLInks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Permission.Response {\n    public record PermissionResponseLinks {\n        /// <summary>\n        /// The API resource URL of the permission itself.\n        /// </summary>\n        public required UrlObjectLink<PermissionResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL to the permission retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/ProfileStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Profile {\n    public static class ProfileStatus {\n        public const string Unverified = \"unverified\";\n        public const string Verified = \"verified\";\n        public const string Blocked = \"blocked\";\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/Request/ProfileRequest.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Profile.Request {\n    public record ProfileRequest {\n        /// <summary>\n        /// The profile's name should reflect the tradename or brand name of the profile's website or application.\n        /// </summary>\n        public required string Name { get; set; }\n\n        /// <summary>\n        /// The URL to the profile's website or application. The URL should start with http:// or https://.\n        /// </summary>\n        public required string Website { get; set; }\n\n        /// <summary>\n        /// The email address associated with the profile's tradename or brand.\n        /// </summary>\n        public required string Email { get; set; }\n\n        /// <summary>\n        /// The phone number associated with the profile's tradename or brand.\n        /// </summary>\n        public required string Phone { get; set; }\n\n        /// <summary>\n        /// The products or services that the profile’s website offers.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The list of countries where you expect that the majority of the profile’s customers will live, in ISO 3166-1 alpha-2 format.\n        /// </summary>\n        public IEnumerable<string>? CountriesOfActivity { get; set; }\n\n        /// <summary>\n        /// The industry associated with the profile’s trade name or brand. Please refer to the documentation of the business category\n        /// for more information on which values are accepted.\n        /// </summary>\n        public string? BusinessCategory { get; set; }\n\n        /// <summary>\n        /// Optional – Creating a test profile by setting this parameter to test, enables you to start using the API without\n        /// having to provide all your business info just yet. Defaults to live.\n        /// </summary>\n        public Mode? Mode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/Response/ApiKey.cs",
    "content": "﻿using System;\n\nnamespace Mollie.Api.Models.Profile.Response {\n    public record ApiKey {\n        /// <summary>\n        ///     Indicates the response contains an API key object.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        ///     The API key's identifier.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        ///     The actual API key, which you'll use when creating payments or when otherwise communicating with the API. Never\n        ///     share the API key with anyone.\n        /// </summary>\n        public required string Key { get; set; }\n\n        /// <summary>\n        ///     The API key's date and time of creation.\n        /// </summary>\n        public DateTime CreatedDatetime { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/Response/EnableGiftCardIssuerResponse.cs",
    "content": "﻿using System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Profile.Response {\n    public record EnableGiftCardIssuerResponse {\n        /// <summary>\n        /// Indicates the response contains an issuer object. Will always contain issuer for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The unique identifier of the gift card issuer.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The full name of the gift card issuer.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// The status that the issuer is in. Possible values: pending-issuer or activated.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the order. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required EnableGiftCardIssuerResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/Response/EnableGiftCardIssuerResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Profile.Response {\n    public record EnableGiftCardIssuerResponseLinks {\n        /// <summary>\n        /// The API resource URL of the gift card issuer itself.\n        /// </summary>\n        public required UrlLink Self { get; set; }\n\n        /// <summary>\n        /// The URL to the gift card issuer retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/Response/EnableGiftCardIssuerStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Profile.Response {\n    /// <summary>\n    /// The status that the issuer is in. Possible values: pending-issuer or activated.\n    /// </summary>\n    public static class EnableGiftCardIssuerStatus {\n        /// <summary>\n        /// The issuer is activated and ready for use.\n        /// </summary>\n        public const string Activated = \"activated\";\n\n        /// <summary>\n        /// Activation of this issuer relies on you taking action with the issuer itself.\n        /// </summary>\n        public const string PendingIssuer = \"pending-issuer\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/Response/ProfileResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Profile.Response {\n    public record ProfileResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a profile object. Will always contain profile for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The identifier uniquely referring to this profile, for example pfl_v9hTwCvYqw.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// Indicates whether the payment profile is in test or production mode.\n        /// Possible values: live or test\n        /// </summary>\n        public Mode Mode { get; set; }\n\n        /// <summary>\n        /// The payment profile's name, this will usually reflect the tradename or brand name of the profile's website or\n        /// application.\n        /// </summary>\n        public required string Name { get; set; }\n\n        /// <summary>\n        /// The URL to the profile's website or application.\n        /// </summary>\n        public required string Website { get; set; }\n\n        /// <summary>\n        /// The products or services that the profile’s website offers.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The list of countries where you expect that the majority of the profile’s customers will live, in ISO 3166-1 alpha-2 format.\n        /// </summary>\n        public IEnumerable<string>? CountriesOfActivity { get; set; }\n\n        /// <summary>\n        /// The email address associated with the profile's tradename or brand.\n        /// </summary>\n        public required string Email { get; set; }\n\n        /// <summary>\n        /// The phone number associated with the profile's tradename or brand.\n        /// </summary>\n        public required string Phone { get; set; }\n\n        /// <summary>\n        /// The industry associated with the profile’s trade name or brand. Please refer to the documentation of the business category\n        /// for more information on which values are accepted.\n        /// </summary>\n        public string? BusinessCategory { get; set; }\n\n        /// <summary>\n        /// The industry associated with the profile's tradename or brand.\n        /// </summary>\n        [Obsolete(\"This parameter is deprecated and will be removed in 2022. Please use the businessCategory parameter instead.\")]\n        public int CategoryCode { get; set; }\n\n        /// <summary>\n        /// The profile status determines whether the payment profile is able to receive live payments. See the\n        /// Mollie.Api.Models.Profile.ProfileStatus class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// The presence of a review object indicates changes have been made that have not yet been approved by Mollie.\n        /// Changes to test profiles are approved automatically, unless a switch to a live profile has been requested.\n        /// The review object will therefore usually be null in test mode.\n        /// </summary>\n        public Review? Review { get; set; }\n\n        /// <summary>\n        /// The payment profile's date and time of creation.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// Useful URLs to related resources.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required ProfileResponseLinks Links { get; set; }\n    }\n\n    public record Review {\n        /// <summary>\n        /// The status of the requested profile changes. See the Mollie.Api.Models.Profile.ReviewStatus\n        /// class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/Response/ProfileResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.PaymentMethod.Response;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Profile.Response {\n    public record ProfileResponseLinks {\n        public required UrlObjectLink<ProfileResponse> Self { get; set; }\n        public required UrlLink Dashboard { get; set; }\n        public UrlObjectLink<ListResponse<ChargebackResponse>>? Chargebacks { get; set; }\n        public UrlObjectLink<ListResponse<PaymentMethodResponse>>? Methods { get; set; }\n        public UrlObjectLink<ListResponse<PaymentResponse>>? Payments { get; set; }\n        public UrlObjectLink<ListResponse<RefundResponse>>? Refunds { get; set; }\n        public UrlLink? CheckoutPreviewUrl { get; set; }\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Profile/ReviewStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Profile {\n    public static class ReviewStatus {\n        /// <summary>\n        /// The changes are pending review. We will review your changes soon.\n        /// </summary>\n        public const string Pending = \"pending\";\n\n        /// <summary>\n        /// We've reviewed and rejected your changes.\n        /// </summary>\n        public const string Rejected = \"rejected\";\n    }\n        \n}"
  },
  {
    "path": "src/Mollie.Api/Models/Refund/Request/RefundRequest.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Refund.Request {\n    public record RefundRequest : ITestModeRequest {\n        /// <summary>\n        /// The amount to refund. For some payments, it can be up to €25.00 more than the original transaction amount.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// Optional – The description of the refund you are creating. This will be shown to the consumer on their card or bank\n        /// statement when possible. Max 140 characters.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, for example a string or a JSON object. We will save the data alongside the refund. Whenever\n        /// you fetch the refund with our API, we’ll also include the metadata. You can use up to approximately 1kB.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// With Mollie Connect you can charge fees on payments that your app is processing on behalf of other Mollie merchants,\n        /// by providing the routing object during payment creation. When creating refunds for these routed payments, by default\n        /// the full amount is deducted from your balance.If you want to pull back the funds that were routed to the connected\n        /// merchant(s), you can set this parameter to true when issuing a full refund. For more fine-grained control and for\n        /// partial refunds, use the routingReversals parameter instead.\n        /// </summary>\n        public bool? ReverseRouting { get; set; }\n\n        /// <summary>\n        /// When creating refunds for routed payments, by default the full amount is deducted from your balance. If you want to\n        /// pull back funds from the connected merchant(s), you can use this parameter to specify what amount needs to be\n        /// reversed from which merchant(s). If you simply want to fully reverse the routed funds, you can also use the\n        /// reverseRouting parameter instead.\n        /// </summary>\n        public IList<RoutingReversal>? RoutingReversals { get; set; }\n\n        /// <summary>\n        /// Set this to true to refund a test mode payment.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Refund/Response/RefundResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Refund.Response {\n    public record RefundResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a refund object. Will always contain refund for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The refund's unique identifier, for example re_4qqhO89gsT.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The description of the refund that may be shown to the consumer, depending on the payment method used.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The amount refunded to the consumer with this refund.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// This optional field will contain the amount that will be deducted from your account balance, converted\n        /// to the currency your account is settled in. It follows the same syntax as the amount property. Note that\n        /// for refunds, the value key of settlementAmount will be negative. Any amounts not settled by Mollie will\n        /// not be reflected in this amount, e.g. PayPal refunds.\n        /// </summary>\n        public Amount? SettlementAmount { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, for example a string or a JSON object. We will save the data alongside the refund. Whenever\n        /// you fetch the refund with our API, we’ll also include the metadata. You can use up to approximately 1kB.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// Since refunds may be delayed for certain payment methods, the refund carries a status field. See the\n        /// Mollie.Api.Models.Refund.RefundStatus class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// With Mollie Connect you can charge fees on payments that your app is processing on behalf of other Mollie merchants,\n        /// by providing the routing object during payment creation. When creating refunds for these routed payments, by default\n        /// the full amount is deducted from your balance.If you want to pull back the funds that were routed to the connected\n        /// merchant(s), you can set this parameter to true when issuing a full refund. For more fine-grained control and for\n        /// partial refunds, use the routingReversals parameter instead.\n        /// </summary>\n        public bool? ReverseRouting { get; set; }\n\n        /// <summary>\n        /// When creating refunds for routed payments, by default the full amount is deducted from your balance. If you want to\n        /// pull back funds from the connected merchant(s), you can use this parameter to specify what amount needs to be\n        /// reversed from which merchant(s). If you simply want to fully reverse the routed funds, you can also use the\n        /// reverseRouting parameter instead.\n        /// </summary>\n        public IList<RoutingReversal>? RoutingReversals { get; set; }\n\n        /// <summary>\n        /// The unique identifier of the payment this refund was created for. For example: tr_7UhSN1zuXS. The full\n        /// payment object can be retrieved via the payment URL in the _links object.\n        /// </summary>\n        public required string PaymentId { get; set; }\n\n        /// <summary>\n        /// The identifier referring to the settlement this payment was settled with. For example, stl_BkEjN2eBb.\n        /// This field is omitted if the refund is not settled (yet).\n        /// </summary>\n        public string? SettlementId { get; set; }\n\n        /// <summary>\n        /// The date and time the refund was issued, in ISO 8601 format.\n        /// </summary>\n        public DateTime? CreatedAt { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the refund. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required RefundResponseLinks Links { get; set; }\n\n        public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n            return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Refund/Response/RefundResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Refund.Response {\n    public record RefundResponseLinks {\n        /// <summary>\n        /// The API resource URL of the refund itself.\n        /// </summary>\n        public required UrlObjectLink<RefundResponse> Self { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the payment the refund belongs to.\n        /// </summary>\n        public required UrlObjectLink<PaymentResponse> Payment { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the settlement this payment has been settled with. Not present if not yet settled.\n        /// </summary>\n        public UrlObjectLink<SettlementResponse>? Settlement { get; set; }\n\n        /// <summary>\n        /// The URL to the refund retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Refund/Response/RefundStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Refund.Response {\n    public static class RefundStatus {\n        public const string Pending = \"pending\";\n        public const string Processing = \"processing\";\n        public const string Refunded = \"refunded\";\n        public const string Queued = \"queued\";\n        public const string Failed = \"failed\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Refund/RoutingReversal.cs",
    "content": "﻿using Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Models.Refund;\n\npublic record RoutingReversal {\n    /// <summary>\n    /// The amount that will be pulled back.\n    /// </summary>\n    public required Amount Amount { get; set; }\n\n    /// <summary>\n    /// Where the funds will be pulled back from.\n    /// </summary>\n    public required RoutingDestination Source { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/EmailDetails.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\npublic record EmailDetails {\n    /// <summary>\n    /// The subject of the email to be sent.\n    /// </summary>\n    public required string Subject { get; set; }\n\n    /// <summary>\n    /// The body of the email to be sent. To add newline characters, you can use \\n.\n    /// </summary>\n    public required string Body { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/PaymentDetails.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\npublic record PaymentDetails {\n    /// <summary>\n    /// The way through which the invoice is to be set to paid. See the\n    /// Mollie.Api.Models.SalesInvoice.PaymentDetailSource class for a full list of known values.\n    /// </summary>\n    public required string Source { get; set; }\n\n    /// <summary>\n    /// A reference to the payment the sales invoice is paid by. Required for source values payment-link and payment.\n    /// </summary>\n    public string? SourceReference { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/PaymentDetailsSource.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\n/// <summary>\n/// The way through which the invoice is to be set to paid.\n/// </summary>\npublic static class PaymentDetailsSource {\n    /// <summary>\n    /// The invoice is to be paid manually.\n    /// </summary>\n    public const string Manual = \"manual\";\n\n    /// <summary>\n    /// The invoice is to be paid through a payment link.\n    /// </summary>\n    public const string PaymentLink = \"payment-link\";\n\n    /// <summary>\n    /// The invoice is to be paid through a payment.\n    /// </summary>\n    public const string Payment = \"payment\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/PaymentTerm.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\n/// <summary>\n/// The payment term to be set on the invoice. Default: 30 days\n/// </summary>\npublic static class PaymentTerm {\n    public const string Days7 = \"7 days\";\n    public const string Days14 = \"14 days\";\n    public const string Days30 = \"30 days\";\n    public const string Days45 = \"45 days\";\n    public const string Days60 = \"60 days\";\n    public const string Days90 = \"90 days\";\n    public const string Days120 = \"120 days\";\n\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/Recipient.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\npublic record Recipient {\n    /// <summary>\n    /// The type of recipient, either consumer or business. This will determine what further fields are required on\n    /// the recipient object. See the Mollie.Api.Models.SalesInvoice.RecipientType class for a full list of known\n    /// values.\n    /// </summary>\n    public required string Type { get; set; }\n\n    /// <summary>\n    /// The title of the consumer type recipient, for example Mr. or Mrs..\n    /// </summary>\n    public string? Title { get; set; }\n\n    /// <summary>\n    /// The given name (first name) of the consumer type recipient should be at least two characters and cannot contain\n    /// only numbers.\n    /// </summary>\n    public string? GivenName { get; set; }\n\n    /// <summary>\n    /// The given name (last name) of the consumer type recipient should be at least two characters and cannot contain\n    /// only numbers.\n    /// </summary>\n    public string? FamilyName { get; set; }\n\n    /// <summary>\n    /// The trading name of the business type recipient.\n    /// </summary>\n    public string? OrganizationName { get; set; }\n\n    /// <summary>\n    /// The Chamber of Commerce number of the organization for a business type recipient. Either this or vatNumber has\n    /// to be provided.\n    /// </summary>\n    public string? OrganizationNumber { get; set; }\n\n    /// <summary>\n    /// The VAT number of the organization for a business type recipient. Either this or organizationNumber has to be\n    /// provided.\n    /// </summary>\n    public string? VatNumber { get; set; }\n\n    /// <summary>\n    /// The email address of the recipient.\n    /// </summary>\n    public required string Email { get; set; }\n\n    /// <summary>\n    /// The phone number of the recipient.\n    /// </summary>\n    public string? Phone { get; set; }\n\n    /// <summary>\n    /// A street and street number.\n    /// </summary>\n    public required string StreetAndNumber { get; set; }\n\n    /// <summary>\n    /// Any additional addressing details, for example an apartment number.\n    /// </summary>\n    public string? StreetAdditional { get; set; }\n\n    /// <summary>\n    /// A postal code.\n    /// </summary>\n    public required string PostalCode { get; set; }\n\n    /// <summary>\n    /// The recipient's city.\n    /// </summary>\n    public required string City { get; set; }\n\n    /// <summary>\n    /// The recipient's region.\n    /// </summary>\n    public string? Region { get; set; }\n\n    /// <summary>\n    /// A country code in ISO 3166-1 alpha-2 format.\n    /// </summary>\n    public required string Country { get; set; }\n\n    /// <summary>\n    /// The locale for the recipient, to be used for translations in PDF generation and payment pages.\n    /// </summary>\n    public required string Locale { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/RecipientType.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\n/// <summary>\n/// The type of recipient, either consumer or business. This will determine what further fields are required on the\n/// recipient object.\n/// </summary>\npublic static class RecipientType {\n    /// <summary>\n    /// The recipient is a consumer.\n    /// </summary>\n    public const string Consumer = \"consumer\";\n\n    /// <summary>\n    /// The recipient is a business.\n    /// </summary>\n    public const string Business = \"business\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/Request/SalesInvoiceRequest.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.SalesInvoice.Request;\n\npublic record SalesInvoiceRequest : ITestModeRequest, IProfileRequest {\n    /// <summary>\n    ///\tWhether to create the entity in test mode or live mode. Most API credentials are specifically created for\n    /// either live mode or test mode, in which case this parameter can be omitted. For organization-level credentials\n    /// such as OAuth access tokens, you can enable test mode by setting testmode to true.\n    /// </summary>\n    public bool? Testmode { get; set; }\n\n    /// <summary>\n    /// The identifier referring to the profile this entity belongs to. Most API credentials are linked to a single\n    /// profile. In these cases the profileId can be omitted in the creation request. For organization-level\n    /// credentials such as OAuth access tokens however, the profileId parameter is required.\n    /// </summary>\n    public string? ProfileId { get; set; }\n\n    /// <summary>\n    /// The status for the invoice to end up in. See the Mollie.Api.Models.SalesInvoice.SalesInvoiceStatus class for\n    /// a full list of known values.\n    /// </summary>\n    public required string Status { get; set; }\n\n    /// <summary>\n    /// The VAT scheme to create the invoice for. You must be enrolled with One Stop Shop enabled to use it. See the\n    /// Mollie.Api.Models.VatScheme class for a full list of known values.\n    /// </summary>\n    public string? VatScheme { get; set; }\n\n    /// <summary>\n    /// The VAT mode to use for VAT calculation. exclusive mode means we will apply the relevant VAT on top of the\n    /// price. inclusive means the prices you are providing to us already contain the VAT you want to apply. See the\n    /// Mollie.Api.Models.VatMode class for a full list of known values.\n    /// </summary>\n    public string? VatMode { get; set; }\n\n    /// <summary>\n    /// A free-form memo you can set on the invoice, and will be shown on the invoice PDF.\n    /// </summary>\n    public string? Memo { get; set; }\n\n    /// <summary>\n    /// Provide any data you like, for example a string or a JSON object. We will save the data alongside the payment. Whenever\n    /// you fetch the payment with our API, we’ll also include the metadata. You can use up to approximately 1kB.\n    /// </summary>\n    [JsonConverter(typeof(RawJsonConverter))]\n    public string? Metadata { get; set; }\n\n    /// <summary>\n    /// The payment term to be set on the invoice. See the Mollie.Api.Models.SalesInvoice.PaymentTerm class for a full\n    /// list of known values.\n    /// </summary>\n    public required string PaymentTerm { get; set; }\n\n    /// <summary>\n    /// Used when setting an invoice to status of paid, and will store a payment that fully pays the invoice with\n    /// the provided details. Required for paid status.\n    /// </summary>\n    public PaymentDetails? PaymentDetails { get; set; }\n\n    /// <summary>\n    /// Used when setting an invoice to status of either issued or paid. Will be used to issue the invoice to the\n    /// recipient with the provided subject and body. Required for issued status.\n    /// </summary>\n    public EmailDetails? EmailDetails { get; set; }\n\n    /// <summary>\n    /// The identifier referring to the customer you want to attempt an automated payment for. If provided,\n    /// mandateId becomes required as well. Only allowed for invoices with status paid.\n    /// </summary>\n    public string? CustomerId { get; set; }\n\n    /// <summary>\n    /// The identifier referring to the mandate you want to use for the automated payment. If provided, customerId\n    /// becomes required as well. Only allowed for invoices with status paid.\n    /// </summary>\n    public string? MandateId { get; set; }\n\n    /// <summary>\n    /// An identifier tied to the recipient data. This should be a unique value based on data your system contains,\n    /// so that both you and us know who we're referring to. It is a value you provide to us so that recipient\n    /// management is not required to send a first invoice to a recipient.\n    /// </summary>\n    public required string RecipientIdentifier { get; set; }\n\n    /// <summary>\n    /// The recipient details\n    /// </summary>\n    public required Recipient Recipient { get; set; }\n\n    /// <summary>\n    /// Provide the line items for the invoice. Each line contains details such as a description of the item ordered\n    /// and its price. All lines must have the same currency as the invoice.\n    /// </summary>\n    public required IEnumerable<SalesInvoiceLine>? Lines { get; set; }\n\n    /// <summary>\n    /// The webhook URL where we will send invoice status updates to. The webhookUrl is optional, but without a webhook\n    /// you will miss out on important status changes to your invoice. The webhookUrl must be reachable from Mollie's\n    /// point of view, so you cannot use localhost. If you want to use webhook during development on localhost, you\n    /// must use a tool like ngrok to have the webhooks delivered to your local machine.\n    /// </summary>\n    public string? WebhookUrl { get; set; }\n\n    /// <summary>\n    /// The discount to be applied to the entire invoice, possibly on top of the line item discounts.\n    /// </summary>\n    public Amount? Discount { get; set; }\n\n    /// <summary>\n    /// This indicates whether the invoice is an e-invoice. The default value is false and can't be changed after the\n    /// invoice has been issued. When emailDetails is provided, an additional email is sent to the recipient. E-invoicing\n    /// is only available for merchants based in Belgium, Germany, and the Netherlands, and only when the recipient is\n    /// also located in one of these countries.\n    /// </summary>\n    public bool IsEInvoice { get; set; }\n\n    public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n        Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/Request/SalesInvoiceUpdateRequest.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.SalesInvoice.Request;\n\npublic record SalesInvoiceUpdateRequest : ITestModeRequest {\n    /// <summary>\n    /// The status for the invoice to end up in. Dependent parameters: paymentDetails for paid, emailDetails for issued\n    /// and paid. See the Mollie.Api.Models.SalesInvoice.SalesInvoiceStatus class for a full list of known values.\n    /// </summary>\n    public string? Status { get; set; }\n\n    /// <summary>\n    /// A free-form memo you can set on the invoice, and will be shown on the invoice PDF.\n    /// </summary>\n    public string? Memo { get; set; }\n\n    /// <summary>\n    /// The payment term to be set on the invoice. See the Mollie.Api.Models.SalesInvoice.PaymentTerm class for a full\n    /// list of known values.\n    /// </summary>\n    public string? PaymentTerm { get; set; }\n\n    /// <summary>\n    /// Used when setting an invoice to status of paid, and will store a payment that fully pays the invoice with the\n    /// provided details. Required for paid status.\n    /// </summary>\n    public PaymentDetails? PaymentDetails { get; set; }\n\n    /// <summary>\n    /// Used when setting an invoice to status of either issued or paid. Will be used to issue the invoice to the\n    /// recipient with the provided subject and body. Required for issued status.\n    /// </summary>\n    public EmailDetails? EmailDetails { get; set; }\n\n    /// <summary>\n    /// An identifier tied to the recipient data. This should be a unique value based on data your system contains,\n    /// so that both you and us know who we're referring to. It is a value you provide to us so that recipient\n    /// management is not required to send a first invoice to a recipient.\n    /// </summary>\n    public string? RecipientIdentifier { get; set; }\n\n    /// <summary>\n    /// The recipient object should contain all the information relevant to create an invoice for an intended recipient.\n    /// This data will be stored, updated, and re-used as appropriate, based on the recipientIdentifier.\n    /// </summary>\n    public Recipient? Recipient { get; set; }\n\n    /// <summary>\n    /// Provide the line items for the invoice. Each line contains details such as a description of the item ordered\n    /// and its price. All lines must have the same currency as the invoice.\n    /// </summary>\n    public IEnumerable<SalesInvoiceLine>? Lines { get; set; }\n\n    /// <summary>\n    /// The webhook URL where we will send invoice status updates to. The webhookUrl is optional, but without a webhook\n    /// you will miss out on important status changes to your invoice. The webhookUrl must be reachable from Mollie's\n    /// point of view, so you cannot use localhost. If you want to use webhook during development on localhost, you\n    /// must use a tool like ngrok to have the webhooks delivered to your local machine.\n    /// </summary>\n    public string? WebhookUrl { get; set; }\n\n    /// <summary>\n    /// The discount to be applied to the entire invoice, possibly on top of the line item discounts.\n    /// </summary>\n    public Amount? Discount { get; set; }\n\n    /// <summary>\n    /// Most API credentials are specifically created for either live mode or test mode. For organization-level\n    /// credentials such as OAuth access tokens, you can enable test mode by setting testmode to true.\n    /// </summary>\n    public bool? Testmode { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/Response/SalesInvoiceResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.SalesInvoice.Response;\n\npublic record SalesInvoiceResponse : IEntity {\n    /// <summary>\n    /// Indicates the response contains a sales invoice object. Will always contain the string sales-invoice for\n    /// this endpoint.\n    /// </summary>\n    public required string Resource { get; set; }\n\n    /// <summary>\n    /// The identifier uniquely referring to this invoice. Example: invoice_4Y0eZitmBnQ6IDoMqZQKh.\n    /// </summary>\n    public required string Id { get; set; }\n\n    /// <summary>\n    /// The mode used to create this sales invoice\n    /// </summary>\n    public required Mode Mode { get; set; }\n\n    /// <summary>\n    /// When issued, an invoice number will be set for the sales invoice.\n    /// </summary>\n    public string? InvoiceNumber { get; set; }\n\n    /// <summary>\n    /// The identifier referring to the profile this entity belongs to.\n    /// </summary>\n    public string? ProfileId { get; set; }\n\n    /// <summary>\n    /// A three-character ISO 4217 currency code.\n    /// </summary>\n    public string? Currency { get; set; }\n\n    /// <summary>\n    /// The status for the invoice to end up in. See the Mollie.Api.Models.SalesInvoice.SalesInvoiceStatus class for\n    /// a full list of known values.\n    /// </summary>\n    public required string Status { get; set; }\n\n    /// <summary>\n    /// The VAT scheme to create the invoice for. You must be enrolled with One Stop Shop enabled to use it. See the\n    /// Mollie.Api.Models.VatScheme class for a full list of known values.\n    /// </summary>\n    public string? VatScheme { get; set; }\n\n    /// <summary>\n    /// The VAT mode to use for VAT calculation. exclusive mode means we will apply the relevant VAT on top of the\n    /// price. inclusive means the prices you are providing to us already contain the VAT you want to apply. See the\n    /// Mollie.Api.Models.VatMode class for a full list of known values.\n    /// </summary>\n    public string? VatMode { get; set; }\n\n    /// <summary>\n    /// A free-form memo you can set on the invoice, and will be shown on the invoice PDF.\n    /// </summary>\n    public string? Memo { get; set; }\n\n    /// <summary>\n    /// The optional metadata you provided upon payment creation. Metadata can be used to link an order to a payment.\n    /// </summary>\n    [JsonConverter(typeof(RawJsonConverter))]\n    public string? Metadata { get; set; }\n\n    /// <summary>\n    /// The payment term to be set on the invoice. See the Mollie.Api.Models.SalesInvoice.PaymentTerm class for a full\n    /// list of known values.\n    /// </summary>\n    public string? PaymentTerm { get; set; }\n\n    /// <summary>\n    /// Used when setting an invoice to status of paid, and will store a payment that fully pays the invoice with\n    /// the provided details. Required for paid status.\n    /// </summary>\n    public PaymentDetails? PaymentDetails { get; set; }\n\n    /// <summary>\n    /// Used when setting an invoice to status of either issued or paid. Will be used to issue the invoice to the\n    /// recipient with the provided subject and body. Required for issued status.\n    /// </summary>\n    public EmailDetails? EmailDetails { get; set; }\n\n    /// <summary>\n    /// The identifier referring to the customer you want to attempt an automated payment for. If provided,\n    /// mandateId becomes required as well. Only allowed for invoices with status paid.\n    /// </summary>\n    public string? CustomerId { get; set; }\n\n    /// <summary>\n    /// The identifier referring to the mandate you want to use for the automated payment. If provided, customerId\n    /// becomes required as well. Only allowed for invoices with status paid.\n    /// </summary>\n    public string? MandateId { get; set; }\n\n    /// <summary>\n    /// An identifier tied to the recipient data. This should be a unique value based on data your system contains,\n    /// so that both you and us know who we're referring to. It is a value you provide to us so that recipient\n    /// management is not required to send a first invoice to a recipient.\n    /// </summary>\n    public required string RecipientIdentifier { get; set; }\n\n    /// <summary>\n    /// The recipient details\n    /// </summary>\n    public Recipient? Recipient { get; set; }\n\n    /// <summary>\n    /// Provide the line items for the invoice. Each line contains details such as a description of the item ordered\n    /// and its price. All lines must have the same currency as the invoice.\n    /// </summary>\n    public required IEnumerable<SalesInvoiceLine>? Lines { get; set; }\n\n    /// <summary>\n    /// The webhook URL where we will send invoice status updates to. The webhookUrl is optional, but without a webhook\n    /// you will miss out on important status changes to your invoice. The webhookUrl must be reachable from Mollie's\n    /// point of view, so you cannot use localhost. If you want to use webhook during development on localhost, you\n    /// must use a tool like ngrok to have the webhooks delivered to your local machine.\n    /// </summary>\n    public string? WebhookUrl { get; set; }\n\n    /// <summary>\n    /// The discount to be applied to the entire invoice, possibly on top of the line item discounts.\n    /// </summary>\n    public Amount? Discount { get; set; }\n\n    /// <summary>\n    /// This indicates whether the invoice is an e-invoice. The default value is false and can't be changed after the\n    /// invoice has been issued. When emailDetails is provided, an additional email is sent to the recipient. E-invoicing\n    /// is only available for merchants based in Belgium, Germany, and the Netherlands, and only when the recipient is\n    /// also located in one of these countries.\n    /// </summary>\n    public bool IsEInvoice { get; set; }\n\n    /// <summary>\n    /// The amount that is left to be paid.\n    /// </summary>\n    public required Amount AmountDue { get; set; }\n\n    /// <summary>\n    /// The total amount without VAT.\n    /// </summary>\n    public required Amount SubtotalAmount { get; set; }\n\n    /// <summary>\n    /// The total amount with VAT.\n    /// </summary>\n    public required Amount TotalAmount { get; set; }\n\n    /// <summary>\n    /// The discounted subtotal amount without VAT.\n    /// </summary>\n    public required Amount DiscountedSubtotalAmount { get; set; }\n\n    /// <summary>\n    /// The entity's date and time of creation.\n    /// </summary>\n    public required DateTime CreatedAt { get; set; }\n\n    /// <summary>\n    /// If issued, the date when the sales invoice was issued.\n    /// </summary>\n    public DateTime? IssuedAt { get; set; }\n\n    /// <summary>\n    /// If issued, the date when the sales invoice payment is due.\n    /// </summary>\n    public DateTime? DueAt { get; set; }\n\n    /// <summary>\n    /// An object with several relevant URLs. Every URL object will contain an href and a type field.\n    /// </summary>\n    [JsonPropertyName(\"_links\")]\n    public required SalesInvoiceResponseLinks Links { get; set; }\n\n    public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n        return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/Response/SalesInvoiceResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.SalesInvoice.Response;\n\npublic record SalesInvoiceResponseLinks {\n    /// <summary>\n    /// In v2 endpoints, URLs are commonly represented as objects with an href and type field.\n    /// </summary>\n    public required UrlObjectLink<SalesInvoiceResponse> Self { get; set; }\n\n    /// <summary>\n    /// The URL your customer should visit to make payment for the invoice. This is where you should redirect the\n    /// customer to unless the status is set to paid.\n    /// </summary>\n    public required UrlLink InvoicePayment { get; set; }\n\n    /// <summary>\n    /// The URL the invoice is available at, if generated.\n    /// </summary>\n    public UrlLink? PdfLink { get; set; }\n\n    /// <summary>\n    /// In v2 endpoints, URLs are commonly represented as objects with an href and type field.\n    /// </summary>\n    public required UrlLink Documentation { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/SalesInvoiceLine.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\npublic record SalesInvoiceLine {\n    /// <summary>\n    /// A description of the line item. For example LEGO 4440 Forest Police Station.\n    /// </summary>\n    public required string Description { get; set; }\n\n    /// <summary>\n    /// The number of items.\n    /// </summary>\n    public required int Quantity { get; set; }\n\n    /// <summary>\n    /// The vat rate to be applied to this line item.\n    /// </summary>\n    public required string VatRate { get; set; }\n\n    /// <summary>\n    /// The price of a single item excluding VAT.\n    /// </summary>\n    public required Amount UnitPrice { get; set; }\n\n    /// <summary>\n    /// The discount to be applied to the line item.\n    /// </summary>\n    public Amount? Discount { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SalesInvoice/SalesInvoiceStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.SalesInvoice;\n\npublic static class SalesInvoiceStatus {\n    public const string Draft = \"draft\";\n    public const string Issued = \"issued\";\n    public const string Paid = \"paid\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Session/Request/SessionRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Models.Session.Request {\n    public record SessionRequest : ITestModeRequest, IProfileRequest {\n        /// <summary>\n        /// The amount that you want to charge, e.g. {currency:\"EUR\", value:\"1000.00\"} if you would want to charge €1000.00.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The description of the session.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// Required - The URL the consumer will be redirected to after the payment process. It could make sense for the\n        /// redirectURL to contain a unique\n        /// identifier – like your order ID – so you can show the right page referencing the order when the consumer returns.\n        /// </summary>\n        public required string RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The URL your consumer will be redirected to when the consumer explicitly cancels the payment. If this URL is not\n        /// provided, the consumer will be redirected to the redirectUrl instead &#x2014; see above.\n        /// <para>Mollie will always give you status updates via webhooks, including for the canceled status. This parameter is\n        /// therefore entirely optional, but can be useful when implementing a dedicated consumer-facing flow to handle payment\n        /// cancellations.</para>\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        /// <summary>\n        /// Optionally provide the order lines for the payment. Each line contains details such as a description of the item ordered and its price.\n        /// All lines must have the same currency as the payment.\n        /// </summary>\n        public List<PaymentLine>? Lines { get; set; }\n\n        /// <summary>\n        /// The customer's billing address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The customer's shipping address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? ShippingAddress { get; set; }\n\n        public SessionPaymentDetails? Payment { get; set; }\n\n        /// <summary>\n        /// The ID of the Customer for whom the payment is being created. This is used for recurring payments and single click payments.\n        /// </summary>\n        public string? CustomerId { get; set; }\n\n        /// <summary>\n        /// Indicate which type of payment this is in a recurring sequence. If set to first, a first payment is created for the\n        /// customer, allowing the customer to agree to automatic recurring charges taking place on their account in the future.\n        /// If set to recurring, the customer’s card is charged automatically. Defaults to oneoff, which is a regular non-recurring\n        /// payment(see also: Recurring). See the Mollie.Api.Models.Payment.SequenceType class for a full list of known values.\n        /// </summary>\n        public string? SequenceType { get; set; }\n\n        /// <summary>\n        /// The website profile’s unique identifier, for example pfl_3RkSN1zuPE.\n        /// </summary>\n        public string? ProfileId { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, and we will save the data alongside the session. Whenever you fetch the session\n        /// with our API, we’ll also include the metadata. You can use up to 1kB of JSON.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this session a test session.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Session/Response/SessionResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Models.Session.Response {\n    public record SessionResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a session object.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The session's unique identifier, for example sub_rVKGtNd6s3.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The mode used to create this session. Mode determines whether the payments are real or test payments.\n        /// </summary>\n        public Mode Mode { get; set; }\n\n        /// <summary>\n        /// The client access token for the session.\n        /// </summary>\n        public required string ClientAccessToken { get; set; }\n\n        /// <summary>\n        /// The session's current status, depends on whether the customer has a pending, valid or invalid mandate.\n        /// See the Mollie.Api.Models.Session.SessionStatus class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// The constant amount that is charged with each session payment.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// The description of the session.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// The URL your customer will be redirected to after the payment process.\n        /// It could make sense for the redirectUrl to contain a unique identifier – like your order ID – so you can show the right page referencing the order when your customer returns.\n        /// </summary>\n        public string? RedirectUrl { get; set; }\n\n        /// <summary>\n        /// The identifier referring to the profile this entity belongs to.\n        /// </summary>\n        public required string ProfileId { get; set; }\n\n        /// <summary>\n        /// The URL your customer will be redirected to when the customer explicitly cancels the payment.\n        /// If this URL is not provided, the customer will be redirected to the redirectUrl instead — see above.\n        /// </summary>\n        public string? CancelUrl { get; set; }\n\n        public SessionPaymentDetails? Payment { get; set; }\n\n        /// <summary>\n        /// Optionally provide the order lines for the payment. Each line contains details such as a description of the item ordered and its price.\n        /// All lines must have the same currency as the payment.\n        /// </summary>\n        public List<PaymentLine>? Lines { get; set; }\n\n        /// <summary>\n        /// The customer's billing address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? BillingAddress { get; set; }\n\n        /// <summary>\n        /// The customer's shipping address details. We advise to provide these details to improve fraud protection and conversion. This is\n        /// particularly relevant for card payments.\n        /// </summary>\n        public PaymentAddressDetails? ShippingAddress { get; set; }\n\n        /// <summary>\n        /// The customer this session belongs to.\n        /// </summary>\n        public required string CustomerId { get; set; }\n\n        /// <summary>\n        /// Indicates which type of payment this is in a recurring sequence. Set to first for first payments that allow the customer to agree\n        /// to automatic recurring charges taking place on their account in the future. Set to recurring for payments where the customer’s card\n        /// is charged automatically. See the Mollie.Api.Models.Payment.SequenceType class for a full list of known values.\n        /// </summary>\n        public required string SequenceType { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon session creation. Metadata can for example be used to link a plan to a\n        /// session.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the session. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required SessionResponseLinks Links { get; set; }\n\n        public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n            return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Session/Response/SessionResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Profile.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Session.Response {\n    public record SessionResponseLinks {\n        /// <summary>\n        ///     The API resource URL of the session itself.\n        /// </summary>\n        public required UrlObjectLink<SessionResponse> Self { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Session/Response/SessionStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Session.Response {\n    public static class SessionStatus {\n        public const string Open = \"open\";\n        public const string Expired = \"expired\";\n        public const string Completed = \"completed\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Session/SessionLine.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Models.Session; \npublic record SessionLine : PaymentLine {\n\n    /// <summary>\n    /// The details of subsequent recurring billing cycles. These parameters are used in the Mollie Checkout to inform the shopper of the details for recurring products in the payments.\n    /// </summary>\n    public SessionLineRecurringDetails? Recurring { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Session/SessionLineRecurringDetails.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Api.Models.Session; \npublic record SessionLineRecurringDetails {\n    /// <summary>\n    /// A description of the recurring item. If not present, the main description of the item will be used.\n    /// </summary>\n    public string? Description { get; set; }\n\n    /// <summary>\n    /// Cadence unit of the recurring item. For example: 12 months, 52 weeks or 365 days.\n    /// </summary>\n    public required string Interval { get; set; }\n\n    /// <summary>\n    /// Total amount and currency of the recurring item.\n    /// </summary>\n    public required Amount Amount { get; set; }\n\n    /// <summary>\n    /// Optional – Total number of charges for the subscription to complete. Leave empty for ongoing subscription.\n    /// </summary>\n    public int? Times { get; set; }\n\n    /// <summary>\n    /// Optional – The start date of the subscription if it does not start right away (format YYYY-MM-DD)\n    /// </summary>\n    [JsonConverter(typeof(DateJsonConverter))]\n    public DateTime? StartDate { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Session/SessionPaymentDetails.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Session;\n\npublic record SessionPaymentDetails {\n\n    /// <summary>\n    /// The webhook URL where we will send payment status updates to.\n    /// This URL will be automatically set as the webhook URL for all payments created for this session.\n    /// </summary>\n    public string? WebhookUrl { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Settlement/Response/SettlementPeriod.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Settlement.Response {\n\tpublic record SettlementPeriod {\n\t\t/// <summary>\n\t\t/// The total revenue for each payment method during this period.\n\t\t/// </summary>\n\t\tpublic required List<SettlementPeriodRevenue> Revenue { get; set; }\n\n\t\t/// <summary>\n\t\t/// The fees withheld for each payment method during this period.\n\t\t/// </summary>\n\t\tpublic required List<SettlementPeriodCosts> Costs { get; set; }\n\n\t\t/// <summary>\n\t\t/// The ID of the invoice that was created to invoice specifically the costs in this month/period.\n\t\t/// If an individual month/period has not been invoiced yet, then this field will not be present until\n\t\t/// that invoice is created.\n\t\t/// </summary>\n\t\tpublic string? InvoiceId { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Settlement/Response/SettlementPeriodCosts.cs",
    "content": "﻿namespace Mollie.Api.Models.Settlement.Response {\n\tpublic record SettlementPeriodCosts {\n\t\t/// <summary>\n\t\t/// A description of the subtotal.\n\t\t/// </summary>\n\t\tpublic required string Description { get; set; }\n\n\t    /// <summary>\n\t    /// The net total of received funds for this payment method (excludes VAT).\n\t    /// </summary>\n\t    public required Amount AmountNet { get; set; }\n\n\t    /// <summary>\n\t    /// The VAT amount applicable to the revenue.\n\t    /// </summary>\n\t    public required Amount AmountVat { get; set; }\n\n\t    /// <summary>\n\t    /// The gross total of received funds for this payment method (includes VAT).\n\t    /// </summary>\n\t    public required Amount AmountGross { get; set; }\n\n        /// <summary>\n        /// The number of payments received for this payment method.\n        /// </summary>\n        public required int Count { get; set; }\n\n\t\t/// <summary>\n\t\t/// The service rates, further divided into fixed and variable costs.\n\t\t/// </summary>\n\t\tpublic required SettlementPeriodCostsRate Rate { get; set; }\n\n\t\t/// <summary>\n\t\t/// The payment method ID, if applicable - See the Mollie.Api.Models.Payment.PaymentMethod\n\t\t/// class for a full list of known values.\n\t\t/// </summary>\n\t\tpublic string? Method { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Settlement/Response/SettlementPeriodCostsRate.cs",
    "content": "﻿namespace Mollie.Api.Models.Settlement.Response\n{\n\tpublic record SettlementPeriodCostsRate {\n        /// <summary>\n        /// An amount object describing the fixed costs.\n        /// </summary>\n\t\tpublic required Amount Fixed { get; set; }\n\n        /// <summary>\n        /// A string describing the variable costs as a percentage.\n        /// </summary>\n\t\tpublic required string Percentage { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Settlement/Response/SettlementPeriodRevenue.cs",
    "content": "﻿namespace Mollie.Api.Models.Settlement.Response\n{\n\tpublic record SettlementPeriodRevenue\n\t{\n\t\t/// <summary>\n\t\t/// A description of the subtotal.\n\t\t/// </summary>\n\t\tpublic required string Description { get; set; }\n\n        /// <summary>\n        /// The net total of received funds for this payment method (excludes VAT).\n        /// </summary>\n        public required Amount AmountNet { get; set; }\n\n        /// <summary>\n        /// The VAT amount applicable to the revenue.\n        /// </summary>\n        public required Amount AmountVat { get; set; }\n\n        /// <summary>\n        /// The gross total of received funds for this payment method (includes VAT).\n        /// </summary>\n        public required Amount AmountGross { get; set; }\n\n\t\t/// <summary>\n\t\t/// The number of times costs were made for this payment method.\n\t\t/// </summary>\n\t\tpublic int Count { get; set; }\n\n\t\t/// <summary>\n\t\t/// The payment method ID, if applicable - See the Mollie.Api.Models.Payment.PaymentMethod\n\t\t/// class for a full list of known values.\n\t\t/// </summary>\n\t\tpublic string? Method { get; set; }\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Settlement/Response/SettlementResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Settlement.Response {\n\tpublic record SettlementResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a settlement object. Will always contain settlement for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n\t\t/// <summary>\n\t\t/// The settlement's identifier, for example stl_jDk30akdN.\n\t\t/// </summary>\n\t\tpublic required string Id { get; set; }\n\n\t\t/// <summary>\n\t\t/// The settlement's bank reference, as found on your invoice and in your Mollie account.\n\t\t/// </summary>\n\t\tpublic required string Reference { get; set; }\n\n\t\t/// <summary>\n\t\t/// The date on which the settlement was created.\n\t\t/// When requesting the next settlement the returned date signifies the expected settlement date.\n\t\t/// </summary>\n\t\tpublic required DateTime CreatedAt { get; set; }\n\n\t\t/// <summary>\n\t\t/// The date on which the settlement was settled.\n\t\t/// When requesting the open settlement or next settlement the return value is null.\n\t\t/// </summary>\n\t\tpublic DateTime? SettledAt { get; set; }\n\n\t\t/// <summary>\n\t\t/// The status of the settlement - See the Mollie.Api.Models.Settlement.SettlementStatus\n\t\t/// class for a full list of known values.\n\t\t/// </summary>\n\t\tpublic required string Status { get; set; }\n\n\t\t/// <summary>\n\t\t/// The total amount paid out with this settlement.\n\t\t/// </summary>\n\t\tpublic required Amount Amount { get; set; }\n\n\t\t/// <summary>\n\t\t/// This object is a collection of Period objects, which describe the settlement by month in full detail.\n\t\t/// Please refer to the Period object section below.\n\t\t/// </summary>\n\t\t[JsonConverter(typeof(SettlementPeriodConverter))]\n\t\tpublic required Dictionary<int, Dictionary<int, SettlementPeriod>> Periods { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the settlement. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required SettlementResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Settlement/Response/SettlementResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Chargeback.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Settlement.Response {\n    public record SettlementResponseLinks {\n        /// <summary>\n        /// The API resource URL of the settlement itself.\n        /// </summary>\n        public required UrlObjectLink<SettlementResponse> Self { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the payments that are included in this settlement.\n        /// </summary>\n        public required UrlObjectLink<ListResponse<PaymentResponse>> Payments { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the refunds that are included in this settlement.\n        /// </summary>\n        public required UrlObjectLink<ListResponse<RefundResponse>> Refunds { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the chargebacks that are included in this settlement.\n        /// </summary>\n        public required UrlObjectLink<ListResponse<ChargebackResponse>> Chargebacks { get; set; }\n\n        /// <summary>\n        /// The URL to the settlement retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Settlement/Response/SettlementStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Settlement.Response {\n\tpublic static class SettlementStatus {\n\t\tpublic const string Open = \"open\";\n\t\tpublic const string Pending = \"pending\";\n\t\tpublic const string PaidOut = \"paidout\";\n\t\tpublic const string Failed = \"failed\";\n\t}\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Shipment/Request/ShipmentLineRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Shipment.Request {\n    public record ShipmentLineRequest {\n        /// <summary>\n        /// The API resource token of the order line, for example: odl_jp31jz.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The number of items that should be shipped for this order line.\n        /// </summary>\n        public int? Quantity { get; set; }\n\n        /// <summary>\n        /// The amount that you want to ship. In almost all cases, Mollie can determine the amount automatically.\n        /// </summary>\n        public Amount? Amount { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Shipment/Request/ShipmentRequest.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Shipment.Request {\n    public record ShipmentRequest : ITestModeRequest {\n        /// <summary>\n        /// The total amount of the order, including VAT and discounts. This is the amount that will be charged\n        /// to your customer.\n        /// </summary>\n        public TrackingObject? Tracking { get; set; }\n\n        /// <summary>\n        /// The lines in the order. Each line contains details such as a description of the item ordered, its\n        /// price et cetera. If you send an empty array, the entire order will be shipped\n        /// </summary>\n        public IEnumerable<ShipmentLineRequest>? Lines { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this shipment a test shipment.\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Shipment/Request/ShipmentUpdateRequest.cs",
    "content": "namespace Mollie.Api.Models.Shipment.Request\n{\n    public record ShipmentUpdateRequest : ITestModeRequest {\n        public required TrackingObject Tracking { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this shipment a test shipment.\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Shipment/Response/ShipmentResponse.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models.Order.Response;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Shipment.Response\n{\n    public record ShipmentResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a shipment object. Will always contain shipment for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The shipment’s unique identifier, for example shp_3wmsgCJN4U.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The order this shipment was created on, for example ord_8wmqcHMN4U.\n        /// </summary>\n        public required string OrderId { get; set; }\n\n        /// <summary>\n        /// The shipment’s date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// An object containing shipment tracking details. Will be omitted when no tracking details are available.\n        /// </summary>\n        public TrackingObject? Tracking { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon subscription creation. Metadata can for example be used to link a plan to a\n        /// subscription.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// An array of order line objects\n        /// </summary>\n        public required IEnumerable<OrderLineResponse> Lines { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the order. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required ShipmentResponseLinks Links { get; set; }\n\n        public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n            return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Shipment/Response/ShipmentResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Shipment.Response {\n    public record ShipmentResponseLinks {\n        /// <summary>\n        /// The API resource URL of the order itself.\n        /// </summary>\n        public required UrlObjectLink<ShipmentResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL your customer should visit to make the payment for the order.\n        /// This is where you should redirect the customer to after creating the order.\n        /// </summary>\n        public required UrlLink Checkout { get; set; }\n\n        /// <summary>\n        /// The URL to the order retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Shipment/TrackingObject.cs",
    "content": "﻿namespace Mollie.Api.Models.Shipment{\n    public record TrackingObject {\n        /// <summary>\n        /// Name of the postal carrier (as specific as possible). For example PostNL.\n        /// </summary>\n        public required string Carrier { get; set; }\n\n        /// <summary>\n        /// The track and trace code of the shipment. For example 3SKABA000000000.\n        /// </summary>\n        public required string Code { get; set; }\n\n        /// <summary>\n        /// The URL where your customer can track the shipment\n        /// </summary>\n        public string? Url { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/SortDirection.cs",
    "content": "﻿using System.Runtime.Serialization;\n\nnamespace Mollie.Api.Models\n{\n    public enum SortDirection\n    {\n        [EnumMember(Value = \"desc\")] Desc,\n        [EnumMember(Value = \"asc\")] Asc\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/StatusReason.cs",
    "content": "﻿namespace Mollie.Api.Models;\n\npublic record StatusReason {\n    /// <summary>\n    /// A machine-readable code that indicates the reason for the status.\n    /// </summary>\n    public required string Code { get; set; }\n\n    /// <summary>\n    /// A machine-readable code that indicates the reason for the status.\n    /// </summary>\n    public required string Message { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Subscription/Request/SubscriptionRequest.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Subscription.Request {\n    public record SubscriptionRequest : ITestModeRequest, IProfileRequest {\n        /// <summary>\n        /// The constant amount in EURO that you want to charge with each subscription payment, e.g. 100.00 if you would want\n        /// to charge € 100,00.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// Optional – Total number of charges for the subscription to complete. Leave empty for an on-going subscription.\n        /// </summary>\n        public int? Times { get; set; }\n\n        /// <summary>\n        /// Interval to wait between charges, for example 1 month or 14 days.\n        /// </summary>\n        public required string Interval { get; set; }\n\n        /// <summary>\n        /// Optional – The start date of the subscription in yyyy-mm-dd format. This is the first day on which your customer\n        /// will be charged. When\n        /// this parameter is not provided, the current date will be used instead.\n        /// </summary>\n        [JsonConverter(typeof(DateJsonConverter))]\n        public DateTime? StartDate { get; set; }\n\n        /// <summary>\n        /// A description unique per customer. This will be included in the payment description along with the charge date in\n        /// Y-m-d format.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// Optional – The payment method used for this subscription, either forced on creation or null if any of the\n        /// customer's valid mandates may be used. See the Mollie.Api.Models.Payment.PaymentMethod class for a full\n        /// list of known values.\n        /// </summary>\n        public string? Method { get; set; }\n\n        /// <summary>\n        /// The mandate used for this subscription. Please note that this parameter can not set together with method.\n        /// </summary>\n        public string? MandateId { get; set; }\n\n        /// <summary>\n        /// Optional – Use this parameter to set a webhook URL for all subscription payments.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Adding an application fee allows you to charge the merchant for each payment in the subscription and\n        /// transfer these amounts to your own account.\n        /// </summary>\n        public ApplicationFee? ApplicationFee { get; set; }\n\n        /// <summary>\n        /// The website profile’s unique identifier, for example pfl_3RkSN1zuPE.\n        /// </summary>\n        public string? ProfileId { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, and we will save the data alongside the subscription. Whenever you fetch the subscription\n        /// with our API, we’ll also include the metadata. You can use up to 1kB of JSON.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this subscription a test subscription.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Subscription/Request/SubscriptionUpdateRequest.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Subscription.Request {\n    public record SubscriptionUpdateRequest : ITestModeRequest {\n        /// <summary>\n        /// The constant amount in EURO that you want to charge with each subscription payment, e.g. 100.00 if you would want\n        /// to charge € 100,00.\n        /// </summary>\n        public Amount? Amount { get; set; }\n\n        /// <summary>\n        /// Optional – Total number of charges for the subscription to complete. Leave empty for an on-going subscription.\n        /// </summary>\n        public int? Times { get; set; }\n\n        /// <summary>\n        /// Optional – The start date of the subscription in yyyy-mm-dd format. This is the first day on which your customer\n        /// will be charged. When\n        /// this parameter is not provided, the current date will be used instead.\n        /// </summary>\n        [JsonConverter(typeof(DateJsonConverter))]\n        public DateTime? StartDate { get; set; }\n\n        /// <summary>\n        /// A description unique per customer. This will be included in the payment description along with the charge date in\n        /// Y-m-d format.\n        /// </summary>\n        public string? Description { get; set; }\n\n        /// <summary>\n        /// Interval to wait between charges, for example 1 month or 14 days.\n        /// </summary>\n        public string? Interval { get; set; }\n\n        /// <summary>\n        /// Optional – Use this parameter to set a webhook URL for all subscription payments.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// Provide any data you like, and we will save the data alongside the subscription. Whenever you fetch the subscription\n        /// with our API, we’ll also include the metadata. You can use up to 1kB of JSON.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// The mandate used for this subscription. Please note that this parameter can not set together with method.\n        /// </summary>\n        public string? MandateId { get; set; }\n\n        /// <summary>\n        ///\tOauth only - Optional – Set this to true to make this subscription a test subscription.\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        public void SetMetadata(object metadataObj, JsonSerializerOptions? jsonSerializerOptions = null) {\n            Metadata = JsonSerializer.Serialize(metadataObj, jsonSerializerOptions);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Subscription/Response/SubscriptionResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Subscription.Response {\n    public record SubscriptionResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a subscription object.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The subscription's unique identifier, for example sub_rVKGtNd6s3.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// The mode used to create this subscription. Mode determines whether the payments are real or test payments.\n        /// </summary>\n        public Mode Mode { get; set; }\n\n        /// <summary>\n        ///  The subscription's date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public required DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// The subscription's current status, depends on whether the customer has a pending, valid or invalid mandate.\n        /// See the Mollie.Api.Models.Subscription.SubscriptionStatus class for a full list of known values.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// The constant amount that is charged with each subscription payment.\n        /// </summary>\n        public required Amount Amount { get; set; }\n\n        /// <summary>\n        /// Total number of charges for the subscription to complete.\n        /// </summary>\n        public int? Times { get; set; }\n\n        /// <summary>\n        /// Number of charges left for the subscription to complete.\n        /// </summary>\n        public int? TimesRemaining { get; set; }\n\n        /// <summary>\n        /// Interval to wait between charges like 1 month(s) or 14 days.\n        /// </summary>\n        public required string Interval { get; set; }\n\n        /// <summary>\n        /// The start date of the subscription in yyyy-mm-dd format.\n        /// </summary>\n        public DateTime? StartDate { get; set; }\n\n        /// <summary>\n        /// The date of the next scheduled payment in YYYY-MM-DD format. When there will be no next payment, for example\n        /// when the subscription has ended, this parameter will not be returned.\n        /// </summary>\n        public DateTime? NextPaymentDate { get; set; }\n\n        /// <summary>\n        /// A description unique per customer. This will be included in the payment description along with the charge date in\n        /// Y-m-d format.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// The payment method used for this subscription, either forced on creation by specifying the method parameter, or\n        /// null if any of the customer's valid mandates may be used. See the Mollie.Api.Models.Payment.PaymentMethod class\n        /// for a full list of known values.\n        /// </summary>\n        public string? Method { get; set; }\n\n        /// <summary>\n        /// The mandate used for this subscription. Please note that this parameter can not set together with method.\n        /// </summary>\n        public string? MandateId { get; set; }\n\n        /// <summary>\n        /// The subscription's date of cancellation, in ISO 8601 format.\n        /// </summary>\n        public DateTime? CanceledAt { get; set; }\n\n        /// <summary>\n        /// The URL Mollie will call as soon a payment status change takes place.\n        /// </summary>\n        public string? WebhookUrl { get; set; }\n\n        /// <summary>\n        /// The customer this subscription belongs to.\n        /// </summary>\n        public required string CustomerId { get; set; }\n\n        /// <summary>\n        /// The optional metadata you provided upon subscription creation. Metadata can for example be used to link a plan to a\n        /// subscription.\n        /// </summary>\n        [JsonConverter(typeof(RawJsonConverter))]\n        public string? Metadata { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the subscription. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required SubscriptionResponseLinks Links { get; set; }\n\n        /// <summary>\n        /// Adding an application fee allows you to charge the merchant for each payment in the subscription and\n        /// transfer these amounts to your own account.\n        /// </summary>\n        public ApplicationFee? ApplicationFee { get; set; }\n\n        public T? GetMetadata<T>(JsonSerializerOptions? jsonSerializerOptions = null) {\n            return Metadata != null ? JsonSerializer.Deserialize<T>(Metadata, jsonSerializerOptions) : default;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Subscription/Response/SubscriptionResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Profile.Response;\nusing Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Subscription.Response {\n    public record SubscriptionResponseLinks {\n        /// <summary>\n        ///     The API resource URL of the subscription itself.\n        /// </summary>\n        public required UrlObjectLink<SubscriptionResponse> Self { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the customer the subscription is for.\n        /// </summary>\n        public required UrlObjectLink<CustomerResponse> Customer { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the payments that are created by this subscription. Not present\n        /// if no payments yet created.\n        /// </summary>\n        public UrlObjectLink<ListResponse<PaymentResponse>>? Payments { get; set; }\n\n        /// <summary>\n        /// The API resource URL of the website profile on which this subscription was created.\n        /// </summary>\n        public required UrlObjectLink<ProfileResponse> Profile { get; set; }\n\n        /// <summary>\n        /// The URL to the subscription retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Subscription/Response/SubscriptionStatus.cs",
    "content": "﻿namespace Mollie.Api.Models.Subscription.Response {\n    public static class SubscriptionStatus {\n        public const string Pending = \"pending\";\n        public const string Active = \"active\";\n        public const string Canceled = \"canceled\";\n        public const string Suspended = \"suspended\";\n        public const string Completed = \"completed\";\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Terminal/Response/TerminalResponse.cs",
    "content": "﻿using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Terminal.Response\n{\n    /// <summary>\n    /// Full documentation for this class can be found at https://docs.mollie.com/reference/v2/terminals-api/overview\n    /// </summary>\n    public record TerminalResponse : IEntity {\n        /// <summary>\n        /// Indicates the response contains a terminal object. Will always contain the string terminal for this endpoint.\n        /// </summary>\n        public required string Resource { get; set; }\n\n        /// <summary>\n        /// The unique identifier used for referring to a terminal. Mollie assigns this identifier at terminal creation time.\n        /// For example term_7MgL4wea46qkRcoTZjWEH. This ID will be used by Mollie to refer to a certain terminal and will be used for assigning a payment to a specific terminal.\n        /// </summary>\n        public required string Id { get; set; }\n\n        /// <summary>\n        /// Whether this entity was created in live mode or in test mode.\n        /// </summary>\n        public required Mode Mode { get; set; }\n\n        /// <summary>\n        /// The identifier used for referring to the profile the terminal was created on. For example, pfl_QkEhN94Ba.\n        /// </summary>\n        public required string ProfileId { get; set; }\n\n        /// <summary>\n        /// The status of the terminal, which is a read-only value determined by Mollie, according to the actions performed for that terminal.\n        /// Its values can be pending, active, inactive. pending means that the terminal has been created but not yet active.\n        /// active means that the terminal is active and can take payments. inactive means that the terminal has been deactivated.\n        /// </summary>\n        public required string Status { get; set; }\n\n        /// <summary>\n        /// The brand of the terminal.\n        /// </summary>\n        public required string Brand { get; set; }\n\n        /// <summary>\n        /// The model of the terminal.\n        /// </summary>\n        public required string Model { get; set; }\n\n        /// <summary>\n        /// The serial number of the terminal. The serial number is provided at terminal creation time.\n        /// </summary>\n        public required string SerialNumber { get; set; }\n\n        /// <summary>\n        /// An ISO 4217 currency code. The currencies supported depend on the payment methods that are enabled on your account.\n        /// </summary>\n        public required string Currency { get; set; }\n\n        /// <summary>\n        /// The full name of the payment terminal.\n        /// </summary>\n        public required string Description { get; set; }\n\n        /// <summary>\n        /// The Terminal's date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public DateTime CreatedAt { get; set; }\n\n        /// <summary>\n        /// The Terminal's date and time of creation, in ISO 8601 format.\n        /// </summary>\n        public DateTime? UpdatedAt { get; set; }\n\n        /// <summary>\n        /// An object with several URL objects relevant to the payment method. Every URL object will contain an href and a type field.\n        /// </summary>\n        [JsonPropertyName(\"_links\")]\n        public required TerminalResponseLinks Links { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Terminal/Response/TerminalResponseLinks.cs",
    "content": "﻿using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.Terminal.Response\n{\n    /// <summary>\n    /// This Sublass is part of the TerminalResponse Class, Full documentation for this class can be found at https://docs.mollie.com/reference/v2/terminals-api/overview\n    /// </summary>\n    public record TerminalResponseLinks\n    {\n        /// <summary>\n        /// The API resource URL of the payment method itself.\n        /// </summary>\n        public required UrlObjectLink<TerminalResponse> Self { get; set; }\n\n        /// <summary>\n        /// The URL to the payment method retrieval endpoint documentation.\n        /// </summary>\n        public required UrlLink Documentation { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/TestmodeModel.cs",
    "content": "﻿namespace Mollie.Api.Models {\n    public record TestmodeModel {\n        public static TestmodeModel? Create(bool testmode) {\n            return testmode ? new TestmodeModel { Testmode = testmode } : null;\n        }\n        \n        /// <summary>\n        ///\tOauth only - Optional\n        /// </summary>\n        public bool? Testmode { get; set; }\n    }\n}"
  },
  {
    "path": "src/Mollie.Api/Models/Url/UrlLink.cs",
    "content": "﻿namespace Mollie.Api.Models.Url {\n    public record UrlLink {\n        public required string Href { get; set; }\n        public required string Type { get; set; }\n\n        public override string ToString() {\n            return $\"{Type} - {Href}\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Url/UrlObjectLink.cs",
    "content": "﻿namespace Mollie.Api.Models.Url {\n    // ReSharper disable once UnusedTypeParameter\n    public record UrlObjectLink<T> : UrlLink;\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/VatMode.cs",
    "content": "﻿namespace Mollie.Api.Models;\n\n/// <summary>\n/// The VAT mode to use for VAT calculation. \n/// </summary>\npublic static class VatMode {\n    /// <summary>\n    /// Inclusive means the prices you are providing to us already contain the VAT you want to apply.\n    /// </summary>\n    public const string Inclusive = \"inclusive\";\n    \n    /// <summary>\n    /// Exclusive mode means we will apply the relevant VAT on top of the price. \n    /// </summary>\n    public const string Exclusive = \"exclusive\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/VatScheme.cs",
    "content": "﻿namespace Mollie.Api.Models;\n\npublic static class VatScheme {\n    public const string Standard = \"standard\";\n    public const string OneStopShop = \"one-stop-shop\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/VoucherCategory.cs",
    "content": "﻿namespace Mollie.Api.Models;\n\npublic static class VoucherCategory {\n    public const string Gift = \"gift\";\n    public const string Eco = \"eco\";\n    public const string Meal = \"meal\";\n    public const string SportCulture = \"sport_culture\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Wallet/Request/ApplePayPaymentSessionRequest.cs",
    "content": "﻿namespace Mollie.Api.Models.Wallet.Request {\n    public record ApplePayPaymentSessionRequest {\n        /// <summary>\n        /// The validationUrl you got from the ApplePayValidateMerchant event.\n        /// A list of all valid host names for merchant validation is available. You should white list these in your\n        /// application and reject any validationUrl that have a host name not in the list.\n        /// </summary>\n        public required string ValidationUrl { get; set; }\n\n        /// <summary>\n        /// The domain of your web shop, that is visible in the browser’s location bar. For example pay.myshop.com.\n        /// </summary>\n        public required string Domain { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Wallet/Response/ApplePayPaymentSessionResponse.cs",
    "content": "﻿using System;\nusing Mollie.Api.JsonConverters;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.Wallet.Response {\n    public record ApplePayPaymentSessionResponse {\n        [JsonConverter(typeof(MicrosecondEpochConverter))]\n        public required DateTime EpochTimestamp { get; set; }\n        [JsonConverter(typeof(MicrosecondEpochConverter))]\n        public required DateTime ExpiresAt { get; set; }\n        public required string MerchantSessionIdentifier { get; set; }\n        public required string Nonce { get; set; }\n        public required string MerchantIdentifier { get; set; }\n        public required string DomainName { get; set; }\n        public required string DisplayName { get; set; }\n        public required string Signature { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Webhook/Request/WebhookRequest.cs",
    "content": "using System.Collections.Generic;\nusing System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.Webhook.Request;\n\npublic record WebhookRequest : ITestModeRequest {\n    /// <summary>\n    /// A name that identifies the webhook.\n    /// </summary>\n    public required string Name { get; set; }\n\n    /// <summary>\n    /// The URL Mollie will send the events to. This URL must be publicly accessible.\n    /// </summary>\n    public required string Url { get; set; }\n\n    /// <summary>\n    /// The list of events to enable for this webhook. You may specify '*' to add all events, except those that require\n    /// explicit selection. Separate multiple event types with a comma. See the Mollie.Api.Models.Webhook.WebhookEventTypes\n    /// class for a full list of known values\n    /// </summary>\n    [JsonConverter(typeof(CollectionToCommaSeparatedListConverter))]\n    public required IList<string> EventTypes { get; set; }\n\n    /// <summary>\n    /// Whether to create the entity in test mode or live mode. Most API credentials are specifically created for\n    /// either live mode or test mode, in which case this parameter can be omitted. For organization-level credentials\n    /// such as OAuth access tokens, you can enable test mode by setting testmode to true.\n    /// </summary>\n    public bool? Testmode { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Webhook/Response/WebhookResponse.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Mollie.Api.Models.Webhook.Response;\n\npublic record WebhookResponse : IEntity {\n    /// <summary>\n    /// Indicates the response contains a webhook subscription object. Will always contain the string webhook for this\n    /// endpoint.\n    /// </summary>\n    public required string Resource { get; set; }\n\n    /// <summary>\n    /// The identifier uniquely referring to this subscription.\n    /// </summary>\n    public required string Id { get; set; }\n\n    /// <summary>\n    /// The subscription's events destination.\n    /// </summary>\n    public required string Url { get; set; }\n\n    /// <summary>\n    /// The identifier uniquely referring to the profile that created the subscription.\n    /// </summary>\n    public required string ProfileId { get; set; }\n\n    /// <summary>\n    /// The subscription's date time of creation.\n    /// </summary>\n    public required DateTime CreatedAt { get; set; }\n\n    /// <summary>\n    /// The subscription's name.\n    /// </summary>\n    public required string Name { get; set; }\n\n    /// <summary>\n    /// The events types that are subscribed. See the Mollie.Api.Models.Webhook.WebhookEventTypes class for a full\n    /// list of known values\n    /// </summary>\n    public required IEnumerable<string> EventTypes { get; set; }\n\n    /// <summary>\n    /// The subscription's current status.\n    /// </summary>\n    public required string Status { get; set; }\n\n    /// <summary>\n    /// The subscription's mode.\n    /// </summary>\n    public required Mode Mode { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/Webhook/WebhookEventTypes.cs",
    "content": "namespace Mollie.Api.Models.Webhook;\n\npublic static class WebhookEventTypes {\n    /// <summary>\n    /// A payment link has been paid.\n    /// </summary>\n    public const string PaymentLinkPaid = \"payment-link.paid\";\n\n    /// <summary>\n    /// A sales invoice has been created.\n    /// </summary>\n    public const string SalesInvoiceCreated = \"sales-invoice.created\";\n\n    /// <summary>\n    /// A sales invoice has been issued.\n    /// </summary>\n    public const string SalesInvoiceIssued = \"sales-invoice.issued\";\n\n    /// <summary>\n    /// A sales invoice has been canceled.\n    /// </summary>\n    public const string SalesInvoiceCanceled = \"sales-invoice.canceled\";\n\n    /// <summary>\n    /// A sales invoice has been paid.\n    /// </summary>\n    public const string SalesInvoicePaid = \"sales-invoice.paid\";\n\n    /// <summary>\n    /// All event types\n    /// </summary>\n    public const string All = \"*\";\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/WebhookEvent/Response/FullWebhookEventResponse.cs",
    "content": "using System.Text.Json.Serialization;\nusing Mollie.Api.JsonConverters;\n\nnamespace Mollie.Api.Models.WebhookEvent.Response;\n\npublic record FullWebhookEventResponse<T> : SimpleWebhookEventResponse where T : IEntity {\n    /// <summary>\n    /// Full payload of the event.\n    /// </summary>\n    [JsonConverter(typeof(WebhookEventEntityJsonConverter))]\n    [JsonPropertyName(\"_embedded\")]\n    public required T Entity { get; set; }\n}\n\npublic record FullWebhookEventResponse : SimpleWebhookEventResponse {\n    /// <summary>\n    /// Full payload of the event.\n    /// </summary>\n    [JsonConverter(typeof(WebhookEventEntityJsonConverter))]\n    [JsonPropertyName(\"_embedded\")]\n    public required IEntity Entity { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/WebhookEvent/Response/SimpleWebhookEventResponse.cs",
    "content": "using System;\nusing System.Text.Json.Serialization;\n\nnamespace Mollie.Api.Models.WebhookEvent.Response;\n\npublic record SimpleWebhookEventResponse : IEntity {\n    /// <summary>\n    /// Indicates the response contains a webhook event object. Will always contain the string event for this endpoint.\n    /// </summary>\n    public required string Resource { get; set; }\n\n    /// <summary>\n    /// The identifier uniquely referring to this event.\n    /// </summary>\n    public required string Id { get; set; }\n\n    /// <summary>\n    /// The event's type.\n    /// </summary>\n    public required string Type { get; set; }\n\n    /// <summary>\n    /// The entity token that triggered the event\n    /// </summary>\n    public required string EntityId { get; set; }\n\n    /// <summary>\n    /// The event's date time of creation.\n    /// </summary>\n    public required DateTime CreatedAt { get; set; }\n\n    /// <summary>\n    /// An object with several relevant URLs. Every URL object will contain an href and a type field.\n    /// </summary>\n    [JsonPropertyName(\"_links\")]\n    public required WebhookEventResponseLinks Links { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Models/WebhookEvent/Response/WebhookEventResponseLinks.cs",
    "content": "using Mollie.Api.Models.Url;\n\nnamespace Mollie.Api.Models.WebhookEvent.Response;\n\n/// <summary>\n/// An object with several relevant URLs. Every URL object will contain an href and a type field.\n/// </summary>\npublic record WebhookEventResponseLinks {\n    /// <summary>\n    /// In v2 endpoints, URLs are commonly represented as objects with an href and type field.\n    /// </summary>\n    public required UrlObjectLink<SimpleWebhookEventResponse> Self { get; set; }\n\n    /// <summary>\n    /// In v2 endpoints, URLs are commonly represented as objects with an href and type field.\n    /// </summary>\n    public required UrlLink Documentation { get; set; }\n\n    /// <summary>\n    /// The API resource URL of the entity that this event belongs to.\n    /// </summary>\n    public required UrlObjectLink<IEntity> Entity { get; set; }\n}\n"
  },
  {
    "path": "src/Mollie.Api/Mollie.Api.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>\n    <Nullable>enable</Nullable>\n    <LangVersion>12</LangVersion>\n    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>\n    <GenerateDocumentationFile>true</GenerateDocumentationFile>\n    <Description>This is a wrapper for the Mollie REST webservice. All payment methods and webservice calls are supported.</Description>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"DotNet.ReproducibleBuilds\" Version=\"2.0.2\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.Extensions.Http.Polly\" Version=\"8.0.19\" />\n    <PackageReference Include=\"PolySharp\" Version=\"1.15.0\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"System.Text.Json\" Version=\"8.0.6\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Include=\"..\\..\\README.md\" Pack=\"true\" PackagePath=\"\\\" />\n    <None Include=\"..\\..\\LICENSE\" Pack=\"true\" PackagePath=\"\\\" />\n  </ItemGroup>\n\n  <ItemGroup Condition=\"'$(SignAssembly)' != 'true'\">\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleTo\">\n      <_Parameter1>Mollie.Tests.Unit</_Parameter1>\n    </AssemblyAttribute>\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleTo\">\n      <_Parameter1>Mollie.Tests.Integration</_Parameter1>\n    </AssemblyAttribute>\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleTo\">\n      <_Parameter1>Mollie.Api.AspNet</_Parameter1>\n    </AssemblyAttribute>\n  </ItemGroup>\n\n  <ItemGroup Condition=\"'$(SignAssembly)' == 'true' and '$(MollieStrongNamePublicKey)' != ''\">\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleTo\">\n      <_Parameter1>Mollie.Tests.Unit, PublicKey=$(MollieStrongNamePublicKey)</_Parameter1>\n    </AssemblyAttribute>\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleTo\">\n      <_Parameter1>Mollie.Tests.Integration, PublicKey=$(MollieStrongNamePublicKey)</_Parameter1>\n    </AssemblyAttribute>\n    <AssemblyAttribute Include=\"System.Runtime.CompilerServices.InternalsVisibleTo\">\n      <_Parameter1>Mollie.Api.AspNet, PublicKey=$(MollieStrongNamePublicKey)</_Parameter1>\n    </AssemblyAttribute>\n  </ItemGroup>\n\n  <Target Name=\"RequirePublicKeyForStrongNamedFriends\"\n          BeforeTargets=\"GenerateAssemblyInfo\"\n          Condition=\"'$(SignAssembly)' == 'true' and '$(MollieStrongNamePublicKey)' == ''\">\n    <Error Text=\"MollieStrongNamePublicKey must be set when SignAssembly=true to emit InternalsVisibleTo attributes.\" />\n  </Target>\n</Project>\n"
  },
  {
    "path": "src/Mollie.Api/Options/MollieClientOptions.cs",
    "content": "using Mollie.Api.Client;\n\nnamespace Mollie.Api.Options;\n\npublic class MollieClientOptions {\n    /// <summary>\n    /// Your API-key or OAuth token\n    /// </summary>\n    public required string ApiKey { get; set; } = string.Empty;\n\n    /// <summary>\n    /// (Optional) The default user agent is \"Mollie.Api.NET {version}\". When this property is set, the custom user\n    /// agent will be appended to the default user agent.\n    /// </summary>\n    public string? CustomUserAgent { get; set; }\n\n    /// <summary>\n    /// (Optional) Enable test mode for all requests\n    /// </summary>\n    public bool? Testmode { get; set; }\n\n    /// <summary>\n    /// (Optional) The profile ID to be used for all requests\n    /// </summary>\n    public string? ProfileId { get; set; }\n\n    /// <summary>\n    /// (Optional) ClientId used by Connect API\n    /// </summary>\n    public string? ClientId { get; set; }\n\n    /// <summary>\n    /// (Optional) ClientSecret used by Connect API\n    /// </summary>\n    /// <returns></returns>\n    public string? ClientSecret { get; set; }\n\n    /// <summary>\n    /// The base URL for all API requests. Can be overridden for testing purposes.\n    /// </summary>\n    public string ApiBaseUrl { get; set; } = BaseMollieClient.DefaultBaseApiEndPoint;\n\n    /// <summary>\n    /// The authorize endpoint for the Connect client. Can be overridden for testing purposes.\n    /// </summary>\n    public string ConnectOAuthAuthorizeEndPoint { get; set; } = ConnectClient.DefaultAuthorizeEndpoint;\n\n    /// <summary>\n    /// The token endpoint for the Connect client. Can be overridden for testing purposes.\n    /// </summary>\n    public string ConnectTokenEndPoint { get; set; } = ConnectClient.DefaultTokenEndpoint;\n}\n"
  },
  {
    "path": "src/Mollie.Api/Options/MollieOptions.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing Mollie.Api.Client;\nusing Mollie.Api.Framework.Authentication.Abstract;\nusing Polly;\n\nnamespace Mollie.Api.Options {\n    public record MollieOptions {\n        /// <summary>\n        /// Your API-key or OAuth token\n        /// </summary>\n        public string ApiKey { get; set; } = string.Empty;\n\n        /// <summary>\n        /// (Optional) ClientId used by Connect API\n        /// </summary>\n        public string? ClientId { get; set; } = string.Empty;\n\n        /// <summary>\n        /// (Optional) ClientSecret used by Connect API\n        /// </summary>\n        /// <returns></returns>\n        public string? ClientSecret { get; set; } = string.Empty;\n\n        /// <summary>\n        /// The base URL for all API requests. Can be overridden for testing purposes.\n        /// </summary>\n        public string ApiBaseUrl { get; set; } = BaseMollieClient.DefaultBaseApiEndPoint;\n\n        /// <summary>\n        /// The authorize endpoint for the Connect client. Can be overridden for testing purposes.\n        /// </summary>\n        public string ConnectOAuthAuthorizeEndPoint { get; set; } = ConnectClient.DefaultAuthorizeEndpoint;\n\n        /// <summary>\n        /// The token endpoint for the Connect client. Can be overridden for testing purposes.\n        /// </summary>\n        public string ConnectTokenEndPoint { get; set; } = ConnectClient.DefaultTokenEndpoint;\n\n        /// <summary>\n        /// (Optional) Polly retry policy for failed requests\n        /// </summary>\n        public IAsyncPolicy<HttpResponseMessage>? RetryPolicy { get; set; }\n\n        /// <summary>\n        /// (Optional) The default user agent is \"Mollie.Api.NET {version}\". When this property is set, the custom user\n        /// agent will be appended to the default user agent.\n        /// </summary>\n        public string? CustomUserAgent { get; set; }\n\n        /// <summary>\n        /// (Optional) Enable test mode for all requests\n        /// </summary>\n        public bool? Testmode { get; set; }\n\n        /// <summary>\n        /// (Optional) The profile ID to be used for all requests\n        /// </summary>\n        public string? ProfileId { get; set; }\n\n        /// <summary>\n        /// (Optional) A custom secret manager that you can override to implement advanced multi-tenant scenario's\n        /// </summary>\n        public Type? CustomMollieSecretManager { get; private set; }\n\n        /// <summary>\n        /// Set a custom secret manager that you can override to implement advanced multi-tenant scenario's\n        /// </summary>\n        public MollieOptions SetCustomMollieSecretManager<T>() where T : IMollieSecretManager {\n            CustomMollieSecretManager = typeof(T);\n            return this;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/DependencyInjection.cs",
    "content": "using Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api.AspNet.Webhooks.Authorization;\nusing Mollie.Api.AspNet.Webhooks.Options;\n\nnamespace Mollie.Api.AspNet;\n\npublic static class DependencyInjection {\n    public static IServiceCollection AddMollieWebhook(\n        this IServiceCollection services,\n        Action<MollieWebhookOptions> optionsDelegate) {\n\n        MollieWebhookOptions options = new();\n        optionsDelegate.Invoke(options);\n\n        services.AddSingleton(options);\n\n        services.AddSingleton<MollieSignatureValidator>();\n#if NET7_0_OR_GREATER\n        services.AddScoped<MollieSignatureEndpointFilter>();\n#endif\n        services.AddScoped<MollieSignatureFilter>();\n\n        return services;\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Mollie.Api.AspNet.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFrameworks>net6.0;net8.0;net10.0</TargetFrameworks>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <LangVersion>11</LangVersion>\n    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>\n    <GenerateDocumentationFile>true</GenerateDocumentationFile>\n    <Description>\n      ASP.NET Core extensions for the Mollie.Api client.\n      Provides ready-to-use model binders, filters, and middleware to securely process Mollie webhooks and integrate payments into your ASP.NET Core MVC or Minimal API applications.\n    </Description>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <FrameworkReference Include=\"Microsoft.AspNetCore.App\"/>\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Include=\"..\\..\\README.md\" Pack=\"true\" PackagePath=\"\\\" />\n    <None Include=\"..\\..\\LICENSE\" Pack=\"true\" PackagePath=\"\\\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Mollie.Api\\Mollie.Api.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Webhooks/Authorization/MollieSignatureEndpointFilter.cs",
    "content": "using Microsoft.AspNetCore.Http;\n\nnamespace Mollie.Api.AspNet.Webhooks.Authorization;\n\n#if NET7_0_OR_GREATER\n\npublic class MollieSignatureEndpointFilter : IEndpointFilter {\n    private readonly MollieSignatureValidator _signatureValidator;\n\n    public MollieSignatureEndpointFilter(MollieSignatureValidator signatureValidator) {\n        _signatureValidator = signatureValidator;\n    }\n\n    public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)\n    {\n\n        var request = context.HttpContext.Request;\n        bool isValid = await _signatureValidator.Validate(request);\n        if (!isValid) {\n            return Results.Unauthorized();\n        }\n\n        return await next(context);\n    }\n}\n#endif\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Webhooks/Authorization/MollieSignatureFilter.cs",
    "content": "using Microsoft.AspNetCore.Mvc;\nusing Microsoft.AspNetCore.Mvc.Filters;\n\nnamespace Mollie.Api.AspNet.Webhooks.Authorization;\n\npublic class MollieSignatureFilter : IAsyncAuthorizationFilter\n{\n    private readonly MollieSignatureValidator _signatureValidator;\n\n    public MollieSignatureFilter(MollieSignatureValidator signatureValidator) {\n        _signatureValidator = signatureValidator;\n    }\n\n    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)\n    {\n        var request = context.HttpContext.Request;\n        bool isValid = await _signatureValidator.Validate(request);\n        if (!isValid) {\n            context.Result = new UnauthorizedResult();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Webhooks/Authorization/MollieSignatureValidator.cs",
    "content": "using System.Security.Cryptography;\nusing System.Text;\nusing Microsoft.AspNetCore.Http;\nusing Mollie.Api.AspNet.Webhooks.Options;\n\nnamespace Mollie.Api.AspNet.Webhooks.Authorization;\n\npublic class MollieSignatureValidator\n{\n    private readonly MollieWebhookOptions _options;\n\n    public MollieSignatureValidator(MollieWebhookOptions options) {\n        _options = options;\n\n        if (options == null) {\n            throw new ArgumentNullException(nameof(options));\n        }\n\n        if (string.IsNullOrWhiteSpace(options.Secret)) {\n            throw new ArgumentException(\"Webhook signing secret cannot be null or empty.\", nameof(MollieWebhookOptions.Secret));\n        }\n    }\n\n    /// <summary>\n    /// Validates the Mollie HMAC webhook signature in the given HTTP request.\n    /// </summary>\n    /// <param name=\"request\">Incoming HTTP request.</param>\n    /// <returns>True if the signature is valid; otherwise false.</returns>\n    public async Task<bool> Validate(HttpRequest request) {\n        if (!request.Headers.TryGetValue(\"X-Mollie-Signature\", out var headerValues))\n        {\n            return false;\n        }\n\n        var headerValue = headerValues.FirstOrDefault();\n        if (string.IsNullOrWhiteSpace(headerValue))\n        {\n            return false;\n        }\n\n        var bodyBytes = await GetRequestBodyBytes(request);\n        var isValid = ValidateHmacSignature(headerValue, bodyBytes, _options.Secret);\n\n        return isValid;\n    }\n\n    private bool ValidateHmacSignature(string headerValue, byte[] bodyBytes, string secret)\n    {\n        if (string.IsNullOrWhiteSpace(headerValue) || string.IsNullOrWhiteSpace(secret)) {\n            return false;\n        }\n\n        // Step 1: Remove optional prefix \"sha256=\" (case-insensitive)\n        const string prefix = \"sha256=\";\n        var sig = headerValue.Trim();\n        if (sig.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) {\n            sig = sig.Substring(prefix.Length);\n        }\n\n        // Step 2: parse header signature bytes\n        byte[] signatureBytes;\n        try\n        {\n            signatureBytes = HexToBytes(sig);\n        }\n        catch\n        {\n            return false;\n        }\n\n        // Step 3: compute HMAC-SHA256 over raw body bytes (secret as UTF8)\n        using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));\n        var computed = hmac.ComputeHash(bodyBytes);\n\n        // Step 4: timing-safe compare\n        if (computed.Length != signatureBytes.Length) {\n            return false;\n        }\n\n        return CryptographicOperations.FixedTimeEquals(computed, signatureBytes);\n    }\n\n    private static byte[] HexToBytes(string hex)\n    {\n        var len = hex.Length / 2;\n        var bytes = new byte[len];\n        for (int i = 0; i < len; i++) {\n            bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);\n        }\n        return bytes;\n    }\n\n    private async Task<byte[]> GetRequestBodyBytes(HttpRequest request)\n    {\n        request.EnableBuffering();\n\n        request.Body.Position = 0;\n        var ms = new MemoryStream();\n\n        await request.Body.CopyToAsync(ms);\n        var bodyBytes = ms.ToArray();\n        request.Body.Seek(0, SeekOrigin.Begin);\n\n        return bodyBytes;\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Webhooks/ModelBinding/FromMollieWebhookAttribute.cs",
    "content": "using Microsoft.AspNetCore.Mvc;\n\nnamespace Mollie.Api.AspNet.Webhooks.ModelBinding;\n\npublic class FromMollieWebhookAttribute : ModelBinderAttribute\n{\n    public FromMollieWebhookAttribute() : base(typeof(FromMollieWebhookModelBinder)) { }\n}\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Webhooks/ModelBinding/FromMollieWebhookModelBinder.cs",
    "content": "using Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc.ModelBinding;\nusing Mollie.Api.Framework;\n\nnamespace Mollie.Api.AspNet.Webhooks.ModelBinding;\n\npublic class FromMollieWebhookModelBinder : IModelBinder {\n    private readonly JsonConverterService _jsonConverterService;\n\n    public FromMollieWebhookModelBinder() {\n        _jsonConverterService = new();\n    }\n\n    public async Task BindModelAsync(ModelBindingContext context)\n    {\n        var request = context.HttpContext.Request;\n        request.EnableBuffering();\n\n        using var reader = new StreamReader(request.Body);\n        var body = await reader.ReadToEndAsync();\n        request.Body.Position = 0;\n\n        try {\n            var result = _jsonConverterService.Deserialize(body, context.ModelType);\n            context.Result = ModelBindingResult.Success(result);\n        }\n        catch (Exception ex)\n        {\n            context.ModelState.AddModelError(context.ModelName, ex.Message);\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Webhooks/ModelBinding/MollieModelBinder.cs",
    "content": "using System.Reflection;\nusing Microsoft.AspNetCore.Http;\nusing Mollie.Api.Framework;\nusing Mollie.Api.Models;\n\nnamespace Mollie.Api.AspNet.Webhooks.ModelBinding;\n\npublic class MollieModelBinder<T> where T : IEntity {\n    public T? Model { get; init; }\n\n    public static async ValueTask<MollieModelBinder<T>?> BindAsync(HttpContext context, ParameterInfo parameter) {\n        JsonConverterService jsonConverterService = new();\n\n        var request = context.Request;\n        request.EnableBuffering();\n\n        var reader = new StreamReader(request.Body);\n        var body = await reader.ReadToEndAsync();\n        request.Body.Position = 0;\n\n        try {\n            var result = jsonConverterService.Deserialize<T>(body);\n            return new MollieModelBinder<T>() {\n                Model = result\n            };\n        }\n        catch (Exception) {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Mollie.Api.AspNet/Webhooks/Options/MollieWebhookOptions.cs",
    "content": "namespace Mollie.Api.AspNet.Webhooks.Options;\n\npublic record MollieWebhookOptions {\n    public string Secret { get; set; } = string.Empty;\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/ApiExceptionTests.cs",
    "content": "﻿using System.Net;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Connect.Request;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class ApiExceptionTests : BaseMollieApiTestClass {\n    private readonly IPaymentClient _paymentClient;\n    private readonly IConnectClient _connectClient;\n\n    public ApiExceptionTests(IPaymentClient paymentClient, IConnectClient connectClient) {\n        _paymentClient = paymentClient;\n        _connectClient = connectClient;\n    }\n\n    [Fact]\n    public async Task CreatePayment_WithInvalidParameters_ShouldThrowMollieApiException() {\n        // Given: we create a payment request with invalid parameters\n        var paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = string.Empty,\n            RedirectUrl = null\n        };\n\n        // Then: Send the payment request to the Mollie Api, this should throw a mollie api exception\n        MollieApiException apiException = await Assert.ThrowsAsync<MollieApiException>(() => _paymentClient.CreatePaymentAsync(paymentRequest));\n        apiException.ShouldNotBeNull();\n        apiException.Details.ShouldNotBeNull();\n        apiException.Details.Status.ShouldBe(422);\n        apiException.Details.Title.ShouldBe(\"Unprocessable Entity\");\n        apiException.Details.Detail.ShouldBe(\"The description is invalid\");\n    }\n\n    [Fact]\n    public async Task RevokeTokenAsync_WithInvalidToken_ShouldThrowMollieApiException() {\n        // Given\n        var tokenRequest = new RevokeTokenRequest {\n            Token = \"token\",\n            TokenTypeHint = \"hint\"\n        };\n\n        // Then\n        MollieApiException apiException = await Assert.ThrowsAsync<MollieApiException>(() => _connectClient.RevokeTokenAsync(tokenRequest));\n        apiException.Details.Title.ShouldBe(\"invalid_request\");\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/BalanceTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models.Balance.Response.BalanceReport;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\n[Trait(\"TestCategory\", \"LocalIntegrationTests\")]\npublic class BalanceTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IBalanceClient _balanceClient;\n\n    public BalanceTests(IBalanceClient balanceClient) {\n        _balanceClient = balanceClient;\n    }\n\n    [Fact]\n    public async Task GetPrimaryBalanceAsync_IsParsedCorrectly() {\n        // When: We retrieve the primary balance from the Mollie API\n        var result = await _balanceClient.GetPrimaryBalanceAsync();\n\n        // Then: Make sure we can parse the result\n        result.ShouldNotBeNull();\n        result.Resource.ShouldBe(\"balance\");\n        result.Currency.ShouldNotBeNull();\n        result.Id.ShouldNotBeNull();\n        result.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/balances-api/get-primary-balance\");\n        result.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/balances/{result.Id}\");\n        result.TransferFrequency.ShouldNotBeNull();\n        result.AvailableAmount.ShouldNotBeNull();\n        result.PendingAmount.ShouldNotBeNull();\n        result.TransferThreshold.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task GetBalanceAsync_IsParsedCorrectly() {\n        // Given: We get a balance id from the list balances endpoint\n        var balanceList = await _balanceClient.GetBalanceListAsync();\n        if (balanceList.Count == 0) {\n            Assert.Fail(\"No balance found to retrieve\");\n        }\n        var firstBalance = balanceList.Items.First();\n\n        // When: We retrieve a specific balance from the Mollie API\n        var result = await _balanceClient.GetBalanceAsync(firstBalance.Id);\n\n        // Then: Make sure we can parse the result\n        result.ShouldNotBeNull();\n        result.Resource.ShouldBe(\"balance\");\n        result.AvailableAmount.ShouldBe(firstBalance.AvailableAmount);\n        result.Id.ShouldBe(firstBalance.Id);\n        result.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/balances-api/get-balance\");\n        result.Links.Self.Href.ShouldBe($\"https://api.mollie.com/v2/balances/{result.Id}\");\n        result.Currency.ShouldBe(firstBalance.Currency);\n        result.TransferFrequency.ShouldBe(firstBalance.TransferFrequency);\n        result.AvailableAmount.ShouldBe(firstBalance.AvailableAmount);\n        result.PendingAmount.ShouldBe(firstBalance.PendingAmount);\n        result.TransferThreshold.ShouldBe(firstBalance.TransferThreshold);\n    }\n\n    [Fact]\n    public async Task ListBalancesAsync_IsParsedCorrectly() {\n        // When: We retrieve the list of balances\n        var result = await _balanceClient.GetBalanceListAsync();\n\n        // Then: Make sure we can parse the result\n        result.ShouldNotBeNull();\n        result.Items.Count.ShouldBe(result.Count);\n    }\n\n    [Theory]\n    [InlineData(ReportGrouping.TransactionCategories, typeof(TransactionCategoriesReportResponse))]\n    [InlineData(ReportGrouping.StatusBalances, typeof(StatusBalanceReportResponse))]\n    public async Task GetBalanceReportAsync_IsParsedCorrectly(string grouping, Type expectedObjectType) {\n        // Given: We retrieve the primary balance\n        var from = new DateTime(2022, 11, 1);\n        var until = new DateTime(2022, 11, 30);\n        var primaryBalance = await _balanceClient.GetPrimaryBalanceAsync();\n\n        // When: We retrieve the primary balance report\n        var result = await _balanceClient.GetBalanceReportAsync(\n            balanceId: primaryBalance.Id,\n            from: from,\n            until: until,\n            grouping: grouping);\n\n        // Then: Make sure we can parse the result\n        result.ShouldNotBeNull();\n        result.ShouldBeOfType(expectedObjectType);\n        result.Resource.ShouldBe(\"balance-report\");\n        result.BalanceId.ShouldBe(primaryBalance.Id);\n        result.From.ShouldBe(from);\n        result.Until.ShouldBe(until);\n        result.Grouping.ShouldBe(grouping);\n    }\n\n    [Fact]\n    public async Task ListBalanceTransactionsAsync_IsParsedCorrectly() {\n        // Given\n        var balanceId = \"bal_CKjKwQdjCwCSArXFAJNFH\";\n        var from = \"baltr_9S8yk4FFqqi2Qm6K3rqRH\";\n        var limit = 250;\n\n        // When: We list the balance transactions\n        var result = await _balanceClient.GetBalanceTransactionListAsync(balanceId, from, limit);\n\n        // Then: Make sure we can parse the result\n        result.ShouldNotBeNull();\n        result.Items.ShouldNotBeNull();\n        result.Links.ShouldNotBeNull();\n        result.Links.Self.Href.ShouldBe($\"https://api.mollie.com/v2/balances/{balanceId}/transactions?from={from}&limit={limit}\");\n    }\n\n    [Fact]\n    public async Task ListPrimaryBalanceTransactionsAsync_IsParsedCorrectly() {\n        // Given\n        var from = \"baltr_9S8yk4FFqqi2Qm6K3rqRH\";\n        var limit = 250;\n\n        // When: We list the balance transactions\n        var result = await _balanceClient.GetPrimaryBalanceTransactionListAsync(from, limit);\n\n        // Then: Make sure we can parse the result\n        result.ShouldNotBeNull();\n        result.Items.ShouldNotBeNull();\n    }\n\n    public void Dispose()\n    {\n        _balanceClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/CaptureTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Capture;\nusing Mollie.Api.Models.Capture.Request;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class CaptureTests : BaseMollieApiTestClass, IDisposable {\n    private readonly ICaptureClient _captureClient;\n    private readonly IPaymentClient _paymentClient;\n\n    public CaptureTests(\n        ICaptureClient captureClient,\n        IPaymentClient paymentClient) {\n        _captureClient = captureClient;\n        _paymentClient = paymentClient;\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we actually have to use the PaymentUrl\" +\n                             \" to make the payment, since Mollie can only capture payments that have been authorized\")]\n    public async Task CanCreateCaptureForPaymentWithManualCaptureMode() {\n        // Given: We create a payment with captureMode set to manual\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, 1000.00m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Method = PaymentMethod.CreditCard,\n            CaptureMode = CaptureMode.Manual\n        };\n        var payment = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // When: We create a capture for the payment\n        var captureRequest = new CaptureRequest\n        {\n            Amount = new Amount(Currency.EUR, 0.01m),\n            Description = \"my capture\",\n            Metadata = \"my-metadata string\"\n        };\n        var capture = await _captureClient.CreateCapture(payment.Id, captureRequest);\n\n        // Then: The capture should be created\n        capture.Status.ShouldBe(\"pending\");\n        capture.PaymentId.ShouldBe(payment.Id);\n        capture.Resource.ShouldBe(\"capture\");\n        capture.Metadata.ShouldBe(captureRequest.Metadata);\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we actually have to use the PaymentUrl\" +\n                             \" to make the payment, since Mollie can only capture payments that have been authorized\")]\n    public async Task CanRetrieveCaptureListForPayment()\n    {\n        // Given: we create a payment and capture\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, 1000.00m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Method = PaymentMethod.CreditCard,\n            CaptureMode = CaptureMode.Manual\n        };\n        var payment = await _paymentClient.CreatePaymentAsync(paymentRequest);\n        var captureRequest = new CaptureRequest\n        {\n            Amount = new Amount(Currency.EUR, 0.01m),\n            Description = \"my capture\",\n            Metadata = \"my-metadata string\"\n        };\n        await _captureClient.CreateCapture(payment.Id, captureRequest);\n\n        // When: we retrieve the captures of the payment\n        var captureList = await _captureClient.GetCaptureListAsync(payment.Id);\n\n        // Then\n        captureList.Count.ShouldBe(1);\n        var capture = captureList.Items.Single();\n        capture.Status.ShouldBe(\"succeeded\");\n        capture.PaymentId.ShouldBe(payment.Id);\n        capture.Resource.ShouldBe(\"capture\");\n        capture.Metadata.ShouldBe(captureRequest.Metadata);\n    }\n\n    public void Dispose()\n    {\n        _captureClient?.Dispose();\n        _paymentClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/ConnectTests.cs",
    "content": "﻿using Mollie.Api.Client;\nusing Mollie.Tests.Integration.Framework;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client.Abstract;\nusing Shouldly;\nusing Mollie.Api.Models.Connect.Request;\nusing Mollie.Api.Models.Connect.Response;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class ConnectTests : BaseMollieApiTestClass {\n    private readonly IConnectClient _connectClient;\n\n    public ConnectTests(IConnectClient connectClient) {\n        _connectClient = connectClient;\n    }\n\n    [Fact]\n    public void GetAuthorizationUrl_WithSingleScope_GeneratesAuthorizationUrl() {\n        // When: We get the authorization URL\n        string authorizationUrl = _connectClient.GetAuthorizationUrl(\"abcde\", new List<string>() { AppPermissions.PaymentsRead });\n\n        // Then:\n        string expectedUrl = $\"https://my.mollie.com/oauth2/authorize?client_id={ClientId}&state=abcde&scope=payments.read&response_type=code&approval_prompt=auto\";\n        authorizationUrl.ShouldBe(expectedUrl);\n    }\n\n    [Fact]\n    public void GetAuthorizationUrl_WithMultipleScopes_GeneratesAuthorizationUrl() {\n        // When: We get the authorization URL\n        string authorizationUrl = _connectClient.GetAuthorizationUrl(\"abcdef\", new List<string>() {\n            AppPermissions.PaymentsRead,\n            AppPermissions.PaymentsWrite,\n            AppPermissions.ProfilesRead,\n            AppPermissions.ProfilesWrite\n        });\n\n        // Then:\n        string expectedUrl = $\"https://my.mollie.com/oauth2/authorize?client_id={ClientId}\" +\n                             $\"&state=abcdef&scope=payments.read+payments.write+profiles.read+profiles.write&response_type=code&approval_prompt=auto\";\n        authorizationUrl.ShouldBe(expectedUrl);\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we login to the mollie dashboard and login to get the auth token\")]\n    public async Task GetAccessTokenAsync_WithValidTokenRequest_ReturnsAccessToken() {\n        // Given: We fetch create a token request\n        string authCode = \"abcde\"; // Set a valid access token here\n        using ConnectClient connectClient = new ConnectClient(ClientId, ClientSecret);\n        TokenRequest tokenRequest = new TokenRequest(authCode, DefaultRedirectUrl);\n\n        // When: We request the auth code\n        TokenResponse tokenResponse = await connectClient.GetAccessTokenAsync(tokenRequest);\n\n        // Then: The access token should not be null\n        tokenResponse.AccessToken.ShouldNotBeNullOrEmpty();\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we need a valid access token\")]\n    public async Task RevokeAccessTokenAsync_WithValidToken_DoesNotThrowError() {\n        // Given: We create a revoke token request\n        string accessToken = \"abcde\";\n        using ConnectClient connectClient = new ConnectClient(ClientId, ClientSecret);\n        RevokeTokenRequest revokeTokenRequest = new RevokeTokenRequest() {\n            TokenTypeHint = TokenType.AccessToken,\n            Token = accessToken\n        };\n\n        // When: we send the request\n        await connectClient.RevokeTokenAsync(revokeTokenRequest);\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/CustomerTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Net;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Customer.Request;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class CustomerTests : BaseMollieApiTestClass, IDisposable {\n    private readonly ICustomerClient _customerClient;\n\n    public CustomerTests(ICustomerClient customerClient) {\n        _customerClient = customerClient;\n    }\n\n    [Fact]\n    public async Task CanRetrieveCustomerList() {\n        // When: Retrieve customer list with default settings\n        ListResponse<CustomerResponse> response = await _customerClient.GetCustomerListAsync();\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task ListCustomersNeverReturnsMoreCustomersThenTheNumberOfRequestedCustomers() {\n        // If: Number of customers requested is 5\n        int numberOfCustomers = 5;\n\n        // When: Retrieve 5 customers\n        ListResponse<CustomerResponse> response = await _customerClient.GetCustomerListAsync(null, numberOfCustomers);\n\n        // Then\n        numberOfCustomers.ShouldBe(response.Items.Count);\n    }\n\n    [Fact]\n    public async Task CanCreateNewCustomer() {\n        // If: We create a customer request with only the required parameters\n        string name = \"Smit\";\n        string email = \"johnsmit@mollie.com\";\n\n        // When: We send the customer request to Mollie\n        CustomerResponse result = await CreateCustomer(name, email);\n\n        // Then: Make sure the requested parameters match the response parameter values\n        result.ShouldNotBeNull();\n        result.Name.ShouldBe(name);\n        result.Email.ShouldBe(email);\n    }\n\n    [Fact]\n    public async Task CanUpdateCustomer() {\n        // If: We retrieve the customer list\n        ListResponse<CustomerResponse> response = await _customerClient.GetCustomerListAsync();\n\n        // When: We update one of the customers in the list\n        string customerIdToUpdate = response.Items.First().Id;\n        string newCustomerName = DateTime.Now.ToShortTimeString();\n        CustomerRequest updateParameters = new CustomerRequest() {\n            Name = newCustomerName\n        };\n        CustomerResponse result = await _customerClient.UpdateCustomerAsync(customerIdToUpdate, updateParameters);\n\n        // Then: Make sure the new name is updated\n        result.ShouldNotBeNull();\n        result.Name.ShouldBe(newCustomerName);\n    }\n\n    [Fact]\n    public async Task CanDeleteCustomer() {\n        // If: We retrieve the customer list\n        ListResponse<CustomerResponse> response = await _customerClient.GetCustomerListAsync();\n\n        // When: We delete one of the customers in the list\n        string customerIdToDelete = response.Items.First().Id;\n        await _customerClient.DeleteCustomerAsync(customerIdToDelete);\n\n        // Then: Make sure its deleted after one second\n        await Task.Delay(TimeSpan.FromSeconds(1));\n        MollieApiException apiException = await Assert.ThrowsAsync<MollieApiException>(() => _customerClient.GetCustomerAsync(customerIdToDelete));\n        apiException.Details.Status.ShouldBe((int)HttpStatusCode.Gone);\n    }\n\n    [Fact]\n    public async Task CanGetCustomerByUrlObject() {\n        // If: We create a customer request with only the required parameters\n        string name = \"Smit\";\n        string email = \"johnsmit@mollie.com\";\n        CustomerResponse createdCustomer = await CreateCustomer(name, email);\n\n        // When: We try to retrieve the customer by Url object\n        CustomerResponse retrievedCustomer = await ExecuteWithRetry(() => _customerClient.GetCustomerAsync(createdCustomer.Links.Self));\n\n        // Then: Make sure it's retrieved\n        retrievedCustomer.Name.ShouldBe(createdCustomer.Name);\n        retrievedCustomer.Email.ShouldBe(createdCustomer.Email);\n    }\n\n    [Fact]\n    public async Task CanCreateCustomerWithJsonMetadata() {\n        // If: We create a customer request with json metadata\n        var customerRequest = new CustomerRequest() {\n            Email =  \"johnsmit@mollie.com\",\n            Name = \"Smit\",\n            Metadata =  \"{\\\"order_id\\\":\\\"4.40\\\"}\",\n            Locale = Locale.nl_NL\n        };\n\n        // When: We try to retrieve the customer by Url object\n        CustomerResponse retrievedCustomer = await _customerClient.CreateCustomerAsync(customerRequest);\n\n        // Then: Make sure it's retrieved\n        IsJsonResultEqual(customerRequest.Metadata, retrievedCustomer.Metadata).ShouldBeTrue();\n    }\n\n    [Fact]\n    public async Task CanCreateCustomerWithStringMetadata() {\n        // If: We create a customer request with string metadata\n        CustomerRequest customerRequest = new CustomerRequest() {\n            Email = \"johnsmit@mollie.com\",\n            Name = \"Smit\",\n            Metadata = \"This is my metadata\",\n            Locale = Locale.nl_NL\n        };\n\n        // When: We try to retrieve the customer by Url object\n        CustomerResponse retrievedCustomer = await _customerClient.CreateCustomerAsync(customerRequest);\n\n        // Then: Make sure it's retrieved\n        retrievedCustomer.Metadata.ShouldBe(customerRequest.Metadata);\n    }\n\n    [Fact]\n    public async Task CanCreateNewCustomerPayment() {\n        // If: We create a customer request with only the required parameters\n        string name = \"Smit\";\n        string email = \"johnsmit@mollie.com\";\n        CustomerResponse customer = await CreateCustomer(name, email);\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We create a payment request for this customer to Mollie\n        PaymentResponse paymentResponse = await _customerClient.CreateCustomerPayment(customer.Id, paymentRequest);\n\n        // Then: Make sure the requested parameters match the response parameter values\n        paymentResponse.ShouldNotBeNull();\n        paymentResponse.CustomerId.ShouldBe(customer.Id);\n    }\n\n    private async Task<CustomerResponse> CreateCustomer(string name, string email) {\n        CustomerRequest customerRequest = new CustomerRequest() {\n            Email = email,\n            Name = name,\n            Locale = Locale.nl_NL\n        };\n\n        return await _customerClient.CreateCustomerAsync(customerRequest);\n    }\n\n    public void Dispose()\n    {\n        _customerClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/MandateTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Mandate.Request;\nusing Mollie.Api.Models.Mandate.Request.PaymentSpecificParameters;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Mandate.Response.PaymentSpecificParameters;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Response.PaymentSpecificParameters;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class MandateTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IMandateClient _mandateClient;\n    private readonly ICustomerClient _customerClient;\n\n    public MandateTests(IMandateClient mandateClient, ICustomerClient customerClient) {\n        _mandateClient = mandateClient;\n        _customerClient = customerClient;\n    }\n\n    [Fact]\n    public async Task CanRetrieveMandateList() {\n        // We can only test this if there are customers\n        ListResponse<CustomerResponse> customers = await _customerClient.GetCustomerListAsync();\n\n        if (customers.Count > 0) {\n            // When: Retrieve mandate list with default settings\n            ListResponse<MandateResponse> response = await _mandateClient.GetMandateListAsync(customers.Items.First().Id);\n\n            // Then\n            response.ShouldNotBeNull();\n            response.Items.ShouldNotBeNull();\n        }\n    }\n\n    [Fact]\n    public async Task ListMandatesNeverReturnsMoreCustomersThenTheNumberOfRequestedMandates() {\n        // We can only test this if there are customers\n        ListResponse<CustomerResponse> customers = await _customerClient.GetCustomerListAsync();\n\n        if (customers.Count > 0) {\n            // If: Number of customers requested is 5\n            int numberOfMandates = 5;\n\n            // When: Retrieve 5 mandates\n            ListResponse<MandateResponse> response = await _mandateClient.GetMandateListAsync(customers.Items.First().Id, null, numberOfMandates);\n\n            // Then\n            numberOfMandates.ShouldBeGreaterThanOrEqualTo(response.Items.Count);\n        }\n    }\n\n    [Fact]\n    public async Task CanCreateSepaDirectDebitMandate() {\n        // We can only test this if there are customers\n        ListResponse<CustomerResponse> customers = await _customerClient.GetCustomerListAsync();\n        if (customers.Count > 0) {\n            // If: We create a new mandate request\n            SepaDirectDebitMandateRequest mandateRequest = new () {\n                ConsumerAccount = \"NL26ABNA0516682814\",\n                ConsumerName = \"John Doe\",\n                Method = PaymentMethod.DirectDebit\n            };\n\n            // When: We send the mandate request\n            MandateResponse mandateResponse = await _mandateClient.CreateMandateAsync(customers.Items.First().Id, mandateRequest);\n\n            // Then: Make sure we created a new mandate\n            mandateResponse.ShouldBeOfType<SepaDirectDebitMandateResponse>();\n            var sepaDirectDebitResponse = (SepaDirectDebitMandateResponse)mandateResponse;\n            sepaDirectDebitResponse.Details.ConsumerAccount.ShouldBe(mandateRequest.ConsumerAccount);\n            sepaDirectDebitResponse.Details.ConsumerName.ShouldBe(mandateRequest.ConsumerName);\n        }\n    }\n\n    public void Dispose()\n    {\n        _mandateClient?.Dispose();\n        _customerClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/OrderTests.cs",
    "content": "﻿using System;\n#pragma warning disable CS0618\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Order;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Order.Request.ManageOrderLines;\nusing Mollie.Api.Models.Order.Request.PaymentSpecificParameters;\nusing Mollie.Api.Models.Order.Response;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\nusing SortDirection = Mollie.Api.Models.SortDirection;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class OrderTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IOrderClient _orderClient;\n\n    public OrderTests(IOrderClient orderClient) {\n        _orderClient = orderClient;\n    }\n\n    [Fact]\n    public async Task GetOrderListAsync_WithoutSortOrder_ReturnsOrdersInDescendingOrder()\n    {\n        // Act\n        var orders = await _orderClient.GetOrderListAsync();\n\n        // Assert\n        if (orders.Items.Any())\n        {\n            orders.Items.Select(x => x.CreatedAt).ShouldBeInOrder(Shouldly.SortDirection.Descending);\n        }\n    }\n\n    [Fact]\n    public async Task GetOrderListAsync_InDescendingOrder_ReturnsOrdersInDescendingOrder()\n    {\n        // Act\n        var orders = await _orderClient.GetOrderListAsync(sort: SortDirection.Desc);\n\n        // Assert\n        if (orders.Items.Any())\n        {\n            orders.Items.Select(x => x.CreatedAt).ShouldBeInOrder(Shouldly.SortDirection.Descending);\n        }\n    }\n\n    [Fact]\n    public async Task GetOrderListAsync_InAscendingOrder_ReturnsOrdersInAscendingOrder()\n    {\n        // Act\n        var orders = await _orderClient.GetOrderListAsync(sort: SortDirection.Asc);\n\n        // Assert\n        if (orders.Items.Any())\n        {\n            orders.Items.Select(x => x.CreatedAt).ShouldBeInOrder(Shouldly.SortDirection.Ascending);\n        }\n    }\n\n    [Fact]\n    public async Task CreateOrderAsync_OrderWithRequiredFields_OrderIsCreated() {\n        // If: we create a order request with only the required parameters\n        OrderRequest orderRequest = CreateOrder();\n\n        // When: We send the order request to Mollie\n        OrderResponse result = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(orderRequest.Amount);\n        result.OrderNumber.ShouldBe(orderRequest.OrderNumber);\n        result.Lines.Count().ShouldBe(orderRequest.Lines.Count());\n        result.Links.ShouldNotBeNull();\n        OrderLineRequest orderLineRequest = orderRequest.Lines.First();\n        OrderLineResponse orderResponseLine = result.Lines.First();\n        orderResponseLine.Type.ShouldBe(orderLineRequest.Type);\n        orderResponseLine.Links.ImageUrl!.Href.ShouldBe(orderLineRequest.ImageUrl);\n        orderResponseLine.Links.ProductUrl!.Href.ShouldBe(orderLineRequest.ProductUrl);\n        var expectedMetadataString = result.Lines.First().Metadata;\n        orderResponseLine.Metadata.ShouldBe(expectedMetadataString);\n    }\n\n    [Fact]\n    public async Task CreateOrderAsync_OrderWithExtendedFields_OrderIsCreated() {\n        // If: we create a order request\n        OrderRequest orderRequest = CreateOrder();\n        orderRequest.ConsumerDateOfBirth = new DateTime(1980, 1, 1);\n        orderRequest.ExpiresAt = DateTime.Now.AddDays(2);\n\n        // When: We send the order request to Mollie\n        OrderResponse result = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.ConsumerDateOfBirth.ShouldBe(orderRequest.ConsumerDateOfBirth);\n        result.ExpiresAt!.Value.Date.ShouldBe(orderRequest.ExpiresAt.Value.Date);\n    }\n\n    [Fact]\n    public async Task CreateOrderAsync_OrderWithApplicationFee_OrderIsCreated() {\n        // If: we create a order request with only the required parameters\n        OrderRequest orderRequest = CreateOrder() with {\n            Payment = new OrderPaymentParameters {\n                ApplicationFee = new ApplicationFee {\n                    Amount = new Amount(Currency.EUR, 0.25m),\n                    Description = \"Test\"\n                }\n            }\n        };\n\n        // When: We send the order request to Mollie\n        OrderResponse result = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(orderRequest.Amount);\n        result.OrderNumber.ShouldBe(orderRequest.OrderNumber);\n        result.Lines.Count().ShouldBe(orderRequest.Lines.Count());\n        result.Links.ShouldNotBeNull();\n        OrderLineRequest orderLineRequest = orderRequest.Lines.First();\n        OrderLineResponse orderResponseLine = result.Lines.First();\n        orderResponseLine.Type.ShouldBe(orderLineRequest.Type);\n        orderResponseLine.Links.ImageUrl!.Href.ShouldBe(orderLineRequest.ImageUrl);\n        orderResponseLine.Links.ProductUrl!.Href.ShouldBe(orderLineRequest.ProductUrl);\n        var expectedMetadataString = result.Lines.First().Metadata;\n        orderResponseLine.Metadata.ShouldBe(expectedMetadataString);\n    }\n\n    [Fact]\n    public async Task CreateOrderAsync_WithMultiplePaymentMethods_OrderIsCreated() {\n        // When: we create a order request and specify multiple payment methods\n        OrderRequest orderRequest = CreateOrder();\n        orderRequest.Methods = new List<string>() {\n            PaymentMethod.Ideal,\n            PaymentMethod.CreditCard,\n            PaymentMethod.DirectDebit\n        };\n\n        // When: We send the order request to Mollie\n        OrderResponse result = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(orderRequest.Amount);\n        result.OrderNumber.ShouldBe(orderRequest.OrderNumber);\n    }\n\n    [Fact]\n    public async Task CreateOrderAsync_WithSinglePaymentMethod_OrderIsCreated() {\n        // When: we create a order request and specify a single payment method\n        OrderRequest orderRequest = CreateOrder();\n        orderRequest.Method = PaymentMethod.CreditCard;\n\n        // When: We send the order request to Mollie\n        OrderResponse result = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // Then: Make sure we get a valid response\n        orderRequest.Method.ShouldBe(PaymentMethod.CreditCard);\n        orderRequest.Methods!.First().ShouldBe(PaymentMethod.CreditCard);\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(orderRequest.Amount);\n        result.OrderNumber.ShouldBe(orderRequest.OrderNumber);\n    }\n\n    public static IEnumerable<object[]> PaymentSpecificParameters =>\n        new List<object[]>\n        {\n            new object[] {\n                new KlarnaSpecificParameters<object> {\n                    ExtraMerchantData = new {\n                        payment_history_simple = new[] {\n                            new {\n                                unique_account_identifier = \"Adam Adamsson\",\n                                paid_before = true\n                            }\n                        }\n                    }\n                }\n            },\n            new object[] {\n                new BillieSpecificParameters {\n                    Company = new CompanyObject {\n                        EntityType = CompanyEntityType.LimitedCompany,\n                        RegistrationNumber = \"registration-number\",\n                        VatNumber = \"vat-number\"\n                    }\n                }\n            },\n            new object[] {\n                new GiftcardSpecificParameters() {\n                    Issuer = \"boekenbon\",\n                    VoucherNumber = \"voucher-number\",\n                    VoucherPin = \"1234\"\n                }\n            },\n            new object[] {\n                new IDealSpecificParameters {\n                    Issuer = \"ideal_INGBNL2A\"\n                }\n            },\n            new object[] {\n                new KbcSpecificParameters {\n                    Issuer = \"ideal_INGBNL2A\"\n                }\n            },\n            new object[] {\n                new PaySafeCardSpecificParameters {\n                    CustomerReference = \"customer-reference\"\n                }\n            },\n            new object[] {\n                new SepaDirectDebitSpecificParameters {\n                    ConsumerAccount = \"Consumer account\"\n                }\n            }\n        };\n\n    [Theory]\n    [MemberData(nameof(PaymentSpecificParameters))]\n    public async Task CreateOrderAsync_WithPaymentSpecificParameters_OrderIsCreated(\n        OrderPaymentParameters paymentSpecificParameters) {\n\n        // If: we create a order request with payment specific parameters\n        OrderRequest orderRequest = CreateOrder();\n        orderRequest.BillingAddress!.Country = \"DE\"; // Billie only works in Germany\n        orderRequest.BillingAddress.OrganizationName = \"Mollie\"; // Billie requires a organization name\n        orderRequest.Payment = paymentSpecificParameters;\n\n        // When: We send the order request to Mollie\n        OrderResponse result = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(orderRequest.Amount);\n        result.OrderNumber.ShouldBe(orderRequest.OrderNumber);\n    }\n\n    [Fact]\n    public async Task GetOrderAsync_OrderIsCreated_OrderCanBeRetrieved() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We attempt to retrieve the order\n        OrderResponse retrievedOrder = await _orderClient.GetOrderAsync(createdOrder.Id);\n\n        // Then: Make sure we get a valid response\n        retrievedOrder.ShouldNotBeNull();\n        retrievedOrder.Id.ShouldBe(createdOrder.Id);\n    }\n\n    [Fact]\n    public async Task GetOrderAsync_WithUrlObject_OrderCanBeRetrieved() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We attempt to retrieve the order\n        OrderResponse retrievedOrder = await _orderClient.GetOrderAsync(createdOrder.Links.Self);\n\n        // Then: Make sure we get a valid response\n        retrievedOrder.ShouldNotBeNull();\n        retrievedOrder.Id.ShouldBe(createdOrder.Id);\n    }\n\n    [Fact]\n    public async Task GetOrderAsync_WithIncludeParameters_OrderIsRetrievedWithEmbeddedData() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We attempt to retrieve the order and add the include parameters\n        OrderResponse retrievedOrder = await _orderClient.GetOrderAsync(createdOrder.Id, embedPayments: true, embedShipments: true, embedRefunds: true);\n\n        // Then: Make sure we get a valid response\n        retrievedOrder.ShouldNotBeNull();\n        retrievedOrder.Id.ShouldBe(createdOrder.Id);\n        retrievedOrder.Embedded.ShouldNotBeNull();\n        retrievedOrder.Embedded!.Payments.ShouldNotBeNull();\n        retrievedOrder.Embedded.Shipments.ShouldNotBeNull();\n        retrievedOrder.Embedded.Refunds.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task UpdateOrderAsync_OrderIsUpdated_OrderIsUpdated() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We attempt to update the order\n        OrderUpdateRequest orderUpdateRequest = new() {\n            OrderNumber = \"1337\",\n            BillingAddress = createdOrder.BillingAddress\n        };\n        OrderResponse updatedOrder = await _orderClient.UpdateOrderAsync(createdOrder.Id, orderUpdateRequest);\n\n        // Then: Make sure the order is updated\n        updatedOrder.OrderNumber.ShouldBe(orderUpdateRequest.OrderNumber);\n    }\n\n    [Fact(Skip = \"Broken - Reported to Mollie: https://discordapp.com/channels/1037712581407817839/1180467187677401198/1180467187677401198\")]\n    public async Task UpdateOrderLinesAsync_WhenOrderLineIsUpdated_UpdatedPropertiesCanBeRetrieved() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We update the order line\n        OrderLineUpdateRequest updateRequest = new() {\n            Name = \"A fluffy bear\"\n        };\n        OrderResponse updatedOrder = await _orderClient.UpdateOrderLinesAsync(createdOrder.Id, createdOrder.Lines.First().Id, updateRequest);\n\n        // Then: The name of the order line should be updated\n        updatedOrder.Lines.First().Name.ShouldBe(updateRequest.Name);\n    }\n\n    [Fact]\n    public async Task ManageOrderLinesAsync_AddOperation_OrderLineIsAdded() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We use the manager order lines endpoint to add a order line\n        ManageOrderLinesAddOperationData newOrderLineRequest = new() {\n            Name = \"LEGO Batman mobile\",\n            Type = OrderLineDetailsType.Physical,\n            Category = VoucherCategory.Gift,\n            Quantity = 1,\n            UnitPrice = new Amount(Currency.EUR, 100.00m),\n            TotalAmount = new Amount(Currency.EUR, 100.00m),\n            VatRate = \"21.00\",\n            VatAmount = new Amount(Currency.EUR, 17.36m),\n            ImageUrl = \"http://www.google.com/legobatmanimage\",\n            ProductUrl = \"http://www.mollie.nl/legobatmanproduct\",\n            Metadata = \"{\\\"is_lego_awesome\\\":\\\"fosho\\\"}\",\n        };\n        ManageOrderLinesRequest manageOrderLinesRequest = new() {\n            Operations = new List<ManageOrderLinesOperation> {\n                new ManageOrderLinesAddOperation {\n                    Data = newOrderLineRequest\n                }\n            }\n        };\n        OrderResponse updatedOrder = await _orderClient.ManageOrderLinesAsync(createdOrder.Id, manageOrderLinesRequest);\n\n        // Then: The order line should be added\n        updatedOrder.Lines.Count().ShouldBe(2);\n        var addedOrderLineRequest = updatedOrder.Lines.SingleOrDefault(line => line.Name == newOrderLineRequest.Name);\n        addedOrderLineRequest.ShouldNotBeNull();\n        addedOrderLineRequest!.Type.ShouldBe(newOrderLineRequest.Type);\n        addedOrderLineRequest.Quantity.ShouldBe(newOrderLineRequest.Quantity);\n        addedOrderLineRequest.UnitPrice.ShouldBe(newOrderLineRequest.UnitPrice);\n        addedOrderLineRequest.TotalAmount.ShouldBe(newOrderLineRequest.TotalAmount);\n        addedOrderLineRequest.VatRate.ShouldBe(newOrderLineRequest.VatRate);\n        addedOrderLineRequest.VatAmount.ShouldBe(newOrderLineRequest.VatAmount);\n        var newMetaData = addedOrderLineRequest.Metadata!\n            .Replace(Environment.NewLine, \"\")\n            .Replace(\" \", \"\");\n        newMetaData.ShouldBe(newOrderLineRequest.Metadata);\n    }\n\n    [Fact]\n    public async Task ManageOrderLinesAsync_UpdateOperation_OrderLineIsUpdated() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We use the manager order lines endpoint to update a order line\n        ManageOrderLinesUpdateOperationData orderLineUpdateRequest = new() {\n            Id = createdOrder.Lines.First().Id,\n            Name = \"LEGO Batman mobile\",\n            Quantity = 1,\n            UnitPrice = new Amount(Currency.EUR, 100.00m),\n            TotalAmount = new Amount(Currency.EUR, 90.00m),\n            VatRate = \"21.00\",\n            VatAmount = new Amount(Currency.EUR, 15.62m),\n            ImageUrl = \"http://www.google.com/legobatmanimage\",\n            ProductUrl = \"http://www.mollie.nl/legobatmanproduct\",\n            Metadata = \"{\\\"is_lego_awesome\\\":\\\"fosho\\\"}\",\n            Sku = \"Sku\",\n            DiscountAmount = new Amount(Currency.EUR, 10m)\n        };\n        ManageOrderLinesRequest manageOrderLinesRequest = new() {\n            Operations = new List<ManageOrderLinesOperation> {\n                new ManageOrderLinesUpdateOperation {\n                    Data = orderLineUpdateRequest\n                }\n            }\n        };\n        OrderResponse updatedOrder = await _orderClient.ManageOrderLinesAsync(createdOrder.Id, manageOrderLinesRequest);\n\n        // Then: The order line should be updated\n        updatedOrder.Lines.Count().ShouldBe(1);\n        var addedOrderLineRequest = updatedOrder.Lines.SingleOrDefault(line => line.Name == orderLineUpdateRequest.Name);\n        addedOrderLineRequest.ShouldNotBeNull();\n        addedOrderLineRequest!.Quantity.ShouldBe(orderLineUpdateRequest.Quantity.Value);\n        addedOrderLineRequest.UnitPrice.ShouldBe(orderLineUpdateRequest.UnitPrice);\n        addedOrderLineRequest.TotalAmount.ShouldBe(orderLineUpdateRequest.TotalAmount);\n        addedOrderLineRequest.VatRate.ShouldBe(orderLineUpdateRequest.VatRate);\n        addedOrderLineRequest.VatAmount.ShouldBe(orderLineUpdateRequest.VatAmount);\n        addedOrderLineRequest.Metadata!\n            .Replace(Environment.NewLine, \"\")\n            .Replace(\" \", \"\")\n            .ShouldBe(orderLineUpdateRequest.Metadata);\n    }\n\n    [Fact]\n    public async Task ManageOrderLinesAsync_CancelOperation_OrderLineIsCanceled() {\n        // If: we create a new order\n        OrderRequest orderRequest = CreateOrder();\n        OrderResponse createdOrder = await _orderClient.CreateOrderAsync(orderRequest);\n\n        // When: We use the manager order lines endpoint to cancel a order line\n        ManagerOrderLinesCancelOperationData orderLineCancelRequest = new() {\n            Id = createdOrder.Lines.First().Id,\n            Quantity = 1\n        };\n        ManageOrderLinesRequest manageOrderLinesRequest = new() {\n            Operations = new List<ManageOrderLinesOperation> {\n                new ManageOrderLinesCancelOperation {\n                    Data = orderLineCancelRequest\n                }\n            }\n        };\n        OrderResponse updatedOrder = await _orderClient.ManageOrderLinesAsync(createdOrder.Id, manageOrderLinesRequest);\n\n        // Then: The order line should be canceled\n        updatedOrder.Lines.Count().ShouldBe(1);\n        var updatedOrderLineRequest = updatedOrder.Lines.Single();\n        updatedOrderLineRequest.Status.ShouldBe(OrderStatus.Canceled);\n    }\n\n    [Fact]\n    public async Task GetOrderListAsync_NoParameters_OrderListIsRetrieved() {\n        // When: Retrieve orders list with default settings\n        ListResponse<OrderResponse> response = await _orderClient.GetOrderListAsync();\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task GetOrderListAsync_WithMaximumNumberOfItems_MaximumNumberOfOrdersIsReturned() {\n        // If: Number of orders requested is 5\n        int numberOfOrders = 5;\n\n        // When: Retrieve 5 orders\n        ListResponse<OrderResponse> response = await _orderClient.GetOrderListAsync(null, numberOfOrders);\n\n        // Then\n        response.Items.Count.ShouldBeLessThanOrEqualTo(numberOfOrders);\n    }\n\n    private OrderRequest CreateOrder() {\n        return new OrderRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            OrderNumber = \"16738\",\n            Lines = new List<OrderLineRequest>() {\n                new() {\n                    Name = \"A box of chocolates\",\n                    Type = OrderLineDetailsType.Physical,\n                    Category = VoucherCategory.Gift,\n                    Quantity = 1,\n                    UnitPrice = new Amount(Currency.EUR, \"100.00\"),\n                    TotalAmount = new Amount(Currency.EUR, \"100.00\"),\n                    VatRate = \"21.00\",\n                    VatAmount = new Amount(Currency.EUR, \"17.36\"),\n                    ImageUrl = \"http://www.google.com/\",\n                    ProductUrl = \"http://www.mollie.nl/\",\n                    Metadata =  \"{\\\"order_id\\\":\\\"4.40\\\"}\",\n                }\n            },\n            BillingAddress = new OrderAddressDetails() {\n                GivenName = \"John\",\n                FamilyName = \"Smit\",\n                Email = \"johnsmit@gmail.com\",\n                City = \"Rotterdam\",\n                Country = \"NL\",\n                PostalCode = \"0000AA\",\n                Region = \"Zuid-Holland\",\n                StreetAndNumber = \"Coolsingel 1\"\n            },\n            RedirectUrl = \"http://www.google.nl\",\n            Locale = Locale.nl_NL\n        };\n    }\n\n    public void Dispose()\n    {\n        _orderClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/PaymentLinkTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Extensions;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.PaymentLink.Request;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class PaymentLinkTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IPaymentLinkClient _paymentLinkClient;\n\n    public PaymentLinkTests(IPaymentLinkClient paymentLinkClient) {\n        _paymentLinkClient = paymentLinkClient;\n    }\n\n    [Fact]\n    public async Task CanRetrievePaymentLinkList() {\n        // When: Retrieve payment list with default settings\n        ListResponse<PaymentLinkResponse> response = await _paymentLinkClient.GetPaymentLinkListAsync();\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentLinkAndRetrieveIt() {\n        // Given: We create a new payment link\n        var address = CreateAddress();\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount = new Amount(Currency.EUR, 50),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            Reusable = true,\n            ExpiresAt = DateTime.Now.AddDays(1),\n            BillingAddress = address,\n            ShippingAddress = address\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We retrieve it\n        var retrievePaymentLinkResponse = await _paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect a payment link with the expected properties\n        var verifyPaymentLinkResponse = new Action<PaymentLinkResponse>(response => {\n            var expiresAtWithoutMs = paymentLinkRequest.ExpiresAt.Value.Truncate(TimeSpan.FromSeconds(1));\n\n            response.Amount.ShouldBe(paymentLinkRequest.Amount);\n            response.MinimumAmount.ShouldBeNull();\n            response.ExpiresAt.ShouldBe(expiresAtWithoutMs);\n            response.Description.ShouldBe(paymentLinkRequest.Description);\n            response.RedirectUrl.ShouldBe(paymentLinkRequest.RedirectUrl);\n            response.Archived.ShouldBeFalse();\n            response.Reusable.ShouldBe(paymentLinkRequest.Reusable);\n            response.BillingAddress.ShouldBe(paymentLinkRequest.BillingAddress);\n            response.ShippingAddress.ShouldBe(paymentLinkRequest.ShippingAddress);\n        });\n\n        verifyPaymentLinkResponse(createdPaymentLinkResponse);\n        verifyPaymentLinkResponse(retrievePaymentLinkResponse);\n    }\n\n\n    [Fact]\n    public async Task CanCreatePaymentLinkWithMinimumAmount() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            MinimumAmount = new Amount(Currency.EUR, 50),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            Reusable = true,\n            ExpiresAt = DateTime.Now.AddDays(1)\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We retrieve it\n        var retrievePaymentLinkResponse = await _paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect a payment link with the expected properties\n        var verifyPaymentLinkResponse = new Action<PaymentLinkResponse>(response => {\n            var expiresAtWithoutMs = paymentLinkRequest.ExpiresAt.Value.Truncate(TimeSpan.FromSeconds(1));\n\n            response.Amount.ShouldBeNull();\n            response.MinimumAmount.ShouldBe(paymentLinkRequest.MinimumAmount);\n            response.ExpiresAt.ShouldBe(expiresAtWithoutMs);\n            response.Description.ShouldBe(paymentLinkRequest.Description);\n            response.RedirectUrl.ShouldBe(paymentLinkRequest.RedirectUrl);\n            response.Archived.ShouldBeFalse();\n            response.Reusable.ShouldBe(paymentLinkRequest.Reusable);\n        });\n\n        verifyPaymentLinkResponse(createdPaymentLinkResponse);\n        verifyPaymentLinkResponse(retrievePaymentLinkResponse);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentLinkForRecurringPayments() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount = new Amount(Currency.EUR, 50),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            Reusable = true,\n            ExpiresAt = DateTime.Now.AddDays(1),\n            SequenceType = SequenceType.First\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We retrieve it\n        var retrievePaymentLinkResponse = await _paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect a payment link with the expected properties\n        var verifyPaymentLinkResponse = new Action<PaymentLinkResponse>(response => {\n            var expiresAtWithoutMs = paymentLinkRequest.ExpiresAt.Value.Truncate(TimeSpan.FromSeconds(1));\n\n            response.Amount.ShouldBe(paymentLinkRequest.Amount);\n            response.ExpiresAt.ShouldBe(expiresAtWithoutMs);\n            response.Description.ShouldBe(paymentLinkRequest.Description);\n            response.RedirectUrl.ShouldBe(paymentLinkRequest.RedirectUrl);\n            response.Archived.ShouldBeFalse();\n            response.Reusable.ShouldBe(paymentLinkRequest.Reusable);\n            response.SequenceType.ShouldBe(paymentLinkRequest.SequenceType);\n        });\n\n        verifyPaymentLinkResponse(createdPaymentLinkResponse);\n        verifyPaymentLinkResponse(retrievePaymentLinkResponse);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentLinkWithLines() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount = new Amount(Currency.EUR, 90m),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            Reusable = false,\n            ExpiresAt = DateTime.Now.AddDays(1),\n            Lines = new List<PaymentLine> {\n                new() {\n                    Type = OrderLineDetailsType.Digital,\n                    Description = \"Star wars lego\",\n                    Quantity = 1,\n                    QuantityUnit = \"pcs\",\n                    UnitPrice = new Amount(Currency.EUR, 100m),\n                    TotalAmount = new Amount(Currency.EUR, 90m),\n                    DiscountAmount = new Amount(Currency.EUR, 10m),\n                    ProductUrl = \"http://www.lego.com/starwars\",\n                    ImageUrl = \"http://www.lego.com/starwars.jpg\",\n                    Sku = \"my-sku\",\n                    VatAmount = new Amount(Currency.EUR, 15.62m),\n                    VatRate = \"21.00\"\n                }\n            }\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We retrieve it\n        var retrievePaymentLinkResponse = await _paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect a payment link with the expected properties\n        var verifyPaymentLinkResponse = new Action<PaymentLinkResponse>(response => {\n            var expiresAtWithoutMs = paymentLinkRequest.ExpiresAt.Value.Truncate(TimeSpan.FromSeconds(1));\n\n            response.Amount.ShouldBe(paymentLinkRequest.Amount);\n            response.ExpiresAt.ShouldBe(expiresAtWithoutMs);\n            response.Description.ShouldBe(paymentLinkRequest.Description);\n            response.RedirectUrl.ShouldBe(paymentLinkRequest.RedirectUrl);\n            response.Archived.ShouldBeFalse();\n            response.Reusable.ShouldBe(paymentLinkRequest.Reusable);\n            response.Lines.ShouldBe(paymentLinkRequest.Lines);\n        });\n\n        verifyPaymentLinkResponse(createdPaymentLinkResponse);\n        verifyPaymentLinkResponse(retrievePaymentLinkResponse);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentLinkWithNullAmount() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount =  null,\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            ExpiresAt = DateTime.Now.AddDays(1)\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We retrieve it\n        var retrievePaymentLinkResponse = await _paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect a payment link with the expected properties\n        var verifyPaymentLinkResponse = new Action<PaymentLinkResponse>(response => {\n            var expiresAtWithoutMs = paymentLinkRequest.ExpiresAt.Value.Truncate(TimeSpan.FromSeconds(1));\n\n            response.Amount.ShouldBeNull();\n            response.ExpiresAt.ShouldBe(expiresAtWithoutMs);\n            response.Description.ShouldBe(paymentLinkRequest.Description);\n            response.RedirectUrl.ShouldBe(paymentLinkRequest.RedirectUrl);\n        });\n\n        verifyPaymentLinkResponse(createdPaymentLinkResponse);\n        verifyPaymentLinkResponse(retrievePaymentLinkResponse);\n    }\n\n\n    [Fact]\n    public async Task CanCreatePaymentLinkWithSpecificPaymentMethods() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount = new Amount(Currency.EUR, 50),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            ExpiresAt = DateTime.Now.AddDays(1),\n            AllowedMethods = [PaymentMethod.Ideal, PaymentMethod.CreditCard]\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We retrieve it\n        var retrievePaymentLinkResponse = await _paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect a payment link with the expected properties\n        var verifyPaymentLinkResponse = new Action<PaymentLinkResponse>(response => {\n            var expiresAtWithoutMs = paymentLinkRequest.ExpiresAt.Value.Truncate(TimeSpan.FromSeconds(1));\n\n            response.Amount.ShouldBe(paymentLinkRequest.Amount);\n            response.ExpiresAt.ShouldBe(expiresAtWithoutMs);\n            response.Description.ShouldBe(paymentLinkRequest.Description);\n            response.RedirectUrl.ShouldBe(paymentLinkRequest.RedirectUrl);\n            response.Archived.ShouldBeFalse();\n            response.AllowedMethods.ShouldBe(paymentLinkRequest.AllowedMethods);\n        });\n\n        verifyPaymentLinkResponse(createdPaymentLinkResponse);\n        verifyPaymentLinkResponse(retrievePaymentLinkResponse);\n    }\n\n    [Fact]\n    public async Task CanUpdatePaymentLink() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount = new Amount(Currency.EUR, 50),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            ExpiresAt = DateTime.Now.AddDays(1)\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We update the payment link\n        PaymentLinkUpdateRequest paymentLinkUpdateRequest = new() {\n            Description = \"Updated description\",\n            Archived = true,\n            AllowedMethods = [PaymentMethod.CreditCard]\n        };\n        var updatedPaymentLinkResponse = await _paymentLinkClient.UpdatePaymentLinkAsync(\n            createdPaymentLinkResponse.Id,\n            paymentLinkUpdateRequest);\n\n        // Then: We expect the payment link to be updated\n        updatedPaymentLinkResponse.Description.ShouldBe(paymentLinkUpdateRequest.Description);\n        updatedPaymentLinkResponse.Archived.ShouldBe(paymentLinkUpdateRequest.Archived);\n        updatedPaymentLinkResponse.AllowedMethods.ShouldBe(paymentLinkUpdateRequest.AllowedMethods);\n    }\n\n    [Fact]\n    public async Task CanDeletePaymentLink() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount = new Amount(Currency.EUR, 50),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            ExpiresAt = DateTime.Now.AddDays(1)\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We delete the payment link\n        await _paymentLinkClient.DeletePaymentLinkAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect the payment link to be updated\n        MollieApiException exception = await Assert.ThrowsAsync<MollieApiException>(() =>\n            _paymentLinkClient.GetPaymentLinkAsync(createdPaymentLinkResponse.Id));\n        exception.Details.Status.ShouldBe(404);\n        exception.Details.Detail.ShouldBe(\"Resource not found\");\n    }\n\n    [Fact]\n    public async Task CanListPaymentLinkPayments() {\n        // Given: We create a new payment link\n        PaymentLinkRequest paymentLinkRequest = new() {\n            Description = \"Test\",\n            Amount = new Amount(Currency.EUR, 50),\n            WebhookUrl = DefaultWebhookUrl,\n            RedirectUrl = DefaultRedirectUrl,\n            ExpiresAt = DateTime.Now.AddDays(1)\n        };\n        var createdPaymentLinkResponse = await _paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n        // When: We get the payment list of the payment link\n        var result = await _paymentLinkClient.GetPaymentLinkPaymentListAsync(createdPaymentLinkResponse.Id);\n\n        // Then: We expect the payment list to be returned\n        result.ShouldNotBeNull();\n        result.Items.Count.ShouldBe(0);\n    }\n\n    private PaymentAddressDetails CreateAddress() {\n        return new PaymentAddressDetails {\n            Title = \"Mr\",\n            GivenName = \"John\",\n            FamilyName = \"Doe\",\n            OrganizationName = \"Mollie\",\n            StreetAndNumber = \"Keizersgracht 126\",\n            Email = \"johndoe@mollie.com\",\n            City = \"Amsterdam\",\n            Country = \"NL\",\n            Phone = \"+31600000000\",\n            Region = \"Zuid-Holland\",\n            PostalCode = \"1015CW\"\n        };\n    }\n\n    public void Dispose()\n    {\n        _paymentLinkClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/PaymentMethodTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.PaymentMethod.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class PaymentMethodTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IPaymentMethodClient _paymentMethodClient;\n\n    public PaymentMethodTests(IPaymentMethodClient paymentMethodClient) {\n        _paymentMethodClient = paymentMethodClient;\n    }\n\n    [Fact]\n    public async Task CanRetrievePaymentMethodList() {\n        // When: Retrieve payment list with default settings\n        ListResponse<PaymentMethodResponse> response = await _paymentMethodClient.GetPaymentMethodListAsync();\n\n        // Then: Make sure it can be retrieved\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task CanRetrievePaymentMethodListIncludeWallets() {\n        // When: Retrieve payment list with default settings\n        ListResponse<PaymentMethodResponse> response = await _paymentMethodClient.GetPaymentMethodListAsync(includeWallets: \"applepay\");\n\n        // Then: Make sure it can be retrieved\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Theory]\n    [InlineData(PaymentMethod.GooglePay)]\n    public async Task CanRetrieveSinglePaymentMethod(string method) {\n        // When: retrieving a payment method\n        PaymentMethodResponse paymentMethod = await _paymentMethodClient.GetPaymentMethodAsync(method);\n\n        // Then: Make sure it can be retrieved\n        paymentMethod.ShouldNotBeNull();\n        paymentMethod.Id.ShouldBe(method);\n    }\n\n    [Fact]\n    public async Task CanRetrieveKbcIssuers() {\n        // When: retrieving the ideal method we can include the issuers\n        PaymentMethodResponse paymentMethod = await _paymentMethodClient.GetPaymentMethodAsync(PaymentMethod.Kbc, true);\n\n        // Then: We should have one or multiple issuers\n        paymentMethod.ShouldNotBeNull();\n        paymentMethod.Issuers.ShouldNotBeEmpty();\n    }\n\n    [Fact]\n    public async Task DoNotRetrieveIssuersWhenIncludeIsFalse() {\n        // When: retrieving the ideal method with the include parameter set to false\n        PaymentMethodResponse paymentMethod = await _paymentMethodClient.GetPaymentMethodAsync(PaymentMethod.Kbc);\n\n        // Then: Issuers should not be included\n        paymentMethod.Issuers.ShouldBeNull();\n    }\n\n    [Fact]\n    public async Task CanRetrieveAllMethods() {\n        // When: retrieving the all mollie payment methods\n        ListResponse<PaymentMethodResponse> paymentMethods = await _paymentMethodClient.GetAllPaymentMethodListAsync();\n\n        // Then: We should have multiple issuers\n        paymentMethods.ShouldNotBeNull();\n        paymentMethods.Items.ShouldNotBeEmpty();\n    }\n\n    [Fact]\n    public async Task CanRetrievePricingForAllMethods() {\n        // When: retrieving the ideal method we can include the issuers\n        ListResponse<PaymentMethodResponse> paymentMethods = await _paymentMethodClient.GetAllPaymentMethodListAsync(includePricing: true);\n\n        // Then: We should have prices available\n        paymentMethods.Items.All(x => x.Pricing != null && x.Pricing.Any(y => y.Fixed.Value > 0)).ShouldBeTrue();\n    }\n\n    [Fact]\n    public async Task CanRetrieveIssuersForAllMethods() {\n        // When: retrieving the all mollie payment methods we can include the issuers\n        ListResponse<PaymentMethodResponse> paymentMethods = await _paymentMethodClient.GetAllPaymentMethodListAsync(includeIssuers: true);\n\n        // Then: We should have one or multiple issuers\n        paymentMethods.Items.ShouldContain(x => x.Issuers != null);\n    }\n\n    [Fact]\n    public async Task CanRetrieveIssuersAndPricingInformation() {\n        // When: retrieving the all mollie payment methods we can include the issuers\n        ListResponse<PaymentMethodResponse> paymentMethods = await _paymentMethodClient.GetAllPaymentMethodListAsync(includeIssuers: true, includePricing: true);\n\n        // Then: We should have one or multiple issuers\n        paymentMethods.Items.ShouldContain(x => x.Issuers != null);\n        paymentMethods.Items.ShouldContain(x => x.Pricing != null && x.Pricing.Any(y => y.Fixed.Value > 0));\n    }\n\n    [Theory]\n    [InlineData(\"JPY\", 249)]\n    [InlineData(\"EUR\", 50.25)]\n    public async Task GetPaymentMethodListAsync_WithVariousCurrencies_ReturnsAvailablePaymentMethods(string currency, decimal value) {\n        // When: Retrieving the payment methods for a currency and amount\n        var amount = new Amount(currency, value);\n        var paymentMethods = await _paymentMethodClient.GetPaymentMethodListAsync(amount: amount);\n\n        // Then: We should have multiple payment methods\n        paymentMethods.Count.ShouldBeGreaterThan(0);\n    }\n\n    public void Dispose()\n    {\n        _paymentMethodClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/PaymentTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Capture;\nusing Mollie.Api.Models.Capture.Request;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Tests.Integration.Framework;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Shouldly;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Payment.Request.PaymentSpecificParameters;\nusing Mollie.Api.Models.Payment.Response.PaymentSpecificParameters;\nusing Mollie.Api.Models.Terminal.Response;\nusing Xunit;\nusing SortDirection = Mollie.Api.Models.SortDirection;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class PaymentTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IPaymentClient _paymentClient;\n    private readonly ICustomerClient _customerClient;\n    private readonly IMandateClient _mandateClient;\n    private readonly ITerminalClient _terminalClient;\n    private readonly ICaptureClient _captureClient;\n\n    public PaymentTests(\n        IPaymentClient paymentClient,\n        ICustomerClient customerClient,\n        IMandateClient mandateClient,\n        ITerminalClient terminalClient,\n        ICaptureClient captureClient) {\n        _paymentClient = paymentClient;\n        _customerClient = customerClient;\n        _mandateClient = mandateClient;\n        _terminalClient = terminalClient;\n        _captureClient = captureClient;\n    }\n\n    [Fact]\n    public async Task CanRetrievePaymentList() {\n        // When: Retrieve payment list with default settings\n        ListResponse<PaymentResponse> response = await _paymentClient.GetPaymentListAsync();\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n        response.Items.Select(x => x.CreatedAt).ShouldBeInOrder(Shouldly.SortDirection.Descending);\n    }\n\n    [Fact]\n    public async Task CanRetrievePaymentListInDescendingOrder()\n    {\n        // When: Retrieve payment list in ascending order\n        ListResponse<PaymentResponse> response = await _paymentClient.GetPaymentListAsync(sort: SortDirection.Desc);\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n        response.Items.Select(x => x.CreatedAt).ShouldBeInOrder(Shouldly.SortDirection.Descending);\n    }\n\n    [Fact]\n    public async Task CanRetrievePaymentListInAscendingOrder()\n    {\n        // When: Retrieve payment list in ascending order\n        ListResponse<PaymentResponse> response = await _paymentClient.GetPaymentListAsync(sort: SortDirection.Asc);\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n        response.Items.Select(x => x.CreatedAt).ShouldBeInOrder(Shouldly.SortDirection.Ascending);\n    }\n\n    [Fact]\n    public async Task ListPaymentsNeverReturnsMorePaymentsThenTheNumberOfRequestedPayments() {\n        // Given: Number of payments requested is 5\n        int numberOfPayments = 5;\n\n        // When: Retrieve 5 payments\n        ListResponse<PaymentResponse> response = await _paymentClient.GetPaymentListAsync(null, numberOfPayments);\n\n        // Then\n        response.Items.Count.ShouldBeLessThanOrEqualTo(numberOfPayments);\n    }\n\n    [Fact]\n    public async Task CanCreateDefaultPaymentWithOnlyRequiredFields() {\n        // Given: we create a payment request with only the required parameters\n        var paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n    }\n\n    [Fact]\n    public async Task CanCreateDefaultPaymentWithCustomIdempotencyKey() {\n        // Given: we create a payment request with only the required parameters\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We send the payment request to Mollie\n        using (_paymentClient.WithIdempotencyKey(\"my-idempotency-key\"))\n        {\n            PaymentResponse firstAttempt = await _paymentClient.CreatePaymentAsync(paymentRequest);\n            PaymentResponse secondAttempt = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n            // Then: Make sure the responses have the same payment Id\n            firstAttempt.Id.ShouldBe(secondAttempt.Id);\n        }\n    }\n\n    [Fact]\n    public async Task CanCreateDefaultPaymentWithAllFields() {\n        // Given: we create a payment request where all parameters have a value\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Locale = Locale.nl_NL,\n            Metadata = \"{\\\"firstName\\\":\\\"John\\\",\\\"lastName\\\":\\\"Doe\\\"}\",\n            Method = PaymentMethod.BankTransfer,\n            WebhookUrl = DefaultWebhookUrl\n        };\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then: Make sure all requested parameters match the response parameter values\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n        result.Locale.ShouldBe(paymentRequest.Locale);\n        result.WebhookUrl.ShouldBe(paymentRequest.WebhookUrl);\n        IsJsonResultEqual(result.Metadata, paymentRequest.Metadata).ShouldBeTrue();\n    }\n\n    [Fact]\n    public async Task CanUpdatePayment() {\n        // Given: We create a payment with only the required parameters\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // When: We update this payment\n        PaymentUpdateRequest paymentUpdateRequest = new PaymentUpdateRequest() {\n            Description = \"Updated description\",\n            Metadata = \"My metadata\"\n        };\n        PaymentResponse updatedPayment = await _paymentClient.UpdatePaymentAsync(result.Id, paymentUpdateRequest);\n\n        // Then: Make sure the payment is updated\n        updatedPayment.Description.ShouldBe(paymentUpdateRequest.Description);\n        updatedPayment.Metadata.ShouldBe(paymentUpdateRequest.Metadata);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithSinglePaymentMethod() {\n        // Given: we create a payment request and specify multiple payment methods\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Method = PaymentMethod.CreditCard\n        };\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n        result.Method.ShouldBe(paymentRequest.Method);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithMultiplePaymentMethods() {\n        // When: we create a payment request and specify multiple payment methods\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Methods = new List<string>() {\n                PaymentMethod.Ideal,\n                PaymentMethod.CreditCard,\n                PaymentMethod.DirectDebit\n            }\n        };\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n        result.Method.ShouldBeNull();\n    }\n\n    [Theory]\n    [InlineData(typeof(PaymentRequest), PaymentMethod.Bancontact, typeof(BancontactPaymentResponse))]\n    [InlineData(typeof(BankTransferPaymentRequest), PaymentMethod.BankTransfer, typeof(BankTransferPaymentResponse))]\n    [InlineData(typeof(PayPalPaymentRequest), PaymentMethod.PayPal, typeof(PayPalPaymentResponse))]\n    [InlineData(typeof(PaymentRequest), PaymentMethod.Belfius, typeof(BelfiusPaymentResponse))]\n    [InlineData(typeof(PaymentRequest), PaymentMethod.Eps, typeof(EpsPaymentResponse))]\n    [InlineData(typeof(PaymentRequest), null, typeof(PaymentResponse))]\n    public async Task CanCreateSpecificPaymentType(Type paymentType, string paymentMethod, Type expectedResponseType) {\n        // When: we create a specific payment type with some bank transfer specific values\n        PaymentRequest paymentRequest = (PaymentRequest)Activator.CreateInstance(paymentType)!;\n        paymentRequest.Amount = new Amount(Currency.EUR, \"100.00\");\n        paymentRequest.Description = \"Description\";\n        paymentRequest.RedirectUrl = DefaultRedirectUrl;\n        paymentRequest.Method = paymentMethod;\n\n        // Set required billing email for Przelewy24\n        if (paymentRequest is Przelewy24PaymentRequest request) {\n            request.BillingEmail = \"example@example.com\";\n        }\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then: Make sure all requested parameters match the response parameter values\n        result.ShouldNotBeNull();\n        result.ShouldBeOfType(expectedResponseType);\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n        result.Method.ShouldBe(paymentRequest.Method);\n        result.Links.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentAndRetrieveIt() {\n        // When: we create a new payment request\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Locale = Locale.de_DE\n        };\n\n        // When: We send the payment request to Mollie and attempt to retrieve it\n        PaymentResponse paymentResponse = await _paymentClient.CreatePaymentAsync(paymentRequest);\n        PaymentResponse result = await _paymentClient.GetPaymentAsync(paymentResponse.Id);\n\n        // Then\n        result.ShouldNotBeNull();\n        result.Id.ShouldBe(paymentResponse.Id);\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n        result.Method.ShouldBe(paymentRequest.Method);\n    }\n\n    [Fact]\n    public async Task CanCreateRecurringPaymentAndRetrieveIt() {\n        // When: we create a new recurring payment\n        MandateResponse? mandate = await GetFirstValidMandate();\n        if (mandate != null) {\n            CustomerResponse customer = await _customerClient.GetCustomerAsync(mandate.Links.Customer);\n            PaymentRequest paymentRequest = new PaymentRequest() {\n                Amount = new Amount(Currency.EUR, \"100.00\"),\n                Description = \"Description\",\n                RedirectUrl = DefaultRedirectUrl,\n                SequenceType = SequenceType.First,\n                CustomerId = customer.Id\n            };\n\n            // When: We send the payment request to Mollie and attempt to retrieve it\n            PaymentResponse paymentResponse = await _paymentClient.CreatePaymentAsync(paymentRequest);\n            PaymentResponse result = await _paymentClient.GetPaymentAsync(paymentResponse.Id);\n\n            // Then: Make sure the recurringtype parameter is entered\n            result.SequenceType.ShouldBe(SequenceType.First);\n        }\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithMetaData() {\n        // When: We create a payment with meta data\n        string metadata = \"this is my metadata\";\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Metadata = metadata\n        };\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then: Make sure we get the same json result as metadata\n        result.Metadata.ShouldBe(metadata);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithJsonMetaData() {\n        // When: We create a payment with meta data\n        string json = \"{\\\"order_id\\\":\\\"4.40\\\"}\";\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Metadata = json\n        };\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then: Make sure we get the same json result as metadata\n        IsJsonResultEqual(result.Metadata, json).ShouldBeTrue();\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithCustomMetaDataClass() {\n        // When: We create a payment with meta data\n        CustomMetadataClass metadataRequest = new CustomMetadataClass() {\n            OrderId = 1,\n            Description = \"Custom description\"\n        };\n\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n        };\n        paymentRequest.SetMetadata(metadataRequest);\n\n        // When: We send the payment request to Mollie\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n        CustomMetadataClass? metadataResponse = result.GetMetadata<CustomMetadataClass>();\n\n        // Then: Make sure we get the same json result as metadata\n        metadataResponse.ShouldNotBeNull();\n        metadataResponse.OrderId.ShouldBe(metadataRequest.OrderId);\n        metadataResponse.Description.ShouldBe(metadataRequest.Description);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithLines() {\n        // Arrange\n        var address = new PaymentAddressDetails {\n            Title = \"Mr\",\n            GivenName = \"John\",\n            FamilyName = \"Doe\",\n            OrganizationName = \"Mollie\",\n            StreetAndNumber = \"Keizersgracht 126\",\n            Email = \"johndoe@mollie.com\",\n            City = \"Amsterdam\",\n            Country = \"NL\",\n            Phone = \"+31600000000\",\n            Region = \"Zuid-Holland\",\n            PostalCode = \"1015CW\"\n        };\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, 90m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Lines = new List<PaymentLine>() {\n                new() {\n                    Type = OrderLineDetailsType.Digital,\n                    Description = \"Star wars lego\",\n                    Quantity = 1,\n                    QuantityUnit = \"pcs\",\n                    UnitPrice = new Amount(Currency.EUR, 100m),\n                    TotalAmount = new Amount(Currency.EUR, 90m),\n                    DiscountAmount = new Amount(Currency.EUR, 10m),\n                    ProductUrl = \"http://www.lego.com/starwars\",\n                    ImageUrl = \"http://www.lego.com/starwars.jpg\",\n                    Sku = \"my-sku\",\n                    VatAmount = new Amount(Currency.EUR, 15.62m),\n                    VatRate = \"21.00\"\n                }\n            },\n            ShippingAddress = address,\n            BillingAddress = address\n        };\n\n        // Act\n        PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Assert\n        result.Lines.ShouldBeEquivalentTo(paymentRequest.Lines);\n        result.BillingAddress.ShouldBeEquivalentTo(paymentRequest.BillingAddress);\n        result.ShippingAddress.ShouldBeEquivalentTo(paymentRequest.ShippingAddress);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithMandate() {\n        // When: We create a payment with a mandate id\n        MandateResponse? validMandate = await GetFirstValidMandate();\n        if (validMandate != null) {\n            CustomerResponse customer = await _customerClient.GetCustomerAsync(validMandate.Links.Customer);\n            PaymentRequest paymentRequest = new PaymentRequest() {\n                Amount = new Amount(Currency.EUR, \"100.00\"),\n                Description = \"Description\",\n                RedirectUrl = DefaultRedirectUrl,\n                SequenceType = SequenceType.Recurring,\n                CustomerId = customer.Id,\n                MandateId = validMandate.Id\n            };\n\n            // When: We send the payment request to Mollie\n            PaymentResponse result = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n            // Then: Make sure we get the mandate id back in the details\n            result.MandateId.ShouldBe(validMandate.Id);\n            result.Links.Mandate!.Href.ShouldEndWith(validMandate.Id);\n            result.Links.Customer!.Href.ShouldEndWith(customer.Id);\n        }\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithDecimalAmountAndRetrieveIt() {\n        // When: we create a new payment request\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, 100.1235m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Locale = Locale.de_DE\n        };\n\n        // When: We send the payment request to Mollie and attempt to retrieve it\n        PaymentResponse paymentResponse = await _paymentClient.CreatePaymentAsync(paymentRequest);\n        PaymentResponse result = await _paymentClient.GetPaymentAsync(paymentResponse.Id);\n\n        // Then\n        result.ShouldNotBeNull();\n        result.Id.ShouldBe(paymentResponse.Id);\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithImplicitAmountCastAndRetrieveIt() {\n        var initialAmount = 100.75m;\n\n        // When: we create a new payment request\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, initialAmount),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Locale = Locale.de_DE\n        };\n\n        // When: We send the payment request to Mollie and attempt to retrieve it\n        PaymentResponse paymentResponse = await _paymentClient.CreatePaymentAsync(paymentRequest);\n        PaymentResponse result = await _paymentClient.GetPaymentAsync(paymentResponse.Id);\n\n        decimal responseAmount = paymentResponse.Amount; // Implicit cast\n        decimal resultAmount = result.Amount; // Implicit cast\n\n        // Then\n        result.ShouldNotBeNull();\n        result.Id.ShouldBe(paymentResponse.Id);\n        result.Amount.ShouldBe(paymentRequest.Amount);\n        result.Description.ShouldBe(paymentRequest.Description);\n        result.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n        resultAmount.ShouldBe(responseAmount);\n        resultAmount.ShouldBe(initialAmount);\n    }\n\n    [Fact]\n    public async Task CanCreatePointOfSalePayment() {\n        // Given\n        ListResponse<TerminalResponse> terminals = await _terminalClient.GetTerminalListAsync();\n        TerminalResponse? terminal = terminals.Items.FirstOrDefault();\n        if (terminal != null) {\n            string terminalId = terminals.Items.First().Id;\n            PointOfSalePaymentRequest paymentRequest = new() {\n                Amount = new Amount(Currency.EUR, 10m),\n                Description = \"Description\",\n                Method = PaymentMethod.PointOfSale,\n                TerminalId = terminalId\n            };\n\n            // When\n            PaymentResponse response = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n            // Then\n            response.ShouldNotBeNull();\n            response.Amount.ShouldBe(paymentRequest.Amount);\n            response.Description.ShouldBe(paymentRequest.Description);\n            response.RedirectUrl.ShouldBe(paymentRequest.RedirectUrl);\n            response.ShouldBeOfType<PointOfSalePaymentResponse>();\n            PointOfSalePaymentResponse posResponse = (PointOfSalePaymentResponse)response;\n            posResponse.Details!.TerminalId.ShouldBe(paymentRequest.TerminalId);\n            posResponse.Details.CardNumber.ShouldBeNull();\n            posResponse.Details.CardFingerprint.ShouldBeNull();\n            posResponse.Details.CardAudience.ShouldBeNull();\n            posResponse.Details.CardLabel.ShouldBeNull();\n            posResponse.Details.CardCountryCode.ShouldBeNull();\n            posResponse.Method.ShouldBe(PaymentMethod.PointOfSale);\n        }\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we have to set the payment status to authorized\")]\n    public async Task CanCreatePaymentWithManualCaptureMode() {\n        // Given\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, 10m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Method = PaymentMethod.CreditCard,\n            CaptureMode = CaptureMode.Manual\n        };\n\n        // When\n        PaymentResponse paymentResponse = await _paymentClient.CreatePaymentAsync(paymentRequest);\n        // Perform payment before API call\n        paymentResponse = await _paymentClient.GetPaymentAsync(paymentResponse.Id);\n        CaptureResponse captureResponse = await _captureClient.CreateCapture(paymentResponse.Id, new CaptureRequest {\n            Amount = new Amount(Currency.EUR, 10m),\n            Description = \"capture\"\n        });\n\n        // Then\n        captureResponse.ShouldNotBeNull();\n        paymentResponse.Status.ShouldBe(PaymentStatus.Authorized);\n        paymentRequest.CaptureMode.ShouldBe(CaptureMode.Manual);\n        paymentResponse.CaptureBefore.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task CanCreatePaymentWithCaptureDelay() {\n        // Given\n        PaymentRequest paymentRequest = new() {\n            Amount = new Amount(Currency.EUR, 10m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Method = PaymentMethod.CreditCard,\n            CaptureDelay = \"2 days\"\n        };\n\n        // When\n        PaymentResponse paymentResponse = await _paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        paymentResponse.CaptureDelay.ShouldBe(paymentRequest.CaptureDelay);\n    }\n\n    private async Task<MandateResponse?> GetFirstValidMandate() {\n        ListResponse<CustomerResponse> customers = await _customerClient.GetCustomerListAsync();\n\n        foreach (CustomerResponse customer in customers.Items) {\n            ListResponse<MandateResponse> customerMandates = await _mandateClient.GetMandateListAsync(customer.Id);\n            MandateResponse? firstValidMandate = customerMandates.Items.FirstOrDefault(x => x.Status == MandateStatus.Valid);\n            if (firstValidMandate != null) {\n                return firstValidMandate;\n            }\n        }\n\n        return null;\n    }\n\n    public void Dispose()\n    {\n        _paymentClient.Dispose();\n        _customerClient.Dispose();\n        _mandateClient.Dispose();\n        _terminalClient.Dispose();\n        _captureClient.Dispose();\n    }\n}\n\npublic record CustomMetadataClass {\n    public required int OrderId { get; init; }\n    public required string Description { get; init; }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/ProfileTests.cs",
    "content": "﻿\nusing System;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Profile.Response;\nusing Mollie.Tests.Integration.Framework;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.PaymentMethod.Response;\nusing Mollie.Api.Models.Profile.Request;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class ProfileTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IProfileClient _profileClient;\n\n    public ProfileTests(IProfileClient profileClient) {\n        _profileClient = profileClient;\n    }\n\n    [Fact]\n    public async Task GetCurrentProfileAsync_ReturnsCurrentProfile() {\n        // Given\n\n        // When: We retrieve the current profile from the mollie API\n        ProfileResponse profileResponse = await _profileClient.GetCurrentProfileAsync();\n\n        // Then: Make sure we get a valid response\n        profileResponse.ShouldNotBeNull();\n        profileResponse.Id.ShouldNotBeNullOrEmpty();\n        profileResponse.Email.ShouldNotBeNullOrEmpty();\n        profileResponse.Status.ShouldNotBeNullOrEmpty();\n    }\n\n    [Fact]\n    public async Task EnablePaymentMethodAsync_WhenEnablingPaymentMethodForCurrentProfile_PaymentMethodIsReturned() {\n        // Given\n\n        // When: We enable a payment method for the current profile\n        PaymentMethodResponse paymentMethodResponse = await _profileClient.EnablePaymentMethodAsync(PaymentMethod.CreditCard);\n\n        // Then: Make sure a payment method is returned\n        paymentMethodResponse.ShouldNotBeNull();\n        paymentMethodResponse.Id.ShouldBe(PaymentMethod.CreditCard);\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we need to retrieve a oauth access token to test this method\")]\n    public async Task EnablePaymentMethodAsync_WhenEnablingPaymentMethodForProfile_PaymentMethodIsReturned() {\n        // Given: We retrieve the profile from the API\n        ProfileClient profileClient = new ProfileClient(\"abcde\"); // Set access token\n        ListResponse<ProfileResponse> allProfiles = await profileClient.GetProfileListAsync();\n        if (allProfiles.Items.Count > 0) {\n            ProfileResponse profileToTestWith = allProfiles.Items.First();\n\n            // When: We enable a payment method for the given profile\n            PaymentMethodResponse paymentMethodResponse = await profileClient.EnablePaymentMethodAsync(profileToTestWith.Id, PaymentMethod.Ideal);\n\n            // Then: Make sure a payment method is returned\n            paymentMethodResponse.ShouldNotBeNull();\n            paymentMethodResponse.Id.ShouldBeNullOrEmpty();\n        }\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we need to retrieve a oauth access token to test this method\")]\n    public async Task CreateProfileAsync_WithDefaultParameters_CreatesProfile() {\n        // Given\n        ProfileRequest profileRequest = new ProfileRequest {\n            Email = \"test@test.com\",\n            Mode = Mode.Test,\n            Name = \"testuser\",\n            BusinessCategory = \"PET_SHOPS\",\n            Website = \"http://github.com\",\n            Phone = \"+31600000000\"\n        };\n        ProfileClient profileClient = new ProfileClient(\"accesstoken\"); // Set access token\n\n        // When: We create a new profile\n        ProfileResponse profileResponse = await profileClient.CreateProfileAsync(profileRequest);\n\n        // Then: Make sure the profile that is created matched the profile request\n        profileResponse.ShouldNotBeNull();\n    }\n\n    [Fact(Skip = \"Don't disable payment methods, other tests might break\")]\n    public async Task DisablePaymentMethodAsync_WhenDisablingPaymentMethodForCurrentProfile_NoErrorIsThrown() {\n        // Given\n\n        // When: We disable a payment method for the current profile\n        await _profileClient.DisablePaymentMethodAsync(PaymentMethod.CreditCard);\n\n        // Then\n    }\n\n    [Fact]\n    public async Task DisableGiftCardIssuerAsync_WhenDisablingGiftCardIssuerForCurrentProfile_NoErrorIsThrown() {\n        // Given\n\n        // When: We disable a issuer method for the current profile\n        await _profileClient.DisableGiftCardIssuerAsync(\"festivalcadeau\");\n\n        // Then\n    }\n\n    public void Dispose()\n    {\n        _profileClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/RefundTests.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Request.PaymentSpecificParameters;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Refund.Request;\nusing Mollie.Api.Models.Refund.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class RefundTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IRefundClient _refundClient;\n    private readonly IPaymentClient _paymentClient;\n\n    public RefundTests(IRefundClient refundClient, IPaymentClient paymentClient) {\n        _refundClient = refundClient;\n        _paymentClient = paymentClient;\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we actually have to use the PaymentUrl to make the payment, since Mollie can only refund payments that have been paid\")]\n    public async Task CanCreateRefund() {\n        // If: We create a payment\n        string amount = \"100.00\";\n        PaymentResponse payment = await CreatePayment(amount);\n\n        // We can only test this if you make the payment using the payment.Links.Checkout property.\n        // If you don't do this, this test will fail because we can only refund payments that have been paid\n        Debugger.Break();\n\n        // When: We attempt to refund this payment\n        RefundRequest refundRequest = new RefundRequest() {\n            Amount = new Amount(Currency.EUR, amount)\n        };\n        RefundResponse refundResponse = await _refundClient.CreatePaymentRefundAsync(payment.Id, refundRequest);\n\n        // Then\n        refundResponse.ShouldNotBeNull();\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we actually have to use the PaymentUrl to make the payment, since Mollie can only refund payments that have been paid\")]\n    public async Task CanCreatePartialRefund() {\n        // If: We create a payment of 250 euro\n        PaymentResponse payment = await CreatePayment(\"250.00\");\n\n        // We can only test this if you make the payment using the payment.Links.PaymentUrl property.\n        // If you don't do this, this test will fail because we can only refund payments that have been paid\n        Debugger.Break();\n\n        // When: We attempt to refund 50 euro\n        RefundRequest refundRequest = new RefundRequest() {\n            Amount = new Amount(Currency.EUR, \"50.00\")\n        };\n        RefundResponse refundResponse = await _refundClient.CreatePaymentRefundAsync(payment.Id, refundRequest);\n\n        // Then\n        refundResponse.Amount.ShouldBe(refundRequest.Amount);\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we actually have to use the PaymentUrl to make the payment, since Mollie can only refund payments that have been paid\")]\n    public async Task CanRetrieveSingleRefund() {\n        // If: We create a payment\n        PaymentResponse payment = await CreatePayment();\n        // We can only test this if you make the payment using the payment.Links.PaymentUrl property.\n        // If you don't do this, this test will fail because we can only refund payments that have been paid\n        Debugger.Break();\n\n        RefundRequest refundRequest = new RefundRequest() {\n            Amount = new Amount(Currency.EUR, \"50.00\")\n        };\n        RefundResponse refundResponse = await _refundClient.CreatePaymentRefundAsync(payment.Id, refundRequest);\n\n        // When: We attempt to retrieve this refund\n        RefundResponse result = await _refundClient.GetPaymentRefundAsync(payment.Id, refundResponse.Id);\n\n        // Then\n        result.ShouldNotBeNull();\n        result.Id.ShouldBe(refundResponse.Id);\n        refundResponse.Amount.ShouldBe(refundRequest.Amount);\n    }\n\n    [Fact]\n    public async Task CanRetrieveRefundList() {\n        // If: We create a payment\n        PaymentResponse payment = await CreatePayment();\n\n        // When: Retrieve refund list for this payment after one second\n        var test = await ExecuteWithRetry(() => _refundClient.GetPaymentRefundListAsync(payment.Id));\n        ListResponse<RefundResponse> refundList = await _refundClient.GetPaymentRefundListAsync(payment.Id);\n\n        // Then\n        refundList.ShouldNotBeNull();\n        refundList.Items.ShouldNotBeNull();\n    }\n\n    [Fact(Skip = \"We can only test this in debug mode, because we actually have to use the PaymentUrl to make the payment, since Mollie can only refund payments that have been paid\")]\n    public async Task CanCreateRefundWithMetaData() {\n        // If: We create a payment\n        string amount = \"100.00\";\n        PaymentResponse payment = await CreatePayment(amount);\n\n        // We can only test this if you make the payment using the payment.Links.Checkout property.\n        // If you don't do this, this test will fail because we can only refund payments that have been paid\n        Debugger.Break();\n\n        // When: We attempt to refund this payment with meta data.\n        var metadata = \"this is my metadata\";\n        RefundRequest refundRequest = new RefundRequest() {\n            Amount = new Amount(Currency.EUR, amount),\n            Metadata = metadata\n        };\n        RefundResponse refundResponse = await _refundClient.CreatePaymentRefundAsync(payment.Id, refundRequest);\n\n        // Then: Make sure we get the same json result as metadata\n        refundResponse.Metadata.ShouldBe(metadata);\n    }\n\n    private async Task<PaymentResponse> CreatePayment(string amount = \"100.00\") {\n        PaymentRequest paymentRequest = new PayPalPaymentRequest\n        {\n            Amount = new Amount(Currency.EUR, amount),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        return await _paymentClient.CreatePaymentAsync(paymentRequest);\n    }\n\n    public void Dispose()\n    {\n        _refundClient?.Dispose();\n        _paymentClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/SalesInvoiceTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Net;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.SalesInvoice;\nusing Mollie.Api.Models.SalesInvoice.Request;\nusing Mollie.Api.Models.SalesInvoice.Response;\nusing Mollie.Api.Models.Url;\nusing Mollie.Tests.Integration.Framework;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\n[Trait(\"TestCategory\", \"LocalIntegrationTests\")]\npublic class SalesInvoiceTests : BaseMollieApiTestClass, IDisposable {\n    private readonly ISalesInvoiceClient _salesInvoiceClient;\n\n    public SalesInvoiceTests(ISalesInvoiceClient salesInvoiceClient) {\n        _salesInvoiceClient = salesInvoiceClient;\n    }\n\n    [Fact]\n    public async Task CreateSalesInvoiceAsync_WithRequiredFields_SalesInvoiceIsCreated() {\n        // Given: We create a new sales invoice\n        var request = CreateSalesInvoiceRequest();\n\n        // When\n        var response = await _salesInvoiceClient.CreateSalesInvoiceAsync(request);\n\n        // Then\n        AssertSalesInvoice(request, response);\n    }\n\n    [Fact]\n    public async Task GetSalesInvoiceListAsync_NoParameters_SalesInvoiceListIsRetrieved() {\n        // When: Retrieve sales invoice list with default settings\n        ListResponse<SalesInvoiceResponse> response = await _salesInvoiceClient.GetSalesInvoiceListAsync();\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n        response.Links.ShouldNotBeNull();\n        response.Links.Self.Href.ShouldEndWith(\"sales-invoices\");\n    }\n\n    [Fact]\n    public async Task GetSalesInvoiceListAsync_WithObjectUrlLink_SalesInvoiceListIsRetrieved() {\n        // When: Retrieve sales invoice list with object URL link\n        var urlObjectLink = new UrlObjectLink<ListResponse<SalesInvoiceResponse>> {\n            Href = \"https://api.mollie.com/v2/sales-invoices\",\n            Type = \"application/hal+json\"\n        };\n        ListResponse<SalesInvoiceResponse> response = await _salesInvoiceClient.GetSalesInvoiceListAsync(urlObjectLink);\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n        response.Links.ShouldNotBeNull();\n        response.Links.Self.Href.ShouldEndWith(\"sales-invoices\");\n    }\n\n    [Fact]\n    public async Task GetSalesInvoiceListAsync_WithMaximumNumberOfItems_MaximumNumberOfSalesInvoicesIsReturned() {\n        // Given: Number of sales invoices requested is 5\n        int numberOfSalesInvoices = 5;\n\n        // When: Retrieve 5 sales invoices\n        ListResponse<SalesInvoiceResponse> response = await _salesInvoiceClient.GetSalesInvoiceListAsync(null, numberOfSalesInvoices);\n\n        // Then\n        response.Items.Count.ShouldBeLessThanOrEqualTo(numberOfSalesInvoices);\n    }\n\n    [Fact]\n    public async Task GetSalesInvoiceAsync_SalesInvoiceCanBeRetrieved() {\n        // Given: We create a new sales invoice\n        var salesInvoiceRequest = CreateSalesInvoiceRequest();\n        var createdSalesInvoice = await _salesInvoiceClient.CreateSalesInvoiceAsync(salesInvoiceRequest);\n\n        // When: We retrieve the sales invoice\n        var retrievedSalesInvoice = await _salesInvoiceClient.GetSalesInvoiceAsync(createdSalesInvoice.Id);\n\n        // Then: The retrieved sales invoice should match the created one\n        AssertSalesInvoice(salesInvoiceRequest, retrievedSalesInvoice);\n    }\n\n    [Fact]\n    public async Task GetSalesInvoiceAsync_WithObjectUrlLink_SalesInvoiceCanBeRetrieved() {\n        // Given: We create a new sales invoice\n        var salesInvoiceRequest = CreateSalesInvoiceRequest();\n        var createdSalesInvoice = await _salesInvoiceClient.CreateSalesInvoiceAsync(salesInvoiceRequest);\n\n        // When: We retrieve the sales invoice\n        var retrievedSalesInvoice = await _salesInvoiceClient.GetSalesInvoiceAsync(createdSalesInvoice.Links.Self);\n\n        // Then: The retrieved sales invoice should match the created one\n        AssertSalesInvoice(salesInvoiceRequest, retrievedSalesInvoice);\n    }\n\n    [Fact]\n    public async Task UpdateSalesInvoiceAsync_UpdatesSalesInvoice() {\n        // Given: We create a new sales invoice\n        var salesInvoiceRequest = CreateSalesInvoiceRequest();\n        var createdSalesInvoice = await _salesInvoiceClient.CreateSalesInvoiceAsync(salesInvoiceRequest);\n\n        // When: We update the sales invoice\n        var updatedSalesInvoiceRequest = new SalesInvoiceUpdateRequest {\n            Memo = \"Updated memo\"\n        };\n        var updatedSalesInvoice = await _salesInvoiceClient.UpdateSalesInvoiceAsync(createdSalesInvoice.Id, updatedSalesInvoiceRequest);\n\n        // Then: The updated sales invoice should match the updated request\n        updatedSalesInvoice.ShouldNotBeNull();\n        updatedSalesInvoice.Memo.ShouldBe(updatedSalesInvoiceRequest.Memo);\n        updatedSalesInvoice.Lines!.Count().ShouldBe(1);\n    }\n\n    [Fact]\n    public async Task DeleteSalesInvoiceAsync_DeletesSalesInvoice() {\n        // If: We retrieve a list of sales invoices\n        ListResponse<SalesInvoiceResponse> response = await _salesInvoiceClient.GetSalesInvoiceListAsync();\n\n        // When: We delete one of the sales invoices in the list\n        var salesInvoiceToDelete = response.Items.FirstOrDefault(x => x.Status == SalesInvoiceStatus.Draft);\n        if (salesInvoiceToDelete != null) {\n            await _salesInvoiceClient.DeleteSalesInvoiceAsync(salesInvoiceToDelete.Id);\n\n            // Then: Make sure the sales invoice is deleted\n            MollieApiException apiException = await Assert.ThrowsAsync<MollieApiException>(() =>\n                _salesInvoiceClient.GetSalesInvoiceAsync(salesInvoiceToDelete.Id));\n            apiException.Details.Status.ShouldBe((int)HttpStatusCode.NotFound);\n        }\n    }\n\n    private SalesInvoiceRequest CreateSalesInvoiceRequest() {\n        return new SalesInvoiceRequest {\n            WebhookUrl = \"https://github.com/Viincenttt/MollieApi\",\n            Status = SalesInvoiceStatus.Draft,\n            PaymentTerm = PaymentTerm.Days30,\n            VatMode = VatMode.Exclusive,\n            VatScheme = VatScheme.Standard,\n            Lines = new[] {\n                new SalesInvoiceLine {\n                    Description = \"Lego Batman\",\n                    Quantity = 1,\n                    VatRate = \"21.00\",\n                    UnitPrice = new Amount(Currency.EUR, 50m)\n                }\n            },\n            RecipientIdentifier = Guid.NewGuid().ToString(),\n            Recipient = new Recipient {\n                Type = RecipientType.Consumer,\n                Email = \"example@example.com\",\n                FamilyName = \"Smit\",\n                GivenName = \"Jan\",\n                StreetAndNumber = \"Keizersgracht 313\",\n                PostalCode = \"1234AB\",\n                City = \"Amsterdam\",\n                Country = \"NL\",\n                Locale = Locale.nl_NL\n            }\n        };\n    }\n\n    private void AssertSalesInvoice(SalesInvoiceRequest request, SalesInvoiceResponse response) {\n        response.ShouldNotBeNull();\n        response.Id.ShouldNotBeNullOrEmpty();\n        response.Resource.ShouldBe(\"sales-invoice\");\n        response.ProfileId.ShouldStartWith(\"pfl_\");\n        response.Status.ShouldBe(request.Status);\n        response.PaymentTerm.ShouldBe(request.PaymentTerm);\n        response.Lines.ShouldNotBeNull();\n        response.Lines.ShouldHaveSingleItem();\n        response.Lines.Single().ShouldBeEquivalentTo(response.Lines.Single());\n        response.Recipient.ShouldNotBeNull();\n        response.Recipient.Email.ShouldBe(request.Recipient.Email);\n        response.Recipient.FamilyName.ShouldBe(request.Recipient.FamilyName);\n        response.Recipient.GivenName.ShouldBe(request.Recipient.GivenName);\n        response.Recipient.StreetAndNumber.ShouldBe(request.Recipient.StreetAndNumber);\n        response.Recipient.PostalCode.ShouldBe(request.Recipient.PostalCode);\n        response.Recipient.City.ShouldBe(request.Recipient.City);\n        response.Recipient.Country.ShouldBe(request.Recipient.Country);\n        response.RecipientIdentifier.ShouldBe(request.RecipientIdentifier);\n        response.Recipient.Type.ShouldBe(RecipientType.Consumer);\n        response.WebhookUrl.ShouldBe(request.WebhookUrl);\n    }\n\n    public void Dispose() {\n        _salesInvoiceClient.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/SessionTests.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Session.Request;\nusing Mollie.Api.Models.Session.Response;\nusing Mollie.Tests.Integration.Framework;\nusing System.Collections.Generic;\nusing Shouldly;\nusing Mollie.Api.Models.Order.Request;\nusing Xunit;\nusing Mollie.Api.Models.Payment;\n\nnamespace Mollie.Tests.Integration.Api;\n\n[Trait(\"TestCategory\", \"LocalIntegrationTests\")]\npublic class SessionTests : BaseMollieApiTestClass, IDisposable {\n    private readonly ISessionClient _sessionClient;\n\n    public SessionTests(\n        ISessionClient sessionClient) {\n        _sessionClient = sessionClient;\n    }\n\n    [Fact]\n    public async Task CanCreateDefaultSessionWithOnlyRequiredFields() {\n        // Given: we create a session request with only the required parameters\n        var sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We send the session request to Mollie\n        SessionResponse result = await _sessionClient.CreateSessionAsync(sessionRequest);\n\n        // Then: Make sure we get a valid response\n        result.ShouldNotBeNull();\n        result.Amount.ShouldBe(sessionRequest.Amount);\n        result.Description.ShouldBe(sessionRequest.Description);\n        result.RedirectUrl.ShouldBe(sessionRequest.RedirectUrl);\n    }\n\n    [Fact]\n    public async Task CanCreateDefaultSessionWithCustomIdempotencyKey() {\n        // Given: we create a session request with only the required parameters\n        SessionRequest sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We send the session request to Mollie\n        using (_sessionClient.WithIdempotencyKey(\"my-idempotency-key\"))\n        {\n            SessionResponse firstAttempt = await _sessionClient.CreateSessionAsync(sessionRequest);\n            SessionResponse secondAttempt = await _sessionClient.CreateSessionAsync(sessionRequest);\n\n            // Then: Make sure the responses have the same session Id\n            firstAttempt.Id.ShouldBe(secondAttempt.Id);\n        }\n    }\n\n    [Fact]\n    public async Task CanCreateSessionAndRetrieveIt() {\n        // When: we create a new session request\n        SessionRequest sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We send the session request to Mollie and attempt to retrieve it\n        SessionResponse sessionResponse = await _sessionClient.CreateSessionAsync(sessionRequest);\n        SessionResponse result = await _sessionClient.GetSessionAsync(sessionResponse.Id);\n\n        // Then\n        result.ShouldNotBeNull();\n        result.Id.ShouldBe(sessionResponse.Id);\n        result.Amount.ShouldBe(sessionRequest.Amount);\n        result.Description.ShouldBe(sessionRequest.Description);\n        result.RedirectUrl.ShouldBe(sessionRequest.RedirectUrl);\n    }\n\n    [Fact]\n    public async Task CanCreateSessionWithJsonMetaData() {\n        // When: We create a session with meta data\n        string json = \"{\\\"order_id\\\":\\\"4.40\\\"}\";\n        SessionRequest sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Metadata = json\n        };\n\n        // When: We send the session request to Mollie\n        SessionResponse result = await _sessionClient.CreateSessionAsync(sessionRequest);\n\n        // Then: Make sure we get the same json result as metadata\n        IsJsonResultEqual(result.Metadata, json).ShouldBeTrue();\n    }\n\n    [Fact]\n    public async Task CanCreateSessionWithCustomMetaDataClass() {\n        // When: We create a session with meta data\n        CustomMetadataClass metadataRequest = new CustomMetadataClass() {\n            OrderId = 1,\n            Description = \"Custom description\"\n        };\n\n        SessionRequest sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n        };\n        sessionRequest.SetMetadata(metadataRequest);\n\n        // When: We send the session request to Mollie\n        SessionResponse result = await _sessionClient.CreateSessionAsync(sessionRequest);\n        CustomMetadataClass? metadataResponse = result.GetMetadata<CustomMetadataClass>();\n\n        // Then: Make sure we get the same json result as metadata\n        metadataResponse.ShouldNotBeNull();\n        metadataResponse.OrderId.ShouldBe(metadataRequest.OrderId);\n        metadataResponse.Description.ShouldBe(metadataRequest.Description);\n    }\n\n    [Fact]\n    public async Task CanCreateSessionWithLines() {\n        // Arrange\n        var address = new PaymentAddressDetails {\n            Title = \"Mr\",\n            GivenName = \"John\",\n            FamilyName = \"Doe\",\n            OrganizationName = \"Mollie\",\n            StreetAndNumber = \"Keizersgracht 126\",\n            Email = \"johndoe@mollie.com\",\n            City = \"Amsterdam\",\n            Country = \"NL\",\n            Phone = \"+31600000000\",\n            Region = \"Zuid-Holland\",\n            PostalCode = \"1015CW\"\n        };\n        SessionRequest sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, 90m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl,\n            Lines = new List<PaymentLine>() {\n                new() {\n                    Type = OrderLineDetailsType.Digital,\n                    Description = \"Star wars lego\",\n                    Quantity = 1,\n                    QuantityUnit = \"pcs\",\n                    UnitPrice = new Amount(Currency.EUR, 100m),\n                    TotalAmount = new Amount(Currency.EUR, 90m),\n                    DiscountAmount = new Amount(Currency.EUR, 10m),\n                    ProductUrl = \"http://www.lego.com/starwars\",\n                    ImageUrl = \"http://www.lego.com/starwars.jpg\",\n                    Sku = \"my-sku\",\n                    VatAmount = new Amount(Currency.EUR, 15.62m),\n                    VatRate = \"21.00\"\n                }\n            },\n            ShippingAddress = address,\n            BillingAddress = address\n        };\n\n        // Act\n        SessionResponse result = await _sessionClient.CreateSessionAsync(sessionRequest);\n\n        // Assert\n        //result.Lines.ShouldBeEquivalentTo(sessionRequest.Lines); Lines are ignored by Mollie's bug\n        result.BillingAddress.ShouldBeEquivalentTo(sessionRequest.BillingAddress);\n        result.ShippingAddress.ShouldBeEquivalentTo(sessionRequest.ShippingAddress);\n    }\n\n    [Fact]\n    public async Task CanCreateSessionWithDecimalAmountAndRetrieveIt() {\n        // When: we create a new session request\n        SessionRequest sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, 100.1235m),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We send the session request to Mollie and attempt to retrieve it\n        SessionResponse sessionResponse = await _sessionClient.CreateSessionAsync(sessionRequest);\n        SessionResponse result = await _sessionClient.GetSessionAsync(sessionResponse.Id);\n\n        // Then\n        result.ShouldNotBeNull();\n        result.Id.ShouldBe(sessionResponse.Id);\n        result.Amount.ShouldBe(sessionRequest.Amount);\n        result.Description.ShouldBe(sessionRequest.Description);\n        result.RedirectUrl.ShouldBe(sessionRequest.RedirectUrl);\n    }\n\n    [Fact]\n    public async Task CanCreateSessionWithImplicitAmountCastAndRetrieveIt() {\n        var initialAmount = 100.75m;\n\n        // When: we create a new session request\n        SessionRequest sessionRequest = new SessionRequest() {\n            Amount = new Amount(Currency.EUR, initialAmount),\n            Description = \"Description\",\n            RedirectUrl = DefaultRedirectUrl\n        };\n\n        // When: We send the session request to Mollie and attempt to retrieve it\n        SessionResponse sessionResponse = await _sessionClient.CreateSessionAsync(sessionRequest);\n        SessionResponse result = await _sessionClient.GetSessionAsync(sessionResponse.Id);\n\n        decimal responseAmount = sessionResponse.Amount; // Implicit cast\n        decimal resultAmount = result.Amount; // Implicit cast\n\n        // Then\n        result.ShouldNotBeNull();\n        result.Id.ShouldBe(sessionResponse.Id);\n        result.Amount.ShouldBe(sessionRequest.Amount);\n        result.Description.ShouldBe(sessionRequest.Description);\n        result.RedirectUrl.ShouldBe(sessionRequest.RedirectUrl);\n        resultAmount.ShouldBe(responseAmount);\n        resultAmount.ShouldBe(initialAmount);\n    }\n\n    public void Dispose()\n    {\n        _sessionClient.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/ShipmentTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Shipment.Request;\nusing Mollie.Api.Models.Shipment.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class ShipmentTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IShipmentClient _shipmentClient;\n\n    public ShipmentTests(IShipmentClient shipmentClient) {\n        _shipmentClient = shipmentClient;\n    }\n\n    [Fact(Skip = \"For manual testing only\")]\n    public async Task CanCreateShipmentWithOnlyRequiredFields() {\n        // the order needs to be autorized to do a shipment on. this can only be done by waiting.\n        string validOrderId = \"XXXXX\";\n        ShipmentRequest shipmentRequest = CreateShipmentWithOnlyRequiredFields();\n        ShipmentResponse result = await _shipmentClient.CreateShipmentAsync(validOrderId, shipmentRequest);\n\n        // Then: Make sure we get a valid shipment response\n        result.ShouldNotBeNull();\n        result.CreatedAt.ShouldBeGreaterThan(DateTime.Now);\n    }\n\n    [Fact(Skip = \"For manual testing only\")]\n    public async Task CanListShipmentsForOrder(){\n        string validOrderId = \"XXXXX\";\n        ListResponse<ShipmentResponse> result = await _shipmentClient.GetShipmentListAsync(validOrderId);\n\n        result.ShouldNotBeNull();\n        result.Count.ShouldBeGreaterThan(0);\n    }\n\n    private ShipmentRequest CreateShipmentWithOnlyRequiredFields() {\n        return new ShipmentRequest() {\n            Lines = new List<ShipmentLineRequest>()\n        };\n    }\n\n    public void Dispose()\n    {\n        _shipmentClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/SubscriptionTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Mandate.Response;\nusing Mollie.Api.Models.Subscription.Request;\nusing Mollie.Api.Models.Subscription.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class SubscriptionTests : BaseMollieApiTestClass, IDisposable {\n    private readonly ISubscriptionClient _subscriptionClient;\n    private readonly ICustomerClient _customerClient;\n    private readonly IMandateClient _mandateClient;\n\n    public SubscriptionTests(\n        ISubscriptionClient subscriptionClient,\n        ICustomerClient customerClient,\n        IMandateClient mandateClient) {\n        _subscriptionClient = subscriptionClient;\n        _customerClient = customerClient;\n        _mandateClient = mandateClient;\n    }\n\n    [Fact]\n    public async Task CanRetrieveSubscriptionList() {\n        // Given\n        string? customerId = await GetFirstCustomerWithValidMandate();\n\n        // When: Retrieve subscription list with default settings\n        if (customerId != null) {\n            ListResponse<SubscriptionResponse> response = await _subscriptionClient.GetSubscriptionListAsync(customerId);\n\n            // Then\n            response.ShouldNotBeNull();\n            response.Items.ShouldNotBeNull();\n        }\n    }\n\n    [Fact]\n    public async Task CanRetrieveAllSubscriptionList() {\n        // Given\n\n        // When: Retrieve subscription list with default settings\n        ListResponse<SubscriptionResponse> response = await _subscriptionClient.GetAllSubscriptionList();\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task ListSubscriptionsNeverReturnsMoreCustomersThenTheNumberOfRequestedSubscriptions() {\n        // Given: Number of customers requested is 5\n        string? customerId = await GetFirstCustomerWithValidMandate();\n        if (customerId != null) {\n            int numberOfSubscriptions = 5;\n\n            // When: Retrieve 5 subscriptions\n            ListResponse<SubscriptionResponse> response = await _subscriptionClient.GetSubscriptionListAsync(customerId, null, numberOfSubscriptions);\n\n            // Then\n            response.Items.Count.ShouldBeLessThanOrEqualTo(numberOfSubscriptions);\n        }\n    }\n\n    [Fact]\n    public async Task CanCreateSubscription() {\n        // Given\n        string? customerId = await GetFirstCustomerWithValidMandate();\n        if (customerId != null) {\n            var subscriptionRequest = new SubscriptionRequest {\n                Amount = new Amount(Currency.EUR, \"100.00\"),\n                Times = 5,\n                Interval = \"1 month\",\n                Description = $\"Subscription {Guid.NewGuid()}\", // Subscriptions must have a unique name\n                WebhookUrl = \"http://www.google.nl\",\n                StartDate = DateTime.Now.AddDays(1)\n            };\n\n            // When\n            SubscriptionResponse subscriptionResponse = await _subscriptionClient.CreateSubscriptionAsync(customerId, subscriptionRequest);\n\n            // Then\n            subscriptionResponse.Amount.ShouldBe(subscriptionRequest.Amount);\n            subscriptionResponse.Times.ShouldBe(subscriptionRequest.Times);\n            subscriptionResponse.Interval.ShouldBe(subscriptionRequest.Interval);\n            subscriptionResponse.Description.ShouldBe(subscriptionRequest.Description);\n            subscriptionResponse.WebhookUrl.ShouldBe(subscriptionRequest.WebhookUrl);\n            subscriptionResponse.StartDate.ShouldBe(subscriptionRequest.StartDate.Value.Date);\n        }\n    }\n\n    [Fact]\n    public async Task CanUpdateSubscription() {\n        // Given\n        var activeSubscription = await GetActiveSubscription();\n\n        // When\n        if (activeSubscription != null) {\n            var customerId = activeSubscription.CustomerId;\n            SubscriptionUpdateRequest request = new () {\n                Description = $\"Updated subscription {Guid.NewGuid()}\"\n            };\n            SubscriptionResponse response = await _subscriptionClient.UpdateSubscriptionAsync(customerId, activeSubscription.Id, request);\n\n            // Then\n            response.Description.ShouldBe(request.Description);\n        }\n    }\n\n    [Fact]\n    public async Task CanCancelSubscription() {\n        // Given: We have a customer with a mandate\n        string? customerId = await GetFirstCustomerWithValidMandate();\n        if (customerId != null) {\n            ListResponse<SubscriptionResponse> subscriptions = await _subscriptionClient.GetSubscriptionListAsync(customerId);\n\n            // When: That customer has a subscription that we can cancel\n            SubscriptionResponse? subscriptionToCancel = subscriptions.Items\n                .FirstOrDefault(s => s.Status != SubscriptionStatus.Canceled);\n            if (subscriptionToCancel != null) {\n                await _subscriptionClient.CancelSubscriptionAsync(customerId, subscriptionToCancel.Id);\n\n                // Then: Make sure its canceled after one second\n                await Task.Delay(TimeSpan.FromSeconds(1));\n                SubscriptionResponse cancelledSubscription = await _subscriptionClient.GetSubscriptionAsync(customerId, subscriptionToCancel.Id);\n                cancelledSubscription.Status.ShouldBe(SubscriptionStatus.Canceled);\n            }\n        }\n    }\n\n    [Fact]\n    public async Task CanCreateSubscriptionWithMetaData() {\n        // If: We create a subscription with meta data\n        string json = \"{\\\"order_id\\\":\\\"4.40\\\"}\";\n        string? customerId = await GetFirstCustomerWithValidMandate();\n        if (customerId != null) {\n            SubscriptionRequest subscriptionRequest = new SubscriptionRequest {\n                Amount = new Amount(Currency.EUR, \"100.00\"),\n                Times = 5,\n                Interval = \"1 month\",\n                Description = $\"Subscription {Guid.NewGuid()}\", // Subscriptions must have a unique name\n                WebhookUrl = \"http://www.google.nl\",\n                StartDate = DateTime.Now.AddDays(1),\n                Metadata = json\n            };\n\n            // When We send the subscription request to Mollie\n            SubscriptionResponse result = await _subscriptionClient.CreateSubscriptionAsync(customerId, subscriptionRequest);\n\n            // Then: Make sure we get the same json result as metadata\n            IsJsonResultEqual(result.Metadata, json).ShouldBeTrue();\n        }\n    }\n\n    private async Task<string?> GetFirstCustomerWithValidMandate() {\n        ListResponse<CustomerResponse> customers = await _customerClient.GetCustomerListAsync();\n\n        foreach (CustomerResponse customer in customers.Items) {\n            ListResponse<MandateResponse> mandates = await _mandateClient.GetMandateListAsync(customer.Id);\n            if (mandates.Items.Any(x => x.Status == MandateStatus.Valid)) {\n                return customer.Id;\n            }\n        }\n\n        return null;\n    }\n\n    private async Task<SubscriptionResponse?> GetActiveSubscription() {\n        ListResponse<CustomerResponse> customers = await _customerClient.GetCustomerListAsync();\n\n        foreach (CustomerResponse customer in customers.Items.OrderByDescending(x => x.CreatedAt)) {\n            ListResponse<SubscriptionResponse> subscriptions = await _subscriptionClient.GetSubscriptionListAsync(customer.Id);\n            var activeSubscription = subscriptions.Items.FirstOrDefault(x => x.Status == SubscriptionStatus.Active);\n            if (activeSubscription != null) {\n                return activeSubscription;\n            }\n        }\n\n        return null;\n    }\n\n    public void Dispose()\n    {\n        _subscriptionClient.Dispose();\n        _customerClient.Dispose();\n        _mandateClient.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/TerminalTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Terminal.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\npublic class TerminalTests : BaseMollieApiTestClass, IDisposable {\n    private readonly ITerminalClient _terminalClient;\n\n    public TerminalTests(ITerminalClient terminalClient) {\n        _terminalClient = terminalClient;\n    }\n\n    [Fact]\n    public async Task CanRetrieveTerminalList() {\n        // Given\n\n        // When: Retrieve terminal client list\n        ListResponse<TerminalResponse> response = await _terminalClient.GetTerminalListAsync();\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Fact(Skip = \"Not implemented by Mollie yet\")]\n    public async Task CanRetrieveSingleTerminal() {\n        // Given\n        ListResponse<TerminalResponse> allTerminals = await _terminalClient.GetTerminalListAsync();\n        if (allTerminals.Count > 0) {\n            TerminalResponse firstTerminal = allTerminals.Items.First();\n\n            // When: Retrieve terminal client list\n            TerminalResponse response = await _terminalClient.GetTerminalAsync(firstTerminal.Id);\n\n            // Then\n            response.ShouldNotBeNull();\n            response.Id.ShouldBe(firstTerminal.Id);\n        }\n    }\n\n    public void Dispose()\n    {\n        _terminalClient?.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/WebhookEventTests.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\n[Trait(\"TestCategory\", \"LocalIntegrationTests\")]\npublic class WebhookEventTests : BaseMollieApiTestClass, IDisposable {\n    private readonly IWebhookEventClient _webhookEventClient;\n\n    public WebhookEventTests(IWebhookEventClient webhookEventClient) {\n        _webhookEventClient = webhookEventClient;\n    }\n\n    [Fact]\n    public async Task CanRetrieveWebhookEvent() {\n        // Arrange\n        const string webhookEventIdToRetrieve = \"event_GvJ8WHrp5isUdRub9CJyH\";\n\n        // Act\n        var webhookEvent = await _webhookEventClient.GetWebhookEventAsync(webhookEventIdToRetrieve);\n\n        // Assert\n        webhookEvent.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task CanRetrieveGenericWebhookEvent() {\n        // Arrange\n        const string webhookEventIdToRetrieve = \"event_GvJ8WHrp5isUdRub9CJyH\";\n\n        // Act\n        var webhookEvent = await _webhookEventClient.GetWebhookEventAsync<PaymentLinkResponse>(webhookEventIdToRetrieve);\n\n        // Assert\n        webhookEvent.ShouldNotBeNull();\n    }\n\n    public void Dispose() {\n        _webhookEventClient.Dispose();\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Api/WebhookTests.cs",
    "content": "using System;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Webhook;\nusing Mollie.Api.Models.Webhook.Request;\nusing Mollie.Api.Models.Webhook.Response;\nusing Mollie.Tests.Integration.Framework;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Integration.Api;\n\n[Trait(\"TestCategory\", \"LocalIntegrationTests\")]\npublic class WebhookTests : BaseMollieApiTestClass, IDisposable, IAsyncLifetime {\n    private readonly IWebhookClient _webhookClient;\n\n    public WebhookTests(IWebhookClient webhookClient) {\n        _webhookClient = webhookClient;\n    }\n\n    [Fact]\n    public async Task CanCreateRetrieveAndDeleteWebhook() {\n        // Given\n        var request = new WebhookRequest {\n            Name = \"my-webhook\",\n            Url = \"https://github.com/Viincenttt/MollieApi/\",\n            EventTypes = [WebhookEventTypes.PaymentLinkPaid, WebhookEventTypes.SalesInvoiceCreated],\n            Testmode = true\n        };\n\n        // When: The webhook is created\n        WebhookResponse created = await _webhookClient.CreateWebhookAsync(request);\n\n        // Then\n        created.Name.ShouldBe(request.Name);\n        created.Url.ShouldBe(request.Url);\n        created.EventTypes.ShouldBe([WebhookEventTypes.PaymentLinkPaid, WebhookEventTypes.SalesInvoiceCreated]);\n        created.Mode.ShouldBe(Mode.Test);\n        created.Resource.ShouldBe(\"webhook\");\n        created.Id.ShouldNotBeNullOrEmpty();\n\n        // Then: The webhook can be retrieved\n        WebhookResponse retrieved = await _webhookClient.GetWebhookAsync(created.Id, testmode: true);\n        retrieved.ShouldBeEquivalentTo(created);\n\n        // Then: The webhook can be deleted\n        await _webhookClient.DeleteWebhookAsync(created.Id, testmode: true);\n    }\n\n    [Fact]\n    public async Task CanRetrieveWebhookList() {\n        // Given\n\n        // When: Retrieve webhook list\n        ListResponse<WebhookResponse> response = await _webhookClient.GetWebhookListAsync(testmode: true);\n\n        // Then\n        response.ShouldNotBeNull();\n        response.Items.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task CanUpdateWebhook() {\n        // Given: Create a webhook\n        var createRequest = new WebhookRequest {\n            Name = \"my-webhook\",\n            Url = \"https://github.com/Viincenttt/MollieApi/\",\n            EventTypes = [WebhookEventTypes.PaymentLinkPaid],\n            Testmode = true\n        };\n        WebhookResponse created = await _webhookClient.CreateWebhookAsync(createRequest);\n        var updateRequest = new WebhookRequest {\n            Name = \"my-webhook-updated\",\n            Url = \"https://github.com/Viincenttt/MollieApi/-updated\",\n            EventTypes = [WebhookEventTypes.PaymentLinkPaid, WebhookEventTypes.SalesInvoiceCreated],\n            Testmode = true\n        };\n\n        // When: The webhook is updated\n        WebhookResponse updated = await _webhookClient.UpdateWebhookAsync(created.Id, updateRequest);\n\n        // Then\n        updated.Name.ShouldBe(updateRequest.Name);\n        updated.Url.ShouldBe(updateRequest.Url);\n        updated.EventTypes.ShouldBe([WebhookEventTypes.PaymentLinkPaid, WebhookEventTypes.SalesInvoiceCreated]);\n        updated.Mode.ShouldBe(Mode.Test);\n    }\n\n    [Fact]\n    public async Task CanTestWebhook() {\n        // Given: Create a webhook\n        var createRequest = new WebhookRequest {\n            Name = \"my-webhook\",\n            Url = \"https://github.com/Viincenttt/MollieApi/\",\n            EventTypes = [WebhookEventTypes.PaymentLinkPaid],\n            Testmode = true\n        };\n        WebhookResponse created = await _webhookClient.CreateWebhookAsync(createRequest);\n\n        // When: The webhook is updated\n        MollieApiException exception = await Assert.ThrowsAsync<MollieApiException>(() => _webhookClient.TestWebhookAsync(created.Id, testmode: true));\n\n        // Then: An exception is thrown as the URL can't be reached\n        exception.Message.ShouldBe(\"Unprocessable Entity - Failed to ping the webhook subscription.\");\n    }\n\n    public async Task InitializeAsync() {\n        ListResponse<WebhookResponse> webhooks = await _webhookClient.GetWebhookListAsync(testmode: true);\n        foreach (var webhook in webhooks.Items) {\n            await _webhookClient.DeleteWebhookAsync(webhook.Id, testmode: true);\n        }\n    }\n\n    public Task DisposeAsync() => Task.CompletedTask;\n\n    public void Dispose() => _webhookClient.Dispose();\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Framework/BaseMollieApiTestClass.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Configuration;\nusing Mollie.Api.Client;\nusing Mollie.Api.Options;\n\nnamespace Mollie.Tests.Integration.Framework {\n    public abstract class BaseMollieApiTestClass {\n        protected readonly string DefaultRedirectUrl = \"http://mysite.com\";\n        protected readonly string DefaultWebhookUrl = \"http://mysite.com/webhook\";\n\n        private readonly MollieOptions _configuration;\n\n        protected string ApiKey => _configuration.ApiKey;\n        protected string ClientId => _configuration.ClientId ?? \"client-id\";\n        protected string ClientSecret => _configuration.ClientSecret ?? \"client-secret\";\n\n        protected BaseMollieApiTestClass() {\n            _configuration = ConfigurationFactory.GetConfiguration().GetSection(\"Mollie\").Get<MollieOptions>()!;\n            EnsureTestApiKey(ApiKey);\n\n            // Mollie returns a 429 response code (Too many requests) if we send a lot of requests in a short timespan.\n            // this is partially mitigated by using a custom http retry policy. However, the RetryAfter header gets\n            // exceedingly long if we do too many requests without any delay. This is why we add a small delay between\n            // each test.\n            TimeSpan timeBetweenTests = TimeSpan.FromMilliseconds(500);\n            Thread.Sleep(timeBetweenTests);\n        }\n\n        private void EnsureTestApiKey(string apiKey) {\n            if (string.IsNullOrEmpty(apiKey)) {\n                throw new ArgumentException(\"Please enter you API key in the BaseMollieApiTestClass class\");\n            }\n\n            if (!apiKey.StartsWith(\"access\") && !apiKey.StartsWith(\"test\")) {\n                throw new ArgumentException(\"You should not run these tests on your live key!\");\n            }\n        }\n\n        protected bool IsJsonResultEqual(string? json1, string? json2) {\n            return string.Compare(json1, json2, CultureInfo.CurrentCulture,\n                CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols) == 0;\n        }\n\n        protected async Task<TResult> ExecuteWithRetry<TResult>(Func<Task<TResult>> apiAction, int numberOfRetries = 3) {\n            MollieApiException? exception = null;\n            for (int i = 0; i < numberOfRetries; i++) {\n                try {\n                    return await apiAction.Invoke();\n                } catch (MollieApiException ex) {\n                    exception = ex;\n                    await Task.Delay(TimeSpan.FromSeconds(1));\n                }\n            }\n\n            throw exception!;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Framework/ConfigurationFactory.cs",
    "content": "﻿using Microsoft.Extensions.Configuration;\nusing System.IO;\n\nnamespace Mollie.Tests.Integration.Framework {\n    public static class ConfigurationFactory {\n        public static IConfiguration GetConfiguration() {\n            var builder = new ConfigurationBuilder()\n                .SetBasePath(Directory.GetCurrentDirectory())\n                .AddJsonFile(\"appsettings.json\")\n                .AddUserSecrets(typeof(ConfigurationFactory).Assembly)\n                .AddEnvironmentVariables();\n\n            var configuration = builder.Build();\n\n            return configuration;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Framework/MollieIntegrationTestHttpRetryPolicies.cs",
    "content": "﻿using System;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Polly;\n\nnamespace Mollie.Tests.Integration.Framework;\n\npublic static class MollieIntegrationTestHttpRetryPolicies {\n\n    public static IAsyncPolicy<HttpResponseMessage> TooManyRequestRetryPolicy() {\n        var retryPolicy = Policy<HttpResponseMessage>\n            .Handle<MollieApiException>(x => x.Details.Status == (int)HttpStatusCode.TooManyRequests)\n            .OrResult(r =>  r?.Headers?.RetryAfter != null)\n            .WaitAndRetryAsync(\n                3,\n                sleepDurationProvider: (_, response, _) =>\n                    response.Result.Headers.RetryAfter?.Delta?.Add(TimeSpan.FromSeconds(1)) ?? TimeSpan.FromSeconds(5),\n                onRetryAsync: (response, _, _, _) => {\n                    // If we send a retry with the same idempotency key, we always get a 429 back...\n                    response.Result.RequestMessage?.Headers.Add(\"Idempotency-Key\", Guid.NewGuid().ToString());\n                    return Task.CompletedTask;\n                }\n            );\n\n        return retryPolicy;\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Mollie.Tests.Integration.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net10.0</TargetFramework>\n\n    <IsPackable>false</IsPackable>\n\n    <UserSecretsId>51f1afd9-6752-484d-845c-119df206c6e7</UserSecretsId>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <None Remove=\"appsettings.json\" />\n    <None Remove=\"secrets.json\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Include=\"appsettings.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </Content>\n    <Content Include=\"secrets.json\" Condition=\"Exists('secrets.json')\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </Content>\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Extensions.Configuration\" Version=\"9.0.1\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.Binder\" Version=\"9.0.1\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.EnvironmentVariables\" Version=\"9.0.1\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.FileExtensions\" Version=\"9.0.1\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.Json\" Version=\"9.0.1\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.UserSecrets\" Version=\"9.0.1\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.12.0\" />\n    <PackageReference Include=\"Shouldly\" Version=\"4.3.0\" />\n    <PackageReference Include=\"xRetry\" Version=\"1.9.0\" />\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageReference Include=\"Xunit.DependencyInjection\" Version=\"9.7.1\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"3.0.1\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"xunit.runner.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Mollie.Api\\Mollie.Api.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/Startup.cs",
    "content": "﻿using System.IO;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.Hosting;\nusing Mollie.Api;\nusing Mollie.Tests.Integration.Framework;\nusing Polly;\n\nnamespace Mollie.Tests.Integration;\n\npublic class Startup\n{\n    public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder\n        .ConfigureHostConfiguration(options => {\n            options\n                .SetBasePath(Directory.GetCurrentDirectory())\n                .AddJsonFile(\"appsettings.json\")\n                .AddUserSecrets(typeof(ConfigurationFactory).Assembly)\n                .AddEnvironmentVariables();\n        })\n        .ConfigureServices((context, services) => {\n            services.AddMollieApi(options => {\n                options.ApiKey = context.Configuration[\"Mollie:ApiKey\"]!;\n                options.ClientId = context.Configuration[\"Mollie:ClientId\"]!;\n                options.ClientSecret = context.Configuration[\"Mollie:ClientSecret\"]!;\n                options.RetryPolicy = MollieIntegrationTestHttpRetryPolicies.TooManyRequestRetryPolicy();\n            });\n        });\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Integration/appsettings.json",
    "content": "{\n  \"Mollie\": {\n    \"ApiKey\": \"<Your api key>\",\n    \"ClientId\": \"<Your client id>\",\n    \"ClientSecret\": \"<Your client secret>\",\n    \"AccessKey\": \"<Your access key>\"\n  }\n}"
  },
  {
    "path": "tests/Mollie.Tests.Integration/xunit.runner.json",
    "content": "﻿{\n  \"parallelizeAssembly\": false,\n  \"parallelizeTestCollections\": false\n}"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/BalanceClientTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Balance.Response;\nusing Mollie.Api.Models.Balance.Response.BalanceReport;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific;\nusing RichardSzalay.MockHttp;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class BalanceClientTests : BaseClientTests {\n      [Fact]\n      public async Task GetBalanceAsync_DefaultBehaviour_ResponseIsParsed() {\n          // Given: We request a specific balance\n          var getBalanceResponseFactory = new GetBalanceResponseFactory();\n          var getBalanceResponse = getBalanceResponseFactory.CreateGetBalanceResponse();\n          string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}balances/{getBalanceResponseFactory.BalanceId}\";\n          var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, getBalanceResponse);\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We make the request\n          BalanceResponse balanceResponse = await balanceClient.GetBalanceAsync(getBalanceResponseFactory.BalanceId);\n\n          // Then: Response should be parsed\n          mockHttp.VerifyNoOutstandingExpectation();\n          balanceResponse.ShouldNotBeNull();\n          balanceResponse.Id.ShouldBe(getBalanceResponseFactory.BalanceId);\n          balanceResponse.CreatedAt.ToUniversalTime().ShouldBe(getBalanceResponseFactory.CreatedAt);\n          balanceResponse.TransferThreshold.Currency.ShouldBe(getBalanceResponseFactory.TransferThreshold.Currency);\n          balanceResponse.Currency.ShouldBe(getBalanceResponseFactory.Currency);\n          balanceResponse.Status.ShouldBe(getBalanceResponseFactory.Status);\n          balanceResponse.AvailableAmount.Currency.ShouldBe(getBalanceResponseFactory.AvailableAmount.Currency);\n          balanceResponse.AvailableAmount.Value.ShouldBe(getBalanceResponseFactory.AvailableAmount.Value);\n          balanceResponse.PendingAmount.Value.ShouldBe(getBalanceResponseFactory.PendingAmount.Value);\n          balanceResponse.PendingAmount.Currency.ShouldBe(getBalanceResponseFactory.PendingAmount.Currency);\n          balanceResponse.TransferFrequency.ShouldBe(getBalanceResponseFactory.TransferFrequency);\n          balanceResponse.TransferReference.ShouldBe(getBalanceResponseFactory.TransferReference);\n          balanceResponse.TransferThreshold.Currency.ShouldBe(getBalanceResponseFactory.TransferThreshold.Currency);\n          balanceResponse.TransferThreshold.Value.ShouldBe(getBalanceResponseFactory.TransferThreshold.Value);\n          balanceResponse.TransferDestination.Type.ShouldBe(getBalanceResponseFactory.TransferDestination.Type);\n          balanceResponse.TransferDestination.BankAccount.ShouldBe(getBalanceResponseFactory.TransferDestination.BankAccount);\n          balanceResponse.TransferDestination.BeneficiaryName.ShouldBe(getBalanceResponseFactory.TransferDestination.BeneficiaryName);\n          balanceResponse.Links.ShouldNotBeNull();\n          balanceResponse.Links.Self.Href.ShouldBe($\"https://api.mollie.com/v2/balances/{getBalanceResponseFactory.BalanceId}\");\n          balanceResponse.Links.Self.Type.ShouldBe(\"application/hal+json\");\n          balanceResponse.Links.Documentation.Href.ShouldBe($\"https://docs.mollie.com/reference/v2/balances-api/get-balance\");\n          balanceResponse.Links.Documentation.Type.ShouldBe(\"text/html\");\n      }\n\n      [Theory]\n      [InlineData(\"\")]\n      [InlineData(\" \")]\n      [InlineData(null)]\n      public async Task GetBalanceAsync_NoBalanceIdIsGiven_ArgumentExceptionIsThrown(string? balanceId) {\n          // Arrange\n          var mockHttp = new MockHttpMessageHandler();\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n          var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await balanceClient.GetBalanceAsync(balanceId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n          // Then\n          exception.Message.ShouldBe(\"Required URL argument 'balanceId' is null or empty\");\n      }\n\n      [Fact]\n      public async Task GetPrimaryBalanceAsync_DefaultBehaviour_ResponseIsParsed() {\n          // Given: We request the primary balance\n          var getBalanceResponseFactory = new GetBalanceResponseFactory();\n          var getBalanceResponse = getBalanceResponseFactory.CreateGetBalanceResponse();\n          string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}balances/primary\";\n          var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, getBalanceResponse);\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We make the request\n          BalanceResponse balanceResponse = await balanceClient.GetPrimaryBalanceAsync();\n\n          // Then: Response should be parsed\n          mockHttp.VerifyNoOutstandingExpectation();\n          balanceResponse.ShouldNotBeNull();\n          balanceResponse.ShouldNotBeNull();\n          balanceResponse.Id.ShouldBe(getBalanceResponseFactory.BalanceId);\n          balanceResponse.CreatedAt.ToUniversalTime().ShouldBe(getBalanceResponseFactory.CreatedAt);\n          balanceResponse.TransferThreshold.Currency.ShouldBe(getBalanceResponseFactory.TransferThreshold.Currency);\n          balanceResponse.Currency.ShouldBe(getBalanceResponseFactory.Currency);\n          balanceResponse.Status.ShouldBe(getBalanceResponseFactory.Status);\n          balanceResponse.AvailableAmount.Currency.ShouldBe(getBalanceResponseFactory.AvailableAmount.Currency);\n          balanceResponse.AvailableAmount.Value.ShouldBe(getBalanceResponseFactory.AvailableAmount.Value);\n          balanceResponse.PendingAmount.Value.ShouldBe(getBalanceResponseFactory.PendingAmount.Value);\n          balanceResponse.PendingAmount.Currency.ShouldBe(getBalanceResponseFactory.PendingAmount.Currency);\n          balanceResponse.TransferFrequency.ShouldBe(getBalanceResponseFactory.TransferFrequency);\n          balanceResponse.TransferReference.ShouldBe(getBalanceResponseFactory.TransferReference);\n          balanceResponse.TransferThreshold.Currency.ShouldBe(getBalanceResponseFactory.TransferThreshold.Currency);\n          balanceResponse.TransferThreshold.Value.ShouldBe(getBalanceResponseFactory.TransferThreshold.Value);\n          balanceResponse.TransferDestination.Type.ShouldBe(getBalanceResponseFactory.TransferDestination.Type);\n          balanceResponse.TransferDestination.BankAccount.ShouldBe(getBalanceResponseFactory.TransferDestination.BankAccount);\n          balanceResponse.TransferDestination.BeneficiaryName.ShouldBe(getBalanceResponseFactory.TransferDestination.BeneficiaryName);\n      }\n\n      [Fact]\n      public async Task ListBalancesAsync_DefaultBehaviour_ResponseIsParsed() {\n          // Given: We request a list of balances\n          string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}balances\";\n          var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, DefaultListBalancesResponse);\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We make the request\n          var balances = await balanceClient.GetBalanceListAsync();\n\n          // Then: Response should be parsed\n          mockHttp.VerifyNoOutstandingExpectation();\n          balances.ShouldNotBeNull();\n          balances.Count.ShouldBe(2);\n          balances.Items.Count.ShouldBe(2);\n      }\n\n      [Fact]\n      public async Task GetBalanceReportAsync_TransactionCategories_ResponseIsParsed() {\n          // Given: We request a balance report\n          string balanceId = \"bal_CKjKwQdjCwCSArXFAJNFH\";\n          DateTime from = new DateTime(2022, 11, 1);\n          DateTime until = new DateTime(2022, 11, 30);\n          string grouping = ReportGrouping.TransactionCategories;\n\n          string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}balances/{balanceId}/report\" +\n                               $\"?from={from.ToString(\"yyyy-MM-dd\")}&until={until.ToString(\"yyyy-MM-dd\")}&grouping={grouping}\";\n          var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, DefaultGetBalanceReportTransactionCategoriesResponse);\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We make the request\n          var balanceReport = await balanceClient.GetBalanceReportAsync(balanceId, from, until, grouping);\n\n          // Then: Response should be parsed\n          mockHttp.VerifyNoOutstandingExpectation();\n          balanceReport.ShouldNotBeNull();\n          balanceReport.ShouldBeOfType<TransactionCategoriesReportResponse>();\n          var specificBalanceReport = (TransactionCategoriesReportResponse)balanceReport;\n          specificBalanceReport.Grouping.ShouldBe(grouping);\n          specificBalanceReport.BalanceId.ShouldBe(balanceId);\n          specificBalanceReport.Resource.ShouldBe(\"balance-report\");\n          specificBalanceReport.From.ShouldBe(from);\n          specificBalanceReport.Until.ShouldBe(until);\n          specificBalanceReport.Totals.ShouldNotBeNull();\n          specificBalanceReport.Totals.Open.Pending.Amount.Value.ShouldBe(\"5.30\");\n          specificBalanceReport.Totals.Open.Pending.Amount.Currency.ShouldBe(\"EUR\");\n          specificBalanceReport.Totals.Open.Available.Amount.Value.ShouldBe(\"0.11\");\n          specificBalanceReport.Totals.Open.Available.Amount.Currency.ShouldBe(\"EUR\");\n          var childSubTotals = specificBalanceReport.Totals.Payments.Pending.Subtotals.First();\n          childSubTotals.TransactionType.ShouldBe(\"payment\");\n          childSubTotals.Count.ShouldBe(36);\n          var childChildSubTotals = childSubTotals.Subtotals!.First();\n          childChildSubTotals.Method.ShouldBe(\"ideal\");\n      }\n\n      [Theory]\n      [InlineData(\"\")]\n      [InlineData(\" \")]\n      [InlineData(null)]\n      public async Task GetBalanceReportAsync_NoBalanceIdIsGiven_ArgumentExceptionIsThrown(string? balanceId) {\n          // Arrange\n          var mockHttp = new MockHttpMessageHandler();\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n          DateTime from = new DateTime(2022, 11, 1);\n          DateTime until = new DateTime(2022, 11, 30);\n\n          // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n          var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await balanceClient.GetBalanceReportAsync(balanceId, from, until));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n          // Then\n          exception.Message.ShouldBe(\"Required URL argument 'balanceId' is null or empty\");\n      }\n\n      [Fact]\n      public async Task GetBalanceReportAsync_StatusBalances_ResponseIsParsed() {\n          // Given: We request a balance report\n          string balanceId = \"bal_CKjKwQdjCwCSArXFAJNFH\";\n          DateTime from = new DateTime(2022, 11, 1);\n          DateTime until = new DateTime(2022, 11, 30);\n          string grouping = ReportGrouping.StatusBalances;\n\n          string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}balances/{balanceId}/report\" +\n                               $\"?from={from.ToString(\"yyyy-MM-dd\")}&until={until.ToString(\"yyyy-MM-dd\")}&grouping={grouping}\";\n          var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, DefaultGetBalanceReportStatusBalancesResponse);\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We make the request\n          var balanceReport = await balanceClient.GetBalanceReportAsync(balanceId, from, until, grouping);\n\n          // Then: Response should be parsed\n          mockHttp.VerifyNoOutstandingExpectation();\n          balanceReport.ShouldNotBeNull();\n          balanceReport.ShouldBeOfType<StatusBalanceReportResponse>();\n          var specificBalanceReport = (StatusBalanceReportResponse)balanceReport;\n          specificBalanceReport.Grouping.ShouldBe(grouping);\n          specificBalanceReport.BalanceId.ShouldBe(balanceId);\n          specificBalanceReport.Resource.ShouldBe(\"balance-report\");\n          specificBalanceReport.From.ShouldBe(from);\n          specificBalanceReport.Until.ShouldBe(until);\n          specificBalanceReport.Totals.ShouldNotBeNull();\n          specificBalanceReport.Totals.PendingBalance.Open.Amount.Value.ShouldBe(\"5.30\");\n          specificBalanceReport.Totals.PendingBalance.Open.Amount.Currency.ShouldBe(Currency.EUR);\n          specificBalanceReport.Totals.AvailableBalance.MovedFromPending.Amount.Value.ShouldBe(\"3.38\");\n          specificBalanceReport.Totals.AvailableBalance.MovedFromPending.Amount.Currency.ShouldBe(Currency.EUR);\n          var childSubTotals = specificBalanceReport.Totals.AvailableBalance.MovedFromPending.Subtotals.First();\n          childSubTotals.TransactionType.ShouldBe(\"payment\");\n          var childChildSubtotals = childSubTotals.Subtotals!.First();\n          childChildSubtotals.Method.ShouldBe(\"ideal\");\n      }\n\n      [Fact]\n      public async Task ListBalanceTransactionsAsync_StatusBalances_ResponseIsParsed() {\n          // Given\n          string balanceId = \"bal_CKjKwQdjCwCSArXFAJNFH\";\n          string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}balances/{balanceId}/transactions\";\n          var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, DefaultListBalanceTransactionsResponse);\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We make the request\n          var balanceTransactions = await balanceClient.GetBalanceTransactionListAsync(balanceId);\n\n          // Then: Response should be parsed\n          mockHttp.VerifyNoOutstandingExpectation();\n          balanceTransactions.Count.ShouldBe(balanceTransactions.Items.Count);\n          var transaction = balanceTransactions.Items.First();\n          transaction.Resource.ShouldBe(\"balance_transactions\");\n          transaction.Id.ShouldBe(\"baltr_9S8yk4FFqqi2Qm6K3rqRH\");\n          transaction.Type.ShouldBe(\"outgoing-transfer\");\n          transaction.ResultAmount.Value.ShouldBe(\"-7.76\");\n          transaction.ResultAmount.Currency.ShouldBe(Currency.EUR);\n          transaction.InitialAmount.Value.ShouldBe(\"-7.76\");\n          transaction.InitialAmount.Currency.ShouldBe(Currency.EUR);\n          transaction.ShouldBeOfType<SettlementBalanceTransactionResponse>();\n          var transactionContext = (SettlementBalanceTransactionResponse)transaction;\n          transactionContext.Context.SettlementId.ShouldBe(\"stl_ma2vu8\");\n          transactionContext.Context.TransferId.ShouldBe(\"trf_ma2vu8\");\n      }\n\n      [Theory]\n      [InlineData(\"\")]\n      [InlineData(\" \")]\n      [InlineData(null)]\n      public async Task ListBalanceTransactionsAsync_NoBalanceIdIsGiven_ArgumentExceptionIsThrown(string? balanceId) {\n          // Arrange\n          var mockHttp = new MockHttpMessageHandler();\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n          var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await balanceClient.GetBalanceTransactionListAsync(balanceId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n          // Then\n          exception.Message.ShouldBe(\"Required URL argument 'balanceId' is null or empty\");\n      }\n\n      [Fact]\n      public async Task ListPrimaryBalanceTransactionsAsync_StatusBalances_ResponseIsParsed() {\n          // Given\n          string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}balances/primary/transactions\";\n          var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, DefaultListBalanceTransactionsResponse);\n          HttpClient httpClient = mockHttp.ToHttpClient();\n          BalanceClient balanceClient = new BalanceClient(\"api-key\", httpClient);\n\n          // When: We make the request\n          var balanceTransactions = await balanceClient.GetPrimaryBalanceTransactionListAsync();\n\n          // Then: Response should be parsed\n          mockHttp.VerifyNoOutstandingExpectation();\n          balanceTransactions.Count.ShouldBe(balanceTransactions.Items.Count);\n      }\n\n      private readonly string DefaultListBalanceTransactionsResponse = @\"\n{\n    \"\"_embedded\"\": {\n        \"\"balance_transactions\"\": [{\n                \"\"resource\"\": \"\"balance_transactions\"\",\n                \"\"id\"\": \"\"baltr_9S8yk4FFqqi2Qm6K3rqRH\"\",\n                \"\"type\"\": \"\"outgoing-transfer\"\",\n                \"\"resultAmount\"\": {\n                    \"\"value\"\": \"\"-7.76\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"initialAmount\"\": {\n                    \"\"value\"\": \"\"-7.76\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"createdAt\"\": \"\"2022-12-21T05:02:50+00:00\"\",\n                \"\"context\"\": {\n                    \"\"settlementId\"\": \"\"stl_ma2vu8\"\",\n                    \"\"transferId\"\": \"\"trf_ma2vu8\"\"\n                }\n            }, {\n                \"\"resource\"\": \"\"balance_transactions\"\",\n                \"\"id\"\": \"\"baltr_2cXFV9Wd9AjYqHa8i2qRH\"\",\n                \"\"type\"\": \"\"payment\"\",\n                \"\"resultAmount\"\": {\n                    \"\"value\"\": \"\"0.15\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"initialAmount\"\": {\n                    \"\"value\"\": \"\"0.15\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"createdAt\"\": \"\"2022-12-20T21:21:09+00:00\"\",\n                \"\"context\"\": {\n                    \"\"paymentId\"\": \"\"tr_JzT2KxV7hZ\"\"\n                }\n            }\n        ]\n    },\n    \"\"count\"\": 2,\n    \"\"_links\"\": {\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/balances-api/list-balance-transactions\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/balances/bal_CKjKwQdjCwCSArXFAJNFH/transactions?limit=50\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"previous\"\": null,\n        \"\"next\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/balances/bal_CKjKwQdjCwCSArXFAJNFH/transactions?from=baltr_pEM6remSK3UGHDRAuzVRH\\u0026limit=50\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }\n    }\n}\";\n\n      private readonly string DefaultListBalancesResponse = $@\"{{\n  \"\"count\"\": 2,\n  \"\"_embedded\"\": {{\n    \"\"balances\"\": [\n       {{\n         \"\"resource\"\": \"\"balance\"\",\n         \"\"id\"\": \"\"bal_gVMhHKqSSRYJyPsuoPNFH\"\",\n         \"\"mode\"\": \"\"live\"\",\n         \"\"createdAt\"\": \"\"2019-01-10T12:06:28+00:00\"\",\n         \"\"currency\"\": \"\"EUR\"\",\n         \"\"status\"\": \"\"active\"\",\n         \"\"availableAmount\"\": {{\n           \"\"value\"\": \"\"0.00\"\",\n           \"\"currency\"\": \"\"EUR\"\"\n         }},\n         \"\"pendingAmount\"\": {{\n           \"\"value\"\": \"\"0.00\"\",\n           \"\"currency\"\": \"\"EUR\"\"\n         }},\n         \"\"transferFrequency\"\": \"\"daily\"\",\n         \"\"transferThreshold\"\": {{\n           \"\"value\"\": \"\"40.00\"\",\n           \"\"currency\"\": \"\"EUR\"\"\n         }},\n         \"\"transferReference\"\": \"\"Mollie payout\"\",\n         \"\"transferDestination\"\": {{\n           \"\"type\"\": \"\"bank-account\"\",\n           \"\"beneficiaryName\"\": \"\"Jack Bauer\"\",\n           \"\"bankAccount\"\": \"\"NL53INGB0654422370\"\",\n           \"\"bankAccountId\"\": \"\"bnk_jrty3f\"\"\n         }},\n         \"\"_links\"\": {{\n           \"\"self\"\": {{\n             \"\"href\"\": \"\"https://api.mollie.com/v2/balances/bal_gVMhHKqSSRYJyPsuoPNFH\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n           }}\n         }}\n       }},\n       {{\n         \"\"resource\"\": \"\"balance\"\",\n         \"\"id\"\": \"\"bal_gVMhHKqSSRYJyPsuoPABC\"\",\n         \"\"mode\"\": \"\"live\"\",\n         \"\"createdAt\"\": \"\"2019-01-10T10:23:41+00:00\"\",\n         \"\"status\"\": \"\"active\"\",\n         \"\"currency\"\": \"\"EUR\"\",\n         \"\"availableAmount\"\": {{\n           \"\"value\"\": \"\"0.00\"\",\n           \"\"currency\"\": \"\"EUR\"\"\n         }},\n         \"\"pendingAmount\"\": {{\n           \"\"value\"\": \"\"0.00\"\",\n           \"\"currency\"\": \"\"EUR\"\"\n         }},\n         \"\"transferFrequency\"\": \"\"twice-a-month\"\",\n         \"\"transferThreshold\"\": {{\n           \"\"value\"\": \"\"5.00\"\",\n           \"\"currency\"\": \"\"EUR\"\"\n         }},\n         \"\"transferReference\"\": \"\"Mollie payout\"\",\n         \"\"transferDestination\"\": {{\n           \"\"type\"\": \"\"bank-account\"\",\n           \"\"beneficiaryName\"\": \"\"Jack Bauer\"\",\n           \"\"bankAccount\"\": \"\"NL97MOLL6351480700\"\",\n           \"\"bankAccountId\"\": \"\"bnk_jrty3e\"\"\n         }},\n         \"\"_links\"\": {{\n           \"\"self\"\": {{\n             \"\"href\"\": \"\"https://api.mollie.com/v2/balances/bal_gVMhHKqSSRYJyPsuoPABC\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n           }}\n         }}\n       }}\n    ]\n  }},\n  \"\"_links\"\": {{\n    \"\"documentation\"\": {{\n      \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/balances-api/list-balances\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    }},\n    \"\"self\"\": {{\n      \"\"href\"\": \"\"https://api.mollie.com/v2/balances?limit=5\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }},\n    \"\"previous\"\": null,\n    \"\"next\"\": {{\n      \"\"href\"\": \"\"https://api.mollie.com/v2/balances?from=bal_gVMhHKqSSRYJyPsuoPABC&limit=5\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }}\n  }}\n}}\";\n\n      private readonly string DefaultGetBalanceReportTransactionCategoriesResponse = @\"{\n    \"\"resource\"\": \"\"balance-report\"\",\n    \"\"balanceId\"\": \"\"bal_CKjKwQdjCwCSArXFAJNFH\"\",\n    \"\"timeZone\"\": \"\"Europe/Amsterdam\"\",\n    \"\"from\"\": \"\"2022-11-01\"\",\n    \"\"until\"\": \"\"2022-11-30\"\",\n    \"\"grouping\"\": \"\"transaction-categories\"\",\n    \"\"totals\"\": {\n        \"\"open\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"5.30\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"available\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.11\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        },\n        \"\"payments\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"3.57\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"transactionType\"\": \"\"payment\"\",\n                        \"\"count\"\": 36,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"1.07\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"0.02\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }, {\n                                \"\"method\"\": \"\"pointofsale\"\",\n                                \"\"count\"\": 35,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"1.05\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"split-payment\"\",\n                        \"\"count\"\": 3,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"2.50\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 3,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"2.50\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }\n                ]\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"3.66\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"transactionType\"\": \"\"payment\"\",\n                        \"\"count\"\": 36,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"1.07\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"0.02\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }, {\n                                \"\"method\"\": \"\"pointofsale\"\",\n                                \"\"count\"\": 35,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"1.05\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"split-payment\"\",\n                        \"\"count\"\": 3,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"2.50\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 3,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"2.50\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"released-rolling-reserve\"\",\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"0.09\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }\n                    }\n                ]\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        },\n        \"\"refunds\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"-1.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"transactionType\"\": \"\"refund\"\",\n                        \"\"count\"\": 1,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-1.00\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"creditcard\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-1.00\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"cardIssuer\"\": \"\"other\"\",\n                                        \"\"cardAudience\"\": \"\"other\"\",\n                                        \"\"cardRegion\"\": \"\"domestic\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-1.00\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        }\n                                    }\n                                ]\n                            }\n                        ]\n                    }\n                ]\n            }\n        },\n        \"\"chargebacks\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        },\n        \"\"capital\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        },\n        \"\"transfers\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        },\n        \"\"fee-prepayments\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"-0.28\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"prepaymentPartType\"\": \"\"fee\"\",\n                        \"\"count\"\": 1,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-0.28\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"feeType\"\": \"\"payment-fee\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-0.28\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"method\"\": \"\"ideal\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-0.28\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        }\n                                    }\n                                ]\n                            }\n                        ]\n                    }\n                ]\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"-0.28\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"prepaymentPartType\"\": \"\"fee\"\",\n                        \"\"count\"\": 1,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-0.28\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"feeType\"\": \"\"payment-fee\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-0.28\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"method\"\": \"\"ideal\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-0.28\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        }\n                                    }\n                                ]\n                            }\n                        ]\n                    }\n                ]\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"-0.24\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"prepaymentPartType\"\": \"\"fee\"\",\n                        \"\"count\"\": 1,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-0.25\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"feeType\"\": \"\"refund-fee\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-0.25\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"invoice-rounding-compensation\"\",\n                        \"\"count\"\": 1,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"0.01\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }\n                    }\n                ]\n            }\n        },\n        \"\"corrections\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        },\n        \"\"close\"\": {\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"5.21\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"available\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"2.25\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        }\n    },\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/balances/bal_CKjKwQdjCwCSArXFAJNFH/report\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/balances-api/get-balance-report\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n\n      private readonly string DefaultGetBalanceReportStatusBalancesResponse = @\"{\n    \"\"resource\"\": \"\"balance-report\"\",\n    \"\"balanceId\"\": \"\"bal_CKjKwQdjCwCSArXFAJNFH\"\",\n    \"\"timeZone\"\": \"\"Europe/Amsterdam\"\",\n    \"\"from\"\": \"\"2022-11-01\"\",\n    \"\"until\"\": \"\"2022-11-30\"\",\n    \"\"grouping\"\": \"\"status-balances\"\",\n    \"\"totals\"\": {\n        \"\"pendingBalance\"\": {\n            \"\"open\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"5.30\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"pending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"3.29\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"transactionType\"\": \"\"payment\"\",\n                        \"\"count\"\": 36,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"1.07\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"0.02\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }, {\n                                \"\"method\"\": \"\"pointofsale\"\",\n                                \"\"count\"\": 35,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"1.05\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"split-payment\"\",\n                        \"\"count\"\": 3,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"2.50\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 3,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"2.50\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"fee-prepayment\"\",\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-0.28\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"prepaymentPartType\"\": \"\"fee\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-0.28\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"feeType\"\": \"\"payment-fee\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-0.28\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        },\n                                        \"\"subtotals\"\": [{\n                                                \"\"method\"\": \"\"ideal\"\",\n                                                \"\"count\"\": 1,\n                                                \"\"amount\"\": {\n                                                    \"\"value\"\": \"\"-0.28\"\",\n                                                    \"\"currency\"\": \"\"EUR\"\"\n                                                }\n                                            }\n                                        ]\n                                    }\n                                ]\n                            }\n                        ]\n                    }\n                ]\n            },\n            \"\"movedToAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"3.38\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"transactionType\"\": \"\"payment\"\",\n                        \"\"count\"\": 36,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"1.07\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"0.02\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }, {\n                                \"\"method\"\": \"\"pointofsale\"\",\n                                \"\"count\"\": 35,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"1.05\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"split-payment\"\",\n                        \"\"count\"\": 3,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"2.50\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 3,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"2.50\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"fee-prepayment\"\",\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-0.28\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"prepaymentPartType\"\": \"\"fee\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-0.28\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"feeType\"\": \"\"payment-fee\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-0.28\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        },\n                                        \"\"subtotals\"\": [{\n                                                \"\"method\"\": \"\"ideal\"\",\n                                                \"\"count\"\": 1,\n                                                \"\"amount\"\": {\n                                                    \"\"value\"\": \"\"-0.28\"\",\n                                                    \"\"currency\"\": \"\"EUR\"\"\n                                                }\n                                            }\n                                        ]\n                                    }\n                                ]\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"released-rolling-reserve\"\",\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"0.09\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }\n                    }\n                ]\n            },\n            \"\"close\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"5.21\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        },\n        \"\"availableBalance\"\": {\n            \"\"open\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"0.11\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            },\n            \"\"movedFromPending\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"3.38\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"transactionType\"\": \"\"payment\"\",\n                        \"\"count\"\": 36,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"1.07\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"0.02\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }, {\n                                \"\"method\"\": \"\"pointofsale\"\",\n                                \"\"count\"\": 35,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"1.05\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"split-payment\"\",\n                        \"\"count\"\": 3,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"2.50\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"ideal\"\",\n                                \"\"count\"\": 3,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"2.50\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                }\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"fee-prepayment\"\",\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-0.28\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"prepaymentPartType\"\": \"\"fee\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-0.28\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"feeType\"\": \"\"payment-fee\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-0.28\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        },\n                                        \"\"subtotals\"\": [{\n                                                \"\"method\"\": \"\"ideal\"\",\n                                                \"\"count\"\": 1,\n                                                \"\"amount\"\": {\n                                                    \"\"value\"\": \"\"-0.28\"\",\n                                                    \"\"currency\"\": \"\"EUR\"\"\n                                                }\n                                            }\n                                        ]\n                                    }\n                                ]\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"released-rolling-reserve\"\",\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"0.09\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }\n                    }\n                ]\n            },\n            \"\"immediatelyAvailable\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"-1.24\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"subtotals\"\": [{\n                        \"\"transactionType\"\": \"\"refund\"\",\n                        \"\"count\"\": 1,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-1.00\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"method\"\": \"\"creditcard\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-1.00\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"cardIssuer\"\": \"\"other\"\",\n                                        \"\"cardAudience\"\": \"\"other\"\",\n                                        \"\"cardRegion\"\": \"\"domestic\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-1.00\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        }\n                                    }\n                                ]\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"fee-prepayment\"\",\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"-0.25\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        },\n                        \"\"subtotals\"\": [{\n                                \"\"prepaymentPartType\"\": \"\"fee\"\",\n                                \"\"count\"\": 1,\n                                \"\"amount\"\": {\n                                    \"\"value\"\": \"\"-0.25\"\",\n                                    \"\"currency\"\": \"\"EUR\"\"\n                                },\n                                \"\"subtotals\"\": [{\n                                        \"\"feeType\"\": \"\"refund-fee\"\",\n                                        \"\"count\"\": 1,\n                                        \"\"amount\"\": {\n                                            \"\"value\"\": \"\"-0.25\"\",\n                                            \"\"currency\"\": \"\"EUR\"\"\n                                        }\n                                    }\n                                ]\n                            }\n                        ]\n                    }, {\n                        \"\"transactionType\"\": \"\"invoice-rounding-compensation\"\",\n                        \"\"count\"\": 1,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"0.01\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }\n                    }\n                ]\n            },\n            \"\"close\"\": {\n                \"\"amount\"\": {\n                    \"\"value\"\": \"\"2.25\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }\n            }\n        }\n    },\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/balances/bal_CKjKwQdjCwCSArXFAJNFH/report\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/balances-api/get-balance-report\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n\n      private class GetBalanceResponseFactory {\n          public string BalanceId { get; set; } = \"bal_gVMhHKqSSRYJyPsuoPNFH\";\n          public DateTime CreatedAt { get; set; } = DateTime.SpecifyKind(new DateTime(2022, 11, 22, 13, 15, 0), DateTimeKind.Utc);\n          public string Currency { get; set; } = \"EUR\";\n          public BalanceResponseStatus Status { get; set; } = BalanceResponseStatus.Active;\n          public Amount AvailableAmount { get; set; } = new Amount(Api.Models.Currency.EUR, 905.25m);\n          public Amount PendingAmount { get; set; } = new Amount(Api.Models.Currency.EUR, 100);\n          public string TransferFrequency { get; set; } = \"twice-a-month\";\n          public Amount TransferThreshold { get; set; } = new Amount(Api.Models.Currency.EUR, 5);\n          public string TransferReference { get; set; } = \"Mollie payout\";\n\n          public BalanceTransferDestination TransferDestination { get; set; } = new BalanceTransferDestination {\n            Type = \"bank-account\",\n            BankAccount = \"bank-account\",\n            BeneficiaryName = \"Piet\"\n          };\n\n          public string CreateGetBalanceResponse() {\n            return @$\"\n  {{\n    \"\"resource\"\": \"\"balance\"\",\n    \"\"id\"\": \"\"{BalanceId}\"\",\n    \"\"mode\"\": \"\"live\"\",\n    \"\"createdAt\"\": \"\"{CreatedAt:yyyy-MM-ddTHH:mm:ss.fffffffzzz}\"\",\n    \"\"currency\"\": \"\"{Currency}\"\",\n    \"\"status\"\": \"\"{Status}\"\",\n    \"\"availableAmount\"\": {{\n      \"\"value\"\": \"\"{AvailableAmount.Value}\"\",\n      \"\"currency\"\": \"\"{AvailableAmount.Currency}\"\"\n    }},\n    \"\"pendingAmount\"\": {{\n      \"\"value\"\": \"\"{PendingAmount.Value}\"\",\n      \"\"currency\"\": \"\"{PendingAmount.Currency}\"\"\n    }},\n    \"\"transferFrequency\"\": \"\"{TransferFrequency}\"\",\n    \"\"transferThreshold\"\": {{\n      \"\"value\"\": \"\"{TransferThreshold.Value}\"\",\n      \"\"currency\"\": \"\"{TransferThreshold.Currency}\"\"\n    }},\n    \"\"transferReference\"\": \"\"{TransferReference}\"\",\n    \"\"transferDestination\"\": {{\n      \"\"type\"\": \"\"{TransferDestination.Type}\"\",\n      \"\"beneficiaryName\"\": \"\"{TransferDestination.BeneficiaryName}\"\",\n      \"\"bankAccount\"\": \"\"{TransferDestination.BankAccount}\"\",\n      \"\"bankAccountId\"\": \"\"bnk_jrty3f\"\"\n    }},\n    \"\"_links\"\": {{\n      \"\"self\"\": {{\n        \"\"href\"\": \"\"https://api.mollie.com/v2/balances/bal_gVMhHKqSSRYJyPsuoPNFH\"\",\n        \"\"type\"\": \"\"application/hal+json\"\"\n      }},\n      \"\"documentation\"\": {{\n        \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/balances-api/get-balance\"\",\n        \"\"type\"\": \"\"text/html\"\"\n      }}\n    }}\n  }}\";\n        }\n      }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/BalanceTransferClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.BalanceTransfer;\nusing Mollie.Api.Models.BalanceTransfer.Request;\nusing Mollie.Api.Models.BalanceTransfer.Response;\nusing RichardSzalay.MockHttp;\nusing Shouldly;\nusing Xunit;\nusing SortDirection = Mollie.Api.Models.SortDirection;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class BalanceTransferClientTests : BaseClientTests {\n    [Fact]\n    public async Task CreateBalanceTransferAsync_WithRequiredParameters_ResponseIsDeserializedInExpectedFormat() {\n        // Given: we create a balance transfer request with only the required parameters\n        const string balanceTransferId = \"balance-transfer-id\";\n        BalanceTransferRequest request = new() {\n            Description = \"Test Description\",\n            Amount = new Amount(Currency.EUR, 50),\n            Source = new BalanceTransferParty {\n                Id = \"source\",\n                Description = \"Test Source\",\n                Type = \"organization\"\n            },\n            Destination = new BalanceTransferParty {\n                Id = \"destination\",\n                Description = \"Test Destination\",\n                Type = \"organization\"\n            }\n        };\n        string jsonToReturnInMockResponse = CreateBalanceTransferJsonResponse(balanceTransferId, request);\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}connect/balance-transfers\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new BalanceTransferClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        BalanceTransferResponse response = await client.CreateBalanceTransferAsync(request);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.ShouldNotBeNull();\n        response.Description.ShouldBe(request.Description);\n        response.Amount.ShouldBeEquivalentTo(request.Amount);\n        response.Source.ShouldBeEquivalentTo(response.Source);\n        response.Destination.ShouldBeEquivalentTo(response.Destination);\n        response.Status.ShouldBe(\"succeeded\");\n        response.StatusReason.Code.ShouldBe(\"success\");\n        response.StatusReason.Message.ShouldBe(\"Balance transfer completed successfully.\");\n        response.CreatedAt.ToUniversalTime().ShouldBe(new DateTime(2025, 5, 1, 10, 0, 0, DateTimeKind.Utc));\n        response.ExecutedAt!.Value.ToUniversalTime().ShouldBe(new DateTime(2025, 5, 1, 10, 5, 0, DateTimeKind.Utc));\n        response.Mode.ShouldBe(Mode.Live);\n    }\n\n    [Theory]\n    [InlineData(null, null,  false, null, \"\")]\n    [InlineData(\"from\", null,  false, null, \"?from=from\")]\n    [InlineData(\"from\", 50,  false, null, \"?from=from&limit=50\")]\n    [InlineData(null, null,  true, null, \"?testmode=true\")]\n    [InlineData(null, null,  true, SortDirection.Desc, \"?testmode=true&sort=desc\")]\n    [InlineData(null, null,  true, SortDirection.Asc, \"?testmode=true&sort=asc\")]\n    public async Task GetBalanceTransferListAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue( string? from,\n        int? limit,\n        bool testmode,\n        SortDirection? sortDirection,\n        string expectedQueryString) {\n        // Given: We retrieve a list of customers\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}connect/balance-transfers{expectedQueryString}\")\n            .Respond(\"application/json\", CreateBalanceTransferListJsonResponse());\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new BalanceTransferClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await client.GetBalanceTransferListAsync(from, limit, sortDirection, testmode);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        result.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task GetBalanceTransferAsync_WithValidBalanceTransferId_ResponseIsDeserializedInExpectedFormat() {\n        // Given: We have a valid balance transfer ID\n        const string balanceTransferId = \"balance-transfer-id\";\n        BalanceTransferRequest request = new() {\n            Description = \"Test Description\",\n            Amount = new Amount(Currency.EUR, 50),\n            Source = new BalanceTransferParty {\n                Id = \"source\",\n                Description = \"Test Source\",\n                Type = \"organization\"\n            },\n            Destination = new BalanceTransferParty {\n                Id = \"destination\",\n                Description = \"Test Destination\",\n                Type = \"organization\"\n            }\n        };\n        string jsonToReturnInMockResponse = CreateBalanceTransferJsonResponse(balanceTransferId, request);\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}connect/balance-transfers/{balanceTransferId}\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new BalanceTransferClient(\"abcde\", httpClient);\n\n        // When: We attempt to retrieve the balance transfer\n        BalanceTransferResponse response = await client.GetBalanceTransferAsync(balanceTransferId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.ShouldNotBeNull();\n        response.Id.ShouldBe(balanceTransferId);\n        response.Description.ShouldBe(request.Description);\n    }\n\n    [Fact]\n    public async Task GetBalanceTransferAsync_WithTestmodeTrue_QueryStringContainsTestmodeParameter() {\n        // Given: We have a valid balance transfer ID\n        const string balanceTransferId = \"balance-transfer-id\";\n        BalanceTransferRequest request = new() {\n            Description = \"Test Description\",\n            Amount = new Amount(Currency.EUR, 50),\n            Source = new BalanceTransferParty {\n                Id = \"source\",\n                Description = \"Test Source\",\n                Type = \"organization\"\n            },\n            Destination = new BalanceTransferParty {\n                Id = \"destination\",\n                Description = \"Test Destination\",\n                Type = \"organization\"\n            }\n        };\n        string jsonToReturnInMockResponse = CreateBalanceTransferJsonResponse(balanceTransferId, request);\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}connect/balance-transfers/{balanceTransferId}?testmode=true\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new BalanceTransferClient(\"abcde\", httpClient);\n\n        // When: We attempt to retrieve the balance transfer\n        BalanceTransferResponse response = await client.GetBalanceTransferAsync(balanceTransferId, testmode: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.ShouldNotBeNull();\n        response.Id.ShouldBe(balanceTransferId);\n        response.Description.ShouldBe(request.Description);\n    }\n\n    [Fact]\n    public async Task GetBalanceTransferAsync_WithEmptyBalanceTransferId_ThrowsException() {\n        // Given: We have an empty balance transfer ID\n        var client = new BalanceTransferClient(\"abcde\", new HttpClient());\n\n        // When: We attempt to retrieve the balance transfer\n        ArgumentException exception = await Should.ThrowAsync<ArgumentException>(async () => {\n            await client.GetBalanceTransferAsync(\"\");\n        });\n\n        // Then\n        exception.Message.ShouldContain(\"balanceTransferId\");\n    }\n\n\n    private string CreateBalanceTransferListJsonResponse() {\n        BalanceTransferRequest request = new() {\n            Description = \"Test Description\",\n            Amount = new Amount(Currency.EUR, 50),\n            Source = new BalanceTransferParty {\n                Id = \"source\",\n                Description = \"Test Source\",\n                Type = \"organization\"\n            },\n            Destination = new BalanceTransferParty {\n                Id = \"destination\",\n                Description = \"Test Destination\",\n                Type = \"organization\"\n            }\n        };\n\n        return $@\"{{\n          \"\"count\"\": 1,\n          \"\"_embedded\"\": {{\n            \"\"connect-balance-transfers\"\": [\n                {CreateBalanceTransferJsonResponse(\"balance-transfer-id-1\", request)},\n                {CreateBalanceTransferJsonResponse(\"balance-transfer-id-2\", request)},\n            ]\n          }}\n        }}\";\n    }\n\n\n    private string CreateBalanceTransferJsonResponse(string balanceTransferId, BalanceTransferRequest request) {\n        return $@\"{{\n  \"\"resource\"\": \"\"connect-balance-transfer\"\",\n  \"\"id\"\": \"\"{balanceTransferId}\"\",\n  \"\"amount\"\": {{\n    \"\"value\"\": \"\"{request.Amount.Value}\"\",\n    \"\"currency\"\": \"\"{request.Amount.Currency}\"\"\n  }},\n  \"\"source\"\": {{\n    \"\"type\"\": \"\"{request.Source.Type}\"\",\n    \"\"id\"\": \"\"{request.Source.Id}\"\",\n    \"\"description\"\": \"\"{request.Source.Description}\"\"\n  }},\n  \"\"destination\"\": {{\n    \"\"type\"\": \"\"{request.Destination.Type}\"\",\n    \"\"id\"\": \"\"{request.Destination.Id}\"\",\n    \"\"description\"\": \"\"{request.Destination.Description}\"\"\n  }},\n  \"\"description\"\": \"\"{request.Description}\"\",\n  \"\"status\"\": \"\"succeeded\"\",\n  \"\"statusReason\"\": {{\n    \"\"code\"\": \"\"success\"\",\n    \"\"message\"\": \"\"Balance transfer completed successfully.\"\"\n  }},\n  \"\"metadata\"\": {{\n    \"\"order_id\"\": 12345,\n    \"\"customer_id\"\": 9876\n  }},\n  \"\"createdAt\"\": \"\"2025-05-01T10:00:00+00:00\"\",\n  \"\"executedAt\"\": \"\"2025-05-01T10:05:00+00:00\"\",\n  \"\"mode\"\": \"\"live\"\"\n}}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/BaseClientTests.cs",
    "content": "﻿using System.Net;\nusing RichardSzalay.MockHttp;\nusing System.Net.Http;\nusing System.Net.Mime;\n\nnamespace Mollie.Tests.Unit.Client {\n    public abstract class BaseClientTests {\n        protected const string DefaultRedirectUrl = \"https://www.mollie.com\";\n\n        protected MockHttpMessageHandler CreateMockHttpMessageHandler(\n            HttpMethod httpMethod,\n            string url,\n            string response,\n            string? expectedPartialContent = null,\n            string responseContentType =  MediaTypeNames.Application.Json,\n            HttpStatusCode responseStatusCode = HttpStatusCode.OK) {\n\n            MockHttpMessageHandler mockHttp = new();\n            MockedRequest mockedRequest = mockHttp.Expect(httpMethod, url)\n                .Respond(responseStatusCode, responseContentType, response);\n\n            if (!string.IsNullOrEmpty(expectedPartialContent))\n            {\n                mockedRequest.With(x =>\n                {\n                    string expectedContent = RemoveWhiteSpaces(expectedPartialContent);\n                    string content = RemoveWhiteSpaces(x.Content!.ReadAsStringAsync().Result);\n                    return content.Contains(expectedContent);\n                });\n            }\n\n            return mockHttp;\n        }\n\n        private string RemoveWhiteSpaces(string input)\n        {\n            return input\n                .Replace(System.Environment.NewLine, string.Empty)\n                .Replace(\" \", string.Empty);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/BaseMollieClientTests.cs",
    "content": "﻿using System.Linq;\nusing System.Net;\nusing System.Net.Http;\nusing System.Net.Mime;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Framework.Authentication;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Options;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class BaseMollieClientTests : BaseClientTests {\n    [Fact]\n    public async Task HttpResponseStatusCodeIsNotSuccesfull_ResponseBodyContainsMollieErrorDetails_MollieApiExceptionIsThrown() {\n\n        // Arrange\n        const string errorMessage = \"A validation error occured\";\n        const int errorStatus = (int)HttpStatusCode.UnprocessableEntity;\n        string responseBody = @$\"{{\n    \"\"_links\"\": {{\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/overview/handling-errors\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }},\n    \"\"detail\"\": \"\"{errorMessage}\"\",\n    \"\"status\"\": {errorStatus},\n    \"\"title\"\": \"\"Error\"\"\n}}\";\n        const string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\";\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Post,\n            expectedUrl,\n            responseBody,\n            responseStatusCode: HttpStatusCode.UnprocessableEntity);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        PaymentClient paymentClient = new(\"api-key\", httpClient);\n        PaymentRequest paymentRequest = new() {\n            Amount = new Amount(Currency.EUR, 50m),\n            Description = \"description\"\n        };\n\n        // Act\n        var exception = await Assert.ThrowsAsync<MollieApiException>(() => paymentClient.CreatePaymentAsync(paymentRequest));\n\n        // Assert\n        exception.Details.Detail.ShouldBe(errorMessage);\n        exception.Details.Status.ShouldBe(errorStatus);\n    }\n\n    [Fact]\n    public async Task HttpResponseStatusCodeIsNotSuccesfull_ResponseBodyContainsHtml_MollieApiExceptionIsThrown() {\n        // Arrange\n        string responseBody = \"<html><body>Whoops!</body></html>\";\n        const string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\";\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Post,\n            expectedUrl,\n            responseBody,\n            responseContentType: MediaTypeNames.Text.Html,\n            responseStatusCode: HttpStatusCode.UnprocessableEntity);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        PaymentClient paymentClient = new(\"api-key\", httpClient);\n        PaymentRequest paymentRequest = new() {\n            Amount = new Amount(Currency.EUR, 50m),\n            Description = \"description\"\n        };\n\n        // Act\n        var exception = await Assert.ThrowsAsync<MollieApiException>(() => paymentClient.CreatePaymentAsync(paymentRequest));\n\n        // Assert\n        exception.Details.Detail.ShouldBe(responseBody);\n        exception.Details.Status.ShouldBe((int)HttpStatusCode.UnprocessableEntity);\n    }\n\n    [Fact]\n    public async Task CustomUserAgentIsSetInOptions_UserAgentIsAppendedToDefaultUserAgent() {\n        // Arrange\n        const string customUserAgent = \"my-user-agent\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get,$\"{BaseMollieClient.DefaultBaseApiEndPoint}methods\")\n            .With(request => {\n                var userAgent = request.Headers.UserAgent.ToArray();\n                userAgent.ShouldNotBeNull();\n                userAgent.Length.ShouldBe(2);\n                userAgent[0].Product!.Name.ShouldStartWith(\"Mollie.Api.NET\");\n                userAgent[1].Product!.Name.ShouldBe(customUserAgent);\n\n                return true;\n            })\n            .Respond(\"application/json\", DefaultPaymentMethodJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var mollieClientOptions = new MollieClientOptions {\n            CustomUserAgent = customUserAgent,\n            ApiKey = \"api-key\"\n        };\n        var secretManager = new DefaultMollieSecretManager(mollieClientOptions.ApiKey);\n        using var paymentMethodClient = new PaymentMethodClient(mollieClientOptions, secretManager, httpClient);\n\n        // Act\n        await paymentMethodClient.GetPaymentMethodListAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task NoCustomUserAgentIsSetInOptions_UserAgentIsAppendedToDefaultUserAgent() {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get,$\"{BaseMollieClient.DefaultBaseApiEndPoint}methods\")\n            .With(request => {\n                var userAgent = request.Headers.UserAgent.ToArray();\n                userAgent.ShouldNotBeNull();\n                userAgent.Length.ShouldBe(1);\n                userAgent[0].Product!.Name.ShouldStartWith(\"Mollie.Api.NET\");\n\n                return true;\n            })\n            .Respond(\"application/json\", DefaultPaymentMethodJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var mollieClientOptions = new MollieClientOptions {\n            CustomUserAgent = null,\n            ApiKey = \"api-key\"\n        };\n        var secretManager = new DefaultMollieSecretManager(mollieClientOptions.ApiKey);\n        using var paymentMethodClient = new PaymentMethodClient(mollieClientOptions, secretManager, httpClient);\n\n        // Act\n        await paymentMethodClient.GetPaymentMethodListAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task CustomApiBaseUrlIsSetInOptions_RequestsAreRoutedToCustomApiUrl() {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        var mollieClientOptions = new MollieClientOptions {\n            ApiKey = \"api-key\",\n            ApiBaseUrl = \"https://custom-api-base.mollie.com/v2/\"\n        };\n        mockHttp.Expect(HttpMethod.Get,$\"{mollieClientOptions.ApiBaseUrl}methods\")\n            .Respond(\"application/json\", DefaultPaymentMethodJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var secretManager = new DefaultMollieSecretManager(mollieClientOptions.ApiKey);\n        using var paymentMethodClient = new PaymentMethodClient(mollieClientOptions, secretManager, httpClient);\n\n        // Act\n        await paymentMethodClient.GetPaymentMethodListAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task ProfileIdIsSetInOptions_ForPostRequest_RequestProfileIdIsSet() {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        var mollieClientOptions = new MollieClientOptions {\n            ApiKey = \"api-key\",\n            ProfileId = \"my-profile-id\"\n        };\n        mockHttp.Expect(HttpMethod.Post, $\"{mollieClientOptions.ApiBaseUrl}payments\")\n            .WithPartialContent($\"\\\"profileId\\\":\\\"{mollieClientOptions.ProfileId}\\\"\")\n            .Respond(\"application/json\", DefaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var secretManager = new DefaultMollieSecretManager(mollieClientOptions.ApiKey);\n        using var paymentClient = new PaymentClient(mollieClientOptions, secretManager, httpClient);\n        var request = new PaymentRequest {\n            Amount = new Amount(Currency.EUR, 10m),\n            Description = \"Test payment\"\n        };\n\n        // Act\n        await paymentClient.CreatePaymentAsync(request);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task TestModeIsSetInOptions_ForPostRequest_RequestTestModeIsSet() {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        var mollieClientOptions = new MollieClientOptions {\n            ApiKey = \"api-key\",\n            Testmode = true\n        };\n        mockHttp.Expect(HttpMethod.Post, $\"{mollieClientOptions.ApiBaseUrl}payments\")\n            .WithPartialContent(\"\\\"testmode\\\":true\")\n            .Respond(\"application/json\", DefaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var secretManager = new DefaultMollieSecretManager(mollieClientOptions.ApiKey);\n        using var paymentClient = new PaymentClient(mollieClientOptions, secretManager, httpClient);\n        var request = new PaymentRequest {\n            Amount = new Amount(Currency.EUR, 10m),\n            Description = \"Test payment\"\n        };\n\n        // Act\n        await paymentClient.CreatePaymentAsync(request);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    private const string DefaultPaymentMethodJsonResponse = @\"{\n        \"\"count\"\": 13,\n        \"\"_embedded\"\": {\n            \"\"methods\"\": [\n                {\n                     \"\"resource\"\": \"\"method\"\",\n                     \"\"id\"\": \"\"ideal\"\",\n                     \"\"description\"\": \"\"iDEAL\"\",\n                     \"\"minimumAmount\"\": {\n                        \"\"value\"\": \"\"0.01\"\",\n                        \"\"currency\"\": \"\"EUR\"\"\n                     },\n                     \"\"maximumAmount\"\": {\n                        \"\"value\"\": \"\"50000.00\"\",\n                        \"\"currency\"\": \"\"EUR\"\"\n                     },\n                     \"\"image\"\": {\n                        \"\"size1x\"\": \"\"https://mollie.com/external/icons/payment-methods/ideal.png\"\",\n                        \"\"size2x\"\": \"\"https://mollie.com/external/icons/payment-methods/ideal%402x.png\"\",\n                        \"\"svg\"\": \"\"https://mollie.com/external/icons/payment-methods/ideal.svg\"\"\n                    },\n                    \"\"status\"\": \"\"activated\"\"\n                }\n            ]\n        }\n    }\";\n\n\n    private const string DefaultPaymentJsonResponse = @\"\n{\n    \"\"resource\"\": \"\"payment\"\",\n    \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n    \"\"mode\"\": \"\"test\"\",\n    \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n    \"\"amount\"\":{\n        \"\"currency\"\":\"\"EUR\"\",\n        \"\"value\"\":\"\"100.00\"\"\n    },\n    \"\"description\"\":\"\"Description\"\",\n    \"\"method\"\": null,\n    \"\"metadata\"\": {\n        \"\"order_id\"\": \"\"12345\"\"\n    },\n    \"\"status\"\": \"\"open\"\",\n    \"\"isCancelable\"\": false,\n    \"\"locale\"\": \"\"nl_NL\"\",\n    \"\"restrictPaymentMethodsToCountry\"\": \"\"NL\"\",\n    \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n    \"\"details\"\": null,\n    \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n    \"\"sequenceType\"\": \"\"oneoff\"\",\n    \"\"redirectUrl\"\": \"\"https://webshop.example.org/order/12345/\"\",\n    \"\"webhookUrl\"\": \"\"https://webshop.example.org/payments/webhook/\"\",\n    \"\"authorizedAt\"\": \"\"2018-03-19T13:28:37+00:00\"\",\n    \"\"paidAt\"\": \"\"2018-03-21T13:28:37+00:00\"\",\n    \"\"canceledAt\"\": \"\"2018-03-22T13:28:37+00:00\"\",\n    \"\"expiredAt\"\": \"\"2018-03-23T13:28:37+00:00\"\",\n    \"\"failedAt\"\": \"\"2018-03-24T13:28:37+00:00\"\",\n    \"\"captureBefore\"\": \"\"2018-03-25T13:28:37+00:00\"\",\n    \"\"amountRefunded\"\": {\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"10.00\"\"\n    },\n    \"\"amountRemaining\"\": {\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"90.00\"\"\n    },\n    \"\"amountChargedBack\"\": {\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"10.00\"\"\n    },\n    \"\"cancelUrl\"\": \"\"https://webshop.example.org/order/12345/cancel\"\",\n    \"\"countryCode\"\": \"\"NL\"\",\n    \"\"settlementId\"\": \"\"stl_jDk30akdN\"\",\n    \"\"subscriptionId\"\": \"\"sub_rVKGtNd6s3\"\",\n    \"\"applicationFee\"\": {\n        \"\"amount\"\": {\n            \"\"currency\"\": \"\"EUR\"\",\n            \"\"value\"\": \"\"1.00\"\"\n        },\n        \"\"description\"\": \"\"description\"\"\n    },\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"checkout\"\": {\n            \"\"href\"\": \"\"https://www.mollie.com/payscreen/select-method/WDqYK6vllg\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"dashboard\"\": {\n            \"\"href\"\": \"\"https://www.mollie.com/dashboard/org_12345678/payments/tr_WDqYK6vllg\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/payments-api/get-payment\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/CapabilityClientTests.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.Capability;\nusing RichardSzalay.MockHttp;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class CapabilityClientTests {\n\n    [Fact]\n    public async Task GetCapabilityListAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get,$\"{BaseMollieClient.DefaultBaseApiEndPoint}capabilities\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", DefaultListCapabilitiesResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var capabilityClient = new CapabilityClient(\"access_1234\", httpClient);\n\n        // Act\n        var result = await capabilityClient.GetCapabilitiesListAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        result.Count.ShouldBe(1);\n        var capability = result.Items[0];\n        capability.Resource.ShouldBe(\"capability\");\n        capability.Name.ShouldBe(\"payments\");\n        capability.Status.ShouldBe(CapabilityStatus.Pending);\n        capability.StatusReason.ShouldBe(CapabilityStatusReason.OnboardingInformtionNeeded);\n        capability.Requirements.Count().ShouldBe(2);\n        var requirement1 = capability.Requirements.First();\n        requirement1.Id.ShouldBe(\"legal-representatives\");\n        requirement1.DueDate.ShouldBeNull();\n        requirement1.Status.ShouldBe(CapabilityRequirementStatus.Requested);\n        requirement1.Links.ShouldNotBeNull();\n        requirement1.Links.Dashboard.Href.ShouldBe(\"https://my.mollie.com/dashboard/\");\n        requirement1.Links.Dashboard.Type.ShouldBe(\"text/html\");\n        var requirement2 = capability.Requirements.Skip(1).First();\n        requirement2.Id.ShouldBe(\"bank-account\");\n        requirement2.DueDate.ShouldBe(new DateTime(2024, 5, 14, 1, 29, 9, DateTimeKind.Utc));\n        requirement2.Status.ShouldBe(CapabilityRequirementStatus.PastDue);\n        requirement2.Links.ShouldNotBeNull();\n        requirement2.Links.Dashboard.Href.ShouldBe(\"https://my.mollie.com/dashboard/\");\n        requirement2.Links.Dashboard.Type.ShouldBe(\"text/html\");\n    }\n\n    private const string DefaultListCapabilitiesResponse = @\"{\n  \"\"count\"\": 1,\n  \"\"_embedded\"\": {\n    \"\"capabilities\"\": [\n      {\n        \"\"resource\"\": \"\"capability\"\",\n        \"\"name\"\": \"\"payments\"\",\n        \"\"status\"\": \"\"pending\"\",\n        \"\"statusReason\"\": \"\"onboarding-information-needed\"\",\n        \"\"requirements\"\": [\n          {\n            \"\"id\"\": \"\"legal-representatives\"\",\n            \"\"dueDate\"\": null,\n            \"\"status\"\": \"\"requested\"\",\n            \"\"_links\"\": {\n              \"\"dashboard\"\": {\n                \"\"href\"\": \"\"https://my.mollie.com/dashboard/\"\",\n                \"\"type\"\": \"\"text/html\"\"\n              }\n            }\n          },\n          {\n            \"\"id\"\": \"\"bank-account\"\",\n            \"\"dueDate\"\": \"\"2024-05-14T01:29:09Z\"\",\n            \"\"status\"\": \"\"past-due\"\",\n            \"\"_links\"\": {\n              \"\"dashboard\"\": {\n                \"\"href\"\": \"\"https://my.mollie.com/dashboard/\"\",\n                \"\"type\"\": \"\"text/html\"\"\n              }\n            }\n          }\n        ]\n      }\n    ]\n  },\n  \"\"_links\"\": {\n    \"\"documentation\"\": {\n      \"\"href\"\": \"\"https://docs.mollie.com/reference/list-capabilities\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    }\n  }\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/CaptureClientTests.cs",
    "content": "﻿using System;\nusing Mollie.Api.Client;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Capture.Request;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.List.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class CaptureClientTests : BaseClientTests {\n        private const string defaultCaptureId = \"tr_ffh435dvgs\";\n        private const string defaultPaymentId = \"tr_WDqYK6vllg\";\n        private const string defaultShipmentId = \"shp_3wmsgCJN4U\";\n        private const string defaultSettlementId = \"settlementId\";\n        private const string defaultAmountValue = \"1027.99\";\n        private const string defaultAmountCurrency = \"EUR\";\n        private const string defaultStatus = \"succeeded\";\n\n        private string defaultCaptureJsonResponse = $@\"{{\n    \"\"resource\"\": \"\"capture\"\",\n    \"\"id\"\": \"\"{defaultCaptureId}\"\",\n    \"\"mode\"\": \"\"live\"\",\n    \"\"amount\"\": {{\n        \"\"value\"\": \"\"{defaultAmountValue}\"\",\n        \"\"currency\"\": \"\"{defaultAmountCurrency}\"\"\n    }},\n    \"\"settlementAmount\"\": {{\n        \"\"value\"\": \"\"1027.99\"\",\n        \"\"currency\"\": \"\"EUR\"\"\n    }},\n    \"\"paymentId\"\": \"\"{defaultPaymentId}\"\",\n    \"\"shipmentId\"\": \"\"{defaultShipmentId}\"\",\n    \"\"settlementId\"\": \"\"{defaultSettlementId}\"\",\n    \"\"status\"\": \"\"{defaultStatus}\"\",\n    \"\"createdAt\"\": \"\"2018-08-02T09:29:56+00:00\"\",\n}}\";\n\n        private string defaultCaptureListJsonResponse = $@\"{{\n    \"\"_embedded\"\": {{\n        \"\"captures\"\": [\n            {{\n                \"\"resource\"\": \"\"capture\"\",\n                \"\"id\"\": \"\"cpt_4qqhO89gsT\"\",\n                \"\"mode\"\": \"\"live\"\",\n                \"\"amount\"\": {{\n                    \"\"value\"\": \"\"{defaultAmountValue}\"\",\n                    \"\"currency\"\": \"\"{defaultAmountCurrency}\"\"\n                }},\n                \"\"settlementAmount\"\": {{\n                    \"\"value\"\": \"\"1027.99\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }},\n                \"\"paymentId\"\": \"\"{defaultPaymentId}\"\",\n                \"\"shipmentId\"\": \"\"{defaultShipmentId}\"\",\n                \"\"settlementId\"\": \"\"{defaultSettlementId}\"\",\n                \"\"status\"\": \"\"{defaultStatus}\"\",\n                \"\"createdAt\"\": \"\"2018-08-02T09:29:56+00:00\"\"\n            }}\n        ]\n    }},\n    \"\"count\"\": 1\n}}\";\n\n        [Theory]\n        [InlineData(true, \"?testmode=true\")]\n        [InlineData(false, \"\")]\n        public async Task GetCaptureAsync_CorrectQueryParametersAreAdded(bool testmode, string expectedQueryString) {\n            // Given: We make a request to retrieve a capture\n            const string paymentId = \"payment-id\";\n            const string captureId = \"capture-id\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}/captures/{captureId}{expectedQueryString}\", defaultCaptureJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await captureClient.GetCaptureAsync(paymentId, captureId, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Theory]\n        [InlineData(true, \"?testmode=true\")]\n        [InlineData(false, \"\")]\n        public async Task GetCapturesListAsync_CorrectQueryParametersAreAdded(bool testmode, string expectedQueryString) {\n            // Given: We make a request to retrieve a capture\n            const string paymentId = \"payment-id\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}/captures{expectedQueryString}\", defaultCaptureJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await captureClient.GetCaptureListAsync(paymentId, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Fact]\n        public async Task GetCaptureAsync_DefaultBehaviour_ResponseIsParsed() {\n            // Given: We request a capture with a payment id and capture id\n            string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{defaultPaymentId}/captures/{defaultCaptureId}\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, defaultCaptureJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"api-key\", httpClient);\n\n            // When: We make the request\n            CaptureResponse captureResponse = await captureClient.GetCaptureAsync(defaultPaymentId, defaultCaptureId);\n\n            // Then: Response should be parsed\n            mockHttp.VerifyNoOutstandingExpectation();\n            captureResponse.ShouldNotBeNull();\n            captureResponse.PaymentId.ShouldBe(defaultPaymentId);\n            captureResponse.ShipmentId.ShouldBe(defaultShipmentId);\n            captureResponse.SettlementId.ShouldBe(defaultSettlementId);\n            captureResponse.Amount.Value.ShouldBe(defaultAmountValue);\n            captureResponse.Amount.Currency.ShouldBe(defaultAmountCurrency);\n            captureResponse.Status.ShouldBe(defaultStatus);\n        }\n\n        [Fact]\n        public async Task GetCapturesListAsync_DefaultBehaviour_ResponseIsParsed() {\n            // Given: We request a list of captures\n            string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{defaultPaymentId}/captures\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, defaultCaptureListJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"api-key\", httpClient);\n\n            // When: We make the request\n            ListResponse<CaptureResponse> listCaptureResponse = await captureClient.GetCaptureListAsync(defaultPaymentId);\n\n            // Then: Response should be parsed\n            mockHttp.VerifyNoOutstandingExpectation();\n            listCaptureResponse.ShouldNotBeNull();\n            listCaptureResponse.Count.ShouldBe(1);\n            CaptureResponse captureResponse = listCaptureResponse.Items.First();\n            captureResponse.PaymentId.ShouldBe(defaultPaymentId);\n            captureResponse.ShipmentId.ShouldBe(defaultShipmentId);\n            captureResponse.SettlementId.ShouldBe(defaultSettlementId);\n            captureResponse.Amount.Value.ShouldBe(defaultAmountValue);\n            captureResponse.Amount.Currency.ShouldBe(defaultAmountCurrency);\n            captureResponse.Status.ShouldBe(defaultStatus);\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetCaptureAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Given\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"abcde\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await captureClient.GetCaptureAsync(paymentId, \"capture-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetCaptureAsync_NoCaptureIdIsGiven_ArgumentExceptionIsThrown(string? captureId) {\n            // Given\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>\n#pragma warning disable CS8604 // Possible null reference argument.\n                await captureClient.GetCaptureAsync(\"payment-id\", captureId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'captureId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetCapturesListAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Given\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"abcde\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await captureClient.GetCaptureListAsync(paymentId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateCapture_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Given\n            var captureRequest = new CaptureRequest {\n                Amount = new Amount(Currency.EUR, 10m),\n                Description = \"capture-description\"\n            };\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"abcde\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await captureClient.CreateCapture(paymentId, captureRequest));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Fact]\n        public async Task CreateCapture_CaptureIsCreated_CaptureIsDeserialized() {\n            // Given\n            var captureRequest = new CaptureRequest {\n                Amount = new Amount(defaultAmountCurrency, defaultAmountValue),\n                Description = \"capture-description\"\n            };\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Post,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{defaultPaymentId}/captures\",\n                defaultCaptureJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            CaptureClient captureClient = new CaptureClient(\"abcde\", httpClient);\n\n            // When\n            CaptureResponse response = await captureClient.CreateCapture(defaultPaymentId, captureRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n            response.Id.ShouldBe(defaultCaptureId);\n            response.PaymentId.ShouldBe(defaultPaymentId);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/ChargebackClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.Chargeback.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class ChargebackClientTests : BaseClientTests {\n        private const string defaultPaymentId = \"tr_WDqYK6vllg\";\n        private const string defaultChargebackId = \"chb_n9z0tp\";\n        private const string defaultChargebackReasonCode = \"AC01\";\n        private const string defaultChargebackReason = \"Account identifier incorrect (i.e. invalid IBAN)\";\n\n        private string defaultGetChargebacksResponse = @$\"{{\n    \"\"resource\"\": \"\"chargeback\"\",\n    \"\"id\"\": \"\"{defaultChargebackId}\"\",\n    \"\"amount\"\": {{\n        \"\"currency\"\": \"\"USD\"\",\n        \"\"value\"\": \"\"43.38\"\"\n    }},\n    \"\"settlementAmount\"\": {{\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"-35.07\"\"\n    }},\n    \"\"createdAt\"\": \"\"2018-03-14T17:00:52.0Z\"\",\n     \"\"reason\"\": {{\n       \"\"code\"\": \"\"AC01\"\",\n       \"\"description\"\": \"\"Account identifier incorrect (i.e. invalid IBAN)\"\"\n     }},\n    \"\"reversedAt\"\": null,\n    \"\"paymentId\"\": \"\"{defaultPaymentId}\"\",\n    \"\"_links\"\": {{\n        \"\"self\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg/chargebacks/chb_n9z0tp\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"payment\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/chargebacks-api/get-chargeback\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }}\n}}\";\n\n        [Fact]\n        public async Task GetChargebackAsync_ResponseIsDeserializedInExpectedFormat() {\n            // Given: we retrieve the chargeback by id and payment id\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}*\")\n                .Respond(\"application/json\", defaultGetChargebacksResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ChargebackClient chargebackClient = new ChargebackClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            ChargebackResponse chargebackResponse = await chargebackClient.GetChargebackAsync(defaultPaymentId, defaultChargebackId);\n\n            // Then\n            chargebackResponse.PaymentId.ShouldBe(defaultPaymentId);\n            chargebackResponse.Id.ShouldBe(defaultChargebackId);\n            chargebackResponse.Reason.ShouldNotBeNull();\n            chargebackResponse.Reason!.Code.ShouldBe(defaultChargebackReasonCode);\n            chargebackResponse.Reason.Description.ShouldBe(defaultChargebackReason);\n        }\n\n        [Theory]\n        [InlineData(false, \"\")]\n        [InlineData(true, \"?testmode=true\")]\n        public async Task GetOrderRefundListAsync_QueryParameterOptions_CorrectParametersAreAdded(bool testmode, string expectedQueryString) {\n            // Given: we retrieve the chargeback by id and payment id\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{defaultPaymentId}/chargebacks/{defaultChargebackId}{expectedQueryString}\")\n                .Respond(\"application/json\", defaultGetChargebacksResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ChargebackClient chargebackClient = new ChargebackClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await chargebackClient.GetChargebackAsync(defaultPaymentId, defaultChargebackId, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Theory]\n        [InlineData(null, null, false, \"\")]\n        [InlineData(\"from\", null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, false, \"?from=from&limit=50\")]\n        [InlineData(null, null, true, \"?testmode=true\")]\n        public async Task GetChargebacksListAsync_FromLimitTestmodeQueryParameterOptions_CorrectParametersAreAdded(string? from, int? limit, bool testmode, string expectedQueryString) {\n            // Given: we retrieve the chargeback by id and payment id\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{defaultPaymentId}/chargebacks{expectedQueryString}\")\n                .Respond(\"application/json\", defaultGetChargebacksResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ChargebackClient chargebackClient = new ChargebackClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await chargebackClient.GetChargebackListAsync(defaultPaymentId, from, limit, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Theory]\n        [InlineData(null, false, \"\")]\n        [InlineData(\"profileId\", false, \"?profileId=profileId\")]\n        [InlineData(\"profileId\", true, \"?profileId=profileId&testmode=true\")]\n        public async Task GetChargebacksListAsync_ProfileTestModeQueryParameterOptions_CorrectParametersAreAdded(string? profileId, bool testmode, string expectedQueryString) {\n            // Given: we retrieve the chargeback by id and payment id\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}chargebacks{expectedQueryString}\")\n                .Respond(\"application/json\", defaultGetChargebacksResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ChargebackClient chargebackClient = new ChargebackClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await chargebackClient.GetChargebackListAsync(profileId, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetChargebackAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ChargebackClient chargebackClient = new ChargebackClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await chargebackClient.GetChargebackAsync(paymentId, \"chargeback-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetChargebackAsync_NoChargeBackIdIsGiven_ArgumentExceptionIsThrown(string? chargebackId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ChargebackClient chargebackClient = new ChargebackClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await chargebackClient.GetChargebackAsync(\"payment-id\", chargebackId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'chargebackId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetChargebacksListAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ChargebackClient chargebackClient = new ChargebackClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await chargebackClient.GetChargebackListAsync(paymentId: paymentId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/ClientClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing RichardSzalay.MockHttp;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class ClientClientTests : BaseClientTests {\n    [Fact]\n    public async Task GetClientAsync_WithoutClientId_ThrowsArgumentException() {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var permissionClient = new ClientClient(\"access_abcde\", httpClient);\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => permissionClient.GetClientAsync(string.Empty));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument 'clientId' is null or empty\");\n    }\n\n    [Fact]\n    public async Task GetClientAsync_WithClientId_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        const string clientId = \"org_12345678\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get,$\"{BaseMollieClient.DefaultBaseApiEndPoint}clients/{clientId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", DefaultGetClientResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var clientClient = new ClientClient(\"access_1234\", httpClient);\n\n        // Act\n        var result = await clientClient.GetClientAsync(clientId);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        result.Resource.ShouldBe(\"client\");\n        result.Id.ShouldBe(clientId);\n        result.Commission.ShouldNotBeNull().Count.ShouldBe(0);\n        result.Links.ShouldNotBeNull();\n        result.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/clients/org_12345678\");\n        result.Links.Self.Type.ShouldBe(\"application/hal+json\");\n        result.Links.Organization.Href.ShouldBe(\"https://api.mollie.com/v2/organizations/org_12345678\");\n        result.Links.Organization.Type.ShouldBe(\"application/hal+json\");\n        result.Links.Onboarding.Href.ShouldBe(\"https://api.mollie.com/v2/onboarding/org_12345678\");\n        result.Links.Onboarding.Type.ShouldBe(\"application/hal+json\");\n        result.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/clients-api\");\n        result.Links.Documentation.Type.ShouldBe(\"text/html\");\n    }\n\n    [Theory]\n    [InlineData(false, false, false, \"\")]\n    [InlineData(true, true, true, \"?embed=organization,onboarding,capabilities\")]\n    [InlineData(true, false, false, \"?embed=organization\")]\n    [InlineData(false, true, false, \"?embed=onboarding\")]\n    [InlineData(false, false, true, \"?embed=capabilities\")]\n    public async Task GetClientAsync_WithEmbeddedParameters_GeneratesExpectedUrl(\n        bool embedOrganization, bool embedOnboarding, bool embedCapabilities, string expectedQueryString)\n    {\n        // Arrange\n        const string clientId = \"org_12345678\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get,$\"{BaseMollieClient.DefaultBaseApiEndPoint}clients/{clientId}{expectedQueryString}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", DefaultGetClientResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var clientClient = new ClientClient(\"access_1234\", httpClient);\n\n        // Act\n        await clientClient.GetClientAsync(clientId, embedOrganization, embedOnboarding, embedCapabilities);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n    }\n\n    [Theory]\n    [InlineData(null, null, false, false, false, \"\")]\n    [InlineData(\"from\", null, false, false, false, \"?from=from\")]\n    [InlineData(\"from\", 50, false, false, false, \"?from=from&limit=50\")]\n    [InlineData(\"from\", 50, true, false, false, \"?from=from&limit=50&embed=organization\")]\n    [InlineData(\"from\", 50, true, true, false, \"?from=from&limit=50&embed=organization,onboarding\")]\n    [InlineData(\"from\", 50, true, true, true, \"?from=from&limit=50&embed=organization,onboarding,capabilities\")]\n    public async Task GetClientListAsync_WithQueryParameters_QueryStringOnlyContainsTestModeParameterIfTrue(\n        string? from, int? limit, bool embedOrganization, bool embedOnboarding, bool embedCapabilities, string expectedQueryString) {\n        // Given: We retrieve a list of clients\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}clients{expectedQueryString}\")\n            .Respond(\"application/json\", DefaultGetClientListResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var clientClient = new ClientClient(\"access_1234\", httpClient);\n\n        // When: We send the request\n        var result = await clientClient.GetClientListAsync(\n            from, limit, embedOrganization, embedOnboarding, embedCapabilities);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        result.ShouldNotBeNull();\n    }\n\n    [Fact]\n    public async Task GetClienListAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get,$\"{BaseMollieClient.DefaultBaseApiEndPoint}clients\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", DefaultGetClientListResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var clientClient = new ClientClient(\"access_1234\", httpClient);\n\n        // Act\n        var result = await clientClient.GetClientListAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        result.Count.ShouldBe(2);\n        result.Items.ShouldNotBeNull();\n        result.Links.ShouldNotBeNull();\n        result.Links.ShouldNotBeNull();\n        result.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/clients\");\n        result.Links.Self.Type.ShouldBe(\"application/hal+json\");\n        result.Links.Previous.ShouldBeNull();\n        result.Links.Next!.Href.ShouldBe(\"https://api.mollie.com/v2/clients?from=org_63916732&limit=5\");\n        result.Links.Next.Type.ShouldBe(\"application/hal+json\");\n        result.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/clients-api\");\n        result.Links.Documentation.Type.ShouldBe(\"text/html\");\n    }\n\n    private const string DefaultGetClientResponse = @\"{\n        \"\"resource\"\": \"\"client\"\",\n        \"\"id\"\": \"\"org_12345678\"\",\n        \"\"commission\"\": {\n          \"\"count\"\": 0\n        },\n        \"\"organizationCreatedAt\"\": \"\"2024-10-03T10:47:38.457381+00:00\"\",\n        \"\"_links\"\": {\n            \"\"self\"\": {\n              \"\"href\"\": \"\"https://api.mollie.com/v2/clients/org_12345678\"\",\n              \"\"type\"\": \"\"application/hal+json\"\"\n            },\n            \"\"organization\"\": {\n              \"\"href\"\": \"\"https://api.mollie.com/v2/organizations/org_12345678\"\",\n              \"\"type\"\": \"\"application/hal+json\"\"\n            },\n            \"\"onboarding\"\": {\n              \"\"href\"\": \"\"https://api.mollie.com/v2/onboarding/org_12345678\"\",\n              \"\"type\"\": \"\"application/hal+json\"\"\n            },\n            \"\"documentation\"\": {\n              \"\"href\"\": \"\"https://docs.mollie.com/reference/clients-api\"\",\n              \"\"type\"\": \"\"text/html\"\"\n            }\n        }\n      }\";\n\n    private const string DefaultGetClientListResponse = $@\"{{\n        \"\"count\"\": 2,\n        \"\"_embedded\"\": {{\n            \"\"clients\"\": [\n                {DefaultGetClientResponse},\n                {DefaultGetClientResponse}\n            ]\n        }},\n        \"\"_links\"\": {{\n            \"\"self\"\": {{\n              \"\"href\"\": \"\"https://api.mollie.com/v2/clients\"\",\n              \"\"type\"\": \"\"application/hal+json\"\"\n            }},\n            \"\"previous\"\": null,\n            \"\"next\"\": {{\n              \"\"href\"\": \"\"https://api.mollie.com/v2/clients?from=org_63916732&limit=5\"\",\n              \"\"type\"\": \"\"application/hal+json\"\"\n            }},\n            \"\"documentation\"\": {{\n              \"\"href\"\": \"\"https://docs.mollie.com/reference/clients-api\"\",\n              \"\"type\"\": \"\"text/html\"\"\n            }}\n          }}\n    }}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/ClientLinkClientTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.ClientLink.Request;\nusing Mollie.Api.Models.ClientLink.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class ClientLinkClientTests : BaseClientTests\n{\n    [Fact]\n    public async Task CreateClientLinkAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Given: We create a payment link\n        const string clientLinkId = \"csr_vZCnNQsV2UtfXxYifWKWH\";\n        const string clientLinkUrl = \"myurl\";\n        string clientLinkResponseJson = CreateClientLinkResponseJson(clientLinkId, clientLinkUrl);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When( HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}client-links\")\n            .Respond(\"application/json\", clientLinkResponseJson);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        ClientLinkClient clientLinkClient = new ClientLinkClient(\"clientId\", \"access_1234\", httpClient);\n        var request = new ClientLinkRequest {\n            Owner = new ClientLinkOwner {\n                Email = \"email\",\n                GivenName = \"gicen-name\",\n                FamilyName = \"family-name\"\n            },\n            Address = new AddressObject(),\n            Name = \"name\"\n        };\n\n        // When: We send the request\n        ClientLinkResponse response = await clientLinkClient.CreateClientLinkAsync(request);\n\n        // Then\n        response.Id.ShouldBe(clientLinkId);\n        response.Links.ClientLink.Href.ShouldBe(clientLinkUrl);\n        mockHttp.VerifyNoOutstandingRequest();\n    }\n\n    [Theory]\n    [InlineData(true)]\n    [InlineData(false)]\n    public void GenerateClientLinkWithParameters_GeneratesExpectedUrl(bool forceApprovalPrompt)\n    {\n        // Arrange\n        const string clientId = \"app_j9Pakf56Ajta6Y65AkdTtAv\";\n        const string clientLinkUrl = \"https://my.mollie.com/dashboard/client-link/csr_vZCnNQsV2UtfXxYifWKWH\";\n        const string state = \"decafbad\";\n        var scopes = new List<string>()\n        {\n            \"onboarding.read\",\n            \"organizations.read\",\n            \"payments.write\",\n            \"payments.read\",\n            \"profiles.write\",\n        };\n        ClientLinkClient clientLinkClient = new ClientLinkClient(\n            clientId, \"access_1234\", new MockHttpMessageHandler().ToHttpClient());\n\n        // Act\n        string result = clientLinkClient.GenerateClientLinkWithParameters(\n            clientLinkUrl, state, scopes, forceApprovalPrompt);\n\n        // Assert\n        string expectedApprovalPrompt = forceApprovalPrompt ? \"force\" : \"auto\";\n        result.ShouldBe(\"https://my.mollie.com/dashboard/client-link/csr_vZCnNQsV2UtfXxYifWKWH\" +\n                        $\"?client_id={clientId}\" +\n                        $\"&state={state}\" +\n                        \"&scope=onboarding.read+organizations.read+payments.write+payments.read+profiles.write\" +\n                        $\"&approval_prompt={expectedApprovalPrompt}\");\n    }\n\n    private string CreateClientLinkResponseJson(string id, string clientLinkUrl)\n    {\n        return $@\"{{\n    \"\"id\"\": \"\"{id}\"\",\n    \"\"resource\"\": \"\"client-link\"\",\n    \"\"_links\"\": {{\n        \"\"clientLink\"\": {{\n            \"\"href\"\": \"\"{clientLinkUrl}\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }},\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/clients-api/create-client-link\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }}\n}}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/ConnectClientTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.Connect.Request;\nusing Mollie.Api.Models.Connect.Response;\nusing Mollie.Api.Options;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class ConnectClientTests : BaseClientTests\n{\n    private const string ClientId = \"client-id\";\n    private const string ClientSecret = \"client-secret\";\n\n    [Fact]\n    public void GetAuthorizationUrl_WithCustomWithSingleScope_GeneratesAuthorizationUrl()\n    {\n        // Arrange\n        var mollieClientOptions = new MollieClientOptions {\n            ApiKey = string.Empty,\n            ConnectOAuthAuthorizeEndPoint = \"https://custom-authorize-endpoint.mollie.com/oauth2/authorize\",\n            ClientId = ClientId,\n            ClientSecret = ClientSecret\n        };\n        HttpClient httpClient = new();\n        ConnectClient connectClient = new(mollieClientOptions, httpClient);\n        var scopes = new List<string> {AppPermissions.PaymentsRead};\n\n        // Act\n        string authorizationUrl = connectClient.GetAuthorizationUrl(\"abcde\", scopes);\n\n        // Assert\n        string expectedUrl = $\"{mollieClientOptions.ConnectOAuthAuthorizeEndPoint}?client_id={ClientId}&state=abcde&scope=payments.read&response_type=code&approval_prompt=auto\";\n        authorizationUrl.ShouldBe(expectedUrl);\n    }\n\n    [Fact]\n    public void GetAuthorizationUrl_WithSingleScope_GeneratesAuthorizationUrl()\n    {\n        // Arrange\n        HttpClient httpClient = new HttpClient();\n        ConnectClient connectClient = new ConnectClient(ClientId, ClientSecret, httpClient);\n        var scopes = new List<string> {AppPermissions.PaymentsRead};\n\n        // Act\n        string authorizationUrl = connectClient.GetAuthorizationUrl(\"abcde\", scopes);\n\n        // Assert\n        string expectedUrl = $\"https://my.mollie.com/oauth2/authorize?client_id={ClientId}&state=abcde&scope=payments.read&response_type=code&approval_prompt=auto\";\n        authorizationUrl.ShouldBe(expectedUrl);\n    }\n\n    [Theory]\n    [InlineData(\"refresh_abcde\", \"refresh_token\")]\n    [InlineData(\"abcde\", \"authorization_code\")]\n    public async Task GetAccessTokenAsync_WithRefreshToken_ResponseIsDeserializedInExpectedFormat(string refreshToken, string expectedGrantType)\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Post, \"https://api.mollie.com/oauth2/tokens\")\n            .Respond(\"application/json\", defaultGetTokenResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        ConnectClient connectClient = new ConnectClient(ClientId, ClientSecret, httpClient);\n        var tokenRequest = new TokenRequest(refreshToken, DefaultRedirectUrl);\n\n        // Act\n        TokenResponse tokenResponse = await connectClient.GetAccessTokenAsync(tokenRequest);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n        tokenRequest.GrantType.ShouldBe(expectedGrantType);\n        tokenResponse.ShouldNotBeNull();\n        tokenResponse.AccessToken.ShouldBe(\"access_46EUJ6x8jFJZZeAvhNH4JVey6qVpqR\");\n        tokenResponse.RefreshToken.ShouldBe(\"refresh_FS4xc3Mgci2xQ5s5DzaLXh3HhaTZOP\");\n        tokenResponse.ExpiresIn.ShouldBe(3600);\n        tokenResponse.TokenType.ShouldBe(\"bearer\");\n        tokenResponse.Scope.ShouldBe(\"payments.read organizations.read\");\n    }\n\n    [Fact]\n    public async Task RevokeTokenAsync_SendsRequest()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Delete, \"https://api.mollie.com/oauth2/tokens\")\n            .Respond(HttpStatusCode.NoContent);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        ConnectClient connectClient = new ConnectClient(ClientId, ClientSecret, httpClient);\n        var revokeTokenRequest = new RevokeTokenRequest\n        {\n            Token = \"access_46EUJ6x8jFJZZeAvhNH4JVey6qVpqR\",\n            TokenTypeHint = \"refresh_token\"\n        };\n\n        // Act\n        await connectClient.RevokeTokenAsync(revokeTokenRequest);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task RevokeTokenAsync_WithCustomTokenEndpoints_SendsRequestToCustomEndpoint()\n    {\n        // Arrange\n        var mollieClientOptions = new MollieClientOptions {\n            ApiKey = string.Empty,\n            ConnectTokenEndPoint = \"https://custom-token-endpoint.mollie.com/oauth2/\",\n            ClientId = ClientId,\n            ClientSecret = ClientSecret\n        };\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Delete, $\"{mollieClientOptions.ConnectTokenEndPoint}tokens\")\n            .Respond(HttpStatusCode.NoContent);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        ConnectClient connectClient = new(mollieClientOptions, httpClient);\n        var revokeTokenRequest = new RevokeTokenRequest\n        {\n            Token = \"access_46EUJ6x8jFJZZeAvhNH4JVey6qVpqR\",\n            TokenTypeHint = \"refresh_token\"\n        };\n\n        // Act\n        await connectClient.RevokeTokenAsync(revokeTokenRequest);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    private const string defaultGetTokenResponse = @\"\n{\n    \"\"access_token\"\": \"\"access_46EUJ6x8jFJZZeAvhNH4JVey6qVpqR\"\",\n    \"\"refresh_token\"\": \"\"refresh_FS4xc3Mgci2xQ5s5DzaLXh3HhaTZOP\"\",\n    \"\"expires_in\"\": 3600,\n    \"\"token_type\"\": \"\"bearer\"\",\n    \"\"scope\"\": \"\"payments.read organizations.read\"\"\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/CustomerClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Customer.Request;\nusing Mollie.Api.Models.Customer.Response;\nusing Mollie.Api.Models.Payment.Request;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class CustomerClientTests : BaseClientTests {\n        [Theory]\n        [InlineData(\"customers/customer-id\", false)]\n        [InlineData(\"customers/customer-id?testmode=true\", true)]\n        public async Task GetCustomerAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string expectedUrl, bool testModeParameter) {\n            // Given: We retrieve a customer\n            const string customerId = \"customer-id\";\n\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}{expectedUrl}\")\n                .Respond(\"application/json\", DefaultCustomerJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            CustomerResponse customerResponse = await customerClient.GetCustomerAsync(customerId, testModeParameter);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            customerResponse.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(null, null, false, \"\")]\n        [InlineData(\"from\", null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, false, \"?from=from&limit=50\")]\n        [InlineData(null, null, true, \"?testmode=true\")]\n        public async Task GetCustomerListAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string? from, int? limit, bool testmode, string expectedQueryString) {\n            // Given: We retrieve a list of customers\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}customers{expectedQueryString}\")\n                .Respond(\"application/json\", DefaultCustomerJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await customerClient.GetCustomerListAsync(from, limit, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(null, null, null, false, \"\")]\n        [InlineData(\"from\", null, null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, null, false, \"?from=from&limit=50\")]\n        [InlineData(null, null, null, true, \"?testmode=true\")]\n        [InlineData(null, null, \"profile-id\", true, \"?profileId=profile-id\")]\n        public async Task GetCustomerPaymentListAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string? from, int? limit, string? profileId, bool testmode, string expectedQueryString) {\n            // Given: We retrieve a list of customers\n            const string customerId = \"customer-id\";\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}customers/{customerId}/payments{expectedQueryString}\")\n                .Respond(\"application/json\", DefaultCustomerJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await customerClient.GetCustomerPaymentListAsync(customerId, from, limit, profileId, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Fact]\n        public async Task DeleteCustomerAsync_TestmodeIsTrue_RequestContainsTestmodeModel() {\n            // Given: We make a request to retrieve a payment with embedded refunds\n            const string customerId = \"customer-id\";\n            string expectedContent = \"\\\"testmode\\\":true\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Delete, $\"{BaseMollieClient.DefaultBaseApiEndPoint}customers/{customerId}\", DefaultCustomerJsonToReturn, expectedContent);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await customerClient.DeleteCustomerAsync(customerId, true);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateCustomerAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await customerClient.UpdateCustomerAsync(customerId, new CustomerRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task DeleteCustomerAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await customerClient.DeleteCustomerAsync(customerId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetCustomerAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await customerClient.GetCustomerAsync(customerId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetCustomerPaymentListAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await customerClient.GetCustomerPaymentListAsync(customerId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateCustomerPayment_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var customerClient = new CustomerClient(\"api-key\", httpClient);\n            var paymentRequest = new PaymentRequest()\n            {\n                Amount = new Amount(Currency.EUR, 100),\n                Description = \"Order #12345\",\n            };\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await customerClient.CreateCustomerPayment(customerId, paymentRequest));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        private const string DefaultCustomerJsonToReturn = @\"{\n    \"\"resource\"\": \"\"customer\"\",\n    \"\"id\"\": \"\"customer-id\"\",\n    \"\"mode\"\": \"\"test\"\",\n    \"\"name\"\": \"\"Customer A\"\",\n    \"\"email\"\": \"\"customer@example.org\"\",\n    \"\"locale\"\": \"\"nl_NL\"\",\n    \"\"metadata\"\": null,\n    \"\"createdAt\"\": \"\"2018-04-06T13:23:21.0Z\"\"\n}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/InvoiceClientTests.cs",
    "content": "﻿using System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class InvoiceClientTests : BaseClientTests\n{\n    [Fact]\n    public async Task GetInvoiceAsync_DefaultBehaviour_ResponseIsParsed()\n    {\n        // Given\n        const string invoiceId = \"inv_xBEbP9rvAq\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}invoices/{invoiceId}\")\n            .Respond(\"application/json\", defaultInvoice);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using InvoiceClient invoiceClient = new InvoiceClient(\"access_abcde\", httpClient);\n\n        // When\n        var result = await invoiceClient.GetInvoiceAsync(invoiceId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        result.ShouldNotBeNull();\n        result.Resource.ShouldBe(\"invoice\");\n        result.Id.ShouldBe(invoiceId);\n        result.Reference.ShouldBe(\"2016.10000\");\n        result.VatNumber.ShouldBe(\"NL001234567B01\");\n        result.Status.ShouldBe(\"open\");\n    }\n\n    [Theory]\n    [InlineData(null, null, null, null, \"\")]\n    [InlineData(\"my-reference\", null, null, null, \"?reference=my-reference\")]\n    [InlineData(\"my-reference\", 2023, null, null, \"?reference=my-reference&year=2023\")]\n    [InlineData(\"my-reference\", 2023, \"abcde\", null, \"?reference=my-reference&year=2023&from=abcde\")]\n    [InlineData(\"my-reference\", 2023, \"abcde\", 10, \"?reference=my-reference&year=2023&from=abcde&limit=10\")]\n    public async Task GetInvoiceListAsync_WithVariousParameters_QueryStringMatchesExpectedValue(\n        string? reference, int? year, string? from, int? limit, string expectedQueryString) {\n        // Given: We retrieve a list of customers\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}invoices{expectedQueryString}\")\n            .Respond(\"application/json\", defaultInvoiceList);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using InvoiceClient invoiceClient = new InvoiceClient(\"access_abcde\", httpClient);\n\n        // When: We send the request\n        var result = await invoiceClient.GetInvoiceListAsync(\n            reference, year, from, limit);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        result.ShouldNotBeNull();\n    }\n\n    private const string defaultInvoice = @\"{\n    \"\"resource\"\": \"\"invoice\"\",\n    \"\"id\"\": \"\"inv_xBEbP9rvAq\"\",\n    \"\"reference\"\": \"\"2016.10000\"\",\n    \"\"vatNumber\"\": \"\"NL001234567B01\"\",\n    \"\"status\"\": \"\"open\"\",\n    \"\"issuedAt\"\": \"\"2016-08-31\"\",\n    \"\"dueAt\"\": \"\"2016-09-14\"\",\n    \"\"netAmount\"\": {\n        \"\"value\"\": \"\"45.00\"\",\n        \"\"currency\"\": \"\"EUR\"\"\n    },\n    \"\"vatAmount\"\": {\n        \"\"value\"\": \"\"9.45\"\",\n        \"\"currency\"\": \"\"EUR\"\"\n    },\n    \"\"grossAmount\"\": {\n        \"\"value\"\": \"\"54.45\"\",\n        \"\"currency\"\": \"\"EUR\"\"\n    },\n    \"\"lines\"\":[\n        {\n            \"\"period\"\": \"\"2016-09\"\",\n            \"\"description\"\": \"\"iDEAL transactiekosten\"\",\n            \"\"count\"\": 100,\n            \"\"vatPercentage\"\": 21,\n            \"\"amount\"\": {\n                \"\"value\"\": \"\"45.00\"\",\n                \"\"currency\"\": \"\"EUR\"\"\n            }\n        }\n    ],\n    \"\"_links\"\": {\n        \"\"self\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/invoices/inv_xBEbP9rvAq\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"pdf\"\": {\n             \"\"href\"\": \"\"https://www.mollie.com/merchant/download/invoice/xBEbP9rvAq/2ab44d60b35b1d06090bba955fa2c602\"\",\n             \"\"type\"\": \"\"application/pdf\"\",\n             \"\"expiresAt\"\": \"\"2018-11-09T14:10:36+00:00\"\"\n        }\n    }\n}\";\n\n    private const string defaultInvoiceList = @\"{\n    \"\"count\"\": 5,\n    \"\"_embedded\"\": {\n        \"\"invoices\"\": [\n            {\n                \"\"resource\"\": \"\"invoice\"\",\n                \"\"id\"\": \"\"inv_xBEbP9rvAq\"\",\n                \"\"reference\"\": \"\"2016.10000\"\",\n                \"\"vatNumber\"\": \"\"NL001234567B01\"\",\n                \"\"status\"\": \"\"open\"\",\n                \"\"issuedAt\"\": \"\"2016-08-31\"\",\n                \"\"dueAt\"\": \"\"2016-09-14\"\",\n                \"\"netAmount\"\": {\n                    \"\"value\"\": \"\"45.00\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"vatAmount\"\": {\n                    \"\"value\"\": \"\"9.45\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"grossAmount\"\": {\n                    \"\"value\"\": \"\"54.45\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                },\n                \"\"lines\"\":[\n                    {\n                        \"\"period\"\": \"\"2016-09\"\",\n                        \"\"description\"\": \"\"iDEAL transactiekosten\"\",\n                        \"\"count\"\": 100,\n                        \"\"vatPercentage\"\": 21,\n                        \"\"amount\"\": {\n                            \"\"value\"\": \"\"45.00\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }\n                    }\n                ],\n                \"\"_links\"\": {\n                    \"\"self\"\": {\n                         \"\"href\"\": \"\"https://api.mollie.com/v2/invoices/inv_xBEbP9rvAq\"\",\n                         \"\"type\"\": \"\"application/hal+json\"\"\n                    },\n                    \"\"pdf\"\": {\n                         \"\"href\"\": \"\"https://www.mollie.com/merchant/download/invoice/xBEbP9rvAq/2ab44d60b35955fa2c602\"\",\n                         \"\"type\"\": \"\"application/pdf\"\",\n                         \"\"expiresAt\"\": \"\"2018-11-09T14:10:36+00:00\"\"\n                    }\n                }\n            },\n            { },\n            { },\n            { },\n            { }\n        ]\n    },\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/invoices?limit=5\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"previous\"\": null,\n        \"\"next\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/invoices?from=inv_xBEbP9rvAq&limit=5\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/invoices-api/list-invoices\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/MandateClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.Mandate.Request;\nusing Mollie.Api.Models.Payment;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class MandateClientTests : BaseClientTests {\n        [Theory]\n        [InlineData(\"customers/customer-id/mandates/mandate-id\", false)]\n        [InlineData(\"customers/customer-id/mandates/mandate-id?testmode=true\", true)]\n        public async Task GetMandateAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string expectedUrl, bool testModeParameter) {\n            // Given: We retrieve a mandate\n            const string customerId = \"customer-id\";\n            const string mandateId = \"mandate-id\";\n\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}{expectedUrl}\")\n                .Respond(\"application/json\", DefaultMandateJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            MandateClient mandateClient = new MandateClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await mandateClient.GetMandateAsync(customerId, mandateId, testModeParameter);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(null, null, false, \"\")]\n        [InlineData(\"from\", null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, false, \"?from=from&limit=50\")]\n        [InlineData(null, null, true, \"?testmode=true\")]\n        public async Task GetMandateListAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(\n            string? from, int? limit, bool testmode, string expectedQueryString) {\n            // Given: We retrieve a list of mandates\n            const string customerId = \"customer-id\";\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}customers/{customerId}/mandates{expectedQueryString}\")\n                .Respond(\"application/json\", DefaultMandateJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            MandateClient mandateClient = new MandateClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await mandateClient.GetMandateListAsync(customerId, from, limit, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Fact]\n        public async Task RevokeMandate_TestmodeIsTrue_RequestContainsTestmodeModel() {\n            // Given: We make a request to retrieve a payment with embedded refunds\n            const string customerId = \"customer-id\";\n            const string mandateId = \"mandate-id\";\n            string expectedContent = \"\\\"testmode\\\":true\";\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Delete,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}customers/{customerId}/mandates/{mandateId}\",\n                DefaultMandateJsonToReturn,\n                expectedContent);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            MandateClient mandateClient = new MandateClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await mandateClient.RevokeMandate(customerId, mandateId, true);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetMandateAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? mandateId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            MandateClient mandateClient = new MandateClient(\"api-key\", httpClient);\n\n            // When: We send the request\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>\n#pragma warning disable CS8604 // Possible null reference argument.\n                await mandateClient.GetMandateAsync(mandateId, \"mandate-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetMandateAsync_NoMandateIdIsGiven_ArgumentExceptionIsThrown(string? mandateId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            MandateClient mandateClient = new MandateClient(\"api-key\", httpClient);\n\n            // When: We send the request\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>\n#pragma warning disable CS8604 // Possible null reference argument.\n                await mandateClient.GetMandateAsync(\"customer-id\", mandateId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'mandateId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetMandateListAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? mandateId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            MandateClient mandateClient = new MandateClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await mandateClient.GetMandateListAsync(mandateId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateMandateAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? mandateId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            MandateClient mandateClient = new MandateClient(\"api-key\", httpClient);\n            MandateRequest mandateRequest = new MandateRequest {\n                ConsumerName = \"John Doe\",\n                Method = PaymentMethod.DirectDebit\n            };\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await mandateClient.CreateMandateAsync(mandateId, mandateRequest));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        private const string DefaultMandateJsonToReturn = @\"{\n    \"\"resource\"\": \"\"mandate\"\",\n    \"\"id\"\": \"\"mdt_h3gAaD5zP\"\",\n    \"\"mode\"\": \"\"test\"\",\n    \"\"status\"\": \"\"valid\"\",\n    \"\"method\"\": \"\"directdebit\"\",\n    \"\"details\"\": {\n        \"\"consumerName\"\": \"\"John Doe\"\",\n        \"\"consumerAccount\"\": \"\"NL55INGB0000000000\"\",\n        \"\"consumerBic\"\": \"\"INGBNL2A\"\"\n    },\n    \"\"mandateReference\"\": \"\"YOUR-COMPANY-MD1380\"\",\n    \"\"signatureDate\"\": \"\"2018-05-07\"\",\n    \"\"createdAt\"\": \"\"2018-05-07T10:49:08+00:00\"\"\n}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/OnboardingClientTests.cs",
    "content": "﻿using Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Onboarding.Request;\nusing Mollie.Api.Models.Onboarding.Response;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class OnboardingClientTests : BaseClientTests {\n        public const string defaultName = \"Mollie API Unit Test\";\n        public const string defaultStatus = OnboardingStatus.Completed;\n        public const string canReceivePayments = \"true\";\n        public const string canReceiveSettlements = \"true\";\n        public const string defaultStreetAndNumber = \"My address\";\n\n        public static readonly string defaultOnboardingStatusJsonResponse = $@\"{{\n    \"\"resource\"\": \"\"onboarding\"\",\n    \"\"name\"\": \"\"{defaultName}\"\",\n    \"\"signedUpAt\"\": \"\"2018-12-20T10:49:08+00:00\"\",\n    \"\"status\"\": \"\"{defaultStatus}\"\",\n    \"\"canReceivePayments\"\": {canReceivePayments},\n    \"\"canReceiveSettlements\"\": {canReceiveSettlements},\n}}\";\n\n        [Fact]\n        public async Task GetOnboardingStatusAsync_DefaultBehaviour_ResponseIsParsed() {\n            // Given: We request the onboarding status\n            string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}onboarding/me\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, defaultOnboardingStatusJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OnboardingClient onboardingClient = new OnboardingClient(\"api-key\", httpClient);\n\n            // When: We make the request\n            OnboardingStatusResponse onboardingResponse = await onboardingClient.GetOnboardingStatusAsync();\n\n            // Then: Response should be parsed\n            mockHttp.VerifyNoOutstandingExpectation();\n            onboardingResponse.ShouldNotBeNull();\n            onboardingResponse.Name.ShouldBe(defaultName);\n            onboardingResponse.Status.ShouldBe(defaultStatus);\n            onboardingResponse.CanReceivePayments.ToString().ToLower().ShouldBe(canReceivePayments);\n            onboardingResponse.CanReceiveSettlements.ToString().ToLower().ShouldBe(canReceiveSettlements);\n        }\n\n        [Fact]\n        public async Task SubmitOnboardingDataAsync_DefaultBehaviour_RequestIsParsed() {\n            // Given: We submit an onboarding status request\n            string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}onboarding/me\";\n            SubmitOnboardingDataRequest submitOnboardingDataRequest = new SubmitOnboardingDataRequest() {\n                Organization = new OnboardingOrganizationRequest() {\n                    Name = defaultName,\n                    Address = new AddressObject() {\n                        StreetAndNumber = defaultStreetAndNumber\n                    }\n                },\n                Profile = new OnboardingProfileRequest() {\n                    Name = defaultName\n                }\n            };\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, expectedUrl, string.Empty);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OnboardingClient onboardingClient = new OnboardingClient(\"api-key\", httpClient);\n\n            // When: We make the request\n            await onboardingClient.SubmitOnboardingDataAsync(submitOnboardingDataRequest);\n\n            // Then: There should be no outstanding requests\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/OrderClientTests.cs",
    "content": "﻿using System;\n#pragma warning disable CS0618\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Order;\nusing Mollie.Api.Models.Payment;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Order.Request.ManageOrderLines;\nusing Mollie.Api.Models.Order.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nusing SortDirection = Mollie.Api.Models.SortDirection;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class OrderClientTests : BaseClientTests {\n        [Fact]\n        public async Task GetOrderAsync_NoEmbedParameters_QueryStringIsEmpty() {\n            // Given: We make a request to retrieve a order without wanting any extra data\n            const string orderId = \"abcde\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}\", defaultOrderJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.GetOrderAsync(orderId);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task GetOrderAsync_SingleEmbedParameters_QueryStringContainsEmbedParameter() {\n            // Given: We make a request to retrieve a order with a single embed parameter\n            const string orderId = \"abcde\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}?embed=payments\", defaultOrderJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.GetOrderAsync(orderId, embedPayments: true);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task GetOrderAsync_MultipleEmbedParameters_QueryStringContainsMultipleParameters() {\n            // Given: We make a request to retrieve a order with a single embed parameter\n            const string orderId = \"abcde\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}?embed=payments,refunds,shipments\", defaultOrderJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.GetOrderAsync(orderId, embedPayments: true, embedRefunds: true, embedShipments: true);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task GetOrderAsync_WithTestModeParameter_QueryStringContainsTestModeParameter() {\n            // Given: We make a request to retrieve a order with a single embed parameter\n            const string orderId = \"abcde\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}?testmode=true\", defaultOrderJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.GetOrderAsync(orderId, testmode: true);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Theory]\n        [InlineData(null, null, null, false, null, \"\")]\n        [InlineData(\"from\", null, null, false, null, \"?from=from\")]\n        [InlineData(\"from\", 50, null, false, null, \"?from=from&limit=50\")]\n        [InlineData(null, null, \"profile-id\", false, null, \"?profileId=profile-id\")]\n        [InlineData(null, null, \"profile-id\", true, null, \"?profileId=profile-id&testmode=true\")]\n        [InlineData(null, null, \"profile-id\", true, SortDirection.Desc, \"?profileId=profile-id&testmode=true&sort=desc\")]\n        [InlineData(null, null, \"profile-id\", true, SortDirection.Asc, \"?profileId=profile-id&testmode=true&sort=asc\")]\n        public async Task GetOrderListAsync_QueryParameterOptions_CorrectParametersAreAdded(\n            string? from,\n            int? limit,\n            string? profileId,\n            bool testmode,\n            SortDirection? sortDirection,\n            string expectedQueryString) {\n            // Given: We make a request to retrieve the list of orders\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders{expectedQueryString}\", defaultOrderListJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.GetOrderListAsync(from, limit, profileId, testmode, sortDirection);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Fact]\n        public async Task CreateOrderAsync_SinglePaymentMethod_RequestIsSerializedInExpectedFormat() {\n            // Given: we create a order with a single payment method\n            OrderRequest orderRequest = CreateOrderRequestWithOnlyRequiredFields();\n            orderRequest.Method = PaymentMethod.Ideal;\n            string expectedPaymentMethodJson = $\"\\\"method\\\":[\\\"{PaymentMethod.Ideal}\";\n            const string jsonResponse = defaultOrderJsonResponse;\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders\", jsonResponse, expectedPaymentMethodJson);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new (\"abcde\", httpClient);\n\n            // When: We send the request\n            OrderResponse orderResponse = await orderClient.CreateOrderAsync(orderRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            orderResponse.Method.ShouldBe(orderRequest.Method);\n        }\n\n        [Fact]\n        public async Task CreateOrderAsync_MultiplePaymentMethods_RequestIsSerializedInExpectedFormat() {\n            // Given: we create a order with a single payment method\n            OrderRequest orderRequest = CreateOrderRequestWithOnlyRequiredFields();\n            orderRequest.Methods = new List<string>() {\n                PaymentMethod.Ideal,\n                PaymentMethod.CreditCard,\n                PaymentMethod.DirectDebit\n            };\n            string expectedPaymentMethodJson = $\"\\\"method\\\":[\\\"{PaymentMethod.Ideal}\\\",\\\"{PaymentMethod.CreditCard}\\\",\\\"{PaymentMethod.DirectDebit}\\\"]\";\n            const string jsonResponse = defaultOrderJsonResponse;\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders\", jsonResponse, expectedPaymentMethodJson);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.CreateOrderAsync(orderRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task CreateOrderPaymentAsync_PaymentWithSinglePaymentMethod_RequestIsSerializedInExpectedFormat() {\n            // Given: We create a payment request with multiple payment methods\n            OrderPaymentRequest orderPaymentRequest = new OrderPaymentRequest() {\n                CustomerId = \"customer-id\",\n                Testmode = true,\n                MandateId = \"mandate-id\",\n                Methods = new List<string>() {\n                    PaymentMethod.Ideal\n                }\n            };\n            const string orderId = \"order-id\";\n            string url = $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}/payments\";\n            string expectedPaymentMethodJson = $\"\\\"method\\\":[\\\"{PaymentMethod.Ideal}\\\"]\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, url, defaultPaymentJsonResponse, expectedPaymentMethodJson);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.CreateOrderPaymentAsync(orderId, orderPaymentRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task CreateOrderPaymentAsync_PaymentWithMultiplePaymentMethods_RequestIsSerializedInExpectedFormat() {\n            // Given: We create a payment request with multiple payment methods\n            OrderPaymentRequest orderPaymentRequest = new () {\n                CustomerId = \"customer-id\",\n                Testmode = true,\n                MandateId = \"mandate-id\",\n                Methods = new List<string>() {\n                    PaymentMethod.Ideal,\n                    PaymentMethod.CreditCard,\n                    PaymentMethod.DirectDebit\n                }\n            };\n            const string orderId = \"order-id\";\n            string url = $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}/payments\";\n            string expectedPaymentMethodJson = $\"\\\"method\\\":[\\\"{PaymentMethod.Ideal}\\\",\\\"{PaymentMethod.CreditCard}\\\",\\\"{PaymentMethod.DirectDebit}\\\"]\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, url, defaultPaymentJsonResponse, expectedPaymentMethodJson);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new (\"abcde\", httpClient);\n\n            // When: We send the request\n            await orderClient.CreateOrderPaymentAsync(orderId, orderPaymentRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetOrderAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await orderClient.GetOrderAsync(orderId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateOrderAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await orderClient.UpdateOrderAsync(orderId, new OrderUpdateRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateOrderLinesAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await orderClient.UpdateOrderLinesAsync(orderId, \"order-line-id\", new OrderLineUpdateRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateOrderLinesAsync_NoOrderLineIdIsGiven_ArgumentExceptionIsThrown(string? orderLineId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await orderClient.UpdateOrderLinesAsync(\"order-id\", orderLineId, new OrderLineUpdateRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderLineId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task ManageOrderLinesAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"api-key\", httpClient);\n            ManageOrderLinesRequest request = new ManageOrderLinesRequest {\n                Operations = new List<ManageOrderLinesOperation> {\n                    new ManageOrderLinesUpdateOperation {\n                        Data = new ManageOrderLinesUpdateOperationData\n                        {\n                            Id = \"id\"\n                        }\n                    }\n                }\n            };\n\n            // When: We send the request\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>\n#pragma warning disable CS8604 // Possible null reference argument.\n                await orderClient.ManageOrderLinesAsync(orderId, request));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CancelOrderAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await orderClient.CancelOrderAsync(orderId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateOrderPaymentAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            OrderClient orderClient = new OrderClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await orderClient.CreateOrderPaymentAsync(orderId, new OrderPaymentRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        private OrderRequest CreateOrderRequestWithOnlyRequiredFields() {\n            return new OrderRequest() {\n                Amount = new Amount(Currency.EUR, \"100.00\"),\n                OrderNumber = \"16738\",\n                Lines = new List<OrderLineRequest>() {\n                    new OrderLineRequest() {\n                        Name = \"A box of chocolates\",\n                        Quantity = 1,\n                        UnitPrice = new Amount(Currency.EUR, \"100.00\"),\n                        TotalAmount = new Amount(Currency.EUR, \"100.00\"),\n                        VatRate = \"21.00\",\n                        VatAmount = new Amount(Currency.EUR, \"17.36\")\n                    }\n                },\n                BillingAddress = new OrderAddressDetails() {\n                    GivenName = \"John\",\n                    FamilyName = \"Smit\",\n                    Email = \"johnsmit@gmail.com\",\n                    City = \"Rotterdam\",\n                    Country = \"NL\",\n                    PostalCode = \"0000AA\",\n                    Region = \"Zuid-Holland\",\n                    StreetAndNumber = \"Coolsingel 1\"\n                },\n                RedirectUrl = \"http://www.google.nl\",\n                Locale = Locale.nl_NL\n            };\n        }\n\n        private const string defaultOrderListJsonResponse = @\"{\n            \"\"count\"\": 5,\n            \"\"_embedded\"\": {\n                \"\"orders\"\": []\n            },\n            \"\"_links\"\": {\n            \"\"self\"\": {\n              \"\"href\"\": \"\"...\"\",\n              \"\"type\"\": \"\"application/hal+json\"\"\n            },\n            \"\"previous\"\": null,\n            \"\"next\"\": {\n              \"\"href\"\": \"\"https://api.mollie.com/v2/orders?from=ord_vsKJpSsabw&limit=5\"\",\n              \"\"type\"\": \"\"application/hal+json\"\"\n            },\n            \"\"documentation\"\": {\n              \"\"href\"\": \"\"...\"\",\n              \"\"type\"\": \"\"text/html\"\"\n            }\n          }\n        }\";\n\n        private const string defaultOrderJsonResponse = @\"{\n            \"\"resource\"\": \"\"order\"\",\n            \"\"id\"\": \"\"ord_kEn1PlbGa\"\",\n            \"\"profileId\"\": \"\"pfl_URR55HPMGx\"\",\n            \"\"method\"\": \"\"ideal\"\",\n            \"\"status\"\": \"\"created\"\",\n            \"\"isCancelable\"\": false,\n            \"\"orderId\"\": \"\"ord_pbjz8x\"\",\n            \"\"createdAt\"\": \"\"2023-08-02T09:29:56.0Z\"\",\n            \"\"locale\"\": \"\"nl_NL\"\",\n            \"\"orderNumber\"\": \"\"34629\"\",\n            \"\"lines\"\": [],\n            \"\"amount\"\": {\n                \"\"value\"\": \"\"1027.99\"\",\n                \"\"currency\"\": \"\"EUR\"\"\n            },\n            \"\"_links\"\": {\n                \"\"self\"\": {\n                  \"\"href\"\": \"\"...\"\",\n                  \"\"type\"\": \"\"application/hal+json\"\"\n                },\n                \"\"checkout\"\": {\n                  \"\"href\"\": \"\"https://www.mollie.com/checkout/select-method/7UhSN1zuXS\"\",\n                  \"\"type\"\": \"\"text/html\"\"\n                },\n                \"\"dashboard\"\": {\n                  \"\"href\"\": \"\"https://www.mollie.com/dashboard/org_123456789/orders/ord_pbjz8x\"\",\n                  \"\"type\"\": \"\"text/html\"\"\n                },\n                \"\"documentation\"\": {\n                  \"\"href\"\": \"\"...\"\",\n                  \"\"type\"\": \"\"text/html\"\"\n                }\n              }\n        }\";\n\n        private const string defaultPaymentJsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"status\"\": \"\"open\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"sequenceType\"\": \"\"oneoff\"\",\n            \"\"redirectUrl\"\":\"\"http://www.mollie.com\"\"}\";\n\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/OrganizationClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.Organization;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class OrganizationClientTests : BaseClientTests\n{\n    [Fact]\n    public async Task GetCurrentOrganizationAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}organizations/me\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultOrganizationResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var organizationsClient = new OrganizationClient(\"access_abcde\", httpClient);\n\n        // Act\n        var result = await organizationsClient.GetCurrentOrganizationAsync();\n\n        // Assert\n        AssertDefaultOrganization(result);\n    }\n\n    [Fact]\n    public async Task GetOrganizationAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        const string organizationId = \"organization-id\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}organizations/{organizationId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultOrganizationResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var organizationsClient = new OrganizationClient(\"access_abcde\", httpClient);\n\n        // Act\n        var result = await organizationsClient.GetOrganizationAsync(organizationId);\n\n        // Assert\n        AssertDefaultOrganization(result);\n    }\n\n    [Fact]\n    public async Task GetOrganizationsListAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}organizations\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultOrganizationListResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var organizationsClient = new OrganizationClient(\"access_abcde\", httpClient);\n\n        // Act\n        var result = await organizationsClient.GetOrganizationListAsync();\n\n        // Assert\n        result.Count.ShouldBe(2);\n        result.Items.Count.ShouldBe(2);\n    }\n\n    [Fact]\n    public async Task GetPartnerStatusAsync_ResponseIsDeserializedInExpectedFormat() {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}organizations/me/partner\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultGetPartnerStatusResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var organizationsClient = new OrganizationClient(\"access_abcde\", httpClient);\n\n        // Act\n        var result = await organizationsClient.GetPartnerStatusAsync();\n\n        // Assert\n        result.ShouldNotBeNull();\n        result.Resource.ShouldBe(\"partner\");\n        result.PartnerType.ShouldBe(PartnerTypes.SignupLink);\n        result.PartnerContractSignedAt.ShouldBe(new DateTimeOffset(2024, 3, 20, 13, 59, 02, TimeSpan.FromHours(0)));\n        result.PartnerContractExpiresAt.ShouldBe(new DateTimeOffset(2024, 4, 19, 23, 59, 59, TimeSpan.FromHours(0)));\n        result.Links.ShouldNotBeNull();\n        result.Links.Self.Href.ShouldBe(\"https://docs.mollie.com/reference/get-partner-status\");\n        result.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/get-partner-status\");\n        result.Links.Signuplink!.Href.ShouldBe(\"https://www.mollie.com/dashboard/signup/exampleCode\");\n    }\n\n    private void AssertDefaultOrganization(OrganizationResponse response)\n    {\n        response.Resource.ShouldBe(\"organization\");\n        response.Id.ShouldBe(\"org_12345678\");\n        response.Name.ShouldBe(\"Mollie B.V.\");\n        response.Email.ShouldBe(\"info@mollie.com\");\n        response.Address.StreetAndNumber.ShouldBe(\"Keizersgracht 126\");\n        response.Address.PostalCode.ShouldBe(\"1015 CW\");\n        response.Address.City.ShouldBe(\"Amsterdam\");\n        response.Address.Country.ShouldBe(\"NL\");\n        response.RegistrationNumber.ShouldBe(\"30204462\");\n        response.VatNumber.ShouldBe(\"NL815839091B01\");\n        response.VatRegulation.ShouldBeNullOrEmpty();\n        response.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/organizations/me\");\n        response.Links.Chargebacks!.Href.ShouldBe(\"https://api.mollie.com/v2/chargebacks\");\n        response.Links.Customers!.Href.ShouldBe(\"https://api.mollie.com/v2/customers\");\n        response.Links.Invoices!.Href.ShouldBe(\"https://api.mollie.com/v2/invoices\");\n        response.Links.Payments!.Href.ShouldBe(\"https://api.mollie.com/v2/payments\");\n        response.Links.Profiles!.Href.ShouldBe(\"https://api.mollie.com/v2/profiles\");\n        response.Links.Refunds!.Href.ShouldBe(\"https://api.mollie.com/v2/refunds\");\n        response.Links.Settlements!.Href.ShouldBe(\"https://api.mollie.com/v2/settlements\");\n        response.Links.Dashboard.Href.ShouldBe(\"https://mollie.com/dashboard/org_12345678\");\n        response.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/organizations-api/current-organization\");\n    }\n\n    private const string defaultOrganizationListResponse = @$\"\n{{\n    \"\"count\"\": 2,\n    \"\"_embedded\"\": {{\n        \"\"organizations\"\": [\n            {defaultOrganizationResponse},\n            {defaultOrganizationResponse}\n        ]\n    }}\n}}\";\n\n    private const string defaultGetPartnerStatusResponse = @\"{\n  \"\"resource\"\": \"\"partner\"\",\n  \"\"partnerType\"\": \"\"signuplink\"\",\n  \"\"partnerContractSignedAt\"\": \"\"2024-03-20T13:59:02+00:00\"\",\n  \"\"partnerContractExpiresAt\"\": \"\"2024-04-19T23:59:59+00:00\"\",\n  \"\"_links\"\": {\n    \"\"self\"\": {\n      \"\"href\"\": \"\"https://docs.mollie.com/reference/get-partner-status\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    },\n    \"\"signuplink\"\": {\n      \"\"href\"\": \"\"https://www.mollie.com/dashboard/signup/exampleCode\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    },\n    \"\"documentation\"\": {\n      \"\"href\"\": \"\"https://docs.mollie.com/reference/get-partner-status\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    }\n  }\n}\";\n\n    private const string defaultOrganizationResponse = @\"{\n     \"\"resource\"\": \"\"organization\"\",\n     \"\"id\"\": \"\"org_12345678\"\",\n     \"\"name\"\": \"\"Mollie B.V.\"\",\n     \"\"email\"\": \"\"info@mollie.com\"\",\n     \"\"locale\"\": \"\"nl_NL\"\",\n     \"\"address\"\": {\n        \"\"streetAndNumber\"\" : \"\"Keizersgracht 126\"\",\n        \"\"postalCode\"\": \"\"1015 CW\"\",\n         \"\"city\"\": \"\"Amsterdam\"\",\n         \"\"country\"\": \"\"NL\"\"\n     },\n     \"\"registrationNumber\"\": \"\"30204462\"\",\n     \"\"vatNumber\"\": \"\"NL815839091B01\"\",\n     \"\"_links\"\": {\n         \"\"self\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/organizations/me\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"chargebacks\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/chargebacks\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"customers\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/customers\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"invoices\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/invoices\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"payments\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/payments\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"profiles\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/profiles\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"refunds\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/refunds\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"settlements\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/settlements\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"dashboard\"\": {\n             \"\"href\"\": \"\"https://mollie.com/dashboard/org_12345678\"\",\n             \"\"type\"\": \"\"text/html\"\"\n         },\n         \"\"documentation\"\": {\n             \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/organizations-api/current-organization\"\",\n             \"\"type\"\": \"\"text/html\"\"\n         }\n     }\n }\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/PaymentClientTests.cs",
    "content": "﻿using System;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing RichardSzalay.MockHttp;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Models.Payment.Request.PaymentSpecificParameters;\nusing Mollie.Api.Models.Payment.Response.PaymentSpecificParameters;\nusing Xunit;\n\nusing SortDirection = Mollie.Api.Models.SortDirection;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class PaymentClientTests : BaseClientTests {\n    [Fact]\n    public async Task CreatePaymentAsync_WithCustomIdempotencyKey_CustomIdemPotencyKeyIsSent()\n    {\n        // Given: We create a payment request with only the required parameters\n        var paymentRequest = new PaymentRequest()\n        {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = \"http://www.mollie.com\"\n        };\n        const string customIdempotencyKey1 = \"my-idempotency-key-1\";\n        const string customIdempotencyKey2 = \"my-idempotency-key-2\";\n        const string jsonToReturnInMockResponse = defaultPaymentJsonResponse;\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}*\")\n            .WithHeaders(\"Idempotency-Key\", customIdempotencyKey1)\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        mockHttp.Expect(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}*\")\n            .WithHeaders(\"Idempotency-Key\", customIdempotencyKey2)\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // Act\n        using (paymentClient.WithIdempotencyKey(customIdempotencyKey1))\n        {\n            await paymentClient.CreatePaymentAsync(paymentRequest);\n        }\n        using (paymentClient.WithIdempotencyKey(customIdempotencyKey2))\n        {\n            await paymentClient.CreatePaymentAsync(paymentRequest);\n        }\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task CreatePaymentAsync_PaymentWithRequiredParameters_ResponseIsDeserializedInExpectedFormat() {\n        // Given: we create a payment request with only the required parameters\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = \"http://www.mollie.com\"\n        };\n        const string jsonToReturnInMockResponse = defaultPaymentJsonResponse;\n\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}*\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        PaymentResponse paymentResponse = await paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        AssertPaymentIsEqual(paymentRequest, paymentResponse);\n        paymentResponse.AuthorizedAt!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 19, 13, 28, 37), DateTimeKind.Utc));\n        paymentResponse.CreatedAt!.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 20, 13, 13, 37), DateTimeKind.Utc));\n        paymentResponse.PaidAt!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 21, 13, 28, 37), DateTimeKind.Utc));\n        paymentResponse.CanceledAt!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 22, 13, 28, 37), DateTimeKind.Utc));\n        paymentResponse.ExpiredAt!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 23, 13, 28, 37), DateTimeKind.Utc));\n        paymentResponse.FailedAt!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 24, 13, 28, 37), DateTimeKind.Utc));\n        paymentResponse.CaptureBefore!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 25, 13, 28, 37), DateTimeKind.Utc));\n        paymentResponse.AmountRefunded!.Value.ShouldBe(\"10.00\");\n        paymentResponse.AmountRefunded.Currency.ShouldBe(Currency.EUR);\n        paymentResponse.AmountRemaining!.Value.ShouldBe(\"90.00\");\n        paymentResponse.AmountRemaining.Currency.ShouldBe(Currency.EUR);\n        paymentResponse.AmountChargedBack!.Value.ShouldBe(\"10.00\");\n        paymentResponse.AmountChargedBack.Currency.ShouldBe(Currency.EUR);\n        paymentResponse.CancelUrl.ShouldBe(\"https://webshop.example.org/order/12345/cancel\");\n        paymentResponse.CountryCode.ShouldBe(\"NL\");\n        paymentResponse.SettlementId.ShouldBe(\"stl_jDk30akdN\");\n        paymentResponse.SubscriptionId.ShouldBe(\"sub_rVKGtNd6s3\");\n        paymentResponse.ApplicationFee.ShouldNotBeNull();\n        paymentResponse.ApplicationFee!.Amount.Value.ShouldBe(\"1.00\");\n        paymentResponse.ApplicationFee.Amount.Currency.ShouldBe(Currency.EUR);\n        paymentResponse.ApplicationFee.Description.ShouldBe(\"description\");\n    }\n\n    [Fact]\n    public async Task CreatePaymentAsync_PaymentWithSinglePaymentMethod_RequestIsSerializedInExpectedFormat() {\n        // Given: We create a payment request with a single payment method\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = \"http://www.mollie.com\",\n            Method = PaymentMethod.Ideal\n        };\n        string expectedPaymentMethodJson = $\"\\\"method\\\":[\\\"{PaymentMethod.Ideal}\\\"\";\n        const string jsonResponse = @\"{\n                \"\"amount\"\":{\n                    \"\"currency\"\":\"\"EUR\"\",\n                    \"\"value\"\":\"\"100.00\"\"\n                },\n                \"\"description\"\":\"\"Description\"\",\n                \"\"method\"\":\"\"ideal\"\",\n                \"\"redirectUrl\"\":\"\"http://www.mollie.com\"\"}\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\", jsonResponse, expectedPaymentMethodJson);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        PaymentResponse paymentResponse = await paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        AssertPaymentIsEqual(paymentRequest, paymentResponse);\n        paymentResponse.Method.ShouldBe(paymentRequest.Method);\n    }\n\n    [Fact]\n    public async Task CreatePaymentAsync_PaymentWithMultiplePaymentMethods_RequestIsSerializedInExpectedFormat() {\n        // Given: We create a payment request with multiple payment methods\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = \"http://www.mollie.com\",\n            Methods = new List<string>() {\n                PaymentMethod.Ideal,\n                PaymentMethod.CreditCard,\n                PaymentMethod.DirectDebit\n            }\n        };\n        string expectedPaymentMethodJson = $\"\\\"method\\\":[\\\"{PaymentMethod.Ideal}\\\",\\\"{PaymentMethod.CreditCard}\\\",\\\"{PaymentMethod.DirectDebit}\\\"]\";\n        const string expectedJsonResponse = @\"{\n                \"\"amount\"\":{\n                    \"\"currency\"\":\"\"EUR\"\",\n                    \"\"value\"\":\"\"100.00\"\"\n                },\n                \"\"description\"\":\"\"Description\"\",\n                \"\"method\"\": null,\n                \"\"redirectUrl\"\":\"\"http://www.mollie.com\"\"}\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\", expectedJsonResponse, expectedPaymentMethodJson);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        PaymentResponse paymentResponse = await paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        AssertPaymentIsEqual(paymentRequest, paymentResponse);\n        paymentResponse.Method.ShouldBeNull();\n    }\n\n    [Fact]\n    public async Task CreatePayment_WithRoutingInformation_RequestIsSerializedInExpectedFormat() {\n        // Given: We create a payment request with the routing request\n        PaymentRoutingRequest routingRequest = new PaymentRoutingRequest {\n            Amount = new Amount(\"EUR\", 100),\n            Destination = new RoutingDestination {\n                Type = \"organization\",\n                OrganizationId = \"organization-id\"\n            },\n            ReleaseDate = new DateTime(2022, 1, 14)\n        };\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = \"http://www.mollie.com\",\n            Routings = new List<PaymentRoutingRequest> {\n                routingRequest\n            }\n        };\n        string expectedRoutingInformation = $\"\\\"routing\\\":[{{\\\"amount\\\":{{\\\"currency\\\":\\\"EUR\\\",\\\"value\\\":\\\"100.00\\\"}},\\\"destination\\\":{{\\\"type\\\":\\\"organization\\\",\\\"organizationId\\\":\\\"organization-id\\\"}},\\\"releaseDate\\\":\\\"2022-01-14\\\"}}]}}\";\n        const string expectedJsonResponse = @\"{\n                \"\"resource\"\": \"\"payment\"\",\n                \"\"id\"\": \"\"tr_5B8cwPMGnU6qLbRvo7qEZo\"\",\n                \"\"mode\"\": \"\"live\"\",\n                \"\"createdAt\"\": \"\"2024-03-20T09:13:37.0Z\"\",\n                \"\"status\"\": \"\"open\"\",\n                \"\"webhookUrl\"\": \"\"https://webshop.example.org/payments/webhook/\"\",\n                \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n                \"\"sequenceType\"\": \"\"oneoff\"\",\n                \"\"amount\"\":{\n                    \"\"currency\"\":\"\"EUR\"\",\n                    \"\"value\"\":\"\"100.00\"\"\n                },\n                \"\"description\"\":\"\"Description\"\",\n                \"\"method\"\": null,\n                \"\"redirectUrl\"\":\"\"http://www.mollie.com\"\",\n                \"\"routing\"\": [{\n                        \"\"resource\"\": \"\"route\"\",\n                        \"\"id\"\": \"\"crt_tntKsr6tffuVdqnEvhq3J\"\",\n                        \"\"amount\"\": {\n                            \"\"currency\"\": \"\"EUR\"\",\n                            \"\"value\"\": \"\"100.00\"\"\n                        },\n                        \"\"destination\"\": {\n                            \"\"type\"\": \"\"organization\"\",\n                            \"\"organizationId\"\": \"\"organization-id\"\"\n                        },\n                        \"\"releaseDate\"\": \"\"2022-01-14\"\"\n                    }\n                ]}\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\", expectedJsonResponse, expectedRoutingInformation);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        PaymentResponse paymentResponse = await paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        AssertPaymentIsEqual(paymentRequest, paymentResponse);\n        paymentResponse.Method.ShouldBeNull();\n    }\n\n    [Fact]\n    public async Task CreatePaymentAsync_IncludeQrCode_QueryStringContainsIncludeQrCodeParameter() {\n        // Given: We make a request to create a payment and include the QR code\n        PaymentRequest paymentRequest = new PaymentRequest() {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            RedirectUrl = \"http://www.mollie.com\",\n            Method = PaymentMethod.Ideal\n        };\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments?include=details.qrCode\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.CreatePaymentAsync(paymentRequest, includeQrCode: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_NoIncludeParameters_RequestIsDeserializedInExpectedFormat() {\n        // Given: We make a request to retrieve a payment without wanting any extra data\n        const string paymentId = \"tr_WDqYK6vllg\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var payment = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        payment.Resource.ShouldBe(\"payment\");\n        payment.Id.ShouldBe(paymentId);\n        payment.Amount.Value.ShouldBe(\"100.00\");\n        payment.Amount.Currency.ShouldBe(Currency.EUR);\n        payment.Description.ShouldBe(\"Description\");\n        payment.Method.ShouldBeNull();\n        payment.Status.ShouldBe(PaymentStatus.Open);\n        payment.IsCancelable.ShouldBe(false);\n        payment.Locale.ShouldBe(\"nl_NL\");\n        payment.ExpiresAt!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 20, 13, 28, 37), DateTimeKind.Utc));\n        payment.ProfileId.ShouldBe(\"pfl_QkEhN94Ba\");\n        payment.SequenceType.ShouldBe(SequenceType.OneOff);\n        payment.RedirectUrl.ShouldBe(\"https://webshop.example.org/order/12345/\");\n        payment.WebhookUrl.ShouldBe(\"https://webshop.example.org/payments/webhook/\");\n        payment.Links.ShouldNotBeNull();\n        payment.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\");\n        payment.Links.Self.Type.ShouldBe(\"application/hal+json\");\n        payment.Links.Checkout!.Href.ShouldBe(\"https://www.mollie.com/payscreen/select-method/WDqYK6vllg\");\n        payment.Links.Checkout.Type.ShouldBe(\"text/html\");\n        payment.Links.Dashboard.Href.ShouldBe(\"https://www.mollie.com/dashboard/org_12345678/payments/tr_WDqYK6vllg\");\n        payment.Links.Dashboard.Type.ShouldBe(\"text/html\");\n        payment.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/payments-api/get-payment\");\n        payment.Links.Documentation.Type.ShouldBe(\"text/html\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_ForBankTransferPayment_DetailsAreDeserialized()\n    {\n        // Given: We make a request to retrieve a bank transfer payment\n        const string paymentId = \"tr_WDqYK6vllg\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"banktransfer\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"bankName\"\": \"\"bank-name\"\",\n                \"\"bankAccount\"\": \"\"bank-account\"\",\n                \"\"bankBic\"\": \"\"bank-bic\"\",\n                \"\"transferReference\"\": \"\"transfer-reference\"\",\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"consumerBic\"\": \"\"consumer-bic\"\",\n                \"\"billingEmail\"\": \"\"billing-email\"\",\n                \"\"qrCode\"\":{\n                    \"\"height\"\": 5,\n                    \"\"width\"\": 10,\n                    \"\"src\"\": \"\"https://www.mollie.com/qr/12345678.png\"\"\n                }\n            },\n            \"\"_links\"\": {\n                \"\"status\"\": {\n                    \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\"\",\n                    \"\"type\"\": \"\"application/hal+json\"\"\n                },\n                \"\"payOnline\"\": {\n                    \"\"href\"\": \"\"https://www.mollie.com/payscreen/select-method/WDqYK6vllg\"\",\n                    \"\"type\"\": \"\"text/html\"\"\n                }\n            }\n        }\";\n\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var payment = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        payment.ShouldBeOfType<BankTransferPaymentResponse>();\n        var bankTransferPayment = payment as BankTransferPaymentResponse;\n        bankTransferPayment!.Details!.BankName.ShouldBe(\"bank-name\");\n        bankTransferPayment.Details.BankAccount.ShouldBe(\"bank-account\");\n        bankTransferPayment.Details.BankBic.ShouldBe(\"bank-bic\");\n        bankTransferPayment.Details.TransferReference.ShouldBe(\"transfer-reference\");\n        bankTransferPayment.Details.ConsumerName.ShouldBe(\"consumer-name\");\n        bankTransferPayment.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        bankTransferPayment.Details.ConsumerBic.ShouldBe(\"consumer-bic\");\n        bankTransferPayment.Details.BillingEmail.ShouldBe(\"billing-email\");\n        bankTransferPayment.Details.QrCode.ShouldNotBeNull();\n        bankTransferPayment.Details.QrCode.Height.ShouldBe(5);\n        bankTransferPayment.Details.QrCode.Width.ShouldBe(10);\n        bankTransferPayment.Details.QrCode.Src.ShouldBe(\"https://www.mollie.com/qr/12345678.png\");\n        bankTransferPayment.Links.ShouldNotBeNull();\n        bankTransferPayment.Links.Status.ShouldNotBeNull();\n        bankTransferPayment.Links.Status.Href.ShouldBe(\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\");\n        bankTransferPayment.Links.Status.Type.ShouldBe(\"application/hal+json\");\n        bankTransferPayment.Links.PayOnline.ShouldNotBeNull();\n        bankTransferPayment.Links.PayOnline.Href.ShouldBe(\"https://www.mollie.com/payscreen/select-method/WDqYK6vllg\");\n        bankTransferPayment.Links.PayOnline.Type.ShouldBe(\"text/html\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_ForBanContactPayment_DetailsAreDeserialized()\n    {\n        // Given: We make a request to retrieve a bancontact payment\n        const string paymentId = \"tr_WDqYK6vllg\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"bancontact\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"cardNumber\"\": \"\"1234567890123456\"\",\n                \"\"cardFingerprint\"\": \"\"fingerprint\"\",\n                \"\"qrCode\"\":{\n                    \"\"height\"\": 5,\n                    \"\"width\"\": 10,\n                    \"\"src\"\": \"\"https://www.mollie.com/qr/12345678.png\"\"\n                },\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"consumerBic\"\": \"\"consumer-bic\"\",\n                \"\"failureReason\"\": \"\"failure-reason\"\"\n            }\n        }\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        result.ShouldBeOfType<BancontactPaymentResponse>();\n        var banContactPayment = result as BancontactPaymentResponse;\n        banContactPayment!.Details!.CardNumber.ShouldBe(\"1234567890123456\");\n        banContactPayment.Details.QrCode.ShouldNotBeNull();\n        banContactPayment.Details.QrCode.Height.ShouldBe(5);\n        banContactPayment.Details.QrCode.Width.ShouldBe(10);\n        banContactPayment.Details.QrCode.Src.ShouldBe(\"https://www.mollie.com/qr/12345678.png\");\n        banContactPayment.Details.ConsumerName.ShouldBe(\"consumer-name\");\n        banContactPayment.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        banContactPayment.Details.ConsumerBic.ShouldBe(\"consumer-bic\");\n        banContactPayment.Details.FailureReason.ShouldBe(\"failure-reason\");\n    }\n\n    [Fact]\n    public async Task CreatePaymentAsync_SepaDirectDebit_RequestAndResponseAreConvertedToExpectedJsonFormat()\n    {\n        // Given we create a creditcard specific payment request\n        var paymentRequest = new SepaDirectDebitRequest()\n        {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            Method = PaymentMethod.Ideal,\n            RedirectUrl = \"http://www.mollie.com\",\n            WebhookUrl = \"http://www.mollie.com/webhook\",\n            ConsumerName = \"consumer-name\",\n            ConsumerAccount = \"consumer-account\"\n        };\n        const string jsonRequest = @\"{\n  \"\"consumerName\"\": \"\"consumer-name\"\",\n  \"\"consumerAccount\"\": \"\"consumer-account\"\",\n  \"\"amount\"\": {\n    \"\"currency\"\": \"\"EUR\"\",\n    \"\"value\"\": \"\"100.00\"\"\n  },\n  \"\"description\"\": \"\"Description\"\",\n  \"\"redirectUrl\"\": \"\"http://www.mollie.com\"\",\n  \"\"webhookUrl\"\": \"\"http://www.mollie.com/webhook\"\",\n  \"\"method\"\": [\n    \"\"ideal\"\"\n  ]\n}\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"directdebit\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"consumerBic\"\": \"\"consumer-bic\"\",\n                \"\"transferReference\"\": \"\"transfer-reference\"\",\n                \"\"bankReasonCode\"\": \"\"bank-reason-code\"\",\n                \"\"bankReason\"\": \"\"bank-reason\"\",\n                \"\"batchReference\"\": \"\"batch-reference\"\",\n                \"\"mandateReference\"\": \"\"mandate-reference\"\",\n                \"\"creditorIdentifier\"\": \"\"creditor-identifier\"\",\n                \"\"dueDate\"\": \"\"2018-03-20\"\",\n                \"\"signatureDate\"\": \"\"2018-03-20\"\",\n                \"\"endToEndIdentifier\"\": \"\"end-to-end-identifier\"\",\n                \"\"batchReference\"\": \"\"batch-reference\"\",\n                \"\"fileReference\"\": \"\"file-reference\"\"\n            }\n        }\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\", jsonResponse, jsonRequest);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        var specificPaymentResponse = result as SepaDirectDebitResponse;\n        specificPaymentResponse.ShouldNotBeNull();\n        specificPaymentResponse.Details!.ConsumerName.ShouldBe(\"consumer-name\");\n        specificPaymentResponse.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        specificPaymentResponse.Details.ConsumerBic.ShouldBe(\"consumer-bic\");\n        specificPaymentResponse.Details.TransferReference.ShouldBe(\"transfer-reference\");\n        specificPaymentResponse.Details.BankReasonCode.ShouldBe(\"bank-reason-code\");\n        specificPaymentResponse.Details.BankReason.ShouldBe(\"bank-reason\");\n        specificPaymentResponse.Details.BatchReference.ShouldBe(\"batch-reference\");\n        specificPaymentResponse.Details.MandateReference.ShouldBe(\"mandate-reference\");\n        specificPaymentResponse.Details.CreditorIdentifier.ShouldBe(\"creditor-identifier\");\n        specificPaymentResponse.Details.DueDate.ShouldBe(\"2018-03-20\");\n        specificPaymentResponse.Details.SignatureDate.ShouldBe(\"2018-03-20\");\n        specificPaymentResponse.Details.EndToEndIdentifier.ShouldBe(\"end-to-end-identifier\");\n        specificPaymentResponse.Details.BatchReference.ShouldBe(\"batch-reference\");\n        specificPaymentResponse.Details.FileReference.ShouldBe(\"file-reference\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_ForPayPalPayment_DetailsAreDeserialized()\n    {\n        // Given: We make a request to retrieve a paypal payment\n        const string paymentId = \"tr_WDqYK6vllg\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"paypal\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"paypalReference\"\": \"\"paypal-ref\"\",\n                \"\"paypalPayerId\"\": \"\"paypal-payer-id\"\",\n                \"\"sellerProtection\"\": \"\"Eligible\"\",\n                \"\"shippingAddress\"\": {\n                    \"\"streetAndNumber\"\": \"\"street-and-number\"\",\n                    \"\"streetAdditional\"\": \"\"street-additional\"\",\n                    \"\"postalCode\"\": \"\"postal-code\"\",\n                    \"\"city\"\": \"\"city\"\",\n                    \"\"region\"\": \"\"region\"\",\n                    \"\"country\"\": \"\"country\"\"\n                },\n                \"\"paypalFee\"\": {\n                    \"\"currency\"\": \"\"EUR\"\",\n                    \"\"value\"\": \"\"100.00\"\"\n                }\n            }\n        }\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        result.ShouldBeOfType<PayPalPaymentResponse>();\n        var payPalPayment = result as PayPalPaymentResponse;\n        payPalPayment!.Details!.ConsumerName.ShouldBe(\"consumer-name\");\n        payPalPayment.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        payPalPayment.Details.PayPalReference.ShouldBe(\"paypal-ref\");\n        payPalPayment.Details.PaypalPayerId.ShouldBe(\"paypal-payer-id\");\n        payPalPayment.Details.SellerProtection.ShouldBe(\"Eligible\");\n        payPalPayment.Details.ShippingAddress.ShouldNotBeNull();\n        payPalPayment.Details.ShippingAddress.StreetAndNumber.ShouldBe(\"street-and-number\");\n        payPalPayment.Details.ShippingAddress.StreetAdditional.ShouldBe(\"street-additional\");\n        payPalPayment.Details.ShippingAddress.PostalCode.ShouldBe(\"postal-code\");\n        payPalPayment.Details.ShippingAddress.City.ShouldBe(\"city\");\n        payPalPayment.Details.ShippingAddress.Region.ShouldBe(\"region\");\n        payPalPayment.Details.ShippingAddress.Country.ShouldBe(\"country\");\n        payPalPayment.Details.PaypalFee.ShouldNotBeNull();\n        payPalPayment.Details.PaypalFee.Currency.ShouldBe(\"EUR\");\n        payPalPayment.Details.PaypalFee.Value.ShouldBe(\"100.00\");\n    }\n\n    [Fact]\n    public async Task CreatePaymentAsync_CreditcardPayment_RequestAndResponseAreConvertedToExpectedJsonFormat()\n    {\n        // Given we create a creditcard specific payment request\n        var paymentRequest = new CreditCardPaymentRequest()\n        {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            Method = PaymentMethod.Ideal,\n            RedirectUrl = \"http://www.mollie.com\",\n            WebhookUrl = \"http://www.mollie.com/webhook\",\n            BillingAddress = new PaymentAddressDetails()\n            {\n                City = \"Amsterdam\",\n                Country = \"NL\",\n                PostalCode = \"1000AA\",\n                Region = \"Noord-Holland\",\n                StreetAndNumber = \"Keizersgracht 313\"\n            },\n            ShippingAddress = new PaymentAddressDetails()\n            {\n                City = \"Amsterdam\",\n                Country = \"NL\",\n                PostalCode = \"1000AA\",\n                Region = \"Noord-Holland\",\n                StreetAndNumber = \"Keizersgracht 313\"\n            },\n            CardToken = \"card-token\"\n        };\n        const string jsonRequest = @\"{\n  \"\"cardToken\"\": \"\"card-token\"\",\n  \"\"amount\"\": {\n    \"\"currency\"\": \"\"EUR\"\",\n    \"\"value\"\": \"\"100.00\"\"\n  },\n  \"\"description\"\": \"\"Description\"\",\n  \"\"redirectUrl\"\": \"\"http://www.mollie.com\"\",\n  \"\"webhookUrl\"\": \"\"http://www.mollie.com/webhook\"\",\n  \"\"billingAddress\"\": {\n    \"\"streetAndNumber\"\": \"\"Keizersgracht 313\"\",\n    \"\"postalCode\"\": \"\"1000AA\"\",\n    \"\"city\"\": \"\"Amsterdam\"\",\n    \"\"region\"\": \"\"Noord-Holland\"\",\n    \"\"country\"\": \"\"NL\"\"\n  },\n  \"\"shippingAddress\"\": {\n    \"\"streetAndNumber\"\": \"\"Keizersgracht 313\"\",\n    \"\"postalCode\"\": \"\"1000AA\"\",\n    \"\"city\"\": \"\"Amsterdam\"\",\n    \"\"region\"\": \"\"Noord-Holland\"\",\n    \"\"country\"\": \"\"NL\"\"\n  },\n  \"\"method\"\": [\n    \"\"ideal\"\"\n  ]\n}\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"status\"\": \"\"open\"\",\n            \"\"webhookUrl\"\": \"\"https://webshop.example.org/payments/webhook/\"\",\n            \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n            \"\"sequenceType\"\": \"\"oneoff\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"creditcard\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"cardNumber\"\": \"\"1234567890123456\"\",\n                \"\"cardHolder\"\": \"\"John Doe\"\",\n                \"\"cardFingerprint\"\": \"\"fingerprint\"\",\n                \"\"cardAudience\"\": \"\"audience\"\",\n                \"\"cardLabel\"\": \"\"American Express\"\",\n                \"\"cardCountryCode\"\": \"\"NL\"\",\n                \"\"cardSecurity\"\": \"\"security\"\",\n                \"\"feeRegion\"\": \"\"american-express\"\",\n                \"\"failureReason\"\": \"\"unknown_reason\"\",\n                \"\"failureMessage\"\": \"\"faulure-message\"\",\n                \"\"wallet\"\": \"\"applepay\"\"\n            }\n        }\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\", jsonResponse, jsonRequest);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        PaymentClient paymentClient = new(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        var specificPaymentResponse = result as CreditCardPaymentResponse;\n        specificPaymentResponse.ShouldNotBeNull();\n        specificPaymentResponse.Details!.CardNumber.ShouldBe(\"1234567890123456\");\n        specificPaymentResponse.Details.CardHolder.ShouldBe(\"John Doe\");\n        specificPaymentResponse.Details.CardFingerprint.ShouldBe(\"fingerprint\");\n        specificPaymentResponse.Details.CardAudience.ShouldBe(\"audience\");\n        specificPaymentResponse.Details.CardLabel.ShouldBe(\"American Express\");\n        specificPaymentResponse.Details.CardCountryCode.ShouldBe(\"NL\");\n        specificPaymentResponse.Details.CardSecurity.ShouldBe(\"security\");\n        specificPaymentResponse.Details.FeeRegion.ShouldBe(\"american-express\");\n        specificPaymentResponse.Details.FailureReason.ShouldBe(\"unknown_reason\");\n        specificPaymentResponse.Details.FailureMessage.ShouldBe(\"faulure-message\");\n        specificPaymentResponse.Details.Wallet.ShouldBe(\"applepay\");\n    }\n\n    [Fact]\n    public async Task CreatePaymentAsync_GiftcardPayment_RequestAndResponseAreConvertedToExpectedJsonFormat()\n    {\n        // Given we create a giftcard specific payment request\n        var paymentRequest = new GiftcardPaymentRequest()\n        {\n            Amount = new Amount(Currency.EUR, \"100.00\"),\n            Description = \"Description\",\n            Method = PaymentMethod.GiftCard,\n            RedirectUrl = \"http://www.mollie.com\",\n            WebhookUrl = \"http://www.mollie.com/webhook\",\n            Issuer = \"issuer\",\n            VoucherNumber = \"voucher-number\",\n            VoucherPin = \"voucher-pin\"\n        };\n        const string jsonRequest = @\"{\n  \"\"voucherNumber\"\" : \"\"voucher-number\"\",\n  \"\"voucherPin\"\" : \"\"voucher-pin\"\",\n  \"\"amount\"\" : {\n    \"\"currency\"\" : \"\"EUR\"\",\n    \"\"value\"\" : \"\"100.00\"\"\n  },\n  \"\"description\"\" : \"\"Description\"\",\n  \"\"redirectUrl\"\" : \"\"http://www.mollie.com\"\",\n  \"\"webhookUrl\"\" : \"\"http://www.mollie.com/webhook\"\",\n  \"\"method\"\" : [ \"\"giftcard\"\" ],\n  \"\"issuer\"\" : \"\"issuer\"\"\n}\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"giftcard\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"voucherNumber\"\": \"\"voucher-number\"\",\n                \"\"giftcards\"\": [\n                    {\n                        \"\"issuer\"\": \"\"issuer\"\",\n                        \"\"amount\"\": {\n                            \"\"currency\"\": \"\"EUR\"\",\n                            \"\"value\"\": \"\"100.00\"\"\n                        },\n                        \"\"voucherNumber\"\": \"\"voucher-number\"\"\n                    }\n                ],\n                \"\"remainderAmount\"\": {\n                    \"\"currency\"\": \"\"EUR\"\",\n                    \"\"value\"\": \"\"100.00\"\"\n                },\n                \"\"remainderMethod\"\": \"\"ideal\"\"\n            }\n        }\";\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Post,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments\",\n            jsonResponse,\n            jsonRequest);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.CreatePaymentAsync(paymentRequest);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        var specificPaymentResponse = result as GiftcardPaymentResponse;\n        specificPaymentResponse.ShouldNotBeNull();\n        specificPaymentResponse!.Details!.VoucherNumber.ShouldBe(\"voucher-number\");\n        specificPaymentResponse.Details.Giftcards.ShouldNotBeNull();\n        specificPaymentResponse.Details.Giftcards.Count.ShouldBe(1);\n        specificPaymentResponse.Details.Giftcards[0].Issuer.ShouldBe(\"issuer\");\n        specificPaymentResponse.Details.Giftcards[0].Amount.ShouldNotBeNull();\n        specificPaymentResponse.Details.Giftcards[0].Amount.Currency.ShouldBe(\"EUR\");\n        specificPaymentResponse.Details.Giftcards[0].Amount.Value.ShouldBe(\"100.00\");\n        specificPaymentResponse.Details.Giftcards[0].VoucherNumber.ShouldBe(\"voucher-number\");\n        specificPaymentResponse.Details.RemainderAmount.ShouldNotBeNull();\n        specificPaymentResponse.Details.RemainderAmount.Currency.ShouldBe(\"EUR\");\n        specificPaymentResponse.Details.RemainderAmount.Value.ShouldBe(\"100.00\");\n        specificPaymentResponse.Details.RemainderMethod.ShouldBe(\"ideal\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_ForBelfiusPayment_DetailsAreDeserialized()\n    {\n        // Given: We make a request to retrieve a belfius payment\n        const string paymentId = \"tr_WDqYK6vllg\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"belfius\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"consumerBic\"\": \"\"consumer-bic\"\"\n            }\n        }\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        result.ShouldBeOfType<BelfiusPaymentResponse>();\n        var belfiusPayment = result as BelfiusPaymentResponse;\n        belfiusPayment!.Details!.ConsumerName.ShouldBe(\"consumer-name\");\n        belfiusPayment.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        belfiusPayment.Details.ConsumerBic.ShouldBe(\"consumer-bic\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_ForIngHomePay_DetailsAreDeserialized()\n    {\n        // Given: We make a request to retrieve a ing home pay payment\n        const string paymentId = \"tr_WDqYK6vllg\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"inghomepay\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"consumerBic\"\": \"\"consumer-bic\"\"\n            }\n        }\";\n\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        result.ShouldBeOfType<IngHomePayPaymentResponse>();\n        var ingHomePayPayment = result as IngHomePayPaymentResponse;\n        ingHomePayPayment!.Details!.ConsumerName.ShouldBe(\"consumer-name\");\n        ingHomePayPayment.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        ingHomePayPayment.Details.ConsumerBic.ShouldBe(\"consumer-bic\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_ForKbcPayment_DetailsAreDeserialized()\n    {\n        // Given: We make a request to retrieve a ing home pay payment\n        const string paymentId = \"tr_WDqYK6vllg\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"kbc\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"consumerBic\"\": \"\"consumer-bic\"\"\n            }\n        }\";\n\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        result.ShouldBeOfType<KbcPaymentResponse>();\n        var kbcPayment = result as KbcPaymentResponse;\n        kbcPayment!.Details!.ConsumerName.ShouldBe(\"consumer-name\");\n        kbcPayment.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        kbcPayment.Details.ConsumerBic.ShouldBe(\"consumer-bic\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_ForSofortPayment_DetailsAreDeserialized()\n    {\n        // Given: We make a request to retrieve a ing home pay payment\n        const string paymentId = \"tr_WDqYK6vllg\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"mode\"\": \"\"test\"\",\n            \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"sofort\"\",\n            \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n            \"\"details\"\": {\n                \"\"consumerName\"\": \"\"consumer-name\"\",\n                \"\"consumerAccount\"\": \"\"consumer-account\"\",\n                \"\"consumerBic\"\": \"\"consumer-bic\"\"\n            }\n        }\";\n\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.GetPaymentAsync(paymentId);\n\n        // Then\n        result.ShouldBeOfType<SofortPaymentResponse>();\n        var sofortPayment = result as SofortPaymentResponse;\n        sofortPayment!.Details!.ConsumerName.ShouldBe(\"consumer-name\");\n        sofortPayment.Details.ConsumerAccount.ShouldBe(\"consumer-account\");\n        sofortPayment.Details.ConsumerBic.ShouldBe(\"consumer-bic\");\n    }\n\n    [Theory]\n    [InlineData(\"\")]\n    [InlineData(\" \")]\n    [InlineData(null)]\n    public async Task GetPaymentAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n        var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await paymentClient.GetPaymentAsync(paymentId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n        // Then\n        exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_IncludeQrCode_QueryStringContainsIncludeQrCodeParameter() {\n        // Given: We make a request to retrieve a payment without wanting any extra data\n        const string paymentId = \"abcde\";\n        const string jsonResponse = @\"{\n            \"\"resource\"\": \"\"payment\"\",\n            \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n            \"\"amount\"\":{\n                \"\"currency\"\":\"\"EUR\"\",\n                \"\"value\"\":\"\"100.00\"\"\n            },\n            \"\"description\"\":\"\"Description\"\",\n            \"\"method\"\": \"\"ideal\"\",\n            \"\"details\"\": {\n                \"\"qrCode\"\":{\n                    \"\"height\"\": 5,\n                    \"\"width\"\": 5,\n                    \"\"src\"\": \"\"https://www.mollie.com/qr/12345678.png\"\"\n                }\n            }\n        }\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}?include=details.qrCode\",\n            jsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        var result = await paymentClient.GetPaymentAsync(paymentId, includeQrCode: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        result.ShouldBeOfType<IdealPaymentResponse>();\n        var paymentResponse = result as IdealPaymentResponse;\n        paymentResponse!.Details!.QrCode.ShouldNotBeNull();\n        paymentResponse.Details.QrCode.Height.ShouldBe(5);\n        paymentResponse.Details.QrCode.Width.ShouldBe(5);\n        paymentResponse.Details.QrCode.Src.ShouldBe(\"https://www.mollie.com/qr/12345678.png\");\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_IncludeRemainderDetails_QueryStringContainsIncludeRemainderDetailsParameter() {\n        // Given: We make a request to retrieve a payment without wanting any extra data\n        const string paymentId = \"abcde\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}?include=details.remainderDetails\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.GetPaymentAsync(paymentId, includeRemainderDetails: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task GetPaymentListAsync_IncludeQrCode_QueryStringContainsIncludeQrCodeParameter() {\n        // Given: We make a request to retrieve a payment without wanting any extra data\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments?include=details.qrCode\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.GetPaymentListAsync(includeQrCode: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_EmbedRefunds_QueryStringContainsEmbedRefundsParameter()\n    {\n        // Given: We make a request to retrieve a payment with embedded refunds\n        const string paymentId = \"abcde\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}?embed=refunds\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.GetPaymentAsync(paymentId, embedRefunds: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task GetPaymentListAsync_EmbedRefunds_QueryStringContainsEmbedRefundsParameter()\n    {\n        // Given: We make a request to retrieve a payment with embedded refunds\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments?embed=refunds\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.GetPaymentListAsync(embedRefunds: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task GetPaymentAsync_EmbedChargebacks_QueryStringContainsEmbedChargebacksParameter()\n    {\n        // Given: We make a request to retrieve a payment with embedded refunds\n        const string paymentId = \"abcde\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}?embed=chargebacks\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.GetPaymentAsync(paymentId, embedChargebacks: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task GetPaymentListAsync_EmbedChargebacks_QueryStringContainsEmbedChargebacksParameter()\n    {\n        // Given: We make a request to retrieve a payment with embedded refunds\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments?embed=chargebacks\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.GetPaymentListAsync(embedChargebacks: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Theory]\n    [InlineData(null, \"\")]\n    [InlineData(SortDirection.Desc, \"?sort=desc\")]\n    [InlineData(SortDirection.Asc, \"?sort=asc\")]\n    public async Task GetPaymentListAsync_AddSortDirection_QueryStringContainsSortDirection(SortDirection? sortDirection, string expectedQueryString)\n    {\n        // Given: We make a request to retrieve a payment with embedded refunds\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments{expectedQueryString}\", defaultPaymentJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.GetPaymentListAsync(embedChargebacks: true, sort: sortDirection);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task DeletePaymentAsync_TestmodeIsTrue_RequestContainsTestmodeModel() {\n        // Given: We make a request to retrieve a payment with embedded refunds\n        const string paymentId = \"payment-id\";\n        string expectedContent = \"\\\"testmode\\\":true\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Delete, $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}\", defaultPaymentJsonResponse, expectedContent);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.CancelPaymentAsync(paymentId, true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Theory]\n    [InlineData(\"\")]\n    [InlineData(\" \")]\n    [InlineData(null)]\n    public async Task ReleasePaymentAuthorizationAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n        var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await paymentClient.ReleasePaymentAuthorization(paymentId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n        // Then\n        exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n    }\n\n    [Fact]\n    public async Task ReleasePaymentAuthorizationAsync_WithTestModeParameter_QueryStringContainsTestModeParameter() {\n        // Given: We make a request to retrieve a payment with a the test mode parameter\n        const string paymentId = \"abcde\";\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Post,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}/release-authorization?testmode=true\",\n            string.Empty);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await paymentClient.ReleasePaymentAuthorization(paymentId, testmode: true);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Theory]\n    [InlineData(\"\")]\n    [InlineData(\" \")]\n    [InlineData(null)]\n    public async Task DeletePaymentAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n        var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await paymentClient.CancelPaymentAsync(paymentId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n        // Then\n        exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n    }\n\n    [Theory]\n    [InlineData(\"\")]\n    [InlineData(\" \")]\n    [InlineData(null)]\n    public async Task UpdatePaymentAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var paymentClient = new PaymentClient(\"abcde\", httpClient);\n\n        // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n        var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await paymentClient.UpdatePaymentAsync(paymentId, new PaymentUpdateRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n        // Then\n        exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n    }\n\n    private void AssertPaymentIsEqual(PaymentRequest paymentRequest, PaymentResponse paymentResponse) {\n        paymentResponse.Amount.Value.ShouldBe(paymentRequest.Amount.Value);\n        paymentResponse.Amount.Currency.ShouldBe(paymentRequest.Amount.Currency);\n        paymentResponse.Description.ShouldBe(paymentRequest.Description);\n        if (paymentRequest.Routings != null) {\n            paymentResponse.Routings!.Count.ShouldBe(paymentRequest.Routings.Count);\n            for (int i = 0; i < paymentRequest.Routings.Count; i++) {\n                var paymentRequestRouting = paymentRequest.Routings[i];\n                var paymentResponseRouting = paymentResponse.Routings[i];\n                paymentResponseRouting.Amount.ShouldBe(paymentRequestRouting.Amount);\n                paymentResponseRouting.Destination.Type.ShouldBe(paymentRequestRouting.Destination.Type);\n                paymentResponseRouting.Destination.OrganizationId.ShouldBe(paymentRequestRouting.Destination.OrganizationId);\n                paymentResponseRouting.ReleaseDate.ShouldBe(paymentRequestRouting.ReleaseDate);\n            }\n        }\n    }\n\n    private const string defaultPaymentJsonResponse = @\"\n{\n    \"\"resource\"\": \"\"payment\"\",\n    \"\"id\"\": \"\"tr_WDqYK6vllg\"\",\n    \"\"mode\"\": \"\"test\"\",\n    \"\"createdAt\"\": \"\"2018-03-20T13:13:37+00:00\"\",\n    \"\"amount\"\":{\n        \"\"currency\"\":\"\"EUR\"\",\n        \"\"value\"\":\"\"100.00\"\"\n    },\n    \"\"description\"\":\"\"Description\"\",\n    \"\"method\"\": null,\n    \"\"metadata\"\": {\n        \"\"order_id\"\": \"\"12345\"\"\n    },\n    \"\"status\"\": \"\"open\"\",\n    \"\"isCancelable\"\": false,\n    \"\"locale\"\": \"\"nl_NL\"\",\n    \"\"restrictPaymentMethodsToCountry\"\": \"\"NL\"\",\n    \"\"expiresAt\"\": \"\"2018-03-20T13:28:37+00:00\"\",\n    \"\"details\"\": null,\n    \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n    \"\"sequenceType\"\": \"\"oneoff\"\",\n    \"\"redirectUrl\"\": \"\"https://webshop.example.org/order/12345/\"\",\n    \"\"webhookUrl\"\": \"\"https://webshop.example.org/payments/webhook/\"\",\n    \"\"authorizedAt\"\": \"\"2018-03-19T13:28:37+00:00\"\",\n    \"\"paidAt\"\": \"\"2018-03-21T13:28:37+00:00\"\",\n    \"\"canceledAt\"\": \"\"2018-03-22T13:28:37+00:00\"\",\n    \"\"expiredAt\"\": \"\"2018-03-23T13:28:37+00:00\"\",\n    \"\"failedAt\"\": \"\"2018-03-24T13:28:37+00:00\"\",\n    \"\"captureBefore\"\": \"\"2018-03-25T13:28:37+00:00\"\",\n    \"\"amountRefunded\"\": {\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"10.00\"\"\n    },\n    \"\"amountRemaining\"\": {\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"90.00\"\"\n    },\n    \"\"amountChargedBack\"\": {\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"10.00\"\"\n    },\n    \"\"cancelUrl\"\": \"\"https://webshop.example.org/order/12345/cancel\"\",\n    \"\"countryCode\"\": \"\"NL\"\",\n    \"\"settlementId\"\": \"\"stl_jDk30akdN\"\",\n    \"\"subscriptionId\"\": \"\"sub_rVKGtNd6s3\"\",\n    \"\"applicationFee\"\": {\n        \"\"amount\"\": {\n            \"\"currency\"\": \"\"EUR\"\",\n            \"\"value\"\": \"\"1.00\"\"\n        },\n        \"\"description\"\": \"\"description\"\"\n    },\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"checkout\"\": {\n            \"\"href\"\": \"\"https://www.mollie.com/payscreen/select-method/WDqYK6vllg\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"dashboard\"\": {\n            \"\"href\"\": \"\"https://www.mollie.com/dashboard/org_12345678/payments/tr_WDqYK6vllg\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/payments-api/get-payment\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/PaymentLinkClientTests.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.PaymentLink.Request;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nusing SortDirection = Mollie.Api.Models.SortDirection;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class PaymentLinkClientTests : BaseClientTests {\n        private const decimal DefaultPaymentAmount = 50;\n        private const string DefaultPaymentLinkId = \"pl_4Y0eZitmBnQ6IDoMqZQKh\";\n        private const string DefaultDescription = \"A car\";\n        private const string DefaultWebhookUrl = \"https://www.mollie.com\";\n\n        [Fact]\n        public async Task CreatePaymentLinkAsync_PaymentLinkWithRequiredParameters_ResponseIsDeserializedInExpectedFormat() {\n            // Given: we create a payment link request with only the required parameters\n            PaymentLinkRequest paymentLinkRequest = new() {\n                Description = \"Test\",\n                Amount = new Amount(Currency.EUR, 50),\n                WebhookUrl = \"https://www.mollie.com\",\n                RedirectUrl = \"https://www.mollie.com\",\n                ExpiresAt = DateTime.Now.AddDays(1)\n            };\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}*\")\n                .Respond(\"application/json\", _defaultPaymentLinkJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentLinkClient paymentLinkClient = new PaymentLinkClient(\"api-key\", httpClient);\n\n            // When: We send the request\n            PaymentLinkResponse response = await paymentLinkClient.CreatePaymentLinkAsync(paymentLinkRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            VerifyPaymentLinkResponse(response);\n        }\n\n        [Fact]\n        public async Task GetPaymentLinkAsync_ResponseIsDeserializedInExpectedFormat() {\n            // Given: we retrieve a payment link\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}*\")\n                .Respond(\"application/json\", _defaultPaymentLinkJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentLinkClient paymentLinkClient = new PaymentLinkClient(\"api-key\", httpClient);\n\n            // When: We send the request\n            PaymentLinkResponse response = await paymentLinkClient.GetPaymentLinkAsync(DefaultPaymentLinkId);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            VerifyPaymentLinkResponse(response);\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetPaymentLinkAsync_NoPaymentLinkIdIsGiven_ArgumentExceptionIsThrown(string? paymentLinkId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentLinkClient paymentLinkClient = new PaymentLinkClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await paymentLinkClient.GetPaymentLinkAsync(paymentLinkId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentLinkId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(false, null, \"\")]\n        [InlineData(false, \"abcde\", \"?profileId=abcde\")]\n        [InlineData(true, \"abcde\", \"?profileId=abcde\")]\n        public async Task DeletePaymentLinkAsync_QueryParameterOptions_CorrectParametersAreAdded(\n            bool testMode,\n            string? profileId,\n            string expectedQueryString) {\n            // Given: We make a request to delete a payment link\n            var expectedPartialContent = testMode ? \"\\\"testmode\\\":true\" : null;\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Delete,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}payment-links/{DefaultPaymentLinkId}{expectedQueryString}\",\n                _defaultPaymentLinkPaymentsJsonResponse,\n                expectedPartialContent);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var paymentLinkClient = new PaymentLinkClient(\"access_abcde\", httpClient);\n\n            // When: We send the request\n            await paymentLinkClient.DeletePaymentLinkAsync(DefaultPaymentLinkId, profileId, testMode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Theory]\n        [InlineData(null, null,  false, null, \"\")]\n        [InlineData(\"from\", null,  false, null, \"?from=from\")]\n        [InlineData(\"from\", 50,  false, null, \"?from=from&limit=50\")]\n        [InlineData(null, null,  true, null, \"?testmode=true\")]\n        [InlineData(null, null,  true, SortDirection.Desc, \"?testmode=true&sort=desc\")]\n        [InlineData(null, null,  true, SortDirection.Asc, \"?testmode=true&sort=asc\")]\n        public async Task GetPaymentLinkPaymentListAsync_QueryParameterOptions_CorrectParametersAreAdded(\n            string? from,\n            int? limit,\n            bool testmode,\n            SortDirection? sortDirection,\n            string expectedQueryString) {\n            // Given: We make a request to retrieve the list of payment links\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Get,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}payment-links/{DefaultPaymentLinkId}/payments{expectedQueryString}\",\n                _defaultPaymentLinkPaymentsJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var paymentLinkClient = new PaymentLinkClient(\"access_abcde\", httpClient);\n\n            // When: We send the request\n            await paymentLinkClient.GetPaymentLinkPaymentListAsync(DefaultPaymentLinkId, from, limit, testmode, sortDirection);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Fact]\n        public async Task GetPaymentLinkPaymentListAsync_ResponseIsDeserializedInExpectedFormat() {\n            // Given: We make a request to retrieve the list of payment links\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Get,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}payment-links/{DefaultPaymentLinkId}/payments\",\n                _defaultPaymentLinkPaymentsJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var paymentLinkClient = new PaymentLinkClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            ListResponse<PaymentResponse> result = await paymentLinkClient.GetPaymentLinkPaymentListAsync(DefaultPaymentLinkId);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n            result.ShouldNotBeNull();\n            result.Count.ShouldBe(1);\n            PaymentResponse payment = result.Items.Single();\n            payment.Id.ShouldBe(\"tr_7UhSN1zuXS\");\n            payment.Amount.Value.ShouldBe(DefaultPaymentAmount.ToString(CultureInfo.InvariantCulture));\n            payment.Description.ShouldBe(DefaultDescription);\n            payment.RedirectUrl.ShouldBe(DefaultRedirectUrl);\n            payment.WebhookUrl.ShouldBe(DefaultWebhookUrl);\n        }\n\n        private void VerifyPaymentLinkResponse(PaymentLinkResponse response) {\n            response.Amount!.Value.ShouldBe(DefaultPaymentAmount.ToString(CultureInfo.InvariantCulture));\n            response.Description.ShouldBe(DefaultDescription);\n            response.Id.ShouldBe(DefaultPaymentLinkId);\n            response.RedirectUrl.ShouldBe(DefaultRedirectUrl);\n            response.WebhookUrl.ShouldBe(DefaultWebhookUrl);\n        }\n\n        private readonly string _defaultPaymentLinkPaymentsJsonResponse = $@\"{{\n  \"\"count\"\": 1,\n  \"\"_embedded\"\": {{\n    \"\"payments\"\": [\n      {{\n        \"\"resource\"\": \"\"payment\"\",\n        \"\"id\"\": \"\"tr_7UhSN1zuXS\"\",\n        \"\"mode\"\": \"\"live\"\",\n        \"\"status\"\": \"\"open\"\",\n        \"\"isCancelable\"\": false,\n        \"\"amount\"\": {{\n          \"\"value\"\": \"\"{DefaultPaymentAmount.ToString(CultureInfo.InvariantCulture)}\"\",\n          \"\"currency\"\": \"\"EUR\"\"\n        }},\n        \"\"description\"\": \"\"{DefaultDescription}\"\",\n        \"\"method\"\": \"\"ideal\"\",\n        \"\"metadata\"\": null,\n        \"\"details\"\": null,\n        \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n        \"\"redirectUrl\"\": \"\"{DefaultRedirectUrl}\"\",\n        \"\"webhookUrl\"\": \"\"{DefaultWebhookUrl}\"\",\n        \"\"createdAt\"\": \"\"2024-02-12T11:58:35.0Z\"\",\n        \"\"expiresAt\"\": \"\"2024-02-12T12:13:35.0Z\"\",\n        \"\"_links\"\": {{\n          \"\"self\"\": {{\n            \"\"href\"\": \"\"...\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n          }},\n          \"\"checkout\"\": {{\n            \"\"href\"\": \"\"https://www.mollie.com/checkout/issuer/select/ideal/7UhSN1zuXS\"\",\n            \"\"type\"\": \"\"text/html\"\"\n          }},\n          \"\"dashboard\"\": {{\n            \"\"href\"\": \"\"https://www.mollie.com/dashboard/org_12345678/payments/tr_7UhSN1zuXS\"\",\n            \"\"type\"\": \"\"text/html\"\"\n          }}\n        }}\n      }}\n    ]\n  }},\n  \"\"_links\"\": {{\n    \"\"previous\"\": null,\n    \"\"next\"\": {{\n      \"\"href\"\": \"\"https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh/payments?from=tr_SDkzMggpvx&limit=5\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }}\n  }}\n}}\";\n\n        private readonly string _defaultPaymentLinkJsonResponse = @$\"{{\n    \"\"resource\"\": \"\"payment-link\"\",\n    \"\"id\"\": \"\"{DefaultPaymentLinkId}\"\",\n    \"\"mode\"\": \"\"test\"\",\n    \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n    \"\"createdAt\"\": \"\"2021-03-20T09:13:37+00:00\"\",\n    \"\"paidAt\"\": null,\n    \"\"updatedAt\"\": null,\n    \"\"expiresAt\"\": \"\"2021-06-06T11:00:00+00:00\"\",\n    \"\"amount\"\": {{\n        \"\"value\"\": \"\"{DefaultPaymentAmount.ToString(CultureInfo.InvariantCulture)}\"\",\n        \"\"currency\"\": \"\"EUR\"\"\n    }},\n    \"\"description\"\": \"\"{DefaultDescription}\"\",\n    \"\"redirectUrl\"\": \"\"{DefaultRedirectUrl}\"\",\n    \"\"webhookUrl\"\": \"\"{DefaultWebhookUrl}\"\",\n    \"\"_links\"\": {{\n        \"\"self\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payment-links/pl_4Y0eZitmBnQ6IDoMqZQKh\"\",\n            \"\"type\"\": \"\"application/json\"\"\n        }},\n        \"\"paymentLink\"\": {{\n            \"\"href\"\": \"\"https://useplink.com/payment/4Y0eZitmBnQ6IDoMqZQKh/\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }},\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/payment-links-api/create-payment-link\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }}\n}}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/PaymentMethodClientTests.cs",
    "content": "﻿using System;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class PaymentMethodClientTests : BaseClientTests {\n        private const string defaultPaymentMethodJsonResponse = @\"{\n            \"\"count\"\": 13,\n            \"\"_embedded\"\": {\n                \"\"methods\"\": [\n                    {\n                         \"\"resource\"\": \"\"method\"\",\n                         \"\"id\"\": \"\"ideal\"\",\n                         \"\"description\"\": \"\"iDEAL\"\"\n                    }\n                ]\n            }\n        }\";\n\n        [Fact]\n        public async Task GetAllPaymentMethodListAsync_NoAmountParameter_QueryStringIsEmpty() {\n            // Given: We make a request to retrieve all payment methods without any parameters\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}methods/all\", defaultPaymentMethodJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentMethodClient paymentMethodClient = new PaymentMethodClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await paymentMethodClient.GetAllPaymentMethodListAsync();\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task GetAllPaymentMethodListAsync_AmountParameterIsAdded_QueryStringContainsAmount() {\n            // Given: We make a request to retrieve all payment methods with a amount parameter\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}methods/all?amount[value]=100.00&amount[currency]=EUR\", defaultPaymentMethodJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentMethodClient paymentMethodClient = new PaymentMethodClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await paymentMethodClient.GetAllPaymentMethodListAsync(amount: new Amount(\"EUR\", 100));\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task GetAllPaymentMethodListAsync_ProfileIdParameterIsSpecified_QueryStringContainsProfileIdParameter() {\n            // Given: We make a request to retrieve all payment methods with a profile id parameter\n            var profileId = \"myProfileId\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}methods/all?profileId={profileId}\", defaultPaymentMethodJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentMethodClient paymentMethodClient = new PaymentMethodClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await paymentMethodClient.GetAllPaymentMethodListAsync(profileId: profileId);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Fact]\n        public async Task GetPaymentMethodListAsync_IncludeWalletsParameterIsSpecified_QueryStringContainsIncludeWalletsParameter() {\n            // Given: We make a request to retrieve the payment methods with a includeWallets parameter\n            var includeWalletsValue = \"includeWalletsValue\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}methods?includeWallets={includeWalletsValue}\", defaultPaymentMethodJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentMethodClient paymentMethodClient = new PaymentMethodClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await paymentMethodClient.GetPaymentMethodListAsync(includeWallets: includeWalletsValue);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetPaymentMethodAsync_NoPaymentMethodIsGiven_ArgumentExceptionIsThrown(string? paymentLinkId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            PaymentMethodClient paymentMethodClient = new PaymentMethodClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await paymentMethodClient.GetPaymentMethodAsync(paymentLinkId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentMethod' is null or empty\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/PermissionClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class PermissionClientTests : BaseClientTests\n{\n    [Fact]\n    public async Task GetPermissionAsync_WithPermissionId_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        const string permissionId = \"payments.read\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}permissions/{permissionId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultGetPermissionResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var permissionClient = new PermissionClient(\"access_abcde\", httpClient);\n\n        // Act\n        var response = await permissionClient.GetPermissionAsync(permissionId);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.Resource.ShouldBe(\"permission\");\n        response.Id.ShouldBe(\"payments.read\");\n        response.Description.ShouldBe(\"View your payments\");\n        response.Granted.ShouldBeTrue();\n        response.Links.ShouldNotBeNull();\n        response.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/permissions/payments.read\");\n        response.Links.Self.Type.ShouldBe(\"application/hal+json\");\n        response.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/permissions-api/get-permission\");\n        response.Links.Documentation.Type.ShouldBe(\"text/html\");\n    }\n\n    [Fact]\n    public async Task GetPermissionAsync_WithoutPermissionId_ThrowsArgumentException()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var permissionClient = new PermissionClient(\"access_abcde\", httpClient);\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => permissionClient.GetPermissionAsync(string.Empty));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument 'permissionId' is null or empty\");\n    }\n\n    [Fact]\n    public async Task GetPermissionListAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}permissions\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultListPermissionsResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var permissionClient = new PermissionClient(\"access_abcde\", httpClient);\n\n        // Act\n        var response = await permissionClient.GetPermissionListAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.Count.ShouldBe(2);\n        response.ShouldNotBeNull();\n        response.Items.Count.ShouldBe(2);\n        response.Items[0].Resource.ShouldBe(\"permission\");\n        response.Items[0].Id.ShouldBe(\"payments.write\");\n        response.Items[0].Description.ShouldBe(\"Create new payments\");\n        response.Items[0].Granted.ShouldBeFalse();\n        response.Items[0].Links.ShouldNotBeNull();\n        response.Items[0].Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/permissions/payments.write\");\n        response.Items[0].Links.Self.Type.ShouldBe(\"application/hal+json\");\n        response.Items[1].Resource.ShouldBe(\"permission\");\n        response.Items[1].Id.ShouldBe(\"payments.read\");\n        response.Items[1].Description.ShouldBe(\"View your payments\");\n        response.Items[1].Granted.ShouldBeTrue();\n        response.Items[1].Links.ShouldNotBeNull();\n        response.Items[1].Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/permissions/payments.read\");\n        response.Items[1].Links.Self.Type.ShouldBe(\"application/hal+json\");\n        response.Links.ShouldNotBeNull();\n        response.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/permissions\");\n        response.Links.Self.Type.ShouldBe(\"application/hal+json\");\n        response.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/permissions-api/list-permissions\");\n        response.Links.Documentation.Type.ShouldBe(\"text/html\");\n    }\n\n    private const string defaultGetPermissionResponse = @\"{\n    \"\"resource\"\": \"\"permission\"\",\n    \"\"id\"\": \"\"payments.read\"\",\n    \"\"description\"\": \"\"View your payments\"\",\n    \"\"granted\"\": true,\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/permissions/payments.read\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/permissions-api/get-permission\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n\n    private const string defaultListPermissionsResponse = @\"{\n    \"\"_embedded\"\": {\n        \"\"permissions\"\": [\n            {\n                \"\"resource\"\": \"\"permission\"\",\n                \"\"id\"\": \"\"payments.write\"\",\n                \"\"description\"\": \"\"Create new payments\"\",\n                \"\"granted\"\": false,\n                \"\"_links\"\": {\n                    \"\"self\"\": {\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/permissions/payments.write\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    }\n                }\n            },\n            {\n                \"\"resource\"\": \"\"permission\"\",\n                \"\"id\"\": \"\"payments.read\"\",\n                \"\"description\"\": \"\"View your payments\"\",\n                \"\"granted\"\": true,\n                \"\"_links\"\": {\n                    \"\"self\"\": {\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/permissions/payments.read\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    }\n                }\n            }\n       ]\n    },\n    \"\"count\"\": 2,\n    \"\"_links\"\": {\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/permissions-api/list-permissions\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/permissions\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }\n    }\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/ProfileClientTests.cs",
    "content": "﻿using System;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Profile;\nusing Mollie.Api.Models.Profile.Request;\nusing Mollie.Api.Models.Profile.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class ProfileClientTests : BaseClientTests\n{\n    [Fact]\n    public async Task CreateProfileAsync_WithRequiredParameters_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        ProfileRequest profileRequest = new() {\n            Name = \"My website name\",\n            Email = \"info@mywebsite.com\",\n            Mode = Mode.Test,\n            Phone = \"+31208202070\",\n            Website = \"https://www.mywebsite.com\",\n            Description = \"Description\",\n            CountriesOfActivity = [\"NL\"],\n            BusinessCategory = \"OTHER_MERCHANDISE\"\n        };\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Post,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles\",\n            defaultProfileJsonResponse,\n            \"\\\"mode\\\": \\\"test\\\"\");\n\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var result = await profileClient.CreateProfileAsync(profileRequest);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        AssertDefaultProfileResponse(result);\n        result.Description.ShouldBe(profileRequest.Description);\n        result.CountriesOfActivity.ShouldBe(profileRequest.CountriesOfActivity);\n    }\n\n    [Fact]\n    public async Task GetProfileAsync_WithProfileId_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        const string profileId = \"profile-id\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get,$\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/{profileId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultProfileJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var result = await profileClient.GetProfileAsync(profileId);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        AssertDefaultProfileResponse(result);\n    }\n\n    [Fact]\n    public async Task GetCurrentProfileAsync_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/me\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultProfileJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var result = await profileClient.GetCurrentProfileAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        AssertDefaultProfileResponse(result);\n    }\n\n    [Fact]\n    public async Task GetProfileListAsync_WithNoParameters_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultGetProfileListJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var result = await profileClient.GetProfileListAsync();\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        result.Count.ShouldBe(1);\n        var profile = result.Items[0];\n        profile.Resource.ShouldBe(\"profiles\");\n        profile.Id.ShouldBe(\"pfl_v9hTwCvYqw\");\n        profile.Mode.ShouldBe(Mode.Live);\n        profile.Name.ShouldBe(\"My website name\");\n        profile.Email.ShouldBe(\"info@mywebsite.com\");\n        profile.Website.ShouldBe(\"https://www.mywebsite.com\");\n        profile.Phone.ShouldBe(\"+31208202070\");\n        profile.BusinessCategory.ShouldBe(\"OTHER_MERCHANDISE\");\n        profile.Status.ShouldBe(ProfileStatus.Verified);\n        profile.Review!.Status.ShouldBe(ReviewStatus.Pending);\n        profile.CreatedAt.ShouldBe(DateTime.Parse(\"2018-03-20T09:28:37+00:00\"));\n        profile.Links.ShouldNotBeNull();\n        profile.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/profiles/pfl_v9hTwCvYqw\");\n        profile.Links.Self.Type.ShouldBe(\"application/hal+json\");\n        profile.Links.Dashboard.Href.ShouldBe(\"https://www.mollie.com/dashboard/org_123456789/settings/profiles/pfl_v9hTwCvYqw\");\n        profile.Links.Dashboard.Type.ShouldBe(\"text/html\");\n        profile.Links.Chargebacks!.Href.ShouldBe(\"https://api.mollie.com/v2/chargebacks?profileId=pfl_v9hTwCvYqw\");\n        profile.Links.Chargebacks.Type.ShouldBe(\"application/hal+json\");\n        profile.Links.Methods!.Href.ShouldBe(\"https://api.mollie.com/v2/methods?profileId=pfl_v9hTwCvYqw\");\n        profile.Links.Methods.Type.ShouldBe(\"application/hal+json\");\n        profile.Links.Payments!.Href.ShouldBe(\"https://api.mollie.com/v2/payments?profileId=pfl_v9hTwCvYqw\");\n        profile.Links.Payments.Type.ShouldBe(\"application/hal+json\");\n        profile.Links.Refunds!.Href.ShouldBe(\"https://api.mollie.com/v2/refunds?profileId=pfl_v9hTwCvYqw\");\n        profile.Links.Refunds.Type.ShouldBe(\"application/hal+json\");\n        profile.Links.CheckoutPreviewUrl!.Href.ShouldBe(\"https://www.mollie.com/payscreen/preview/pfl_v9hTwCvYqw\");\n        profile.Links.CheckoutPreviewUrl.Type.ShouldBe(\"text/html\");\n        profile.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/profiles-api/create-profile\");\n        profile.Links.Documentation.Type.ShouldBe(\"text/html\");\n    }\n\n    [Fact]\n    public async Task UpdateProfileAsync_WithRequiredParameters_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        const string profileId = \"profileId\";\n        ProfileRequest profileRequest = new ProfileRequest() {\n            Name = \"My website name\",\n            Email = \"info@mywebsite.com\",\n            Mode = Mode.Test,\n            Phone = \"+31208202070\",\n            Website = \"https://www.mywebsite.com\",\n            BusinessCategory = \"OTHER_MERCHANDISE\"\n        };\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Patch, $\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/{profileId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultProfileJsonResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var result = await profileClient.UpdateProfileAsync(profileId, profileRequest);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        AssertDefaultProfileResponse(result);\n    }\n\n    [Fact]\n    public async Task UpdateProfileAsync_WithMissingProfileIdParameter_ThrowsArgumentException()\n    {\n        // Arrange\n        const string profileId = \"\";\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n        ProfileRequest profileRequest = new ProfileRequest() {\n            Name = \"My website name\",\n            Email = \"info@mywebsite.com\",\n            Mode = Mode.Test,\n            Phone = \"+31208202070\",\n            Website = \"https://www.mywebsite.com\",\n            BusinessCategory = \"OTHER_MERCHANDISE\"\n        };\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => profileClient.UpdateProfileAsync(profileId, profileRequest));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument '{nameof(profileId)}' is null or empty\");\n    }\n\n    [Fact]\n    public async Task EnablePaymentMethodAsync_ForCurrentProfile_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        const string paymentMethod = PaymentMethod.Ideal;\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Post,$\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/me/methods/{paymentMethod}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultPaymentMethodResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var result = await profileClient.EnablePaymentMethodAsync(paymentMethod);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        result.Resource.ShouldBe(\"method\");\n        result.Id.ShouldBe(paymentMethod);\n    }\n\n    [Fact]\n    public async Task EnablePaymentMethodAsync_ForCurrentProfileWithMissingPaymentMethodParameter_ThrowsArgumentException()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => profileClient.EnablePaymentMethodAsync(string.Empty));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument 'paymentMethod' is null or empty\");\n    }\n\n    [Fact]\n    public async Task DisablePaymentMethodAsync_ForCurrentProfile_SendsRequest()\n    {\n        // Arrange\n        const string paymentMethod = PaymentMethod.Ideal;\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Delete, $\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/me/methods/{paymentMethod}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(HttpStatusCode.NoContent);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        await profileClient.DisablePaymentMethodAsync(paymentMethod);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task DisablePaymentMethodAsync_ForCurrentProfileWithMissingPaymentMethodParameter_ThrowsArgumentException()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => profileClient.DisablePaymentMethodAsync(string.Empty));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument 'paymentMethod' is null or empty\");\n    }\n\n    [Fact]\n    public async Task DeleteProfileAsync_ForGivenProfileId_SendsRequest()\n    {\n        // Arrange\n        const string profileId = \"profile-id\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Delete, $\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/{profileId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(HttpStatusCode.NoContent);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        await profileClient.DeleteProfileAsync(profileId);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task DeleteProfileAsync_WithMissingProfileIdParameter_ThrowsArgumentException()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => profileClient.DeleteProfileAsync(string.Empty));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument 'profileId' is null or empty\");\n    }\n\n    [Fact]\n    public async Task EnableGiftCardIssuerAsync_ForCurrentProfile_ResponseIsDeserializedInExpectedFormat()\n    {\n        // Arrange\n        const string issuer = \"festivalcadeau\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Post,$\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/me/methods/giftcard/issuers/{issuer}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", defaultEnableGiftcardIssuerResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var result = await profileClient.EnableGiftCardIssuerAsync(issuer);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingRequest();\n        result.Resource.ShouldBe(\"issuer\");\n        result.Id.ShouldBe(issuer);\n        result.Description.ShouldBe(\"FestivalCadeau Giftcard\");\n        result.Status.ShouldBe(\"pending-issuer\");\n    }\n\n    [Fact]\n    public async Task EnableGiftCardIssuerAsync_ForCurrentProfileWithMissingIssuerParameter_ThrowsArgumentException()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => profileClient.EnableGiftCardIssuerAsync(string.Empty));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument 'issuer' is null or empty\");\n    }\n\n    [Fact]\n    public async Task DisableGiftCardIssuerAsync_ForCurrentProfile_SendsRequest()\n    {\n        // Arrange\n        const string issuer = \"festivalcadeau\";\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.Expect(HttpMethod.Delete, $\"{BaseMollieClient.DefaultBaseApiEndPoint}profiles/me/methods/giftcard/issuers/{issuer}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(HttpStatusCode.NoContent);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        await profileClient.DisableGiftCardIssuerAsync(issuer);\n\n        // Assert\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task DisableGiftCardIssuerAsync_ForCurrentProfileWithMissingIssuerParameter_ThrowsArgumentException()\n    {\n        // Arrange\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        using var profileClient = new ProfileClient(\"abcde\", httpClient);\n\n        // Act\n        var exception = await Assert.ThrowsAsync<ArgumentException>(() => profileClient.DisableGiftCardIssuerAsync(string.Empty));\n\n        // Assert\n        exception.Message.ShouldBe($\"Required URL argument 'issuer' is null or empty\");\n    }\n\n    private void AssertDefaultProfileResponse(ProfileResponse result)\n    {\n        result.Resource.ShouldBe(\"profile\");\n        result.Id.ShouldBe(\"pfl_v9hTwCvYqw\");\n        result.Mode.ShouldBe(Mode.Test);\n        result.Name.ShouldBe(\"My website name\");\n        result.Email.ShouldBe(\"info@mywebsite.com\");\n        result.Website.ShouldBe(\"https://www.mywebsite.com\");\n        result.Phone.ShouldBe(\"+31208202070\");\n        result.BusinessCategory.ShouldBe(\"OTHER_MERCHANDISE\");\n        result.Status.ShouldBe(ProfileStatus.Unverified);\n    }\n\n    private const string defaultEnableGiftcardIssuerResponse = @\"{\n     \"\"resource\"\": \"\"issuer\"\",\n     \"\"id\"\": \"\"festivalcadeau\"\",\n     \"\"description\"\": \"\"FestivalCadeau Giftcard\"\",\n     \"\"status\"\": \"\"pending-issuer\"\",\n     \"\"_links\"\": {\n         \"\"self\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/issuers/festivalcadeau\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"documentation\"\": {\n             \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/profiles-api/enable-giftcard-issuer\"\",\n             \"\"type\"\": \"\"text/html\"\"\n         }\n     }\n }\";\n\n    private const string defaultPaymentMethodResponse = @\"{\n     \"\"resource\"\": \"\"method\"\",\n     \"\"id\"\": \"\"ideal\"\",\n     \"\"description\"\": \"\"iDEAL\"\",\n     \"\"minimumAmount\"\": {\n         \"\"value\"\": \"\"0.01\"\",\n         \"\"currency\"\": \"\"EUR\"\"\n     },\n     \"\"maximumAmount\"\": {\n         \"\"value\"\": \"\"50000.00\"\",\n         \"\"currency\"\": \"\"EUR\"\"\n     },\n     \"\"image\"\": {\n         \"\"size1x\"\": \"\"https://www.mollie.com/external/icons/payment-methods/ideal.png\"\",\n         \"\"size2x\"\": \"\"https://www.mollie.com/external/icons/payment-methods/ideal%402x.png\"\",\n         \"\"svg\"\": \"\"https://www.mollie.com/external/icons/payment-methods/ideal.svg\"\"\n     },\n     \"\"status\"\": \"\"activated\"\",\n     \"\"_links\"\": {\n         \"\"self\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/methods/ideal\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"documentation\"\": {\n             \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/profiles-api/enable-method\"\",\n             \"\"type\"\": \"\"text/html\"\"\n         }\n     }\n }\";\n\n    private const string defaultProfileJsonResponse = @\"{\n    \"\"resource\"\": \"\"profile\"\",\n    \"\"id\"\": \"\"pfl_v9hTwCvYqw\"\",\n    \"\"mode\"\": \"\"test\"\",\n    \"\"name\"\": \"\"My website name\"\",\n    \"\"website\"\": \"\"https://www.mywebsite.com\"\",\n    \"\"email\"\": \"\"info@mywebsite.com\"\",\n    \"\"phone\"\": \"\"+31208202070\"\",\n    \"\"description\"\": \"\"Description\"\",\n    \"\"countriesOfActivity\"\": [\"\"NL\"\"],\n    \"\"businessCategory\"\": \"\"OTHER_MERCHANDISE\"\",\n    \"\"categoryCode\"\": 5399,\n    \"\"status\"\": \"\"unverified\"\",\n    \"\"createdAt\"\": \"\"2018-03-20T09:28:37+00:00\"\",\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/profiles/pfl_v9hTwCvYqw\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"dashboard\"\": {\n            \"\"href\"\": \"\"https://www.mollie.com/dashboard/org_123456789/settings/profiles/pfl_v9hTwCvYqw\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"chargebacks\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/chargebacks?profileId=pfl_v9hTwCvYqw\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"methods\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/methods?profileId=pfl_v9hTwCvYqw\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"payments\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments?profileId=pfl_v9hTwCvYqw\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"refunds\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/refunds?profileId=pfl_v9hTwCvYqw\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"checkoutPreviewUrl\"\": {\n            \"\"href\"\": \"\"https://www.mollie.com/payscreen/preview/pfl_v9hTwCvYqw\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/profiles-api/create-profile\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n\n    private const string defaultGetProfileListJsonResponse = @\"{\n    \"\"_embedded\"\": {\n        \"\"profiles\"\": [\n            {\n                \"\"resource\"\": \"\"profiles\"\",\n                \"\"id\"\": \"\"pfl_v9hTwCvYqw\"\",\n                \"\"mode\"\": \"\"live\"\",\n                \"\"name\"\": \"\"My website name\"\",\n                \"\"website\"\": \"\"https://www.mywebsite.com\"\",\n                \"\"email\"\": \"\"info@mywebsite.com\"\",\n                \"\"phone\"\": \"\"+31208202070\"\",\n                \"\"businessCategory\"\": \"\"OTHER_MERCHANDISE\"\",\n                \"\"categoryCode\"\": 5399,\n                \"\"status\"\": \"\"verified\"\",\n                \"\"review\"\": {\n                    \"\"status\"\": \"\"pending\"\"\n                },\n                \"\"createdAt\"\": \"\"2018-03-20T09:28:37+00:00\"\",\n                \"\"_links\"\": {\n                    \"\"self\"\": {\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/profiles/pfl_v9hTwCvYqw\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    },\n                    \"\"dashboard\"\": {\n                        \"\"href\"\": \"\"https://www.mollie.com/dashboard/org_123456789/settings/profiles/pfl_v9hTwCvYqw\"\",\n                        \"\"type\"\": \"\"text/html\"\"\n                    },\n                    \"\"chargebacks\"\": {\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/chargebacks?profileId=pfl_v9hTwCvYqw\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    },\n                    \"\"methods\"\": {\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/methods?profileId=pfl_v9hTwCvYqw\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    },\n                    \"\"payments\"\": {\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/payments?profileId=pfl_v9hTwCvYqw\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    },\n                    \"\"refunds\"\": {\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/refunds?profileId=pfl_v9hTwCvYqw\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    },\n                    \"\"checkoutPreviewUrl\"\": {\n                        \"\"href\"\": \"\"https://www.mollie.com/payscreen/preview/pfl_v9hTwCvYqw\"\",\n                        \"\"type\"\": \"\"text/html\"\"\n                    },\n                    \"\"documentation\"\": {\n                        \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/profiles-api/create-profile\"\",\n                        \"\"type\"\": \"\"text/html\"\"\n                    }\n                }\n            }\n        ]\n    },\n    \"\"count\"\": 1,\n    \"\"_links\"\": {\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/profiles-api/list-profiles\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        },\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/profiles?limit=5\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"previous\"\": null,\n        \"\"next\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/profiles?from=pfl_3RkSN1zuPE&limit=5\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }\n    }\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/RefundClientTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Mollie.Api.Client;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Order.Request;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Refund;\nusing Mollie.Api.Models.Refund.Request;\nusing Mollie.Api.Models.Refund.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class RefundClientTests : BaseClientTests {\n        private const string defaultSettlementId = \"stl_BkEjN2eBb\";\n        private readonly string defaultGetRefundResponse = @$\"{{\n    \"\"resource\"\": \"\"refund\"\",\n    \"\"id\"\": \"\"re_4qqhO89gsT\"\",\n    \"\"amount\"\": {{\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"5.95\"\"\n    }},\n    \"\"settlementId\"\": \"\"{defaultSettlementId}\"\",\n    \"\"status\"\": \"\"pending\"\",\n    \"\"createdAt\"\": \"\"2018-03-14T17:09:02.0Z\"\",\n    \"\"description\"\": \"\"Order #33\"\",\n    \"\"metadata\"\": {{\n         \"\"bookkeeping_id\"\": 12345\n    }},\n    \"\"paymentId\"\": \"\"tr_WDqYK6vllg\"\",\n    \"\"_links\"\": {{\n        \"\"self\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg/refunds/re_4qqhO89gsT\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"payment\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/refunds-api/get-refund\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }}\n}}\";\n\n        [Theory]\n        [InlineData(\"payments/paymentId/refunds/refundId\", null)]\n        [InlineData(\"payments/paymentId/refunds/refundId\", false)]\n        [InlineData(\"payments/paymentId/refunds/refundId?testmode=true\", true)]\n        public async Task GetRefundAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string expectedUrl, bool? testModeParameter) {\n            // Given: We make a request to retrieve a payment without wanting any extra data\n            bool testMode = testModeParameter ?? false;\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}{expectedUrl}\", defaultGetRefundResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var refundResponse = await refundClient.GetPaymentRefundAsync(\"paymentId\", \"refundId\", testmode: testMode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            refundResponse.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateRefundAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Given: We create a refund without specifying a paymentId\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n            var refund = new RefundRequest  {\n                Amount = new Amount(Currency.EUR, 100m)\n            };\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.CreatePaymentRefundAsync(paymentId, refund));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public async Task CreateRefundAsync_WithReverseRouting_ResponseIsDeserializedInExpectedFormat(bool reverseRouting) {\n            // Given: We create a refund with a routing destination\n            const string paymentId = \"tr_7UhSN1zuXS\";\n            var refundRequest = new RefundRequest  {\n                Amount = new Amount(Currency.EUR, 100m),\n                ReverseRouting = reverseRouting\n            };\n            string expectedStringValue = reverseRouting.ToString().ToLowerInvariant();\n            string expectedRoutingInformation = $\"\\\"reverseRouting\\\": {expectedStringValue}\";\n            string expectedJsonResponse = @$\"{{\n  \"\"resource\"\": \"\"refund\"\",\n  \"\"id\"\": \"\"re_4qqhO89gsT\"\",\n  \"\"description\"\": \"\"\"\",\n  \"\"amount\"\": {{\n    \"\"currency\"\": \"\"EUR\"\",\n    \"\"value\"\": \"\"100.00\"\"\n  }},\n  \"\"reverseRouting\"\": {expectedStringValue},\n  \"\"status\"\": \"\"pending\"\",\n  \"\"metadata\"\": null,\n  \"\"paymentId\"\": \"\"{paymentId}\"\",\n  \"\"createdAt\"\": \"\"2023-03-14T17:09:02.0Z\"\"\n}}\";\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Post,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}/refunds\",\n                expectedJsonResponse,\n                expectedRoutingInformation);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new(\"api-key\", httpClient);\n\n            // When: We create the refund\n            RefundResponse refundResponse = await refundClient.CreatePaymentRefundAsync(paymentId, refundRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            refundResponse.ReverseRouting.ShouldBe(reverseRouting);\n            refundResponse.RoutingReversals.ShouldBeNull();\n        }\n\n        [Fact]\n        public async Task CreateRefundAsync_WithRoutingInformation_ResponseIsDeserializedInExpectedFormat() {\n            // Given: We create a refund with a routing destination\n            const string paymentId = \"tr_7UhSN1zuXS\";\n            var refundRequest = new RefundRequest  {\n                Amount = new Amount(Currency.EUR, 100m),\n                ReverseRouting = null,\n                RoutingReversals = new List<RoutingReversal> {\n                    new RoutingReversal {\n                        Amount = new Amount(Currency.EUR, 50m),\n                        Source = new RoutingDestination {\n                            Type = \"organization\",\n                            OrganizationId = \"organization-id\"\n                        }\n                    }\n                }\n            };\n            string expectedRoutingInformation = $\"\\\"routingReversals\\\":[{{\\\"amount\\\":{{\\\"currency\\\":\\\"EUR\\\",\\\"value\\\":\\\"50.00\\\"}},\\\"source\\\":{{\\\"type\\\":\\\"organization\\\",\\\"organizationId\\\":\\\"organization-id\\\"}}}}]}}\";\n            string expectedJsonResponse = @$\"{{\n  \"\"resource\"\": \"\"refund\"\",\n  \"\"id\"\": \"\"re_4qqhO89gsT\"\",\n  \"\"description\"\": \"\"\"\",\n  \"\"amount\"\": {{\n    \"\"currency\"\": \"\"EUR\"\",\n    \"\"value\"\": \"\"100.00\"\"\n  }},\n  \"\"routingReversals\"\": [\n    {{\n      \"\"amount\"\": {{\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"50.00\"\"\n      }},\n      \"\"source\"\": {{\n        \"\"type\"\": \"\"organization\"\",\n        \"\"organizationId\"\": \"\"organization-id\"\"\n      }}\n    }}\n  ],\n  \"\"status\"\": \"\"pending\"\",\n  \"\"metadata\"\": null,\n  \"\"paymentId\"\": \"\"{paymentId}\"\",\n  \"\"createdAt\"\": \"\"2023-03-14T17:09:02.0Z\"\"\n}}\";\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Post,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}payments/{paymentId}/refunds\",\n                expectedJsonResponse,\n                expectedRoutingInformation);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new(\"api-key\", httpClient);\n\n            // When: We create the refund\n            RefundResponse refundResponse = await refundClient.CreatePaymentRefundAsync(paymentId, refundRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            refundResponse.RoutingReversals.ShouldBeEquivalentTo(refundRequest.RoutingReversals);\n            refundResponse.ReverseRouting.ShouldBeNull();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetRefundListAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.GetPaymentRefundListAsync(paymentId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetRefundAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.GetPaymentRefundAsync(paymentId, \"refund-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetRefundAsync_NoRefundIsGiven_ArgumentExceptionIsThrown(string? refundId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.GetPaymentRefundAsync(\"payment-id\", refundId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'refundId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CancelRefundAsync_NoPaymentIdIsGiven_ArgumentExceptionIsThrown(string? paymentId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.CancelPaymentRefundAsync(paymentId, \"refund-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'paymentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CancelRefundAsync_NoRefundIsGiven_ArgumentExceptionIsThrown(string? refundId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.CancelPaymentRefundAsync(\"payment-id\", refundId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'refundId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(null, null, false, \"\")]\n        [InlineData(\"from\", null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, false, \"?from=from&limit=50\")]\n        [InlineData(null, null, true, \"?testmode=true\")]\n        public async Task GetOrderRefundListAsync_QueryParameterOptions_CorrectParametersAreAdded(string? from, int? limit, bool testmode, string expectedQueryString) {\n            // Given: We make a request to retrieve the list of orders\n            const string orderId = \"abcde\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}/refunds{expectedQueryString}\", defaultOrderJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n            await refundClient.GetOrderRefundListAsync(orderId, from, limit, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingRequest();\n        }\n\n        [Fact]\n        public async Task CreateOrderRefundAsync_WithRequiredParameters_ResponseIsDeserializedInExpectedFormat()\n        {\n            // Given: We create a refund request with only the required parameters\n            const string orderId = \"ord_stTC2WHAuS\";\n            OrderRefundRequest orderRefundRequest = new OrderRefundRequest()\n            {\n                Description = \"description\",\n                Lines = new[]\n                {\n                    new OrderLineDetails()\n                    {\n                        Id = \"odl_dgtxyl\",\n                        Quantity = 1,\n                        Amount = new Amount(Currency.EUR, \"399.00\")\n                    }\n                },\n                Metadata = \"my-metadata\"\n            };\n            string url = $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}/refunds\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, url, defaultOrderRefundJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n            var response = await refundClient.CreateOrderRefundAsync(orderId, orderRefundRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            response.Resource.ShouldBe(\"refund\");\n            response.Id.ShouldBe(\"re_4qqhO89gsT\");\n            response.Description.ShouldBe(\"description\");\n            response.Status.ShouldBe(\"pending\");\n            response.CreatedAt!.Value.ToUniversalTime().ShouldBe(DateTime.SpecifyKind(new DateTime(2018, 3, 14, 17, 09, 02), DateTimeKind.Utc));\n            response.PaymentId.ShouldBe(\"tr_WDqYK6vllg\");\n            response.OrderId.ShouldBe(orderId);\n            response.Lines.Count().ShouldBe(1);\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateOrderRefundAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n            var request = new OrderRefundRequest()\n            {\n                Lines = new List<OrderLineDetails>()\n            };\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.CreateOrderRefundAsync(orderId, request));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetOrderRefundListAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            RefundClient refundClient = new RefundClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await refundClient.GetOrderRefundListAsync(orderId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        private const string defaultOrderJsonResponse = @\"{\n            \"\"resource\"\": \"\"order\"\",\n            \"\"id\"\": \"\"ord_kEn1PlbGa\"\",\n            \"\"profileId\"\": \"\"pfl_URR55HPMGx\"\",\n            \"\"method\"\": \"\"ideal\"\",\n            \"\"amount\"\": {\n                \"\"value\"\": \"\"1027.99\"\",\n                \"\"currency\"\": \"\"EUR\"\"\n            },\n        }\";\n\n        private const string defaultOrderRefundJsonResponse = @\"{\n    \"\"resource\"\": \"\"refund\"\",\n    \"\"id\"\": \"\"re_4qqhO89gsT\"\",\n    \"\"amount\"\": {\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"698.00\"\"\n    },\n    \"\"status\"\": \"\"pending\"\",\n    \"\"createdAt\"\": \"\"2018-03-14T17:09:02.0Z\"\",\n    \"\"description\"\": \"\"description\"\",\n    \"\"metadata\"\": {\n         \"\"bookkeeping_id\"\": 12345\n    },\n    \"\"paymentId\"\": \"\"tr_WDqYK6vllg\"\",\n    \"\"orderId\"\": \"\"ord_stTC2WHAuS\"\",\n    \"\"lines\"\": [\n        {\n            \"\"resource\"\": \"\"orderline\"\",\n            \"\"id\"\": \"\"odl_dgtxyl\"\",\n            \"\"orderId\"\": \"\"ord_stTC2WHAuS\"\",\n            \"\"name\"\": \"\"LEGO 42083 Bugatti Chiron\"\",\n            \"\"sku\"\": \"\"5702016116977\"\",\n            \"\"type\"\": \"\"physical\"\",\n            \"\"status\"\": \"\"paid\"\",\n            \"\"metadata\"\": null,\n            \"\"quantity\"\": 1,\n            \"\"unitPrice\"\": {\n                \"\"value\"\": \"\"399.00\"\",\n                \"\"currency\"\": \"\"EUR\"\"\n            },\n            \"\"vatRate\"\": \"\"21.00\"\",\n            \"\"vatAmount\"\": {\n                \"\"value\"\": \"\"51.89\"\",\n                \"\"currency\"\": \"\"EUR\"\"\n            },\n            \"\"discountAmount\"\": {\n                \"\"value\"\": \"\"100.00\"\",\n                \"\"currency\"\": \"\"EUR\"\"\n            },\n            \"\"totalAmount\"\": {\n                \"\"value\"\": \"\"299.00\"\",\n                \"\"currency\"\": \"\"EUR\"\"\n            },\n            \"\"createdAt\"\": \"\"2018-08-02T09:29:56+00:00\"\",\n            \"\"_links\"\": {\n                \"\"productUrl\"\": {\n                    \"\"href\"\": \"\"https://shop.lego.com/nl-NL/Bugatti-Chiron-42083\"\",\n                    \"\"type\"\": \"\"text/html\"\"\n                },\n                \"\"imageUrl\"\": {\n                    \"\"href\"\": \"\"https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$\"\",\n                    \"\"type\"\": \"\"text/html\"\"\n                }\n            }\n        }\n    ],\n    \"\"_links\"\": {\n        \"\"self\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg/refunds/re_4qqhO89gsT\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"payment\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"order\"\": {\n            \"\"href\"\": \"\"https://api.mollie.com/v2/orders/ord_stTC2WHAuS\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        },\n        \"\"documentation\"\": {\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/refunds-api/create-order-refund\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }\n    }\n}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/SalesInvoiceClientTests.cs",
    "content": "﻿using System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.SalesInvoice;\nusing Mollie.Api.Models.SalesInvoice.Request;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class SalesInvoiceClientTests : BaseClientTests {\n    [Fact]\n    public async Task CreateSalesInvoiceAsync_ShouldReturnSalesInvoiceResponse() {\n        // Given: We create a new sales invoice\n        var request = new SalesInvoiceRequest {\n            Status = SalesInvoiceStatus.Draft,\n            PaymentTerm = PaymentTerm.Days30,\n            RecipientIdentifier = \"123532354\",\n            Recipient = new Recipient {\n                Type = RecipientType.Consumer,\n                Email = \"given.family@mollie.com\",\n                StreetAndNumber = \"Street 1\",\n                PostalCode = \"1000 AA\",\n                City = \"Amsterdam\",\n                Country = \"NL\",\n                Locale = \"nl_NL\",\n                GivenName = \"Given\",\n                FamilyName = \"Family\"\n            },\n            Lines = [\n                new SalesInvoiceLine {\n                    Description = \"LEGO 4440 Forest Police Station\",\n                    Quantity = 1,\n                    VatRate = \"21.00\",\n                    UnitPrice = new Amount(\"89.00\", \"EUR\")\n                }\n            ]\n        };\n        string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}sales-invoices\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post, expectedUrl, DefaultSalesInvoiceClientResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var salesInvoiceClient = new SalesInvoiceClient(\"api-key\", httpClient);\n\n        // When: We create the new invoice\n        var result = await salesInvoiceClient.CreateSalesInvoiceAsync(request);\n\n        // Then: We should get a valid response\n        mockHttp.VerifyNoOutstandingExpectation();\n        result.Id.ShouldBe(\"invoice_4Y0eZitmBnQ6IDoMqZQKh\");\n        result.Status.ShouldBe(SalesInvoiceStatus.Draft);\n        result.Currency.ShouldBe(Currency.EUR);\n        result.Lines.ShouldNotBeEmpty();\n        var orderLine = result.Lines.Single();\n        orderLine.Description.ShouldBe(\"LEGO 4440 Forest Police Station\");\n        orderLine.Quantity.ShouldBe(1);\n        orderLine.VatRate.ShouldBe(\"21.00\");\n        orderLine.UnitPrice.Value.ShouldBe(\"89.00\");\n        orderLine.UnitPrice.Currency.ShouldBe(Currency.EUR);\n        orderLine.Discount.ShouldBeNull();\n        result.AmountDue.Value.ShouldBe(\"107.69\");\n        result.AmountDue.Currency.ShouldBe(Currency.EUR);\n        result.DiscountedSubtotalAmount.Value.ShouldBe(\"89.00\");\n        result.DiscountedSubtotalAmount.Currency.ShouldBe(Currency.EUR);\n    }\n\n    [Fact]\n    public async Task GetSalesInvoiceAsync_ShouldReturnSalesInvoiceResponse() {\n        // Given: A sales invoice ID\n        const string salesInvoiceId = \"invoice_4Y0eZitmBnQ6IDoMqZQKh\";\n        string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}sales-invoices/{salesInvoiceId}\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, DefaultSalesInvoiceClientResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var salesInvoiceClient = new SalesInvoiceClient(\"api-key\", httpClient);\n\n        // When: We retrieve the sales invoice\n        var result = await salesInvoiceClient.GetSalesInvoiceAsync(salesInvoiceId);\n\n        // Then: The response should match the expected data\n        mockHttp.VerifyNoOutstandingExpectation();\n        result.Id.ShouldBe(salesInvoiceId);\n        result.Status.ShouldBe(SalesInvoiceStatus.Draft);\n        result.Currency.ShouldBe(Currency.EUR);\n        result.Lines.ShouldNotBeEmpty();\n        var orderLine = result.Lines.Single();\n        orderLine.Description.ShouldBe(\"LEGO 4440 Forest Police Station\");\n        orderLine.Quantity.ShouldBe(1);\n        orderLine.VatRate.ShouldBe(\"21.00\");\n        orderLine.UnitPrice.Value.ShouldBe(\"89.00\");\n        orderLine.UnitPrice.Currency.ShouldBe(Currency.EUR);\n        orderLine.Discount.ShouldBeNull();\n        result.AmountDue.Value.ShouldBe(\"107.69\");\n        result.AmountDue.Currency.ShouldBe(Currency.EUR);\n        result.DiscountedSubtotalAmount.Value.ShouldBe(\"89.00\");\n        result.DiscountedSubtotalAmount.Currency.ShouldBe(Currency.EUR);\n    }\n\n    [Fact]\n    public async Task UpdateSalesInvoiceAsync_ShouldReturnUpdatedSalesInvoiceResponse() {\n        // Given: A sales invoice ID and update request\n        const string salesInvoiceId = \"invoice_4Y0eZitmBnQ6IDoMqZQKh\";\n        var updateRequest = new SalesInvoiceUpdateRequest {\n            Memo = \"Updated memo\"\n        };\n        string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}sales-invoices/{salesInvoiceId}\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Patch, expectedUrl, DefaultSalesInvoiceClientResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var salesInvoiceClient = new SalesInvoiceClient(\"api-key\", httpClient);\n\n        // When: We update the sales invoice\n        await salesInvoiceClient.UpdateSalesInvoiceAsync(salesInvoiceId, updateRequest);\n\n        // Then: The update sales invoice endpoint should be called\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Fact]\n    public async Task DeleteSalesInvoiceAsync_ShouldNotThrowException() {\n        // Given: A sales invoice ID\n        const string salesInvoiceId = \"invoice_4Y0eZitmBnQ6IDoMqZQKh\";\n        string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}sales-invoices/{salesInvoiceId}\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Delete, expectedUrl, \"{}\");\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var salesInvoiceClient = new SalesInvoiceClient(\"api-key\", httpClient);\n\n        // When: We delete the sales invoice\n        await salesInvoiceClient.DeleteSalesInvoiceAsync(salesInvoiceId);\n\n        // Then: No exception should be thrown\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    private const string DefaultSalesInvoiceClientResponse = @\"{\n  \"\"resource\"\": \"\"sales-invoice\"\",\n  \"\"id\"\": \"\"invoice_4Y0eZitmBnQ6IDoMqZQKh\"\",\n  \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n  \"\"invoiceNumber\"\": null,\n  \"\"currency\"\": \"\"EUR\"\",\n  \"\"status\"\": \"\"draft\"\",\n  \"\"vatScheme\"\": \"\"standard\"\",\n  \"\"paymentTerm\"\": \"\"30 days\"\",\n  \"\"recipientIdentifier\"\": \"\"123532354\"\",\n  \"\"recipient\"\": {\n    \"\"type\"\": \"\"consumer\"\",\n    \"\"title\"\": null,\n    \"\"givenName\"\": \"\"Given\"\",\n    \"\"familyName\"\": \"\"Family\"\",\n    \"\"email\"\": \"\"given.family@mollie.com\"\",\n    \"\"phone\"\": null,\n    \"\"streetAndNumber\"\": \"\"Street 1\"\",\n    \"\"streetAdditional\"\": null,\n    \"\"postalCode\"\": \"\"1000 AA\"\",\n    \"\"city\"\": \"\"Amsterdam\"\",\n    \"\"region\"\": null,\n    \"\"country\"\": \"\"NL\"\",\n    \"\"locale\"\": \"\"nl_NL\"\"\n  },\n  \"\"lines\"\": [\n    {\n      \"\"description\"\": \"\"LEGO 4440 Forest Police Station\"\",\n      \"\"quantity\"\": 1,\n      \"\"vatRate\"\": \"\"21.00\"\",\n      \"\"unitPrice\"\": {\n        \"\"value\"\": \"\"89.00\"\",\n        \"\"currency\"\": \"\"EUR\"\"\n      },\n      \"\"discount\"\": null\n    }\n  ],\n  \"\"discount\"\": null,\n  \"\"amountDue\"\": {\n    \"\"value\"\": \"\"107.69\"\",\n    \"\"currency\"\": \"\"EUR\"\"\n  },\n  \"\"subtotalAmount\"\": {\n    \"\"value\"\": \"\"89.00\"\",\n    \"\"currency\"\": \"\"EUR\"\"\n  },\n  \"\"totalAmount\"\": {\n    \"\"value\"\": \"\"107.69\"\",\n    \"\"currency\"\": \"\"EUR\"\"\n  },\n  \"\"totalVatAmount\"\": {\n    \"\"value\"\": \"\"18.69\"\",\n    \"\"currency\"\": \"\"EUR\"\"\n  },\n  \"\"discountedSubtotalAmount\"\": {\n    \"\"value\"\": \"\"89.00\"\",\n    \"\"currency\"\": \"\"EUR\"\"\n  },\n  \"\"createdAt\"\": \"\"2024-10-03T10:47:38.457381+00:00\"\",\n  \"\"issuedAt\"\": null,\n  \"\"dueAt\"\": null,\n  \"\"memo\"\": null,\n  \"\"metadata\"\": [],\n  \"\"_links\"\": {\n    \"\"self\"\": {\n      \"\"href\"\": \"\"...\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    },\n    \"\"invoicePayment\"\": {\n      \"\"href\"\": \"\"...\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    },\n    \"\"pdfLink\"\": {\n      \"\"href\"\": \"\"...\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    },\n    \"\"documentation\"\": {\n      \"\"href\"\": \"\"...\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    }\n  }\n}\";\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/SettlementClientTests.cs",
    "content": "﻿using System;\nusing Mollie.Api.Client;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Models.Capture.Response;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Settlement.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class SettlementClientTests : BaseClientTests {\n        [Fact]\n        public async Task ListSettlementCaptures_DefaultBehaviour_ResponseIsParsed() {\n            // Given: We request a list of captures\n            string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}settlements/{defaultSettlementId}/captures\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, defaultCaptureListJsonResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            SettlementClient settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We make the request\n            ListResponse<CaptureResponse> listCaptureResponse = await settlementClient.GetSettlementCaptureListAsync(defaultSettlementId);\n\n            // Then: Response should be parsed\n            mockHttp.VerifyNoOutstandingExpectation();\n            listCaptureResponse.ShouldNotBeNull();\n            listCaptureResponse.Count.ShouldBe(1);\n            listCaptureResponse.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/settlements/stl_jDk30akdN/captures?limit=50\");\n            listCaptureResponse.Links.Self.Type.ShouldBe(\"application/hal+json\");\n            listCaptureResponse.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/settlements-api/list-settlement-captures\");\n            listCaptureResponse.Links.Documentation.Type.ShouldBe(\"text/html\");\n            CaptureResponse captureResponse = listCaptureResponse.Items.First();\n            captureResponse.PaymentId.ShouldBe(defaultPaymentId);\n            captureResponse.ShipmentId.ShouldBe(defaultShipmentId);\n            captureResponse.SettlementId.ShouldBe(defaultSettlementId);\n            captureResponse.Amount.Value.ShouldBe(defaultAmountValue);\n            captureResponse.Amount.Currency.ShouldBe(defaultAmountCurrency);\n            captureResponse.Links.ShouldNotBeNull();\n            captureResponse.Links.Self.Href.ShouldBe($\"https://api.mollie.com/v2/payments/{defaultPaymentId}/captures/cpt_4qqhO89gsT\");\n            captureResponse.Links.Self.Type.ShouldBe(\"application/hal+json\");\n            captureResponse.Links.Payment.Href.ShouldBe($\"https://api.mollie.com/v2/payments/{defaultPaymentId}\");\n            captureResponse.Links.Payment.Type.ShouldBe(\"application/hal+json\");\n            captureResponse.Links.Shipment.Href.ShouldBe($\"https://api.mollie.com/v2/orders/ord_8wmqcHMN4U/shipments/shp_3wmsgCJN4U\");\n            captureResponse.Links.Shipment.Type.ShouldBe(\"application/hal+json\");\n            captureResponse.Links.Settlement.Href.ShouldBe($\"https://api.mollie.com/v2/settlements/stl_jDk30akdN\");\n            captureResponse.Links.Settlement.Type.ShouldBe(\"application/hal+json\");\n            captureResponse.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/captures-api/get-capture\");\n            captureResponse.Links.Documentation.Type.ShouldBe(\"text/html\");\n        }\n\n        [Fact]\n        public async Task GetOpenSettlement_DefaultBehaviour_ResponseIsParsed() {\n            // Given: We request a list of captures\n            string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}settlements/open\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, defaultGetSettlementResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            SettlementClient settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We make the request\n            SettlementResponse settlementResponse = await settlementClient.GetOpenSettlement();\n\n            // Then: Response should be parsed\n            mockHttp.VerifyNoOutstandingExpectation();\n            settlementResponse.ShouldNotBeNull();\n            settlementResponse.Amount.Value.ShouldBe(defaultAmountValue);\n            settlementResponse.Amount.Currency.ShouldBe(defaultAmountCurrency);\n            settlementResponse.Periods.Count.ShouldBe(1);\n            settlementResponse.Periods[2018][4].InvoiceId.ShouldBe(defaultInvoiceId);\n            settlementResponse.Periods[2018][4].Revenue.Count.ShouldBe(2);\n            settlementResponse.Periods[2018][4].Revenue[0].Description.ShouldBe(\"iDEAL\");\n            settlementResponse.Periods[2018][4].Revenue[0].Method.ShouldBe(\"ideal\");\n            settlementResponse.Periods[2018][4].Revenue[0].Count.ShouldBe(6);\n            settlementResponse.Periods[2018][4].Revenue[0].AmountNet.Value.ShouldBe(\"86.1000\");\n            settlementResponse.Periods[2018][4].Revenue[0].AmountNet.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Revenue[0].AmountVat.ShouldBeNull();\n            settlementResponse.Periods[2018][4].Revenue[0].AmountGross.Value.ShouldBe(\"86.1000\");\n            settlementResponse.Periods[2018][4].Revenue[0].AmountGross.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Revenue[1].Description.ShouldBe(\"Refunds iDEAL\");\n            settlementResponse.Periods[2018][4].Revenue[1].Method.ShouldBe(\"refund\");\n            settlementResponse.Periods[2018][4].Revenue[1].Count.ShouldBe(2);\n            settlementResponse.Periods[2018][4].Revenue[1].AmountNet.Value.ShouldBe(\"-43.2000\");\n            settlementResponse.Periods[2018][4].Revenue[1].AmountNet.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Revenue[1].AmountVat.ShouldBeNull();\n            settlementResponse.Periods[2018][4].Revenue[1].AmountGross.Value.ShouldBe(\"43.2000\");\n            settlementResponse.Periods[2018][4].Revenue[1].AmountGross.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs.Count.ShouldBe(2);\n            settlementResponse.Periods[2018][4].Costs[0].Description.ShouldBe(\"iDEAL\");\n            settlementResponse.Periods[2018][4].Costs[0].Method.ShouldBe(\"ideal\");\n            settlementResponse.Periods[2018][4].Costs[0].Count.ShouldBe(6);\n            settlementResponse.Periods[2018][4].Costs[0].Rate.Fixed.Value.ShouldBe(\"0.3500\");\n            settlementResponse.Periods[2018][4].Costs[0].Rate.Fixed.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs[0].Rate.Percentage.ShouldBeNull();\n            settlementResponse.Periods[2018][4].Costs[0].AmountNet.Value.ShouldBe(\"2.1000\");\n            settlementResponse.Periods[2018][4].Costs[0].AmountNet.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs[0].AmountVat.Value.ShouldBe(\"0.4410\");\n            settlementResponse.Periods[2018][4].Costs[0].AmountVat.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs[0].AmountGross.Value.ShouldBe(\"2.5410\");\n            settlementResponse.Periods[2018][4].Costs[0].AmountGross.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs[1].Description.ShouldBe(\"Refunds iDEAL\");\n            settlementResponse.Periods[2018][4].Costs[1].Method.ShouldBe(\"refund\");\n            settlementResponse.Periods[2018][4].Costs[1].Count.ShouldBe(2);\n            settlementResponse.Periods[2018][4].Costs[1].Rate.Fixed.Value.ShouldBe(\"0.2500\");\n            settlementResponse.Periods[2018][4].Costs[1].Rate.Fixed.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs[1].Rate.Percentage.ShouldBeNull();\n            settlementResponse.Periods[2018][4].Costs[1].AmountNet.Value.ShouldBe(\"0.5000\");\n            settlementResponse.Periods[2018][4].Costs[1].AmountNet.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs[1].AmountVat.Value.ShouldBe(\"0.1050\");\n            settlementResponse.Periods[2018][4].Costs[1].AmountVat.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Periods[2018][4].Costs[1].AmountGross.Value.ShouldBe(\"0.6050\");\n            settlementResponse.Periods[2018][4].Costs[1].AmountGross.Currency.ShouldBe(\"EUR\");\n            settlementResponse.Links.ShouldNotBeNull();\n            settlementResponse.Links.Self.Href.ShouldBe(\"https://api.mollie.com/v2/settlements/open\");\n            settlementResponse.Links.Self.Type.ShouldBe(\"application/hal+json\");\n            settlementResponse.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/reference/v2/settlements-api/get-open-settlement\");\n            settlementResponse.Links.Documentation.Type.ShouldBe(\"text/html\");\n        }\n\n        [Fact]\n        public async Task GetOpenSettlement_ResponseWithEmptyPeriods_ResponseIsParsed() {\n            // Given: We request a list of captures\n            string expectedUrl = $\"{BaseMollieClient.DefaultBaseApiEndPoint}settlements/open\";\n            var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Get, expectedUrl, emptyPeriodsSettlementResponse);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            SettlementClient settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We make the request\n            SettlementResponse settlementResponse = await settlementClient.GetOpenSettlement();\n\n            // Then: Response should be parsed\n            mockHttp.VerifyNoOutstandingExpectation();\n            settlementResponse.ShouldNotBeNull();\n            settlementResponse.Periods.Count.ShouldBe(0);\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSettlementAsync_NoSettlementIdIsGiven_ArgumentExceptionIsThrown(string? settlementId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            SettlementClient settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await settlementClient.GetSettlementAsync(settlementId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'settlementId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSettlementPaymentsListAsync_NoSettlementIdIsGiven_ArgumentExceptionIsThrown(string? settlementId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            SettlementClient settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await settlementClient.GetSettlementPaymentListAsync(settlementId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'settlementId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSettlementRefundsListAsync_NoSettlementIdIsGiven_ArgumentExceptionIsThrown(string? settlementId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            SettlementClient settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await settlementClient.GetSettlementRefundListAsync(settlementId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'settlementId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSettlementChargebacksListAsync_NoSettlementIdIsGiven_ArgumentExceptionIsThrown(string? settlementId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            SettlementClient settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await settlementClient.GetSettlementChargebackListAsync(settlementId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'settlementId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSettlementCapturesListAsync_NoSettlementIdIsGiven_ArgumentExceptionIsThrown(string? settlementId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var settlementClient = new SettlementClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await settlementClient.GetSettlementCaptureListAsync(settlementId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'settlementId' is null or empty\");\n        }\n\n\n        private const string defaultSettlementId = \"tr_Agfg241g\";\n        private const string defaultPaymentId = \"tr_WDqYK6vllg\";\n        private const string defaultShipmentId = \"shp_3wmsgCJN4U\";\n        private const string defaultAmountValue = \"1027.99\";\n        private const string defaultAmountCurrency = \"EUR\";\n        private const string defaultInvoiceId = \"inv_FrvewDA3Pr\";\n\n        private string defaultCaptureListJsonResponse = $@\"{{\n    \"\"_embedded\"\": {{\n        \"\"captures\"\": [\n            {{\n                \"\"resource\"\": \"\"capture\"\",\n                \"\"id\"\": \"\"cpt_4qqhO89gsT\"\",\n                \"\"mode\"\": \"\"live\"\",\n                \"\"amount\"\": {{\n                    \"\"value\"\": \"\"{defaultAmountValue}\"\",\n                    \"\"currency\"\": \"\"{defaultAmountCurrency}\"\"\n                }},\n                \"\"settlementAmount\"\": {{\n                    \"\"value\"\": \"\"1027.99\"\",\n                    \"\"currency\"\": \"\"EUR\"\"\n                }},\n                \"\"paymentId\"\": \"\"{defaultPaymentId}\"\",\n                \"\"shipmentId\"\": \"\"{defaultShipmentId}\"\",\n                \"\"settlementId\"\": \"\"{defaultSettlementId}\"\",\n                \"\"createdAt\"\": \"\"2018-08-02T09:29:56+00:00\"\",\n                \"\"_links\"\": {{\n                    \"\"self\"\": {{\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg/captures/cpt_4qqhO89gsT\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    }},\n                    \"\"payment\"\": {{\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/payments/tr_WDqYK6vllg\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    }},\n                    \"\"shipment\"\": {{\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/orders/ord_8wmqcHMN4U/shipments/shp_3wmsgCJN4U\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    }},\n                    \"\"settlement\"\": {{\n                        \"\"href\"\": \"\"https://api.mollie.com/v2/settlements/stl_jDk30akdN\"\",\n                        \"\"type\"\": \"\"application/hal+json\"\"\n                    }},\n                    \"\"documentation\"\": {{\n                        \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/captures-api/get-capture\"\",\n                        \"\"type\"\": \"\"text/html\"\"\n                    }}\n                }}\n            }}\n        ]\n    }},\n    \"\"count\"\": 1,\n    \"\"_links\"\": {{\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/settlements-api/list-settlement-captures\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }},\n        \"\"self\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/settlements/stl_jDk30akdN/captures?limit=50\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"previous\"\": null,\n        \"\"next\"\": null\n    }}\n}}\";\n\n        private string defaultGetSettlementResponse = $@\"{{\n    \"\"resource\"\": \"\"settlement\"\",\n    \"\"id\"\": \"\"open\"\",\n    \"\"status\"\": \"\"open\"\",\n    \"\"amount\"\": {{\n        \"\"currency\"\": \"\"{defaultAmountCurrency}\"\",\n        \"\"value\"\": \"\"{defaultAmountValue}\"\"\n    }},\n    \"\"periods\"\": {{\n        \"\"2018\"\": {{\n            \"\"04\"\": {{\n                \"\"revenue\"\": [\n                    {{\n                        \"\"description\"\": \"\"iDEAL\"\",\n                        \"\"method\"\": \"\"ideal\"\",\n                        \"\"count\"\": 6,\n                        \"\"amountNet\"\": {{\n                            \"\"value\"\": \"\"86.1000\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }},\n                        \"\"amountVat\"\": null,\n                        \"\"amountGross\"\": {{\n                            \"\"value\"\": \"\"86.1000\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }}\n                    }},\n                    {{\n                        \"\"description\"\": \"\"Refunds iDEAL\"\",\n                        \"\"method\"\": \"\"refund\"\",\n                        \"\"count\"\": 2,\n                        \"\"amountNet\"\": {{\n                            \"\"value\"\": \"\"-43.2000\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }},\n                        \"\"amountVat\"\": null,\n                        \"\"amountGross\"\": {{\n                            \"\"value\"\": \"\"43.2000\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }}\n                    }}\n                ],\n                \"\"costs\"\": [\n                    {{\n                        \"\"description\"\": \"\"iDEAL\"\",\n                        \"\"method\"\": \"\"ideal\"\",\n                        \"\"count\"\": 6,\n                        \"\"rate\"\": {{\n                            \"\"fixed\"\": {{\n                                \"\"value\"\": \"\"0.3500\"\",\n                                \"\"currency\"\": \"\"EUR\"\"\n                            }},\n                            \"\"percentage\"\": null\n                        }},\n                        \"\"amountNet\"\": {{\n                            \"\"value\"\": \"\"2.1000\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }},\n                        \"\"amountVat\"\": {{\n                            \"\"value\"\": \"\"0.4410\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }},\n                        \"\"amountGross\"\": {{\n                            \"\"value\"\": \"\"2.5410\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }}\n                    }},\n                    {{\n                        \"\"description\"\": \"\"Refunds iDEAL\"\",\n                        \"\"method\"\": \"\"refund\"\",\n                        \"\"count\"\": 2,\n                        \"\"rate\"\": {{\n                            \"\"fixed\"\": {{\n                                \"\"value\"\": \"\"0.2500\"\",\n                                \"\"currency\"\": \"\"EUR\"\"\n                            }},\n                            \"\"percentage\"\": null\n                        }},\n                        \"\"amountNet\"\": {{\n                            \"\"value\"\": \"\"0.5000\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }},\n                        \"\"amountVat\"\": {{\n                            \"\"value\"\": \"\"0.1050\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }},\n                        \"\"amountGross\"\": {{\n                            \"\"value\"\": \"\"0.6050\"\",\n                            \"\"currency\"\": \"\"EUR\"\"\n                        }}\n                    }}\n                ],\n                \"\"invoiceId\"\": \"\"{defaultInvoiceId}\"\"\n            }}\n        }}\n    }},\n    \"\"_links\"\": {{\n        \"\"self\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/settlements/open\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/settlements-api/get-open-settlement\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }}\n}}\";\n\n        private readonly string emptyPeriodsSettlementResponse = @$\"{{\n   \"\"resource\"\":\"\"settlement\"\",\n   \"\"id\"\":\"\"open\"\",\n   \"\"createdAt\"\":\"\"2020-11-11T07:10:53+00:00\"\",\n   \"\"status\"\":\"\"open\"\",\n   \"\"amount\"\":{{\n      \"\"value\"\":\"\"0.00\"\",\n      \"\"currency\"\":\"\"EUR\"\"\n   }},\n   \"\"periods\"\":[\n\n   ],\n   \"\"_links\"\":{{\n      \"\"self\"\":{{\n         \"\"href\"\":\"\"https://api.mollie.com/v2/settlements/open\"\",\n         \"\"type\"\":\"\"application/hal+json\"\"\n      }},\n      \"\"documentation\"\":{{\n         \"\"href\"\":\"\"https://docs.mollie.com/reference/v2/settlements-api/get-open-settlement\"\",\n         \"\"type\"\":\"\"text/html\"\"\n      }}\n   }}\n}}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/ShipmentClientTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Shipment;\nusing Mollie.Api.Models.Shipment.Request;\nusing Mollie.Api.Models.Shipment.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class ShipmentClientTests : BaseClientTests {\n        [Fact]\n        public async Task CreateShipmentAsync_ValidShipment_ResponseIsDeserializedInExpectedFormat() {\n            // Given: We create a shipment\n            var shipmentRequest = new ShipmentRequest {\n                Tracking = new TrackingObject {\n                    Carrier = \"tracking-carrier\",\n                    Code = \"tracking-code\",\n                    Url = \"tracking-url\"\n                },\n                Testmode = true,\n                Lines = new List<ShipmentLineRequest> {\n                    new ShipmentLineRequest {\n                        Id = \"shipment-line-id\",\n                        Amount = new Amount(Currency.EUR, 50),\n                        Quantity = 1\n                    }\n                }\n            };\n            const string orderId = \"order-id\";\n            const string expectedPartialRequest = @\"{\"\"tracking\"\":{\"\"carrier\"\":\"\"tracking-carrier\"\",\"\"code\"\":\"\"tracking-code\"\",\"\"url\"\":\"\"tracking-url\"\"},\"\"lines\"\":[{\"\"id\"\":\"\"shipment-line-id\"\",\"\"quantity\"\":1,\"\"amount\"\":{\"\"currency\"\":\"\"EUR\"\",\"\"value\"\":\"\"50.00\"\"}}],\"\"testmode\"\":true}\";\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Post,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}/shipments\",\n                DefaultShipmentJsonToReturn,\n                expectedPartialRequest);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            ShipmentResponse shipmentResponse = await shipmentClient.CreateShipmentAsync(orderId, shipmentRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            shipmentResponse.ShouldNotBeNull();\n            shipmentResponse.OrderId.ShouldBe(orderId);\n            shipmentResponse.Tracking!.Carrier.ShouldBe(shipmentRequest.Tracking.Carrier);\n            shipmentResponse.Tracking.Code.ShouldBe(shipmentRequest.Tracking.Code);\n            shipmentResponse.Tracking.Url.ShouldBe(shipmentRequest.Tracking.Url);\n        }\n\n        [Theory]\n        [InlineData(\"orders/order-id/shipments/shipment-id\", false)]\n        [InlineData(\"orders/order-id/shipments/shipment-id?testmode=true\", true)]\n        public async Task GetShipmentAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string expectedUrl, bool testModeParameter) {\n            // Given: We retrieve a shipment\n            const string orderId = \"order-id\";\n            const string shipmentId = \"shipment-id\";\n\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}{expectedUrl}\")\n                .Respond(\"application/json\", DefaultShipmentJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            ShipmentResponse shipmentResponse = await shipmentClient.GetShipmentAsync(orderId, shipmentId, testModeParameter);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            shipmentResponse.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(\"orders/order-id/shipments\", false)]\n        [InlineData(\"orders/order-id/shipments?testmode=true\", true)]\n        public async Task GetShipmentsListAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string expectedUrl, bool testModeParameter) {\n            // Given: We retrieve the list of shipments\n            const string orderId = \"order-id\";\n\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}{expectedUrl}\")\n                .Respond(\"application/json\", DefaultShipmentJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var shipmentListResponse = await shipmentClient.GetShipmentListAsync(orderId, testModeParameter);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            shipmentListResponse.ShouldNotBeNull();\n        }\n\n        [Fact]\n        public async Task UpdateShipmentAsync_ValidUpdateShipmentRequest_ResponseIsDeserializedInExpectedFormat() {\n            // Given: We create a shipment\n            var updateShipmentRequest = new ShipmentUpdateRequest {\n                Tracking = new TrackingObject {\n                    Carrier = \"tracking-carrier\",\n                    Code = \"tracking-code\",\n                    Url = \"tracking-url\"\n                },\n                Testmode = true\n            };\n            const string orderId = \"order-id\";\n            const string shipmentId = \"shipment-id\";\n            const string expectedPartialRequest = @\"{\"\"tracking\"\":{\"\"carrier\"\":\"\"tracking-carrier\"\",\"\"code\"\":\"\"tracking-code\"\",\"\"url\"\":\"\"tracking-url\"\"},\"\"testmode\"\":true}\";\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Patch,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}orders/{orderId}/shipments/{shipmentId}\",\n                DefaultShipmentJsonToReturn,\n                expectedPartialRequest);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            ShipmentResponse shipmentResponse = await shipmentClient.UpdateShipmentAsync(orderId, shipmentId, updateShipmentRequest);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            shipmentResponse.ShouldNotBeNull();\n            shipmentResponse.OrderId.ShouldBe(orderId);\n            shipmentResponse.Tracking!.Carrier.ShouldBe(updateShipmentRequest.Tracking.Carrier);\n            shipmentResponse.Tracking.Code.ShouldBe(updateShipmentRequest.Tracking.Code);\n            shipmentResponse.Tracking.Url.ShouldBe(updateShipmentRequest.Tracking.Url);\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateShipmentAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await shipmentClient.CreateShipmentAsync(orderId, new ShipmentRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetShipmentAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await shipmentClient.GetShipmentAsync(orderId, \"shipment-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetShipmentAsync_NoShipmentIdIsGiven_ArgumentExceptionIsThrown(string? shipmentId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await shipmentClient.GetShipmentAsync(\"order-id\", shipmentId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'shipmentId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetShipmentsListAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await shipmentClient.GetShipmentListAsync(orderId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateShipmentAsync_NoOrderIdIsGiven_ArgumentExceptionIsThrown(string? orderId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"api-key\", httpClient);\n            var updateRequest = new ShipmentUpdateRequest {\n                Tracking = new TrackingObject {\n                    Carrier = \"carrier\",\n                    Code = \"code\"\n                }\n            };\n\n            // When: We send the request\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>\n#pragma warning disable CS8604 // Possible null reference argument.\n                await shipmentClient.UpdateShipmentAsync(orderId, \"shipment-id\", updateRequest));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'orderId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateShipmentAsync_NoShipmentIdIsGiven_ArgumentExceptionIsThrown(string? shipmentId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            ShipmentClient shipmentClient = new ShipmentClient(\"api-key\", httpClient);\n            var updateRequest = new ShipmentUpdateRequest {\n                Tracking = new TrackingObject {\n                    Carrier = \"carrier\",\n                    Code = \"code\"\n                }\n            };\n\n            // When: We send the request\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>\n#pragma warning disable CS8604 // Possible null reference argument.\n                await shipmentClient.UpdateShipmentAsync(\"order-id\", shipmentId, updateRequest));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'shipmentId' is null or empty\");\n        }\n\n        private const string DefaultShipmentJsonToReturn = @\"{\n     \"\"resource\"\": \"\"shipment\"\",\n     \"\"id\"\": \"\"shipment-id\"\",\n     \"\"orderId\"\": \"\"order-id\"\",\n     \"\"createdAt\"\": \"\"2018-08-09T14:33:54+00:00\"\",\n     \"\"tracking\"\": {\n         \"\"carrier\"\": \"\"tracking-carrier\"\",\n         \"\"code\"\": \"\"tracking-code\"\",\n         \"\"url\"\": \"\"tracking-url\"\"\n     },\n     \"\"lines\"\": [\n         {\n             \"\"resource\"\": \"\"orderline\"\",\n             \"\"id\"\": \"\"odl_dgtxyl\"\",\n             \"\"orderId\"\": \"\"ord_pbjz8x\"\",\n             \"\"name\"\": \"\"LEGO 42083 Bugatti Chiron\"\",\n             \"\"sku\"\": \"\"5702016116977\"\",\n             \"\"type\"\": \"\"physical\"\",\n             \"\"status\"\": \"\"shipping\"\",\n             \"\"metadata\"\": null,\n             \"\"isCancelable\"\": true,\n             \"\"quantity\"\": 1,\n             \"\"amountShipped\"\": {\n                 \"\"value\"\": \"\"329.99\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"unitPrice\"\": {\n                 \"\"value\"\": \"\"399.00\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"vatRate\"\": \"\"21.00\"\",\n             \"\"vatAmount\"\": {\n                 \"\"value\"\": \"\"51.89\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"discountAmount\"\": {\n                 \"\"value\"\": \"\"100.00\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"totalAmount\"\": {\n                 \"\"value\"\": \"\"299.00\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"createdAt\"\": \"\"2018-08-02T09:29:56+00:00\"\",\n             \"\"_links\"\": {\n                 \"\"productUrl\"\": {\n                     \"\"href\"\": \"\"https://shop.lego.com/nl-NL/Bugatti-Chiron-42083\"\",\n                     \"\"type\"\": \"\"text/html\"\"\n                 },\n                 \"\"imageUrl\"\": {\n                     \"\"href\"\": \"\"https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$\"\",\n                     \"\"type\"\": \"\"text/html\"\"\n                 }\n             }\n         },\n         {\n             \"\"resource\"\": \"\"orderline\"\",\n             \"\"id\"\": \"\"odl_jp31jz\"\",\n             \"\"orderId\"\": \"\"ord_pbjz8x\"\",\n             \"\"name\"\": \"\"LEGO 42056 Porsche 911 GT3 RS\"\",\n             \"\"sku\"\": \"\"5702015594028\"\",\n             \"\"type\"\": \"\"physical\"\",\n             \"\"status\"\": \"\"completed\"\",\n             \"\"metadata\"\": null,\n             \"\"isCancelable\"\": false,\n             \"\"quantity\"\": 1,\n             \"\"unitPrice\"\": {\n                 \"\"value\"\": \"\"329.99\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"vatRate\"\": \"\"21.00\"\",\n             \"\"vatAmount\"\": {\n                 \"\"value\"\": \"\"57.27\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"totalAmount\"\": {\n                 \"\"value\"\": \"\"329.99\"\",\n                 \"\"currency\"\": \"\"EUR\"\"\n             },\n             \"\"createdAt\"\": \"\"2018-08-02T09:29:56+00:00\"\",\n             \"\"_links\"\": {\n                 \"\"productUrl\"\": {\n                     \"\"href\"\": \"\"https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056\"\",\n                     \"\"type\"\": \"\"text/html\"\"\n                 },\n                 \"\"imageUrl\"\": {\n                     \"\"href\"\": \"\"https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$\"\",\n                     \"\"type\"\": \"\"text/html\"\"\n                 }\n             }\n         }\n     ],\n     \"\"_links\"\": {\n         \"\"self\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/order/ord_kEn1PlbGa/shipments/shp_3wmsgCJN4U\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"order\"\": {\n             \"\"href\"\": \"\"https://api.mollie.com/v2/orders/ord_kEn1PlbGa\"\",\n             \"\"type\"\": \"\"application/hal+json\"\"\n         },\n         \"\"documentation\"\": {\n             \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/shipments-api/get-shipment\"\",\n             \"\"type\"\": \"\"text/html\"\"\n         }\n     }\n }\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/SubscriptionClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Subscription.Request;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client {\n    public class SubscriptionClientTests : BaseClientTests {\n        [Theory]\n        [InlineData(null, null, null,false, \"\")]\n        [InlineData(\"from\", null, null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, null, false, \"?from=from&limit=50\")]\n        [InlineData(null, null,null, true, \"?testmode=true\")]\n        [InlineData(null, null,\"profile-id\", true, \"?profileId=profile-id\")]\n        public async Task GetSubscriptionListAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string? from, int? limit, string? profileId, bool testmode, string expectedQueryString) {\n            // Given: We retrieve a list of subscriptions\n            const string customerId = \"customer-id\";\n\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}customers/customer-id/subscriptions{expectedQueryString}\")\n                .Respond(\"application/json\", DefaultSubscriptionJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await subscriptionClient.GetSubscriptionListAsync(customerId, from, limit, profileId, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(null, null, null,false, \"\")]\n        [InlineData(\"from\", null, null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, null, false, \"?from=from&limit=50\")]\n        [InlineData(null, null,null, true, \"?testmode=true\")]\n        [InlineData(null, null,\"profile-id\", true, \"?profileId=profile-id\")]\n        public async Task GetAllSubscriptionList_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string? from, int? limit, string? profileId, bool testmode, string expectedQueryString) {\n            // Given: We retrieve a list of subscriptions\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}subscriptions{expectedQueryString}\")\n                .Respond(\"application/json\", DefaultSubscriptionJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await subscriptionClient.GetAllSubscriptionList(from, limit, profileId, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(\"customers/customer-id/subscriptions/subscription-id\", false)]\n        [InlineData(\"customers/customer-id/subscriptions/subscription-id?testmode=true\", true)]\n        public async Task GetSubscriptionAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string expectedUrl, bool testModeParameter) {\n            // Given: We retrieve a subscriptions\n            const string customerId = \"customer-id\";\n            const string subscriptionId = \"subscription-id\";\n\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}{expectedUrl}\")\n                .Respond(\"application/json\", DefaultSubscriptionJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await subscriptionClient.GetSubscriptionAsync(customerId, subscriptionId, testModeParameter);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Fact]\n        public async Task RevokeMandate_TestmodeIsTrue_RequestContainsTestmodeModel() {\n            // Given: We make a request to retrieve a payment with embedded refunds\n            const string customerId = \"customer-id\";\n            const string subscriptionId = \"subscription-id\";\n\n            string expectedContent = \"\\\"testmode\\\":true\";\n            var mockHttp = CreateMockHttpMessageHandler(\n                HttpMethod.Delete,\n                $\"{BaseMollieClient.DefaultBaseApiEndPoint}customers/{customerId}/subscriptions/{subscriptionId}\",\n                DefaultSubscriptionJsonToReturn,\n                expectedContent);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            await subscriptionClient.CancelSubscriptionAsync(customerId, subscriptionId, true);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n        }\n\n        [Theory]\n        [InlineData(null, null, false, \"\")]\n        [InlineData(\"from\", null, false, \"?from=from\")]\n        [InlineData(\"from\", 50, false, \"?from=from&limit=50\")]\n        [InlineData(null, null,true, \"?testmode=true\")]\n        public async Task GetSubscriptionPaymentListAsync_TestModeParameterCase_QueryStringOnlyContainsTestModeParameterIfTrue(string? from, int? limit, bool testmode, string expectedQueryString) {\n            // Given: We retrieve a list of subscriptions\n            const string customerId = \"customer-id\";\n            const string subscriptionId = \"subscription-id\";\n            var mockHttp = new MockHttpMessageHandler();\n            mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}customers/{customerId}/subscriptions/{subscriptionId}/payments{expectedQueryString}\")\n                .Respond(\"application/json\", DefaultSubscriptionJsonToReturn);\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"abcde\", httpClient);\n\n            // When: We send the request\n            var result = await subscriptionClient.GetSubscriptionPaymentListAsync(customerId, subscriptionId, from, limit, testmode);\n\n            // Then\n            mockHttp.VerifyNoOutstandingExpectation();\n            result.ShouldNotBeNull();\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSubscriptionListAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.GetSubscriptionListAsync(customerId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSubscriptionAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.GetSubscriptionAsync(customerId, \"subscription-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSubscriptionAsync_NoSubscriptionIdIsGiven_ArgumentExceptionIsThrown(string? subscriptionId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.GetSubscriptionAsync(\"customer-Id\", subscriptionId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'subscriptionId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CreateSubscriptionAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n            var subscriptionRequest = new SubscriptionRequest {\n                Amount = new Amount(Currency.EUR, \"100.00\"),\n                Times = 5,\n                Interval = \"1 month\",\n                Description = $\"Subscription {Guid.NewGuid()}\", // Subscriptions must have a unique name\n                WebhookUrl = \"http://www.google.nl\",\n                StartDate = DateTime.Now.AddDays(1),\n            };\n\n            // When: We send the request\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () =>\n#pragma warning disable CS8604 // Possible null reference argument.\n                await subscriptionClient.CreateSubscriptionAsync(customerId, subscriptionRequest));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CancelSubscriptionAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.CancelSubscriptionAsync(customerId, \"subscription-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task CancelSubscriptionAsync_NoSubscriptionIdIsGiven_ArgumentExceptionIsThrown(string? subscriptionId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.CancelSubscriptionAsync(\"customer-Id\", subscriptionId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'subscriptionId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateSubscriptionAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.UpdateSubscriptionAsync(customerId, \"subscription-id\", new SubscriptionUpdateRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task UpdateSubscriptionAsync_NoSubscriptionIdIsGiven_ArgumentExceptionIsThrown(string? subscriptionId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.UpdateSubscriptionAsync(\"customer-Id\", subscriptionId, new SubscriptionUpdateRequest()));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'subscriptionId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSubscriptionPaymentListAsync_NoCustomerIdIsGiven_ArgumentExceptionIsThrown(string? customerId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.GetSubscriptionPaymentListAsync(customerId, \"subscription-id\"));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'customerId' is null or empty\");\n        }\n\n        [Theory]\n        [InlineData(\"\")]\n        [InlineData(\" \")]\n        [InlineData(null)]\n        public async Task GetSubscriptionPaymentListAsync_NoSubscriptionIdIsGiven_ArgumentExceptionIsThrown(string? subscriptionId) {\n            // Arrange\n            var mockHttp = new MockHttpMessageHandler();\n            HttpClient httpClient = mockHttp.ToHttpClient();\n            var subscriptionClient = new SubscriptionClient(\"api-key\", httpClient);\n\n            // When: We send the request\n#pragma warning disable CS8604 // Possible null reference argument.\n            var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await subscriptionClient.GetSubscriptionPaymentListAsync(\"customer-Id\", subscriptionId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n            // Then\n            exception.Message.ShouldBe(\"Required URL argument 'subscriptionId' is null or empty\");\n        }\n\n        private const string DefaultSubscriptionJsonToReturn = @\"{\n    \"\"resource\"\": \"\"subscription\"\",\n    \"\"id\"\": \"\"subscription-id\"\",\n    \"\"mode\"\": \"\"live\"\",\n    \"\"createdAt\"\": \"\"2016-06-01T12:23:34+00:00\"\",\n    \"\"status\"\": \"\"active\"\",\n    \"\"amount\"\": {\n        \"\"value\"\": \"\"25.00\"\",\n        \"\"currency\"\": \"\"EUR\"\"\n    },\n    \"\"times\"\": 4,\n    \"\"timesRemaining\"\": 4,\n    \"\"interval\"\": \"\"3 months\"\",\n    \"\"startDate\"\": \"\"2016-06-01\"\",\n    \"\"nextPaymentDate\"\": \"\"2016-09-01\"\",\n    \"\"description\"\": \"\"Quarterly payment\"\",\n    \"\"method\"\": null,\n    \"\"mandateId\"\": \"\"mdt_38HS4fsS\"\",\n    \"\"webhookUrl\"\": \"\"https://webshop.example.org/payments/webhook\"\",\n    \"\"metadata\"\": {\n        \"\"plan\"\": \"\"small\"\"\n    }\n}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/TerminalClientTests.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Terminal.Response;\nusing RichardSzalay.MockHttp;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class TerminalClientTests : BaseClientTests {\n    [Theory]\n    [InlineData(\"\")]\n    [InlineData(\" \")]\n    [InlineData(null)]\n    public async Task GetTerminalAsync_NoTerminalIdIsGiven_ArgumentExceptionIsThrown(string? terminalId) {\n        // Given\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var terminalClient = new TerminalClient(\"api-key\", httpClient);\n\n        // When\n#pragma warning disable CS8604 // Possible null reference argument.\n        var exception = await Assert.ThrowsAsync<ArgumentException>(async () => await terminalClient.GetTerminalAsync(terminalId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n        // Then\n        exception.Message.ShouldBe(\"Required URL argument 'terminalId' is null or empty\");\n    }\n\n    [Fact]\n    public async Task GetTerminalAsync_WithTerminalId_ResponseIsDeserializedInExpectedFormat() {\n        // Given\n        const string terminalId = \"terminal-id\";\n        const string description = \"terminal-description\";\n        const string serialNumber = \"serial-number\";\n        const string brand = \"brand\";\n        const string model = \"model\";\n        string jsonToReturnInMockResponse = CreateTerminalJsonResponse(terminalId, description, serialNumber, brand, model);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}terminals/{terminalId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var terminalClient = new TerminalClient(\"abcde\", httpClient);\n\n        // When\n        TerminalResponse response = await terminalClient.GetTerminalAsync(terminalId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.Id.ShouldBe(terminalId);\n        response.Description.ShouldBe(description);\n        response.SerialNumber.ShouldBe(serialNumber);\n        response.Brand.ShouldBe(brand);\n        response.Model.ShouldBe(model);\n        response.Links.ShouldNotBeNull();\n        response.Links.Self.ShouldNotBeNull();\n        response.Links.Self.Href.ShouldBe($\"https://api.mollie.com/v2/terminals/{terminalId}\");\n        response.Links.Documentation.ShouldNotBeNull();\n    }\n\n    [Theory]\n    [InlineData(true, \"?testmode=true\")]\n    [InlineData(false, \"\")]\n    public async Task GetTerminalAsync_QueryParameterOptions_CorrectParametersAreAdded(bool testMode, string expectedQueryString) {\n        // Given\n        const string terminalId = \"terminal-id\";\n        const string description = \"terminal-description\";\n        const string serialNumber = \"serial-number\";\n        const string brand = \"brand\";\n        const string model = \"model\";\n        string jsonToReturnInMockResponse = CreateTerminalJsonResponse(terminalId, description, serialNumber, brand, model);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}terminals/{terminalId}{expectedQueryString}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var terminalClient = new TerminalClient(\"abcde\", httpClient);\n\n        // When\n        await terminalClient.GetTerminalAsync(terminalId, testMode);\n\n        // Then\n        mockHttp.VerifyNoOutstandingRequest();\n    }\n\n    [Theory]\n    [InlineData(null, null, null, false, \"\")]\n    [InlineData(\"from\", null, null, false, \"?from=from\")]\n    [InlineData(\"from\", 50, null, false, \"?from=from&limit=50\")]\n    [InlineData(null, null, \"profile-id\", false, \"?profileId=profile-id\")]\n    [InlineData(null, null, \"profile-id\", true, \"?profileId=profile-id&testmode=true\")]\n    public async Task GetTerminalListAsync_QueryParameterOptions_CorrectParametersAreAdded(string? from, int? limit, string? profileId, bool testmode, string expectedQueryString) {\n        // Given\n        string jsonToReturnInMockResponse = CreateTerminalListJsonResponse();\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}terminals{expectedQueryString}\",\n            jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var terminalClient = new TerminalClient(\"abcde\", httpClient);\n\n        // When\n        await terminalClient.GetTerminalListAsync(from, limit, profileId, testmode);\n\n        // Then\n        mockHttp.VerifyNoOutstandingRequest();\n    }\n\n    [Fact]\n    public async Task GetTerminalListAsync_ResponseIsDeserializedInExpectedFormat() {\n        // Given\n        string jsonToReturnInMockResponse = CreateTerminalListJsonResponse();\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}terminals\",\n            jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var terminalClient = new TerminalClient(\"abcde\", httpClient);\n\n        // When\n        ListResponse<TerminalResponse> response = await terminalClient.GetTerminalListAsync();\n\n        // Then\n        response.Count.ShouldBe(1);\n        response.Items.Count.ShouldBe(response.Count);\n        response.Links.ShouldNotBeNull();\n        response.Links.Self.Href.ShouldNotBeNull();\n    }\n\n    private string CreateTerminalListJsonResponse() {\n        string terminalJson = CreateTerminalJsonResponse(\"terminal-id\", \"description\", \"serial\", \"brand\", \"model\");\n\n        return @$\"{{\n    \"\"count\"\": 1,\n    \"\"_embedded\"\": {{\n        \"\"terminals\"\": [\n            {terminalJson}\n        ]\n    }},\n    \"\"_links\"\": {{\n        \"\"self\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/terminalss?limit=5\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"previous\"\": null,\n        \"\"next\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/terminals?from=term_7MgL4wea46qkRcoTZjWEH&limit=5\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/terminals-api/list-terminals\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }}\n}}\";\n    }\n\n    private string CreateTerminalJsonResponse(string terminalId, string description, string serialNumber, string brand, string model) {\n        return $@\"{{\n    \"\"id\"\": \"\"{terminalId}\"\",\n    \"\"profileId\"\": \"\"pfl_QkEhN94Ba\"\",\n    \"\"status\"\": \"\"active\"\",\n    \"\"brand\"\": \"\"{brand}\"\",\n    \"\"model\"\": \"\"{model}\"\",\n    \"\"serialNumber\"\": \"\"{serialNumber}\"\",\n    \"\"currency\"\": \"\"EUR\"\",\n    \"\"description\"\": \"\"{description}\"\",\n    \"\"createdAt\"\": \"\"2022-02-12T11:58:35.0Z\"\",\n    \"\"updatedAt\"\": \"\"2022-11-15T13:32:11+00:00\"\",\n    \"\"deactivatedAt\"\": \"\"2022-02-12T12:13:35.0Z\"\",\n    \"\"_links\"\": {{\n        \"\"self\"\": {{\n            \"\"href\"\": \"\"https://api.mollie.com/v2/terminals/{terminalId}\"\",\n            \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"documentation\"\": {{\n            \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/terminals-api/get-terminal\"\",\n            \"\"type\"\": \"\"text/html\"\"\n        }}\n    }}\n}}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/WalletClientTest.cs",
    "content": "﻿using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Shouldly;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models.Wallet.Request;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class WalletClientTest : BaseClientTests {\n    private const string defaultApplePayPaymentSessionResponse = @\"{\n        \"\"epochTimestamp\"\": 1555507053169,\n        \"\"expiresAt\"\": 1555510653169,\n        \"\"merchantSessionIdentifier\"\": \"\"SSH2EAF8AFAEAA94DEEA898162A5DAFD36E_916523AAED1343F5BC5815E12BEE9250AFFDC1A17C46B0DE5A943F0F94927C24\"\",\n        \"\"nonce\"\": \"\"0206b8db\"\",\n        \"\"merchantIdentifier\"\": \"\"BD62FEB196874511C22DB28A9E14A89E3534C93194F73EA417EC566368D391EB\"\",\n        \"\"domainName\"\": \"\"pay.example.org\"\",\n        \"\"displayName\"\": \"\"Chuck Norris's Store\"\",\n        \"\"signature\"\": \"\"308006092a864886f7...8cc030ad3000000000000\"\"\n    }\";\n\n    [Fact]\n    public async Task RequestApplePayPaymentSessionAsync_ResponseIsDeserializedInExpectedFormat() {\n        // Arrange\n        var request = new ApplePayPaymentSessionRequest() {\n            Domain = \"pay.mywebshop.com\",\n            ValidationUrl = \"https://apple-pay-gateway-cert.apple.com/paymentservices/paymentSession\"\n        };\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Post,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}wallets/applepay/sessions\",\n            defaultApplePayPaymentSessionResponse);\n        using var walletClient = new WalletClient(\"abcde\", mockHttp.ToHttpClient());\n\n        // Act\n        var response = await walletClient.RequestApplePayPaymentSessionAsync(request);\n\n        // Assert\n        response.EpochTimestamp.ShouldBe(DateTimeOffset.FromUnixTimeMilliseconds(1555507053169).UtcDateTime);\n        response.ExpiresAt.ShouldBe(DateTimeOffset.FromUnixTimeMilliseconds(1555510653169).UtcDateTime);\n        response.MerchantSessionIdentifier.ShouldBe(\"SSH2EAF8AFAEAA94DEEA898162A5DAFD36E_916523AAED1343F5BC5815E12BEE9250AFFDC1A17C46B0DE5A943F0F94927C24\");\n        response.Nonce.ShouldBe(\"0206b8db\");\n        response.MerchantIdentifier.ShouldBe(\"BD62FEB196874511C22DB28A9E14A89E3534C93194F73EA417EC566368D391EB\");\n        response.DomainName.ShouldBe(\"pay.example.org\");\n        response.DisplayName.ShouldBe(\"Chuck Norris's Store\");\n        response.Signature.ShouldBe(\"308006092a864886f7...8cc030ad3000000000000\");\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/WebhookClientTests.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.List.Response;\nusing Mollie.Api.Models.Webhook;\nusing Mollie.Api.Models.Webhook.Request;\nusing Mollie.Api.Models.Webhook.Response;\nusing RichardSzalay.MockHttp;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class WebhookClientTests : BaseClientTests {\n    [Fact]\n    public async Task CreateWebhookAsync_WebhookWithRequiredParameters_ResponseIsDeserializedInExpectedFormat() {\n        // Given: we create a webhook request with only the required parameters\n        string webhookId = \"webhook-id\";\n        WebhookRequest request = new() {\n            Name = \"my-webhook\",\n            Url = \"https://github.com/Viincenttt/MollieApi/-updated\",\n            EventTypes = [WebhookEventTypes.PaymentLinkPaid],\n            Testmode = true\n        };\n        string jsonToReturnInMockResponse = CreateWebhookJsonResponse(webhookId, request.Name, request.Url, [WebhookEventTypes.PaymentLinkPaid]);\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Post,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}webhooks\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new WebhookClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        WebhookResponse response = await client.CreateWebhookAsync(request);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.ShouldNotBeNull();\n        response.Id.ShouldBe(webhookId);\n        response.Resource.ShouldBe(\"webhook\");\n        response.Name.ShouldBe(request.Name);\n        response.Url.ShouldBe(request.Url);\n        response.EventTypes.ShouldNotBeNull();\n        response.EventTypes.ShouldBe(new[] { WebhookEventTypes.PaymentLinkPaid });\n    }\n\n    [Fact]\n    public async Task UpdateWebhookAsync_WebhookWithRequiredParameters_ResponseIsDeserializedInExpectedFormat() {\n        // Given: we update webhook with only the required parameters\n        string webhookId = \"webhook-id\";\n        WebhookRequest request = new() {\n            Name = \"my-webhook\",\n            Url = \"https://github.com/Viincenttt/MollieApi/-updated\",\n            EventTypes = [WebhookEventTypes.PaymentLinkPaid],\n            Testmode = true\n        };\n        string jsonToReturnInMockResponse = CreateWebhookJsonResponse(webhookId, request.Name, request.Url, [WebhookEventTypes.PaymentLinkPaid]);\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Patch,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}webhooks/{webhookId}\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new WebhookClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        WebhookResponse response = await client.UpdateWebhookAsync(webhookId, request);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.ShouldNotBeNull();\n        response.Id.ShouldBe(webhookId);\n        response.Resource.ShouldBe(\"webhook\");\n        response.Name.ShouldBe(request.Name);\n        response.Url.ShouldBe(request.Url);\n        response.EventTypes.ShouldNotBeNull();\n        response.EventTypes.ShouldBe(new[] { WebhookEventTypes.PaymentLinkPaid });\n    }\n\n    [Fact]\n    public async Task DeleteWebhookAsync_WebhookWithRequiredParameters_ResponseIsDeserializedInExpectedFormat() {\n        // Given\n        string webhookId = \"webhook-id\";\n        var mockHttp = CreateMockHttpMessageHandler(HttpMethod.Delete,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}webhooks/{webhookId}\", \"\");\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new WebhookClient(\"abcde\", httpClient);\n\n        // When: We send the request\n        await client.DeleteWebhookAsync(webhookId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n    }\n\n    [Theory]\n    [InlineData(\"\")]\n    [InlineData(\" \")]\n    [InlineData(null)]\n    public async Task GetWebhookAsync_NoWebhookIdIsGiven_ArgumentExceptionIsThrown(string? webhookId) {\n        // Given\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new WebhookClient(\"api-key\", httpClient);\n\n        // When\n#pragma warning disable CS8604 // Possible null reference argument.\n        var exception =\n            await Assert.ThrowsAsync<ArgumentException>(async () => await client.GetWebhookAsync(webhookId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n        // Then\n        exception.Message.ShouldBe(\"Required URL argument 'webhookId' is null or empty\");\n    }\n\n\n    [Fact]\n    public async Task GetWebhookAsync_WithWebhookId_ResponseIsDeserializedInExpectedFormat() {\n        // Given\n        const string webhookId = \"webhook-id\";\n        const string name = \"webhook-name\";\n        const string url = \"https://mollie.com/webhook\";\n        string[] eventTypes = [WebhookEventTypes.PaymentLinkPaid, WebhookEventTypes.SalesInvoiceCreated];\n        string jsonToReturnInMockResponse = CreateWebhookJsonResponse(webhookId, name, url, eventTypes);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}webhooks/{webhookId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var webhookClient = new WebhookClient(\"abcde\", httpClient);\n\n        // When\n        WebhookResponse response = await webhookClient.GetWebhookAsync(webhookId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingExpectation();\n        response.Id.ShouldBe(webhookId);\n        response.Resource.ShouldBe(\"webhook\");\n        response.Name.ShouldBe(name);\n        response.Url.ShouldBe(url);\n        response.EventTypes.ShouldNotBeNull();\n        response.EventTypes.ShouldBe(eventTypes);\n        response.ProfileId.ShouldBe(\"pfl_8XcSdLtrNK\");\n        response.CreatedAt.ShouldBe(DateTime.Parse(\"2024-12-06T10:09:56+00:00\"));\n        response.Status.ShouldBe(\"enabled\");\n        response.Mode.ShouldBe(Mode.Test);\n    }\n\n    [Theory]\n    [InlineData(true, \"?testmode=true\")]\n    [InlineData(false, \"\")]\n    public async Task GetWebhookAsync_QueryParameterOptions_CorrectParametersAreAdded(bool testMode, string expectedQueryString) {\n        // Given\n        const string webhookId = \"webhook-id\";\n        const string name = \"webhook-name\";\n        const string url = \"https://mollie.com/webhook\";\n        string[] eventTypes = [WebhookEventTypes.PaymentLinkPaid, WebhookEventTypes.SalesInvoiceCreated];\n        string jsonToReturnInMockResponse = CreateWebhookJsonResponse(webhookId, name, url, eventTypes);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}webhooks/{webhookId}{expectedQueryString}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var webhookClient = new WebhookClient(\"abcde\", httpClient);\n\n        // When\n        await webhookClient.GetWebhookAsync(webhookId, testMode);\n\n        // Then\n        mockHttp.VerifyNoOutstandingRequest();\n    }\n\n    [Theory]\n    [InlineData(null, null, false, \"\")]\n    [InlineData(\"from\", null, false, \"?from=from\")]\n    [InlineData(\"from\", 50, false, \"?from=from&limit=50\")]\n    public async Task GetWebhookListAsync_QueryParameterOptions_CorrectParametersAreAdded(string? from, int? limit, bool testmode, string expectedQueryString) {\n        // Given\n        string jsonToReturnInMockResponse = CreateWebhookListJsonResponse();\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}webhooks{expectedQueryString}\",\n            jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var webhookClient = new WebhookClient(\"abcde\", httpClient);\n\n        // When\n        await webhookClient.GetWebhookListAsync(from, limit, testmode);\n\n        // Then\n        mockHttp.VerifyNoOutstandingRequest();\n    }\n\n    [Fact]\n    public async Task GetWebhookListAsync_ResponseIsDeserializedInExpectedFormat() {\n        // Given\n        string jsonToReturnInMockResponse = CreateWebhookListJsonResponse();\n        var mockHttp = CreateMockHttpMessageHandler(\n            HttpMethod.Get,\n            $\"{BaseMollieClient.DefaultBaseApiEndPoint}webhooks\",\n            jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var webhookClient = new WebhookClient(\"abcde\", httpClient);\n\n        // When\n        ListResponse<WebhookResponse> response = await webhookClient.GetWebhookListAsync();\n\n        // Then\n        response.Count.ShouldBe(1);\n        response.Items.Count.ShouldBe(response.Count);\n        response.Links.ShouldNotBeNull();\n        response.Links.Self.Href.ShouldNotBeNull();\n    }\n\n    private string CreateWebhookListJsonResponse() {\n        string webhookJson = CreateWebhookJsonResponse(\"hook_5foxphpBru4xNPCDJJPzH\", \"Webhook 1\",\n            \"https://mollie.com/webhook1\", [WebhookEventTypes.PaymentLinkPaid]);\n\n        return $@\"{{\n  \"\"_embedded\"\": {{\n    \"\"webhooks\"\": [\n      {webhookJson}\n    ]\n  }},\n  \"\"count\"\": 1,\n  \"\"_links\"\": {{\n    \"\"documentation\"\": {{\n      \"\"href\"\": \"\"https://docs.mollie.com/reference/list-webhook\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    }},\n    \"\"self\"\": {{\n      \"\"href\"\": \"\"https://api.mollie.localhost/v2/webhooks?from=hook_yjtBMWDCGw5YFSPQ3HPzH&limit=2\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }},\n    \"\"previous\"\": {{\n      \"\"href\"\": \"\"https://api.mollie.localhost/v2/webhooks?from=hook_5foxphpBru4xNPCDJJPzH&limit=2\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }},\n    \"\"next\"\": {{\n      \"\"href\"\": \"\"https://api.mollie.localhost/v2/webhooks?from=hook_fTqARmWsfs9oXvKbZEPzH&limit=2\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }}\n  }}\n}}\";\n    }\n\n    private string CreateWebhookJsonResponse(string webhookId, string name, string url, string[] eventTypes) {\n        var jsonToReturnInMockResponse = string.Join(\",\", eventTypes.Select(x => $\"\\\"{x}\\\"\"));\n\n        return $@\"{{\n  \"\"resource\"\": \"\"webhook\"\",\n  \"\"id\"\": \"\"{webhookId}\"\",\n  \"\"url\"\": \"\"{url}\"\",\n  \"\"profileId\"\": \"\"pfl_8XcSdLtrNK\"\",\n  \"\"createdAt\"\": \"\"2024-12-06T10:09:56+00:00\"\",\n  \"\"name\"\": \"\"{name}\"\",\n  \"\"status\"\": \"\"enabled\"\",\n  \"\"mode\"\": \"\"test\"\",\n  \"\"eventTypes\"\": [{jsonToReturnInMockResponse}],\n  \"\"_links\"\": {{\n    \"\"documentation\"\": {{\n      \"\"href\"\": \"\"https://docs.mollie.com/reference/get-webhook\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    }}\n  }}\n}}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Client/WebhookEventClientTests.cs",
    "content": "using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Mollie.Api.Client;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.PaymentLink.Response;\nusing RichardSzalay.MockHttp;\nusing Shouldly;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Client;\n\npublic class WebhookEventClientTests : BaseClientTests {\n    [Theory]\n    [InlineData(\"\")]\n    [InlineData(\" \")]\n    [InlineData(null)]\n    public async Task GetWebhookEventAsync_NoWebhookIdIsGiven_ArgumentExceptionIsThrown(string? webhookEventId) {\n        // Given\n        var mockHttp = new MockHttpMessageHandler();\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var client = new WebhookEventClient(\"api-key\", httpClient);\n\n        // When\n#pragma warning disable CS8604 // Possible null reference argument.\n        var exception =\n            await Assert.ThrowsAsync<ArgumentException>(async () => await client.GetWebhookEventAsync(webhookEventId));\n#pragma warning restore CS8604 // Possible null reference argument.\n\n        // Then\n        exception.Message.ShouldBe(\"Required URL argument 'webhookEventId' is null or empty\");\n    }\n\n\n    [Theory]\n    [InlineData(true, \"?testmode=true\")]\n    [InlineData(false, \"\")]\n    public async Task GetWebhookEventAsync_QueryParameterOptions_CorrectParametersAreAdded(bool testMode, string expectedQueryString) {\n        // Given\n        const string webhookEventId = \"webhook-event-id\";\n        const string type = \"payment-link.paid\";\n        const string paymentLinkEntityId = \"pl_qng5gbbv8NAZ5gpM5ZYgx\";\n        string entityJson = CreatePaymentLinkJsonResponse(paymentLinkEntityId);\n        string jsonToReturnInMockResponse = CreateWebhookEventJsonResponse(webhookEventId, type, paymentLinkEntityId, entityJson);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}events/{webhookEventId}{expectedQueryString}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var webhookClient = new WebhookEventClient(\"abcde\", httpClient);\n\n        // When\n        await webhookClient.GetWebhookEventAsync(webhookEventId, testMode);\n\n        // Then\n        mockHttp.VerifyNoOutstandingRequest();\n    }\n\n    [Fact]\n    public async Task GetWebhookEventAsync_With_Generic_Parameter_ResponseIsDeserializedInExpectedFormat() {\n        // Given\n        const string webhookEventId = \"webhook-event-id\";\n        const string type = \"payment-link.paid\";\n        const string paymentLinkEntityId = \"pl_qng5gbbv8NAZ5gpM5ZYgx\";\n        string entityJson = CreatePaymentLinkJsonResponse(paymentLinkEntityId);\n        string jsonToReturnInMockResponse = CreateWebhookEventJsonResponse(webhookEventId, type, paymentLinkEntityId, entityJson);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}events/{webhookEventId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var webhookClient = new WebhookEventClient(\"abcde\", httpClient);\n\n        // When\n        var response = await webhookClient.GetWebhookEventAsync<PaymentLinkResponse>(webhookEventId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingRequest();\n        response.Id.ShouldBe(webhookEventId);\n        response.Type.ShouldBe(type);\n        response.CreatedAt.ShouldBe(new DateTime(2024, 12, 16, 15, 57, 04, DateTimeKind.Utc));\n        response.EntityId.ShouldBe(paymentLinkEntityId);\n        response.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/guides/webhooks\");\n        response.Links.Entity.Href.ShouldBe($\"/v2/payment-links/{paymentLinkEntityId}\");\n        response.Links.Self.Href.ShouldBe($\"https://api.mollie.com/v2/events/{webhookEventId}\");\n        response.Entity.ShouldNotBeNull();\n        response.Entity.Id.ShouldBe(paymentLinkEntityId);\n        response.Entity.Resource.ShouldBe(\"payment-link\");\n        response.Entity.ProfileId.ShouldBe(\"pfl_D96wnsu869\");\n        response.Entity.Mode.ShouldBe(Mode.Live);\n        response.Entity.Description.ShouldBe(\"Bicycle tires\");\n        response.Entity.Amount!.Currency.ShouldBe(\"EUR\");\n        response.Entity.Amount!.Value.ShouldBe(\"24.95\");\n        response.Entity.MinimumAmount.ShouldBeNull();\n        response.Entity.Archived.ShouldBeFalse();\n    }\n\n    [Fact]\n    public async Task GetWebhookEventAsync_ResponseIsDeserializedInExpectedFormat() {\n        // Given\n        const string webhookEventId = \"webhook-event-id\";\n        const string type = \"payment-link.paid\";\n        const string paymentLinkEntityId = \"pl_qng5gbbv8NAZ5gpM5ZYgx\";\n        string entityJson = CreatePaymentLinkJsonResponse(paymentLinkEntityId);\n        string jsonToReturnInMockResponse = CreateWebhookEventJsonResponse(webhookEventId, type, paymentLinkEntityId, entityJson);\n        var mockHttp = new MockHttpMessageHandler();\n        mockHttp.When($\"{BaseMollieClient.DefaultBaseApiEndPoint}events/{webhookEventId}\")\n            .With(request => request.Headers.Contains(\"Idempotency-Key\"))\n            .Respond(\"application/json\", jsonToReturnInMockResponse);\n        HttpClient httpClient = mockHttp.ToHttpClient();\n        var webhookClient = new WebhookEventClient(\"abcde\", httpClient);\n\n        // When\n        var response = await webhookClient.GetWebhookEventAsync(webhookEventId);\n\n        // Then\n        mockHttp.VerifyNoOutstandingRequest();\n        response.Id.ShouldBe(webhookEventId);\n        response.Type.ShouldBe(type);\n        response.CreatedAt.ShouldBe(new DateTime(2024, 12, 16, 15, 57, 04, DateTimeKind.Utc));\n        response.EntityId.ShouldBe(paymentLinkEntityId);\n        response.Links.Documentation.Href.ShouldBe(\"https://docs.mollie.com/guides/webhooks\");\n        response.Links.Entity.Href.ShouldBe($\"/v2/payment-links/{paymentLinkEntityId}\");\n        response.Links.Self.Href.ShouldBe($\"https://api.mollie.com/v2/events/{webhookEventId}\");\n    }\n\n    private string CreateWebhookEventJsonResponse(string webhookEventId, string type, string entityId, string entityJson) {\n        return $@\"{{\n  \"\"resource\"\": \"\"event\"\",\n  \"\"id\"\": \"\"{webhookEventId}\"\",\n  \"\"type\"\": \"\"{type}\"\",\n  \"\"entityId\"\": \"\"{entityId}\"\",\n  \"\"createdAt\"\": \"\"2024-12-16T15:57:04.0Z\"\",\n  \"\"_embedded\"\": {{\n    \"\"entity\"\": {entityJson}\n  }},\n  \"\"_links\"\": {{\n    \"\"self\"\": {{\n      \"\"href\"\": \"\"https://api.mollie.com/v2/events/{webhookEventId}\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }},\n    \"\"documentation\"\": {{\n      \"\"href\"\": \"\"https://docs.mollie.com/guides/webhooks\"\",\n      \"\"type\"\": \"\"text/html\"\"\n    }},\n    \"\"entity\"\": {{\n      \"\"href\"\": \"\"/v2/payment-links/{entityId}\"\",\n      \"\"type\"\": \"\"application/hal+json\"\"\n    }}\n  }}\n}}\";\n    }\n\n    private string CreatePaymentLinkJsonResponse(string entityId) {\n        return $@\"{{\n      \"\"resource\"\": \"\"payment-link\"\",\n      \"\"id\"\": \"\"{entityId}\"\",\n      \"\"profileId\"\": \"\"pfl_D96wnsu869\"\",\n      \"\"mode\"\": \"\"live\"\",\n      \"\"description\"\": \"\"Bicycle tires\"\",\n      \"\"amount\"\": {{\n        \"\"currency\"\": \"\"EUR\"\",\n        \"\"value\"\": \"\"24.95\"\"\n      }},\n      \"\"minimumAmount\"\": null,\n      \"\"archived\"\": false,\n      \"\"redirectUrl\"\": \"\"https://webshop.example.org/thanks\"\",\n      \"\"webhookUrl\"\": null,\n      \"\"reusable\"\": true,\n      \"\"createdAt\"\": \"\"2021-03-20T09:29:56.0Z\"\",\n      \"\"paidAt\"\": null,\n      \"\"expiresAt\"\": \"\"2023-06-06T11:00:00.0Z\"\",\n      \"\"allowedMethods\"\": null,\n      \"\"applicationFee\"\": null,\n      \"\"_links\"\": {{\n        \"\"self\"\": {{\n          \"\"href\"\": \"\"https://api.mollie.com/v2/payment-links/{entityId}\"\",\n          \"\"type\"\": \"\"application/hal+json\"\"\n        }},\n        \"\"paymentLink\"\": {{\n          \"\"href\"\": \"\"https://www.mollie.com/paymentscreen/example\"\",\n          \"\"type\"\": \"\"text/html\"\"\n        }},\n        \"\"documentation\"\": {{\n          \"\"href\"\": \"\"https://docs.mollie.com/reference/v2/payment-links-api/get-payment-link\"\",\n          \"\"type\"\": \"\"text/html\"\"\n        }}\n      }}\n    }}\";\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/DependencyInjectionTests.cs",
    "content": "﻿using System.Linq;\nusing System.Reflection;\nusing Shouldly;\nusing Microsoft.Extensions.DependencyInjection;\nusing Mollie.Api;\nusing Mollie.Api.Client.Abstract;\nusing Mollie.Api.Framework;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit;\n\npublic class DependencyInjectionTests\n{\n    [Fact]\n    public void AddMollieClient_ShouldRegisterAllApiInterfaces()\n    {\n        // Arrange\n        var serviceCollection = new ServiceCollection();\n        serviceCollection.AddMollieApi(options =>\n        {\n            options.ApiKey = \"access_api-key\";\n            options.ClientId = \"client-id\";\n            options.ClientSecret = \"client-secret\";\n            options.RetryPolicy = MollieHttpRetryPolicies.TransientHttpErrorRetryPolicy();\n        });\n\n        // Act\n        var serviceProvider = serviceCollection.BuildServiceProvider();\n\n        // Assert\n        var assembly = Assembly.GetAssembly(typeof(IPaymentClient));\n        var apiClientInterfaces = assembly!\n            .GetTypes()\n            .Where(type => type.Namespace == typeof(IPaymentClient).Namespace);\n        foreach (var apiClientInterface in apiClientInterfaces)\n        {\n            if (apiClientInterface != typeof(IBaseMollieClient))\n            {\n                var apiClientImplementation = serviceProvider.GetService(apiClientInterface);\n                apiClientImplementation.ShouldNotBeNull();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Extensions/DictionaryExtensionsTests.cs",
    "content": "﻿using System.Collections.Generic;\nusing Shouldly;\nusing Mollie.Api.Extensions;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Extensions\n{\n    public class DictionaryExtensionsTests\n    {\n        [Fact]\n        public void ToQueryString_WhenMultipleKeyValuePairsAreAdded_MultipleParametersAreAddedToQueryString()\n        {\n            // Arrange\n            var parameters = new Dictionary<string, string>()\n            {\n                {\"include\", \"issuers\"},\n                {\"testmode\", \"true\"}\n            };\n            var expected = \"?include=issuers&testmode=true\";\n\n            // Act\n            var result = parameters.ToQueryString();\n\n            // Assert\n            result.ShouldBe(expected);\n        }\n\n        [Fact]\n        public void ToQueryString_WhenDictionaryIsEmpty_QueryStringIsEmpty()\n        {\n            // Arrange\n            var parameters = new Dictionary<string, string>();\n            string expected = string.Empty;\n\n            // Act\n            var result = parameters.ToQueryString();\n\n            // Assert\n            result.ShouldBe(expected);\n        }\n\n        [Fact]\n        public void AddValueIfNotNullOrEmpty_ValueIsNotNull_ValueIsAdded()\n        {\n            // Arrange\n            var parameters = new Dictionary<string, string>();\n            var parameterName = \"include\";\n            var parameterValue = \"issuers\";\n\n            // Act\n            parameters.AddValueIfNotNullOrEmpty(parameterName, parameterValue);\n\n            // Assert\n            parameters.ShouldNotBeEmpty();\n            parameters[parameterName].ShouldBe(parameterValue);\n        }\n\n        [Fact]\n        public void AddValueIfNotNullOrEmpty_ValueIsEmpty_ValueIsNotAdded()\n        {\n            // Arrange\n            var parameters = new Dictionary<string, string>();\n\n            // Act\n            parameters.AddValueIfNotNullOrEmpty(\"include\", \"\");\n\n            // Assert\n            parameters.ShouldBeEmpty();\n        }\n\n        [Fact]\n        public void AddValueIfTrue_ValueIsTrue_ValueIsAdded()\n        {\n            // Arrange\n            var parameters = new Dictionary<string, string>();\n            var parameterName = \"testmode\";\n\n            // Act\n            parameters.AddValueIfTrue(parameterName, true);\n\n            // Assert\n            parameters.ShouldNotBeEmpty();\n            parameters[parameterName].ShouldBe(bool.TrueString.ToLower());\n        }\n\n        [Fact]\n        public void AddValueIfTrue_ValueIsFalse_ValueIsNotAdded()\n        {\n            // Arrange\n            var parameters = new Dictionary<string, string>();\n\n            // Act\n            parameters.AddValueIfTrue(\"testmode\", false);\n\n            // Assert\n            parameters.ShouldBeEmpty();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Framework/AmountConversionTests.cs",
    "content": "﻿using Mollie.Api.Models;\nusing System;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Framework {\n    public class AmountConversionTests {\n        [Fact]\n        public void InvalidAmountValueWillThrowInvalidCastException() {\n\n            // Initiate Amount with invalid decimal value\n            var amount = new Amount(Currency.EUR, \"NotAValidDecimal\");\n\n            // When: We implicitly cast Amount to decimal\n            // Then: An InvalidCastException will be thrown\n            Assert.Throws<InvalidCastException>(() => {\n                // ReSharper disable once UnusedVariable\n                decimal a = amount;\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Framework/Factories/BalanceReportResponseFactoryTests.cs",
    "content": "﻿using System;\nusing Shouldly;\nusing Mollie.Api.Framework.Factories;\nusing Mollie.Api.Models.Balance.Response.BalanceReport;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.StatusBalance;\nusing Mollie.Api.Models.Balance.Response.BalanceReport.Specific.TransactionCategories;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Framework.Factories {\n    public class BalanceReportResponseFactoryTests {\n        [Theory]\n        [InlineData(ReportGrouping.StatusBalances, typeof(StatusBalanceReportResponse))]\n        [InlineData(ReportGrouping.TransactionCategories, typeof(TransactionCategoriesReportResponse))]\n        [InlineData(\"unknown\", typeof(BalanceReportResponse))]\n        public void Create_CreatesExpectedType(string grouping, Type expectedType) {\n            // Given\n            var factory = new BalanceReportResponseFactory();\n\n            // When\n            var result = factory.Create(grouping);\n\n            // Then\n            result.ShouldBeOfType(expectedType);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Framework/Factories/BalanceTransactionFactoryTests.cs",
    "content": "﻿using System;\nusing Shouldly;\nusing Mollie.Api.Framework.Factories;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction;\nusing Mollie.Api.Models.Balance.Response.BalanceTransaction.Specific;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Framework.Factories {\n    public class BalanceTransactionFactoryTests {\n        [Theory]\n        [InlineData(BalanceTransactionContextType.Payment, typeof(PaymentBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.Capture, typeof(CaptureBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.UnauthorizedDirectDebit, typeof(PaymentBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.FailedPayment, typeof(PaymentBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.Refund, typeof(RefundBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.ReturnedRefund, typeof(RefundBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.Chargeback, typeof(ChargebackBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.ChargebackReversal, typeof(PaymentBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.OutgoingTransfer, typeof(SettlementBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.CanceledOutgoingTransfer, typeof(SettlementBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.ReturnedTransfer, typeof(SettlementBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.InvoiceCompensation, typeof(InvoiceBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.BalanceCorrection, typeof(BalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.ApplicationFee, typeof(PaymentBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.SplitPayment, typeof(PaymentBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.PlatformPaymentRefund, typeof(RefundBalanceTransactionResponse))]\n        [InlineData(BalanceTransactionContextType.PlatformPaymentChargeback, typeof(ChargebackBalanceTransactionResponse))]\n        [InlineData(\"UnknownType\", typeof(BalanceTransactionResponse))]\n        public void Create_CreatesTypeBasedOnType(string type, Type expectedType) {\n            // Given\n            var sut = new BalanceTransactionFactory();\n\n            // When\n            var result = sut.Create(type);\n\n            // Then\n            result.ShouldBeOfType(expectedType);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Framework/Factories/PaymentResponseFactoryTests.cs",
    "content": "﻿using System;\nusing Shouldly;\nusing Mollie.Api.Framework.Factories;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Response;\nusing Mollie.Api.Models.Payment.Response.PaymentSpecificParameters;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Framework.Factories {\n    public class PaymentResponseFactoryTests {\n        [Theory]\n        [InlineData(PaymentMethod.Bancontact, typeof(BancontactPaymentResponse))]\n        [InlineData(PaymentMethod.BankTransfer, typeof(BankTransferPaymentResponse))]\n        [InlineData(PaymentMethod.Belfius, typeof(BelfiusPaymentResponse))]\n        [InlineData(PaymentMethod.CreditCard, typeof(CreditCardPaymentResponse))]\n        [InlineData(PaymentMethod.DirectDebit, typeof(SepaDirectDebitResponse))]\n        [InlineData(PaymentMethod.Eps, typeof(EpsPaymentResponse))]\n        [InlineData(PaymentMethod.GiftCard, typeof(GiftcardPaymentResponse))]\n        [InlineData(PaymentMethod.Giropay, typeof(GiropayPaymentResponse))]\n        [InlineData(PaymentMethod.Ideal, typeof(IdealPaymentResponse))]\n        [InlineData(PaymentMethod.IngHomePay, typeof(IngHomePayPaymentResponse))]\n        [InlineData(PaymentMethod.Kbc, typeof(KbcPaymentResponse))]\n        [InlineData(PaymentMethod.PayPal, typeof(PayPalPaymentResponse))]\n        [InlineData(PaymentMethod.PaySafeCard, typeof(PaySafeCardPaymentResponse))]\n        [InlineData(PaymentMethod.Sofort, typeof(SofortPaymentResponse))]\n        [InlineData(PaymentMethod.Refund, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.KlarnaPayLater, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.KlarnaSliceIt, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.KlarnaOne, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Przelewy24, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.ApplePay, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.MealVoucher, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.In3, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.PointOfSale, typeof(PointOfSalePaymentResponse))]\n        [InlineData(PaymentMethod.Billie, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Trustly, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Twint, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Satispay, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Riverty, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Blik, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.BancomatPay, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.BacsDirectDebit, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Alma, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.GooglePay, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Voucher, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.MbWay, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Multibanco, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.Swish, typeof(PaymentResponse))]\n        [InlineData(PaymentMethod.KlarnaPayNow, typeof(PaymentResponse))]\n        [InlineData(\"UnknownPaymentMethod\", typeof(PaymentResponse))]\n        public void Create_CreatesTypeBasedOnPaymentMethod(string paymentMethod, Type expectedType) {\n            // Given\n            var sut = new PaymentResponseFactory();\n\n            // When\n            var result = sut.Create(paymentMethod);\n\n            // Then\n            result.ShouldBeOfType(expectedType);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Framework/JsonConverterServiceTests.cs",
    "content": "﻿using Shouldly;\nusing Mollie.Api.Framework;\nusing Mollie.Api.JsonConverters;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Response;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Framework {\n    public class JsonConverterServiceTests {\n        [Fact]\n        public void Serialize_JsonData_IsSerialized() {\n            // Given: A JSON metadata value\n            JsonConverterService jsonConverterService = new JsonConverterService();\n            PaymentRequest paymentRequest = new PaymentRequest() {\n                Amount = new Amount(Currency.EUR, \"100.00\"),\n                Description = \"Description\",\n                RedirectUrl = \"http://www.mollie.com\",\n                Metadata = \"{\\\"firstName\\\":\\\"John\\\",\\\"lastName\\\":\\\"Doe\\\"}\",\n            };\n            string expectedJsonValue = \"{\\\"amount\\\":{\\\"currency\\\":\\\"EUR\\\",\\\"value\\\":\\\"100.00\\\"},\\\"description\\\":\\\"Description\\\",\\\"redirectUrl\\\":\\\"http://www.mollie.com\\\",\\\"metadata\\\":{\\\"firstName\\\":\\\"John\\\",\\\"lastName\\\":\\\"Doe\\\"}}\";\n\n            // When: We serialize the JSON\n            string jsonValue = jsonConverterService.Serialize(paymentRequest);\n\n            // Then:\n            jsonValue.ShouldBe(expectedJsonValue);\n        }\n\n        [Fact]\n        public void Deserialize_JsonData_IsDeserialized() {\n            // Given: A JSON metadata value\n            JsonConverterService jsonConverterService = new JsonConverterService();\n            string metadataJson = @\"{\n  \"\"ReferenceNumber\"\": null,\n  \"\"OrderID\"\": null,\n  \"\"UserID\"\": \"\"534721\"\"\n}\";\n            string paymentJson = @\"{\"\"metadata\"\":\" + metadataJson + \"}\";\n\n            // When: We deserialize the JSON\n            PaymentResponse payments = jsonConverterService.Deserialize<PaymentResponse>(paymentJson)!;\n\n            // Then:\n            payments.Metadata.ShouldBe(metadataJson);\n        }\n\n        [Fact]\n        public void Deserialize_StringData_IsDeserialized() {\n            // Given: A JSON metadata value\n            JsonConverterService jsonConverterService = new JsonConverterService();\n            string metadataJson = \"This is my metadata\";\n            string paymentJson = @\"{\"\"metadata\"\":\"\"\" + metadataJson + @\"\"\"}\";\n\n            // When: We deserialize the JSON\n            PaymentResponse payments = jsonConverterService.Deserialize<PaymentResponse>(paymentJson)!;\n\n            // Then:\n            payments.Metadata.ShouldBe(metadataJson);\n        }\n\n        [Fact]\n        public void Deserialize_JsonDataWithNullValues_IsDeserialized() {\n            // Given: A JSON metadata value\n            var jsonConverterService = new JsonConverterService();\n            string metadataJson = @\"null\";\n            string paymentJson = @\"{\"\"metadata\"\":\" + metadataJson + \"}\";\n\n            // When: We deserialize the JSON\n            PaymentResponse payments = jsonConverterService.Deserialize<PaymentResponse>(paymentJson)!;\n\n            // Then:\n            payments.Metadata.ShouldBeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Models/AmountTests.cs",
    "content": "﻿using Shouldly;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Payment.Response;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Models {\n    public class AmountTests {\n        [Theory]\n        [InlineData(\"EUR\", 50.25, \"50.25\")]\n        [InlineData(\"EUR\", 50, \"50.00\")]\n        [InlineData(\"JPY\", 51, \"51\")]\n        [InlineData(\"ISK\", 52, \"52\")]\n        [InlineData(\"ISK\", 52.40, \"52\")]\n        public void CreateAmount_DecimalIsConverted_ValueHasCorrectFormat(string currency, decimal value, string expectedResult) {\n            // Arrange & act\n            var amount = new Amount(currency, value);\n\n            // Assert\n            amount.Value.ShouldBe(expectedResult);\n        }\n\n        [Fact]\n        public void Amount_ConvertedToDecimal_IsEqualToOriginalValue() {\n            // Arrange\n            decimal originalValue = 50.25m;\n            var amount = new Amount(Currency.EUR, originalValue);\n\n            // Act\n            decimal convertedValue = amount;\n\n            // Assert\n            convertedValue.ShouldBe(originalValue);\n        }\n\n        [Fact]\n        public void NullableAmount_ConvertedToNullableDecimal_IsEqualToOriginalValue() {\n            // Arrange\n            decimal originalValue = 50.25m;\n            Amount? amount = new(Currency.EUR, originalValue);\n\n            // Act\n            decimal? convertedValue = amount;\n\n            // Assert\n            convertedValue.ShouldBe(originalValue);\n        }\n\n        [Fact]\n        public void NullAmount_ConvertedToNullableDecimal_IsNull() {\n            // Arrange\n            Amount? amount = null;\n\n            // Act\n            decimal? convertedValue = amount;\n\n            // Assert\n            convertedValue.ShouldBeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Models/Payment/Request/PaymentRequestTests.cs",
    "content": "﻿using System;\nusing Shouldly;\nusing Mollie.Api.Models;\nusing Mollie.Api.Models.Payment;\nusing Mollie.Api.Models.Payment.Request;\nusing Mollie.Api.Models.Payment.Request.PaymentSpecificParameters;\nusing Xunit;\n\nnamespace Mollie.Tests.Unit.Models.Payment.Request;\n\npublic class PaymentRequestTests {\n    [Theory]\n    [InlineData(PaymentMethod.CreditCard, typeof(CreditCardPaymentRequest))]\n    [InlineData(PaymentMethod.PayPal, typeof(PayPalPaymentRequest))]\n    public void CreatePaymentRequest(string paymentMethod, Type expectedType) {\n        var amount = new Amount(Currency.EUR, 50m);\n        var description = \"my-description\";\n        var paymentRequest = new PaymentRequest() {\n            Amount = amount,\n            Description = description\n        };\n        switch (paymentMethod) {\n            case PaymentMethod.CreditCard:\n                paymentRequest = new CreditCardPaymentRequest(paymentRequest) {\n                    CardToken = \"card-token\"\n                };\n                break;\n            case PaymentMethod.PayPal:\n                paymentRequest = new PayPalPaymentRequest(paymentRequest) {\n                    DigitalGoods = true\n                };\n                break;\n        }\n\n        paymentRequest.ShouldBeOfType(expectedType);\n        paymentRequest.Amount.ShouldBe(amount);\n        paymentRequest.Description.ShouldBe(description);\n    }\n}\n"
  },
  {
    "path": "tests/Mollie.Tests.Unit/Mollie.Tests.Unit.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net10.0</TargetFramework>\n\n    <IsPackable>false</IsPackable>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Moq\" Version=\"4.20.72\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.12.0\" />\n    <PackageReference Include=\"RichardSzalay.MockHttp\" Version=\"7.0.0\" />\n    <PackageReference Include=\"Shouldly\" Version=\"4.3.0\" />\n    <PackageReference Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"3.0.1\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Mollie.Api\\Mollie.Api.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  }
]