Skip to content

Add store-scoped payment management to Grand.Web.Store#714

Merged
KrzysztofPajak merged 6 commits into
developfrom
feature/store-payment-controller
Jun 12, 2026
Merged

Add store-scoped payment management to Grand.Web.Store#714
KrzysztofPajak merged 6 commits into
developfrom
feature/store-payment-controller

Conversation

@KrzysztofPajak

Copy link
Copy Markdown
Member

Type: feature

Issue

The store-manager panel (Grand.Web.Store) already mirrors many Admin configuration areas in a store-scoped way (Shipping, Tax, GiftVoucher, Discount, ContactAttribute), but payment configuration was missing — it lived only in Grand.Web.Admin. A store owner had no way to manage payment methods, payment settings, or payment restrictions for their own store.

Solution

Adds a store-scoped PaymentController to Grand.Web.Store, following the existing Store ShippingController conventions (primary-constructor DI, CurrentStoreId from StaffStoreId, [PermissionAuthorize(PermissionSystemName.PaymentMethods)] + action-level permissions). It provides the three capabilities requested:

  • Payment methods — list available providers and enable/disable them for the store (stored in the store-scoped PaymentSettings.ActivePaymentProviderSystemNames).
  • Payment settings — the store-level PaymentSettings toggles.
  • Payment restrictions — restrict each method by country / shipping method, like the Store shipping restrictions.

Payment settings and active methods were already store-scoped via ISettingService + PaymentSettings. Payment restrictions, however, were stored globally (setting keys PaymentMethodRestictions.{SystemName} / ...Shipping.{SystemName} with no storeId), unlike shipping restrictions which live on the store-scoped ShippingMethod entity. To get true per-store isolation, the four restriction methods on IPaymentService / PaymentService now accept an optional string storeId = "", which is threaded into:

  • ISettingService.GetSettingByKey(..., storeId) — store-specific read with fallback to the global value.
  • ISettingService.SetSetting(..., storeId) — writes a per-store setting row.
  • LoadActivePaymentMethods / LoadAllPaymentMethods — so restrictions apply per store at checkout.

Views live in Areas/Store/Views/Payment/ (Index grid, Settings, MethodRestrictions + Country/Shipping tab partials), reusing the existing Grand.Web.AdminShared payment models/mappers. The Store sidebar reuses the shared AdminSiteMap, which already contains the Payment node, so no sitemap change was needed.

Plugin configuration links (gateway credentials via each provider's ConfigurationUrl) are intentionally out of scope here and deferred to a separate task; the Store methods grid shows the list + active toggle only.

Breaking changes

None. The new storeId parameters on IPaymentService are optional and default to "", so the existing Admin PaymentController and all other callers keep their current global behaviour unchanged.

Testing

  1. Build the solution (dotnet build) — Admin and Store both compile.
  2. As an admin, grant the Manage payment methods permission to the store manager customer group (Customers → Customer groups → store manager → ACL). Note: this permission is not part of the default store-manager set (consistent with how ShippingSettings / TaxSettings were added).
  3. Log in to the store panel (/store) as a store manager. Confirm a Payment item appears in the sidebar with Payment methods, Payment settings, and Payment method restrictions.
  4. Methods: open store/payment, toggle a provider active, reload, and confirm it persists. Verify the PaymentSettings Setting record carries the manager's StoreId (store-scoped, not global).
  5. Settings: change a toggle on the settings page, save, reload — persists for that store only.
  6. Restrictions: open Method restrictions, restrict a method for a country and/or a store shipping method, save. Confirm a paymentmethodrestictions.* / paymentmethodrestictionsshipping.* Setting row is written with the manager's StoreId, leaving any global row untouched.
  7. Isolation: with two stores, confirm restrictions set by store A do not affect store B, and that at checkout in store A the restricted method is hidden for the restricted country/shipping while store B is unaffected (falling back to the global value if it has no override).

🤖 Generated with Claude Code

Adds a PaymentController to the store-manager panel mirroring the Admin
payment configuration, scoped to the store owner (CurrentStoreId), following
the existing Store ShippingController conventions:

- Payment methods: list providers and toggle active per store
- Payment settings: store-scoped PaymentSettings toggles
- Payment restrictions: by country / shipping method, per store

Payment restrictions were stored globally (setting keys
PaymentMethodRestictions.{SystemName} / ...Shipping.{SystemName} with no
storeId). To support true per-store isolation, the four restriction methods on
IPaymentService/PaymentService now take an optional storeId (default ""), which
is threaded into ISettingService (store-specific read with global fallback,
per-store write) and into LoadActive/LoadAllPaymentMethods so restrictions
apply per store at checkout. The default keeps Admin behaviour unchanged.

Plugin configuration links are intentionally deferred to a separate task.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/Tests/Grand.Web.Admin.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Admin.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Admin.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Store.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Store.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Store.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Store.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Store.Tests/Controllers/PaymentControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Store.Tests/Controllers/ShippingControllerTests.cs Dismissed
Comment thread src/Tests/Grand.Web.Store.Tests/Controllers/ShippingControllerTests.cs Dismissed
@sonarqubecloud

sonarqubecloud Bot commented Jun 12, 2026

Copy link
Copy Markdown

@KrzysztofPajak KrzysztofPajak merged commit 0755a50 into develop Jun 12, 2026
7 of 8 checks passed
@KrzysztofPajak KrzysztofPajak deleted the feature/store-payment-controller branch June 12, 2026 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant