Skip to content

Commit

Permalink
OCC-63: Separate Stripe payment into a feature so it can be disabled …
Browse files Browse the repository at this point in the history
…if other payment provider is desired. (#373)

* Adding Product List base architecture

* Improving boolean attribute display in cart

* Handling attributes on checkout in ProductAttributeProvider

* Handling attributes during Order creation

* Fixing Order view

* Renaming SelectedAttributes property to SelectedTextAttributes

* Adding boolean attribute editing capabilities to Order editor

* Fixing bug with boolean attributes display

* Constructing actual boolean attributes as well

* Fistfighting analyzer

* Adjusting Order editor styling

* Adding handling of numeric attributes

* Improving numeric inputs in Order editor

* Fixing warning

* Potentially fixing test

* Extending UI test

* Adding minor improvements

* Improving JSON parsing

* Adding minor fixes

* Creating navigation extension method

* Fixing string in view

* Replacing SelectedTextAttributes with SelectedAttributes

* Create OrchardCore.Commerce.Payment module.

* Add separate module to OrchardCore.Commerce.Payment.Stripe.

* Move most Stripe files into its own module.

* Move PaymentIntent too.

* Fix some easier errors.

* Using SelectedAttributes everywhere

* Moving business logic to service

* Warnin't

* Fixing test

* Use _productService.GetProductsAsync in CreateOrderLineItemsAsync.

* Create RequestOptionsService.

* Create OrchardCore.Commerce.Abstraction to store some models and interfaces the modules should be able to access. This will be relevant to #175 (OCC-81) as well.

* Some project organization.

* Move two view-models and add SKU holder interfaces.

* Move more stuff over to abstractions.

* More code reorganization.

* Move serialization to abstraction.

* Resolve non-Payment related errors except ProductAttributeValueConverter.

* Modular deserializers.

* Move CreateOrderLineItemsAsync to ShoppingCartHelpers.

* Working on adding providers

* Fixing Order editor; removing unnecessary code

* Moving method to service

* Make GetPaymentAmount private.

* Extending providers with new meth

* Move WebhookController.

* Create StripeController.

* Move order updating from StripePaymentService to regular PaymentService.

* Abstract CheckoutViewModel.

* Replace InitializePaymentIntentAsync with CreateClientSecretAsync.

* Move assets to the stripe project.

* Fix NodeJS Extensions references in csproj.

* Move payment-form.scss into Add separate module to OrchardCore.Commerce.Payment.

* Move FieldsOnlyDisplayManager to ContentFields module.

* Move PaymentController and PaymentService to the module.

* Move AddressField into ContentFields module.

* Extract the UserAddress stuff into an event handler.

* Adding ordering options

* Move commerce-regions.js to ContentFields.

* Externalize OrderContentTypeDefinitionDisplayDriver._excludedShapes.

* Remove stripe-specific properties from ICheckoutViewModel.

* Adding title filter

* Abstract stripe data in CheckoutViewModel.

* Replace StripeCheckout shape usages with a list of provider shapes.

* Go back to directly importing PaymentForm after all.

* Wire OrchardCore.Commerce.Payment into OrchardCore.Commerce.

* Update excludes.

* Add "deserializers" to the allow list.

* unusing

* Fix non-Stripe problems with PaymentController.

* Add ProductAttributeProvider name constants.

* Minor code cleanup.

* Post merge fix-up.

* PaymentViewModel

* Create shape data in the provider, move Stripe stuff to StripePaymentProvider.

* Make `~/checkout/validate` provider-based.

* Namespace fix.

* Don't assume default shopping cart ID.

* More shopping cart fixes.

* Set charges in the outer service.

* Turn Payment into a record.

* Resolving applied filters from query string

* Adding UI tests

* Renaming interface and fixing analyzer violations

* Fixing analyzer violation

* Ignoring pager HTML validation error

* Removing unnecessary ContainedPart from products

* Some more fixes.

* Add missing dependency.

* Add IPaymentProvider.FinalModificationOfOrderAsync().

* Move OrderCreatedEvent workflow event into abstraction.

* Update inventories using the OrderedAsync event.

* Save user addresses in the FinalizeAsync event.

* All promotion services should be in the PromotionStartup.

* Add PromotionOrderEvents.

* Add UserSettingsCheckoutEvents.

* Make Promotion a dependency of Payment.Stripe.

* Add missing Node Extensions files.

* Remove broken project reference.

* Ensure payment view model's data is never null.

* Fix CreatedFreeAsync.

* Add missing Node Extensions files.

* Fix warnings.

* Feature setup.

* Don't break with free orders.

* shoppingCartId nullable

* Minor refactorings

* Accepting only one order by value

* Fixing failing UI test

* Update src/Modules/OrchardCore.Commerce/Services/ProductListService.cs

* Move Checkout-Stripe to CheckoutStripe.

* Fix wrong data property names.

* Fail early in PaymentConfirmationMiddleware if the payment intent or order are missing.

* Throw notification if there is a total in the free order.

* Use UpdateOrderToOrderedAsync in OrderController.

* Move IPaymentService to OrchardCore.Commerce.Payment.

* Return the same way in stripe too.

* No need for IOrchardHelper.

* Turn StripePaymentService.CheckTotals into an extension method.

* Extract reusable parts of CreateOrUpdateOrderFromShoppingCartAsync logic.

* Handle FrontendException.

* Merge unnecessary single-use private method.

* Simplify StripePaymentService constructor.

* Add PaymentIntentPersistence.Remove() method.

* Add dummy provider.

* Extract payment button into a separate shape.

* Fix PayButton.

* Add "Stripe" to the middleware action's name for consistency.

* Fix spinner on the wrong button.

* Update payment intent persistence during submit.

* Add CreateShoppingCartViewModelAsync extension method.

* grammar

* Add WhereName extension method to payment provider collection.

* Now working dummy provider.

* Update recipes.

* Code cleanup.

* Don't break if the Stripe API key is not configured.

* Update Stripe docs.

* Add general payment provider documentation.

* Add unit test.

* Fix spacing.

* Update excludes.txt.

* Fix CartEventsShouldUpdateTableAndAddLineItem.

* fallbacks

* fix paymentRequestUrl

* cshtml unusing

* Move ContentTypes to Abstractions.

* Pluralize OrchardCore.Commerce.Abstraction.

* Fix namespace.

* Fix missing constant from unit test.

* Fix and DRY ShoppingCartControllerTests.

* Update namespaces.

* Early payment intent error handling.

* Skip charges if there is no PaymentMethod.

* Fix Stripe checkout for real now.

* Add error message to PaymentConfirmationMiddleware failure.

* Add const for repeated string.

* DRY AddNewItemToCart and AddExistingItemToCart tests.

* Add warning when no providers are applicable.

* Validate that the Stripe order is not empty.

* This didn't work as expected.

* Fix bug where orderPart.LineItems.SetItems() cleared itself.

* Fix nuget references.

* Remove broken usings.

---------

Co-authored-by: Márk Bartha <barthamark@gmail.com>
Co-authored-by: Gábor Pór <gabor.por@lombiq.com>
Co-authored-by: Dávid El-Saig <david.el-saig@lombiq.com>
  • Loading branch information
4 people committed Nov 9, 2023
1 parent 5a30434 commit 582887b
Show file tree
Hide file tree
Showing 283 changed files with 7,644 additions and 1,666 deletions.
3 changes: 2 additions & 1 deletion .github/actions/spelling/allow/occ.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ CLA
contentpart
CVC
datetimefield
deserializers
disqus
emoji
EUR
Expand All @@ -27,8 +28,8 @@ pricefield
roadmap
shoppingcart
skus
testdiscountedproduct
testproduct
testproductvariant
testdiscountedproduct
unpublish
webhooks
4 changes: 2 additions & 2 deletions .github/actions/spelling/excludes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ docs/releases
docs/requirements\.txt$
mkdocs\.yml$
src/Libraries/OrchardCore\.Commerce\.MoneyDataType/Currency\.extra\.cs$
src/Modules/OrchardCore\.Commerce/Constants/CurrencyCollectionConstants\.cs$
src/Modules/OrchardCore\.Commerce/Extensions/PaymentExtensions\.cs$
src/Modules/OrchardCore\.Commerce\.Payment/Constants/CurrencyCollectionConstants\.cs$
src/Modules/OrchardCore\.Commerce\.Payment\.Stripe/Extensions/PaymentExtensions\.cs$
test/OrchardCore\.Commerce\.Tests/Fakes/AnkhMorporkCurrencyProvider\.cs$
test/OrchardCore\.Commerce\.Tests/ProductAttributeTests\.cs$
29 changes: 22 additions & 7 deletions OrchardCore.Commerce.sln
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "features", "features", "{9B
docs\features\tiered-price-part.md = docs\features\tiered-price-part.md
docs\features\user-features.md = docs\features\user-features.md
docs\features\workflows.md = docs\features\workflows.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "releases", "releases", "{E4DD8D47-02FA-41F7-8133-CBC4419645F5}"
ProjectSection(SolutionItems) = preProject
docs\releases\0.0.1.md = docs\releases\0.0.1.md
docs\releases\1.0.0.md = docs\releases\1.0.0.md
docs\features\payment-providers.md = docs\features\payment-providers.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "actions", "actions", "{83C01924-6F58-4777-A9EC-07943F7A2E31}"
Expand All @@ -108,6 +103,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libraries", "libraries", "{
docs\resources\libraries\README.md = docs\resources\libraries\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrchardCore.Commerce.Payment", "src\Modules\OrchardCore.Commerce.Payment\OrchardCore.Commerce.Payment.csproj", "{58DD682C-DA5C-4B51-BCB8-C65D690AAC67}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrchardCore.Commerce.Payment.Stripe", "src\Modules\OrchardCore.Commerce.Payment.Stripe\OrchardCore.Commerce.Payment.Stripe.csproj", "{A4D69733-CDC0-46AE-B46A-163CCC6F77F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrchardCore.Commerce.Abstractions", "src\Libraries\OrchardCore.Commerce.Abstractions\OrchardCore.Commerce.Abstractions.csproj", "{28DB6CBB-1527-42A1-8EFE-3D95BF185884}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -158,6 +159,18 @@ Global
{3DB5D0DD-1509-40B8-AD1A-47D5672BF484}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DB5D0DD-1509-40B8-AD1A-47D5672BF484}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DB5D0DD-1509-40B8-AD1A-47D5672BF484}.Release|Any CPU.Build.0 = Release|Any CPU
{58DD682C-DA5C-4B51-BCB8-C65D690AAC67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58DD682C-DA5C-4B51-BCB8-C65D690AAC67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58DD682C-DA5C-4B51-BCB8-C65D690AAC67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58DD682C-DA5C-4B51-BCB8-C65D690AAC67}.Release|Any CPU.Build.0 = Release|Any CPU
{A4D69733-CDC0-46AE-B46A-163CCC6F77F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4D69733-CDC0-46AE-B46A-163CCC6F77F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4D69733-CDC0-46AE-B46A-163CCC6F77F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4D69733-CDC0-46AE-B46A-163CCC6F77F9}.Release|Any CPU.Build.0 = Release|Any CPU
{28DB6CBB-1527-42A1-8EFE-3D95BF185884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28DB6CBB-1527-42A1-8EFE-3D95BF185884}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28DB6CBB-1527-42A1-8EFE-3D95BF185884}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28DB6CBB-1527-42A1-8EFE-3D95BF185884}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -177,13 +190,15 @@ Global
{87C422CA-C6F2-408F-987B-C8418995A331} = {E6C02BDF-EEB0-4ABD-ADEC-9932F60923AE}
{93871E12-0083-4323-BB7B-3CDA6E332D87} = {E6C02BDF-EEB0-4ABD-ADEC-9932F60923AE}
{9B2DB1CD-2B4A-4823-9762-CF4E90661404} = {BEBA1764-178A-4722-A193-4DEF26DCE8D1}
{E4DD8D47-02FA-41F7-8133-CBC4419645F5} = {BEBA1764-178A-4722-A193-4DEF26DCE8D1}
{83C01924-6F58-4777-A9EC-07943F7A2E31} = {4561F321-6E57-484B-950C-AC46798B1F40}
{E32B62B8-D737-4713-87C5-8220C9746643} = {83C01924-6F58-4777-A9EC-07943F7A2E31}
{7FB7940D-EEF4-4355-BCBF-C160080F257A} = {E32B62B8-D737-4713-87C5-8220C9746643}
{3DB5D0DD-1509-40B8-AD1A-47D5672BF484} = {772AFE42-DF1F-49B1-9F64-7C901E588C00}
{62DF9FF9-D2B3-4333-948D-2E405699B47B} = {BEBA1764-178A-4722-A193-4DEF26DCE8D1}
{C788AFFF-F440-4259-9102-5B4C1B91FAFA} = {62DF9FF9-D2B3-4333-948D-2E405699B47B}
{58DD682C-DA5C-4B51-BCB8-C65D690AAC67} = {E6C02BDF-EEB0-4ABD-ADEC-9932F60923AE}
{A4D69733-CDC0-46AE-B46A-163CCC6F77F9} = {E6C02BDF-EEB0-4ABD-ADEC-9932F60923AE}
{28DB6CBB-1527-42A1-8EFE-3D95BF185884} = {90913510-3D7F-4BCC-B55E-56343128F049}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {456CBC78-579D-483F-A4C3-AF5C12AB3324}
Expand Down
5 changes: 3 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ This project uses `Lombiq Node.js Extensions` to compile and lint client-side as
2. Build and run the `OrchardCore.Commerce.Web` project.
3. Thanks to [Auto Setup](https://docs.orchardcore.net/en/latest/docs/reference/modules/AutoSetup/), the site will be set up with the `OrchardCore Commerce - Development` recipe.
4. Go to the dashboard, using the credentials `admin` and `Password1!`.
5. Go to _Configuration__Commerce__Stripe API_. Set the keys to the test keys found [here](docs/features/stripe-payment.md). If the keys are not set, payment won't work.
5. If you want to test Stripe, go to _Configuration__Commerce__Stripe API_. Set the keys to the test keys found [here](docs/features/stripe-payment.md). If the keys are not set, the Stripe payment button won't appear during checkout.
6. Go to _Content__Content Items_, and create your first `Product`.

## Documentation

- [Inventory](docs/features/inventory.md)
- [Products and Prices](docs/features/products-and-prices.md)
- [Promotions](docs/features/promotions.md)
- [Stripe Payment](docs/features/stripe-payment.md)
- [Payment providers](docs/features/payment-providers.md)
- [Stripe Payment](docs/features/stripe-payment.md)
- [Taxation](docs/features/taxation.md)
- [User Features](docs/features/user-features.md)
- [Workflows](docs/features/workflows.md)
Expand Down
20 changes: 20 additions & 0 deletions docs/features/payment-providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Payment Providers

Orchard Core Commerce supports multiple payment providers and allows developers to extend it further with their own.

## Official payment providers

Each provider is a stand-alone feature you can turn on or off.

- [Stripe](stripe-payment.md): A production-ready provider for [stripe.com](https://stripe.com/).
- Dummy: A development-only provider that lets you click through the checkout without going off-site. Mainly used for UI testing.

## Creating your own

To create a custom payment provider your code must contain the following:
- An implementation of `IPaymentProvider` registered as a service.
- A shape type `Checkout{provider.Name}`, such as _CheckoutStripe.cshtml_ and _CheckoutDummy.cshtml_.

The `IPaymentProvider` contains implementable methods used by the `CheckoutController`. To learn more about the individual methods in the interface, check out the individual methods' XML documentation.

The shape has the payment button that will be displayed on the `~/checkout` screen. It's up to you to include the front-end logic that calls out to your payment processor and to provide a callback URL. For the latter you can use the `~/checkout/callback/{providerName}/{orderId?}` action. It handles some basic state checking and redirection, but otherwise lets you resolve the pending order using `IPaymentProvider.UpdateAndRedirectToFinishedOrderAsync()`.
8 changes: 5 additions & 3 deletions docs/features/stripe-payment.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Stripe Payment

Orchard Core Commerce [aims to support multiple payment providers](https://github.com/OrchardCMS/OrchardCore.Commerce/issues/149), but at this time [Stripe](https://stripe.com/) is the only supported implementation. This document describes how to set it up for testing, but if you just want to try out the checkout flow you can use the [cards](#cards) listed below without any configuration.
Orchard Core Commerce supports multiple [payment providers](payment-providers.md). [Stripe](https://stripe.com/) was the first implemented. This document describes how to set it up for testing, including hooking your site up to the Stripe dashboard. If you just want to try out the checkout flow you can skip the Webhook sections.

## Test data for Stripe Payment

Expand All @@ -14,13 +14,15 @@ Stripe API uses a secret-publishable key pair. The following API keys are public

**Publishable and secret keys are just publicly available test keys. Don't submit any personally identifiable information in requests made with this key.**

You can obtain your own test keys from the Stripe dashboard. You can find them at _Dashboard → Developers → API keys_.
You can obtain your own test keys from the Stripe dashboard. You can find them in the [developer dashboard's Api keys tab](https://dashboard.stripe.com/test/apikeys).

In your Orchard Core site go to _Admin__Configuration__Commerce__Stripe API_ and provide at least the _Publishable key_ and _Secret key_. Otherwise the feature can't work and the payment button will be hidden during checkout.

### Webhook signing key

It is not needed, but recommended to use webhook. Otherwise, if there is a problem with redirecting the user, the payment confirmation will fail.

There is no publicly available webhook signing key. Use your own API keys and Webhook key. Create your own at _Dashboard → Developers → Webhooks_.
There is no publicly available webhook signing key. Use your own API keys and Webhook key. You can create one in the [developer dashboard's Webhooks tab](https://dashboard.stripe.com/test/webhooks).

Read about webhook status codes [here](https://stripe.com/docs/webhooks/best-practices#pending-webhook-statuses). Our webhook endpoint returns _200_ if the request was received without an exception. It does not mean that it has been processed. It returns _400_ if there was an exception inside the webhook controller. Everything else comes from Stripe itself.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using OrchardCore.Commerce.Abstractions.Models;
using System.Threading.Tasks;

namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// Extension points for events related to checkout.
/// </summary>
public interface ICheckoutEvents
{
/// <summary>
/// Invoked at the start of a new <see cref="OrderPart"/> creation which is used to create the <see
/// cref="ICheckoutViewModel"/>.
/// </summary>
Task OrderCreatingAsync(OrderPart orderPart, string shoppingCartId) => Task.CompletedTask;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Mvc.Rendering;
using OrchardCore.Commerce.MoneyDataType;
using OrchardCore.DisplayManagement;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace OrchardCore.Commerce.Abstractions.Abstractions;

[SuppressMessage(
"StyleCop.CSharp.DocumentationRules",
"SA1600:Elements should be documented",
Justification = "Nothing to say besides what's already on the property names.")]
public interface ICheckoutViewModel : IPaymentViewModel, IShape
{
string ShoppingCartId { get; }
Amount GrossTotal { get; }
IEnumerable<SelectListItem> Regions { get; set; }
IDictionary<string, IDictionary<string, string>> Provinces { get; }
string UserEmail { get; }
IEnumerable<IShape> CheckoutShapes { get; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using OrchardCore.Commerce.MoneyDataType;

namespace OrchardCore.Commerce.Abstractions;
namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// Represents an object that contains some of an order line item's basic info.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using OrchardCore.Commerce.Abstractions.Models;
using OrchardCore.Commerce.Abstractions.ViewModels;
using OrchardCore.ContentManagement;
using System.Threading.Tasks;

namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// Extension points for events related to orders.
/// </summary>
public interface IOrderEvents
{
/// <summary>
/// Invoked when a new free (non-payment) order is created.
/// </summary>
Task CreatedFreeAsync(OrderPart orderPart, ShoppingCart cart, ShoppingCartViewModel viewModel) => Task.CompletedTask;

/// <summary>
/// Invoked when the <paramref name="order"/> is set to the <c>Ordered</c> state.
/// </summary>
Task OrderedAsync(ContentItem order, string shoppingCartId) => Task.CompletedTask;

/// <summary>
/// Invoked during cleanup after the order has been finalized.
/// </summary>
Task FinalizeAsync(ContentItem order, string shoppingCartId, string paymentProviderName) => Task.CompletedTask;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using OrchardCore.Commerce.MoneyDataType;
using System;

namespace OrchardCore.Commerce.Abstractions;
namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// Describes a payment transaction's details.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using OrchardCore.Commerce.Abstractions.Models;
using OrchardCore.Commerce.MoneyDataType;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace OrchardCore.Commerce.Abstractions.Abstractions;

[SuppressMessage(
"StyleCop.CSharp.DocumentationRules",
"SA1600:Elements should be documented",
Justification = "Nothing to say besides what's already on the property names.")]
public interface IPaymentViewModel
{
Amount SingleCurrencyTotal { get; }
Amount NetTotal { get; }
IDictionary<string, object> PaymentProviderData { get; }
OrderPart OrderPart { get; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace OrchardCore.Commerce.Abstractions;
namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// Represents a predefined <see cref="IProductAttributeValue"/> with no type specified.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text.Json.Nodes;

namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// Deserializes the attribute of the type <see cref="AttributeTypeName"/>.
/// </summary>
public interface IProductAttributeDeserializer
{
// Not necessary to document as they are not externally accessible.
#pragma warning disable SA1600 // Elements should be documented.
internal static readonly Dictionary<string, IProductAttributeDeserializer> Deserializers =
new(StringComparer.OrdinalIgnoreCase);

private static readonly object _lock = new();
#pragma warning restore SA1600

/// <summary>
/// Gets the attribute name used to identify this deserializer.
/// </summary>
string AttributeTypeName { get; }

/// <summary>
/// Deserializes using <c>Newtonsoft.Json</c>.
/// </summary>
IProductAttributeValue Deserialize(string attributeName, JObject attribute);

/// <summary>
/// Deserializes using <c>System.Text.Json</c>.
/// </summary>
IProductAttributeValue Deserialize(string attributeName, JsonObject attribute);

/// <summary>
/// Registers serializers used to deserialize product attributes.
/// </summary>
public static void AddSerializers(params IProductAttributeDeserializer[] deserializers)
{
lock (_lock)
{
foreach (var deserializer in deserializers)
{
Deserializers[deserializer.AttributeTypeName] = deserializer;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Newtonsoft.Json;
using OrchardCore.Commerce.Serialization;
using OrchardCore.Commerce.Abstractions.Serialization;
using System;
using System.Globalization;
using System.Linq;

namespace OrchardCore.Commerce.Abstractions;
namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// A specific value from a product attribute field.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Globalization;
using System.Threading.Tasks;

namespace OrchardCore.Commerce.Abstractions;
namespace OrchardCore.Commerce.Abstractions.Abstractions;

/// <summary>
/// A service for accessing and customizing regions.
Expand Down
Loading

0 comments on commit 582887b

Please sign in to comment.