using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Routing; using Nop.Core.Domain.Cms; using Nop.Core.Domain.Orders; using Nop.Core.Domain.Payments; using Nop.Plugin.Payments.PayPalCommerce.Components.Admin; using Nop.Plugin.Payments.PayPalCommerce.Components.Public; using Nop.Plugin.Payments.PayPalCommerce.Domain; using Nop.Plugin.Payments.PayPalCommerce.Services; using Nop.Services.Cms; using Nop.Services.Configuration; using Nop.Services.Localization; using Nop.Services.Payments; using Nop.Services.Plugins; using Nop.Services.Stores; using Nop.Web.Framework.Infrastructure; namespace Nop.Plugin.Payments.PayPalCommerce; /// /// Represents the PayPal Commerce payment method /// public class PayPalCommercePaymentMethod : BasePlugin, IPaymentMethod, IWidgetPlugin { #region Fields private readonly IActionContextAccessor _actionContextAccessor; private readonly ILocalizationService _localizationService; private readonly ISettingService _settingService; private readonly IStoreService _storeService; private readonly IUrlHelperFactory _urlHelperFactory; private readonly PaymentSettings _paymentSettings; private readonly PayPalCommerceServiceManager _serviceManager; private readonly PayPalCommerceSettings _settings; private readonly WidgetSettings _widgetSettings; #endregion #region Ctor public PayPalCommercePaymentMethod(IActionContextAccessor actionContextAccessor, ILocalizationService localizationService, ISettingService settingService, IStoreService storeService, IUrlHelperFactory urlHelperFactory, PaymentSettings paymentSettings, PayPalCommerceServiceManager serviceManager, PayPalCommerceSettings settings, WidgetSettings widgetSettings) { _actionContextAccessor = actionContextAccessor; _localizationService = localizationService; _settingService = settingService; _storeService = storeService; _urlHelperFactory = urlHelperFactory; _paymentSettings = paymentSettings; _serviceManager = serviceManager; _settings = settings; _widgetSettings = widgetSettings; } #endregion #region Methods /// /// Process a payment /// /// Payment info required for an order processing /// /// A task that represents the asynchronous operation /// The task result contains the process payment result /// public Task ProcessPaymentAsync(ProcessPaymentRequest processPaymentRequest) { return Task.FromResult(new ProcessPaymentResult()); } /// /// Post process payment (used by payment gateways that require redirecting to a third-party URL) /// /// Payment info required for an order processing /// A task that represents the asynchronous operation public Task PostProcessPaymentAsync(PostProcessPaymentRequest postProcessPaymentRequest) { return Task.CompletedTask; } /// /// Captures payment /// /// Capture payment request /// /// A task that represents the asynchronous operation /// The task result contains the capture payment result /// public async Task CaptureAsync(CapturePaymentRequest capturePaymentRequest) { //capture previously authorized payment var (capture, error) = await _serviceManager.CaptureAuthorizationAsync(_settings, capturePaymentRequest.Order.AuthorizationTransactionId); if (!string.IsNullOrEmpty(error)) return new() { Errors = new[] { error } }; //request succeeded return new() { CaptureTransactionId = capture.Id, CaptureTransactionResult = capture.Status, NewPaymentStatus = PaymentStatus.Paid }; } /// /// Voids a payment /// /// Request /// /// A task that represents the asynchronous operation /// The task result contains the result /// public async Task VoidAsync(VoidPaymentRequest voidPaymentRequest) { //void previously authorized payment var (_, error) = await _serviceManager.VoidAsync(_settings, voidPaymentRequest.Order.AuthorizationTransactionId); if (!string.IsNullOrEmpty(error)) return new() { Errors = new[] { error } }; //request succeeded return new() { NewPaymentStatus = PaymentStatus.Voided }; } /// /// Refunds a payment /// /// Request /// /// A task that represents the asynchronous operation /// The task result contains the result /// public async Task RefundAsync(RefundPaymentRequest refundPaymentRequest) { //refund previously captured payment var amount = refundPaymentRequest.AmountToRefund != refundPaymentRequest.Order.OrderTotal ? (decimal?)refundPaymentRequest.AmountToRefund : null; var (_, error) = await _serviceManager.RefundAsync(_settings, refundPaymentRequest.Order, amount); if (!string.IsNullOrEmpty(error)) return new() { Errors = new[] { error } }; //request succeeded return new() { NewPaymentStatus = refundPaymentRequest.IsPartialRefund ? PaymentStatus.PartiallyRefunded : PaymentStatus.Refunded }; } /// /// Process recurring payment /// /// Payment info required for an order processing /// /// A task that represents the asynchronous operation /// The task result contains the process payment result /// public Task ProcessRecurringPaymentAsync(ProcessPaymentRequest processPaymentRequest) { return Task.FromResult(new ProcessPaymentResult { Errors = new[] { "Recurring payment not supported" } }); } /// /// Cancels a recurring payment /// /// Request /// /// A task that represents the asynchronous operation /// The task result contains the result /// public Task CancelRecurringPaymentAsync(CancelRecurringPaymentRequest cancelPaymentRequest) { return Task.FromResult(new CancelRecurringPaymentResult { Errors = new[] { "Recurring payment not supported" } }); } /// /// Returns a value indicating whether payment method should be hidden during checkout /// /// Shoping cart /// /// A task that represents the asynchronous operation /// The task result contains true - hide; false - display. /// public Task HidePaymentMethodAsync(IList cart) { var notConnected = !PayPalCommerceServiceManager.IsConnected(_settings); return Task.FromResult(notConnected); } /// /// Gets additional handling fee /// /// Shoping cart /// /// A task that represents the asynchronous operation /// The task result contains the additional handling fee /// public Task GetAdditionalHandlingFeeAsync(IList cart) { return Task.FromResult(decimal.Zero); } /// /// Gets a value indicating whether customers can complete a payment after order is placed but not completed (for redirection payment methods) /// /// Order /// /// A task that represents the asynchronous operation /// The task result contains the result /// public Task CanRePostProcessPaymentAsync(Order order) { return Task.FromResult(false); } /// /// Validate payment form /// /// The parsed form values /// /// A task that represents the asynchronous operation /// The task result contains the list of validating errors /// public Task> ValidatePaymentFormAsync(IFormCollection form) { return Task.FromResult>(new List()); } /// /// Get payment information /// /// The parsed form values /// /// A task that represents the asynchronous operation /// The task result contains the payment info holder /// public Task GetPaymentInfoAsync(IFormCollection form) { return Task.FromResult(new ProcessPaymentRequest()); } /// /// Gets a configuration page URL /// public override string GetConfigurationPageUrl() { return _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext).RouteUrl(PayPalCommerceDefaults.Route.Configuration); } /// /// Gets a view component for displaying plugin in public store ("payment info" checkout step) /// public Type GetPublicViewComponent() { return typeof(PaymentInfoViewComponent); } /// /// Gets widget zones where this widget should be rendered /// /// /// A task that represents the asynchronous operation /// The task result contains the widget zones /// public Task> GetWidgetZonesAsync() { return Task.FromResult>(new List { PublicWidgetZones.ProductDetailsAddInfo, PublicWidgetZones.OrderSummaryContentBefore, PublicWidgetZones.HeaderLinksBefore, PublicWidgetZones.Footer, PublicWidgetZones.OrderSummaryTotals, AdminWidgetZones.OrderShipmentDetailsButtons, AdminWidgetZones.OrderShipmentAddButtons, AdminWidgetZones.PaymentMethodListTop }); } /// /// Gets a type of a view component for displaying widget /// /// Name of the widget zone /// View component type public Type GetWidgetViewComponent(string widgetZone) { ArgumentNullException.ThrowIfNull(widgetZone); if (widgetZone.Equals(PublicWidgetZones.ProductDetailsAddInfo) || widgetZone.Equals(PublicWidgetZones.OrderSummaryContentBefore)) return typeof(ButtonsViewComponent); if (widgetZone.Equals(PublicWidgetZones.HeaderLinksBefore) || widgetZone.Equals(PublicWidgetZones.Footer)) return typeof(LogoViewComponent); if (widgetZone.Equals(PublicWidgetZones.OrderSummaryTotals)) return typeof(MessagesViewComponent); if (widgetZone.Equals(AdminWidgetZones.OrderShipmentDetailsButtons) || widgetZone.Equals(AdminWidgetZones.OrderShipmentAddButtons)) return typeof(ShipmentCarrierViewComponent); if (widgetZone.Equals(AdminWidgetZones.PaymentMethodListTop)) return typeof(PaymentMethodViewComponent); return null; } /// /// Install the plugin /// /// A task that represents the asynchronous operation public override async Task InstallAsync() { await _settingService.SaveSettingAsync(new PayPalCommerceSettings { SetCredentialsManually = false, UseSandbox = false, PaymentType = PaymentType.Capture, UseCardFields = false, CustomerAuthenticationRequired = true, UseApplePay = false, UseGooglePay = false, UseAlternativePayments = false, UseVault = false, SkipOrderConfirmPage = false, UseShipmentTracking = false, DisplayButtonsOnPaymentMethod = true, DisplayButtonsOnProductDetails = true, DisplayButtonsOnShoppingCart = true, DisplayLogoInHeaderLinks = false, DisplayLogoInFooter = false, RequestTimeout = PayPalCommerceDefaults.RequestTimeout, EnabledFunding = "paylater,venmo", StyleLayout = "vertical", StyleColor = "gold", StyleShape = "rect", StyleLabel = "paypal", StyleTagline = "true", HideCheckoutButton = false, ImmediatePaymentRequired = false, OrderValidityInterval = 5 * 60, //5 minutes ConfiguratorSupported = false, MerchantIdRequired = false, LogoInHeaderLinks = "
  • " + "\"Now
  • ", LogoInFooter = "", }); if (!_paymentSettings.ActivePaymentMethodSystemNames.Contains(PayPalCommerceDefaults.SystemName)) { _paymentSettings.ActivePaymentMethodSystemNames.Add(PayPalCommerceDefaults.SystemName); await _settingService.SaveSettingAsync(_paymentSettings); } if (!_widgetSettings.ActiveWidgetSystemNames.Contains(PayPalCommerceDefaults.SystemName)) { _widgetSettings.ActiveWidgetSystemNames.Add(PayPalCommerceDefaults.SystemName); await _settingService.SaveSettingAsync(_widgetSettings); } await _localizationService.AddOrUpdateLocaleResourceAsync(new Dictionary { ["Enums.Nop.Plugin.Payments.PayPalCommerce.Domain.ButtonPlacement.Cart"] = "Shopping cart", ["Enums.Nop.Plugin.Payments.PayPalCommerce.Domain.ButtonPlacement.Product"] = "Product", ["Enums.Nop.Plugin.Payments.PayPalCommerce.Domain.ButtonPlacement.PaymentMethod"] = "Checkout", ["Enums.Nop.Plugin.Payments.PayPalCommerce.Domain.PaymentType.Authorize"] = "Authorize", ["Enums.Nop.Plugin.Payments.PayPalCommerce.Domain.PaymentType.Capture"] = "Capture", ["Plugins.Payments.PayPalCommerce.ApplePay.Discount"] = "Discount", ["Plugins.Payments.PayPalCommerce.ApplePay.Shipping"] = "Shipping", ["Plugins.Payments.PayPalCommerce.ApplePay.Subtotal"] = "Subtotal", ["Plugins.Payments.PayPalCommerce.ApplePay.Tax"] = "Tax", ["Plugins.Payments.PayPalCommerce.Card.Button"] = "Pay now with Card", ["Plugins.Payments.PayPalCommerce.Card.New"] = "Pay by new card", ["Plugins.Payments.PayPalCommerce.Card.Prefix"] = "Pay by", ["Plugins.Payments.PayPalCommerce.Card.Save"] = "Save your card", ["Plugins.Payments.PayPalCommerce.Configuration"] = "Configuration", ["Plugins.Payments.PayPalCommerce.Configuration.Error"] = "Error: {0} (see details in the log)", ["Plugins.Payments.PayPalCommerce.Credentials.Valid"] = "The specified credentials are valid", ["Plugins.Payments.PayPalCommerce.Credentials.Invalid"] = "The specified credentials are invalid", ["Plugins.Payments.PayPalCommerce.Fields.ClientId"] = "Client ID", ["Plugins.Payments.PayPalCommerce.Fields.ClientId.Hint"] = "Enter your PayPal REST API client ID. This identifies your PayPal account and determines where transactions are paid.", ["Plugins.Payments.PayPalCommerce.Fields.ClientId.Required"] = "Client ID is required", ["Plugins.Payments.PayPalCommerce.Fields.CustomerAuthenticationRequired"] = "Use 3D Secure", ["Plugins.Payments.PayPalCommerce.Fields.CustomerAuthenticationRequired.Hint"] = "3D Secure enables you to authenticate card holders through card issuers. It reduces the likelihood of fraud when you use supported cards and improves transaction performance. A successful 3D Secure authentication can shift liability for chargebacks due to fraud from you to the card issuer.", ["Plugins.Payments.PayPalCommerce.Fields.DisplayButtonsOnProductDetails"] = "Display buttons on product details", ["Plugins.Payments.PayPalCommerce.Fields.DisplayButtonsOnProductDetails.Hint"] = "Determine whether to display PayPal buttons on product details pages (simple products only) allowing buyers to complete a purchase without going through the full checkout process.", ["Plugins.Payments.PayPalCommerce.Fields.DisplayButtonsOnShoppingCart"] = "Display buttons on shopping cart", ["Plugins.Payments.PayPalCommerce.Fields.DisplayButtonsOnShoppingCart.Hint"] = "Determine whether to display PayPal buttons on the shopping cart page in addition to the default checkout button.", ["Plugins.Payments.PayPalCommerce.Fields.DisplayLogoInFooter"] = "Display logo in footer", ["Plugins.Payments.PayPalCommerce.Fields.DisplayLogoInFooter.Hint"] = "Determine whether to display PayPal logo in the footer. These logos and banners are a great way to let your buyers know that you choose PayPal to securely process their payments.", ["Plugins.Payments.PayPalCommerce.Fields.DisplayLogoInHeaderLinks"] = "Display logo in header links", ["Plugins.Payments.PayPalCommerce.Fields.DisplayLogoInHeaderLinks.Hint"] = "Determine whether to display PayPal logo in header links. These logos and banners are a great way to let your buyers know that you choose PayPal to securely process their payments.", ["Plugins.Payments.PayPalCommerce.Fields.LogoInFooter"] = "Logo source code", ["Plugins.Payments.PayPalCommerce.Fields.LogoInFooter.Hint"] = "Enter source code of the logo. Find more logos and banners on PayPal Logo Center. You can also modify the code to fit correctly into your theme and site style.", ["Plugins.Payments.PayPalCommerce.Fields.LogoInHeaderLinks"] = "Logo source code", ["Plugins.Payments.PayPalCommerce.Fields.LogoInHeaderLinks.Hint"] = "Enter source code of the logo. Find more logos and banners on PayPal Logo Center. You can also modify the code to fit correctly into your theme and site style.", ["Plugins.Payments.PayPalCommerce.Fields.MerchantId"] = "Merchant ID", ["Plugins.Payments.PayPalCommerce.Fields.MerchantId.Hint"] = "PayPal account ID of the merchant.", ["Plugins.Payments.PayPalCommerce.Fields.MerchantId.Required"] = "Merchant ID is required", ["Plugins.Payments.PayPalCommerce.Fields.PaymentType"] = "Payment type", ["Plugins.Payments.PayPalCommerce.Fields.PaymentType.Hint"] = "Choose a payment type to either capture payment immediately or authorize a payment for an order after order creation. Notice, that alternative payment methods don't work with the 'authorize and capture later' feature.", ["Plugins.Payments.PayPalCommerce.Fields.SecretKey"] = "Secret", ["Plugins.Payments.PayPalCommerce.Fields.SecretKey.Hint"] = "Enter your PayPal REST API secret.", ["Plugins.Payments.PayPalCommerce.Fields.SecretKey.Required"] = "Secret is required", ["Plugins.Payments.PayPalCommerce.Fields.SetCredentialsManually"] = "Specify API credentials manually", ["Plugins.Payments.PayPalCommerce.Fields.SetCredentialsManually.Hint"] = "Determine whether to manually set the credentials (for example, there is already the REST API application created, or if you want to use the sandbox mode).", ["Plugins.Payments.PayPalCommerce.Fields.SkipOrderConfirmPage"] = "Skip 'Confirm Order' page", ["Plugins.Payments.PayPalCommerce.Fields.SkipOrderConfirmPage.Hint"] = "Determine whether to skip the 'Confirm Order' step during checkout so that after approving the payment on PayPal site, customers will redirected directly to the 'Order Completed' page.", ["Plugins.Payments.PayPalCommerce.Fields.UseAlternativePayments"] = "Use Alternative Payments Methods", ["Plugins.Payments.PayPalCommerce.Fields.UseAlternativePayments.Hint"] = "With alternative payment methods, customers across the globe can pay with their bank accounts, wallets, and other local payment methods.", ["Plugins.Payments.PayPalCommerce.Fields.UseApplePay"] = "Use Apple Pay", ["Plugins.Payments.PayPalCommerce.Fields.UseApplePay.Hint"] = "Apple Pay is a mobile payment and digital wallet service provided by Apple Inc.", ["Plugins.Payments.PayPalCommerce.Fields.UseApplePay.Warning"] = "Don't forget to enable 'Serve unknown types of static files' on the App settings page, so that the domain association file is processed correctly.", ["Plugins.Payments.PayPalCommerce.Fields.UseCardFields"] = "Use Custom Card Fields", ["Plugins.Payments.PayPalCommerce.Fields.UseCardFields.Hint"] = "Advanced Credit and Debit Card Payments (Custom Card Fields) are a PCI compliant solution to accept debit and credit card payments.", ["Plugins.Payments.PayPalCommerce.Fields.UseGooglePay"] = "Use Google Pay", ["Plugins.Payments.PayPalCommerce.Fields.UseGooglePay.Hint"] = "Google Pay is a mobile payment and digital wallet service provided by Alphabet Inc.", ["Plugins.Payments.PayPalCommerce.Fields.UseSandbox"] = "Use sandbox", ["Plugins.Payments.PayPalCommerce.Fields.UseSandbox.Hint"] = "Determine whether to use the sandbox environment for testing purposes.", ["Plugins.Payments.PayPalCommerce.Fields.UseShipmentTracking"] = "Use shipment tracking", ["Plugins.Payments.PayPalCommerce.Fields.UseShipmentTracking.Hint"] = "Determine whether to use the package tracking. It allows to automatically sync orders and shipment status with PayPal.", ["Plugins.Payments.PayPalCommerce.Fields.UseVault"] = "Use Vault", ["Plugins.Payments.PayPalCommerce.Fields.UseVault.Hint"] = "Determine whether to use PayPal Vault. It allows to store buyers payment information and use it in subsequent transactions.", ["Plugins.Payments.PayPalCommerce.GooglePay.Discount"] = "Discount", ["Plugins.Payments.PayPalCommerce.GooglePay.Shipping"] = "Shipping", ["Plugins.Payments.PayPalCommerce.GooglePay.Subtotal"] = "Subtotal", ["Plugins.Payments.PayPalCommerce.GooglePay.Tax"] = "Tax", ["Plugins.Payments.PayPalCommerce.GooglePay.Total"] = "Total", ["Plugins.Payments.PayPalCommerce.Onboarding.AccessRevoked"] = "Profile access has been successfully revoked.", ["Plugins.Payments.PayPalCommerce.Onboarding.Button"] = "Sign up for PayPal", ["Plugins.Payments.PayPalCommerce.Onboarding.Button.Sandbox"] = "Sign up for PayPal (sandbox)", ["Plugins.Payments.PayPalCommerce.Onboarding.ButtonRevoke"] = "Revoke access", ["Plugins.Payments.PayPalCommerce.Onboarding.Completed"] = "Onboarding is sucessfully completed", ["Plugins.Payments.PayPalCommerce.Onboarding.Error"] = "An error occurred during the onboarding process, the credentials are empty", ["Plugins.Payments.PayPalCommerce.Onboarding.InProcess"] = "Onboarding is in process, see details below", ["Plugins.Payments.PayPalCommerce.Onboarding.Process.Account.Success"] = "PayPal account is created", ["Plugins.Payments.PayPalCommerce.Onboarding.Process.Email.Success"] = "Email address is confirmed", ["Plugins.Payments.PayPalCommerce.Onboarding.Process.Payments.Success"] = "Billing information is set", ["Plugins.Payments.PayPalCommerce.Onboarding.Sandbox"] = "After you finish testing the plugin in the PayPal sandbox, move it into the production environment so you can process live transactions. To take the plugin live: 1. Revoke access to the sandbox account, 2. Disable 'Use sandbox' setting, 3. Sign up for the live PayPal account.", ["Plugins.Payments.PayPalCommerce.Onboarding.Title"] = "Connect PayPal account", ["Plugins.Payments.PayPalCommerce.Order.Adjustment.Name"] = "Adjustment item", ["Plugins.Payments.PayPalCommerce.Order.Adjustment.Description"] = "Used to adjust the order total amount when applying complex discounts or/and calculations", ["Plugins.Payments.PayPalCommerce.Order.Error"] = "Failed to get order details", ["Plugins.Payments.PayPalCommerce.Order.Id"] = "PayPal order ID", ["Plugins.Payments.PayPalCommerce.Order.Placement"] = "PayPal component placement", ["Plugins.Payments.PayPalCommerce.PaymentTokens"] = "Payment methods", ["Plugins.Payments.PayPalCommerce.PaymentTokens.Default"] = "Default", ["Plugins.Payments.PayPalCommerce.PaymentTokens.Expiration"] = "Expires", ["Plugins.Payments.PayPalCommerce.PaymentTokens.None"] = "No payment methods saved yet", ["Plugins.Payments.PayPalCommerce.PaymentTokens.MarkDefault"] = "Make default", ["Plugins.Payments.PayPalCommerce.PaymentTokens.Title"] = "Method", ["Plugins.Payments.PayPalCommerce.PayLater"] = "Pay Later", ["Plugins.Payments.PayPalCommerce.Prominently"] = "Feature PayPal Prominently", ["Plugins.Payments.PayPalCommerce.PaymentMethodDescription"] = "PayPal Checkout with using methods like Venmo, PayPal Credit, credit card payments", ["Plugins.Payments.PayPalCommerce.RoundingWarning"] = "It looks like you have RoundPricesDuringCalculation setting disabled. Keep in mind that this can lead to a discrepancy of the order total amount, as PayPal rounds to two decimals only.", ["Plugins.Payments.PayPalCommerce.Shipment.Carrier"] = "Carrier", ["Plugins.Payments.PayPalCommerce.Shipment.Carrier.Hint"] = "Specify the carrier for the shipment (e.g. UPS or FEDEX_UK, see allowed values on PayPal site).", ["Plugins.Payments.PayPalCommerce.WebhookWarning"] = "Webhook was not created, so some functions may not work correctly (see details in the log. Please ensure that your store is under SSL, PayPal service doesn't send requests to unsecured sites.)" }); await base.InstallAsync(); } /// /// Uninstall the plugin /// /// A task that represents the asynchronous operation public override async Task UninstallAsync() { //clear webhooks when uninstall var stores = await _storeService.GetAllStoresAsync(); var storeIds = new List { 0 }.Union(stores.Select(store => store.Id)); foreach (var storeId in storeIds) { var settings = await _settingService.LoadSettingAsync(storeId); if (PayPalCommerceServiceManager.IsConnected(settings)) await _serviceManager.DeleteWebhookAsync(settings); } if (_paymentSettings.ActivePaymentMethodSystemNames.Contains(PayPalCommerceDefaults.SystemName)) { _paymentSettings.ActivePaymentMethodSystemNames.Remove(PayPalCommerceDefaults.SystemName); await _settingService.SaveSettingAsync(_paymentSettings); } if (_widgetSettings.ActiveWidgetSystemNames.Contains(PayPalCommerceDefaults.SystemName)) { _widgetSettings.ActiveWidgetSystemNames.Remove(PayPalCommerceDefaults.SystemName); await _settingService.SaveSettingAsync(_widgetSettings); } await _settingService.DeleteSettingAsync(); await _localizationService.DeleteLocaleResourcesAsync("Enums.Nop.Plugin.Payments.PayPalCommerce"); await _localizationService.DeleteLocaleResourcesAsync("Plugins.Payments.PayPalCommerce"); await base.UninstallAsync(); } /// /// Gets a payment method description that will be displayed on checkout pages in the public store /// /// A task that represents the asynchronous operation public async Task GetPaymentMethodDescriptionAsync() { return await _localizationService.GetResourceAsync("Plugins.Payments.PayPalCommerce.PaymentMethodDescription"); } #endregion #region Properties /// /// Gets a value indicating whether capture is supported /// public bool SupportCapture => true; /// /// Gets a value indicating whether void is supported /// public bool SupportVoid => true; /// /// Gets a value indicating whether refund is supported /// public bool SupportRefund => true; /// /// Gets a value indicating whether partial refund is supported /// public bool SupportPartiallyRefund => true; /// /// Gets a recurring payment type of payment method /// public RecurringPaymentType RecurringPaymentType => RecurringPaymentType.NotSupported; /// /// Gets a payment method type /// public PaymentMethodType PaymentMethodType => PaymentMethodType.Standard; /// /// Gets a value indicating whether we should display a payment information page for this plugin /// public bool SkipPaymentInfo => false; /// /// Gets a value indicating whether to hide this plugin on the widget list page in the admin area /// public bool HideInWidgetList => true; #endregion }