diff --git a/.psalm/stubs.php b/.psalm/stubs.php index 7282b6907..6d897c723 100644 --- a/.psalm/stubs.php +++ b/.psalm/stubs.php @@ -2,6 +2,12 @@ if (!defined('PAYPAL_INTEGRATION_DATE')) { define('PAYPAL_INTEGRATION_DATE', '2023-06-02'); } +if (!defined('PAYPAL_URL')) { + define( 'PAYPAL_URL', 'https://www.paypal.com' ); +} +if (!defined('PAYPAL_SANDBOX_URL')) { + define( 'PAYPAL_SANDBOX_URL', 'https://www.sandbox.paypal.com' ); +} if (!defined('EP_PAGES')) { define('EP_PAGES', 4096); } diff --git a/api/order-functions.php b/api/order-functions.php index 701b064fb..340be8585 100644 --- a/api/order-functions.php +++ b/api/order-functions.php @@ -21,6 +21,7 @@ use WooCommerce\PayPalCommerce\PPCP; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Helper\RefundFeesUpdater; use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor; +use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor; use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor; /** @@ -47,6 +48,19 @@ function ppcp_get_paypal_order( $paypal_id_or_wc_order ): Order { return $order_endpoint->order( $paypal_id_or_wc_order ); } +/** + * Creates a PayPal order for the given WC order. + * + * @param WC_Order $wc_order The WC order. + * @throws Exception When the operation fails. + */ +function ppcp_create_paypal_order_for_wc_order( WC_Order $wc_order ): Order { + $order_processor = PPCP::container()->get( 'wcgateway.order-processor' ); + assert( $order_processor instanceof OrderProcessor ); + + return $order_processor->create_order( $wc_order ); +} + /** * Captures the PayPal order. * diff --git a/changelog.txt b/changelog.txt index 723707185..5ef614c32 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,37 @@ *** Changelog *** += 2.4.3 - xxxx-xx-xx = +* Fix - PayPal Subscription initiated without a WooCommerce order #1907 +* Fix - Block Checkout reloads when submitting order with empty fields #1904 +* Fix - "Send checkout billing and shipping data to Apple Pay" displayed when Apple Pay is disabled #1883 +* Fix - "Order does not contain intent" error for ACDC renewals when triggering 3D Secure #1888 +* Enhancement - Add button to reload feature eligibility status from Connection tab #1902 +* Enhancement - Apple Pay validation message improvements #1901 +* Enhancement - Improve support for Classic Cart & Classic Checkout blocks #1894 +* Enhancement - Ensure uniform button appearance for PayPal, Google Pay, and Apple Pay buttons #1900 +* Enhancement - remove string translations for package tracking carriers from repository #1885 +* Enhancement - Incorrect margins when PayPal buttons are rendered as separate gateways. #1908 +* Feature preview - Save payment methods (Vault v3) integration #1779 + += 2.4.2 - 2023-12-04 = +* Fix - Action callback arguments count in ShipStation tracking integration #1841 +* Fix - Google Pay scripts loading on unrelated admin pages #1834 +* Fix - Do not ignore disabled APMs list in blocks #1865 +* Fix - Display Package Tracking metabox below Order actions when HPOS is active #1850 +* Fix - ApplePay use checkout form data to update shipping and billing #1832 +* Fix - Fix Apple Pay CSS #1872 +* Enhancement - Allow redirect to PayPal with "Place order" button if smart buttons failed to load #1840 #1870 +* Enhancement - Extend list of supported countries for Package Tracking v2 integration #1848 +* Enhancement - Improve Block Theme support for Pay Later messaging #1855 +* Enhancement - Render block buttons separately and add block style settings #1858 +* Enhancement - Enable Block Cart and Block Express Checkout button locations by default #1852 +* Enhancement - Improve single product page button placement with Block themes #1847 +* Enhancement - Remove the Home location from default enabled Pay Later messaging locations #1856 +* Enhancement - Chrome browser detected as eligible for Apple Pay on settings page #1828 +* Enhancement - Hide Apple Pay & Google Pay for subscription type products #1835 +* Enhancement - Add Standard Card Button gateway styling settings & preview #1827 +* Feature preview - Upgrade to new Hosted Card Fields for Advanced Card Processing #1843 + = 2.4.1 - 2023-11-14 = * Fix - Error "PayPal order ID not found in meta" prevents automations from triggering when buying subscription via third-party payment gateway #1822 * Fix - Card button subscription support declaration #1796 diff --git a/modules.php b/modules.php index b386df62a..33a15fc3b 100644 --- a/modules.php +++ b/modules.php @@ -20,13 +20,14 @@ return function ( string $root_dir ): iterable { ( require "$modules_dir/ppcp-onboarding/module.php" )(), ( require "$modules_dir/ppcp-session/module.php" )(), ( require "$modules_dir/ppcp-status-report/module.php" )(), - ( require "$modules_dir/ppcp-subscription/module.php" )(), + ( require "$modules_dir/ppcp-wc-subscriptions/module.php" )(), ( require "$modules_dir/ppcp-wc-gateway/module.php" )(), ( require "$modules_dir/ppcp-webhooks/module.php" )(), ( require "$modules_dir/ppcp-vaulting/module.php" )(), ( require "$modules_dir/ppcp-order-tracking/module.php" )(), ( require "$modules_dir/ppcp-uninstall/module.php" )(), ( require "$modules_dir/ppcp-blocks/module.php" )(), + ( require "$modules_dir/ppcp-paypal-subscriptions/module.php" )(), ); if ( apply_filters( // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores @@ -60,5 +61,13 @@ return function ( string $root_dir ): iterable { $modules[] = ( require "$modules_dir/ppcp-card-fields/module.php" )(); } + if ( apply_filters( + //phpcs:disable WordPress.NamingConventions.ValidHookName.UseUnderscores + 'woocommerce.feature-flags.woocommerce_paypal_payments.save_payment_methods_enabled', + getenv( 'PCP_SAVE_PAYMENT_METHODS' ) === '1' + ) ) { + $modules[] = ( require "$modules_dir/ppcp-save-payment-methods/module.php" )(); + } + return $modules; }; diff --git a/modules/ppcp-api-client/services.php b/modules/ppcp-api-client/services.php index c5478554f..be2872c3d 100644 --- a/modules/ppcp-api-client/services.php +++ b/modules/ppcp-api-client/services.php @@ -9,12 +9,16 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\ApiClient; +use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken; +use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentMethodTokensEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Entity\CardAuthenticationResult; +use WooCommerce\PayPalCommerce\ApiClient\Factory\CardAuthenticationResultFactory; use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry; use WooCommerce\PayPalCommerce\Common\Pattern\SingletonDecorator; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingSubscriptions; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\CatalogProducts; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingPlans; -use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerPayableBreakdown; use WooCommerce\PayPalCommerce\ApiClient\Factory\BillingCycleFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentPreferencesFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\RefundFactory; @@ -50,7 +54,6 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PatchCollectionFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayeeFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentsFactory; -use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentSourceFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenActionLinksFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PlatformFeeFactory; @@ -74,31 +77,40 @@ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; return array( - 'api.host' => function( ContainerInterface $container ) : string { + 'api.host' => function( ContainerInterface $container ) : string { return PAYPAL_API_URL; }, - 'api.paypal-host' => function( ContainerInterface $container ) : string { + 'api.paypal-host' => function( ContainerInterface $container ) : string { return PAYPAL_API_URL; }, - 'api.partner_merchant_id' => static function () : string { + // It seems this 'api.paypal-website-url' key is always overridden in ppcp-onboarding/services.php. + 'api.paypal-website-url' => function( ContainerInterface $container ) : string { + return PAYPAL_URL; + }, + 'api.factory.paypal-checkout-url' => function( ContainerInterface $container ) : callable { + return function ( string $id ) use ( $container ): string { + return $container->get( 'api.paypal-website-url' ) . '/checkoutnow?token=' . $id; + }; + }, + 'api.partner_merchant_id' => static function () : string { return ''; }, - 'api.merchant_email' => function () : string { + 'api.merchant_email' => function () : string { return ''; }, - 'api.merchant_id' => function () : string { + 'api.merchant_id' => function () : string { return ''; }, - 'api.key' => static function (): string { + 'api.key' => static function (): string { return ''; }, - 'api.secret' => static function (): string { + 'api.secret' => static function (): string { return ''; }, - 'api.prefix' => static function (): string { + 'api.prefix' => static function (): string { return 'WC-'; }, - 'api.bearer' => static function ( ContainerInterface $container ): Bearer { + 'api.bearer' => static function ( ContainerInterface $container ): Bearer { $cache = new Cache( 'ppcp-paypal-bearer' ); $key = $container->get( 'api.key' ); $secret = $container->get( 'api.secret' ); @@ -114,7 +126,7 @@ return array( $settings ); }, - 'api.endpoint.partners' => static function ( ContainerInterface $container ) : PartnersEndpoint { + 'api.endpoint.partners' => static function ( ContainerInterface $container ) : PartnersEndpoint { return new PartnersEndpoint( $container->get( 'api.host' ), $container->get( 'api.bearer' ), @@ -125,10 +137,10 @@ return array( $container->get( 'api.helper.failure-registry' ) ); }, - 'api.factory.sellerstatus' => static function ( ContainerInterface $container ) : SellerStatusFactory { + 'api.factory.sellerstatus' => static function ( ContainerInterface $container ) : SellerStatusFactory { return new SellerStatusFactory(); }, - 'api.endpoint.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenEndpoint { + 'api.endpoint.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenEndpoint { return new PaymentTokenEndpoint( $container->get( 'api.host' ), $container->get( 'api.bearer' ), @@ -138,7 +150,14 @@ return array( $container->get( 'api.repository.customer' ) ); }, - 'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint { + 'api.endpoint.payment-tokens' => static function( ContainerInterface $container ) : PaymentTokensEndpoint { + return new PaymentTokensEndpoint( + $container->get( 'api.host' ), + $container->get( 'api.bearer' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, + 'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint { return new WebhookEndpoint( $container->get( 'api.host' ), @@ -148,7 +167,7 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ) ); }, - 'api.endpoint.partner-referrals' => static function ( ContainerInterface $container ) : PartnerReferrals { + 'api.endpoint.partner-referrals' => static function ( ContainerInterface $container ) : PartnerReferrals { return new PartnerReferrals( $container->get( 'api.host' ), @@ -156,7 +175,7 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ) ); }, - 'api.endpoint.identity-token' => static function ( ContainerInterface $container ) : IdentityToken { + 'api.endpoint.identity-token' => static function ( ContainerInterface $container ) : IdentityToken { $logger = $container->get( 'woocommerce.logger.woocommerce' ); $settings = $container->get( 'wcgateway.settings' ); $customer_repository = $container->get( 'api.repository.customer' ); @@ -168,7 +187,7 @@ return array( $customer_repository ); }, - 'api.endpoint.payments' => static function ( ContainerInterface $container ): PaymentsEndpoint { + 'api.endpoint.payments' => static function ( ContainerInterface $container ): PaymentsEndpoint { $authorizations_factory = $container->get( 'api.factory.authorization' ); $capture_factory = $container->get( 'api.factory.capture' ); $logger = $container->get( 'woocommerce.logger.woocommerce' ); @@ -181,7 +200,7 @@ return array( $logger ); }, - 'api.endpoint.login-seller' => static function ( ContainerInterface $container ) : LoginSeller { + 'api.endpoint.login-seller' => static function ( ContainerInterface $container ) : LoginSeller { $logger = $container->get( 'woocommerce.logger.woocommerce' ); return new LoginSeller( @@ -190,7 +209,7 @@ return array( $logger ); }, - 'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint { + 'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint { $order_factory = $container->get( 'api.factory.order' ); $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' ); $logger = $container->get( 'woocommerce.logger.woocommerce' ); @@ -204,7 +223,7 @@ return array( $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE'; $application_context_repository = $container->get( 'api.repository.application-context' ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); return new OrderEndpoint( $container->get( 'api.host' ), $container->get( 'api.bearer' ), @@ -219,14 +238,14 @@ return array( $bn_code ); }, - 'api.endpoint.billing-agreements' => static function ( ContainerInterface $container ): BillingAgreementsEndpoint { + 'api.endpoint.billing-agreements' => static function ( ContainerInterface $container ): BillingAgreementsEndpoint { return new BillingAgreementsEndpoint( $container->get( 'api.host' ), $container->get( 'api.bearer' ), $container->get( 'woocommerce.logger.woocommerce' ) ); }, - 'api.endpoint.catalog-products' => static function ( ContainerInterface $container ): CatalogProducts { + 'api.endpoint.catalog-products' => static function ( ContainerInterface $container ): CatalogProducts { return new CatalogProducts( $container->get( 'api.host' ), $container->get( 'api.bearer' ), @@ -234,7 +253,7 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ) ); }, - 'api.endpoint.billing-plans' => static function( ContainerInterface $container ): BillingPlans { + 'api.endpoint.billing-plans' => static function( ContainerInterface $container ): BillingPlans { return new BillingPlans( $container->get( 'api.host' ), $container->get( 'api.bearer' ), @@ -243,53 +262,60 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ) ); }, - 'api.endpoint.billing-subscriptions' => static function( ContainerInterface $container ): BillingSubscriptions { + 'api.endpoint.billing-subscriptions' => static function( ContainerInterface $container ): BillingSubscriptions { return new BillingSubscriptions( $container->get( 'api.host' ), $container->get( 'api.bearer' ), $container->get( 'woocommerce.logger.woocommerce' ) ); }, - 'api.repository.application-context' => static function( ContainerInterface $container ) : ApplicationContextRepository { + 'api.endpoint.payment-method-tokens' => static function( ContainerInterface $container ): PaymentMethodTokensEndpoint { + return new PaymentMethodTokensEndpoint( + $container->get( 'api.host' ), + $container->get( 'api.bearer' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, + 'api.repository.application-context' => static function( ContainerInterface $container ) : ApplicationContextRepository { $settings = $container->get( 'wcgateway.settings' ); return new ApplicationContextRepository( $settings ); }, - 'api.repository.partner-referrals-data' => static function ( ContainerInterface $container ) : PartnerReferralsData { + 'api.repository.partner-referrals-data' => static function ( ContainerInterface $container ) : PartnerReferralsData { $dcc_applies = $container->get( 'api.helpers.dccapplies' ); return new PartnerReferralsData( $dcc_applies ); }, - 'api.repository.payee' => static function ( ContainerInterface $container ): PayeeRepository { + 'api.repository.payee' => static function ( ContainerInterface $container ): PayeeRepository { $merchant_email = $container->get( 'api.merchant_email' ); $merchant_id = $container->get( 'api.merchant_id' ); return new PayeeRepository( $merchant_email, $merchant_id ); }, - 'api.repository.customer' => static function( ContainerInterface $container ): CustomerRepository { + 'api.repository.customer' => static function( ContainerInterface $container ): CustomerRepository { $prefix = $container->get( 'api.prefix' ); return new CustomerRepository( $prefix ); }, - 'api.repository.order' => static function( ContainerInterface $container ): OrderRepository { + 'api.repository.order' => static function( ContainerInterface $container ): OrderRepository { return new OrderRepository( $container->get( 'api.endpoint.order' ) ); }, - 'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory { + 'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory { return new ApplicationContextFactory(); }, - 'api.factory.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenFactory { + 'api.factory.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenFactory { return new PaymentTokenFactory(); }, - 'api.factory.payment-token-action-links' => static function ( ContainerInterface $container ) : PaymentTokenActionLinksFactory { + 'api.factory.payment-token-action-links' => static function ( ContainerInterface $container ) : PaymentTokenActionLinksFactory { return new PaymentTokenActionLinksFactory(); }, - 'api.factory.webhook' => static function ( ContainerInterface $container ): WebhookFactory { + 'api.factory.webhook' => static function ( ContainerInterface $container ): WebhookFactory { return new WebhookFactory(); }, - 'api.factory.webhook-event' => static function ( ContainerInterface $container ): WebhookEventFactory { + 'api.factory.webhook-event' => static function ( ContainerInterface $container ): WebhookEventFactory { return new WebhookEventFactory(); }, - 'api.factory.capture' => static function ( ContainerInterface $container ): CaptureFactory { + 'api.factory.capture' => static function ( ContainerInterface $container ): CaptureFactory { $amount_factory = $container->get( 'api.factory.amount' ); return new CaptureFactory( @@ -298,7 +324,7 @@ return array( $container->get( 'api.factory.fraud-processor-response' ) ); }, - 'api.factory.refund' => static function ( ContainerInterface $container ): RefundFactory { + 'api.factory.refund' => static function ( ContainerInterface $container ): RefundFactory { $amount_factory = $container->get( 'api.factory.amount' ); return new RefundFactory( $amount_factory, @@ -306,7 +332,7 @@ return array( $container->get( 'api.factory.refund_payer' ) ); }, - 'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory { + 'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory { $amount_factory = $container->get( 'api.factory.amount' ); $item_factory = $container->get( 'api.factory.item' ); @@ -326,32 +352,32 @@ return array( $sanitizer ); }, - 'api.factory.patch-collection-factory' => static function ( ContainerInterface $container ): PatchCollectionFactory { + 'api.factory.patch-collection-factory' => static function ( ContainerInterface $container ): PatchCollectionFactory { return new PatchCollectionFactory(); }, - 'api.factory.payee' => static function ( ContainerInterface $container ): PayeeFactory { + 'api.factory.payee' => static function ( ContainerInterface $container ): PayeeFactory { return new PayeeFactory(); }, - 'api.factory.item' => static function ( ContainerInterface $container ): ItemFactory { + 'api.factory.item' => static function ( ContainerInterface $container ): ItemFactory { return new ItemFactory( $container->get( 'api.shop.currency' ) ); }, - 'api.factory.shipping' => static function ( ContainerInterface $container ): ShippingFactory { + 'api.factory.shipping' => static function ( ContainerInterface $container ): ShippingFactory { return new ShippingFactory( $container->get( 'api.factory.address' ), $container->get( 'api.factory.shipping-option' ) ); }, - 'api.factory.shipping-preference' => static function ( ContainerInterface $container ): ShippingPreferenceFactory { + 'api.factory.shipping-preference' => static function ( ContainerInterface $container ): ShippingPreferenceFactory { return new ShippingPreferenceFactory(); }, - 'api.factory.shipping-option' => static function ( ContainerInterface $container ): ShippingOptionFactory { + 'api.factory.shipping-option' => static function ( ContainerInterface $container ): ShippingOptionFactory { return new ShippingOptionFactory( $container->get( 'api.factory.money' ) ); }, - 'api.factory.amount' => static function ( ContainerInterface $container ): AmountFactory { + 'api.factory.amount' => static function ( ContainerInterface $container ): AmountFactory { $item_factory = $container->get( 'api.factory.item' ); return new AmountFactory( $item_factory, @@ -359,86 +385,84 @@ return array( $container->get( 'api.shop.currency' ) ); }, - 'api.factory.money' => static function ( ContainerInterface $container ): MoneyFactory { + 'api.factory.money' => static function ( ContainerInterface $container ): MoneyFactory { return new MoneyFactory(); }, - 'api.factory.payer' => static function ( ContainerInterface $container ): PayerFactory { + 'api.factory.payer' => static function ( ContainerInterface $container ): PayerFactory { $address_factory = $container->get( 'api.factory.address' ); return new PayerFactory( $address_factory ); }, - 'api.factory.refund_payer' => static function ( ContainerInterface $container ): RefundPayerFactory { + 'api.factory.refund_payer' => static function ( ContainerInterface $container ): RefundPayerFactory { return new RefundPayerFactory(); }, - 'api.factory.address' => static function ( ContainerInterface $container ): AddressFactory { + 'api.factory.address' => static function ( ContainerInterface $container ): AddressFactory { return new AddressFactory(); }, - 'api.factory.payment-source' => static function ( ContainerInterface $container ): PaymentSourceFactory { - return new PaymentSourceFactory(); - }, - 'api.factory.order' => static function ( ContainerInterface $container ): OrderFactory { + 'api.factory.order' => static function ( ContainerInterface $container ): OrderFactory { $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' ); $payer_factory = $container->get( 'api.factory.payer' ); $application_context_repository = $container->get( 'api.repository.application-context' ); $application_context_factory = $container->get( 'api.factory.application-context' ); - $payment_source_factory = $container->get( 'api.factory.payment-source' ); return new OrderFactory( $purchase_unit_factory, $payer_factory, $application_context_repository, - $application_context_factory, - $payment_source_factory + $application_context_factory ); }, - 'api.factory.payments' => static function ( ContainerInterface $container ): PaymentsFactory { + 'api.factory.payments' => static function ( ContainerInterface $container ): PaymentsFactory { $authorizations_factory = $container->get( 'api.factory.authorization' ); $capture_factory = $container->get( 'api.factory.capture' ); $refund_factory = $container->get( 'api.factory.refund' ); return new PaymentsFactory( $authorizations_factory, $capture_factory, $refund_factory ); }, - 'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory { + 'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory { return new AuthorizationFactory(); }, - 'api.factory.exchange-rate' => static function ( ContainerInterface $container ): ExchangeRateFactory { + 'api.factory.exchange-rate' => static function ( ContainerInterface $container ): ExchangeRateFactory { return new ExchangeRateFactory(); }, - 'api.factory.platform-fee' => static function ( ContainerInterface $container ): PlatformFeeFactory { + 'api.factory.platform-fee' => static function ( ContainerInterface $container ): PlatformFeeFactory { return new PlatformFeeFactory( $container->get( 'api.factory.money' ), $container->get( 'api.factory.payee' ) ); }, - 'api.factory.seller-receivable-breakdown' => static function ( ContainerInterface $container ): SellerReceivableBreakdownFactory { + 'api.factory.seller-receivable-breakdown' => static function ( ContainerInterface $container ): SellerReceivableBreakdownFactory { return new SellerReceivableBreakdownFactory( $container->get( 'api.factory.money' ), $container->get( 'api.factory.exchange-rate' ), $container->get( 'api.factory.platform-fee' ) ); }, - 'api.factory.seller-payable-breakdown' => static function ( ContainerInterface $container ): SellerPayableBreakdownFactory { + 'api.factory.seller-payable-breakdown' => static function ( ContainerInterface $container ): SellerPayableBreakdownFactory { return new SellerPayableBreakdownFactory( $container->get( 'api.factory.money' ), $container->get( 'api.factory.platform-fee' ) ); }, - 'api.factory.fraud-processor-response' => static function ( ContainerInterface $container ): FraudProcessorResponseFactory { + 'api.factory.fraud-processor-response' => static function ( ContainerInterface $container ): FraudProcessorResponseFactory { return new FraudProcessorResponseFactory(); }, - 'api.factory.product' => static function( ContainerInterface $container ): ProductFactory { + 'api.factory.product' => static function( ContainerInterface $container ): ProductFactory { return new ProductFactory(); }, - 'api.factory.billing-cycle' => static function( ContainerInterface $container ): BillingCycleFactory { + 'api.factory.billing-cycle' => static function( ContainerInterface $container ): BillingCycleFactory { return new BillingCycleFactory( $container->get( 'api.shop.currency' ) ); }, - 'api.factory.payment-preferences' => static function( ContainerInterface $container ):PaymentPreferencesFactory { + 'api.factory.payment-preferences' => static function( ContainerInterface $container ):PaymentPreferencesFactory { return new PaymentPreferencesFactory( $container->get( 'api.shop.currency' ) ); }, - 'api.factory.plan' => static function( ContainerInterface $container ): PlanFactory { + 'api.factory.plan' => static function( ContainerInterface $container ): PlanFactory { return new PlanFactory( $container->get( 'api.factory.billing-cycle' ), $container->get( 'api.factory.payment-preferences' ) ); }, - 'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies { + 'api.factory.card-authentication-result-factory' => static function( ContainerInterface $container ): CardAuthenticationResultFactory { + return new CardAuthenticationResultFactory(); + }, + 'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies { return new DccApplies( $container->get( 'api.dcc-supported-country-currency-matrix' ), $container->get( 'api.dcc-supported-country-card-matrix' ), @@ -447,7 +471,7 @@ return array( ); }, - 'api.shop.currency' => static function ( ContainerInterface $container ) : string { + 'api.shop.currency' => static function ( ContainerInterface $container ) : string { $currency = get_woocommerce_currency(); if ( $currency ) { return $currency; @@ -460,18 +484,18 @@ return array( return $currency; }, - 'api.shop.country' => static function ( ContainerInterface $container ) : string { + 'api.shop.country' => static function ( ContainerInterface $container ) : string { $location = wc_get_base_location(); return $location['country']; }, - 'api.shop.is-psd2-country' => static function ( ContainerInterface $container ) : bool { + 'api.shop.is-psd2-country' => static function ( ContainerInterface $container ) : bool { return in_array( $container->get( 'api.shop.country' ), $container->get( 'api.psd2-countries' ), true ); }, - 'api.shop.is-currency-supported' => static function ( ContainerInterface $container ) : bool { + 'api.shop.is-currency-supported' => static function ( ContainerInterface $container ) : bool { return in_array( $container->get( 'api.shop.currency' ), $container->get( 'api.supported-currencies' ), @@ -480,7 +504,7 @@ return array( }, - 'api.shop.is-latin-america' => static function ( ContainerInterface $container ): bool { + 'api.shop.is-latin-america' => static function ( ContainerInterface $container ): bool { return in_array( $container->get( 'api.shop.country' ), array( @@ -538,7 +562,7 @@ return array( * * From https://developer.paypal.com/docs/reports/reference/paypal-supported-currencies/ */ - 'api.supported-currencies' => static function ( ContainerInterface $container ) : array { + 'api.supported-currencies' => static function ( ContainerInterface $container ) : array { return array( 'AUD', 'BRL', @@ -571,7 +595,7 @@ return array( /** * The matrix which countries and currency combinations can be used for DCC. */ - 'api.dcc-supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array { + 'api.dcc-supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array { /** * Returns which countries and currency combinations can be used for DCC. */ @@ -893,7 +917,7 @@ return array( /** * Which countries support which credit cards. Empty credit card arrays mean no restriction on currency. */ - 'api.dcc-supported-country-card-matrix' => static function ( ContainerInterface $container ) : array { + 'api.dcc-supported-country-card-matrix' => static function ( ContainerInterface $container ) : array { /** * Returns which countries support which credit cards. Empty credit card arrays mean no restriction on currency. */ @@ -1062,7 +1086,7 @@ return array( ); }, - 'api.psd2-countries' => static function ( ContainerInterface $container ) : array { + 'api.psd2-countries' => static function ( ContainerInterface $container ) : array { return array( 'AT', 'BE', @@ -1094,19 +1118,19 @@ return array( 'SE', ); }, - 'api.order-helper' => static function( ContainerInterface $container ): OrderHelper { + 'api.order-helper' => static function( ContainerInterface $container ): OrderHelper { return new OrderHelper(); }, - 'api.helper.order-transient' => static function( ContainerInterface $container ): OrderTransient { + 'api.helper.order-transient' => static function( ContainerInterface $container ): OrderTransient { $cache = new Cache( 'ppcp-paypal-bearer' ); $purchase_unit_sanitizer = $container->get( 'api.helper.purchase-unit-sanitizer' ); return new OrderTransient( $cache, $purchase_unit_sanitizer ); }, - 'api.helper.failure-registry' => static function( ContainerInterface $container ): FailureRegistry { + 'api.helper.failure-registry' => static function( ContainerInterface $container ): FailureRegistry { $cache = new Cache( 'ppcp-paypal-api-status-cache' ); return new FailureRegistry( $cache ); }, - 'api.helper.purchase-unit-sanitizer' => SingletonDecorator::make( + 'api.helper.purchase-unit-sanitizer' => SingletonDecorator::make( static function( ContainerInterface $container ): PurchaseUnitSanitizer { $settings = $container->get( 'wcgateway.settings' ); assert( $settings instanceof Settings ); @@ -1116,4 +1140,11 @@ return array( return new PurchaseUnitSanitizer( $behavior, $line_name ); } ), + 'api.user-id-token' => static function( ContainerInterface $container ): UserIdToken { + return new UserIdToken( + $container->get( 'api.host' ), + $container->get( 'api.bearer' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, ); diff --git a/modules/ppcp-api-client/src/Authentication/UserIdToken.php b/modules/ppcp-api-client/src/Authentication/UserIdToken.php new file mode 100644 index 000000000..cae8cb58a --- /dev/null +++ b/modules/ppcp-api-client/src/Authentication/UserIdToken.php @@ -0,0 +1,105 @@ +host = $host; + $this->bearer = $bearer; + $this->logger = $logger; + } + + /** + * Returns `id_token` which uniquely identifies the payer. + * + * @param string $target_customer_id Vaulted customer id. + * + * @return string + * + * @throws PayPalApiException If the request fails. + * @throws RuntimeException If something unexpected happens. + */ + public function id_token( string $target_customer_id = '' ): string { + $bearer = $this->bearer->bearer(); + + $url = trailingslashit( $this->host ) . 'v1/oauth2/token?grant_type=client_credentials&response_type=id_token'; + if ( $target_customer_id ) { + $url = add_query_arg( + array( + 'target_customer_id' => $target_customer_id, + ), + $url + ); + } + + $args = array( + 'method' => 'POST', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/x-www-form-urlencoded', + ), + ); + + $response = $this->request( $url, $args ); + if ( $response instanceof WP_Error ) { + throw new RuntimeException( $response->get_error_message() ); + } + + $json = json_decode( $response['body'] ); + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( 200 !== $status_code ) { + throw new PayPalApiException( $json, $status_code ); + } + + return $json->id_token; + } +} diff --git a/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php b/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php index abba2c182..91b45d550 100644 --- a/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php @@ -18,6 +18,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\PatchCollection; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer; +use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken; use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; @@ -27,7 +28,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PatchCollectionFactory; use WooCommerce\PayPalCommerce\ApiClient\Helper\ErrorResponse; use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository; use Psr\Log\LoggerInterface; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNet; use WP_Error; @@ -174,12 +175,15 @@ class OrderEndpoint { /** * Creates an order. * - * @param PurchaseUnit[] $items The purchase unit items for the order. - * @param string $shipping_preference One of ApplicationContext::SHIPPING_PREFERENCE_ values. - * @param Payer|null $payer The payer off the order. - * @param PaymentToken|null $payment_token The payment token. - * @param string $paypal_request_id The paypal request id. - * @param string $user_action The user action. + * @param PurchaseUnit[] $items The purchase unit items for the order. + * @param string $shipping_preference One of ApplicationContext::SHIPPING_PREFERENCE_ values. + * @param Payer|null $payer The payer off the order. + * @param PaymentToken|null $payment_token The payment token. + * @param string $paypal_request_id The PayPal request id. + * @param string $user_action The user action. + * @param string $payment_method WC payment method. + * @param array $request_data Request data. + * @param PaymentSource|null $payment_source The payment source. * * @return Order * @throws RuntimeException If the request fails. @@ -190,7 +194,10 @@ class OrderEndpoint { Payer $payer = null, PaymentToken $payment_token = null, string $paypal_request_id = '', - string $user_action = ApplicationContext::USER_ACTION_CONTINUE + string $user_action = ApplicationContext::USER_ACTION_CONTINUE, + string $payment_method = '', + array $request_data = array(), + PaymentSource $payment_source = null ): Order { $bearer = $this->bearer->bearer(); $data = array( @@ -217,11 +224,16 @@ class OrderEndpoint { if ( $payment_token ) { $data['payment_source']['token'] = $payment_token->to_array(); } + if ( $payment_source ) { + $data['payment_source'] = array( + $payment_source->name() => $payment_source->properties(), + ); + } /** * The filter can be used to modify the order creation request body data. */ - $data = apply_filters( 'ppcp_create_order_request_body_data', $data ); + $data = apply_filters( 'ppcp_create_order_request_body_data', $data, $payment_method, $request_data ); $url = trailingslashit( $this->host ) . 'v2/checkout/orders'; $args = array( 'method' => 'POST', @@ -260,26 +272,25 @@ class OrderEndpoint { ); throw $error; } + $json = json_decode( $response['body'] ); $status_code = (int) wp_remote_retrieve_response_code( $response ); - if ( 201 !== $status_code ) { + if ( ! in_array( $status_code, array( 200, 201 ), true ) ) { $error = new PayPalApiException( $json, $status_code ); - $this->logger->log( - 'warning', + + $this->logger->warning( sprintf( 'Failed to create order. PayPal API response: %1$s', $error->getMessage() - ), - array( - 'args' => $args, - 'response' => $response, ) ); + throw $error; } + $order = $this->order_factory->from_paypal_response( $json ); do_action( 'woocommerce_paypal_payments_paypal_order_created', $order ); diff --git a/modules/ppcp-api-client/src/Endpoint/PaymentMethodTokensEndpoint.php b/modules/ppcp-api-client/src/Endpoint/PaymentMethodTokensEndpoint.php new file mode 100644 index 000000000..ab8d5473b --- /dev/null +++ b/modules/ppcp-api-client/src/Endpoint/PaymentMethodTokensEndpoint.php @@ -0,0 +1,155 @@ +host = $host; + $this->bearer = $bearer; + $this->logger = $logger; + } + + /** + * Creates a setup token. + * + * @param PaymentSource $payment_source The payment source. + * + * @return stdClass + * + * @throws RuntimeException When something when wrong with the request. + * @throws PayPalApiException When something when wrong setting up the token. + */ + public function setup_tokens( PaymentSource $payment_source ): stdClass { + $data = array( + 'payment_source' => array( + $payment_source->name() => $payment_source->properties(), + ), + ); + + $bearer = $this->bearer->bearer(); + $url = trailingslashit( $this->host ) . 'v3/vault/setup-tokens'; + + $args = array( + 'method' => 'POST', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/json', + 'PayPal-Request-Id' => uniqid( 'ppcp-', true ), + ), + 'body' => wp_json_encode( $data ), + ); + + $response = $this->request( $url, $args ); + + if ( is_wp_error( $response ) || ! is_array( $response ) ) { + throw new RuntimeException( 'Not able to create setup token.' ); + } + + $json = json_decode( $response['body'] ); + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( ! in_array( $status_code, array( 200, 201 ), true ) ) { + throw new PayPalApiException( + $json, + $status_code + ); + } + + return $json; + } + + /** + * Creates a payment token for the given payment source. + * + * @param PaymentSource $payment_source The payment source. + * + * @return stdClass + * + * @throws RuntimeException When something when wrong with the request. + * @throws PayPalApiException When something when wrong setting up the token. + */ + public function payment_tokens( PaymentSource $payment_source ): stdClass { + $data = array( + 'payment_source' => array( + $payment_source->name() => $payment_source->properties(), + ), + ); + + $bearer = $this->bearer->bearer(); + $url = trailingslashit( $this->host ) . 'v3/vault/payment-tokens'; + + $args = array( + 'method' => 'POST', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/json', + 'PayPal-Request-Id' => uniqid( 'ppcp-', true ), + ), + 'body' => wp_json_encode( $data ), + ); + + $response = $this->request( $url, $args ); + + if ( is_wp_error( $response ) || ! is_array( $response ) ) { + throw new RuntimeException( 'Not able to create setup token.' ); + } + + $json = json_decode( $response['body'] ); + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( ! in_array( $status_code, array( 200, 201 ), true ) ) { + throw new PayPalApiException( + $json, + $status_code + ); + } + + return $json; + } +} diff --git a/modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php b/modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php new file mode 100644 index 000000000..bfe05d1b5 --- /dev/null +++ b/modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php @@ -0,0 +1,95 @@ +host = $host; + $this->bearer = $bearer; + $this->logger = $logger; + } + + /** + * Deletes a payment token with the given id. + * + * @param string $id Payment token id. + * + * @return void + * + * @throws RuntimeException When something went wrong with the request. + * @throws PayPalApiException When something went wrong deleting the payment token. + */ + public function delete( string $id ): void { + $bearer = $this->bearer->bearer(); + $url = trailingslashit( $this->host ) . 'v3/vault/payment-tokens/' . $id; + $args = array( + 'method' => 'DELETE', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/json', + ), + ); + + $response = $this->request( $url, $args ); + if ( $response instanceof WP_Error ) { + throw new RuntimeException( $response->get_error_message() ); + } + + $json = json_decode( $response['body'] ); + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( 204 !== $status_code ) { + throw new PayPalApiException( $json, $status_code ); + } + } +} diff --git a/modules/ppcp-api-client/src/Entity/CardAuthenticationResult.php b/modules/ppcp-api-client/src/Entity/CardAuthenticationResult.php index 7eedf7d56..e4d969c5f 100644 --- a/modules/ppcp-api-client/src/Entity/CardAuthenticationResult.php +++ b/modules/ppcp-api-client/src/Entity/CardAuthenticationResult.php @@ -14,7 +14,6 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Entity; */ class CardAuthenticationResult { - const LIABILITY_SHIFT_POSSIBLE = 'POSSIBLE'; const LIABILITY_SHIFT_NO = 'NO'; const LIABILITY_SHIFT_UNKNOWN = 'UNKNOWN'; diff --git a/modules/ppcp-api-client/src/Entity/Order.php b/modules/ppcp-api-client/src/Entity/Order.php index 67eb982a3..d40e7a4e6 100644 --- a/modules/ppcp-api-client/src/Entity/Order.php +++ b/modules/ppcp-api-client/src/Entity/Order.php @@ -107,14 +107,6 @@ class Order { $this->id = $id; $this->application_context = $application_context; - $this->purchase_units = array_values( - array_filter( - $purchase_units, - static function ( $unit ): bool { - return is_a( $unit, PurchaseUnit::class ); - } - ) - ); $this->payer = $payer; $this->order_status = $order_status; $this->intent = ( 'CAPTURE' === $intent ) ? 'CAPTURE' : 'AUTHORIZE'; @@ -236,9 +228,6 @@ class Order { if ( $this->application_context() ) { $order['application_context'] = $this->application_context()->to_array(); } - if ( $this->payment_source() ) { - $order['payment_source'] = $this->payment_source()->to_array(); - } return $order; } diff --git a/modules/ppcp-api-client/src/Entity/OrderStatus.php b/modules/ppcp-api-client/src/Entity/OrderStatus.php index e2dec053b..387830dd3 100644 --- a/modules/ppcp-api-client/src/Entity/OrderStatus.php +++ b/modules/ppcp-api-client/src/Entity/OrderStatus.php @@ -15,14 +15,15 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; * Class OrderStatus */ class OrderStatus { - const INTERNAL = 'INTERNAL'; - const CREATED = 'CREATED'; - const SAVED = 'SAVED'; - const APPROVED = 'APPROVED'; - const VOIDED = 'VOIDED'; - const COMPLETED = 'COMPLETED'; - const PENDING_APPROVAL = 'PENDING_APPROVAL'; - const VALID_STATUS = array( + const INTERNAL = 'INTERNAL'; + const CREATED = 'CREATED'; + const SAVED = 'SAVED'; + const APPROVED = 'APPROVED'; + const VOIDED = 'VOIDED'; + const COMPLETED = 'COMPLETED'; + const PENDING_APPROVAL = 'PENDING_APPROVAL'; + const PAYER_ACTION_REQUIRED = 'PAYER_ACTION_REQUIRED'; + const VALID_STATUS = array( self::INTERNAL, self::CREATED, self::SAVED, @@ -30,6 +31,7 @@ class OrderStatus { self::VOIDED, self::COMPLETED, self::PENDING_APPROVAL, + self::PAYER_ACTION_REQUIRED, ); /** diff --git a/modules/ppcp-api-client/src/Entity/PaymentSource.php b/modules/ppcp-api-client/src/Entity/PaymentSource.php index dcac61108..d3f1a8cc7 100644 --- a/modules/ppcp-api-client/src/Entity/PaymentSource.php +++ b/modules/ppcp-api-client/src/Entity/PaymentSource.php @@ -9,74 +9,53 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\ApiClient\Entity; +use stdClass; + /** * Class PaymentSource */ class PaymentSource { /** - * The card. + * Payment source name. * - * @var PaymentSourceCard|null + * @var string */ - private $card; + private $name; /** - * The wallet. + * Payment source properties. * - * @var PaymentSourceWallet|null + * @var object */ - private $wallet; + private $properties; /** * PaymentSource constructor. * - * @param PaymentSourceCard|null $card The card. - * @param PaymentSourceWallet|null $wallet The wallet. + * @param string $name Payment source name. + * @param object $properties Payment source properties. */ - public function __construct( - PaymentSourceCard $card = null, - PaymentSourceWallet $wallet = null - ) { - - $this->card = $card; - $this->wallet = $wallet; + public function __construct( string $name, object $properties ) { + $this->name = $name; + $this->properties = $properties; } /** - * Returns the card. + * Payment source name. * - * @return PaymentSourceCard|null + * @return string */ - public function card() { - - return $this->card; + public function name(): string { + return $this->name; } /** - * Returns the wallet. + * Payment source properties. * - * @return PaymentSourceWallet|null + * @return object */ - public function wallet() { - - return $this->wallet; - } - - /** - * Returns the array of the object. - * - * @return array - */ - public function to_array(): array { - - $data = array(); - if ( $this->card() ) { - $data['card'] = $this->card()->to_array(); - } - if ( $this->wallet() ) { - $data['wallet'] = $this->wallet()->to_array(); - } - return $data; + public function properties(): object { + return $this->properties; } } diff --git a/modules/ppcp-api-client/src/Entity/PaymentSourceCard.php b/modules/ppcp-api-client/src/Entity/PaymentSourceCard.php deleted file mode 100644 index 1edc7eb37..000000000 --- a/modules/ppcp-api-client/src/Entity/PaymentSourceCard.php +++ /dev/null @@ -1,123 +0,0 @@ -last_digits = $last_digits; - $this->brand = $brand; - $this->type = $type; - $this->authentication_result = $authentication_result; - } - - /** - * Returns the last digits. - * - * @return string - */ - public function last_digits(): string { - - return $this->last_digits; - } - - /** - * Returns the brand. - * - * @return string - */ - public function brand(): string { - - return $this->brand; - } - - /** - * Returns the type. - * - * @return string - */ - public function type(): string { - - return $this->type; - } - - /** - * Returns the authentication result. - * - * @return CardAuthenticationResult|null - */ - public function authentication_result() { - - return $this->authentication_result; - } - - /** - * Returns the object as array. - * - * @return array - */ - public function to_array(): array { - - $data = array( - 'last_digits' => $this->last_digits(), - 'brand' => $this->brand(), - 'type' => $this->type(), - ); - if ( $this->authentication_result() ) { - $data['authentication_result'] = $this->authentication_result()->to_array(); - } - return $data; - } -} diff --git a/modules/ppcp-api-client/src/Entity/PaymentSourceWallet.php b/modules/ppcp-api-client/src/Entity/PaymentSourceWallet.php deleted file mode 100644 index 18a5a7742..000000000 --- a/modules/ppcp-api-client/src/Entity/PaymentSourceWallet.php +++ /dev/null @@ -1,25 +0,0 @@ -liability_shift ?? '', + $authentication_result->three_d_secure->enrollment_status ?? '', + $authentication_result->three_d_secure->authentication_status ?? '' + ); + } +} diff --git a/modules/ppcp-api-client/src/Factory/OrderFactory.php b/modules/ppcp-api-client/src/Factory/OrderFactory.php index 7a7f057db..0b8876594 100644 --- a/modules/ppcp-api-client/src/Factory/OrderFactory.php +++ b/modules/ppcp-api-client/src/Factory/OrderFactory.php @@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Factory; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; +use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository; @@ -48,13 +49,6 @@ class OrderFactory { */ private $application_context_factory; - /** - * The PaymentSource factory. - * - * @var PaymentSourceFactory - */ - private $payment_source_factory; - /** * OrderFactory constructor. * @@ -62,21 +56,18 @@ class OrderFactory { * @param PayerFactory $payer_factory The Payer factory. * @param ApplicationContextRepository $application_context_repository The Application Context repository. * @param ApplicationContextFactory $application_context_factory The Application Context factory. - * @param PaymentSourceFactory $payment_source_factory The Payment Source factory. */ public function __construct( PurchaseUnitFactory $purchase_unit_factory, PayerFactory $payer_factory, ApplicationContextRepository $application_context_repository, - ApplicationContextFactory $application_context_factory, - PaymentSourceFactory $payment_source_factory + ApplicationContextFactory $application_context_factory ) { $this->purchase_unit_factory = $purchase_unit_factory; $this->payer_factory = $payer_factory; $this->application_context_repository = $application_context_repository; $this->application_context_factory = $application_context_factory; - $this->payment_source_factory = $payment_source_factory; } /** @@ -152,9 +143,23 @@ class OrderFactory { $application_context = ( isset( $order_data->application_context ) ) ? $this->application_context_factory->from_paypal_response( $order_data->application_context ) : null; - $payment_source = ( isset( $order_data->payment_source ) ) ? - $this->payment_source_factory->from_paypal_response( $order_data->payment_source ) : - null; + + $payment_source = null; + if ( isset( $order_data->payment_source ) ) { + $json_encoded_payment_source = wp_json_encode( $order_data->payment_source ); + if ( $json_encoded_payment_source ) { + $payment_source_as_array = json_decode( $json_encoded_payment_source, true ); + if ( $payment_source_as_array ) { + $name = array_key_first( $payment_source_as_array ); + if ( $name ) { + $payment_source = new PaymentSource( + $name, + $order_data->payment_source->$name + ); + } + } + } + } return new Order( $order_data->id, diff --git a/modules/ppcp-api-client/src/Factory/PaymentSourceFactory.php b/modules/ppcp-api-client/src/Factory/PaymentSourceFactory.php deleted file mode 100644 index b4efffb0e..000000000 --- a/modules/ppcp-api-client/src/Factory/PaymentSourceFactory.php +++ /dev/null @@ -1,53 +0,0 @@ -card ) ) { - $authentication_result = null; - if ( isset( $data->card->authentication_result ) ) { - $authentication_result = new CardAuthenticationResult( - isset( $data->card->authentication_result->liability_shift ) ? - (string) $data->card->authentication_result->liability_shift : '', - isset( $data->card->authentication_result->three_d_secure->enrollment_status ) ? - (string) $data->card->authentication_result->three_d_secure->enrollment_status : '', - isset( $data->card->authentication_result->three_d_secure->authentication_status ) ? - (string) $data->card->authentication_result->three_d_secure->authentication_status : '' - ); - } - $card = new PaymentSourceCard( - isset( $data->card->last_digits ) ? (string) $data->card->last_digits : '', - isset( $data->card->brand ) ? (string) $data->card->brand : '', - isset( $data->card->type ) ? (string) $data->card->type : '', - $authentication_result - ); - } - return new PaymentSource( $card, $wallet ); - } -} diff --git a/modules/ppcp-applepay/extensions.php b/modules/ppcp-applepay/extensions.php index 89828849f..fe810320e 100644 --- a/modules/ppcp-applepay/extensions.php +++ b/modules/ppcp-applepay/extensions.php @@ -49,7 +49,9 @@ return array( // Domain validation. $domain_validation_text = __( 'Status: Domain validation failed ❌', 'woocommerce-paypal-payments' ); - if ( $container->get( 'applepay.is_validated' ) ) { + if ( ! $container->get( 'applepay.has_validated' ) ) { + $domain_validation_text = __( 'The domain has not yet been validated. Use the Apple Pay button to validate the domain ❌', 'woocommerce-paypal-payments' ); + } elseif ( $container->get( 'applepay.is_validated' ) ) { $domain_validation_text = __( 'Status: Domain successfully validated ✔️', 'woocommerce-paypal-payments' ); } @@ -157,6 +159,7 @@ return array( ->action_visible( 'applepay_button_color' ) ->action_visible( 'applepay_button_type' ) ->action_visible( 'applepay_button_language' ) + ->action_visible( 'applepay_checkout_data_mode' ) ->to_array(), ) ), diff --git a/modules/ppcp-applepay/resources/css/styles.scss b/modules/ppcp-applepay/resources/css/styles.scss index 5eabe5640..858094433 100644 --- a/modules/ppcp-applepay/resources/css/styles.scss +++ b/modules/ppcp-applepay/resources/css/styles.scss @@ -1,63 +1,44 @@ -#applepay-container, .ppcp-button-applepay { +.ppcp-button-applepay { + // Should replicate apm-button.scss sizes. --apple-pay-button-height: 45px; - --apple-pay-button-min-height: 40px; + --apple-pay-button-min-height: 35px; --apple-pay-button-width: 100%; --apple-pay-button-max-width: 750px; --apple-pay-button-border-radius: 4px; --apple-pay-button-overflow: hidden; - margin:7px 0; + + .ppcp-width-min & { + --apple-pay-button-height: 35px; + } + .ppcp-width-300 & { + --apple-pay-button-height: 45px; + } + .ppcp-width-500 & { + --apple-pay-button-height: 55px; + } + &.ppcp-button-pill { --apple-pay-button-border-radius: 50px; } &.ppcp-button-minicart { --apple-pay-button-display: block; - --apple-pay-button-height: 40px; } } -.woocommerce-checkout { - #applepay-container, .ppcp-button-applepay { - margin-top: 0.5em; - --apple-pay-button-border-radius: 4px; - --apple-pay-button-height: 45px; - &.ppcp-button-pill { - --apple-pay-button-border-radius: 50px; - } - } -} +.wp-block-woocommerce-checkout, .wp-block-woocommerce-cart { + .ppcp-button-applepay { + --apple-pay-button-margin: 0; -.ppcp-has-applepay-block { - - .wp-block-woocommerce-checkout { - #applepay-container, .ppcp-button-applepay { - --apple-pay-button-margin: 0; - --apple-pay-button-height: 40px; - &.ppcp-button-pill { - --apple-pay-button-border-radius: 50px; - } - } - } - - .wp-block-woocommerce-cart { - #applepay-container, .ppcp-button-applepay { - --apple-pay-button-margin: 0; - --apple-pay-button-height: 40px; - } - /* Workaround for blocks grid */ - .wc-block-components-express-payment__event-buttons { - --apple-pay-button-display: block; - li[id*="express-payment-method-ppcp-"] { - --apple-pay-button-padding-bottom: 0; - } + apple-pay-button { + min-width: 0; + width: 100%; + --apple-pay-button-width-default: 100%; } } } .wp-admin { - .ppcp-button-applepay { - pointer-events: none; - } &.ppcp-non-ios-device { .ppcp-button-applepay { apple-pay-button { diff --git a/modules/ppcp-applepay/resources/js/ApplepayButton.js b/modules/ppcp-applepay/resources/js/ApplepayButton.js index 0ae04fb2f..d9d971ff9 100644 --- a/modules/ppcp-applepay/resources/js/ApplepayButton.js +++ b/modules/ppcp-applepay/resources/js/ApplepayButton.js @@ -5,10 +5,13 @@ import {setEnabled} from '../../../ppcp-button/resources/js/modules/Helper/Butto import FormValidator from "../../../ppcp-button/resources/js/modules/Helper/FormValidator"; import ErrorHandler from '../../../ppcp-button/resources/js/modules/ErrorHandler'; import widgetBuilder from "../../../ppcp-button/resources/js/modules/Renderer/WidgetBuilder"; +import {apmButtonsInit} from "../../../ppcp-button/resources/js/modules/Helper/ApmButtons"; class ApplepayButton { constructor(context, externalHandler, buttonConfig, ppcpConfig) { + apmButtonsInit(ppcpConfig); + this.isInitialized = false; this.context = context; @@ -60,7 +63,7 @@ class ApplepayButton { this.initEventHandlers(); this.isInitialized = true; this.applePayConfig = config; - const isEligible = this.applePayConfig.isEligible; + const isEligible = (this.applePayConfig.isEligible && window.ApplePaySession) || this.buttonConfig.is_admin; if (isEligible) { this.fetchTransactionInfo().then(() => { @@ -84,6 +87,10 @@ class ApplepayButton { }); } }); + } else { + jQuery('#' + this.buttonConfig.button.wrapper).hide(); + jQuery('#' + this.buttonConfig.button.mini_cart_wrapper).hide(); + jQuery('#express-payment-method-ppcp-applepay').hide(); } } @@ -107,7 +114,7 @@ class ApplepayButton { let config = { wrapper: this.buttonConfig.button.wrapper, ppcpStyle: this.ppcpConfig.button.style, - //buttonStyle: this.buttonConfig.button.style, + buttonStyle: this.buttonConfig.button.style, ppcpButtonWrapper: this.ppcpConfig.button.wrapper } @@ -119,7 +126,7 @@ class ApplepayButton { } if (['cart-block', 'checkout-block'].indexOf(this.context) !== -1) { - config.ppcpButtonWrapper = '#express-payment-method-ppcp-gateway'; + config.ppcpButtonWrapper = '#express-payment-method-ppcp-gateway-paypal'; } return config; @@ -167,14 +174,8 @@ class ApplepayButton { addButton() { this.log('addButton', this.context); - const wrapper = - (this.context === 'mini-cart') - ? this.buttonConfig.button.mini_cart_wrapper - : this.buttonConfig.button.wrapper; - const shape = - (this.context === 'mini-cart') - ? this.ppcpConfig.button.mini_cart_style.shape - : this.ppcpConfig.button.style.shape; + const { wrapper, ppcpStyle } = this.contextConfig(); + const appleContainer = document.getElementById(wrapper); const type = this.buttonConfig.button.type; const language = this.buttonConfig.button.lang; @@ -185,8 +186,13 @@ class ApplepayButton { appleContainer.innerHTML = ``; } - jQuery('#' + wrapper).addClass('ppcp-button-' + shape); - jQuery(wrapper).append(appleContainer); + const $wrapper = jQuery('#' + wrapper); + $wrapper.addClass('ppcp-button-' + ppcpStyle.shape); + + if (ppcpStyle.height) { + $wrapper.css('--apple-pay-button-height', `${ppcpStyle.height}px`) + $wrapper.css('height', `${ppcpStyle.height}px`) + } } //------------------------ diff --git a/modules/ppcp-applepay/resources/js/boot-admin.js b/modules/ppcp-applepay/resources/js/boot-admin.js index 30032f56b..f584ce41b 100644 --- a/modules/ppcp-applepay/resources/js/boot-admin.js +++ b/modules/ppcp-applepay/resources/js/boot-admin.js @@ -65,7 +65,7 @@ import widgetBuilder from "../../../ppcp-button/resources/js/modules/Renderer/Wi buttonConfig.button.wrapper = selector.replace('#', ''); applyConfigOptions(buttonConfig); - const wrapperElement = `
`; + const wrapperElement = `
`; if (!jQuery(selector).length) { jQuery(ppcpConfig.button.wrapper).after(wrapperElement); diff --git a/modules/ppcp-applepay/resources/js/boot-block.js b/modules/ppcp-applepay/resources/js/boot-block.js index 2f97b7fbc..b8f905b6d 100644 --- a/modules/ppcp-applepay/resources/js/boot-block.js +++ b/modules/ppcp-applepay/resources/js/boot-block.js @@ -23,12 +23,6 @@ const ApplePayComponent = () => { const manager = new ApplepayManager(buttonConfig, ppcpConfig); manager.init(); }; - useEffect(() => { - const bodyClass = 'ppcp-has-applepay-block'; - if (!document.body.classList.contains(bodyClass)) { - document.body.classList.add(bodyClass); - } - }, []); useEffect(() => { // Load ApplePay SDK @@ -50,14 +44,13 @@ const ApplePayComponent = () => { }, [paypalLoaded, applePayLoaded]); return ( -
+
); } const features = ['products']; -let registerMethod = registerExpressPaymentMethod; -registerMethod({ +registerExpressPaymentMethod({ name: buttonData.id, label:
, content: , diff --git a/modules/ppcp-applepay/services.php b/modules/ppcp-applepay/services.php index 0f1266006..5c82ac32c 100644 --- a/modules/ppcp-applepay/services.php +++ b/modules/ppcp-applepay/services.php @@ -62,6 +62,11 @@ return array( ); }, + 'applepay.has_validated' => static function ( ContainerInterface $container ): bool { + $settings = $container->get( 'wcgateway.settings' ); + return $settings->has( 'applepay_validated' ); + }, + 'applepay.is_validated' => static function ( ContainerInterface $container ): bool { $settings = $container->get( 'wcgateway.settings' ); return $settings->has( 'applepay_validated' ) ? $settings->get( 'applepay_validated' ) === true : false; diff --git a/modules/ppcp-applepay/src/Assets/ApplePayButton.php b/modules/ppcp-applepay/src/Assets/ApplePayButton.php index c34a9fc6c..f8ce67bd6 100644 --- a/modules/ppcp-applepay/src/Assets/ApplePayButton.php +++ b/modules/ppcp-applepay/src/Assets/ApplePayButton.php @@ -968,7 +968,7 @@ class ApplePayButton implements ButtonInterface { add_action( $render_placeholder, function () { - echo ''; + echo ''; }, 21 ); @@ -981,7 +981,7 @@ class ApplePayButton implements ButtonInterface { */ protected function applepay_button(): void { ?> -
+
$this->sdk_url, 'is_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG ? true : false, + 'is_admin' => false, 'preferences' => array( 'checkout_data_mode' => $checkout_data_mode, ), @@ -204,6 +205,7 @@ class DataToAppleButtonScripts { return array( 'sdk_url' => $this->sdk_url, 'is_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG ? true : false, + 'is_admin' => false, 'preferences' => array( 'checkout_data_mode' => $checkout_data_mode, ), @@ -252,6 +254,7 @@ class DataToAppleButtonScripts { return array( 'sdk_url' => $this->sdk_url, 'is_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG ? true : false, + 'is_admin' => true, 'preferences' => array( 'checkout_data_mode' => $checkout_data_mode, ), diff --git a/modules/ppcp-applepay/src/Helper/ApmApplies.php b/modules/ppcp-applepay/src/Helper/ApmApplies.php index dec9b1a08..0fa12420b 100644 --- a/modules/ppcp-applepay/src/Helper/ApmApplies.php +++ b/modules/ppcp-applepay/src/Helper/ApmApplies.php @@ -1,6 +1,7 @@ { * @returns {Object} */ export const paypalPayerToWc = (payer) => { - const firstName = payer.name.given_name; - const lastName = payer.name.surname; + const firstName = payer?.name?.given_name ?? ''; + const lastName = payer?.name?.surname ?? ''; const address = payer.address ? paypalAddressToWc(payer.address) : {}; return { ...address, @@ -100,10 +100,12 @@ export const paypalOrderToWcShippingAddress = (order) => { const res = paypalShippingToWc(shipping); // use the name from billing if the same, to avoid possible mistakes when splitting full_name - const billingAddress = paypalPayerToWc(order.payer); - if (`${res.first_name} ${res.last_name}` === `${billingAddress.first_name} ${billingAddress.last_name}`) { - res.first_name = billingAddress.first_name; - res.last_name = billingAddress.last_name; + if (order.payer) { + const billingAddress = paypalPayerToWc(order.payer); + if (`${res.first_name} ${res.last_name}` === `${billingAddress.first_name} ${billingAddress.last_name}`) { + res.first_name = billingAddress.first_name; + res.last_name = billingAddress.last_name; + } } return res; @@ -116,10 +118,13 @@ export const paypalOrderToWcShippingAddress = (order) => { */ export const paypalOrderToWcAddresses = (order) => { const shippingAddress = paypalOrderToWcShippingAddress(order); - let billingAddress = paypalPayerToWc(order.payer); - // no billing address, such as if billing address retrieval is not allowed in the merchant account - if (!billingAddress.address_line_1) { - billingAddress = {...shippingAddress, ...paypalPayerToWc(order.payer)}; + let billingAddress = shippingAddress; + if (order.payer) { + billingAddress = paypalPayerToWc(order.payer); + // no billing address, such as if billing address retrieval is not allowed in the merchant account + if (!billingAddress.address_line_1) { + billingAddress = {...shippingAddress, ...paypalPayerToWc(order.payer)}; + } } return {billingAddress, shippingAddress}; diff --git a/modules/ppcp-blocks/resources/js/checkout-block.js b/modules/ppcp-blocks/resources/js/checkout-block.js index 582fdede3..015601d52 100644 --- a/modules/ppcp-blocks/resources/js/checkout-block.js +++ b/modules/ppcp-blocks/resources/js/checkout-block.js @@ -1,13 +1,20 @@ import {useEffect, useState} from '@wordpress/element'; import {registerExpressPaymentMethod, registerPaymentMethod} from '@woocommerce/blocks-registry'; import {mergeWcAddress, paypalAddressToWc, paypalOrderToWcAddresses} from "./Helper/Address"; -import {loadPaypalScript} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading' +import { + loadPaypalScriptPromise +} from '../../../ppcp-button/resources/js/modules/Helper/ScriptLoading' +import { + normalizeStyleForFundingSource +} from '../../../ppcp-button/resources/js/modules/Helper/Style' import buttonModuleWatcher from "../../../ppcp-button/resources/js/modules/ButtonModuleWatcher"; const config = wc.wcSettings.getSetting('ppcp-gateway_data'); window.ppcpFundingSource = config.fundingSource; +let registeredContext = false; + const PayPalComponent = ({ onClick, onClose, @@ -18,46 +25,37 @@ const PayPalComponent = ({ activePaymentMethod, shippingData, isEditing, + fundingSource, }) => { const {onPaymentSetup, onCheckoutFail, onCheckoutValidation} = eventRegistration; const {responseTypes} = emitResponse; const [paypalOrder, setPaypalOrder] = useState(null); + const [gotoContinuationOnError, setGotoContinuationOnError] = useState(false); + + const methodId = fundingSource ? `${config.id}-${fundingSource}` : config.id; useEffect(() => { // fill the form if in continuation (for product or mini-cart buttons) if (!config.scriptData.continuation || !config.scriptData.continuation.order || window.ppcpContinuationFilled) { return; } - const paypalAddresses = paypalOrderToWcAddresses(config.scriptData.continuation.order); - const wcAddresses = wp.data.select('wc/store/cart').getCustomerData(); - const addresses = mergeWcAddress(wcAddresses, paypalAddresses); - wp.data.dispatch('wc/store/cart').setBillingAddress(addresses.billingAddress); - if (shippingData.needsShipping) { - wp.data.dispatch('wc/store/cart').setShippingAddress(addresses.shippingAddress); + try { + const paypalAddresses = paypalOrderToWcAddresses(config.scriptData.continuation.order); + const wcAddresses = wp.data.select('wc/store/cart').getCustomerData(); + const addresses = mergeWcAddress(wcAddresses, paypalAddresses); + wp.data.dispatch('wc/store/cart').setBillingAddress(addresses.billingAddress); + if (shippingData.needsShipping) { + wp.data.dispatch('wc/store/cart').setShippingAddress(addresses.shippingAddress); + } + } catch (err) { + // sometimes the PayPal address is missing, skip in this case. + console.log(err); } // this useEffect should run only once, but adding this in case of some kind of full re-rendering window.ppcpContinuationFilled = true; }, []) - const [loaded, setLoaded] = useState(false); - useEffect(() => { - if (!loaded) { - loadPaypalScript(config.scriptData, () => { - setLoaded(true); - - buttonModuleWatcher.registerContextBootstrap(config.scriptData.context, { - createOrder: () => { - return createOrder(); - }, - onApprove: (data, actions) => { - return handleApprove(data, actions); - }, - }); - }); - } - }, [loaded]); - const createOrder = async () => { try { const res = await fetch(config.scriptData.ajax.create_order.endpoint, { @@ -155,6 +153,7 @@ const PayPalComponent = ({ if (config.finalReviewEnabled) { location.href = getCheckoutRedirectUrl(); } else { + setGotoContinuationOnError(true); onSubmit(); } } catch (err) { @@ -173,7 +172,7 @@ const PayPalComponent = ({ if (config.scriptData.continuation) { return true; } - if (wp.data.select('wc/store/validation').hasValidationErrors()) { + if (gotoContinuationOnError && wp.data.select('wc/store/validation').hasValidationErrors()) { location.href = getCheckoutRedirectUrl(); return { type: responseTypes.ERROR }; } @@ -181,7 +180,7 @@ const PayPalComponent = ({ return true; }); return unsubscribe; - }, [onCheckoutValidation] ); + }, [onCheckoutValidation, gotoContinuationOnError] ); const handleClick = (data, actions) => { if (isEditing) { @@ -233,7 +232,7 @@ const PayPalComponent = ({ } useEffect(() => { - if (activePaymentMethod !== config.id) { + if (activePaymentMethod !== methodId) { return; } @@ -269,7 +268,7 @@ const PayPalComponent = ({ }, [onPaymentSetup, paypalOrder, activePaymentMethod]); useEffect(() => { - if (activePaymentMethod !== config.id) { + if (activePaymentMethod !== methodId) { return; } const unsubscribe = onCheckoutFail(({ processingResponse }) => { @@ -296,15 +295,26 @@ const PayPalComponent = ({ ) } - if (!loaded) { - return null; + if (!registeredContext) { + buttonModuleWatcher.registerContextBootstrap(config.scriptData.context, { + createOrder: () => { + return createOrder(); + }, + onApprove: (data, actions) => { + return handleApprove(data, actions); + }, + }); + registeredContext = true; } + const style = normalizeStyleForFundingSource(config.scriptData.button.style, fundingSource); + const PayPalButton = window.paypal.Buttons.driver("react", { React, ReactDOM }); return (
; + if (config.placeOrderButtonDescription) { + descriptionElement =
+

+

+
; + } + + registerPaymentMethod({ + name: config.id, + label:
, + content: descriptionElement, + edit: descriptionElement, + placeOrderButtonLabel: config.placeOrderButtonText, + ariaLabel: config.title, + canMakePayment: () => config.enabled, + supports: { + features: features, + }, + }); } -registerMethod({ - name: config.id, - label:
, - content: , - edit: , - ariaLabel: config.title, - canMakePayment: () => config.enabled, - supports: { - features: features, - }, -}); +if (config.scriptData.continuation) { + registerPaymentMethod({ + name: config.id, + label:
, + content: , + edit: , + ariaLabel: config.title, + canMakePayment: () => true, + supports: { + features: [...features, 'ppcp_continuation'], + }, + }); +} else if (!config.usePlaceOrder) { + const paypalScriptPromise = loadPaypalScriptPromise(config.scriptData); + + for (const fundingSource of ['paypal', ...config.enabledFundingSources]) { + registerExpressPaymentMethod({ + name: `${config.id}-${fundingSource}`, + paymentMethodId: config.id, + label:
, + content: , + edit: , + ariaLabel: config.title, + canMakePayment: async () => { + await paypalScriptPromise; + + return paypal.Buttons({fundingSource}).isEligible(); + }, + supports: { + features: features, + }, + }); + } +} diff --git a/modules/ppcp-blocks/services.php b/modules/ppcp-blocks/services.php index 5b5a5159b..e2fb01b64 100644 --- a/modules/ppcp-blocks/services.php +++ b/modules/ppcp-blocks/services.php @@ -34,7 +34,12 @@ return array( $container->get( 'wcgateway.paypal-gateway' ), $container->get( 'blocks.settings.final_review_enabled' ), $container->get( 'session.cancellation.view' ), - $container->get( 'session.handler' ) + $container->get( 'session.handler' ), + $container->get( 'blocks.add-place-order-method' ), + $container->get( 'wcgateway.use-place-order-button' ), + $container->get( 'wcgateway.place-order-button-text' ), + $container->get( 'wcgateway.place-order-button-description' ), + $container->get( 'wcgateway.all-funding-sources' ) ); }, 'blocks.settings.final_review_enabled' => static function ( ContainerInterface $container ): bool { @@ -54,4 +59,14 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ) ); }, + + 'blocks.add-place-order-method' => function ( ContainerInterface $container ) : bool { + /** + * Whether to create a non-express method with the standard "Place order" button redirecting to PayPal. + */ + return apply_filters( + 'woocommerce_paypal_payments_blocks_add_place_order_method', + true + ); + }, ); diff --git a/modules/ppcp-blocks/src/BlocksModule.php b/modules/ppcp-blocks/src/BlocksModule.php index afe4eb430..25290dbee 100644 --- a/modules/ppcp-blocks/src/BlocksModule.php +++ b/modules/ppcp-blocks/src/BlocksModule.php @@ -96,6 +96,27 @@ class BlocksModule implements ServiceModule, ExtendingModule, ExecutableModule { } ); + // Enqueue frontend scripts. + add_action( + 'wp_enqueue_scripts', + static function () use ( $c ) { + if ( ! has_block( 'woocommerce/checkout' ) && ! has_block( 'woocommerce/cart' ) ) { + return; + } + + $module_url = $c->get( 'blocks.url' ); + $asset_version = $c->get( 'ppcp.asset-version' ); + + wp_register_style( + 'wc-ppcp-blocks', + untrailingslashit( $module_url ) . '/assets/css/gateway.css', + array(), + $asset_version + ); + wp_enqueue_style( 'wc-ppcp-blocks' ); + } + ); + return true; } } diff --git a/modules/ppcp-blocks/src/PayPalPaymentMethod.php b/modules/ppcp-blocks/src/PayPalPaymentMethod.php index 3c407f2a2..1f43d26a1 100644 --- a/modules/ppcp-blocks/src/PayPalPaymentMethod.php +++ b/modules/ppcp-blocks/src/PayPalPaymentMethod.php @@ -87,6 +87,41 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType { */ private $session_handler; + /** + * Whether to create a non-express method with the standard "Place order" button. + * + * @var bool + */ + protected $add_place_order_method; + + /** + * Whether to use the standard "Place order" button instead of PayPal buttons. + * + * @var bool + */ + protected $use_place_order; + + /** + * The text for the standard "Place order" button. + * + * @var string + */ + protected $place_order_button_text; + + /** + * The text for additional "Place order" description. + * + * @var string + */ + protected $place_order_button_description; + + /** + * All existing funding sources for PayPal buttons. + * + * @var array + */ + private $all_funding_sources; + /** * Assets constructor. * @@ -99,6 +134,11 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType { * @param bool $final_review_enabled Whether the final review is enabled. * @param CancelView $cancellation_view The cancellation view. * @param SessionHandler $session_handler The Session handler. + * @param bool $add_place_order_method Whether to create a non-express method with the standard "Place order" button. + * @param bool $use_place_order Whether to use the standard "Place order" button instead of PayPal buttons. + * @param string $place_order_button_text The text for the standard "Place order" button. + * @param string $place_order_button_description The text for additional "Place order" description. + * @param array $all_funding_sources All existing funding sources for PayPal buttons. */ public function __construct( string $module_url, @@ -109,18 +149,28 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType { PayPalGateway $gateway, bool $final_review_enabled, CancelView $cancellation_view, - SessionHandler $session_handler + SessionHandler $session_handler, + bool $add_place_order_method, + bool $use_place_order, + string $place_order_button_text, + string $place_order_button_description, + array $all_funding_sources ) { - $this->name = PayPalGateway::ID; - $this->module_url = $module_url; - $this->version = $version; - $this->smart_button = $smart_button; - $this->plugin_settings = $plugin_settings; - $this->settings_status = $settings_status; - $this->gateway = $gateway; - $this->final_review_enabled = $final_review_enabled; - $this->cancellation_view = $cancellation_view; - $this->session_handler = $session_handler; + $this->name = PayPalGateway::ID; + $this->module_url = $module_url; + $this->version = $version; + $this->smart_button = $smart_button; + $this->plugin_settings = $plugin_settings; + $this->settings_status = $settings_status; + $this->gateway = $gateway; + $this->final_review_enabled = $final_review_enabled; + $this->cancellation_view = $cancellation_view; + $this->session_handler = $session_handler; + $this->add_place_order_method = $add_place_order_method; + $this->use_place_order = $use_place_order; + $this->place_order_button_text = $place_order_button_text; + $this->place_order_button_description = $place_order_button_description; + $this->all_funding_sources = $all_funding_sources; } /** @@ -174,20 +224,33 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType { } } + $disabled_funding_sources = explode( ',', $script_data['url_params']['disable-funding'] ?? '' ) ?: array(); + $funding_sources = array_values( + array_diff( + array_keys( $this->all_funding_sources ), + $disabled_funding_sources + ) + ); + return array( - 'id' => $this->gateway->id, - 'title' => $this->gateway->title, - 'description' => $this->gateway->description, - 'enabled' => $this->settings_status->is_smart_button_enabled_for_location( $script_data['context'] ), - 'fundingSource' => $this->session_handler->funding_source(), - 'finalReviewEnabled' => $this->final_review_enabled, - 'ajax' => array( + 'id' => $this->gateway->id, + 'title' => $this->gateway->title, + 'description' => $this->gateway->description, + 'enabled' => $this->settings_status->is_smart_button_enabled_for_location( $script_data['context'] ), + 'fundingSource' => $this->session_handler->funding_source(), + 'finalReviewEnabled' => $this->final_review_enabled, + 'addPlaceOrderMethod' => $this->add_place_order_method, + 'usePlaceOrder' => $this->use_place_order, + 'placeOrderButtonText' => $this->place_order_button_text, + 'placeOrderButtonDescription' => $this->place_order_button_description, + 'enabledFundingSources' => $funding_sources, + 'ajax' => array( 'update_shipping' => array( 'endpoint' => WC_AJAX::get_endpoint( UpdateShippingEndpoint::ENDPOINT ), 'nonce' => wp_create_nonce( UpdateShippingEndpoint::nonce() ), ), ), - 'scriptData' => $script_data, + 'scriptData' => $script_data, ); } } diff --git a/modules/ppcp-blocks/webpack.config.js b/modules/ppcp-blocks/webpack.config.js index 4695769ed..bdf508fba 100644 --- a/modules/ppcp-blocks/webpack.config.js +++ b/modules/ppcp-blocks/webpack.config.js @@ -9,7 +9,8 @@ module.exports = { target: 'web', plugins: [ new DependencyExtractionWebpackPlugin() ], entry: { - 'checkout-block': path.resolve('./resources/js/checkout-block.js') + 'checkout-block': path.resolve('./resources/js/checkout-block.js'), + "gateway": path.resolve('./resources/css/gateway.scss') }, output: { path: path.resolve(__dirname, 'assets/'), diff --git a/modules/ppcp-button/resources/css/gateway.scss b/modules/ppcp-button/resources/css/gateway.scss index 42b216e92..ee848f0cd 100644 --- a/modules/ppcp-button/resources/css/gateway.scss +++ b/modules/ppcp-button/resources/css/gateway.scss @@ -1,3 +1,5 @@ +@use "mixins/apm-button" as apm-button; + #place_order.ppcp-hidden { display: none !important; } @@ -15,3 +17,24 @@ .ppc-button-wrapper #ppcp-messages:first-child { padding-top: 10px; } + +// Prevents spacing after button group. +#ppc-button-ppcp-gateway { + line-height: 0; + + div[class^="item-"] { + margin-top: 14px; + &:first-child { + margin-top: 0; + } + } +} + +#ppc-button-minicart { + line-height: 0; + display: block; +} + +.ppcp-button-apm { + @include apm-button.button; +} diff --git a/modules/ppcp-button/resources/css/mixins/apm-button.scss b/modules/ppcp-button/resources/css/mixins/apm-button.scss new file mode 100644 index 000000000..5c9e73921 --- /dev/null +++ b/modules/ppcp-button/resources/css/mixins/apm-button.scss @@ -0,0 +1,42 @@ + +@mixin button { + overflow: hidden; + min-width: 0; + max-width: 750px; + line-height: 0; + border-radius: 4px; + + // Defaults + height: 45px; + margin-top: 14px; + + &.ppcp-button-pill { + border-radius: 50px; + } + + &.ppcp-button-minicart { + display: block; + } + + .ppcp-width-min & { + height: 35px; + } + + .ppcp-width-300 & { + height: 45px; + } + + .ppcp-width-500 & { + height: 55px; + } + + // No margin on block layout. + .wp-block-woocommerce-checkout &, .wp-block-woocommerce-cart & { + margin: 0; + min-width: 0; + } + + .wp-admin & { + pointer-events: none; + } +} diff --git a/modules/ppcp-button/resources/js/button.js b/modules/ppcp-button/resources/js/button.js index 4366b6592..40997d15a 100644 --- a/modules/ppcp-button/resources/js/button.js +++ b/modules/ppcp-button/resources/js/button.js @@ -22,6 +22,7 @@ import FormValidator from "./modules/Helper/FormValidator"; import {loadPaypalScript} from "./modules/Helper/ScriptLoading"; import buttonModuleWatcher from "./modules/ButtonModuleWatcher"; import MessagesBootstrap from "./modules/ContextBootstrap/MessagesBootstap"; +import {apmButtonsInit} from "./modules/Helper/ApmButtons"; // TODO: could be a good idea to have a separate spinner for each gateway, // but I think we care mainly about the script loading, so one spinner should be enough. @@ -145,6 +146,7 @@ const bootstrap = () => { }; const onSmartButtonsInit = () => { + jQuery(document).trigger('ppcp-smart-buttons-init', this); buttonsSpinner.unblock(); }; const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit); @@ -217,6 +219,8 @@ const bootstrap = () => { messageRenderer, ); messagesBootstrap.init(); + + apmButtonsInit(PayPalCommerceGateway); }; document.addEventListener( @@ -279,11 +283,12 @@ document.addEventListener( }); let bootstrapped = false; + let failed = false; hideOrderButtonIfPpcpGateway(); jQuery(document.body).on('updated_checkout payment_method_selected', () => { - if (bootstrapped) { + if (bootstrapped || failed) { return; } @@ -294,6 +299,12 @@ document.addEventListener( bootstrapped = true; bootstrap(); + }, () => { + failed = true; + + setVisibleByClass(ORDER_BUTTON_SELECTOR, true, 'ppcp-hidden'); + buttonsSpinner.unblock(); + cardsSpinner.unblock(); }); }, ); diff --git a/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js b/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js index b6882ff3f..93ecf7c8f 100644 --- a/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js +++ b/modules/ppcp-button/resources/js/modules/ActionHandler/CheckoutActionHandler.js @@ -2,6 +2,7 @@ import 'formdata-polyfill'; import onApprove from '../OnApproveHandler/onApproveForPayNow.js'; import {payerData} from "../Helper/PayerData"; import {getCurrentPaymentMethod} from "../Helper/CheckoutMethodState"; +import validateCheckoutForm from "../Helper/CheckoutFormValidation"; class CheckoutActionHandler { @@ -13,7 +14,13 @@ class CheckoutActionHandler { subscriptionsConfiguration() { return { - createSubscription: (data, actions) => { + createSubscription: async (data, actions) => { + try { + await validateCheckoutForm(this.config); + } catch (error) { + throw {type: 'form-validation-error'}; + } + return actions.subscription.create({ 'plan_id': this.config.subscription_plan_id }); @@ -56,6 +63,8 @@ class CheckoutActionHandler { const paymentMethod = getCurrentPaymentMethod(); const fundingSource = window.ppcpFundingSource; + const savePaymentMethod = !!document.getElementById('wc-ppcp-credit-card-gateway-new-payment-method')?.checked; + return fetch(this.config.ajax.create_order.endpoint, { method: 'POST', headers: { @@ -72,7 +81,8 @@ class CheckoutActionHandler { funding_source: fundingSource, // send as urlencoded string to handle complex fields via PHP functions the same as normal form submit form_encoded: new URLSearchParams(formData).toString(), - createaccount: createaccount + createaccount: createaccount, + save_payment_method: savePaymentMethod }) }).then(function (res) { return res.json(); diff --git a/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js b/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js index bb143eb08..6ef7bd007 100644 --- a/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js +++ b/modules/ppcp-button/resources/js/modules/DataClientIdAttributeHandler.js @@ -26,7 +26,7 @@ const storeToken = (token) => { sessionStorage.setItem(storageKey, JSON.stringify(token)); } -const dataClientIdAttributeHandler = (scriptOptions, config, callback) => { +const dataClientIdAttributeHandler = (scriptOptions, config, callback, errorCallback = null) => { fetch(config.endpoint, { method: 'POST', headers: { @@ -51,6 +51,10 @@ const dataClientIdAttributeHandler = (scriptOptions, config, callback) => { if (typeof callback === 'function') { callback(paypal); } + }).catch(err => { + if (typeof errorCallback === 'function') { + errorCallback(err); + } }); }); } diff --git a/modules/ppcp-button/resources/js/modules/Helper/ApmButtons.js b/modules/ppcp-button/resources/js/modules/Helper/ApmButtons.js new file mode 100644 index 000000000..ebe0d5051 --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/Helper/ApmButtons.js @@ -0,0 +1,114 @@ + +export const apmButtonsInit = (config, selector = '.ppcp-button-apm') => { + let selectorInContainer = selector; + + if (window.ppcpApmButtons) { + return; + } + + if (config && config.button) { + + // If it's separate gateways, modify wrapper to account for the individual buttons as individual APMs. + const wrapper = config.button.wrapper; + const isSeparateGateways = jQuery(wrapper).children('div[class^="item-"]').length > 0; + + if (isSeparateGateways) { + selector += `, ${wrapper} div[class^="item-"]`; + selectorInContainer += `, div[class^="item-"]`; + } + } + + window.ppcpApmButtons = new ApmButtons(selector, selectorInContainer); +} + +export class ApmButtons { + + constructor(selector, selectorInContainer) { + this.selector = selector; + this.selectorInContainer = selectorInContainer; + this.containers = []; + + // Reloads button containers. + this.reloadContainers(); + + // Refresh button layout. + jQuery(window).resize(() => { + this.refresh(); + }).resize(); + + jQuery(document).on('ppcp-smart-buttons-init', () => { + this.refresh(); + }); + + // Observes for new buttons. + (new MutationObserver(this.observeElementsCallback.bind(this))) + .observe(document.body, { childList: true, subtree: true }); + } + + observeElementsCallback(mutationsList, observer) { + const observeSelector = this.selector + ', .widget_shopping_cart, .widget_shopping_cart_content'; + + let shouldReload = false; + for (let mutation of mutationsList) { + if (mutation.type === 'childList') { + mutation.addedNodes.forEach(node => { + if (node.matches && node.matches(observeSelector)) { + shouldReload = true; + } + }); + } + } + + if (shouldReload) { + this.reloadContainers(); + this.refresh(); + } + }; + + reloadContainers() { + jQuery(this.selector).each((index, el) => { + const parent = jQuery(el).parent(); + if (!this.containers.some($el => $el.is(parent))) { + this.containers.push(parent); + } + }); + console.log('this.containers', this.containers); + } + + refresh() { + for (const container of this.containers) { + const $container = jQuery(container); + + // Check width and add classes + const width = $container.width(); + + $container.removeClass('ppcp-width-500 ppcp-width-300 ppcp-width-min'); + + if (width >= 500) { + $container.addClass('ppcp-width-500'); + } else if (width >= 300) { + $container.addClass('ppcp-width-300'); + } else { + $container.addClass('ppcp-width-min'); + } + + // Check first apm button + const $firstElement = $container.children(':visible').first(); + + // Assign margins to buttons + $container.find(this.selectorInContainer).each((index, el) => { + const $el = jQuery(el); + + if ($el.is($firstElement)) { + $el.css('margin-top', `0px`); + return true; + } + + const height = $el.height(); + $el.css('margin-top', `${Math.round(height * 0.3)}px`); + }); + + } + } + +} diff --git a/modules/ppcp-button/resources/js/modules/Helper/CardFieldsHelper.js b/modules/ppcp-button/resources/js/modules/Helper/CardFieldsHelper.js new file mode 100644 index 000000000..5dc02d3d6 --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/Helper/CardFieldsHelper.js @@ -0,0 +1,50 @@ +export const cardFieldStyles = (field) => { + const allowedProperties = [ + 'appearance', + 'color', + 'direction', + 'font', + 'font-family', + 'font-size', + 'font-size-adjust', + 'font-stretch', + 'font-style', + 'font-variant', + 'font-variant-alternates', + 'font-variant-caps', + 'font-variant-east-asian', + 'font-variant-ligatures', + 'font-variant-numeric', + 'font-weight', + 'letter-spacing', + 'line-height', + 'opacity', + 'outline', + 'padding', + 'padding-bottom', + 'padding-left', + 'padding-right', + 'padding-top', + 'text-shadow', + 'transition', + '-moz-appearance', + '-moz-osx-font-smoothing', + '-moz-tap-highlight-color', + '-moz-transition', + '-webkit-appearance', + '-webkit-osx-font-smoothing', + '-webkit-tap-highlight-color', + '-webkit-transition', + ]; + + const stylesRaw = window.getComputedStyle(field); + const styles = {}; + Object.values(stylesRaw).forEach((prop) => { + if (!stylesRaw[prop] || !allowedProperties.includes(prop)) { + return; + } + styles[prop] = '' + stylesRaw[prop]; + }); + + return styles; +} diff --git a/modules/ppcp-button/resources/js/modules/Helper/CheckoutFormValidation.js b/modules/ppcp-button/resources/js/modules/Helper/CheckoutFormValidation.js new file mode 100644 index 000000000..092d0f148 --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/Helper/CheckoutFormValidation.js @@ -0,0 +1,48 @@ +import Spinner from "./Spinner"; +import FormValidator from "./FormValidator"; +import ErrorHandler from "../ErrorHandler"; + +const validateCheckoutForm = function (config) { + return new Promise(async (resolve, reject) => { + try { + const spinner = new Spinner(); + const errorHandler = new ErrorHandler( + config.labels.error.generic, + document.querySelector('.woocommerce-notices-wrapper') + ); + + const formSelector = config.context === 'checkout' ? 'form.checkout' : 'form#order_review'; + const formValidator = config.early_checkout_validation_enabled ? + new FormValidator( + config.ajax.validate_checkout.endpoint, + config.ajax.validate_checkout.nonce, + ) : null; + + if (!formValidator) { + resolve(); + return; + } + + formValidator.validate(document.querySelector(formSelector)).then((errors) => { + if (errors.length > 0) { + spinner.unblock(); + errorHandler.clear(); + errorHandler.messages(errors); + + // fire WC event for other plugins + jQuery( document.body ).trigger( 'checkout_error' , [ errorHandler.currentHtml() ] ); + + reject(); + } else { + resolve(); + } + }); + + } catch (error) { + console.error(error); + reject(); + } + }); +} + +export default validateCheckoutForm; diff --git a/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js b/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js index fea81923b..e3df5a27e 100644 --- a/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js +++ b/modules/ppcp-button/resources/js/modules/Helper/ScriptLoading.js @@ -7,10 +7,11 @@ import {keysToCamelCase} from "./Utils"; // This component may be used by multiple modules. This assures that options are shared between all instances. let options = window.ppcpWidgetBuilder = window.ppcpWidgetBuilder || { isLoading: false, - onLoadedCallbacks: [] + onLoadedCallbacks: [], + onErrorCallbacks: [], }; -export const loadPaypalScript = (config, onLoaded) => { +export const loadPaypalScript = (config, onLoaded, onError = null) => { // If PayPal is already loaded call the onLoaded callback and return. if (typeof paypal !== 'undefined') { onLoaded(); @@ -19,6 +20,9 @@ export const loadPaypalScript = (config, onLoaded) => { // Add the onLoaded callback to the onLoadedCallbacks stack. options.onLoadedCallbacks.push(onLoaded); + if (onError) { + options.onErrorCallbacks.push(onError); + } // Return if it's still loading. if (options.isLoading) { @@ -26,6 +30,12 @@ export const loadPaypalScript = (config, onLoaded) => { } options.isLoading = true; + const resetState = () => { + options.isLoading = false; + options.onLoadedCallbacks = []; + options.onErrorCallbacks = []; + } + // Callback to be called once the PayPal script is loaded. const callback = (paypal) => { widgetBuilder.setPaypal(paypal); @@ -34,8 +44,14 @@ export const loadPaypalScript = (config, onLoaded) => { onLoadedCallback(); } - options.isLoading = false; - options.onLoadedCallbacks = []; + resetState(); + } + const errorCallback = (err) => { + for (const onErrorCallback of options.onErrorCallbacks) { + onErrorCallback(err); + } + + resetState(); } // Build the PayPal script options. @@ -44,12 +60,26 @@ export const loadPaypalScript = (config, onLoaded) => { // Load PayPal script for special case with data-client-token if (config.data_client_id.set_attribute) { - dataClientIdAttributeHandler(scriptOptions, config.data_client_id, callback); + dataClientIdAttributeHandler(scriptOptions, config.data_client_id, callback, errorCallback); return; } + // Adds data-user-id-token to script options. + const userIdToken = config?.save_payment_methods?.id_token; + if(userIdToken) { + scriptOptions['data-user-id-token'] = userIdToken; + } + // Load PayPal script - loadScript(scriptOptions).then(callback); + loadScript(scriptOptions) + .then(callback) + .catch(errorCallback); +} + +export const loadPaypalScriptPromise = (config) => { + return new Promise((resolve, reject) => { + loadPaypalScript(config, resolve, reject) + }); } export const loadPaypalJsScript = (options, buttons, container) => { @@ -57,3 +87,11 @@ export const loadPaypalJsScript = (options, buttons, container) => { paypal.Buttons(buttons).render(container); }); } + +export const loadPaypalJsScriptPromise = (options) => { + return new Promise((resolve, reject) => { + loadScript(options) + .then(resolve) + .catch(reject); + }); +} diff --git a/modules/ppcp-button/resources/js/modules/Helper/Style.js b/modules/ppcp-button/resources/js/modules/Helper/Style.js new file mode 100644 index 000000000..a7672cc78 --- /dev/null +++ b/modules/ppcp-button/resources/js/modules/Helper/Style.js @@ -0,0 +1,20 @@ +export const normalizeStyleForFundingSource = (style, fundingSource) => { + const commonProps = {}; + ['shape', 'height'].forEach(prop => { + if (style[prop]) { + commonProps[prop] = style[prop]; + } + }); + + switch (fundingSource) { + case 'paypal': + return style; + case 'paylater': + return { + color: style.color, + ...commonProps + }; + default: + return commonProps; + } +} diff --git a/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js b/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js index 29514186a..377568fcb 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/CardFieldsRenderer.js @@ -1,4 +1,5 @@ import {show} from "../Helper/Hiding"; +import {cardFieldStyles} from "../Helper/CardFieldsHelper"; class CardFieldsRenderer { @@ -53,28 +54,28 @@ class CardFieldsRenderer { if (cardField.isEligible()) { const nameField = document.getElementById('ppcp-credit-card-gateway-card-name'); if (nameField) { - let styles = this.cardFieldStyles(nameField); + let styles = cardFieldStyles(nameField); cardField.NameField({style: {'input': styles}}).render(nameField.parentNode); nameField.remove(); } const numberField = document.getElementById('ppcp-credit-card-gateway-card-number'); if (numberField) { - let styles = this.cardFieldStyles(numberField); + let styles = cardFieldStyles(numberField); cardField.NumberField({style: {'input': styles}}).render(numberField.parentNode); numberField.remove(); } const expiryField = document.getElementById('ppcp-credit-card-gateway-card-expiry'); if (expiryField) { - let styles = this.cardFieldStyles(expiryField); + let styles = cardFieldStyles(expiryField); cardField.ExpiryField({style: {'input': styles}}).render(expiryField.parentNode); expiryField.remove(); } const cvvField = document.getElementById('ppcp-credit-card-gateway-card-cvc'); if (cvvField) { - let styles = this.cardFieldStyles(cvvField); + let styles = cardFieldStyles(cvvField); cardField.CVVField({style: {'input': styles}}).render(cvvField.parentNode); cvvField.remove(); } @@ -91,65 +92,35 @@ class CardFieldsRenderer { this.spinner.block(); this.errorHandler.clear(); + const paymentToken = document.querySelector('input[name="wc-ppcp-credit-card-gateway-payment-token"]:checked')?.value + if(paymentToken && paymentToken !== 'new') { + fetch(this.defaultConfig.ajax.capture_card_payment.endpoint, { + method: 'POST', + credentials: 'same-origin', + body: JSON.stringify({ + nonce: this.defaultConfig.ajax.capture_card_payment.nonce, + payment_token: paymentToken + }) + }).then((res) => { + return res.json(); + }).then((data) => { + document.querySelector('#place_order').click(); + }); + + return; + } + cardField.submit() .catch((error) => { this.spinner.unblock(); console.error(error) this.errorHandler.message(this.defaultConfig.hosted_fields.labels.fields_not_valid); - }) + }); }); } - cardFieldStyles(field) { - const allowedProperties = [ - 'appearance', - 'color', - 'direction', - 'font', - 'font-family', - 'font-size', - 'font-size-adjust', - 'font-stretch', - 'font-style', - 'font-variant', - 'font-variant-alternates', - 'font-variant-caps', - 'font-variant-east-asian', - 'font-variant-ligatures', - 'font-variant-numeric', - 'font-weight', - 'letter-spacing', - 'line-height', - 'opacity', - 'outline', - 'padding', - 'padding-bottom', - 'padding-left', - 'padding-right', - 'padding-top', - 'text-shadow', - 'transition', - '-moz-appearance', - '-moz-osx-font-smoothing', - '-moz-tap-highlight-color', - '-moz-transition', - '-webkit-appearance', - '-webkit-osx-font-smoothing', - '-webkit-tap-highlight-color', - '-webkit-transition', - ]; - - const stylesRaw = window.getComputedStyle(field); - const styles = {}; - Object.values(stylesRaw).forEach((prop) => { - if (!stylesRaw[prop] || !allowedProperties.includes(prop)) { - return; - } - styles[prop] = '' + stylesRaw[prop]; - }); - - return styles; - } + disableFields() {} + enableFields() {} } export default CardFieldsRenderer; diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js index c40fcc384..f01219467 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js @@ -2,6 +2,7 @@ import merge from "deepmerge"; import {loadScript} from "@paypal/paypal-js"; import {keysToCamelCase} from "../Helper/Utils"; import widgetBuilder from "./WidgetBuilder"; +import {normalizeStyleForFundingSource} from "../Helper/Style"; class Renderer { constructor(creditCardRenderer, defaultSettings, onSmartButtonClick, onSmartButtonsInit) { @@ -36,16 +37,7 @@ class Renderer { } else { // render each button separately for (const fundingSource of paypal.getFundingSources().filter(s => !(s in enabledSeparateGateways))) { - let style = settings.button.style; - if (fundingSource !== 'paypal') { - style = { - shape: style.shape, - color: style.color, - }; - if (fundingSource !== 'paylater') { - delete style.color; - } - } + const style = normalizeStyleForFundingSource(settings.button.style, fundingSource); this.renderButtons( settings.button.wrapper, diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 9267307d8..a812dc53e 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -15,8 +15,10 @@ use WooCommerce\PayPalCommerce\Button\Endpoint\SimulateCartEndpoint; use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper; use WooCommerce\PayPalCommerce\Button\Helper\CheckoutFormSaver; use WooCommerce\PayPalCommerce\Button\Endpoint\SaveCheckoutFormEndpoint; +use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait; use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator; use WooCommerce\PayPalCommerce\Button\Endpoint\ValidateCheckoutEndpoint; +use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\Button\Assets\DisabledSmartButton; use WooCommerce\PayPalCommerce\Button\Assets\SmartButton; @@ -68,8 +70,41 @@ return array( return $dummy_ids[ $shop_country ] ?? $container->get( 'button.client_id' ); }, + // This service may not work correctly when called too early. + 'button.context' => static function ( ContainerInterface $container ): string { + $obj = new class() { + use ContextTrait; + + /** + * Session handler. + * + * @var SessionHandler + */ + protected $session_handler; + + /** Constructor. */ + public function __construct() { + // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundInStatic + $this->session_handler = new SessionHandler(); + } + + /** + * Wrapper for a non-public function. + */ + public function get_context(): string { + // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundInStatic + return $this->context(); + } + }; + return $obj->get_context(); + }, 'button.smart-button' => static function ( ContainerInterface $container ): SmartButtonInterface { $state = $container->get( 'onboarding.state' ); + if ( $container->get( 'wcgateway.use-place-order-button' ) + && in_array( $container->get( 'button.context' ), array( 'checkout', 'pay-now' ), true ) + ) { + return new DisabledSmartButton(); + } if ( $state->current_state() !== State::STATE_ONBOARDED ) { return new DisabledSmartButton(); } @@ -84,7 +119,7 @@ return array( $request_data = $container->get( 'button.request-data' ); $client_id = $container->get( 'button.client_id' ); $dcc_applies = $container->get( 'api.helpers.dccapplies' ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); $messages_apply = $container->get( 'button.helper.messages-apply' ); $environment = $container->get( 'onboarding.environment' ); $payment_token_repository = $container->get( 'vaulting.repository.payment-token' ); @@ -259,8 +294,10 @@ return array( }, 'button.helper.three-d-secure' => static function ( ContainerInterface $container ): ThreeDSecure { - $logger = $container->get( 'woocommerce.logger.woocommerce' ); - return new ThreeDSecure( $logger ); + return new ThreeDSecure( + $container->get( 'api.factory.card-authentication-result-factory' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); }, 'button.helper.messages-apply' => static function ( ContainerInterface $container ): MessagesApply { return new MessagesApply( diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 4acbc7ee4..ec2b5a395 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -33,8 +33,8 @@ use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait; use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply; use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; @@ -272,6 +272,8 @@ class SmartButton implements SmartButtonInterface { * @return bool */ public function render_wrapper(): bool { + $this->init_context(); + if ( $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' ) ) { $this->render_button_wrapper_registrar(); $this->render_message_wrapper_registrar(); @@ -303,7 +305,13 @@ class SmartButton implements SmartButtonInterface { add_filter( 'woocommerce_credit_card_form_fields', function ( array $default_fields, $id ) use ( $subscription_helper ) : array { - if ( is_user_logged_in() && $this->settings->has( 'vault_enabled_dcc' ) && $this->settings->get( 'vault_enabled_dcc' ) && CreditCardGateway::ID === $id ) { + if ( + is_user_logged_in() + && $this->settings->has( 'vault_enabled_dcc' ) + && $this->settings->get( 'vault_enabled_dcc' ) + && CreditCardGateway::ID === $id + && apply_filters( 'woocommerce_paypal_payments_should_render_card_custom_fields', true ) + ) { $default_fields['card-vault'] = sprintf( '

', @@ -638,7 +646,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages return $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) && $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) && $this->dcc_applies->for_country_currency() - && in_array( $this->context(), array( 'checkout', 'pay-now' ), true ); + && in_array( $this->context(), array( 'checkout', 'pay-now', 'add-payment-method' ), true ); } /** @@ -1049,30 +1057,39 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages 'mini_cart_wrapper' => '#ppc-button-minicart', 'is_mini_cart_disabled' => $this->is_button_disabled( 'mini-cart' ), 'cancel_wrapper' => '#ppcp-cancel', - 'mini_cart_style' => array( - 'layout' => $this->style_for_context( 'layout', 'mini-cart' ), - 'color' => $this->style_for_context( 'color', 'mini-cart' ), - 'shape' => $this->style_for_context( 'shape', 'mini-cart' ), - 'label' => $this->style_for_context( 'label', 'mini-cart' ), - 'tagline' => $this->style_for_context( 'tagline', 'mini-cart' ), - 'height' => $this->settings->has( 'button_mini-cart_height' ) && $this->settings->get( 'button_mini-cart_height' ) ? $this->normalize_height( (int) $this->settings->get( 'button_mini-cart_height' ) ) : 35, + 'mini_cart_style' => $this->normalize_style( + array( + 'layout' => $this->style_for_context( 'layout', 'mini-cart' ), + 'color' => $this->style_for_context( 'color', 'mini-cart' ), + 'shape' => $this->style_for_context( 'shape', 'mini-cart' ), + 'label' => $this->style_for_context( 'label', 'mini-cart' ), + 'tagline' => $this->style_for_context( 'tagline', 'mini-cart' ), + 'height' => $this->normalize_height( $this->style_for_context( 'height', 'mini-cart', 35 ), 25, 55 ), + ) ), - 'style' => array( - 'layout' => $this->style_for_context( 'layout', $this->context() ), - 'color' => $this->style_for_context( 'color', $this->context() ), - 'shape' => $this->style_for_context( 'shape', $this->context() ), - 'label' => $this->style_for_context( 'label', $this->context() ), - 'tagline' => $this->style_for_context( 'tagline', $this->context() ), + 'style' => $this->normalize_style( + array( + 'layout' => $this->style_for_context( 'layout', $this->context() ), + 'color' => $this->style_for_context( 'color', $this->context() ), + 'shape' => $this->style_for_context( 'shape', $this->context() ), + 'label' => $this->style_for_context( 'label', $this->context() ), + 'tagline' => $this->style_for_context( 'tagline', $this->context() ), + 'height' => in_array( $this->context(), array( 'cart-block', 'checkout-block' ), true ) + ? $this->normalize_height( $this->style_for_context( 'height', $this->context(), 48 ), 40, 55 ) + : null, + ) ), ), 'separate_buttons' => array( 'card' => array( 'id' => CardButtonGateway::ID, 'wrapper' => '#ppc-button-' . CardButtonGateway::ID, - 'style' => array( - 'shape' => $this->style_for_apm( 'shape', 'card' ), - 'color' => $this->style_for_apm( 'color', 'card', 'black' ), - 'layout' => $this->style_for_apm( 'poweredby_tagline', 'card', false ) === $this->normalize_style_value( true ) ? 'vertical' : 'horizontal', + 'style' => $this->normalize_style( + array( + 'shape' => $this->style_for_apm( 'shape', 'card' ), + 'color' => $this->style_for_apm( 'color', 'card', 'black' ), + 'layout' => $this->style_for_apm( 'poweredby_tagline', 'card', false ) === $this->normalize_style_value( true ) ? 'vertical' : 'horizontal', + ) ), ), ), @@ -1143,13 +1160,6 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages $localize['pay_now'] = $this->pay_now_script_data(); } - if ( $this->style_for_context( 'layout', 'mini-cart' ) !== 'horizontal' ) { - $localize['button']['mini_cart_style']['tagline'] = false; - } - if ( $this->style_for_context( 'layout', $this->context() ) !== 'horizontal' ) { - $localize['button']['style']['tagline'] = false; - } - if ( $this->is_paypal_continuation() ) { $order = $this->session_handler->order(); assert( $order !== null ); @@ -1160,7 +1170,8 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages } $this->request_data->dequeue_nonce_fix(); - return $localize; + + return apply_filters( 'woocommerce_paypal_payments_localized_script_data', $localize ); } /** @@ -1269,9 +1280,12 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages } if ( in_array( $context, array( 'checkout-block', 'cart-block' ), true ) ) { - $disable_funding = array_diff( - array_keys( $this->all_funding_sources ), - array( 'venmo', 'paylater' ) + $disable_funding = array_merge( + $disable_funding, + array_diff( + array_keys( $this->all_funding_sources ), + array( 'venmo', 'paylater' ) + ) ); } @@ -1410,12 +1424,14 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages * * @param string $style The name of the style property. * @param string $context The context. + * @param ?mixed $default The default value. * - * @return string + * @return string|int */ - private function style_for_context( string $style, string $context ): string { - // Use the cart/checkout styles for blocks. - $context = str_replace( '-block', '', $context ); + private function style_for_context( string $style, string $context, $default = null ) { + if ( $context === 'checkout-block' ) { + $context = 'checkout-block-express'; + } $defaults = array( 'layout' => 'vertical', @@ -1433,6 +1449,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages return $this->get_style_value( "button_{$context}_${style}" ) ?? $this->get_style_value( "button_${style}" ) + ?? ( $default ? $this->normalize_style_value( $default ) : null ) ?? $this->normalize_style_value( $defaults[ $style ] ?? '' ); } @@ -1443,9 +1460,9 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages * @param string $apm The APM name, such as 'card'. * @param ?mixed $default The default value. * - * @return string + * @return string|int */ - private function style_for_apm( string $style, string $apm, $default = null ): string { + private function style_for_apm( string $style, string $apm, $default = null ) { return $this->get_style_value( "${apm}_button_${style}" ) ?? ( $default ? $this->normalize_style_value( $default ) : null ) ?? $this->style_for_context( $style, 'checkout' ); @@ -1455,9 +1472,9 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages * Returns the style property value or null. * * @param string $key The style property key in the settings. - * @return string|null + * @return string|int|null */ - private function get_style_value( string $key ): ?string { + private function get_style_value( string $key ) { if ( ! $this->settings->has( $key ) ) { return null; } @@ -1468,27 +1485,49 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages * Converts the style property value to string. * * @param mixed $value The style property value. - * @return string + * @return string|int */ - private function normalize_style_value( $value ): string { + private function normalize_style_value( $value ) { if ( is_bool( $value ) ) { $value = $value ? 'true' : 'false'; } + if ( is_int( $value ) ) { + return $value; + } return (string) $value; } /** - * Returns a value between 25 and 55. + * Fixes the style. * - * @param int $height The input value. + * @param array $style The style properties. + * @return array + */ + private function normalize_style( array $style ): array { + if ( array_key_exists( 'tagline', $style ) && ( ! array_key_exists( 'layout', $style ) || $style['layout'] !== 'horizontal' ) ) { + $style['tagline'] = false; + } + if ( array_key_exists( 'height', $style ) && ! $style['height'] ) { + unset( $style['height'] ); + } + return $style; + } + + /** + * Returns a number between min and max. + * + * @param mixed $height The input value. + * @param int $min The minimum value. + * @param int $max The maximum value. * @return int The normalized output value. */ - private function normalize_height( int $height ): int { - if ( $height < 25 ) { - return 25; + private function normalize_height( $height, int $min, int $max ): int { + $height = (int) $height; + if ( $height < $min ) { + return $min; } - if ( $height > 55 ) { - return 55; + if ( $height > $max ) { + return $max; } return $height; diff --git a/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php index 7e4f7c4ee..e33ab3b69 100644 --- a/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php @@ -14,6 +14,7 @@ use Exception; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; +use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderHelper; @@ -144,10 +145,11 @@ class ApproveOrderEndpoint implements EndpointInterface { $order = $this->api_endpoint->order( $data['order_id'] ); - if ( $order->payment_source() && $order->payment_source()->card() ) { + $payment_source = $order->payment_source(); + if ( $payment_source && $payment_source->name() === 'card' ) { if ( $this->settings->has( 'disable_cards' ) ) { $disabled_cards = (array) $this->settings->get( 'disable_cards' ); - $card = strtolower( $order->payment_source()->card()->brand() ); + $card = strtolower( $payment_source->properties()->brand ?? '' ); if ( 'master_card' === $card ) { $card = 'mastercard'; } diff --git a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php index 4ee88c3c7..2150b931f 100644 --- a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php @@ -25,12 +25,11 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory; -use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient; use WooCommerce\PayPalCommerce\Button\Exception\ValidationException; use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator; use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; +use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; use WooCommerce\PayPalCommerce\WcGateway\CardBillingMode; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; @@ -305,7 +304,7 @@ class CreateOrderEndpoint implements EndpointInterface { } try { - $order = $this->create_paypal_order( $wc_order ); + $order = $this->create_paypal_order( $wc_order, $payment_method, $data ); } catch ( Exception $exception ) { $this->logger->error( 'Order creation failed: ' . $exception->getMessage() ); throw $exception; @@ -416,6 +415,8 @@ class CreateOrderEndpoint implements EndpointInterface { * Creates the order in the PayPal, uses data from WC order if provided. * * @param \WC_Order|null $wc_order WC order to get data from. + * @param string $payment_method WC payment method. + * @param array $data Request data. * * @return Order Created PayPal order. * @@ -423,7 +424,7 @@ class CreateOrderEndpoint implements EndpointInterface { * @throws PayPalApiException If create order request fails. * phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber */ - private function create_paypal_order( \WC_Order $wc_order = null ): Order { + private function create_paypal_order( \WC_Order $wc_order = null, string $payment_method = '', array $data = array() ): Order { assert( $this->purchase_unit instanceof PurchaseUnit ); $funding_source = $this->parsed_request_data['funding_source'] ?? ''; @@ -465,7 +466,9 @@ class CreateOrderEndpoint implements EndpointInterface { $payer, null, '', - $action + $action, + $payment_method, + $data ); } catch ( PayPalApiException $exception ) { // Looks like currently there is no proper way to validate the shipping address for PayPal, diff --git a/modules/ppcp-button/src/Helper/ContextTrait.php b/modules/ppcp-button/src/Helper/ContextTrait.php index db6735424..c2811cb7b 100644 --- a/modules/ppcp-button/src/Helper/ContextTrait.php +++ b/modules/ppcp-button/src/Helper/ContextTrait.php @@ -12,6 +12,39 @@ namespace WooCommerce\PayPalCommerce\Button\Helper; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; trait ContextTrait { + /** + * Initializes context preconditions like is_cart() and is_checkout(). + * + * @return void + */ + protected function init_context(): void { + if ( ! apply_filters( 'woocommerce_paypal_payments_block_classic_compat', true ) ) { + return; + } + + /** + * Activate is_checkout() on woocommerce/classic-shortcode checkout blocks. + * + * @psalm-suppress MissingClosureParamType + */ + add_filter( + 'woocommerce_is_checkout', + function ( $is_checkout ) { + if ( $is_checkout ) { + return $is_checkout; + } + return has_block( 'woocommerce/classic-shortcode {"shortcode":"checkout"}' ); + } + ); + + // Activate is_cart() on woocommerce/classic-shortcode cart blocks. + if ( ! is_cart() && is_callable( 'wc_maybe_define_constant' ) ) { + if ( has_block( 'woocommerce/classic-shortcode' ) && ! has_block( 'woocommerce/classic-shortcode {"shortcode":"checkout"}' ) ) { + wc_maybe_define_constant( 'WOOCOMMERCE_CART', true ); + } + } + } + /** * Checks WC is_checkout() + WC checkout ajax requests. */ @@ -94,6 +127,10 @@ trait ContextTrait { return 'checkout'; } + if ( $this->is_add_payment_method_page() ) { + return 'add-payment-method'; + } + return 'mini-cart'; } @@ -125,6 +162,11 @@ trait ContextTrait { * @return bool */ private function is_paypal_continuation(): bool { + /** + * Property is already defined in trait consumers. + * + * @psalm-suppress UndefinedThisPropertyFetch + */ $order = $this->session_handler->order(); if ( ! $order ) { return false; @@ -137,7 +179,7 @@ trait ContextTrait { } $source = $order->payment_source(); - if ( $source && $source->card() ) { + if ( $source && $source->name() === 'card' ) { return false; // Ignore for DCC. } @@ -147,4 +189,22 @@ trait ContextTrait { return true; } + + /** + * Checks whether current page is Add payment method. + * + * @return bool + */ + private function is_add_payment_method_page(): bool { + /** + * Needed for WordPress `query_vars`. + * + * @psalm-suppress InvalidGlobal + */ + global $wp; + + $page_id = wc_get_page_id( 'myaccount' ); + + return $page_id && is_page( $page_id ) && isset( $wp->query_vars['add-payment-method'] ); + } } diff --git a/modules/ppcp-button/src/Helper/ThreeDSecure.php b/modules/ppcp-button/src/Helper/ThreeDSecure.php index e2d8b9e49..e99f12bdc 100644 --- a/modules/ppcp-button/src/Helper/ThreeDSecure.php +++ b/modules/ppcp-button/src/Helper/ThreeDSecure.php @@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\Button\Helper; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Entity\CardAuthenticationResult as AuthResult; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; +use WooCommerce\PayPalCommerce\ApiClient\Factory\CardAuthenticationResultFactory; /** * Class ThreeDSecure @@ -23,6 +24,13 @@ class ThreeDSecure { const REJECT = 2; const RETRY = 3; + /** + * Card authentication result factory. + * + * @var CardAuthenticationResultFactory + */ + private $card_authentication_result_factory; + /** * The logger. * @@ -33,10 +41,15 @@ class ThreeDSecure { /** * ThreeDSecure constructor. * - * @param LoggerInterface $logger The logger. + * @param CardAuthenticationResultFactory $card_authentication_result_factory Card authentication result factory. + * @param LoggerInterface $logger The logger. */ - public function __construct( LoggerInterface $logger ) { - $this->logger = $logger; + public function __construct( + CardAuthenticationResultFactory $card_authentication_result_factory, + LoggerInterface $logger + ) { + $this->logger = $logger; + $this->card_authentication_result_factory = $card_authentication_result_factory; } /** @@ -49,29 +62,36 @@ class ThreeDSecure { * @return int */ public function proceed_with_order( Order $order ): int { - if ( ! $order->payment_source() ) { - return self::NO_DECISION; - } - if ( ! $order->payment_source()->card() ) { - return self::NO_DECISION; - } - if ( ! $order->payment_source()->card()->authentication_result() ) { + $payment_source = $order->payment_source(); + if ( ! $payment_source ) { return self::NO_DECISION; } - $result = $order->payment_source()->card()->authentication_result(); - $this->logger->info( '3DS authentication result: ' . wc_print_r( $result->to_array(), true ) ); - - if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) { - return self::PROCCEED; + if ( ! $payment_source->properties()->brand ?? '' ) { + return self::NO_DECISION; + } + if ( ! $payment_source->properties()->authentication_result ?? '' ) { + return self::NO_DECISION; } - if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_UNKNOWN ) { - return self::RETRY; - } - if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_NO ) { - return $this->no_liability_shift( $result ); + $authentication_result = $payment_source->properties()->authentication_result ?? null; + if ( $authentication_result ) { + $result = $this->card_authentication_result_factory->from_paypal_response( $authentication_result ); + + $this->logger->info( '3DS authentication result: ' . wc_print_r( $result->to_array(), true ) ); + + if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) { + return self::PROCCEED; + } + + if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_UNKNOWN ) { + return self::RETRY; + } + if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_NO ) { + return $this->no_liability_shift( $result ); + } } + return self::NO_DECISION; } diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index 4471485aa..8524f1f6d 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -89,6 +89,12 @@ class CardFieldsModule implements ModuleInterface { add_filter( 'ppcp_create_order_request_body_data', function( array $data ) use ( $c ): array { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $payment_method = wc_clean( wp_unslash( $_POST['payment_method'] ?? '' ) ); + if ( $payment_method !== CreditCardGateway::ID ) { + return $data; + } + $settings = $c->get( 'wcgateway.settings' ); assert( $settings instanceof Settings ); diff --git a/modules/ppcp-compat/services.php b/modules/ppcp-compat/services.php index 9907a15c0..364686a84 100644 --- a/modules/ppcp-compat/services.php +++ b/modules/ppcp-compat/services.php @@ -27,7 +27,7 @@ return array( }, 'compat.ppec.subscriptions-handler' => static function ( ContainerInterface $container ) { - $ppcp_renewal_handler = $container->get( 'subscription.renewal-handler' ); + $ppcp_renewal_handler = $container->get( 'wc-subscriptions.renewal-handler' ); $gateway = $container->get( 'compat.ppec.mock-gateway' ); return new PPEC\SubscriptionsHandler( $ppcp_renewal_handler, $gateway ); diff --git a/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php b/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php index 90e2b5493..217374007 100644 --- a/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php +++ b/modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php @@ -11,7 +11,7 @@ namespace WooCommerce\PayPalCommerce\Compat\PPEC; use Automattic\WooCommerce\Utilities\OrderUtil; use stdClass; -use WooCommerce\PayPalCommerce\Subscription\RenewalHandler; +use WooCommerce\PayPalCommerce\WcSubscriptions\RenewalHandler; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken; /** diff --git a/modules/ppcp-googlepay/resources/css/styles.scss b/modules/ppcp-googlepay/resources/css/styles.scss index f8233a410..0747a2a91 100644 --- a/modules/ppcp-googlepay/resources/css/styles.scss +++ b/modules/ppcp-googlepay/resources/css/styles.scss @@ -1,52 +1,9 @@ .ppcp-button-googlepay { - margin: 7px 0; - overflow: hidden; min-height: 40px; - height: 45px; - - &.ppcp-button-pill { - border-radius: 50px; - } - - &.ppcp-button-minicart { - display: block; - height: 40px; - } } -.woocommerce-checkout { - .ppcp-button-googlepay { - margin-top: 0; - } -} - -.ppcp-has-googlepay-block { - - .wp-block-woocommerce-checkout { - .ppcp-button-googlepay { - margin: 0; - height: 40px; - } - } - - .wp-block-woocommerce-cart { - .ppcp-button-googlepay { - margin: 0; - height: 40px; - } - /* Workaround for blocks grid */ - .wc-block-components-express-payment__event-buttons { - display: block; - li[id*="express-payment-method-ppcp-"] { - padding-bottom: 0; - } - } - } - -} - -.wp-admin { - .ppcp-button-googlepay { - pointer-events: none; +.wp-block-woocommerce-checkout, .wp-block-woocommerce-cart { + .gpay-button { + min-width: 0 !important; } } diff --git a/modules/ppcp-googlepay/resources/js/GooglepayButton.js b/modules/ppcp-googlepay/resources/js/GooglepayButton.js index 61b5451ba..3331a4d49 100644 --- a/modules/ppcp-googlepay/resources/js/GooglepayButton.js +++ b/modules/ppcp-googlepay/resources/js/GooglepayButton.js @@ -3,10 +3,13 @@ import {setVisible} from '../../../ppcp-button/resources/js/modules/Helper/Hidin import {setEnabled} from '../../../ppcp-button/resources/js/modules/Helper/ButtonDisabler'; import widgetBuilder from "../../../ppcp-button/resources/js/modules/Renderer/WidgetBuilder"; import UpdatePaymentData from "./Helper/UpdatePaymentData"; +import {apmButtonsInit} from "../../../ppcp-button/resources/js/modules/Helper/ApmButtons"; class GooglepayButton { constructor(context, externalHandler, buttonConfig, ppcpConfig) { + apmButtonsInit(ppcpConfig); + this.isInitialized = false; this.context = context; @@ -111,7 +114,7 @@ class GooglepayButton { } if (['cart-block', 'checkout-block'].indexOf(this.context) !== -1) { - config.ppcpButtonWrapper = '#express-payment-method-ppcp-gateway'; + config.ppcpButtonWrapper = '#express-payment-method-ppcp-gateway-paypal'; } return config; @@ -168,6 +171,10 @@ class GooglepayButton { this.waitForWrapper(wrapper, () => { jQuery(wrapper).addClass('ppcp-button-' + ppcpStyle.shape); + if (ppcpStyle.height) { + jQuery(wrapper).css('height', `${ppcpStyle.height}px`) + } + const button = this.paymentsClient.createButton({ onClick: this.onButtonClick.bind(this), diff --git a/modules/ppcp-googlepay/resources/js/boot-admin.js b/modules/ppcp-googlepay/resources/js/boot-admin.js index 577733b6b..3b971986f 100644 --- a/modules/ppcp-googlepay/resources/js/boot-admin.js +++ b/modules/ppcp-googlepay/resources/js/boot-admin.js @@ -67,7 +67,7 @@ import widgetBuilder from "../../../ppcp-button/resources/js/modules/Renderer/Wi buttonConfig.button.wrapper = selector; applyConfigOptions(buttonConfig); - const wrapperElement = `
`; + const wrapperElement = `
`; if (!jQuery(selector).length) { jQuery(ppcpConfig.button.wrapper).after(wrapperElement); diff --git a/modules/ppcp-googlepay/resources/js/boot-block.js b/modules/ppcp-googlepay/resources/js/boot-block.js index 8b7ab78fb..bc117357a 100644 --- a/modules/ppcp-googlepay/resources/js/boot-block.js +++ b/modules/ppcp-googlepay/resources/js/boot-block.js @@ -24,13 +24,6 @@ const GooglePayComponent = () => { manager.init(); }; - useEffect(() => { - const bodyClass = 'ppcp-has-googlepay-block'; - if (!document.body.classList.contains(bodyClass)) { - document.body.classList.add(bodyClass); - } - }, []); - useEffect(() => { // Load GooglePay SDK loadCustomScript({ url: buttonConfig.sdk_url }).then(() => { @@ -51,14 +44,13 @@ const GooglePayComponent = () => { }, [paypalLoaded, googlePayLoaded]); return ( -
+
); } const features = ['products']; -let registerMethod = registerExpressPaymentMethod; -registerMethod({ +registerExpressPaymentMethod({ name: buttonData.id, label:
, content: , diff --git a/modules/ppcp-googlepay/src/Assets/Button.php b/modules/ppcp-googlepay/src/Assets/Button.php index df482c73f..15f16e381 100644 --- a/modules/ppcp-googlepay/src/Assets/Button.php +++ b/modules/ppcp-googlepay/src/Assets/Button.php @@ -311,7 +311,7 @@ class Button implements ButtonInterface { add_action( $render_placeholder, function () { - echo ''; + echo ''; }, 21 ); @@ -325,7 +325,7 @@ class Button implements ButtonInterface { */ private function googlepay_button(): void { ?> -
+
{ const toggleElement = document.querySelector(selector); @@ -317,6 +317,7 @@ document.addEventListener( '#field-button' + locationPrefix + '_label', '#field-button' + locationPrefix + '_color', '#field-button' + locationPrefix + '_shape', + '#field-button' + locationPrefix + '_height', '#field-button' + locationPrefix + '_preview', ] @@ -324,11 +325,7 @@ document.addEventListener( inputSelectors.push('#field-button_' + location + '_heading'); } - if (location === 'mini-cart') { - inputSelectors.push('#field-button' + locationPrefix + '_height'); - } - - return inputSelectors + return inputSelectors.filter(selector => document.querySelector(selector)); } const allPayLaterMessaginginputSelectors = () => { diff --git a/modules/ppcp-onboarding/services.php b/modules/ppcp-onboarding/services.php index 27ab1ad25..b76519f62 100644 --- a/modules/ppcp-onboarding/services.php +++ b/modules/ppcp-onboarding/services.php @@ -71,6 +71,12 @@ return array( 'api.paypal-host-sandbox' => static function( ContainerInterface $container ) : string { return PAYPAL_SANDBOX_API_URL; }, + 'api.paypal-website-url-production' => static function( ContainerInterface $container ) : string { + return PAYPAL_URL; + }, + 'api.paypal-website-url-sandbox' => static function( ContainerInterface $container ) : string { + return PAYPAL_SANDBOX_URL; + }, 'api.partner_merchant_id-production' => static function( ContainerInterface $container ) : string { return CONNECT_WOO_MERCHANT_ID; }, @@ -89,6 +95,15 @@ return array( } return $container->get( 'api.paypal-host-production' ); + }, + 'api.paypal-website-url' => function( ContainerInterface $container ) : string { + $environment = $container->get( 'onboarding.environment' ); + assert( $environment instanceof Environment ); + if ( $environment->current_environment_is( Environment::SANDBOX ) ) { + return $container->get( 'api.paypal-website-url-sandbox' ); + } + return $container->get( 'api.paypal-website-url-production' ); + }, 'api.bearer' => static function ( ContainerInterface $container ): Bearer { diff --git a/modules/ppcp-order-tracking/carriers.php b/modules/ppcp-order-tracking/carriers.php index 429f12a51..07f84a174 100644 --- a/modules/ppcp-order-tracking/carriers.php +++ b/modules/ppcp-order-tracking/carriers.php @@ -9,1585 +9,1607 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\OrderTracking; +if ( ! function_exists( 'WooCommerce\PayPalCommerce\OrderTracking\tr' ) ) { + /** + * Prevent strings of being added to the .pot file but still be translatable via "gettext_with_context" filter if necessary. + * + * @param string $text Text to translate. + * @param string $context Context information for the translators. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. + * @return string Translated context string without pipe. + */ + function tr( string $text, string $context, string $domain ): string { + // We want to call "_x" with variable arguments so the text isn't added to generated .pot translation files. + return _x( + // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText + $text, + // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralContext + $context, + // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain + $domain + ); + } +} + return (array) apply_filters( 'woocommerce_paypal_payments_tracking_carriers', array( 'global' => array( 'name' => 'Global', 'items' => array( - '99MINUTOS' => _x( '99minutos', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'A2B_BA' => _x( 'A2B Express Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ABCUSTOM_SFTP' => _x( 'AB Custom Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ACILOGISTIX' => _x( 'ACI Logistix', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ACOMMERCE' => _x( 'ACOMMERCE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ACTIVOS24_API' => _x( 'Activos24', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ADS' => _x( 'ADS Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AEROFLASH' => _x( 'AEROFLASH', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AGEDISS_SFTP' => _x( 'Agediss', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AIR_21' => _x( 'AIR 21', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AIRSPEED' => _x( 'AIRSPEED', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AIRTERRA' => _x( 'Airterra', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AITWORLDWIDE_API' => _x( 'AIT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AITWORLDWIDE_SFTP' => _x( 'AIT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ALLIED_EXPRESS_FTP' => _x( 'Allied Express (FTP)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ALLJOY' => _x( 'ALLJOY SUPPLY CHAIN', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AMAZON_EMAIL_PUSH' => _x( 'Amazon', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AMAZON_ORDER' => _x( 'Amazon order', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AMAZON_UK_API' => _x( 'amazon_uk_api', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AMS_GRP' => _x( 'AMS Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ANDREANI_API' => _x( 'Andreani', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ANTERAJA' => _x( 'Anteraja', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARAMEX' => _x( 'Aramex', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARAMEX_API' => _x( 'Aramex', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARASKARGO' => _x( 'Aras Cargo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARGENTS_WEBHOOK' => _x( 'Argents Express Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ASENDIA_DE' => _x( 'asendia_de', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ATSHEALTHCARE_REFERENCE' => _x( 'ATS Healthcare', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ATSHEALTHCARE' => _x( 'ATS Healthcare', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AUEXPRESS' => _x( 'Au Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AUSTRALIA_POST_API' => _x( 'Australia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AVERITT' => _x( 'Averitt Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AXLEHIRE_FTP' => _x( 'Axlehire', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AXLEHIRE' => _x( 'AxleHire', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BARQEXP' => _x( 'Barq', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BDMNET' => _x( 'BDMnet', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BEL_BELGIUM_POST' => _x( 'bel_belgium_post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BLR_BELPOST' => _x( 'Belpost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BERT' => _x( 'BERT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BESTTRANSPORT_SFTP' => _x( 'Best Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BETTERTRUCKS' => _x( 'Better Trucks', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BIGSMART' => _x( 'Big Smart', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BIOCAIR_FTP' => _x( 'BioCair', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BJSHOMEDELIVERY' => _x( 'BJS Distribution courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BJSHOMEDELIVERY_FTP' => _x( 'BJS Distribution, Storage & Couriers - FTP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BLUEDART' => _x( 'BLUEDART', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BLUEDART_API' => _x( 'Bluedart', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BOLLORE_LOGISTICS' => _x( 'Bollore Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BOMI' => _x( 'Bomi Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BE_BPOST' => _x( 'Bpost (www.bpost.be)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BPOST_API' => _x( 'Bpost API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BPOST_INT' => _x( 'Bpost international', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BRT_IT_API' => _x( 'BRT Bartolini API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BUFFALO' => _x( 'BUFFALO', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BURD' => _x( 'Burd Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CHROBINSON' => _x( 'C.H. Robinson Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CAGO' => _x( 'Cago', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CANPAR' => _x( 'CANPAR', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CAPITAL' => _x( 'Capital Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CARRY_FLAP' => _x( 'Carry-Flap Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CBL_LOGISTICA_API' => _x( 'CBL Logistica (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CDLDELIVERS' => _x( 'CDL Last Mile', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CELERITAS' => _x( 'Celeritas Transporte', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CEVA' => _x( 'CEVA LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CEVA_TRACKING' => _x( 'CEVA Package', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CHAZKI' => _x( 'Chazki', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CHIENVENTURE_WEBHOOK' => _x( 'Chienventure', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CHILEXPRESS' => _x( 'Chile Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CITY56_WEBHOOK' => _x( 'City Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJ_GLS' => _x( 'CJ GLS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJ_LOGISTICS' => _x( 'CJ Logistics International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJ_PHILIPPINES' => _x( 'cj_philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CLICKLINK_SFTP' => _x( 'ClickLink', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_LOGISTICS' => _x( 'CN Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COLLECTPLUS' => _x( 'COLLECTPLUS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COM1EXPRESS' => _x( 'ComOne Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CONCISE' => _x( 'Concise', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CONCISE_WEBHOOK' => _x( 'Concise', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CONCISE_API' => _x( 'Concise', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COORDINADORA_API' => _x( 'Coordinadora', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COPA_COURIER' => _x( 'Copa Airlines Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CORREOS_DE_ESPANA' => _x( 'CORREOS DE ESPANA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CORREOSEXPRESS_API' => _x( 'Correos Express (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CORREOS_ES' => _x( 'correos Express (www.correos.es)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COURANT_PLUS_API' => _x( 'Courant Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COURIER_POST' => _x( 'COURIER POST', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COURIERPLUS' => _x( 'COURIERPLUS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CRLEXPRESS' => _x( 'CRL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CROSSFLIGHT' => _x( 'Crossflight Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CRYOPDP_FTP' => _x( 'CryoPDP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CESKAPOSTA_API' => _x( 'Czech Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DEXPRESS_WEBHOOK' => _x( 'D Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DACHSER' => _x( 'DACHSER', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DACHSER_WEB' => _x( 'DACHSER', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DAESHIN' => _x( 'Daeshin', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DAIICHI' => _x( 'Daiichi Freight System Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DANNIAO' => _x( 'Danniao', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DAO365' => _x( 'DAO365', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DAYROSS' => _x( 'Day & Ross', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DYLT' => _x( 'Daylight Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DBSCHENKER_API' => _x( 'DB Schenker', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DBSCHENKER_B2B' => _x( 'DB Schenker B2B', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DBSCHENKER_ICELAND' => _x( 'DB Schenker Iceland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DDEXPRESS' => _x( 'DD Express Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DE_DHL' => _x( 'DE DHL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELCART_IN' => _x( 'delcart_in', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELIVERYOURPARCEL_ZA' => _x( 'Deliver Your Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELIVER_IT' => _x( 'Deliver-iT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELIVERE' => _x( 'delivere', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELIVERR_SFTP' => _x( 'Deliverr', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELTEC_DE' => _x( 'DELTEC DE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DEMANDSHIP' => _x( 'DemandShip', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DEUTSCHE_DE' => _x( 'deutsche_de', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_API' => _x( 'DHL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_REFERENCE_API' => _x( 'DHL (Reference number)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_ACTIVE_TRACING' => _x( 'DHL Active Tracing', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_ECOMMERCE_GC' => _x( 'DHL eCommerce Greater China', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_GLOBAL_MAIL_API' => _x( 'DHL eCommerce Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DE_DHL_EXPRESS' => _x( 'DHL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_SFTP' => _x( 'DHL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_FR' => _x( 'DHL France (www.dhl.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_FREIGHT' => _x( 'DHL Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL' => _x( 'dhl Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_GLOBAL_FORWARDING_API' => _x( 'DHL Global Forwarding API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_GT_API' => _x( 'DHL Global Forwarding Guatemala', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_PA_API' => _x( 'DHL GLOBAL FORWARDING PANAMÁ', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IT_DHL_ECOMMERCE' => _x( 'DHL International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_JP' => _x( 'DHL Japan', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_PARCEL_NL' => _x( 'DHL Parcel NL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_SG' => _x( 'dhl Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_ES_SFTP' => _x( 'DHL Spain Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_SUPPLYCHAIN_IN' => _x( 'DHL supply chain India', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_SUPPLYCHAIN_ID' => _x( 'DHL Supply Chain Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_AT' => _x( 'dhl_at', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_GLOBAL_MAIL' => _x( 'dhl_global_mail', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_IT' => _x( 'dhl_it', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_PIECEID' => _x( 'dhl_pieceid', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_SUPPLY_CHAIN_AU' => _x( 'dhl_supply_chain_au', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHLPARCEL_UK' => _x( 'dhlparcel_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIALOGO_LOGISTICA_API' => _x( 'Dialogo Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIALOGO_LOGISTICA' => _x( 'Dialogo Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIRECTFREIGHT_AU_REF' => _x( 'Direct Freight Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIREX' => _x( 'Direx', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DKSH' => _x( 'DKSH', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DMFGROUP' => _x( 'DMF', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DNJ_EXPRESS' => _x( 'DNJ Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DOTZOT' => _x( 'DOTZOT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD' => _x( 'DPD', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_AT_SFTP' => _x( 'DPD Austria', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_DELISTRACK' => _x( 'DPD delistrack', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_NL' => _x( 'DPD Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_RU_API' => _x( 'DPD Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_SK_SFTP' => _x( 'DPD Slovakia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_CH_SFTP' => _x( 'DPD Switzerland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_UK_SFTP' => _x( 'DPD UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_DE' => _x( 'dpd_de', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_FR_REFERENCE' => _x( 'dpd_fr_reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_UK' => _x( 'dpd_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_DPEX' => _x( 'DPEX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPEX' => _x( 'DPEX (www.dpex.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DSV' => _x( 'DSV courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DSV_REFERENCE' => _x( 'DSV Futurewave', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DX' => _x( 'DX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DX_B2B_CONNUM' => _x( 'DX (B2B)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DX_FREIGHT' => _x( 'DX Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DYNALOGIC' => _x( 'Dynamic Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EASTWESTCOURIER_FTP' => _x( 'East West Courier Pte Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EC_CN' => _x( 'EC_CN', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ECARGO' => _x( 'ECARGO', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ECEXPRESS' => _x( 'ECexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ECMS' => _x( 'ECMS International Logistics Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ECOFREIGHT' => _x( 'Eco Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ECOURIER' => _x( 'ecourier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ECOUTIER' => _x( 'eCoutier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EFS' => _x( 'EFS (E-commerce Fulfillment Service)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ELITE_CO' => _x( 'Elite Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ELOGISTICA' => _x( 'elogistica', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ELTA_GR' => _x( 'elta_gr', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARE_EMIRATES_POST' => _x( 'Emirates Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EMS' => _x( 'EMS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EMS_CN' => _x( 'ems_cn', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ENSENDA' => _x( 'ENSENDA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EFWNOW_API' => _x( 'Estes Forwarding Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ETOMARS' => _x( 'Etomars', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ETOTAL' => _x( 'eTotal Solution Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EDF_FTP' => _x( 'Eurodifarm', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EURODIS' => _x( 'eurodis', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EUROPAKET_API' => _x( 'Europacket+', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYHERMES_UK_API' => _x( 'EVRi', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EWE' => _x( 'EWE Global Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EXELOT_FTP' => _x( 'Exelot Ltd.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EXPEDITORS' => _x( 'Expeditors', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EXPEDITORS_API_REF' => _x( 'Expeditors API Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EZSHIP' => _x( 'EZship', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FAIRSENDEN_API' => _x( 'fairsenden', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FXTRAN' => _x( 'Falcon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FAN' => _x( 'FAN COURIER EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FNF_ZA' => _x( 'Fast & Furious', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTDESPATCH' => _x( 'Fast Despatch Logistics Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTBOX' => _x( 'Fastbox', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTSHIP' => _x( 'Fastship Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTTRACK' => _x( 'fasttrack', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTWAY_AU' => _x( 'fastway_au', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTWAY_UK' => _x( 'FASTWAY_UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTWAY_US' => _x( 'FASTWAY_US', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTWAY_ZA' => _x( 'fastway_za', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FAXECARGO' => _x( 'Faxe Cargo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FEDEX_FR' => _x( 'FedEx® Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FEDEX_API' => _x( 'FedEx®', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FERCAM_IT' => _x( 'fercam_it', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FETCHR' => _x( 'Fetchr', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FIRST_LOGISTICS_API' => _x( 'First Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FIRST_LOGISITCS' => _x( 'first_logisitcs', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FITZMARK_API' => _x( 'FitzMark', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FLASHEXPRESS_WEBHOOK' => _x( 'Flash Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FLIGHTLG' => _x( 'Flight Logistics Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FLIPXP' => _x( 'FlipXpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FLYTEXPRESS' => _x( 'FLYTEXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FORWARDAIR' => _x( 'Forward Air', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FOUR_PX_EXPRESS' => _x( 'FOUR PX EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FR_COLISSIMO' => _x( 'fr_colissimo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FR_MONDIAL' => _x( 'fr_mondial', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FRAGILEPAK_SFTP' => _x( 'FragilePAK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FRONTDOORCORP' => _x( 'FRONTdoor Collective', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FUJEXP' => _x( 'FUJIE EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GWLOGIS_API' => _x( 'G.I.G', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GAC' => _x( 'GAC', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GATI_KWE_API' => _x( 'Gati-KWE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GDPHARM' => _x( 'GDPharm Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GW_WORLD' => _x( 'Gebrüder Weiss', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GEODIS' => _x( 'GEODIS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GEODIS_API' => _x( 'GEODIS - Distribution & Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GPOST' => _x( 'Georgian Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GIAO_HANG' => _x( 'Giao hàng nhanh', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GIO_ECOURIER_API' => _x( 'GIO Express Ecourier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GIO_ECOURIER' => _x( 'GIO Express Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GOGLOBALPOST' => _x( 'Global Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOBEGISTICS' => _x( 'GLOBEGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOVO' => _x( 'Glovo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS' => _x( 'GLS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_SPAIN_API' => _x( 'GLS Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_DE' => _x( 'GLS_DE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_ES' => _x( 'GLS_ES', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_FR' => _x( 'GLS_FR', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_ITALY_FTP' => _x( 'gls_italy_ftp', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_SPAIN' => _x( 'gls_spain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GOLS' => _x( 'GO Logistics & Storage', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GOPEOPLE' => _x( 'Go People', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GORUSH' => _x( 'Go Rush', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GOJEK' => _x( 'Gojek', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GREYHOUND' => _x( 'GREYHOUND', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAZET' => _x( 'Groupe Mazet', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HANJIN' => _x( 'HanJin', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HELLENIC_POST' => _x( 'Hellenic (Greece) Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HELLMANN' => _x( 'Hellmann Worldwide Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HELTHJEM_API' => _x( 'Helthjem', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HERMES_DE_FTP' => _x( 'Hermes Germany', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HERMES_UK_SFTP' => _x( 'Hermes UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HERMESWORLD_UK' => _x( 'hermesworld_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HEROEXPRESS' => _x( 'Hero Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HFD' => _x( 'HFD', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HK_RPX' => _x( 'hk_rpx', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HOMELOGISTICS' => _x( 'Home Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HOMERUNNER' => _x( 'HomeRunner', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HERMES_IT' => _x( 'HR Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HSDEXPRESS' => _x( 'HSDEXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HSM_GLOBAL' => _x( 'HSM Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HUANTONG' => _x( 'HuanTong', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HUBBED' => _x( 'HUBBED', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HUNTER_EXPRESS_SFTP' => _x( 'Hunter Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IBVENTURE_WEBHOOK' => _x( 'IB Venture', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTUR_IS' => _x( 'Iceland Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ICSCOURIER' => _x( 'ICS COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IDEXPRESS_ID' => _x( 'iDexpress Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IDN_POS' => _x( 'idn_pos', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IDS_LOGISTICS' => _x( 'ids_logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ILYANGLOGIS' => _x( 'Ilyang logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IMEXGLOBALSOLUTIONS' => _x( 'imexglobalsolutions', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IMILE_API' => _x( 'iMile', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IML' => _x( 'IML courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IMX' => _x( 'IMX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INDIA_POST' => _x( 'India Post Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INDIA_POST_INT' => _x( 'India Post International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INEXPOST' => _x( 'Inexpost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INNTRALOG_SFTP' => _x( 'Inntralog GmbH', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INPOST_UK' => _x( 'InPost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INSTABOX_WEBHOOK' => _x( 'Instabox', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTERNATIONAL_SEUR_API' => _x( 'International Seur API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTERSMARTTRANS' => _x( 'INTERSMARTTRANS & SOLUTIONS SL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTEX_DE' => _x( 'INTEX Paketdienst GmbH', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTIME_FTP' => _x( 'InTime', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ITHINKLOGISTICS' => _x( 'iThink Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JTCARGO' => _x( 'J&T CARGO', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JTEXPRESS_PH' => _x( 'J&T Express Philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JTEXPRESS_SG_API' => _x( 'J&T Express Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JT_LOGISTICS' => _x( 'J&T International logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JAVIT' => _x( 'Javit', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_JCEX' => _x( 'JCEX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JD_EXPRESS' => _x( 'JD Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JD_WORLDWIDE' => _x( 'JD Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JETSHIP_MY' => _x( 'jetship_my', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JNE_API' => _x( 'JNE (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IDN_JNE' => _x( 'JNE Express (Jalur Nugraha Ekakurir)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JOYINGBOX' => _x( 'joyingbox', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KARGOMKOLAY' => _x( 'KargomKolay (CargoMini)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KEDAEX' => _x( 'KedaEX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HK_TGX' => _x( 'Kerry Express Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KERRY_EXPRESS_TW_API' => _x( 'Kerry Express TaiWan', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THA_KERRY' => _x( 'Kerry Express Thailand', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KERRY_EXPRESS_TH_WEBHOOK' => _x( 'Kerry Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KNG' => _x( 'Keuhne + Nagel Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BE_KIALA' => _x( 'Kiala', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGISYSTEMS_SFTP' => _x( 'Kiitääjät', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KOMON_EXPRESS' => _x( 'Komon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KRONOS_WEBHOOK' => _x( 'Kronos Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KRONOS' => _x( 'Kronos Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KUEHNE' => _x( 'Kuehne + Nagel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LALAMOVE_API' => _x( 'Lalamove', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LBCEXPRESS_FTP' => _x( 'LBC EXPRESS INC.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LBCEXPRESS_API' => _x( 'LBC EXPRESS INC.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LCTBR_API' => _x( 'LCT do Brasil', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LTU_LIETUVOS' => _x( 'Lietuvos pastas', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LINKBRIDGE' => _x( 'Link Bridge(BeiJing)international logistics co.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LION_PARCEL' => _x( 'LION PARCEL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LIVRAPIDE' => _x( 'Livrapide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGGI' => _x( 'Loggi', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGISTICSWORLDWIDE_KR' => _x( 'LOGISTICSWORLDWIDE KR', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGISTICSWORLDWIDE_MY' => _x( 'LOGISTICSWORLDWIDE MY', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGWIN_LOGISTICS' => _x( 'Logwin Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGYSTO' => _x( 'Logysto', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LUWJISTIK' => _x( 'Luwjistik', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MX_CARGO' => _x( 'M&X cargo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'M3LOGISTICS' => _x( 'M3 Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'REIMAGINEDELIVERY' => _x( 'maergo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAGYAR_POSTA_API' => _x( 'Magyar Posta', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAIL_BOX_ETC' => _x( 'Mail Boxes Etc.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYS_EMS' => _x( 'Malaysia Post EMS / Pos Laju', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MALCA_AMIT_API' => _x( 'Malca Amit', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MALCA_AMIT' => _x( 'Malca-Amit', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MARKEN' => _x( 'Marken', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MEDAFRICA' => _x( 'Med Africa Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MEEST' => _x( 'Meest', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MEGASAVE' => _x( 'megasave', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MENSAJEROSURBANOS_API' => _x( 'Mensajeros Urbanos', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MWD' => _x( 'Metropolitan Warehouse & Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MWD_API' => _x( 'Metropolitan Warehouse & Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MHI' => _x( 'Mhi', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MIKROPAKKET' => _x( 'Mikropakket', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MISUMI_CN' => _x( 'MISUMI Group Inc.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MNX' => _x( 'MNX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MOBI_BR' => _x( 'Mobi Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MONDIALRELAY_FR' => _x( 'Mondial Relay France', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MONDIALRELAY_ES' => _x( 'Mondial Relay Spain(Punto Pack)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MONDIAL_BE' => _x( 'MONDIAL_BE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MOOVA' => _x( 'Moova', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MORNINGLOBAL' => _x( 'Morning Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MOTHERSHIP_API' => _x( 'Mothership', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MOVIANTO' => _x( 'Movianto', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MUDITA' => _x( 'MUDITA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYDYNALOGIC' => _x( 'My DynaLogic', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYSENDLE_API' => _x( 'mySendle', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NMTRANSFER' => _x( 'N&M Transfer Co., Inc.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NACEX_SPAIN_REFERENCE' => _x( 'nacex_spain_reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NAEKO_FTP' => _x( 'Naeko Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NAQEL_EXPRESS' => _x( 'Naqel Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NEWZEALAND_COURIERS' => _x( 'NEW ZEALAND COURIERS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NEWGISTICS' => _x( 'Newgistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NEWGISTICSAPI' => _x( 'Newgistics API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NIGHTLINE_UK' => _x( 'nightline_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NIMBUSPOST' => _x( 'NimbusPost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NIPPON_EXPRESS_FTP' => _x( 'Nippon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NIPPON_EXPRESS' => _x( 'Nippon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NORTHLINE' => _x( 'Northline', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NOVA_POSHTA_API' => _x( 'Nova Poshta API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NOVOFARMA_WEBHOOK' => _x( 'Novofarma', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NTL' => _x( 'NTL logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NYTLOGISTICS' => _x( 'NYT SUPPLY CHAIN LOGISTICS Co., LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OHI_WEBHOOK' => _x( 'Ohi', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHOPOLIVE' => _x( 'Olive', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OMLOGISTICS_API' => _x( 'OM LOGISTICS LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OMNIRPS_WEBHOOK' => _x( 'Omni Returns', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ONTRAC' => _x( 'ONTRAC', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ORANGECONNEX' => _x( 'orangeconnex', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ORANGE_DS' => _x( 'OrangeDS (Orange Distribution Solutions Inc)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OSM_WORLDWIDE_SFTP' => _x( 'OSM Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OZEPARTS_SHIPPING' => _x( 'Ozeparts Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'P2P_TRC' => _x( 'P2P TrakPak', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PACKETA' => _x( 'Packeta', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PACKFLEET' => _x( 'PACKFLEET', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PACKS' => _x( 'Packs', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAKAJO' => _x( 'Pakajo World', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PANDAGO_API' => _x( 'Pandago', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PANDION' => _x( 'Pandion', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PANDU' => _x( 'PANDU', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PANTHER_REFERENCE_API' => _x( 'Panther Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PANTHER_ORDER_NUMBER' => _x( 'panther_order_number', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAPA_WEBHOOK' => _x( 'Papa', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELRIGHT' => _x( 'Parcel Right', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCEL_2_POST' => _x( 'Parcel To Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELFORCE' => _x( 'PARCELFORCE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELSTARS_WEBHOOK' => _x( 'Parcelstars', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCLL' => _x( 'PARCLL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PASSPORTSHIPPING' => _x( 'Passport Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PATHEON' => _x( 'Patheon Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAYO' => _x( 'Payo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PCHOME_API' => _x( 'Pchome Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PGEON_API' => _x( 'Pgeon', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PHSE_API' => _x( 'PHSE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PICKUPP_VNM' => _x( 'pickupp_vnm', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PIDGE' => _x( 'Pidge', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PIL_LOGISTICS' => _x( 'PIL Logistics (China) Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PLYCONGROUP' => _x( 'Plycon Transportation Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POLARSPEED' => _x( 'PolarSpeed Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTONE' => _x( 'Post ONE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTAPLUS' => _x( 'Posta Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTE_ITALIANE_PACCOCELERE' => _x( 'Poste Italiane Paccocelere', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTEN_NORGE' => _x( 'Posten Norge (www.posten.no)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTI_API' => _x( 'Posti API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTNL_INT_3_S' => _x( 'PostNL International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NLD_POSTNL' => _x( 'PostNL International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTNL_INTERNATIONAL' => _x( 'PostNL International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SWE_POSTNORD' => _x( 'Postnord sweden', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTPLUS' => _x( 'PostPlus', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PROCARRIER' => _x( 'Pro Carrier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRODUCTCAREGROUP_SFTP' => _x( 'Product Care Services Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PROFESSIONAL_COURIERS' => _x( 'PROFESSIONAL COURIERS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PPL' => _x( 'Professional Parcel Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PROMEDDELIVERY' => _x( 'ProMed Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PUROLATOR' => _x( 'purolator', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PUROLATOR_INTERNATIONAL' => _x( 'Purolator International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'QTRACK' => _x( 'QTrack', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'QUALITYPOST' => _x( 'qualitypost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'QINTL_API' => _x( 'Quickstat Courier LLC', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'QUIQUP' => _x( 'Quiqup', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RANSA_WEBHOOK' => _x( 'Ransa', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'REDJEPAKKETJE' => _x( 'Red je Pakketje', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RELAISCOLIS' => _x( 'Relais Colis', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RHENUS_GROUP' => _x( 'Rhenus Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RHENUS_UK_API' => _x( 'Rhenus Logistics UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AIR_CANADA' => _x( 'Rivo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RIXONHK_API' => _x( 'Rixon Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROCHE_INTERNAL_SFTP' => _x( 'Roche Internal Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROYAL_MAIL_FTP' => _x( 'Royal Mail', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROYALSHIPMENTS' => _x( 'royalshipments', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RRDONNELLEY' => _x( 'rrdonnelley', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RUSSIAN_POST' => _x( 'Russian post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SAEE' => _x( 'saee', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SAGAWA' => _x( 'SAGAWA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SAGAWA_API' => _x( 'Sagawa', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SBERLOGISTICS_RU' => _x( 'Sber Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SECRETLAB_WEBHOOK' => _x( 'Secretlab', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SEINO_API' => _x( 'Seino', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SEKO_SFTP' => _x( 'SEKO Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SENDING' => _x( 'Sending Transporte Urgente y Comunicacion', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHOWL' => _x( 'SENHONG INTERNATIONAL LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NOWLOG_API' => _x( 'Sequoialog', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SERVIENTREGA' => _x( 'Servientrega', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SERVIP_WEBHOOK' => _x( 'SerVIP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SETEL' => _x( 'Setel Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SF_EX' => _x( 'SF Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SF_EXPRESS_CN' => _x( 'SF Express China', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SGT_IT' => _x( 'SGT_IT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHADOWFAX' => _x( 'Shadowfax', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHENZHEN' => _x( 'shenzhen 1st International Logistics(Group)Co', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HOTSIN_CARGO' => _x( 'SHENZHEN HOTSIN CARGO INTL FORWARDING CO., LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KWT' => _x( 'Shenzhen Jinghuada Logistics Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHERPA' => _x( 'Sherpa', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPA' => _x( 'SHIPA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPPIE' => _x( 'Shippie', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPPIFY' => _x( 'Shippify, Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPROCKET' => _x( 'Shiprocket X', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPX' => _x( 'ShipX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPXPRES' => _x( 'SHIPXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPX' => _x( 'Shopee Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPX_TH' => _x( 'Shopee Xpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHUNBANG_EXPRESS' => _x( 'ShunBang Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHYPLITE' => _x( 'Shypmax', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SIMPLETIRE_WEBHOOK' => _x( 'SimpleTire', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SIMSGLOBAL' => _x( 'Sims Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SIODEMKA' => _x( 'SIODEMKA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SKynet_WORLDWIDE' => _x( 'SkyNet Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SKY_POSTAL' => _x( 'SkyPostal', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SK_POSTA' => _x( 'Slovenska pošta', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SMARTCAT' => _x( 'SMARTCAT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SMARTKARGO' => _x( 'SmartKargo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SMG_EXPRESS' => _x( 'SMG Direct', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SMSA_EXPRESS_WEBHOOK' => _x( 'SMSA Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SNTGLOBAL_API' => _x( 'Snt Global Etrax', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SOLISTICA_API' => _x( 'solistica', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPANISH_SEUR_FTP' => _x( 'Spanish Seur', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPECTRAN' => _x( 'Spectran', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPEEDEX' => _x( 'speedex', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPEEDY' => _x( 'Speedy', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPREETAIL_API' => _x( 'Spreetail', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPRINT_PACK' => _x( 'SPRINT PACK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SRT_TRANSPORT' => _x( 'SRT Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STAR_TRACK_NEXT_FLIGHT' => _x( 'Star Track Next Flight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STARLINKS_API' => _x( 'Starlinks Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STARTRACK' => _x( 'startrack', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STAR_TRACK_WEBHOOK' => _x( 'StarTrack', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STARTRACK_EXPRESS' => _x( 'startrack_express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STATOVERNIGHT' => _x( 'Stat Overnight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_STO' => _x( 'STO Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SWISHIP' => _x( 'Swiship', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SWISS_POST' => _x( 'SWISS POST', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'T_CAT' => _x( 'T-cat', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'T_CAT_API' => _x( 'T-cat', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGINEXT_WEBHOOK' => _x( 'T&W Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TW_TAIWAN_POST' => _x( 'Taiwan Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TAMERGROUP_WEBHOOK' => _x( 'Tamer Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TAQBIN_HK' => _x( 'TAQBIN Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TAQBIN_SG' => _x( 'taqbin_sg', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TCS_API' => _x( 'TCS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TECOR' => _x( 'tecor', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TELEPORT_WEBHOOK' => _x( 'Teleport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SIC_TELIWAY' => _x( 'Teliway SIC Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TESTING_COURIER_WEBHOOK' => _x( 'Testing Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TESTING_COURIER' => _x( 'Testing Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TH_CJ' => _x( 'TH_CJ', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THIJS_NL' => _x( 'Thijs Logistiek', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THUNDEREXPRESS' => _x( 'Thunder Express Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TIPSA_API' => _x( 'Tipsa API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TIPSA_REF' => _x( 'Tipsa Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_FR_REFERENCE' => _x( 'TNT France Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_REFR' => _x( 'TNT Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_AU' => _x( 'tnt_au', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_CN' => _x( 'TNT_CN', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_DE' => _x( 'TNT_DE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_ES' => _x( 'TNT_ES', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_IT' => _x( 'tnt_it', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_JP' => _x( 'TNT_JP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_PL' => _x( 'TNT_PL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOLL_WEBHOOK' => _x( 'Toll Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOLL_IPEC' => _x( 'TOLL IPEC', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOLL_PRIORITY' => _x( 'Toll Priority', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOMYDOOR' => _x( 'Tomydoor', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TONAMI_FTP' => _x( 'Tonami', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESDEX' => _x( 'Top Ideal Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOTAL_EXPRESS_API' => _x( 'Total Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOURLINE_REFERENCE' => _x( 'Tourline Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THAIPARCELS' => _x( 'TP Logistic', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRANS2U' => _x( 'Trans2u', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRANSMISSION' => _x( 'TRANSMISSION', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TANET' => _x( 'Transport Ambientales', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRANSVIRTUAL' => _x( 'TransVirtual', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRUNKRS' => _x( 'Trunkrs', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRUSK' => _x( 'Trusk France', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TUSKLOGISTICS' => _x( 'Tusk Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TYP' => _x( 'TYP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'U_ENVIOS' => _x( 'U-ENVIOS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UBER_WEBHOOK' => _x( 'Uber', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UCS' => _x( 'UCS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UDS' => _x( 'United Delivery Service', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UPS' => _x( 'United Parcel Service', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UP_EXPRESS' => _x( 'up_express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UPARCEL' => _x( 'uParcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UPS_API' => _x( 'UPS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UPS_FREIGHT' => _x( 'UPS Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UPS_REFERENCE' => _x( 'UPS Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'URGENT_CARGUS' => _x( 'Urgent Cargus', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'US_APC' => _x( 'us_apc', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'USPS_API' => _x( 'USPS API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PB_USPSFLATS_FTP' => _x( 'USPS Flats (Pitney Bowes)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'USPS_WEBHOOK' => _x( 'USPS Informed Visibility - Webhook', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VALUE_WEBHOOK' => _x( 'Value Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VIAXPRESS' => _x( 'ViaXpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VNPOST_API' => _x( 'Vietnam Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VIRTRANSPORT_SFTP' => _x( 'Vir Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VNPOST_EMS' => _x( 'vnpost_ems', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VOX' => _x( 'VOX SOLUCION EMPRESARIAL SRL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WATKINS_SHEPARD' => _x( 'watkins_shepard', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WEWORLDEXPRESS' => _x( 'We World Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WESHIP_API' => _x( 'WeShip', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WESHIP' => _x( 'WeShip', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WHISTL_SFTP' => _x( 'Whistl', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WINESHIPPING_WEBHOOK' => _x( 'Wineshipping', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WISH_EMAIL_PUSH' => _x( 'Wish', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WOOYOUNG_LOGISTICS_SFTP' => _x( 'WOO YOUNG LOGISTICS CO., LTD.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WORLDCOURIER' => _x( 'World Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WORLDNET' => _x( 'Worldnet Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WSPEXPRESS' => _x( 'WSP Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XYY' => _x( 'Xingyunyi Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XPEDIGO' => _x( 'Xpedigo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XPRESSBEES' => _x( 'XPRESSBEES', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YAMATO' => _x( 'YAMATO', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TAQBIN_SG_API' => _x( 'Yamato Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YIFAN' => _x( 'YiFan Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YODEL' => _x( 'yodel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YODEL_API' => _x( 'Yodel API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YODEL_DIR' => _x( 'Yodel Direct', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YODEL_INTNL' => _x( 'Yodel International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YUSEN' => _x( 'Yusen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YUSEN_SFTP' => _x( 'Yusen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YYCOM' => _x( 'yycom', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YYEXPRESS' => _x( 'YYEXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZTO_DOMESTIC' => _x( 'ZTO Express China', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZUELLIGPHARMA_SFTP' => _x( 'Zuellig Pharma Korea', 'Name of carrier', 'woocommerce-paypal-payments' ), + '99MINUTOS' => tr( '99minutos', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'A2B_BA' => tr( 'A2B Express Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ABCUSTOM_SFTP' => tr( 'AB Custom Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ACILOGISTIX' => tr( 'ACI Logistix', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ACOMMERCE' => tr( 'ACOMMERCE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ACTIVOS24_API' => tr( 'Activos24', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ADS' => tr( 'ADS Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AEROFLASH' => tr( 'AEROFLASH', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AGEDISS_SFTP' => tr( 'Agediss', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AIR_21' => tr( 'AIR 21', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AIRSPEED' => tr( 'AIRSPEED', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AIRTERRA' => tr( 'Airterra', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AITWORLDWIDE_API' => tr( 'AIT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AITWORLDWIDE_SFTP' => tr( 'AIT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ALLIED_EXPRESS_FTP' => tr( 'Allied Express (FTP)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ALLJOY' => tr( 'ALLJOY SUPPLY CHAIN', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AMAZON_EMAIL_PUSH' => tr( 'Amazon', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AMAZON_ORDER' => tr( 'Amazon order', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AMAZON_UK_API' => tr( 'amazon_uk_api', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AMS_GRP' => tr( 'AMS Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ANDREANI_API' => tr( 'Andreani', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ANTERAJA' => tr( 'Anteraja', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARAMEX' => tr( 'Aramex', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARAMEX_API' => tr( 'Aramex', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARASKARGO' => tr( 'Aras Cargo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARGENTS_WEBHOOK' => tr( 'Argents Express Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ASENDIA_DE' => tr( 'asendia_de', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ATSHEALTHCARE_REFERENCE' => tr( 'ATS Healthcare', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ATSHEALTHCARE' => tr( 'ATS Healthcare', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AUEXPRESS' => tr( 'Au Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AUSTRALIA_POST_API' => tr( 'Australia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AVERITT' => tr( 'Averitt Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AXLEHIRE_FTP' => tr( 'Axlehire', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AXLEHIRE' => tr( 'AxleHire', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BARQEXP' => tr( 'Barq', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BDMNET' => tr( 'BDMnet', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BEL_BELGIUM_POST' => tr( 'bel_belgium_post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BLR_BELPOST' => tr( 'Belpost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BERT' => tr( 'BERT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BESTTRANSPORT_SFTP' => tr( 'Best Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BETTERTRUCKS' => tr( 'Better Trucks', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BIGSMART' => tr( 'Big Smart', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BIOCAIR_FTP' => tr( 'BioCair', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BJSHOMEDELIVERY' => tr( 'BJS Distribution courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BJSHOMEDELIVERY_FTP' => tr( 'BJS Distribution, Storage & Couriers - FTP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BLUEDART' => tr( 'BLUEDART', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BLUEDART_API' => tr( 'Bluedart', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BOLLORE_LOGISTICS' => tr( 'Bollore Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BOMI' => tr( 'Bomi Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BE_BPOST' => tr( 'Bpost (www.bpost.be)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BPOST_API' => tr( 'Bpost API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BPOST_INT' => tr( 'Bpost international', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BRT_IT_API' => tr( 'BRT Bartolini API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BUFFALO' => tr( 'BUFFALO', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BURD' => tr( 'Burd Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHROBINSON' => tr( 'C.H. Robinson Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CAGO' => tr( 'Cago', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CANPAR' => tr( 'CANPAR', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CAPITAL' => tr( 'Capital Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CARRY_FLAP' => tr( 'Carry-Flap Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CBL_LOGISTICA_API' => tr( 'CBL Logistica (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CDLDELIVERS' => tr( 'CDL Last Mile', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CELERITAS' => tr( 'Celeritas Transporte', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CEVA' => tr( 'CEVA LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CEVA_TRACKING' => tr( 'CEVA Package', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHAZKI' => tr( 'Chazki', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHIENVENTURE_WEBHOOK' => tr( 'Chienventure', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHILEXPRESS' => tr( 'Chile Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CITY56_WEBHOOK' => tr( 'City Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJ_GLS' => tr( 'CJ GLS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJ_LOGISTICS' => tr( 'CJ Logistics International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJ_PHILIPPINES' => tr( 'cj_philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CLICKLINK_SFTP' => tr( 'ClickLink', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_LOGISTICS' => tr( 'CN Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COLLECTPLUS' => tr( 'COLLECTPLUS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COM1EXPRESS' => tr( 'ComOne Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CONCISE' => tr( 'Concise', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CONCISE_WEBHOOK' => tr( 'Concise', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CONCISE_API' => tr( 'Concise', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COORDINADORA_API' => tr( 'Coordinadora', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COPA_COURIER' => tr( 'Copa Airlines Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CORREOS_DE_ESPANA' => tr( 'CORREOS DE ESPANA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CORREOSEXPRESS_API' => tr( 'Correos Express (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CORREOS_ES' => tr( 'correos Express (www.correos.es)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COURANT_PLUS_API' => tr( 'Courant Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COURIER_POST' => tr( 'COURIER POST', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COURIERPLUS' => tr( 'COURIERPLUS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CRLEXPRESS' => tr( 'CRL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CROSSFLIGHT' => tr( 'Crossflight Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CRYOPDP_FTP' => tr( 'CryoPDP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CESKAPOSTA_API' => tr( 'Czech Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DEXPRESS_WEBHOOK' => tr( 'D Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DACHSER' => tr( 'DACHSER', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DACHSER_WEB' => tr( 'DACHSER', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DAESHIN' => tr( 'Daeshin', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DAIICHI' => tr( 'Daiichi Freight System Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DANNIAO' => tr( 'Danniao', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DAO365' => tr( 'DAO365', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DAYROSS' => tr( 'Day & Ross', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DYLT' => tr( 'Daylight Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DBSCHENKER_API' => tr( 'DB Schenker', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DBSCHENKER_B2B' => tr( 'DB Schenker B2B', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DBSCHENKER_ICELAND' => tr( 'DB Schenker Iceland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DDEXPRESS' => tr( 'DD Express Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DE_DHL' => tr( 'DE DHL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELCART_IN' => tr( 'delcart_in', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELIVERYOURPARCEL_ZA' => tr( 'Deliver Your Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELIVER_IT' => tr( 'Deliver-iT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELIVERE' => tr( 'delivere', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELIVERR_SFTP' => tr( 'Deliverr', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELTEC_DE' => tr( 'DELTEC DE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DEMANDSHIP' => tr( 'DemandShip', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DEUTSCHE_DE' => tr( 'deutsche_de', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_API' => tr( 'DHL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_REFERENCE_API' => tr( 'DHL (Reference number)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_ACTIVE_TRACING' => tr( 'DHL Active Tracing', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_ECOMMERCE_GC' => tr( 'DHL eCommerce Greater China', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_GLOBAL_MAIL_API' => tr( 'DHL eCommerce Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DE_DHL_EXPRESS' => tr( 'DHL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_SFTP' => tr( 'DHL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_FR' => tr( 'DHL France (www.dhl.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_FREIGHT' => tr( 'DHL Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL' => tr( 'dhl Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_GLOBAL_FORWARDING_API' => tr( 'DHL Global Forwarding API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_GT_API' => tr( 'DHL Global Forwarding Guatemala', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_PA_API' => tr( 'DHL GLOBAL FORWARDING PANAMÁ', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IT_DHL_ECOMMERCE' => tr( 'DHL International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_JP' => tr( 'DHL Japan', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_PARCEL_NL' => tr( 'DHL Parcel NL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_SG' => tr( 'dhl Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_ES_SFTP' => tr( 'DHL Spain Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_SUPPLYCHAIN_IN' => tr( 'DHL supply chain India', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_SUPPLYCHAIN_ID' => tr( 'DHL Supply Chain Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_AT' => tr( 'dhl_at', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_GLOBAL_MAIL' => tr( 'dhl_global_mail', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_IT' => tr( 'dhl_it', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_PIECEID' => tr( 'dhl_pieceid', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_SUPPLY_CHAIN_AU' => tr( 'dhl_supply_chain_au', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHLPARCEL_UK' => tr( 'dhlparcel_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIALOGO_LOGISTICA_API' => tr( 'Dialogo Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIALOGO_LOGISTICA' => tr( 'Dialogo Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIRECTFREIGHT_AU_REF' => tr( 'Direct Freight Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIREX' => tr( 'Direx', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DKSH' => tr( 'DKSH', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DMFGROUP' => tr( 'DMF', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DNJ_EXPRESS' => tr( 'DNJ Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DOTZOT' => tr( 'DOTZOT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD' => tr( 'DPD', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_AT_SFTP' => tr( 'DPD Austria', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_DELISTRACK' => tr( 'DPD delistrack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_NL' => tr( 'DPD Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_RU_API' => tr( 'DPD Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_SK_SFTP' => tr( 'DPD Slovakia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_CH_SFTP' => tr( 'DPD Switzerland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_UK_SFTP' => tr( 'DPD UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_DE' => tr( 'dpd_de', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_FR_REFERENCE' => tr( 'dpd_fr_reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_UK' => tr( 'dpd_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_DPEX' => tr( 'DPEX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPEX' => tr( 'DPEX (www.dpex.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DSV' => tr( 'DSV courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DSV_REFERENCE' => tr( 'DSV Futurewave', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DX' => tr( 'DX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DX_B2B_CONNUM' => tr( 'DX (B2B)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DX_FREIGHT' => tr( 'DX Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DYNALOGIC' => tr( 'Dynamic Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EASTWESTCOURIER_FTP' => tr( 'East West Courier Pte Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EC_CN' => tr( 'EC_CN', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ECARGO' => tr( 'ECARGO', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ECEXPRESS' => tr( 'ECexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ECMS' => tr( 'ECMS International Logistics Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ECOFREIGHT' => tr( 'Eco Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ECOURIER' => tr( 'ecourier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ECOUTIER' => tr( 'eCoutier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EFS' => tr( 'EFS (E-commerce Fulfillment Service)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ELITE_CO' => tr( 'Elite Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ELOGISTICA' => tr( 'elogistica', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ELTA_GR' => tr( 'elta_gr', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARE_EMIRATES_POST' => tr( 'Emirates Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EMS' => tr( 'EMS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EMS_CN' => tr( 'ems_cn', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ENSENDA' => tr( 'ENSENDA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EFWNOW_API' => tr( 'Estes Forwarding Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ETOMARS' => tr( 'Etomars', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ETOTAL' => tr( 'eTotal Solution Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EDF_FTP' => tr( 'Eurodifarm', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EURODIS' => tr( 'eurodis', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EUROPAKET_API' => tr( 'Europacket+', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYHERMES_UK_API' => tr( 'EVRi', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EWE' => tr( 'EWE Global Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EXELOT_FTP' => tr( 'Exelot Ltd.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EXPEDITORS' => tr( 'Expeditors', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EXPEDITORS_API_REF' => tr( 'Expeditors API Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EZSHIP' => tr( 'EZship', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FAIRSENDEN_API' => tr( 'fairsenden', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FXTRAN' => tr( 'Falcon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FAN' => tr( 'FAN COURIER EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FNF_ZA' => tr( 'Fast & Furious', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTDESPATCH' => tr( 'Fast Despatch Logistics Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTBOX' => tr( 'Fastbox', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTSHIP' => tr( 'Fastship Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTTRACK' => tr( 'fasttrack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTWAY_AU' => tr( 'fastway_au', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTWAY_UK' => tr( 'FASTWAY_UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTWAY_US' => tr( 'FASTWAY_US', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTWAY_ZA' => tr( 'fastway_za', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FAXECARGO' => tr( 'Faxe Cargo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FEDEX_FR' => tr( 'FedEx® Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FEDEX_API' => tr( 'FedEx®', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FERCAM_IT' => tr( 'fercam_it', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FETCHR' => tr( 'Fetchr', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FIRST_LOGISTICS_API' => tr( 'First Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FIRST_LOGISITCS' => tr( 'first_logisitcs', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FITZMARK_API' => tr( 'FitzMark', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FLASHEXPRESS_WEBHOOK' => tr( 'Flash Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FLIGHTLG' => tr( 'Flight Logistics Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FLIPXP' => tr( 'FlipXpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FLYTEXPRESS' => tr( 'FLYTEXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FORWARDAIR' => tr( 'Forward Air', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FOUR_PX_EXPRESS' => tr( 'FOUR PX EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FR_COLISSIMO' => tr( 'fr_colissimo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FR_MONDIAL' => tr( 'fr_mondial', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FRAGILEPAK_SFTP' => tr( 'FragilePAK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FRONTDOORCORP' => tr( 'FRONTdoor Collective', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FUJEXP' => tr( 'FUJIE EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GWLOGIS_API' => tr( 'G.I.G', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GAC' => tr( 'GAC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GATI_KWE_API' => tr( 'Gati-KWE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GDPHARM' => tr( 'GDPharm Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GW_WORLD' => tr( 'Gebrüder Weiss', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GEODIS' => tr( 'GEODIS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GEODIS_API' => tr( 'GEODIS - Distribution & Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GPOST' => tr( 'Georgian Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GIAO_HANG' => tr( 'Giao hàng nhanh', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GIO_ECOURIER_API' => tr( 'GIO Express Ecourier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GIO_ECOURIER' => tr( 'GIO Express Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GOGLOBALPOST' => tr( 'Global Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOBEGISTICS' => tr( 'GLOBEGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOVO' => tr( 'Glovo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS' => tr( 'GLS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_SPAIN_API' => tr( 'GLS Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_DE' => tr( 'GLS_DE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_ES' => tr( 'GLS_ES', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_FR' => tr( 'GLS_FR', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_ITALY_FTP' => tr( 'gls_italy_ftp', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_SPAIN' => tr( 'gls_spain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GOLS' => tr( 'GO Logistics & Storage', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GOPEOPLE' => tr( 'Go People', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GORUSH' => tr( 'Go Rush', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GOJEK' => tr( 'Gojek', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GREYHOUND' => tr( 'GREYHOUND', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAZET' => tr( 'Groupe Mazet', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HANJIN' => tr( 'HanJin', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HELLENIC_POST' => tr( 'Hellenic (Greece) Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HELLMANN' => tr( 'Hellmann Worldwide Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HELTHJEM_API' => tr( 'Helthjem', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HERMES_DE_FTP' => tr( 'Hermes Germany', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HERMES_UK_SFTP' => tr( 'Hermes UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HERMESWORLD_UK' => tr( 'hermesworld_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HEROEXPRESS' => tr( 'Hero Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HFD' => tr( 'HFD', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HK_RPX' => tr( 'hk_rpx', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HOMELOGISTICS' => tr( 'Home Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HOMERUNNER' => tr( 'HomeRunner', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HERMES_IT' => tr( 'HR Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HSDEXPRESS' => tr( 'HSDEXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HSM_GLOBAL' => tr( 'HSM Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HUANTONG' => tr( 'HuanTong', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HUBBED' => tr( 'HUBBED', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HUNTER_EXPRESS_SFTP' => tr( 'Hunter Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IBVENTURE_WEBHOOK' => tr( 'IB Venture', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTUR_IS' => tr( 'Iceland Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ICSCOURIER' => tr( 'ICS COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IDEXPRESS_ID' => tr( 'iDexpress Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IDN_POS' => tr( 'idn_pos', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IDS_LOGISTICS' => tr( 'ids_logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ILYANGLOGIS' => tr( 'Ilyang logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IMEXGLOBALSOLUTIONS' => tr( 'imexglobalsolutions', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IMILE_API' => tr( 'iMile', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IML' => tr( 'IML courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IMX' => tr( 'IMX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INDIA_POST' => tr( 'India Post Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INDIA_POST_INT' => tr( 'India Post International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INEXPOST' => tr( 'Inexpost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INNTRALOG_SFTP' => tr( 'Inntralog GmbH', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INPOST_UK' => tr( 'InPost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INSTABOX_WEBHOOK' => tr( 'Instabox', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTERNATIONAL_SEUR_API' => tr( 'International Seur API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTERSMARTTRANS' => tr( 'INTERSMARTTRANS & SOLUTIONS SL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTEX_DE' => tr( 'INTEX Paketdienst GmbH', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTIME_FTP' => tr( 'InTime', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ITHINKLOGISTICS' => tr( 'iThink Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JTCARGO' => tr( 'J&T CARGO', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JTEXPRESS_PH' => tr( 'J&T Express Philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JTEXPRESS_SG_API' => tr( 'J&T Express Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JT_LOGISTICS' => tr( 'J&T International logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JAVIT' => tr( 'Javit', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_JCEX' => tr( 'JCEX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JD_EXPRESS' => tr( 'JD Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JD_WORLDWIDE' => tr( 'JD Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JETSHIP_MY' => tr( 'jetship_my', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JNE_API' => tr( 'JNE (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IDN_JNE' => tr( 'JNE Express (Jalur Nugraha Ekakurir)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JOYINGBOX' => tr( 'joyingbox', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KARGOMKOLAY' => tr( 'KargomKolay (CargoMini)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KEDAEX' => tr( 'KedaEX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HK_TGX' => tr( 'Kerry Express Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KERRY_EXPRESS_TW_API' => tr( 'Kerry Express TaiWan', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THA_KERRY' => tr( 'Kerry Express Thailand', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KERRY_EXPRESS_TH_WEBHOOK' => tr( 'Kerry Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KNG' => tr( 'Keuhne + Nagel Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BE_KIALA' => tr( 'Kiala', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGISYSTEMS_SFTP' => tr( 'Kiitääjät', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KOMON_EXPRESS' => tr( 'Komon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KRONOS_WEBHOOK' => tr( 'Kronos Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KRONOS' => tr( 'Kronos Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KUEHNE' => tr( 'Kuehne + Nagel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LALAMOVE_API' => tr( 'Lalamove', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LBCEXPRESS_FTP' => tr( 'LBC EXPRESS INC.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LBCEXPRESS_API' => tr( 'LBC EXPRESS INC.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LCTBR_API' => tr( 'LCT do Brasil', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LTU_LIETUVOS' => tr( 'Lietuvos pastas', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LINKBRIDGE' => tr( 'Link Bridge(BeiJing)international logistics co.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LION_PARCEL' => tr( 'LION PARCEL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LIVRAPIDE' => tr( 'Livrapide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGGI' => tr( 'Loggi', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGISTICSWORLDWIDE_KR' => tr( 'LOGISTICSWORLDWIDE KR', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGISTICSWORLDWIDE_MY' => tr( 'LOGISTICSWORLDWIDE MY', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGWIN_LOGISTICS' => tr( 'Logwin Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGYSTO' => tr( 'Logysto', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LUWJISTIK' => tr( 'Luwjistik', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MX_CARGO' => tr( 'M&X cargo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'M3LOGISTICS' => tr( 'M3 Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'REIMAGINEDELIVERY' => tr( 'maergo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAGYAR_POSTA_API' => tr( 'Magyar Posta', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAIL_BOX_ETC' => tr( 'Mail Boxes Etc.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYS_EMS' => tr( 'Malaysia Post EMS / Pos Laju', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MALCA_AMIT_API' => tr( 'Malca Amit', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MALCA_AMIT' => tr( 'Malca-Amit', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MARKEN' => tr( 'Marken', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MEDAFRICA' => tr( 'Med Africa Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MEEST' => tr( 'Meest', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MEGASAVE' => tr( 'megasave', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MENSAJEROSURBANOS_API' => tr( 'Mensajeros Urbanos', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MWD' => tr( 'Metropolitan Warehouse & Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MWD_API' => tr( 'Metropolitan Warehouse & Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MHI' => tr( 'Mhi', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MIKROPAKKET' => tr( 'Mikropakket', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MISUMI_CN' => tr( 'MISUMI Group Inc.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MNX' => tr( 'MNX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MOBI_BR' => tr( 'Mobi Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MONDIALRELAY_FR' => tr( 'Mondial Relay France', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MONDIALRELAY_ES' => tr( 'Mondial Relay Spain(Punto Pack)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MONDIAL_BE' => tr( 'MONDIAL_BE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MOOVA' => tr( 'Moova', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MORNINGLOBAL' => tr( 'Morning Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MOTHERSHIP_API' => tr( 'Mothership', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MOVIANTO' => tr( 'Movianto', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MUDITA' => tr( 'MUDITA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYDYNALOGIC' => tr( 'My DynaLogic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYSENDLE_API' => tr( 'mySendle', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NMTRANSFER' => tr( 'N&M Transfer Co., Inc.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NACEX_SPAIN_REFERENCE' => tr( 'nacex_spain_reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NAEKO_FTP' => tr( 'Naeko Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NAQEL_EXPRESS' => tr( 'Naqel Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NEWZEALAND_COURIERS' => tr( 'NEW ZEALAND COURIERS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NEWGISTICS' => tr( 'Newgistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NEWGISTICSAPI' => tr( 'Newgistics API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NIGHTLINE_UK' => tr( 'nightline_uk', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NIMBUSPOST' => tr( 'NimbusPost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NIPPON_EXPRESS_FTP' => tr( 'Nippon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NIPPON_EXPRESS' => tr( 'Nippon Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NORTHLINE' => tr( 'Northline', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NOVA_POSHTA_API' => tr( 'Nova Poshta API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NOVOFARMA_WEBHOOK' => tr( 'Novofarma', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NTL' => tr( 'NTL logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NYTLOGISTICS' => tr( 'NYT SUPPLY CHAIN LOGISTICS Co., LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OHI_WEBHOOK' => tr( 'Ohi', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHOPOLIVE' => tr( 'Olive', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OMLOGISTICS_API' => tr( 'OM LOGISTICS LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OMNIRPS_WEBHOOK' => tr( 'Omni Returns', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ONTRAC' => tr( 'ONTRAC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ORANGECONNEX' => tr( 'orangeconnex', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ORANGE_DS' => tr( 'OrangeDS (Orange Distribution Solutions Inc)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OSM_WORLDWIDE_SFTP' => tr( 'OSM Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OZEPARTS_SHIPPING' => tr( 'Ozeparts Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'P2P_TRC' => tr( 'P2P TrakPak', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PACKETA' => tr( 'Packeta', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PACKFLEET' => tr( 'PACKFLEET', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PACKS' => tr( 'Packs', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAKAJO' => tr( 'Pakajo World', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PANDAGO_API' => tr( 'Pandago', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PANDION' => tr( 'Pandion', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PANDU' => tr( 'PANDU', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PANTHER_REFERENCE_API' => tr( 'Panther Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PANTHER_ORDER_NUMBER' => tr( 'panther_order_number', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAPA_WEBHOOK' => tr( 'Papa', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELRIGHT' => tr( 'Parcel Right', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCEL_2_POST' => tr( 'Parcel To Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELFORCE' => tr( 'PARCELFORCE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELSTARS_WEBHOOK' => tr( 'Parcelstars', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCLL' => tr( 'PARCLL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PASSPORTSHIPPING' => tr( 'Passport Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PATHEON' => tr( 'Patheon Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAYO' => tr( 'Payo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PCHOME_API' => tr( 'Pchome Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PGEON_API' => tr( 'Pgeon', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PHSE_API' => tr( 'PHSE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PICKUPP_VNM' => tr( 'pickupp_vnm', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PIDGE' => tr( 'Pidge', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PIL_LOGISTICS' => tr( 'PIL Logistics (China) Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PLYCONGROUP' => tr( 'Plycon Transportation Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POLARSPEED' => tr( 'PolarSpeed Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTONE' => tr( 'Post ONE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTAPLUS' => tr( 'Posta Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTE_ITALIANE_PACCOCELERE' => tr( 'Poste Italiane Paccocelere', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTEN_NORGE' => tr( 'Posten Norge (www.posten.no)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTI_API' => tr( 'Posti API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTNL_INT_3_S' => tr( 'PostNL International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NLD_POSTNL' => tr( 'PostNL International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTNL_INTERNATIONAL' => tr( 'PostNL International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SWE_POSTNORD' => tr( 'Postnord sweden', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTPLUS' => tr( 'PostPlus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PROCARRIER' => tr( 'Pro Carrier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRODUCTCAREGROUP_SFTP' => tr( 'Product Care Services Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PROFESSIONAL_COURIERS' => tr( 'PROFESSIONAL COURIERS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PPL' => tr( 'Professional Parcel Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PROMEDDELIVERY' => tr( 'ProMed Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PUROLATOR' => tr( 'purolator', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PUROLATOR_INTERNATIONAL' => tr( 'Purolator International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'QTRACK' => tr( 'QTrack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'QUALITYPOST' => tr( 'qualitypost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'QINTL_API' => tr( 'Quickstat Courier LLC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'QUIQUP' => tr( 'Quiqup', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RANSA_WEBHOOK' => tr( 'Ransa', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'REDJEPAKKETJE' => tr( 'Red je Pakketje', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RELAISCOLIS' => tr( 'Relais Colis', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RHENUS_GROUP' => tr( 'Rhenus Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RHENUS_UK_API' => tr( 'Rhenus Logistics UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AIR_CANADA' => tr( 'Rivo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RIXONHK_API' => tr( 'Rixon Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROCHE_INTERNAL_SFTP' => tr( 'Roche Internal Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROYAL_MAIL_FTP' => tr( 'Royal Mail', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROYALSHIPMENTS' => tr( 'royalshipments', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RRDONNELLEY' => tr( 'rrdonnelley', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RUSSIAN_POST' => tr( 'Russian post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SAEE' => tr( 'saee', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SAGAWA' => tr( 'SAGAWA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SAGAWA_API' => tr( 'Sagawa', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SBERLOGISTICS_RU' => tr( 'Sber Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SECRETLAB_WEBHOOK' => tr( 'Secretlab', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SEINO_API' => tr( 'Seino', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SEKO_SFTP' => tr( 'SEKO Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SENDING' => tr( 'Sending Transporte Urgente y Comunicacion', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHOWL' => tr( 'SENHONG INTERNATIONAL LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NOWLOG_API' => tr( 'Sequoialog', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SERVIENTREGA' => tr( 'Servientrega', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SERVIP_WEBHOOK' => tr( 'SerVIP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SETEL' => tr( 'Setel Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SF_EX' => tr( 'SF Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SF_EXPRESS_CN' => tr( 'SF Express China', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SGT_IT' => tr( 'SGT_IT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHADOWFAX' => tr( 'Shadowfax', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHENZHEN' => tr( 'shenzhen 1st International Logistics(Group)Co', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HOTSIN_CARGO' => tr( 'SHENZHEN HOTSIN CARGO INTL FORWARDING CO., LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KWT' => tr( 'Shenzhen Jinghuada Logistics Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHERPA' => tr( 'Sherpa', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPA' => tr( 'SHIPA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPPIE' => tr( 'Shippie', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPPIFY' => tr( 'Shippify, Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPROCKET' => tr( 'Shiprocket X', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPX' => tr( 'ShipX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPXPRES' => tr( 'SHIPXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPX' => tr( 'Shopee Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPX_TH' => tr( 'Shopee Xpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHUNBANG_EXPRESS' => tr( 'ShunBang Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHYPLITE' => tr( 'Shypmax', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SIMPLETIRE_WEBHOOK' => tr( 'SimpleTire', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SIMSGLOBAL' => tr( 'Sims Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SIODEMKA' => tr( 'SIODEMKA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SKynet_WORLDWIDE' => tr( 'SkyNet Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SKY_POSTAL' => tr( 'SkyPostal', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SK_POSTA' => tr( 'Slovenska pošta', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SMARTCAT' => tr( 'SMARTCAT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SMARTKARGO' => tr( 'SmartKargo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SMG_EXPRESS' => tr( 'SMG Direct', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SMSA_EXPRESS_WEBHOOK' => tr( 'SMSA Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SNTGLOBAL_API' => tr( 'Snt Global Etrax', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SOLISTICA_API' => tr( 'solistica', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPANISH_SEUR_FTP' => tr( 'Spanish Seur', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPECTRAN' => tr( 'Spectran', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPEEDEX' => tr( 'speedex', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPEEDY' => tr( 'Speedy', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPREETAIL_API' => tr( 'Spreetail', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPRINT_PACK' => tr( 'SPRINT PACK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SRT_TRANSPORT' => tr( 'SRT Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STAR_TRACK_NEXT_FLIGHT' => tr( 'Star Track Next Flight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STARLINKS_API' => tr( 'Starlinks Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STARTRACK' => tr( 'startrack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STAR_TRACK_WEBHOOK' => tr( 'StarTrack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STARTRACK_EXPRESS' => tr( 'startrack_express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STATOVERNIGHT' => tr( 'Stat Overnight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_STO' => tr( 'STO Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SWISHIP' => tr( 'Swiship', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SWISS_POST' => tr( 'SWISS POST', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'T_CAT' => tr( 'T-cat', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'T_CAT_API' => tr( 'T-cat', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGINEXT_WEBHOOK' => tr( 'T&W Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TW_TAIWAN_POST' => tr( 'Taiwan Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TAMERGROUP_WEBHOOK' => tr( 'Tamer Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TAQBIN_HK' => tr( 'TAQBIN Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TAQBIN_SG' => tr( 'taqbin_sg', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TCS_API' => tr( 'TCS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TECOR' => tr( 'tecor', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TELEPORT_WEBHOOK' => tr( 'Teleport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SIC_TELIWAY' => tr( 'Teliway SIC Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TESTING_COURIER_WEBHOOK' => tr( 'Testing Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TESTING_COURIER' => tr( 'Testing Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TH_CJ' => tr( 'TH_CJ', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THIJS_NL' => tr( 'Thijs Logistiek', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THUNDEREXPRESS' => tr( 'Thunder Express Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TIPSA_API' => tr( 'Tipsa API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TIPSA_REF' => tr( 'Tipsa Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_FR_REFERENCE' => tr( 'TNT France Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_REFR' => tr( 'TNT Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_AU' => tr( 'tnt_au', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_CN' => tr( 'TNT_CN', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_DE' => tr( 'TNT_DE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_ES' => tr( 'TNT_ES', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_IT' => tr( 'tnt_it', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_JP' => tr( 'TNT_JP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_PL' => tr( 'TNT_PL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOLL_WEBHOOK' => tr( 'Toll Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOLL_IPEC' => tr( 'TOLL IPEC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOLL_PRIORITY' => tr( 'Toll Priority', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOMYDOOR' => tr( 'Tomydoor', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TONAMI_FTP' => tr( 'Tonami', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESDEX' => tr( 'Top Ideal Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOTAL_EXPRESS_API' => tr( 'Total Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOURLINE_REFERENCE' => tr( 'Tourline Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THAIPARCELS' => tr( 'TP Logistic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRANS2U' => tr( 'Trans2u', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRANSMISSION' => tr( 'TRANSMISSION', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TANET' => tr( 'Transport Ambientales', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRANSVIRTUAL' => tr( 'TransVirtual', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRUNKRS' => tr( 'Trunkrs', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRUSK' => tr( 'Trusk France', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TUSKLOGISTICS' => tr( 'Tusk Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TYP' => tr( 'TYP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'U_ENVIOS' => tr( 'U-ENVIOS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UBER_WEBHOOK' => tr( 'Uber', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UCS' => tr( 'UCS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UDS' => tr( 'United Delivery Service', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UPS' => tr( 'United Parcel Service', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UP_EXPRESS' => tr( 'up_express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UPARCEL' => tr( 'uParcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UPS_API' => tr( 'UPS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UPS_FREIGHT' => tr( 'UPS Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UPS_REFERENCE' => tr( 'UPS Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'URGENT_CARGUS' => tr( 'Urgent Cargus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'US_APC' => tr( 'us_apc', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'USPS_API' => tr( 'USPS API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PB_USPSFLATS_FTP' => tr( 'USPS Flats (Pitney Bowes)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'USPS_WEBHOOK' => tr( 'USPS Informed Visibility - Webhook', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VALUE_WEBHOOK' => tr( 'Value Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VIAXPRESS' => tr( 'ViaXpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VNPOST_API' => tr( 'Vietnam Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VIRTRANSPORT_SFTP' => tr( 'Vir Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VNPOST_EMS' => tr( 'vnpost_ems', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VOX' => tr( 'VOX SOLUCION EMPRESARIAL SRL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WATKINS_SHEPARD' => tr( 'watkins_shepard', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WEWORLDEXPRESS' => tr( 'We World Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WESHIP_API' => tr( 'WeShip', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WESHIP' => tr( 'WeShip', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WHISTL_SFTP' => tr( 'Whistl', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WINESHIPPING_WEBHOOK' => tr( 'Wineshipping', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WISH_EMAIL_PUSH' => tr( 'Wish', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WOOYOUNG_LOGISTICS_SFTP' => tr( 'WOO YOUNG LOGISTICS CO., LTD.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WORLDCOURIER' => tr( 'World Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WORLDNET' => tr( 'Worldnet Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WSPEXPRESS' => tr( 'WSP Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XYY' => tr( 'Xingyunyi Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XPEDIGO' => tr( 'Xpedigo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XPRESSBEES' => tr( 'XPRESSBEES', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YAMATO' => tr( 'YAMATO', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TAQBIN_SG_API' => tr( 'Yamato Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YIFAN' => tr( 'YiFan Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YODEL' => tr( 'yodel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YODEL_API' => tr( 'Yodel API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YODEL_DIR' => tr( 'Yodel Direct', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YODEL_INTNL' => tr( 'Yodel International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YUSEN' => tr( 'Yusen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YUSEN_SFTP' => tr( 'Yusen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YYCOM' => tr( 'yycom', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YYEXPRESS' => tr( 'YYEXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZTO_DOMESTIC' => tr( 'ZTO Express China', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZUELLIGPHARMA_SFTP' => tr( 'Zuellig Pharma Korea', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'AG' => array( - 'name' => _x( 'Argentina', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Argentina', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'FASTRACK' => _x( 'Fasttrack', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ANDREANI' => _x( 'Grupo logistico Andreani', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARG_OCA' => _x( 'OCA Argentina', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTRACK' => tr( 'Fasttrack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ANDREANI' => tr( 'Grupo logistico Andreani', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARG_OCA' => tr( 'OCA Argentina', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'AU' => array( - 'name' => _x( 'Australia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Australia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ADSONE' => _x( 'Adsone', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ALLIEDEXPRESS' => _x( 'Allied Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARAMEX_AU' => _x( 'Aramex Australia (formerly Fastway AU)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AU_AU_POST' => _x( 'Australia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BLUESTAR' => _x( 'Blue Star', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BONDSCOURIERS' => _x( 'Bonds Courier Service (bondscouriers.com.au)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BORDEREXPRESS' => _x( 'Border Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COPE' => _x( 'Cope Sensitive Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COURIERS_PLEASE' => _x( 'CouriersPlease (couriersplease.com.au)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELIVERE' => _x( 'deliverE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DESIGNERTRANSPORT_WEBHOOK' => _x( 'Designer Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_AU' => _x( 'DHL Supply Chain Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIRECTCOURIERS' => _x( 'Direct Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DTDC_AU' => _x( 'DTDC Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ENDEAVOUR_DELIVERY' => _x( 'Endeavour Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HUNTER_EXPRESS' => _x( 'Hunter Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ICUMULUS' => _x( 'iCumulus', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTERPARCEL_AU' => _x( 'Interparcel Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NEWAY' => _x( 'Neway Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELPOINT' => _x( 'Parcelpoint', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PFLOGISTICS' => _x( 'PFL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SENDLE' => _x( 'Sendle', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPPIT' => _x( 'Shippit', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THENILE_WEBHOOK' => _x( 'SortHub courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STAR_TRACK_EXPRESS' => _x( 'Star Track Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AUS_STARTRACK' => _x( 'StarTrack (startrack.com.au)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TFM' => _x( 'TFM Xpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TIGFREIGHT' => _x( 'TIG Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOLL' => _x( 'Toll IPEC', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UBI_LOGISTICS' => _x( 'UBI Smart Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XL_EXPRESS' => _x( 'XL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ADSONE' => tr( 'Adsone', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ALLIEDEXPRESS' => tr( 'Allied Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARAMEX_AU' => tr( 'Aramex Australia (formerly Fastway AU)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AU_AU_POST' => tr( 'Australia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BLUESTAR' => tr( 'Blue Star', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BONDSCOURIERS' => tr( 'Bonds Courier Service (bondscouriers.com.au)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BORDEREXPRESS' => tr( 'Border Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COPE' => tr( 'Cope Sensitive Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COURIERS_PLEASE' => tr( 'CouriersPlease (couriersplease.com.au)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELIVERE' => tr( 'deliverE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DESIGNERTRANSPORT_WEBHOOK' => tr( 'Designer Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_AU' => tr( 'DHL Supply Chain Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIRECTCOURIERS' => tr( 'Direct Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DTDC_AU' => tr( 'DTDC Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ENDEAVOUR_DELIVERY' => tr( 'Endeavour Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HUNTER_EXPRESS' => tr( 'Hunter Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ICUMULUS' => tr( 'iCumulus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTERPARCEL_AU' => tr( 'Interparcel Australia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NEWAY' => tr( 'Neway Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELPOINT' => tr( 'Parcelpoint', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PFLOGISTICS' => tr( 'PFL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SENDLE' => tr( 'Sendle', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPPIT' => tr( 'Shippit', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THENILE_WEBHOOK' => tr( 'SortHub courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STAR_TRACK_EXPRESS' => tr( 'Star Track Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AUS_STARTRACK' => tr( 'StarTrack (startrack.com.au)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TFM' => tr( 'TFM Xpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TIGFREIGHT' => tr( 'TIG Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOLL' => tr( 'Toll IPEC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UBI_LOGISTICS' => tr( 'UBI Smart Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XL_EXPRESS' => tr( 'XL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'AT' => array( - 'name' => _x( 'Austria', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Austria', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'AUSTRIAN_POST_EXPRESS' => _x( 'Austrian Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AU_AUSTRIAN_POST' => _x( 'Austrian Post (Registered)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AUSTRIAN_POST_EXPRESS' => tr( 'Austrian Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AU_AUSTRIAN_POST' => tr( 'Austrian Post (Registered)', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'BGD' => array( - 'name' => _x( 'Bangladesh', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Bangladesh', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'PAPERFLY' => _x( 'Paperfly Private Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAPERFLY' => tr( 'Paperfly Private Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'BE' => array( - 'name' => _x( 'Belgium', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Belgium', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'B_TWO_C_EUROPE' => _x( 'B2C courier Europe', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_BENELUX' => _x( 'dhl benelux', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BEL_DHL' => _x( 'DHL Benelux', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LANDMARK_GLOBAL' => _x( 'Landmark Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LANDMARK_GLOBAL_REFERENCE' => _x( 'Landmark Global Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MIKROPAKKET_BE' => _x( 'Mikropakket Belgium', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'B_TWO_C_EUROPE' => tr( 'B2C courier Europe', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_BENELUX' => tr( 'dhl benelux', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BEL_DHL' => tr( 'DHL Benelux', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LANDMARK_GLOBAL' => tr( 'Landmark Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LANDMARK_GLOBAL_REFERENCE' => tr( 'Landmark Global Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MIKROPAKKET_BE' => tr( 'Mikropakket Belgium', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'BIH' => array( - 'name' => _x( 'Bosnia and Herzegovina', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Bosnia and Herzegovina', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BH_POSTA' => _x( 'BH Posta (www.posta.ba)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BH_POSTA' => tr( 'BH Posta (www.posta.ba)', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'BR' => array( - 'name' => _x( 'Brazil', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Brazil', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BRA_CORREIOS' => _x( 'Correios Brazil', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIRECTLOG' => _x( 'Directlog', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FRETERAPIDO' => _x( 'Frete Rapido', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTELIPOST' => _x( 'Intelipost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOTAL_EXPRESS' => _x( 'Total Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BRA_CORREIOS' => tr( 'Correios Brazil', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIRECTLOG' => tr( 'Directlog', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FRETERAPIDO' => tr( 'Frete Rapido', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTELIPOST' => tr( 'Intelipost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOTAL_EXPRESS' => tr( 'Total Express', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'BG' => array( - 'name' => _x( 'Bulgaria', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Bulgaria', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'A1POST' => _x( 'A1Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BG_BULGARIAN_POST' => _x( 'Bulgarian Posts', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'A1POST' => tr( 'A1Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BG_BULGARIAN_POST' => tr( 'Bulgarian Posts', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'KHM' => array( - 'name' => _x( 'Cambodia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Cambodia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'AFLLOG_FTP' => _x( 'AFL LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KHM_CAMBODIA_POST' => _x( 'Cambodia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROADRUNNER_FREIGHT' => _x( 'Roadbull Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AFLLOG_FTP' => tr( 'AFL LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KHM_CAMBODIA_POST' => tr( 'Cambodia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROADRUNNER_FREIGHT' => tr( 'Roadbull Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'CA' => array( - 'name' => _x( 'Canada', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Canada', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CA_CANADA_POST' => _x( 'Canada Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CHITCHATS' => _x( 'Chit Chats', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CORPORATECOURIERS_WEBHOOK' => _x( 'Corporate Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COURANT_PLUS' => _x( 'Courant Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOBAL_ESTES' => _x( 'Estes Express Lines', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DICOM' => _x( 'GLS Logistic Systems Canada Ltd./Dicom', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOCUS_WEBHOOK' => _x( 'Locus courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOOMIS_EXPRESS' => _x( 'Loomis Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MBW' => _x( 'MBW Courier Inc.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NATIONEX' => _x( 'Nationex courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELPAL_WEBHOOK' => _x( 'ParcelPal', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AIR_CANADA_GLOBAL' => _x( 'Rivo (Air canada)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROUTIFIC_WEBHOOK' => _x( 'Routific', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RPXLOGISTICS' => _x( 'RPX Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STALLIONEXPRESS' => _x( 'Stallion Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZIINGFINALMILE' => _x( 'Ziing Final Mile Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CA_CANADA_POST' => tr( 'Canada Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHITCHATS' => tr( 'Chit Chats', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CORPORATECOURIERS_WEBHOOK' => tr( 'Corporate Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COURANT_PLUS' => tr( 'Courant Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOBAL_ESTES' => tr( 'Estes Express Lines', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DICOM' => tr( 'GLS Logistic Systems Canada Ltd./Dicom', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOCUS_WEBHOOK' => tr( 'Locus courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOOMIS_EXPRESS' => tr( 'Loomis Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MBW' => tr( 'MBW Courier Inc.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NATIONEX' => tr( 'Nationex courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELPAL_WEBHOOK' => tr( 'ParcelPal', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AIR_CANADA_GLOBAL' => tr( 'Rivo (Air canada)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROUTIFIC_WEBHOOK' => tr( 'Routific', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RPXLOGISTICS' => tr( 'RPX Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STALLIONEXPRESS' => tr( 'Stallion Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZIINGFINALMILE' => tr( 'Ziing Final Mile Inc', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'CL' => array( - 'name' => _x( 'Chile', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Chile', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BLUEX' => _x( 'Blue Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STARKEN' => _x( 'STARKEN couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BLUEX' => tr( 'Blue Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STARKEN' => tr( 'STARKEN couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'CN' => array( - 'name' => _x( 'China', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'China', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CN_17POST' => _x( '17 Post Service', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ACSWORLDWIDE' => _x( 'ACS Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CAINIAO' => _x( 'AliExpress Standard Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ANJUN' => _x( 'Anjun couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ANSERX' => _x( 'ANSERX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AUPOST_CN' => _x( 'AuPost China', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BEL_RS' => _x( 'BEL North Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_BESTEXPRESS' => _x( 'Best Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_BOXC' => _x( 'BoxC courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BUYLOGIC' => _x( 'buylogic', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CPEX' => _x( 'Captain Express International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CGS_EXPRESS' => _x( 'CGS Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_CHINA_POST_EMS' => _x( 'China Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CHUKOU1' => _x( 'Chukou1', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJPACKET' => _x( 'CJ Packet', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CLEVY_LINKS' => _x( 'Clevy Links', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CNDEXPRESS' => _x( 'CND Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CNEXPS' => _x( 'CNE Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COMET_TECH' => _x( 'CometTech', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CPACKET' => _x( 'Cpacket couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CUCKOOEXPRESS' => _x( 'Cuckoo Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DEX_I' => _x( 'DEX-I courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIDADI' => _x( 'DIDADI Logistics tech', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPE_EXPRESS' => _x( 'DPE Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DTD_EXPR' => _x( 'DTD Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EMPS_CN' => _x( 'EMPS Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_EQUICK' => _x( 'Equick China', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESHIPPING' => _x( 'Eshipping', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZES_EXPRESS' => _x( 'Eshun international Logistic', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FAR_INTERNATIONAL' => _x( 'Far international', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FARGOOD' => _x( 'FarGood', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FULFILLME' => _x( 'Fulfillme', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GANGBAO' => _x( 'GANGBAO Supplychain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GESWL' => _x( 'GESWL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_GOFLY' => _x( 'GoFly', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HDB' => _x( 'Haidaibao', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HDB_BOX' => _x( 'Haidaibao (BOX)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HH_EXP' => _x( 'Hua Han Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HUAHAN_EXPRESS' => _x( 'HUAHANG EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HUODULL' => _x( 'Huodull', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HX_EXPRESS' => _x( 'HX Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IDEXPRESS' => _x( 'IDEX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTEL_VALLEY' => _x( 'Intel-Valley Supply chain (ShenZhen) Co. Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'J_NET' => _x( 'J-Net', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JINDOUYUN' => _x( 'jindouyun courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JOOM_LOGIS' => _x( 'Joom Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JOYING_BOX' => _x( 'Joying Box', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'K1_EXPRESS' => _x( 'K1 Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KY_EXPRESS' => _x( 'Kua Yue Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LALAMOVE' => _x( 'Lalamove', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LEADER' => _x( 'leader', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SDH_SCM' => _x( 'lightning monkey', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGISTERS' => _x( 'Logisters', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LTIANEXP' => _x( 'LTIAN EXP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LTL' => _x( 'LTL COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MORE_LINK' => _x( 'Morelink', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MXE' => _x( 'MXE Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NANJINGWOYUAN' => _x( 'Nanjing Woyuan', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ONEWORLDEXPRESS' => _x( 'One World Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PADTF' => _x( 'padtf.com', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAGO' => _x( 'Pago Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAN_ASIA' => _x( 'Pan-Asia International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_PAYPAL_PACKAGE' => _x( 'PayPal Package', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PFCEXPRESS' => _x( 'PFC Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_POST56' => _x( 'Post56', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HKD' => _x( 'Qingdao HKD International Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ETS_EXPRESS' => _x( 'RETS express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RUSTON' => _x( 'Ruston', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_SF_EXPRESS' => _x( 'SF Express (www.sf-express.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SFB2C' => _x( 'SF International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SFC_LOGISTICS' => _x( 'SFC', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SFCSERVICE' => _x( 'SFC Service', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DAJIN' => _x( 'Shanghai Aqrum Chemical Logistics Co.Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SINOTRANS' => _x( 'Sinotrans', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STONE3PL' => _x( 'STONE3PL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SYPOST' => _x( 'Sunyou Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TARRIVE' => _x( 'TONDA GLOBAL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOPHATTEREXPRESS' => _x( 'Tophatter Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOPYOU' => _x( 'TopYou', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UC_EXPRE' => _x( 'ucexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VIWO' => _x( 'VIWO IoT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WANBEXPRESS' => _x( 'WanbExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WEASHIP' => _x( 'Weaship', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_WEDO' => _x( 'WeDo Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WINIT' => _x( 'WinIt', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WISE_EXPRESS' => _x( 'Wise Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_WISHPOST' => _x( 'WishPost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XQ_EXPRESS' => _x( 'XQ Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YANWEN' => _x( 'Yanwen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YDH_EXPRESS' => _x( 'YDH express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ELIAN_POST' => _x( 'Yilian (Elian) Supply Chain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YINGNUO_LOGISTICS' => _x( 'yingnuo logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YTO' => _x( 'YTO Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CN_YUNDA' => _x( 'Yunda Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YUNEXPRESS' => _x( 'YunExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZJS_EXPRESS' => _x( 'ZJS International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZTO_EXPRESS' => _x( 'ZTO Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_17POST' => tr( '17 Post Service', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ACSWORLDWIDE' => tr( 'ACS Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CAINIAO' => tr( 'AliExpress Standard Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ANJUN' => tr( 'Anjun couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ANSERX' => tr( 'ANSERX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AUPOST_CN' => tr( 'AuPost China', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BEL_RS' => tr( 'BEL North Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_BESTEXPRESS' => tr( 'Best Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_BOXC' => tr( 'BoxC courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BUYLOGIC' => tr( 'buylogic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CPEX' => tr( 'Captain Express International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CGS_EXPRESS' => tr( 'CGS Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_CHINA_POST_EMS' => tr( 'China Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHUKOU1' => tr( 'Chukou1', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJPACKET' => tr( 'CJ Packet', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CLEVY_LINKS' => tr( 'Clevy Links', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CNDEXPRESS' => tr( 'CND Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CNEXPS' => tr( 'CNE Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COMET_TECH' => tr( 'CometTech', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CPACKET' => tr( 'Cpacket couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CUCKOOEXPRESS' => tr( 'Cuckoo Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DEX_I' => tr( 'DEX-I courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIDADI' => tr( 'DIDADI Logistics tech', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPE_EXPRESS' => tr( 'DPE Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DTD_EXPR' => tr( 'DTD Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EMPS_CN' => tr( 'EMPS Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_EQUICK' => tr( 'Equick China', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESHIPPING' => tr( 'Eshipping', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZES_EXPRESS' => tr( 'Eshun international Logistic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FAR_INTERNATIONAL' => tr( 'Far international', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FARGOOD' => tr( 'FarGood', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FULFILLME' => tr( 'Fulfillme', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GANGBAO' => tr( 'GANGBAO Supplychain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GESWL' => tr( 'GESWL Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_GOFLY' => tr( 'GoFly', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HDB' => tr( 'Haidaibao', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HDB_BOX' => tr( 'Haidaibao (BOX)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HH_EXP' => tr( 'Hua Han Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HUAHAN_EXPRESS' => tr( 'HUAHANG EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HUODULL' => tr( 'Huodull', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HX_EXPRESS' => tr( 'HX Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IDEXPRESS' => tr( 'IDEX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTEL_VALLEY' => tr( 'Intel-Valley Supply chain (ShenZhen) Co. Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'J_NET' => tr( 'J-Net', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JINDOUYUN' => tr( 'jindouyun courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JOOM_LOGIS' => tr( 'Joom Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JOYING_BOX' => tr( 'Joying Box', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'K1_EXPRESS' => tr( 'K1 Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KY_EXPRESS' => tr( 'Kua Yue Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LALAMOVE' => tr( 'Lalamove', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LEADER' => tr( 'leader', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SDH_SCM' => tr( 'lightning monkey', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGISTERS' => tr( 'Logisters', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LTIANEXP' => tr( 'LTIAN EXP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LTL' => tr( 'LTL COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MORE_LINK' => tr( 'Morelink', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MXE' => tr( 'MXE Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NANJINGWOYUAN' => tr( 'Nanjing Woyuan', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ONEWORLDEXPRESS' => tr( 'One World Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PADTF' => tr( 'padtf.com', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAGO' => tr( 'Pago Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAN_ASIA' => tr( 'Pan-Asia International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_PAYPAL_PACKAGE' => tr( 'PayPal Package', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PFCEXPRESS' => tr( 'PFC Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_POST56' => tr( 'Post56', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HKD' => tr( 'Qingdao HKD International Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ETS_EXPRESS' => tr( 'RETS express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RUSTON' => tr( 'Ruston', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_SF_EXPRESS' => tr( 'SF Express (www.sf-express.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SFB2C' => tr( 'SF International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SFC_LOGISTICS' => tr( 'SFC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SFCSERVICE' => tr( 'SFC Service', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DAJIN' => tr( 'Shanghai Aqrum Chemical Logistics Co.Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SINOTRANS' => tr( 'Sinotrans', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STONE3PL' => tr( 'STONE3PL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SYPOST' => tr( 'Sunyou Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TARRIVE' => tr( 'TONDA GLOBAL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOPHATTEREXPRESS' => tr( 'Tophatter Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOPYOU' => tr( 'TopYou', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UC_EXPRE' => tr( 'ucexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VIWO' => tr( 'VIWO IoT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WANBEXPRESS' => tr( 'WanbExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WEASHIP' => tr( 'Weaship', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_WEDO' => tr( 'WeDo Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WINIT' => tr( 'WinIt', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WISE_EXPRESS' => tr( 'Wise Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_WISHPOST' => tr( 'WishPost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XQ_EXPRESS' => tr( 'XQ Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YANWEN' => tr( 'Yanwen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YDH_EXPRESS' => tr( 'YDH express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ELIAN_POST' => tr( 'Yilian (Elian) Supply Chain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YINGNUO_LOGISTICS' => tr( 'yingnuo logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YTO' => tr( 'YTO Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CN_YUNDA' => tr( 'Yunda Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YUNEXPRESS' => tr( 'YunExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZJS_EXPRESS' => tr( 'ZJS International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZTO_EXPRESS' => tr( 'ZTO Express', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'COL' => array( - 'name' => _x( 'Colombia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Colombia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'COORDINADORA' => _x( 'Coordinadora', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COORDINADORA' => tr( 'Coordinadora', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'HRV' => array( - 'name' => _x( 'Croatia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Croatia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'GLS_CROTIA' => _x( 'GLS Croatia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HRV_HRVATSKA' => _x( 'Hrvatska posta', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OVERSE_EXP' => _x( 'Overseas Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_CROTIA' => tr( 'GLS Croatia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HRV_HRVATSKA' => tr( 'Hrvatska posta', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OVERSE_EXP' => tr( 'Overseas Express', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'CY' => array( - 'name' => _x( 'Cyprus', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Cyprus', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CYPRUS_POST_CYP' => _x( 'Cyprus Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CYPRUS_POST_CYP' => tr( 'Cyprus Post', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'CZ' => array( - 'name' => _x( 'Czech Republic', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Czech Republic', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CESKA_CZ' => _x( 'Ceska Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_CZ' => _x( 'GLS Czech Republic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CESKA_CZ' => tr( 'Ceska Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_CZ' => tr( 'GLS Czech Republic', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'DNK' => array( - 'name' => _x( 'Denmark', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Denmark', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BUDBEE_WEBHOOK' => _x( 'Budbee courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DANSKE_FRAGT' => _x( 'Danske Fragtaend', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTNORD_LOGISTICS_DK' => _x( 'ostnord denmark', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTNORD_LOGISTICS' => _x( 'PostNord Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XPRESSEN_DK' => _x( 'Xpressen courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BUDBEE_WEBHOOK' => tr( 'Budbee courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DANSKE_FRAGT' => tr( 'Danske Fragtaend', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTNORD_LOGISTICS_DK' => tr( 'ostnord denmark', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTNORD_LOGISTICS' => tr( 'PostNord Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XPRESSEN_DK' => tr( 'Xpressen courier', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'EST' => array( - 'name' => _x( 'Estonia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Estonia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'OMNIVA' => _x( 'Omniva', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OMNIVA' => tr( 'Omniva', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'FIN' => array( - 'name' => _x( 'Finland', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Finland', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'MATKAHUOLTO' => _x( 'Matkahuolto', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTI' => _x( 'Posti courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MATKAHUOLTO' => tr( 'Matkahuolto', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTI' => tr( 'Posti courier', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'FR' => array( - 'name' => _x( 'France', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'France', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CHRONOPOST_FR' => _x( 'Chronopost france (www.chronopost.fr)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COLIS_PRIVE' => _x( 'Colis Privé', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FR_COLIS' => _x( 'Colissimo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CUBYN' => _x( 'Cubyn', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_FR' => _x( 'DPD France', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FR_EXAPAQ' => _x( 'DPD France (formerly exapaq)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GEODIS_ESPACE' => _x( 'Geodis E-space', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HEPPNER_FR' => _x( 'Heppner France', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LA_POSTE_SUIVI' => _x( 'La Poste', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_FR' => _x( 'TNT France', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VIRTRANSPORT' => _x( 'VIR Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHRONOPOST_FR' => tr( 'Chronopost france (www.chronopost.fr)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COLIS_PRIVE' => tr( 'Colis Privé', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FR_COLIS' => tr( 'Colissimo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CUBYN' => tr( 'Cubyn', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_FR' => tr( 'DPD France', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FR_EXAPAQ' => tr( 'DPD France (formerly exapaq)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GEODIS_ESPACE' => tr( 'Geodis E-space', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HEPPNER_FR' => tr( 'Heppner France', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LA_POSTE_SUIVI' => tr( 'La Poste', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_FR' => tr( 'TNT France', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VIRTRANSPORT' => tr( 'VIR Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'DE' => array( - 'name' => _x( 'Germany', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Germany', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'HERMES_DE' => _x( 'Hermes Germany', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AO_DEUTSCHLAND' => _x( 'AO Deutschland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DE_DPD_DELISTRACK' => _x( 'DPD Germany', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FIEGE' => _x( 'Fiege Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GEIS' => _x( 'Geis CZ', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GEL_EXPRESS' => _x( 'Gel Express Logistik', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GENERAL_OVERNIGHT' => _x( 'Go!Express and logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HEPPNER' => _x( 'Heppner Internationale Spedition GmbH & Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HERMES_2MANN_HANDLING' => _x( 'Hermes Einrichtungs Service GmbH & Co. KG', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NOX_NACHTEXPRESS' => _x( 'Innight Express Germany GmbH (nox NachtExpress)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LIEFERY' => _x( 'liefery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NOX_NIGHT_TIME_EXPRESS' => _x( 'NOX NightTimeExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELONE' => _x( 'PARCEL ONE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRESSIODE' => _x( 'Pressio', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RABEN_GROUP' => _x( 'Raben Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STRECK_TRANSPORT' => _x( 'Streck Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SWISHIP_DE' => _x( 'Swiship DE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HERMES_DE' => tr( 'Hermes Germany', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AO_DEUTSCHLAND' => tr( 'AO Deutschland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DE_DPD_DELISTRACK' => tr( 'DPD Germany', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FIEGE' => tr( 'Fiege Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GEIS' => tr( 'Geis CZ', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GEL_EXPRESS' => tr( 'Gel Express Logistik', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GENERAL_OVERNIGHT' => tr( 'Go!Express and logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HEPPNER' => tr( 'Heppner Internationale Spedition GmbH & Co.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HERMES_2MANN_HANDLING' => tr( 'Hermes Einrichtungs Service GmbH & Co. KG', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NOX_NACHTEXPRESS' => tr( 'Innight Express Germany GmbH (nox NachtExpress)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LIEFERY' => tr( 'liefery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NOX_NIGHT_TIME_EXPRESS' => tr( 'NOX NightTimeExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELONE' => tr( 'PARCEL ONE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRESSIODE' => tr( 'Pressio', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RABEN_GROUP' => tr( 'Raben Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STRECK_TRANSPORT' => tr( 'Streck Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SWISHIP_DE' => tr( 'Swiship DE', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'GR' => array( - 'name' => _x( 'Greece', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Greece', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ACS_GR' => _x( 'ACS Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EASY_MAIL' => _x( 'Easy Mail', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GENIKI_GR' => _x( 'Geniki Taxydromiki', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPEEDCOURIERS_GR' => _x( 'Speed Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPEEDEXCOURIER' => _x( 'SPEEDEX couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ACS_GR' => tr( 'ACS Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EASY_MAIL' => tr( 'Easy Mail', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GENIKI_GR' => tr( 'Geniki Taxydromiki', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPEEDCOURIERS_GR' => tr( 'Speed Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPEEDEXCOURIER' => tr( 'SPEEDEX couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'HK' => array( - 'name' => _x( 'Hong Kong', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Hong Kong', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CFL_LOGISTICS' => _x( 'CFL Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJ_HK_INTERNATIONAL' => _x( 'CJ Logistics International(Hong Kong)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CLE_LOGISTICS' => _x( 'CL E-Logistics Solutions Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CONTINENTAL' => _x( 'Continental', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COSTMETICSNOW' => _x( 'Cosmetics Now', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DEALERSEND' => _x( 'DealerSend', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_ECOMERCE_ASA' => _x( 'DHL eCommerce Asia (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_GLOBAL_MAIL_ASIA' => _x( 'DHL Global Mail Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_HK' => _x( 'DHL Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_HK' => _x( 'DPD Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DTDC_EXPRESS' => _x( 'DTDC express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOBAVEND' => _x( 'Globavend', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HK_POST' => _x( 'Hongkong Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JANCO' => _x( 'Janco Ecommerce', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JS_EXPRESS' => _x( 'JS EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KEC' => _x( 'KEC courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KERRY_ECOMMERCE' => _x( 'Kerry eCommerce', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LHT_EXPRESS' => _x( 'LHT Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGISTICSWORLDWIDE_HK' => _x( 'Logistic Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAINWAY' => _x( 'Mainway', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MORNING_EXPRESS' => _x( 'Morning Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OKAYPARCEL' => _x( 'OkayParcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OMNIPARCEL' => _x( 'Omni Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PALEXPRESS' => _x( 'PAL Express Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PICKUP' => _x( 'Pickupp', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'QUANTIUM' => _x( 'Quantium', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RPX' => _x( 'RPX Online', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SEKOLOGISTICS' => _x( 'SEKO Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIP_IT_ASIA' => _x( 'Ship It Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SMOOTH' => _x( 'Smooth Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'STEPFORWARDFS' => _x( 'STEP FORWARD FREIGHT SERVICE CO LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SFPLUS_WEBHOOK' => _x( 'Zeek courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZEEK_2_DOOR' => _x( 'Zeek2Door', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CFL_LOGISTICS' => tr( 'CFL Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJ_HK_INTERNATIONAL' => tr( 'CJ Logistics International(Hong Kong)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CLE_LOGISTICS' => tr( 'CL E-Logistics Solutions Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CONTINENTAL' => tr( 'Continental', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COSTMETICSNOW' => tr( 'Cosmetics Now', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DEALERSEND' => tr( 'DealerSend', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_ECOMERCE_ASA' => tr( 'DHL eCommerce Asia (API)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_GLOBAL_MAIL_ASIA' => tr( 'DHL Global Mail Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_HK' => tr( 'DHL Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_HK' => tr( 'DPD Hong Kong', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DTDC_EXPRESS' => tr( 'DTDC express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOBAVEND' => tr( 'Globavend', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HK_POST' => tr( 'Hongkong Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JANCO' => tr( 'Janco Ecommerce', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JS_EXPRESS' => tr( 'JS EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KEC' => tr( 'KEC courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KERRY_ECOMMERCE' => tr( 'Kerry eCommerce', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LHT_EXPRESS' => tr( 'LHT Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGISTICSWORLDWIDE_HK' => tr( 'Logistic Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAINWAY' => tr( 'Mainway', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MORNING_EXPRESS' => tr( 'Morning Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OKAYPARCEL' => tr( 'OkayParcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OMNIPARCEL' => tr( 'Omni Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PALEXPRESS' => tr( 'PAL Express Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PICKUP' => tr( 'Pickupp', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'QUANTIUM' => tr( 'Quantium', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RPX' => tr( 'RPX Online', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SEKOLOGISTICS' => tr( 'SEKO Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIP_IT_ASIA' => tr( 'Ship It Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SMOOTH' => tr( 'Smooth Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'STEPFORWARDFS' => tr( 'STEP FORWARD FREIGHT SERVICE CO LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SFPLUS_WEBHOOK' => tr( 'Zeek courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZEEK_2_DOOR' => tr( 'Zeek2Door', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'HU' => array( - 'name' => _x( 'Hungary', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Hungary', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'DPD_HGRY' => _x( 'DPD Hungary', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAGYAR_HU' => _x( 'Magyar Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_HGRY' => tr( 'DPD Hungary', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAGYAR_HU' => tr( 'Magyar Post', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'IN' => array( - 'name' => _x( 'India', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'India', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BOMBINOEXP' => _x( 'Bombino Express Pvt', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IND_DELHIVERY' => _x( 'Delhivery India', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELIVERYONTIME' => _x( 'DELIVERYONTIME LOGISTICS PVT LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DTDC_IN' => _x( 'DTDC India', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IND_ECOM' => _x( 'Ecom Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EKART' => _x( 'Ekart logistics (ekartlogistics.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IND_FIRSTFLIGHT' => _x( 'First Flight Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IND_GATI' => _x( 'Gati-KWE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IND_GOJAVAS' => _x( 'GoJavas', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HOLISOL' => _x( 'Holisol', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LEXSHIP' => _x( 'LexShip', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OCS' => _x( 'OCS ANA Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELLED_IN' => _x( 'Parcelled.in', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PICKRR' => _x( 'Pickrr', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IND_SAFEEXPRESS' => _x( 'Safexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SCUDEX_EXPRESS' => _x( 'Scudex Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHREE_ANJANI_COURIER' => _x( 'Shree Anjani Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHREE_MARUTI' => _x( 'Shree Maruti Courier Services Pvt Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHREENANDANCOURIER' => _x( 'SHREE NANDAN COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHREETIRUPATI' => _x( 'SHREE TIRUPATI COURIER SERVICES PVT. LTD.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPOTON' => _x( 'SPOTON Logistics Pvt Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRACKON' => _x( 'Trackon Couriers Pvt. Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BOMBINOEXP' => tr( 'Bombino Express Pvt', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IND_DELHIVERY' => tr( 'Delhivery India', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELIVERYONTIME' => tr( 'DELIVERYONTIME LOGISTICS PVT LTD', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DTDC_IN' => tr( 'DTDC India', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IND_ECOM' => tr( 'Ecom Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EKART' => tr( 'Ekart logistics (ekartlogistics.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IND_FIRSTFLIGHT' => tr( 'First Flight Couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IND_GATI' => tr( 'Gati-KWE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IND_GOJAVAS' => tr( 'GoJavas', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HOLISOL' => tr( 'Holisol', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LEXSHIP' => tr( 'LexShip', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OCS' => tr( 'OCS ANA Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELLED_IN' => tr( 'Parcelled.in', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PICKRR' => tr( 'Pickrr', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IND_SAFEEXPRESS' => tr( 'Safexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SCUDEX_EXPRESS' => tr( 'Scudex Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHREE_ANJANI_COURIER' => tr( 'Shree Anjani Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHREE_MARUTI' => tr( 'Shree Maruti Courier Services Pvt Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHREENANDANCOURIER' => tr( 'SHREE NANDAN COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHREETIRUPATI' => tr( 'SHREE TIRUPATI COURIER SERVICES PVT. LTD.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPOTON' => tr( 'SPOTON Logistics Pvt Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRACKON' => tr( 'Trackon Couriers Pvt. Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'ID' => array( - 'name' => _x( 'Indonesia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Indonesia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ALFATREX' => _x( 'AlfaTrex', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CHOIR_EXP' => _x( 'Choir Express Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INDOPAKET' => _x( 'INDOPAKET', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JX' => _x( 'JX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KURASI' => _x( 'KURASI', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NINJAVAN_ID' => _x( 'Ninja Van Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NINJAVAN_WB' => _x( 'Ninjavan Webhook', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MGLOBAL' => _x( 'PT MGLOBAL LOGISTICS INDONESIA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRIMAMULTICIPTA' => _x( 'PT Prima Multi Cipta', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RCL' => _x( 'Red Carpet Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RPX_ID' => _x( 'RPX Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SAP_EXPRESS' => _x( 'SAP EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SIN_GLBL' => _x( 'Sin Global Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TIKI_ID' => _x( 'Tiki shipment', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRANS_KARGO' => _x( 'Trans Kargo Internasional', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WAHANA_ID' => _x( 'Wahana express (www.wahana.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ALFATREX' => tr( 'AlfaTrex', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CHOIR_EXP' => tr( 'Choir Express Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INDOPAKET' => tr( 'INDOPAKET', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JX' => tr( 'JX courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KURASI' => tr( 'KURASI', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NINJAVAN_ID' => tr( 'Ninja Van Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NINJAVAN_WB' => tr( 'Ninjavan Webhook', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MGLOBAL' => tr( 'PT MGLOBAL LOGISTICS INDONESIA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRIMAMULTICIPTA' => tr( 'PT Prima Multi Cipta', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RCL' => tr( 'Red Carpet Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RPX_ID' => tr( 'RPX Indonesia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SAP_EXPRESS' => tr( 'SAP EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SIN_GLBL' => tr( 'Sin Global Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TIKI_ID' => tr( 'Tiki shipment', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRANS_KARGO' => tr( 'Trans Kargo Internasional', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WAHANA_ID' => tr( 'Wahana express (www.wahana.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'IE' => array( - 'name' => _x( 'Ireland', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Ireland', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'AN_POST' => _x( 'An Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_IR' => _x( 'DPD Ireland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTWAY_IR' => _x( 'Fastway Ireland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WISELOADS' => _x( 'Wiseloads', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AN_POST' => tr( 'An Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_IR' => tr( 'DPD Ireland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTWAY_IR' => tr( 'Fastway Ireland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WISELOADS' => tr( 'Wiseloads', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'IL' => array( - 'name' => _x( 'Israel', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Israel', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ISRAEL_POST' => _x( 'Israel Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ISR_POST_DOMESTIC' => _x( 'Israel Post Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ISRAEL_POST' => tr( 'Israel Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ISR_POST_DOMESTIC' => tr( 'Israel Post Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'IT' => array( - 'name' => _x( 'Italy', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Italy', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BRT_IT_PARCELID' => _x( 'BRT Bartolini (Parcel ID)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BRT_IT' => _x( 'BRT Couriers Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARCO_SPEDIZIONI' => _x( 'Arco Spedizioni SP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BLINKLASTMILE' => _x( 'Blink', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BRT_IT_SENDER_REF' => _x( 'BRT Bartolini (Sender Reference)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DMM_NETWORK' => _x( 'DMM Network', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLS_IT' => _x( 'GLS Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HRPARCEL' => _x( 'HR Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'I_DIKA' => _x( 'i-dika', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LICCARDI_EXPRESS' => _x( 'LICCARDI EXPRESS COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MILKMAN' => _x( 'Milkman Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IT_NEXIVE' => _x( 'Nexive (TNT Post Italy)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IT_POSTE_ITALIA' => _x( 'Poste Italiane', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SAILPOST' => _x( 'SAILPOST', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SDA_IT' => _x( 'SDA Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_CLICK_IT' => _x( 'TNT-Click Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BRT_IT_PARCELID' => tr( 'BRT Bartolini (Parcel ID)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BRT_IT' => tr( 'BRT Couriers Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARCO_SPEDIZIONI' => tr( 'Arco Spedizioni SP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BLINKLASTMILE' => tr( 'Blink', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BRT_IT_SENDER_REF' => tr( 'BRT Bartolini (Sender Reference)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DMM_NETWORK' => tr( 'DMM Network', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_IT' => tr( 'GLS Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HRPARCEL' => tr( 'HR Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'I_DIKA' => tr( 'i-dika', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LICCARDI_EXPRESS' => tr( 'LICCARDI EXPRESS COURIER', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MILKMAN' => tr( 'Milkman Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IT_NEXIVE' => tr( 'Nexive (TNT Post Italy)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IT_POSTE_ITALIA' => tr( 'Poste Italiane', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SAILPOST' => tr( 'SAILPOST', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SDA_IT' => tr( 'SDA Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_CLICK_IT' => tr( 'TNT-Click Italy', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'JP' => array( - 'name' => _x( 'Japan', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Japan', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'EFEX' => _x( 'eFEx (E-Commerce Fulfillment & Express)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JPN_JAPAN_POST' => _x( 'Japan Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KWE_GLOBAL' => _x( 'KWE Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAIL_PLUS' => _x( 'MailPlus', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAILPLUS_JPN' => _x( 'MailPlus (Japan)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SEINO' => _x( 'Seino', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EFEX' => tr( 'eFEx (E-Commerce Fulfillment & Express)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JPN_JAPAN_POST' => tr( 'Japan Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KWE_GLOBAL' => tr( 'KWE Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAIL_PLUS' => tr( 'MailPlus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAILPLUS_JPN' => tr( 'MailPlus (Japan)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SEINO' => tr( 'Seino', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'JEY' => array( - 'name' => _x( 'Jersey', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Jersey', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'JERSEY_POST' => _x( 'Jersey Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JERSEY_POST' => tr( 'Jersey Post', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'KR' => array( - 'name' => _x( 'Korea', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Korea', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CELLO_SQUARE' => _x( 'Cello Square', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CROSHOT' => _x( 'Croshot', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DOORA' => _x( 'Doora Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EPARCEL_KR' => _x( 'eParcel Korea', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KPOST' => _x( 'Korea Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KR_KOREA_POST' => _x( 'Koreapost (www.koreapost.go.kr)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KYUNGDONG_PARCEL' => _x( 'Kyungdong Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOTTE' => _x( 'Lotte Global Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RINCOS' => _x( 'Rincos', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROCKET_PARCEL' => _x( 'Rocket Parcel International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIP_GATE' => _x( 'ShipGate', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPTER' => _x( 'SHIPTER', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SRE_KOREA' => _x( 'SRE Korea (www.srekorea.co.kr)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOLOS' => _x( 'Tolos courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CELLO_SQUARE' => tr( 'Cello Square', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CROSHOT' => tr( 'Croshot', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DOORA' => tr( 'Doora Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EPARCEL_KR' => tr( 'eParcel Korea', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KPOST' => tr( 'Korea Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KR_KOREA_POST' => tr( 'Koreapost (www.koreapost.go.kr)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KYUNGDONG_PARCEL' => tr( 'Kyungdong Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOTTE' => tr( 'Lotte Global Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RINCOS' => tr( 'Rincos', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROCKET_PARCEL' => tr( 'Rocket Parcel International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIP_GATE' => tr( 'ShipGate', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPTER' => tr( 'SHIPTER', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SRE_KOREA' => tr( 'SRE Korea (www.srekorea.co.kr)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOLOS' => tr( 'Tolos courier', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'KWT' => array( - 'name' => _x( 'Kuwait', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Kuwait', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'POSTA_PLUS' => _x( 'Posta Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTA_PLUS' => tr( 'Posta Plus', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'LAO' => array( - 'name' => _x( "Lao People's Democratic Republic (the)", 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( "Lao People's Democratic Republic (the)", 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'LAO_POST' => _x( 'Lao Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LAO_POST' => tr( 'Lao Post', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'LVA' => array( - 'name' => _x( 'Latvia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Latvia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CDEK' => _x( 'CDEK courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LATVIJAS_PASTS' => _x( 'Latvijas Pasts', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CDEK' => tr( 'CDEK courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LATVIJAS_PASTS' => tr( 'Latvijas Pasts', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'LT' => array( - 'name' => _x( 'Lithuania', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Lithuania', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'VENIPAK' => _x( 'Venipak', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VENIPAK' => tr( 'Venipak', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'MY' => array( - 'name' => _x( 'Malaysia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Malaysia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ABXEXPRESS_MY' => _x( 'ABX Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYS_AIRPAK' => _x( 'Airpak Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CITYLINK_MY' => _x( 'City-Link Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJ_CENTURY' => _x( 'CJ Century', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJ_INT_MY' => _x( 'CJ International Malaysia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COLLECTCO' => _x( 'CollectCo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FMX' => _x( 'FMX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYS_GDEX' => _x( 'GDEX Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JTEXPRESS' => _x( 'J&T EXPRESS MALAYSIA', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JINSUNG' => _x( 'JINSUNG TRADING', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JOCOM' => _x( 'Jocom', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KANGAROO_MY' => _x( 'Kangaroo Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LINE' => _x( 'Line Clear Express & Logistics Sdn Bhd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGISTIKA' => _x( 'Logistika', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'M_XPRESS' => _x( 'M Xpress Sdn Bhd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYS_MYS_POST' => _x( 'Malaysia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MATDESPATCH' => _x( 'Matdespatch', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYS_MYPOST_ONLINE' => _x( 'Mypostonline', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NATIONWIDE_MY' => _x( 'Nationwide Express Courier Services Bhd (www.nationwide.com.my)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NINJAVAN_MY' => _x( 'Ninja Van (www.ninjavan.co)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PICKUPP_MYS' => _x( 'PICK UPP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYS_SKYNET' => _x( 'Skynet Malaysia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TAQBIN_MY' => _x( 'TAQBIN Malaysia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WEPOST' => _x( 'WePost Sdn Bhd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WYNGS' => _x( 'Wyngs', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZEPTO_EXPRESS' => _x( 'ZeptoExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ABXEXPRESS_MY' => tr( 'ABX Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYS_AIRPAK' => tr( 'Airpak Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CITYLINK_MY' => tr( 'City-Link Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJ_CENTURY' => tr( 'CJ Century', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJ_INT_MY' => tr( 'CJ International Malaysia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COLLECTCO' => tr( 'CollectCo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FMX' => tr( 'FMX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYS_GDEX' => tr( 'GDEX Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JTEXPRESS' => tr( 'J&T EXPRESS MALAYSIA', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JINSUNG' => tr( 'JINSUNG TRADING', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JOCOM' => tr( 'Jocom', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KANGAROO_MY' => tr( 'Kangaroo Worldwide Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LINE' => tr( 'Line Clear Express & Logistics Sdn Bhd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGISTIKA' => tr( 'Logistika', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'M_XPRESS' => tr( 'M Xpress Sdn Bhd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYS_MYS_POST' => tr( 'Malaysia Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MATDESPATCH' => tr( 'Matdespatch', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYS_MYPOST_ONLINE' => tr( 'Mypostonline', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NATIONWIDE_MY' => tr( 'Nationwide Express Courier Services Bhd (www.nationwide.com.my)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NINJAVAN_MY' => tr( 'Ninja Van (www.ninjavan.co)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PICKUPP_MYS' => tr( 'PICK UPP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYS_SKYNET' => tr( 'Skynet Malaysia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TAQBIN_MY' => tr( 'TAQBIN Malaysia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WEPOST' => tr( 'WePost Sdn Bhd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WYNGS' => tr( 'Wyngs', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZEPTO_EXPRESS' => tr( 'ZeptoExpress', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'MX' => array( - 'name' => _x( 'Mexico', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Mexico', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CORREOS_DE_MEXICO' => _x( 'Correos Mexico', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MEX_ESTAFETA' => _x( 'Estafeta (www.estafeta.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GRUPO' => _x( 'Grupo ampm', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HOUNDEXPRESS' => _x( 'Hound Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IVOY_WEBHOOK' => _x( 'Ivoy courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MEX_SENDA' => _x( 'Mexico Senda Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAQUETEXPRESS' => _x( 'Paquetexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MEX_REDPACK' => _x( 'Redpack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CORREOS_DE_MEXICO' => tr( 'Correos Mexico', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MEX_ESTAFETA' => tr( 'Estafeta (www.estafeta.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GRUPO' => tr( 'Grupo ampm', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HOUNDEXPRESS' => tr( 'Hound Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IVOY_WEBHOOK' => tr( 'Ivoy courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MEX_SENDA' => tr( 'Mexico Senda Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAQUETEXPRESS' => tr( 'Paquetexpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MEX_REDPACK' => tr( 'Redpack', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'NL' => array( - 'name' => _x( 'Netherlands', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Netherlands', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BROUWER_TRANSPORT' => _x( 'Brouwer Transport en Logistiek', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NLD_DHL' => _x( 'DHL Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FIEGE_NL' => _x( 'Fiege Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NLD_GLS' => _x( 'GLS Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HAPPY2POINT' => _x( 'Happy 2ThePoint', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAPER_EXPRESS' => _x( 'Paper Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTNL_INTL_3S' => _x( 'PostNL International 3S', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRUNKRS_WEBHOOK' => _x( 'Trunkrs courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BROUWER_TRANSPORT' => tr( 'Brouwer Transport en Logistiek', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NLD_DHL' => tr( 'DHL Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FIEGE_NL' => tr( 'Fiege Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NLD_GLS' => tr( 'GLS Netherlands', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HAPPY2POINT' => tr( 'Happy 2ThePoint', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAPER_EXPRESS' => tr( 'Paper Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTNL_INTL_3S' => tr( 'PostNL International 3S', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRUNKRS_WEBHOOK' => tr( 'Trunkrs courier', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'NZ' => array( - 'name' => _x( 'New Zealand', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'New Zealand', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'FASTWAY_NZ' => _x( 'Fastway New Zealand', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTERPARCEL_NZ' => _x( 'Interparcel New Zealand', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAINFREIGHT' => _x( 'Mainfreight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NZ_NZ_POST' => _x( 'New Zealand Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOLL_NZ' => _x( 'Toll New Zealand', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTWAY_NZ' => tr( 'Fastway New Zealand', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTERPARCEL_NZ' => tr( 'Interparcel New Zealand', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAINFREIGHT' => tr( 'Mainfreight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NZ_NZ_POST' => tr( 'New Zealand Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOLL_NZ' => tr( 'Toll New Zealand', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'NG' => array( - 'name' => _x( 'Nigeria', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Nigeria', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'NIPOST_NG' => _x( 'NIpost (www.nipost.gov.ng)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NIPOST_NG' => tr( 'NIpost (www.nipost.gov.ng)', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'NO' => array( - 'name' => _x( 'Norway', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Norway', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'HELTHJEM' => _x( 'Helthjem', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HELTHJEM' => tr( 'Helthjem', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'PAK' => array( - 'name' => _x( 'Pakistan', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Pakistan', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'FORRUN' => _x( 'forrun Pvt Ltd (Arpatech Venture)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TCS' => _x( 'TCS courier ', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FORRUN' => tr( 'forrun Pvt Ltd (Arpatech Venture)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TCS' => tr( 'TCS courier ', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'PRY' => array( - 'name' => _x( 'Paraguay', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Paraguay', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'AEX' => _x( 'AEX Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AEX' => tr( 'AEX Group', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'PH' => array( - 'name' => _x( 'Philippines', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Philippines', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'TWO_GO' => _x( '2GO Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PHL_JAMEXPRESS' => _x( 'Jam Express Philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PIXSELL' => _x( 'PIXSELL LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RAF_PH' => _x( 'RAF Philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XDE_WEBHOOK' => _x( 'Ximex Delivery Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XPOST' => _x( 'Xpost.ph', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TWO_GO' => tr( '2GO Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PHL_JAMEXPRESS' => tr( 'Jam Express Philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PIXSELL' => tr( 'PIXSELL LOGISTICS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RAF_PH' => tr( 'RAF Philippines', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XDE_WEBHOOK' => tr( 'Ximex Delivery Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XPOST' => tr( 'Xpost.ph', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'PL' => array( - 'name' => _x( 'Poland', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Poland', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'DHL_PL' => _x( 'DHL Poland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_POLAND' => _x( 'DPD Poland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FEDEX_POLAND' => _x( 'FedEx® Poland Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INPOST_PACZKOMATY' => _x( 'InPost Paczkomaty', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PL_POCZTA_POLSKA' => _x( 'Poczta Polska', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROYAL_MAIL' => _x( 'Royal Mail', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_PL' => tr( 'DHL Poland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_POLAND' => tr( 'DPD Poland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FEDEX_POLAND' => tr( 'FedEx® Poland Domestic', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INPOST_PACZKOMATY' => tr( 'InPost Paczkomaty', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PL_POCZTA_POLSKA' => tr( 'Poczta Polska', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROYAL_MAIL' => tr( 'Royal Mail', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'PT' => array( - 'name' => _x( 'Portugal', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Portugal', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ADICIONAL' => _x( 'Adicional Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BNEED' => _x( 'Bneed courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CARRIERS' => _x( 'Carriers courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRT_CHRONOPOST' => _x( 'Chronopost Portugal', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRT_CTT' => _x( 'CTT Portugal', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELNEXT' => _x( 'Delnext', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ADICIONAL' => tr( 'Adicional Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BNEED' => tr( 'Bneed courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CARRIERS' => tr( 'Carriers courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRT_CHRONOPOST' => tr( 'Chronopost Portugal', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRT_CTT' => tr( 'CTT Portugal', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELNEXT' => tr( 'Delnext', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'RO' => array( - 'name' => _x( 'Romania', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Romania', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'DPD_RO' => _x( 'DPD Romania', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTA_RO' => _x( 'Post Roman (www.posta-romana.ro)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_RO' => tr( 'DPD Romania', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTA_RO' => tr( 'Post Roman (www.posta-romana.ro)', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'RUS' => array( - 'name' => _x( 'Russia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Russia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'BOX_BERRY' => _x( 'Boxberry courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CSE' => _x( 'CSE courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_PARCEL_RU' => _x( 'DHL Parcel Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DOBROPOST' => _x( 'DobroPost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_RU' => _x( 'DPD Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EXPRESSSALE' => _x( 'Expresssale', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GBS_BROKER' => _x( 'GBS-Broker', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PONY_EXPRESS' => _x( 'Pony express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHOPFANS' => _x( 'ShopfansRU LLC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BOX_BERRY' => tr( 'Boxberry courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CSE' => tr( 'CSE courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_PARCEL_RU' => tr( 'DHL Parcel Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DOBROPOST' => tr( 'DobroPost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_RU' => tr( 'DPD Russia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EXPRESSSALE' => tr( 'Expresssale', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GBS_BROKER' => tr( 'GBS-Broker', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PONY_EXPRESS' => tr( 'Pony express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHOPFANS' => tr( 'ShopfansRU LLC', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'SAU' => array( - 'name' => _x( 'Saudi Arabia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Saudi Arabia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'SAU_SAUDI_POST' => _x( 'Saudi Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SMSA_EXPRESS' => _x( 'SMSA Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THABIT_LOGISTICS' => _x( 'Thabit Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZAJIL_EXPRESS' => _x( 'Zajil Express Company', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SAU_SAUDI_POST' => tr( 'Saudi Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SMSA_EXPRESS' => tr( 'SMSA Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THABIT_LOGISTICS' => tr( 'Thabit Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZAJIL_EXPRESS' => tr( 'Zajil Express Company', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'SRB' => array( - 'name' => _x( 'Serbia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Serbia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'POST_SERBIA' => _x( 'Posta Serbia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POST_SERBIA' => tr( 'Posta Serbia', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'SG' => array( - 'name' => _x( 'Singapore', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Singapore', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CLOUDWISH_ASIA' => _x( 'Cloudwish Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SG_DETRACK' => _x( 'Detrack', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FONSEN' => _x( 'Fonsen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GRAB_WEBHOOK' => _x( 'Grab courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SIMPLYPOST' => _x( 'J&T Express Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JANIO' => _x( 'Janio Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'IND_JAYONEXPRESS' => _x( 'Jayon Express (JEX)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'JET_SHIP' => _x( 'Jet-Ship Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KGMHUB' => _x( 'KGM Hub', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LEGION_EXPRESS' => _x( 'Legion Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NHANS_SOLUTIONS' => _x( 'Nhans Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NINJAVAN_SG' => _x( 'Ninja van Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELPOST_SG' => _x( 'Parcel Post Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARKNPARCEL' => _x( 'Park N Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PICKUPP_SGP' => _x( 'PICK UPP (Singapore)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SG_QXPRESS' => _x( 'Qxpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RAIDEREX' => _x( 'RaidereX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ROADBULL' => _x( 'Red Carpet Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RZYEXPRESS' => _x( 'RZY Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SG_SG_POST' => _x( 'Singapore Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SG_SPEEDPOST' => _x( 'Singapore Speedpost', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TCK_EXPRESS' => _x( 'TCK Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COUREX' => _x( 'Urbanfox', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WMG' => _x( 'WMG Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZYLLEM' => _x( 'Zyllem', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CLOUDWISH_ASIA' => tr( 'Cloudwish Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SG_DETRACK' => tr( 'Detrack', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FONSEN' => tr( 'Fonsen Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GRAB_WEBHOOK' => tr( 'Grab courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SIMPLYPOST' => tr( 'J&T Express Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JANIO' => tr( 'Janio Asia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IND_JAYONEXPRESS' => tr( 'Jayon Express (JEX)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JET_SHIP' => tr( 'Jet-Ship Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KGMHUB' => tr( 'KGM Hub', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LEGION_EXPRESS' => tr( 'Legion Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NHANS_SOLUTIONS' => tr( 'Nhans Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NINJAVAN_SG' => tr( 'Ninja van Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELPOST_SG' => tr( 'Parcel Post Singapore', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARKNPARCEL' => tr( 'Park N Parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PICKUPP_SGP' => tr( 'PICK UPP (Singapore)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SG_QXPRESS' => tr( 'Qxpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RAIDEREX' => tr( 'RaidereX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ROADBULL' => tr( 'Red Carpet Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RZYEXPRESS' => tr( 'RZY Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SG_SG_POST' => tr( 'Singapore Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SG_SPEEDPOST' => tr( 'Singapore Speedpost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TCK_EXPRESS' => tr( 'TCK Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COUREX' => tr( 'Urbanfox', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WMG' => tr( 'WMG Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZYLLEM' => tr( 'Zyllem', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'SVK' => array( - 'name' => _x( 'Slovakia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Slovakia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'GLS_SLOV' => _x( 'GLS General Logistics Systems Slovakia s.r.o.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_SLOV' => tr( 'GLS General Logistics Systems Slovakia s.r.o.', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'SVN' => array( - 'name' => _x( 'Slovenia', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Slovenia', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'GLS_SLOVEN' => _x( 'GLS Slovenia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POST_SLOVENIA' => _x( 'Post of Slovenia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLS_SLOVEN' => tr( 'GLS Slovenia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POST_SLOVENIA' => tr( 'Post of Slovenia', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'ZA' => array( - 'name' => _x( 'South Africa', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'South Africa', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ZA_COURIERIT' => _x( 'Courier IT', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DAWN_WING' => _x( 'Dawn Wing', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPE_SOUTH_AFRC' => _x( 'DPE South Africa', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTEXPRESS' => _x( 'Internet Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'COLLIVERY' => _x( 'MDS Collivery Pty (Ltd)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RAM' => _x( 'RAM courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SKYNET_ZA' => _x( 'Skynet World Wide Express South Africa', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SOUTH_AFRICAN_POST_OFFICE' => _x( 'South African Post Office', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZA_SPECIALISED_FREIGHT' => _x( 'Specialised Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THECOURIERGUY' => _x( 'The Courier Guy', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZA_COURIERIT' => tr( 'Courier IT', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DAWN_WING' => tr( 'Dawn Wing', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPE_SOUTH_AFRC' => tr( 'DPE South Africa', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTEXPRESS' => tr( 'Internet Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'COLLIVERY' => tr( 'MDS Collivery Pty (Ltd)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RAM' => tr( 'RAM courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SKYNET_ZA' => tr( 'Skynet World Wide Express South Africa', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SOUTH_AFRICAN_POST_OFFICE' => tr( 'South African Post Office', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZA_SPECIALISED_FREIGHT' => tr( 'Specialised Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THECOURIERGUY' => tr( 'The Courier Guy', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'ES' => array( - 'name' => _x( 'Spain', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Spain', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ABCUSTOM' => _x( 'AB Custom Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ADERONLINE' => _x( 'Ader couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ASIGNA' => _x( 'ASIGNA courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESP_ASM' => _x( 'ASM(GLS Spain)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CBL_LOGISTICA' => _x( 'CBL Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CORREOS_EXPRESS' => _x( 'Correos Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_PARCEL_ES' => _x( 'DHL parcel Spain(www.dhl.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_ES' => _x( 'DHL Spain(www.dhl.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ECOSCOOTING' => _x( 'ECOSCOOTING', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESP_ENVIALIA' => _x( 'Envialia', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ENVIALIA_REFERENCE' => _x( 'Envialia Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTEGRA2_FTP' => _x( 'Integra2', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MRW_FTP' => _x( 'MRW courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESP_MRW' => _x( 'MRW spain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NACEX' => _x( 'NACEX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NACEX_ES' => _x( 'NACEX Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESP_NACEX' => _x( 'NACEX Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PAACK_WEBHOOK' => _x( 'Paack courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESP_PACKLINK' => _x( 'Packlink', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ESP_REDUR' => _x( 'Redur Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRT_INT_SEUR' => _x( 'SEUR International', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRT_SEUR' => _x( 'SEUR portugal', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SEUR_ES' => _x( 'Seur Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SEUR_SP_API' => _x( 'Spanish Seur API', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPRING_GDS' => _x( 'Spring GDS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SZENDEX' => _x( 'SZENDEX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_NL' => _x( 'THT Netherland', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TIPSA' => _x( 'TIPSA courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT' => _x( 'TNT Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOBAL_TNT' => _x( 'TNT global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TOURLINE' => _x( 'tourline', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VAMOX' => _x( 'VAMOX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VIA_EXPRESS' => _x( 'Viaxpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZELERIS' => _x( 'Zeleris', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ABCUSTOM' => tr( 'AB Custom Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ADERONLINE' => tr( 'Ader couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ASIGNA' => tr( 'ASIGNA courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESP_ASM' => tr( 'ASM(GLS Spain)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CBL_LOGISTICA' => tr( 'CBL Logistica', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CORREOS_EXPRESS' => tr( 'Correos Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_PARCEL_ES' => tr( 'DHL parcel Spain(www.dhl.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_ES' => tr( 'DHL Spain(www.dhl.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ECOSCOOTING' => tr( 'ECOSCOOTING', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESP_ENVIALIA' => tr( 'Envialia', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ENVIALIA_REFERENCE' => tr( 'Envialia Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTEGRA2_FTP' => tr( 'Integra2', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MRW_FTP' => tr( 'MRW courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESP_MRW' => tr( 'MRW spain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NACEX' => tr( 'NACEX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NACEX_ES' => tr( 'NACEX Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESP_NACEX' => tr( 'NACEX Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PAACK_WEBHOOK' => tr( 'Paack courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESP_PACKLINK' => tr( 'Packlink', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ESP_REDUR' => tr( 'Redur Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRT_INT_SEUR' => tr( 'SEUR International', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRT_SEUR' => tr( 'SEUR portugal', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SEUR_ES' => tr( 'Seur Spain', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SEUR_SP_API' => tr( 'Spanish Seur API', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPRING_GDS' => tr( 'Spring GDS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SZENDEX' => tr( 'SZENDEX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_NL' => tr( 'THT Netherland', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TIPSA' => tr( 'TIPSA courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT' => tr( 'TNT Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOBAL_TNT' => tr( 'TNT global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TOURLINE' => tr( 'tourline', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VAMOX' => tr( 'VAMOX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VIA_EXPRESS' => tr( 'Viaxpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZELERIS' => tr( 'Zeleris', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'SE' => array( - 'name' => _x( 'Sweden', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Sweden', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'AIRMEE_WEBHOOK' => _x( 'Airmee couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BRING' => _x( 'Bring', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DBSCHENKER_SE' => _x( 'DB Schenker (www.dbschenker.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DBSCHENKER_SV' => _x( 'DB Schenker Sweden', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AIRMEE_WEBHOOK' => tr( 'Airmee couriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BRING' => tr( 'Bring', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DBSCHENKER_SE' => tr( 'DB Schenker (www.dbschenker.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DBSCHENKER_SV' => tr( 'DB Schenker Sweden', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'CH' => array( - 'name' => _x( 'Switzerland', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Switzerland', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ASENDIA_HK' => _x( 'Asendia HonKong', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PLANZER' => _x( 'Planzer Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SWISS_POST_FTP' => _x( 'Swiss Post FTP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VIAEUROPE' => _x( 'ViaEurope', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ASENDIA_HK' => tr( 'Asendia HonKong', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PLANZER' => tr( 'Planzer Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SWISS_POST_FTP' => tr( 'Swiss Post FTP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VIAEUROPE' => tr( 'ViaEurope', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'TW' => array( - 'name' => _x( 'Taiwan', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Taiwan', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CNWANGTONG' => _x( 'cnwangtong', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CTC_EXPRESS' => _x( 'CTC Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIMERCO' => _x( 'Dimerco Express Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HCT_LOGISTICS' => _x( 'HCT LOGISTICS CO.LTD.', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KERRYTJ' => _x( 'Kerry TJ Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PRESIDENT_TRANS' => _x( 'PRESIDENT TRANSNET CORP', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOBAL_EXPRESS' => _x( 'Tai Wan Global Business', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CNWANGTONG' => tr( 'cnwangtong', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CTC_EXPRESS' => tr( 'CTC Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIMERCO' => tr( 'Dimerco Express Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HCT_LOGISTICS' => tr( 'HCT LOGISTICS CO.LTD.', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KERRYTJ' => tr( 'Kerry TJ Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PRESIDENT_TRANS' => tr( 'PRESIDENT TRANSNET CORP', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOBAL_EXPRESS' => tr( 'Tai Wan Global Business', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'TH' => array( - 'name' => _x( 'Thailand', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Thailand', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ALPHAFAST' => _x( 'Alphafast', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CJ_KR' => _x( 'CJ Korea Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THA_DYNAMIC_LOGISTICS' => _x( 'Dynamic Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FASTRK_SERV' => _x( 'Fastrak Services', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FLASHEXPRESS' => _x( 'Flash Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NIM_EXPRESS' => _x( 'Nim Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NINJAVAN_THAI' => _x( 'Ninja van Thai', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SENDIT' => _x( 'Sendit', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SKYBOX' => _x( 'SKYBOX', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THA_THAILAND_POST' => _x( 'Thailand Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ALPHAFAST' => tr( 'Alphafast', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CJ_KR' => tr( 'CJ Korea Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THA_DYNAMIC_LOGISTICS' => tr( 'Dynamic Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FASTRK_SERV' => tr( 'Fastrak Services', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FLASHEXPRESS' => tr( 'Flash Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NIM_EXPRESS' => tr( 'Nim Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NINJAVAN_THAI' => tr( 'Ninja van Thai', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SENDIT' => tr( 'Sendit', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SKYBOX' => tr( 'SKYBOX', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THA_THAILAND_POST' => tr( 'Thailand Post', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'TR' => array( - 'name' => _x( 'Turkey', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Turkey', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'ASE' => _x( 'ASE KARGO', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CDEK_TR' => _x( 'CDEK TR', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PTS' => _x( 'PTS courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PTT_POST' => _x( 'PTT Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPENTEGRA' => _x( 'ShipEntegra', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YURTICI_KARGO' => _x( 'Yurtici Kargo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ASE' => tr( 'ASE KARGO', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CDEK_TR' => tr( 'CDEK TR', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PTS' => tr( 'PTS courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PTT_POST' => tr( 'PTT Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPENTEGRA' => tr( 'ShipEntegra', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YURTICI_KARGO' => tr( 'Yurtici Kargo', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'UA' => array( - 'name' => _x( 'Ukraine', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Ukraine', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'NOVA_POSHTA_INT' => _x( 'Nova Poshta (International)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NOVA_POSHTA' => _x( 'Nova Poshta (novaposhta.ua)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'POSTA_UKR' => _x( 'UkrPoshta', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NOVA_POSHTA_INT' => tr( 'Nova Poshta (International)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NOVA_POSHTA' => tr( 'Nova Poshta (novaposhta.ua)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'POSTA_UKR' => tr( 'UkrPoshta', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'AE' => array( - 'name' => _x( 'United Arab Emirates', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'United Arab Emirates', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'IBEONE' => _x( 'Beone Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MARA_XPRESS' => _x( 'Mara Xpress', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FETCHR_WEBHOOK' => _x( 'Mena 360 (Fetchr)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ONECLICK' => _x( 'One click delivery services', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SKYNET_UAE' => _x( 'SKYNET UAE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'IBEONE' => tr( 'Beone Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MARA_XPRESS' => tr( 'Mara Xpress', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FETCHR_WEBHOOK' => tr( 'Mena 360 (Fetchr)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ONECLICK' => tr( 'One click delivery services', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SKYNET_UAE' => tr( 'SKYNET UAE', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'GB' => array( - 'name' => _x( 'United Kingdom', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'United Kingdom', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'AMAZON' => _x( 'Amazon Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AO_COURIER' => _x( 'AO Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'APC_OVERNIGHT' => _x( 'APC overnight (apc-overnight.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'APC_OVERNIGHT_CONNUM' => _x( 'APC Overnight Consignment', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'APG' => _x( 'APG eCommerce Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ARK_LOGISTICS' => _x( 'ARK Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GB_ARROW' => _x( 'Arrow XL', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ASENDIA_UK' => _x( 'Asendia UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BH_WORLDWIDE' => _x( 'B&H Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BIRDSYSTEM' => _x( 'BirdSystem', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'BLUECARE' => _x( 'Bluecare Express Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CAE_DELIVERS' => _x( 'CAE Delivers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'CARIBOU' => _x( 'Caribou', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DAIGLOBALTRACK' => _x( 'DAI Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DELTEC_UK' => _x( 'Deltec Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_REFR' => _x( 'DHl (Reference number)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DHL_UK' => _x( 'dhl UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIAMOND_EUROGISTICS' => _x( 'Diamond Eurogistics Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DIRECTPARCELS' => _x( 'Direct Parcels', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DMS_MATRIX' => _x( 'DMSMatrix', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_LOCAL' => _x( 'DPD Local', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DPD_LOCAL_REF' => _x( 'DPD Local reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DX_SFTP' => _x( 'DX (SFTP)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'EU_FLEET_SOLUTIONS' => _x( 'EU Fleet Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FEDEX_UK' => _x( 'FedEx® UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'FURDECO' => _x( 'Furdeco', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GBA' => _x( 'GBA Services Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GEMWORLDWIDE' => _x( 'GEM Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HERMES' => _x( 'HermesWorld UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HOME_DELIVERY_SOLUTIONS' => _x( 'Home Delivery Solutions Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'INTERPARCEL_UK' => _x( 'Interparcel UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MYHERMES' => _x( 'MyHermes UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NATIONAL_SAMEDAY' => _x( 'National Sameday', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GB_NORSK' => _x( 'Norsk Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OCS_WORLDWIDE' => _x( 'OCS WORLDWIDE', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PALLETWAYS' => _x( 'Palletways', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GB_PANTHER' => _x( 'Panther', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PANTHER_REFERENCE' => _x( 'Panther Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCEL2GO' => _x( 'Parcel2Go', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PARCELINKLOGISTICS' => _x( 'Parcelink Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PLUS_LOG_UK' => _x( 'Plus UK Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RPD2MAN' => _x( 'RPD2man Deliveries', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SKYNET_UK' => _x( 'Skynet UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'AMAZON_FBA_SWISHIP' => _x( 'Swiship UK', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'THEDELIVERYGROUP' => _x( 'TDG – The Delivery Group', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PALLET_NETWORK' => _x( 'The Pallet Network', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_UK' => _x( 'TNT UK Limited (www.tnt.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TNT_UK_REFR' => _x( 'TNT UK Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GB_TUFFNELLS' => _x( 'Tuffnells Parcels Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TUFFNELLS_REFERENCE' => _x( 'Tuffnells Parcels Express- Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UK_UK_MAIL' => _x( 'UK mail (ukmail.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WHISTL' => _x( 'Whistl', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WNDIRECT' => _x( 'wnDirect', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UK_XDP' => _x( 'XDP Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XDP_UK_REFERENCE' => _x( 'XDP Express Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XPERT_DELIVERY' => _x( 'Xpert Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UK_YODEL' => _x( 'Yodel (www.yodel.co.uk)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AMAZON' => tr( 'Amazon Shipping', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AO_COURIER' => tr( 'AO Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'APC_OVERNIGHT' => tr( 'APC overnight (apc-overnight.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'APC_OVERNIGHT_CONNUM' => tr( 'APC Overnight Consignment', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'APG' => tr( 'APG eCommerce Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ARK_LOGISTICS' => tr( 'ARK Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GB_ARROW' => tr( 'Arrow XL', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ASENDIA_UK' => tr( 'Asendia UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BH_WORLDWIDE' => tr( 'B&H Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BIRDSYSTEM' => tr( 'BirdSystem', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'BLUECARE' => tr( 'Bluecare Express Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CAE_DELIVERS' => tr( 'CAE Delivers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CARIBOU' => tr( 'Caribou', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DAIGLOBALTRACK' => tr( 'DAI Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DELTEC_UK' => tr( 'Deltec Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_REFR' => tr( 'DHl (Reference number)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DHL_UK' => tr( 'dhl UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIAMOND_EUROGISTICS' => tr( 'Diamond Eurogistics Limited', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DIRECTPARCELS' => tr( 'Direct Parcels', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DMS_MATRIX' => tr( 'DMSMatrix', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_LOCAL' => tr( 'DPD Local', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DPD_LOCAL_REF' => tr( 'DPD Local reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DX_SFTP' => tr( 'DX (SFTP)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'EU_FLEET_SOLUTIONS' => tr( 'EU Fleet Solutions', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FEDEX_UK' => tr( 'FedEx® UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'FURDECO' => tr( 'Furdeco', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GBA' => tr( 'GBA Services Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GEMWORLDWIDE' => tr( 'GEM Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HERMES' => tr( 'HermesWorld UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HOME_DELIVERY_SOLUTIONS' => tr( 'Home Delivery Solutions Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'INTERPARCEL_UK' => tr( 'Interparcel UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MYHERMES' => tr( 'MyHermes UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NATIONAL_SAMEDAY' => tr( 'National Sameday', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GB_NORSK' => tr( 'Norsk Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OCS_WORLDWIDE' => tr( 'OCS WORLDWIDE', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PALLETWAYS' => tr( 'Palletways', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GB_PANTHER' => tr( 'Panther', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PANTHER_REFERENCE' => tr( 'Panther Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCEL2GO' => tr( 'Parcel2Go', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PARCELINKLOGISTICS' => tr( 'Parcelink Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PLUS_LOG_UK' => tr( 'Plus UK Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RPD2MAN' => tr( 'RPD2man Deliveries', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SKYNET_UK' => tr( 'Skynet UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'AMAZON_FBA_SWISHIP' => tr( 'Swiship UK', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'THEDELIVERYGROUP' => tr( 'TDG – The Delivery Group', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PALLET_NETWORK' => tr( 'The Pallet Network', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_UK' => tr( 'TNT UK Limited (www.tnt.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TNT_UK_REFR' => tr( 'TNT UK Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GB_TUFFNELLS' => tr( 'Tuffnells Parcels Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TUFFNELLS_REFERENCE' => tr( 'Tuffnells Parcels Express- Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UK_UK_MAIL' => tr( 'UK mail (ukmail.com)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WHISTL' => tr( 'Whistl', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WNDIRECT' => tr( 'wnDirect', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UK_XDP' => tr( 'XDP Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XDP_UK_REFERENCE' => tr( 'XDP Express Reference', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XPERT_DELIVERY' => tr( 'Xpert Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UK_YODEL' => tr( 'Yodel (www.yodel.co.uk)', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'US' => array( - 'name' => _x( 'United States', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'United States', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'GIO_EXPRESS' => _x( 'Gio Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOBALTRANZ' => _x( 'GlobalTranz', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GSI_EXPRESS' => _x( 'GSI EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GSO' => _x( 'GSO (GLS-USA)', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'HIPSHIPPER' => _x( 'Hipshipper', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'GLOBAL_IPARCEL' => _x( 'i-parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'DESCARTES' => _x( 'Innovel courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'US_LASERSHIP' => _x( 'LaserShip', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LONESTAR' => _x( 'Lone Star Overnight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'MAILAMERICAS' => _x( 'MailAmericas', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NEWEGGEXPRESS' => _x( 'Newegg Express', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'US_OLD_DOMINION' => _x( 'Old Dominion Freight Line', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'OSM_WORLDWIDE' => _x( 'OSM Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PCFCORP' => _x( 'PCF Final Mile', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PILOT_FREIGHT' => _x( 'Pilot Freight Services', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PITNEY_BOWES' => _x( 'Pitney Bowes', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'PITTOHIO' => _x( 'PITT OHIO', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'QWINTRY' => _x( 'Qwintry Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'RL_US' => _x( 'RL Carriers', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SAIA_FREIGHT' => _x( 'Saia LTL Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SHIPTOR' => _x( 'Shiptor', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SONICTL' => _x( 'Sonic Transportation & Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SEFL' => _x( 'Southeastern Freight Lines', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SPEEDEE' => _x( 'Spee-Dee Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'SUTTON' => _x( 'Sutton Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TAZMANIAN_FREIGHT' => _x( 'Tazmanian Freight Systems', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TFORCE_FINALMILE' => _x( 'TForce Final Mile', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'LOGISTYX_TRANSGROUP' => _x( 'Transgroup courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'TRUMPCARD' => _x( 'TRUMPCARD LLC', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'USPS' => _x( 'United States Postal Service', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'UPS_MAIL_INNOVATIONS' => _x( 'UPS Mail Innovations', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'USF_REDDAWAY' => _x( 'USF Reddaway', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'USHIP' => _x( 'uShip courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WESTBANK_COURIER' => _x( 'West Bank Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WESTGATE_GL' => _x( 'Westgate Global', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'WIZMO' => _x( 'Wizmo', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'XPO_LOGISTICS' => _x( 'XPO logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'YAKIT' => _x( 'Yakit courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'US_YRC' => _x( 'YRC courier', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'ZINC' => _x( 'Zinc courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GIO_EXPRESS' => tr( 'Gio Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOBALTRANZ' => tr( 'GlobalTranz', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GSI_EXPRESS' => tr( 'GSI EXPRESS', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GSO' => tr( 'GSO (GLS-USA)', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'HIPSHIPPER' => tr( 'Hipshipper', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'GLOBAL_IPARCEL' => tr( 'i-parcel', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'DESCARTES' => tr( 'Innovel courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'US_LASERSHIP' => tr( 'LaserShip', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LONESTAR' => tr( 'Lone Star Overnight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'MAILAMERICAS' => tr( 'MailAmericas', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NEWEGGEXPRESS' => tr( 'Newegg Express', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'US_OLD_DOMINION' => tr( 'Old Dominion Freight Line', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'OSM_WORLDWIDE' => tr( 'OSM Worldwide', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PCFCORP' => tr( 'PCF Final Mile', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PILOT_FREIGHT' => tr( 'Pilot Freight Services', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PITNEY_BOWES' => tr( 'Pitney Bowes', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'PITTOHIO' => tr( 'PITT OHIO', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'QWINTRY' => tr( 'Qwintry Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'RL_US' => tr( 'RL Carriers', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SAIA_FREIGHT' => tr( 'Saia LTL Freight', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SHIPTOR' => tr( 'Shiptor', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SONICTL' => tr( 'Sonic Transportation & Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SEFL' => tr( 'Southeastern Freight Lines', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SPEEDEE' => tr( 'Spee-Dee Delivery', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'SUTTON' => tr( 'Sutton Transport', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TAZMANIAN_FREIGHT' => tr( 'Tazmanian Freight Systems', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TFORCE_FINALMILE' => tr( 'TForce Final Mile', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'LOGISTYX_TRANSGROUP' => tr( 'Transgroup courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'TRUMPCARD' => tr( 'TRUMPCARD LLC', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'USPS' => tr( 'United States Postal Service', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'UPS_MAIL_INNOVATIONS' => tr( 'UPS Mail Innovations', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'USF_REDDAWAY' => tr( 'USF Reddaway', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'USHIP' => tr( 'uShip courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WESTBANK_COURIER' => tr( 'West Bank Courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WESTGATE_GL' => tr( 'Westgate Global', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'WIZMO' => tr( 'Wizmo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'XPO_LOGISTICS' => tr( 'XPO logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'YAKIT' => tr( 'Yakit courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'US_YRC' => tr( 'YRC courier', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'ZINC' => tr( 'Zinc courier', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'URY' => array( - 'name' => _x( 'Uruguay', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Uruguay', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'CORREO_UY' => _x( 'Correo Uruguayo', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'CORREO_UY' => tr( 'Correo Uruguayo', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), 'VN' => array( - 'name' => _x( 'Vietnam', 'Name of carrier country', 'woocommerce-paypal-payments' ), + 'name' => tr( 'Vietnam', 'Name of carrier country', 'woocommerce-paypal-payments' ), 'items' => array( - 'JTEXPRESS_VN' => _x( 'J&T Express Vietnam', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'KERRYTTC_VN' => _x( 'Kerry Express (Vietnam) Co Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'NTLOGISTICS_VN' => _x( 'Nhat Tin Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VNM_VIETNAM_POST' => _x( 'Vietnam Post', 'Name of carrier', 'woocommerce-paypal-payments' ), - 'VNM_VIETTELPOST' => _x( 'ViettelPost', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'JTEXPRESS_VN' => tr( 'J&T Express Vietnam', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'KERRYTTC_VN' => tr( 'Kerry Express (Vietnam) Co Ltd', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'NTLOGISTICS_VN' => tr( 'Nhat Tin Logistics', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VNM_VIETNAM_POST' => tr( 'Vietnam Post', 'Name of carrier', 'woocommerce-paypal-payments' ), + 'VNM_VIETTELPOST' => tr( 'ViettelPost', 'Name of carrier', 'woocommerce-paypal-payments' ), ), ), ) diff --git a/modules/ppcp-subscription/.babelrc b/modules/ppcp-paypal-subscriptions/.babelrc similarity index 100% rename from modules/ppcp-subscription/.babelrc rename to modules/ppcp-paypal-subscriptions/.babelrc diff --git a/modules/ppcp-paypal-subscriptions/.gitignore b/modules/ppcp-paypal-subscriptions/.gitignore new file mode 100644 index 000000000..0bd2b9f58 --- /dev/null +++ b/modules/ppcp-paypal-subscriptions/.gitignore @@ -0,0 +1,3 @@ +node_modules +assets/js +assets/css diff --git a/modules/ppcp-paypal-subscriptions/composer.json b/modules/ppcp-paypal-subscriptions/composer.json new file mode 100644 index 000000000..161c4b9ce --- /dev/null +++ b/modules/ppcp-paypal-subscriptions/composer.json @@ -0,0 +1,17 @@ +{ + "name": "woocommerce/ppcp-paypal-subscriptions", + "type": "dhii-mod", + "description": "Module for PayPal Subscriptions API integration", + "license": "GPL-2.0", + "require": { + "php": "^7.2 | ^8.0", + "dhii/module-interface": "^0.3.0-alpha1" + }, + "autoload": { + "psr-4": { + "WooCommerce\\PayPalCommerce\\PayPalSubscriptions\\": "src" + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/modules/ppcp-paypal-subscriptions/extensions.php b/modules/ppcp-paypal-subscriptions/extensions.php new file mode 100644 index 000000000..fc91cd245 --- /dev/null +++ b/modules/ppcp-paypal-subscriptions/extensions.php @@ -0,0 +1,14 @@ + static function ( ContainerInterface $container ): DeactivatePlanEndpoint { + return new DeactivatePlanEndpoint( + $container->get( 'button.request-data' ), + $container->get( 'api.endpoint.billing-plans' ) + ); + }, + 'paypal-subscriptions.api-handler' => static function( ContainerInterface $container ): SubscriptionsApiHandler { + return new SubscriptionsApiHandler( + $container->get( 'api.endpoint.catalog-products' ), + $container->get( 'api.factory.product' ), + $container->get( 'api.endpoint.billing-plans' ), + $container->get( 'api.factory.billing-cycle' ), + $container->get( 'api.factory.payment-preferences' ), + $container->get( 'api.shop.currency' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, + 'paypal-subscriptions.module.url' => static function ( ContainerInterface $container ): string { + /** + * The path cannot be false. + * + * @psalm-suppress PossiblyFalseArgument + */ + return plugins_url( + '/modules/ppcp-paypal-subscriptions/', + dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php' + ); + }, +); diff --git a/modules/ppcp-subscription/src/DeactivatePlanEndpoint.php b/modules/ppcp-paypal-subscriptions/src/DeactivatePlanEndpoint.php similarity index 94% rename from modules/ppcp-subscription/src/DeactivatePlanEndpoint.php rename to modules/ppcp-paypal-subscriptions/src/DeactivatePlanEndpoint.php index fe10c0638..4bbdc4e28 100644 --- a/modules/ppcp-subscription/src/DeactivatePlanEndpoint.php +++ b/modules/ppcp-paypal-subscriptions/src/DeactivatePlanEndpoint.php @@ -2,12 +2,12 @@ /** * The deactivate Subscription Plan Endpoint. * - * @package WooCommerce\PayPalCommerce\OrderTracking\Endpoint + * @package WooCommerce\PayPalCommerce\WcSubscriptions */ declare( strict_types=1 ); -namespace WooCommerce\PayPalCommerce\Subscription; +namespace WooCommerce\PayPalCommerce\PayPalSubscriptions; use Exception; use WC_Product; diff --git a/modules/ppcp-subscription/src/SubscriptionModule.php b/modules/ppcp-paypal-subscriptions/src/PayPalSubscriptionsModule.php similarity index 69% rename from modules/ppcp-subscription/src/SubscriptionModule.php rename to modules/ppcp-paypal-subscriptions/src/PayPalSubscriptionsModule.php index f99a4fd8d..a69aaefef 100644 --- a/modules/ppcp-subscription/src/SubscriptionModule.php +++ b/modules/ppcp-paypal-subscriptions/src/PayPalSubscriptionsModule.php @@ -1,50 +1,40 @@ renew( $order, $c ); - }, - 10, - 2 - ); - - add_action( - 'woocommerce_scheduled_subscription_payment_' . CreditCardGateway::ID, - function ( $amount, $order ) use ( $c ) { - $this->renew( $order, $c ); - }, - 10, - 2 - ); - - add_action( - 'woocommerce_subscription_payment_complete', - function ( $subscription ) use ( $c ) { - if ( ! in_array( $subscription->get_payment_method(), array( PayPalGateway::ID, CreditCardGateway::ID, CardButtonGateway::ID ), true ) ) { - return; - } - - $paypal_subscription_id = $subscription->get_meta( 'ppcp_subscription' ) ?? ''; - if ( $paypal_subscription_id ) { - return; - } - - $payment_token_repository = $c->get( 'vaulting.repository.payment-token' ); - $logger = $c->get( 'woocommerce.logger.woocommerce' ); - - $this->add_payment_token_id( $subscription, $payment_token_repository, $logger ); - - if ( count( $subscription->get_related_orders() ) === 1 ) { - $parent_order = $subscription->get_parent(); - if ( is_a( $parent_order, WC_Order::class ) ) { - $order_repository = $c->get( 'api.repository.order' ); - $order = $order_repository->for_wc_order( $parent_order ); - $transaction_id = $this->get_paypal_order_transaction_id( $order ); - if ( $transaction_id ) { - $subscription->update_meta_data( 'ppcp_previous_transaction_reference', $transaction_id ); - $subscription->save(); - } - } - } - } - ); - - add_filter( - 'woocommerce_gateway_description', - function ( $description, $id ) use ( $c ) { - $payment_token_repository = $c->get( 'vaulting.repository.payment-token' ); - $settings = $c->get( 'wcgateway.settings' ); - $subscription_helper = $c->get( 'subscription.helper' ); - - return $this->display_saved_paypal_payments( $settings, (string) $id, $payment_token_repository, (string) $description, $subscription_helper ); - }, - 10, - 2 - ); - - add_filter( - 'woocommerce_credit_card_form_fields', - function ( $default_fields, $id ) use ( $c ) { - $payment_token_repository = $c->get( 'vaulting.repository.payment-token' ); - $settings = $c->get( 'wcgateway.settings' ); - $subscription_helper = $c->get( 'subscription.helper' ); - - return $this->display_saved_credit_cards( $settings, $id, $payment_token_repository, $default_fields, $subscription_helper ); - }, - 20, - 2 - ); - - add_filter( - 'ppcp_create_order_request_body_data', - function( array $data ) use ( $c ) { - // phpcs:ignore WordPress.Security.NonceVerification.Missing - $wc_order_action = wc_clean( wp_unslash( $_POST['wc_order_action'] ?? '' ) ); - - // phpcs:ignore WordPress.Security.NonceVerification.Missing - $subscription_id = wc_clean( wp_unslash( $_POST['post_ID'] ?? '' ) ); - if ( ! $subscription_id ) { - return $data; - } - $subscription = wc_get_order( $subscription_id ); - if ( ! is_a( $subscription, WC_Subscription::class ) ) { - return $data; - } - - if ( - $wc_order_action === 'wcs_process_renewal' && $subscription->get_payment_method() === CreditCardGateway::ID - && isset( $data['payment_source']['token'] ) && $data['payment_source']['token']['type'] === 'PAYMENT_METHOD_TOKEN' - && isset( $data['payment_source']['token']['source']->card ) - ) { - $data['payment_source'] = array( - 'card' => array( - 'vault_id' => $data['payment_source']['token']['id'], - 'stored_credential' => array( - 'payment_initiator' => 'MERCHANT', - 'payment_type' => 'RECURRING', - 'usage' => 'SUBSEQUENT', - ), - ), - ); - - $previous_transaction_reference = $subscription->get_meta( 'ppcp_previous_transaction_reference' ); - if ( $previous_transaction_reference ) { - $data['payment_source']['card']['stored_credential']['previous_transaction_reference'] = $previous_transaction_reference; - } - } - - return $data; - } - ); - - $this->subscriptions_api_integration( $c ); - - add_action( - 'admin_enqueue_scripts', - /** - * Param types removed to avoid third-party issues. - * - * @psalm-suppress MissingClosureParamType - */ - function( $hook ) use ( $c ) { - if ( ! is_string( $hook ) ) { - return; - } - $settings = $c->get( 'wcgateway.settings' ); - $subscription_mode = $settings->has( 'subscriptions_mode' ) ? $settings->get( 'subscriptions_mode' ) : ''; - if ( $hook !== 'post.php' || $subscription_mode !== 'subscriptions_api' ) { - return; - } - - //phpcs:disable WordPress.Security.NonceVerification.Recommended - $post_id = wc_clean( wp_unslash( $_GET['post'] ?? '' ) ); - $product = wc_get_product( $post_id ); - if ( ! ( is_a( $product, WC_Product::class ) ) ) { - return; - } - - $subscriptions_helper = $c->get( 'subscription.helper' ); - assert( $subscriptions_helper instanceof SubscriptionHelper ); - - if ( - ! $subscriptions_helper->plugin_is_active() - || ! ( - is_a( $product, WC_Product_Subscription::class ) - || is_a( $product, WC_Product_Variable_Subscription::class ) - || is_a( $product, WC_Product_Subscription_Variation::class ) - ) - || ! WC_Subscriptions_Product::is_subscription( $product ) - ) { - return; - } - - $module_url = $c->get( 'subscription.module.url' ); - wp_enqueue_script( - 'ppcp-paypal-subscription', - untrailingslashit( $module_url ) . '/assets/js/paypal-subscription.js', - array( 'jquery' ), - $c->get( 'ppcp.asset-version' ), - true - ); - - $products = array( $this->set_product_config( $product ) ); - if ( $product->get_type() === 'variable-subscription' ) { - $products = array(); - - /** - * Suppress pslam. - * - * @psalm-suppress TypeDoesNotContainType - * - * WC_Product_Variable_Subscription extends WC_Product_Variable. - */ - assert( $product instanceof WC_Product_Variable ); - $available_variations = $product->get_available_variations(); - foreach ( $available_variations as $variation ) { - /** - * The method is defined in WooCommerce. - * - * @psalm-suppress UndefinedMethod - */ - $variation = wc_get_product_object( 'variation', $variation['variation_id'] ); - $products[] = $this->set_product_config( $variation ); - } - } - - wp_localize_script( - 'ppcp-paypal-subscription', - 'PayPalCommerceGatewayPayPalSubscriptionProducts', - $products - ); - } - ); - - $endpoint = $c->get( 'subscription.deactivate-plan-endpoint' ); - assert( $endpoint instanceof DeactivatePlanEndpoint ); - add_action( - 'wc_ajax_' . DeactivatePlanEndpoint::ENDPOINT, - array( $endpoint, 'handle_request' ) - ); - - add_action( - 'add_meta_boxes', - /** - * Param types removed to avoid third-party issues. - * - * @psalm-suppress MissingClosureParamType - */ - function( string $post_type, $post_or_order_object ) use ( $c ) { - if ( ! function_exists( 'wcs_get_subscription' ) ) { - return; - } - - $order = ( $post_or_order_object instanceof WP_Post ) - ? wc_get_order( $post_or_order_object->ID ) - : $post_or_order_object; - - if ( ! is_a( $order, WC_Order::class ) ) { - return; - } - - $subscription = wcs_get_subscription( $order->get_id() ); - if ( ! is_a( $subscription, WC_Subscription::class ) ) { - return; - } - - $subscription_id = $subscription->get_meta( 'ppcp_subscription' ) ?? ''; - if ( ! $subscription_id ) { - return; - } - - $screen_id = wc_get_page_screen_id( 'shop_subscription' ); - remove_meta_box( 'woocommerce-subscription-schedule', $screen_id, 'side' ); - - $environment = $c->get( 'onboarding.environment' ); - add_meta_box( - 'ppcp_paypal_subscription', - __( 'PayPal Subscription', 'woocommerce-paypal-payments' ), - function() use ( $subscription_id, $environment ) { - $host = $environment->current_environment_is( Environment::SANDBOX ) ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com'; - $url = trailingslashit( $host ) . 'billing/subscriptions/' . $subscription_id; - echo '

' . esc_html__( 'This subscription is linked to a PayPal Subscription, Cancel it to unlink.', 'woocommerce-paypal-payments' ) . '

'; - echo '

' . esc_html__( 'Subscription:', 'woocommerce-paypal-payments' ) . ' ' . esc_attr( $subscription_id ) . '

'; - }, - $post_type, - 'side' - ); - - }, - 30, - 2 - ); - - add_action( - 'action_scheduler_before_execute', - /** - * Param types removed to avoid third-party issues. - * - * @psalm-suppress MissingClosureParamType - */ - function( $action_id ) { - /** - * Class exist in WooCommerce. - * - * @psalm-suppress UndefinedClass - */ - $store = ActionScheduler_Store::instance(); - $action = $store->fetch_action( $action_id ); - - $subscription_id = $action->get_args()['subscription_id'] ?? null; - if ( $subscription_id ) { - $subscription = wcs_get_subscription( $subscription_id ); - if ( is_a( $subscription, WC_Subscription::class ) ) { - $paypal_subscription_id = $subscription->get_meta( 'ppcp_subscription' ) ?? ''; - if ( $paypal_subscription_id ) { - as_unschedule_action( $action->get_hook(), $action->get_args() ); - } - } - } - } - ); - } - - /** - * Returns the key for the module. - * - * @return string|void - */ - public function getKey() { - } - - /** - * Handles a Subscription product renewal. - * - * @param \WC_Order $order WooCommerce order. - * @param ContainerInterface|null $container The container. - * @return void - */ - protected function renew( $order, $container ) { - if ( ! ( $order instanceof \WC_Order ) ) { - return; - } - - $handler = $container->get( 'subscription.renewal-handler' ); - $handler->renew( $order ); - } - - /** - * Adds Payment token ID to subscription. - * - * @param \WC_Subscription $subscription The subscription. - * @param PaymentTokenRepository $payment_token_repository The payment repository. - * @param LoggerInterface $logger The logger. - */ - protected function add_payment_token_id( - \WC_Subscription $subscription, - PaymentTokenRepository $payment_token_repository, - LoggerInterface $logger - ) { - try { - $tokens = $payment_token_repository->all_for_user_id( $subscription->get_customer_id() ); - if ( $tokens ) { - $latest_token_id = end( $tokens )->id() ? end( $tokens )->id() : ''; - $subscription->update_meta_data( 'payment_token_id', $latest_token_id ); - $subscription->save(); - } - } catch ( RuntimeException $error ) { - $message = sprintf( - // translators: %1$s is the payment token Id, %2$s is the error message. - __( - 'Could not add token Id to subscription %1$s: %2$s', - 'woocommerce-paypal-payments' - ), - $subscription->get_id(), - $error->getMessage() - ); - - $logger->log( 'warning', $message ); - } - } - - /** - * Displays saved PayPal payments. - * - * @param Settings $settings The settings. - * @param string $id The payment gateway Id. - * @param PaymentTokenRepository $payment_token_repository The payment token repository. - * @param string $description The payment gateway description. - * @param SubscriptionHelper $subscription_helper The subscription helper. - * @return string - */ - protected function display_saved_paypal_payments( - Settings $settings, - string $id, - PaymentTokenRepository $payment_token_repository, - string $description, - SubscriptionHelper $subscription_helper - ): string { - if ( $settings->has( 'vault_enabled' ) - && $settings->get( 'vault_enabled' ) - && PayPalGateway::ID === $id - && $subscription_helper->is_subscription_change_payment() - ) { - $tokens = $payment_token_repository->all_for_user_id( get_current_user_id() ); - if ( ! $tokens || ! $payment_token_repository->tokens_contains_paypal( $tokens ) ) { - return esc_html__( - 'No PayPal payments saved, in order to use a saved payment you first need to create it through a purchase.', - 'woocommerce-paypal-payments' - ); - } - - $output = sprintf( - '

'; - - return $output; - } - - return $description; - } - - /** - * Displays saved credit cards. - * - * @param Settings $settings The settings. - * @param string $id The payment gateway Id. - * @param PaymentTokenRepository $payment_token_repository The payment token repository. - * @param array $default_fields Default payment gateway fields. - * @param SubscriptionHelper $subscription_helper The subscription helper. - * @return array|mixed|string - * @throws NotFoundException When setting was not found. - */ - protected function display_saved_credit_cards( - Settings $settings, - string $id, - PaymentTokenRepository $payment_token_repository, - array $default_fields, - SubscriptionHelper $subscription_helper - ) { - - if ( $settings->has( 'vault_enabled_dcc' ) - && $settings->get( 'vault_enabled_dcc' ) - && $subscription_helper->is_subscription_change_payment() - && CreditCardGateway::ID === $id - ) { - $tokens = $payment_token_repository->all_for_user_id( get_current_user_id() ); - if ( ! $tokens || ! $payment_token_repository->tokens_contains_card( $tokens ) ) { - $default_fields = array(); - $default_fields['saved-credit-card'] = esc_html__( - 'No Credit Card saved, in order to use a saved Credit Card you first need to create it through a purchase.', - 'woocommerce-paypal-payments' - ); - return $default_fields; - } - - $output = sprintf( - '

'; - - $default_fields = array(); - $default_fields['saved-credit-card'] = $output; - return $default_fields; - } - - return $default_fields; - } - - /** - * Adds PayPal subscriptions API integration. - * - * @param ContainerInterface $c The container. - * @return void - * @throws Exception When something went wrong. - */ - protected function subscriptions_api_integration( ContainerInterface $c ): void { add_action( 'save_post', /** @@ -554,7 +80,7 @@ class SubscriptionModule implements ModuleInterface { return; } - $subscriptions_api_handler = $c->get( 'subscription.api-handler' ); + $subscriptions_api_handler = $c->get( 'paypal-subscriptions.api-handler' ); assert( $subscriptions_api_handler instanceof SubscriptionsApiHandler ); $this->update_subscription_product_meta( $product, $subscriptions_api_handler ); }, @@ -571,7 +97,7 @@ class SubscriptionModule implements ModuleInterface { function( $variation_id ) use ( $c ) { $wcsnonce_save_variations = wc_clean( wp_unslash( $_POST['_wcsnonce_save_variations'] ?? '' ) ); - $subscriptions_helper = $c->get( 'subscription.helper' ); + $subscriptions_helper = $c->get( 'wc-subscriptions.helper' ); assert( $subscriptions_helper instanceof SubscriptionHelper ); if ( @@ -588,7 +114,7 @@ class SubscriptionModule implements ModuleInterface { return; } - $subscriptions_api_handler = $c->get( 'subscription.api-handler' ); + $subscriptions_api_handler = $c->get( 'paypal-subscriptions.api-handler' ); assert( $subscriptions_api_handler instanceof SubscriptionsApiHandler ); $this->update_subscription_product_meta( $product, $subscriptions_api_handler ); }, @@ -947,6 +473,236 @@ class SubscriptionModule implements ModuleInterface { 10, 3 ); + + add_action( + 'admin_enqueue_scripts', + /** + * Param types removed to avoid third-party issues. + * + * @psalm-suppress MissingClosureParamType + */ + function( $hook ) use ( $c ) { + if ( ! is_string( $hook ) ) { + return; + } + $settings = $c->get( 'wcgateway.settings' ); + $subscription_mode = $settings->has( 'subscriptions_mode' ) ? $settings->get( 'subscriptions_mode' ) : ''; + if ( $hook !== 'post.php' || $subscription_mode !== 'subscriptions_api' ) { + return; + } + + //phpcs:disable WordPress.Security.NonceVerification.Recommended + $post_id = wc_clean( wp_unslash( $_GET['post'] ?? '' ) ); + $product = wc_get_product( $post_id ); + if ( ! ( is_a( $product, WC_Product::class ) ) ) { + return; + } + + $subscriptions_helper = $c->get( 'wc-subscriptions.helper' ); + assert( $subscriptions_helper instanceof SubscriptionHelper ); + + if ( + ! $subscriptions_helper->plugin_is_active() + || ! ( + is_a( $product, WC_Product_Subscription::class ) + || is_a( $product, WC_Product_Variable_Subscription::class ) + || is_a( $product, WC_Product_Subscription_Variation::class ) + ) + || ! WC_Subscriptions_Product::is_subscription( $product ) + ) { + return; + } + + $module_url = $c->get( 'paypal-subscriptions.module.url' ); + wp_enqueue_script( + 'ppcp-paypal-subscription', + untrailingslashit( $module_url ) . '/assets/js/paypal-subscription.js', + array( 'jquery' ), + $c->get( 'ppcp.asset-version' ), + true + ); + + $products = array( $this->set_product_config( $product ) ); + if ( $product->get_type() === 'variable-subscription' ) { + $products = array(); + + /** + * Suppress pslam. + * + * @psalm-suppress TypeDoesNotContainType + * + * WC_Product_Variable_Subscription extends WC_Product_Variable. + */ + assert( $product instanceof WC_Product_Variable ); + $available_variations = $product->get_available_variations(); + foreach ( $available_variations as $variation ) { + /** + * The method is defined in WooCommerce. + * + * @psalm-suppress UndefinedMethod + */ + $variation = wc_get_product_object( 'variation', $variation['variation_id'] ); + $products[] = $this->set_product_config( $variation ); + } + } + + wp_localize_script( + 'ppcp-paypal-subscription', + 'PayPalCommerceGatewayPayPalSubscriptionProducts', + $products + ); + } + ); + + $endpoint = $c->get( 'paypal-subscriptions.deactivate-plan-endpoint' ); + assert( $endpoint instanceof DeactivatePlanEndpoint ); + add_action( + 'wc_ajax_' . DeactivatePlanEndpoint::ENDPOINT, + array( $endpoint, 'handle_request' ) + ); + + add_action( + 'add_meta_boxes', + /** + * Param types removed to avoid third-party issues. + * + * @psalm-suppress MissingClosureParamType + */ + function( string $post_type, $post_or_order_object ) use ( $c ) { + if ( ! function_exists( 'wcs_get_subscription' ) ) { + return; + } + + $order = ( $post_or_order_object instanceof WP_Post ) + ? wc_get_order( $post_or_order_object->ID ) + : $post_or_order_object; + + if ( ! is_a( $order, WC_Order::class ) ) { + return; + } + + $subscription = wcs_get_subscription( $order->get_id() ); + if ( ! is_a( $subscription, WC_Subscription::class ) ) { + return; + } + + $subscription_id = $subscription->get_meta( 'ppcp_subscription' ) ?? ''; + if ( ! $subscription_id ) { + return; + } + + $screen_id = wc_get_page_screen_id( 'shop_subscription' ); + remove_meta_box( 'woocommerce-subscription-schedule', $screen_id, 'side' ); + + $host = $c->get( 'api.paypal-website-url' ); + + add_meta_box( + 'ppcp_paypal_subscription', + __( 'PayPal Subscription', 'woocommerce-paypal-payments' ), + function() use ( $subscription_id, $host ) { + $url = trailingslashit( $host ) . 'billing/subscriptions/' . $subscription_id; + echo '

' . esc_html__( 'This subscription is linked to a PayPal Subscription, Cancel it to unlink.', 'woocommerce-paypal-payments' ) . '

'; + echo '

' . esc_html__( 'Subscription:', 'woocommerce-paypal-payments' ) . ' ' . esc_attr( $subscription_id ) . '

'; + }, + $post_type, + 'side' + ); + + }, + 30, + 2 + ); + + add_action( + 'action_scheduler_before_execute', + /** + * Param types removed to avoid third-party issues. + * + * @psalm-suppress MissingClosureParamType + */ + function( $action_id ) { + /** + * Class exist in WooCommerce. + * + * @psalm-suppress UndefinedClass + */ + $store = ActionScheduler_Store::instance(); + $action = $store->fetch_action( $action_id ); + + $subscription_id = $action->get_args()['subscription_id'] ?? null; + if ( $subscription_id ) { + $subscription = wcs_get_subscription( $subscription_id ); + if ( is_a( $subscription, WC_Subscription::class ) ) { + $paypal_subscription_id = $subscription->get_meta( 'ppcp_subscription' ) ?? ''; + if ( $paypal_subscription_id ) { + as_unschedule_action( $action->get_hook(), $action->get_args() ); + } + } + } + } + ); + } + + /** + * Updates subscription product meta. + * + * @param WC_Product $product The product. + * @param SubscriptionsApiHandler $subscriptions_api_handler The subscription api handler. + * @return void + */ + private function update_subscription_product_meta( WC_Product $product, SubscriptionsApiHandler $subscriptions_api_handler ): void { + // phpcs:ignore WordPress.Security.NonceVerification + $enable_subscription_product = wc_clean( wp_unslash( $_POST['_ppcp_enable_subscription_product'] ?? '' ) ); + $product->update_meta_data( '_ppcp_enable_subscription_product', $enable_subscription_product ); + $product->save(); + + if ( ( $product->get_type() === 'subscription' || $product->get_type() === 'subscription_variation' ) && $enable_subscription_product === 'yes' ) { + if ( $product->meta_exists( 'ppcp_subscription_product' ) && $product->meta_exists( 'ppcp_subscription_plan' ) ) { + $subscriptions_api_handler->update_product( $product ); + $subscriptions_api_handler->update_plan( $product ); + return; + } + + if ( ! $product->meta_exists( 'ppcp_subscription_product' ) ) { + $subscriptions_api_handler->create_product( $product ); + } + + if ( $product->meta_exists( 'ppcp_subscription_product' ) && ! $product->meta_exists( 'ppcp_subscription_plan' ) ) { + // phpcs:ignore WordPress.Security.NonceVerification + $subscription_plan_name = wc_clean( wp_unslash( $_POST['_ppcp_subscription_plan_name'] ?? '' ) ); + if ( ! is_string( $subscription_plan_name ) ) { + return; + } + + $product->update_meta_data( '_ppcp_subscription_plan_name', $subscription_plan_name ); + $product->save(); + + $subscriptions_api_handler->create_plan( $subscription_plan_name, $product ); + } + } + } + + /** + * Returns subscription product configuration. + * + * @param WC_Product $product The product. + * @return array + */ + private function set_product_config( WC_Product $product ): array { + $plan = $product->get_meta( 'ppcp_subscription_plan' ) ?? array(); + $plan_id = $plan['id'] ?? ''; + + return array( + 'product_connected' => $product->get_meta( '_ppcp_enable_subscription_product' ) ?? '', + 'plan_id' => $plan_id, + 'product_id' => $product->get_id(), + 'ajax' => array( + 'deactivate_plan' => array( + 'endpoint' => \WC_AJAX::get_endpoint( DeactivatePlanEndpoint::ENDPOINT ), + 'nonce' => wp_create_nonce( DeactivatePlanEndpoint::ENDPOINT ), + ), + ), + ); } /** @@ -1019,66 +775,4 @@ class SubscriptionModule implements ModuleInterface { ); } } - - /** - * Updates subscription product meta. - * - * @param WC_Product $product The product. - * @param SubscriptionsApiHandler $subscriptions_api_handler The subscription api handler. - * @return void - */ - private function update_subscription_product_meta( WC_Product $product, SubscriptionsApiHandler $subscriptions_api_handler ): void { - // phpcs:ignore WordPress.Security.NonceVerification - $enable_subscription_product = wc_clean( wp_unslash( $_POST['_ppcp_enable_subscription_product'] ?? '' ) ); - $product->update_meta_data( '_ppcp_enable_subscription_product', $enable_subscription_product ); - $product->save(); - - if ( ( $product->get_type() === 'subscription' || $product->get_type() === 'subscription_variation' ) && $enable_subscription_product === 'yes' ) { - if ( $product->meta_exists( 'ppcp_subscription_product' ) && $product->meta_exists( 'ppcp_subscription_plan' ) ) { - $subscriptions_api_handler->update_product( $product ); - $subscriptions_api_handler->update_plan( $product ); - return; - } - - if ( ! $product->meta_exists( 'ppcp_subscription_product' ) ) { - $subscriptions_api_handler->create_product( $product ); - } - - if ( $product->meta_exists( 'ppcp_subscription_product' ) && ! $product->meta_exists( 'ppcp_subscription_plan' ) ) { - // phpcs:ignore WordPress.Security.NonceVerification - $subscription_plan_name = wc_clean( wp_unslash( $_POST['_ppcp_subscription_plan_name'] ?? '' ) ); - if ( ! is_string( $subscription_plan_name ) ) { - return; - } - - $product->update_meta_data( '_ppcp_subscription_plan_name', $subscription_plan_name ); - $product->save(); - - $subscriptions_api_handler->create_plan( $subscription_plan_name, $product ); - } - } - } - - /** - * Returns subscription product configuration. - * - * @param WC_Product $product The product. - * @return array - */ - private function set_product_config( WC_Product $product ): array { - $plan = $product->get_meta( 'ppcp_subscription_plan' ) ?? array(); - $plan_id = $plan['id'] ?? ''; - - return array( - 'product_connected' => $product->get_meta( '_ppcp_enable_subscription_product' ) ?? '', - 'plan_id' => $plan_id, - 'product_id' => $product->get_id(), - 'ajax' => array( - 'deactivate_plan' => array( - 'endpoint' => \WC_AJAX::get_endpoint( DeactivatePlanEndpoint::ENDPOINT ), - 'nonce' => wp_create_nonce( DeactivatePlanEndpoint::ENDPOINT ), - ), - ), - ); - } } diff --git a/modules/ppcp-subscription/src/SubscriptionsApiHandler.php b/modules/ppcp-paypal-subscriptions/src/SubscriptionsApiHandler.php similarity index 98% rename from modules/ppcp-subscription/src/SubscriptionsApiHandler.php rename to modules/ppcp-paypal-subscriptions/src/SubscriptionsApiHandler.php index 2d8bb1d7b..4d56558ab 100644 --- a/modules/ppcp-subscription/src/SubscriptionsApiHandler.php +++ b/modules/ppcp-paypal-subscriptions/src/SubscriptionsApiHandler.php @@ -2,12 +2,12 @@ /** * The subscription module. * - * @package WooCommerce\PayPalCommerce\Subscription + * @package WooCommerce\PayPalCommerce\WcSubscriptions */ declare(strict_types=1); -namespace WooCommerce\PayPalCommerce\Subscription; +namespace WooCommerce\PayPalCommerce\PayPalSubscriptions; use Psr\Log\LoggerInterface; use WC_Product; diff --git a/modules/ppcp-subscription/webpack.config.js b/modules/ppcp-paypal-subscriptions/webpack.config.js similarity index 100% rename from modules/ppcp-subscription/webpack.config.js rename to modules/ppcp-paypal-subscriptions/webpack.config.js diff --git a/modules/ppcp-subscription/yarn.lock b/modules/ppcp-paypal-subscriptions/yarn.lock similarity index 100% rename from modules/ppcp-subscription/yarn.lock rename to modules/ppcp-paypal-subscriptions/yarn.lock diff --git a/modules/ppcp-save-payment-methods/.babelrc b/modules/ppcp-save-payment-methods/.babelrc new file mode 100644 index 000000000..822778e6c --- /dev/null +++ b/modules/ppcp-save-payment-methods/.babelrc @@ -0,0 +1,14 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "useBuiltIns": "usage", + "corejs": "3.25.0" + } + ], + [ + "@babel/preset-react" + ] + ] +} diff --git a/modules/ppcp-save-payment-methods/.gitignore b/modules/ppcp-save-payment-methods/.gitignore new file mode 100644 index 000000000..0bd2b9f58 --- /dev/null +++ b/modules/ppcp-save-payment-methods/.gitignore @@ -0,0 +1,3 @@ +node_modules +assets/js +assets/css diff --git a/modules/ppcp-subscription/composer.json b/modules/ppcp-save-payment-methods/composer.json similarity index 59% rename from modules/ppcp-subscription/composer.json rename to modules/ppcp-save-payment-methods/composer.json index b8f68646c..50ff8c251 100644 --- a/modules/ppcp-subscription/composer.json +++ b/modules/ppcp-save-payment-methods/composer.json @@ -1,7 +1,7 @@ { - "name": "woocommerce/ppcp-subscription", + "name": "woocommerce/ppcp-save-payment-methods", "type": "dhii-mod", - "description": "Subscription module for PPCP", + "description": "Save payment methods module for PPCP", "license": "GPL-2.0", "require": { "php": "^7.2 | ^8.0", @@ -9,7 +9,7 @@ }, "autoload": { "psr-4": { - "WooCommerce\\PayPalCommerce\\Subscription\\": "src" + "WooCommerce\\PayPalCommerce\\SavePaymentMethods\\": "src" } }, "minimum-stability": "dev", diff --git a/modules/ppcp-save-payment-methods/extensions.php b/modules/ppcp-save-payment-methods/extensions.php new file mode 100644 index 000000000..1758f8960 --- /dev/null +++ b/modules/ppcp-save-payment-methods/extensions.php @@ -0,0 +1,14 @@ + 0.5%", + "Safari >= 8", + "Chrome >= 41", + "Firefox >= 43", + "Edge >= 14" + ], + "dependencies": { + "core-js": "^3.25.0", + "@paypal/paypal-js": "^6.0.0" + }, + "devDependencies": { + "@babel/core": "^7.19", + "@babel/preset-env": "^7.19", + "@babel/preset-react": "^7.18.6", + "@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0", + "babel-loader": "^8.2", + "cross-env": "^7.0.3", + "file-loader": "^6.2.0", + "sass": "^1.42.1", + "sass-loader": "^12.1.0", + "webpack": "^5.76", + "webpack-cli": "^4.10" + }, + "scripts": { + "build": "cross-env BABEL_ENV=default NODE_ENV=production webpack", + "watch": "cross-env BABEL_ENV=default NODE_ENV=production webpack --watch", + "dev": "cross-env BABEL_ENV=default webpack --watch" + } +} diff --git a/modules/ppcp-save-payment-methods/resources/js/add-payment-method.js b/modules/ppcp-save-payment-methods/resources/js/add-payment-method.js new file mode 100644 index 000000000..d861421e4 --- /dev/null +++ b/modules/ppcp-save-payment-methods/resources/js/add-payment-method.js @@ -0,0 +1,182 @@ +import { + getCurrentPaymentMethod, + ORDER_BUTTON_SELECTOR, + PaymentMethods +} from "../../../ppcp-button/resources/js/modules/Helper/CheckoutMethodState"; +import {loadScript} from "@paypal/paypal-js"; +import { + setVisible, + setVisibleByClass +} from "../../../ppcp-button/resources/js/modules/Helper/Hiding"; +import ErrorHandler from "../../../ppcp-button/resources/js/modules/ErrorHandler"; +import {cardFieldStyles} from "../../../ppcp-button/resources/js/modules/Helper/CardFieldsHelper"; + +const errorHandler = new ErrorHandler( + PayPalCommerceGateway.labels.error.generic, + document.querySelector('.woocommerce-notices-wrapper') +); + +const init = () => { + setVisibleByClass(ORDER_BUTTON_SELECTOR, getCurrentPaymentMethod() !== PaymentMethods.PAYPAL, 'ppcp-hidden'); + setVisible(`#ppc-button-${PaymentMethods.PAYPAL}-save-payment-method`, getCurrentPaymentMethod() === PaymentMethods.PAYPAL); +} + +document.addEventListener( + 'DOMContentLoaded', + () => { + jQuery(document.body).on('click init_add_payment_method', '.payment_methods input.input-radio', function () { + init() + }); + + setTimeout(() => { + loadScript({ + clientId: ppcp_add_payment_method.client_id, + merchantId: ppcp_add_payment_method.merchant_id, + dataUserIdToken: ppcp_add_payment_method.id_token, + components: 'buttons,card-fields', + }) + .then((paypal) => { + errorHandler.clear(); + + paypal.Buttons( + { + createVaultSetupToken: async () => { + const response = await fetch(ppcp_add_payment_method.ajax.create_setup_token.endpoint, { + method: "POST", + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + nonce: ppcp_add_payment_method.ajax.create_setup_token.nonce, + }) + }) + + const result = await response.json() + if (result.data.id) { + return result.data.id + } + + errorHandler.message(ppcp_add_payment_method.error_message); + }, + onApprove: async ({vaultSetupToken}) => { + const response = await fetch(ppcp_add_payment_method.ajax.create_payment_token.endpoint, { + method: "POST", + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + nonce: ppcp_add_payment_method.ajax.create_payment_token.nonce, + vault_setup_token: vaultSetupToken, + }) + }) + + const result = await response.json(); + if(result.success === true) { + window.location.href = ppcp_add_payment_method.payment_methods_page; + return; + } + + errorHandler.message(ppcp_add_payment_method.error_message); + }, + onError: (error) => { + console.error(error) + errorHandler.message(ppcp_add_payment_method.error_message); + } + }, + ).render(`#ppc-button-${PaymentMethods.PAYPAL}-save-payment-method`); + + const cardField = paypal.CardFields({ + createVaultSetupToken: async () => { + const response = await fetch(ppcp_add_payment_method.ajax.create_setup_token.endpoint, { + method: "POST", + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + nonce: ppcp_add_payment_method.ajax.create_setup_token.nonce, + payment_method: PaymentMethods.CARDS, + verification_method: ppcp_add_payment_method.verification_method + }) + }) + + const result = await response.json() + if (result.data.id) { + return result.data.id + } + + errorHandler.message(ppcp_add_payment_method.error_message); + }, + onApprove: async ({vaultSetupToken}) => { + const response = await fetch(ppcp_add_payment_method.ajax.create_payment_token.endpoint, { + method: "POST", + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + nonce: ppcp_add_payment_method.ajax.create_payment_token.nonce, + vault_setup_token: vaultSetupToken, + payment_method: PaymentMethods.CARDS + }) + }) + + const result = await response.json(); + if(result.success === true) { + window.location.href = ppcp_add_payment_method.payment_methods_page; + return; + } + + errorHandler.message(ppcp_add_payment_method.error_message); + }, + onError: (error) => { + console.error(error) + errorHandler.message(ppcp_add_payment_method.error_message); + } + }); + + if (cardField.isEligible()) { + const nameField = document.getElementById('ppcp-credit-card-gateway-card-name'); + if (nameField) { + let styles = cardFieldStyles(nameField); + cardField.NameField({style: {'input': styles}}).render(nameField.parentNode); + nameField.hidden = true; + } + + const numberField = document.getElementById('ppcp-credit-card-gateway-card-number'); + if (numberField) { + let styles = cardFieldStyles(numberField); + cardField.NumberField({style: {'input': styles}}).render(numberField.parentNode); + numberField.hidden = true; + } + + const expiryField = document.getElementById('ppcp-credit-card-gateway-card-expiry'); + if (expiryField) { + let styles = cardFieldStyles(expiryField); + cardField.ExpiryField({style: {'input': styles}}).render(expiryField.parentNode); + expiryField.hidden = true; + } + + const cvvField = document.getElementById('ppcp-credit-card-gateway-card-cvc'); + if (cvvField) { + let styles = cardFieldStyles(cvvField); + cardField.CVVField({style: {'input': styles}}).render(cvvField.parentNode); + cvvField.hidden = true; + } + } + + document.querySelector('#place_order').addEventListener("click", (event) => { + event.preventDefault(); + + cardField.submit() + .catch((error) => { + console.error(error) + }); + }); + }) + }, 1000) + } +); + diff --git a/modules/ppcp-save-payment-methods/services.php b/modules/ppcp-save-payment-methods/services.php new file mode 100644 index 000000000..f1a188681 --- /dev/null +++ b/modules/ppcp-save-payment-methods/services.php @@ -0,0 +1,90 @@ + static function ( ContainerInterface $container ): bool { + $save_payment_methods_applies = $container->get( 'save-payment-methods.helpers.save-payment-methods-applies' ); + assert( $save_payment_methods_applies instanceof SavePaymentMethodsApplies ); + + return $save_payment_methods_applies->for_country_currency(); + }, + 'save-payment-methods.helpers.save-payment-methods-applies' => static function ( ContainerInterface $container ) : SavePaymentMethodsApplies { + return new SavePaymentMethodsApplies( + $container->get( 'save-payment-methods.supported-country-currency-matrix' ), + $container->get( 'api.shop.currency' ), + $container->get( 'api.shop.country' ) + ); + }, + 'save-payment-methods.supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array { + return apply_filters( + 'woocommerce_paypal_payments_save_payment_methods_supported_country_currency_matrix', + array( + 'US' => array( + 'AUD', + 'CAD', + 'EUR', + 'GBP', + 'JPY', + 'USD', + ), + ) + ); + }, + 'save-payment-methods.module.url' => static function ( ContainerInterface $container ): string { + /** + * The path cannot be false. + * + * @psalm-suppress PossiblyFalseArgument + */ + return plugins_url( + '/modules/ppcp-save-payment-methods/', + dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php' + ); + }, + 'save-payment-methods.endpoint.create-setup-token' => static function ( ContainerInterface $container ): CreateSetupToken { + return new CreateSetupToken( + $container->get( 'button.request-data' ), + $container->get( 'api.endpoint.payment-method-tokens' ) + ); + }, + 'save-payment-methods.wc-payment-tokens' => static function( ContainerInterface $container ): WooCommercePaymentTokens { + return new WooCommercePaymentTokens( + $container->get( 'vaulting.payment-token-helper' ), + $container->get( 'vaulting.payment-token-factory' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, + 'save-payment-methods.endpoint.create-payment-token' => static function ( ContainerInterface $container ): CreatePaymentToken { + return new CreatePaymentToken( + $container->get( 'button.request-data' ), + $container->get( 'api.endpoint.payment-method-tokens' ), + $container->get( 'save-payment-methods.wc-payment-tokens' ) + ); + }, + 'save-payment-methods.endpoint.capture-card-payment' => static function( ContainerInterface $container ): CaptureCardPayment { + return new CaptureCardPayment( + $container->get( 'button.request-data' ), + $container->get( 'api.host' ), + $container->get( 'api.bearer' ), + $container->get( 'api.factory.order' ), + $container->get( 'api.factory.purchase-unit' ), + $container->get( 'api.endpoint.order' ), + $container->get( 'session.handler' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, +); diff --git a/modules/ppcp-save-payment-methods/src/Endpoint/CaptureCardPayment.php b/modules/ppcp-save-payment-methods/src/Endpoint/CaptureCardPayment.php new file mode 100644 index 000000000..6bf923867 --- /dev/null +++ b/modules/ppcp-save-payment-methods/src/Endpoint/CaptureCardPayment.php @@ -0,0 +1,219 @@ +request_data = $request_data; + $this->host = $host; + $this->bearer = $bearer; + $this->order_factory = $order_factory; + $this->purchase_unit_factory = $purchase_unit_factory; + $this->order_endpoint = $order_endpoint; + $this->logger = $logger; + $this->session_handler = $session_handler; + } + + /** + * Returns the nonce. + * + * @return string + */ + public static function nonce(): string { + return self::ENDPOINT; + } + + /** + * Handles the request. + * + * @return bool + */ + public function handle_request(): bool { + $data = $this->request_data->read_request( $this->nonce() ); + + $tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() ); + foreach ( $tokens as $token ) { + if ( $token->get_id() === (int) $data['payment_token'] ) { + try { + $order = $this->create_order( $token->get_token() ); + + $id = $order->id ?? ''; + $status = $order->status ?? ''; + $payment_source = isset( $order->payment_source->card ) ? 'card' : ''; + if ( $id && $status && $payment_source ) { + WC()->session->set( + 'ppcp_saved_payment_card', + array( + 'order_id' => $id, + 'status' => $status, + 'payment_source' => $payment_source, + ) + ); + + wp_send_json_success(); + return true; + } + } catch ( RuntimeException $exception ) { + wp_send_json_error(); + return false; + } + } + } + + wp_send_json_error(); + return false; + } + + /** + * Creates PayPal order from the given card vault id. + * + * @param string $vault_id Vault id. + * @return stdClass + * @throws RuntimeException When request fails. + */ + private function create_order( string $vault_id ): stdClass { + $items = array( $this->purchase_unit_factory->from_wc_cart() ); + + $data = array( + 'intent' => 'CAPTURE', + 'purchase_units' => array_map( + static function ( PurchaseUnit $item ): array { + return $item->to_array( true, false ); + }, + $items + ), + 'payment_source' => array( + 'card' => array( + 'vault_id' => $vault_id, + ), + ), + ); + + $bearer = $this->bearer->bearer(); + $url = trailingslashit( $this->host ) . 'v2/checkout/orders'; + $args = array( + 'method' => 'POST', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/json', + 'PayPal-Request-Id' => uniqid( 'ppcp-', true ), + ), + 'body' => wp_json_encode( $data ), + ); + + $response = $this->request( $url, $args ); + if ( $response instanceof WP_Error ) { + throw new RuntimeException( $response->get_error_message() ); + } + + return json_decode( $response['body'] ); + } +} + diff --git a/modules/ppcp-save-payment-methods/src/Endpoint/CreatePaymentToken.php b/modules/ppcp-save-payment-methods/src/Endpoint/CreatePaymentToken.php new file mode 100644 index 000000000..6698c4340 --- /dev/null +++ b/modules/ppcp-save-payment-methods/src/Endpoint/CreatePaymentToken.php @@ -0,0 +1,143 @@ +request_data = $request_data; + $this->payment_method_tokens_endpoint = $payment_method_tokens_endpoint; + $this->wc_payment_tokens = $wc_payment_tokens; + } + + /** + * Returns the nonce. + * + * @return string + */ + public static function nonce(): string { + return self::ENDPOINT; + } + + /** + * Handles the request. + * + * @return bool + * @throws Exception On Error. + */ + public function handle_request(): bool { + try { + $data = $this->request_data->read_request( $this->nonce() ); + + /** + * Suppress ArgumentTypeCoercion + * + * @psalm-suppress ArgumentTypeCoercion + */ + $payment_source = new PaymentSource( + 'token', + (object) array( + 'id' => $data['vault_setup_token'], + 'type' => 'SETUP_TOKEN', + ) + ); + + $result = $this->payment_method_tokens_endpoint->payment_tokens( $payment_source ); + + if ( is_user_logged_in() && isset( $result->customer->id ) ) { + update_user_meta( get_current_user_id(), '_ppcp_target_customer_id', $result->customer->id ); + + if ( isset( $result->payment_source->paypal ) ) { + $email = ''; + if ( isset( $result->payment_source->paypal->email_address ) ) { + $email = $result->payment_source->paypal->email_address; + } + + $this->wc_payment_tokens->create_payment_token_paypal( + get_current_user_id(), + $result->id, + $email + ); + } + + if ( isset( $result->payment_source->card ) ) { + $token = new \WC_Payment_Token_CC(); + $token->set_token( $result->id ); + $token->set_user_id( get_current_user_id() ); + $token->set_gateway_id( CreditCardGateway::ID ); + + $token->set_last4( $result->payment_source->card->last_digits ?? '' ); + $expiry = explode( '-', $result->payment_source->card->expiry ?? '' ); + $token->set_expiry_year( $expiry[0] ?? '' ); + $token->set_expiry_month( $expiry[1] ?? '' ); + + $brand = $result->payment_source->card->brand ?? __( 'N/A', 'woocommerce-paypal-payments' ); + if ( $brand ) { + $token->set_card_type( $brand ); + } + + $token->save(); + } + } + + wp_send_json_success( $result ); + return true; + } catch ( Exception $exception ) { + wp_send_json_error(); + return false; + } + } +} diff --git a/modules/ppcp-save-payment-methods/src/Endpoint/CreateSetupToken.php b/modules/ppcp-save-payment-methods/src/Endpoint/CreateSetupToken.php new file mode 100644 index 000000000..7eb3a5ace --- /dev/null +++ b/modules/ppcp-save-payment-methods/src/Endpoint/CreateSetupToken.php @@ -0,0 +1,115 @@ +request_data = $request_data; + $this->payment_method_tokens_endpoint = $payment_method_tokens_endpoint; + } + + /** + * Returns the nonce. + * + * @return string + */ + public static function nonce(): string { + return self::ENDPOINT; + } + + /** + * Handles the request. + * + * @return bool + * @throws Exception On Error. + */ + public function handle_request(): bool { + try { + $data = $this->request_data->read_request( $this->nonce() ); + + $payment_source = new PaymentSource( + 'paypal', + (object) array( + 'usage_type' => 'MERCHANT', + 'experience_context' => (object) array( + 'return_url' => esc_url( wc_get_account_endpoint_url( 'payment-methods' ) ), + 'cancel_url' => esc_url( wc_get_account_endpoint_url( 'add-payment-method' ) ), + ), + ) + ); + + $payment_method = $data['payment_method'] ?? ''; + if ( $payment_method === CreditCardGateway::ID ) { + $properties = (object) array(); + + $verification_method = $data['verification_method'] ?? ''; + if ( $verification_method === 'SCA_WHEN_REQUIRED' || $verification_method === 'SCA_ALWAYS' ) { + $properties = (object) array( + 'verification_method' => $verification_method, + 'usage_type' => 'MERCHANT', + 'experience_context' => (object) array( + 'return_url' => esc_url( wc_get_account_endpoint_url( 'payment-methods' ) ), + 'cancel_url' => esc_url( wc_get_account_endpoint_url( 'add-payment-method' ) ), + ), + ); + } + + $payment_source = new PaymentSource( + 'card', + $properties + ); + } + + $result = $this->payment_method_tokens_endpoint->setup_tokens( $payment_source ); + + wp_send_json_success( $result ); + return true; + } catch ( Exception $exception ) { + wp_send_json_error(); + return false; + } + } +} diff --git a/modules/ppcp-save-payment-methods/src/Helper/SavePaymentMethodsApplies.php b/modules/ppcp-save-payment-methods/src/Helper/SavePaymentMethodsApplies.php new file mode 100644 index 000000000..bef3e6989 --- /dev/null +++ b/modules/ppcp-save-payment-methods/src/Helper/SavePaymentMethodsApplies.php @@ -0,0 +1,66 @@ +allowed_country_currency_matrix = $allowed_country_currency_matrix; + $this->currency = $currency; + $this->country = $country; + } + + /** + * Returns whether Save Payment Methods can be used in the current country and the current currency used. + * + * @return bool + */ + public function for_country_currency(): bool { + if ( ! in_array( $this->country, array_keys( $this->allowed_country_currency_matrix ), true ) ) { + return false; + } + return in_array( $this->currency, $this->allowed_country_currency_matrix[ $this->country ], true ); + } +} diff --git a/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php b/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php new file mode 100644 index 000000000..9dcb02359 --- /dev/null +++ b/modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php @@ -0,0 +1,377 @@ +get( 'save-payment-methods.eligible' ) ) { + return; + } + + add_filter( + 'woocommerce_paypal_payments_localized_script_data', + function( array $localized_script_data ) use ( $c ) { + $api = $c->get( 'api.user-id-token' ); + assert( $api instanceof UserIdToken ); + + $logger = $c->get( 'woocommerce.logger.woocommerce' ); + assert( $logger instanceof LoggerInterface ); + + $localized_script_data = $this->add_id_token_to_script_data( $api, $logger, $localized_script_data ); + + $localized_script_data['ajax']['capture_card_payment'] = array( + 'endpoint' => \WC_AJAX::get_endpoint( CaptureCardPayment::ENDPOINT ), + 'nonce' => wp_create_nonce( CaptureCardPayment::nonce() ), + ); + + return $localized_script_data; + } + ); + + // Adds attributes needed to save payment method. + add_filter( + 'ppcp_create_order_request_body_data', + function( array $data, string $payment_method, array $request_data ): array { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $wc_order_action = wc_clean( wp_unslash( $_POST['wc_order_action'] ?? '' ) ); + if ( $wc_order_action === 'wcs_process_renewal' ) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $subscription_id = wc_clean( wp_unslash( $_POST['post_ID'] ?? '' ) ); + $subscription = wcs_get_subscription( (int) $subscription_id ); + if ( $subscription ) { + $customer_id = $subscription->get_customer_id(); + $wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID ); + foreach ( $wc_tokens as $token ) { + $data['payment_source'] = array( + 'paypal' => array( + 'vault_id' => $token->get_token(), + ), + ); + + return $data; + } + } + } + + if ( $payment_method === CreditCardGateway::ID ) { + $save_payment_method = $request_data['save_payment_method'] ?? false; + if ( $save_payment_method ) { + $data['payment_source'] = array( + 'card' => array( + 'attributes' => array( + 'vault' => array( + 'store_in_vault' => 'ON_SUCCESS', + ), + ), + ), + ); + + $target_customer_id = get_user_meta( get_current_user_id(), '_ppcp_target_customer_id', true ); + if ( $target_customer_id ) { + $data['payment_source']['card']['attributes']['customer'] = array( + 'id' => $target_customer_id, + ); + } + } + } + + if ( $payment_method === PayPalGateway::ID ) { + $data['payment_source'] = array( + 'paypal' => array( + 'attributes' => array( + 'vault' => array( + 'store_in_vault' => 'ON_SUCCESS', + 'usage_type' => 'MERCHANT', + ), + ), + ), + ); + } + + return $data; + }, + 10, + 3 + ); + + add_action( + 'woocommerce_paypal_payments_after_order_processor', + function( WC_Order $wc_order, Order $order ) use ( $c ) { + $payment_source = $order->payment_source(); + assert( $payment_source instanceof PaymentSource ); + + $payment_vault_attributes = $payment_source->properties()->attributes->vault ?? null; + if ( $payment_vault_attributes ) { + $customer_id = $payment_vault_attributes->customer->id ?? ''; + $token_id = $payment_vault_attributes->id ?? ''; + if ( ! $customer_id || ! $token_id ) { + return; + } + + update_user_meta( $wc_order->get_customer_id(), '_ppcp_target_customer_id', $customer_id ); + + $wc_payment_tokens = $c->get( 'save-payment-methods.wc-payment-tokens' ); + assert( $wc_payment_tokens instanceof WooCommercePaymentTokens ); + + if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) { + $token = new \WC_Payment_Token_CC(); + $token->set_token( $token_id ); + $token->set_user_id( $wc_order->get_customer_id() ); + $token->set_gateway_id( CreditCardGateway::ID ); + + $token->set_last4( $payment_source->properties()->last_digits ?? '' ); + $expiry = explode( '-', $payment_source->properties()->expiry ?? '' ); + $token->set_expiry_year( $expiry[0] ?? '' ); + $token->set_expiry_month( $expiry[1] ?? '' ); + $token->set_card_type( $payment_source->properties()->brand ?? '' ); + + $token->save(); + } + + if ( $wc_order->get_payment_method() === PayPalGateway::ID ) { + $wc_payment_tokens->create_payment_token_paypal( + $wc_order->get_customer_id(), + $token_id, + $payment_source->properties()->email_address ?? '' + ); + } + } + }, + 10, + 2 + ); + + add_filter( 'woocommerce_paypal_payments_disable_add_payment_method', '__return_false' ); + add_filter( 'woocommerce_paypal_payments_subscription_renewal_return_before_create_order_without_token', '__return_false' ); + add_filter( 'woocommerce_paypal_payments_should_render_card_custom_fields', '__return_false' ); + + add_action( + 'wp_enqueue_scripts', + function() use ( $c ) { + if ( ! is_user_logged_in() || ! $this->is_add_payment_method_page() ) { + return; + } + + $module_url = $c->get( 'save-payment-methods.module.url' ); + wp_enqueue_script( + 'ppcp-add-payment-method', + untrailingslashit( $module_url ) . '/assets/js/add-payment-method.js', + array( 'jquery' ), + $c->get( 'ppcp.asset-version' ), + true + ); + + $api = $c->get( 'api.user-id-token' ); + assert( $api instanceof UserIdToken ); + + try { + $target_customer_id = ''; + if ( is_user_logged_in() ) { + $target_customer_id = get_user_meta( get_current_user_id(), '_ppcp_target_customer_id', true ); + } + + $id_token = $api->id_token( $target_customer_id ); + + $settings = $c->get( 'wcgateway.settings' ); + assert( $settings instanceof Settings ); + $verification_method = $settings->has( '3d_secure_contingency' ) ? $settings->get( '3d_secure_contingency' ) : ''; + + wp_localize_script( + 'ppcp-add-payment-method', + 'ppcp_add_payment_method', + array( + 'client_id' => $c->get( 'button.client_id' ), + 'merchant_id' => $c->get( 'api.merchant_id' ), + 'id_token' => $id_token, + 'payment_methods_page' => wc_get_account_endpoint_url( 'payment-methods' ), + 'error_message' => __( 'Could not save payment method.', 'woocommerce-paypal-payments' ), + 'verification_method' => $verification_method, + 'ajax' => array( + 'create_setup_token' => array( + 'endpoint' => \WC_AJAX::get_endpoint( CreateSetupToken::ENDPOINT ), + 'nonce' => wp_create_nonce( CreateSetupToken::nonce() ), + ), + 'create_payment_token' => array( + 'endpoint' => \WC_AJAX::get_endpoint( CreatePaymentToken::ENDPOINT ), + 'nonce' => wp_create_nonce( CreatePaymentToken::nonce() ), + ), + ), + ) + ); + } catch ( RuntimeException $exception ) { + $logger = $c->get( 'woocommerce.logger.woocommerce' ); + assert( $logger instanceof LoggerInterface ); + + $error = $exception->getMessage(); + if ( is_a( $exception, PayPalApiException::class ) ) { + $error = $exception->get_details( $error ); + } + + $logger->error( $error ); + } + } + ); + + add_action( + 'woocommerce_add_payment_method_form_bottom', + function () { + if ( ! is_user_logged_in() || ! is_add_payment_method_page() ) { + return; + } + + echo '
'; + } + ); + + add_action( + 'wc_ajax_' . CreateSetupToken::ENDPOINT, + static function () use ( $c ) { + $endpoint = $c->get( 'save-payment-methods.endpoint.create-setup-token' ); + assert( $endpoint instanceof CreateSetupToken ); + + $endpoint->handle_request(); + } + ); + + add_action( + 'wc_ajax_' . CreatePaymentToken::ENDPOINT, + static function () use ( $c ) { + $endpoint = $c->get( 'save-payment-methods.endpoint.create-payment-token' ); + assert( $endpoint instanceof CreatePaymentToken ); + + $endpoint->handle_request(); + } + ); + + add_action( + 'woocommerce_paypal_payments_before_delete_payment_token', + function( string $token_id ) use ( $c ) { + try { + $endpoint = $c->get( 'api.endpoint.payment-tokens' ); + assert( $endpoint instanceof PaymentTokensEndpoint ); + + $endpoint->delete( $token_id ); + } catch ( RuntimeException $exception ) { + $logger = $c->get( 'woocommerce.logger.woocommerce' ); + assert( $logger instanceof LoggerInterface ); + + $error = $exception->getMessage(); + if ( is_a( $exception, PayPalApiException::class ) ) { + $error = $exception->get_details( $error ); + } + + $logger->error( $error ); + } + } + ); + + add_filter( + 'woocommerce_paypal_payments_credit_card_gateway_vault_supports', + function( array $supports ) use ( $c ): array { + $settings = $c->get( 'wcgateway.settings' ); + assert( $settings instanceof ContainerInterface ); + + if ( $settings->has( 'vault_enabled_dcc' ) && $settings->get( 'vault_enabled_dcc' ) ) { + $supports[] = 'tokenization'; + } + + return $supports; + } + ); + + add_action( + 'wc_ajax_' . CaptureCardPayment::ENDPOINT, + static function () use ( $c ) { + $endpoint = $c->get( 'save-payment-methods.endpoint.capture-card-payment' ); + assert( $endpoint instanceof CaptureCardPayment ); + + $endpoint->handle_request(); + } + ); + } + + /** + * Adds id token to localized script data. + * + * @param UserIdToken $api User id token api. + * @param LoggerInterface $logger The logger. + * @param array $localized_script_data The localized script data. + * @return array + */ + private function add_id_token_to_script_data( + UserIdToken $api, + LoggerInterface $logger, + array $localized_script_data + ): array { + try { + $target_customer_id = ''; + if ( is_user_logged_in() ) { + $target_customer_id = get_user_meta( get_current_user_id(), '_ppcp_target_customer_id', true ); + } + + $id_token = $api->id_token( $target_customer_id ); + $localized_script_data['save_payment_methods'] = array( + 'id_token' => $id_token, + ); + + $localized_script_data['data_client_id']['set_attribute'] = false; + + } catch ( RuntimeException $exception ) { + $error = $exception->getMessage(); + if ( is_a( $exception, PayPalApiException::class ) ) { + $error = $exception->get_details( $error ); + } + + $logger->error( $error ); + } + + return $localized_script_data; + } +} diff --git a/modules/ppcp-save-payment-methods/src/WooCommercePaymentTokens.php b/modules/ppcp-save-payment-methods/src/WooCommercePaymentTokens.php new file mode 100644 index 000000000..4fb066b6e --- /dev/null +++ b/modules/ppcp-save-payment-methods/src/WooCommercePaymentTokens.php @@ -0,0 +1,102 @@ +payment_token_helper = $payment_token_helper; + $this->payment_token_factory = $payment_token_factory; + $this->logger = $logger; + } + + /** + * Creates a WC Payment Token for PayPal payment. + * + * @param int $customer_id The WC customer ID. + * @param string $token The PayPal payment token. + * @param string $email The PayPal customer email. + * + * @return void + */ + public function create_payment_token_paypal( + int $customer_id, + string $token, + string $email + ): void { + + $wc_tokens = WC_Payment_Tokens::get_customer_tokens( $customer_id, PayPalGateway::ID ); + if ( $this->payment_token_helper->token_exist( $wc_tokens, $token ) ) { + return; + } + + $payment_token_paypal = $this->payment_token_factory->create( 'paypal' ); + assert( $payment_token_paypal instanceof PaymentTokenPayPal ); + + $payment_token_paypal->set_token( $token ); + $payment_token_paypal->set_user_id( $customer_id ); + $payment_token_paypal->set_gateway_id( PayPalGateway::ID ); + + if ( $email && is_email( $email ) ) { + $payment_token_paypal->set_email( $email ); + } + + try { + $payment_token_paypal->save(); + } catch ( Exception $exception ) { + $this->logger->error( + "Could not create WC payment token PayPal for customer {$customer_id}. " . $exception->getMessage() + ); + } + } +} diff --git a/modules/ppcp-save-payment-methods/webpack.config.js b/modules/ppcp-save-payment-methods/webpack.config.js new file mode 100644 index 000000000..16f380538 --- /dev/null +++ b/modules/ppcp-save-payment-methods/webpack.config.js @@ -0,0 +1,38 @@ +const path = require('path'); +const isProduction = process.env.NODE_ENV === 'production'; + +const DependencyExtractionWebpackPlugin = require( '@woocommerce/dependency-extraction-webpack-plugin' ); + +module.exports = { + devtool: isProduction ? 'source-map' : 'eval-source-map', + mode: isProduction ? 'production' : 'development', + target: 'web', + plugins: [ new DependencyExtractionWebpackPlugin() ], + entry: { + 'add-payment-method': path.resolve('./resources/js/add-payment-method.js') + }, + output: { + path: path.resolve(__dirname, 'assets/'), + filename: 'js/[name].js', + }, + module: { + rules: [{ + test: /\.js?$/, + exclude: /node_modules/, + loader: 'babel-loader', + }, + { + test: /\.scss$/, + exclude: /node_modules/, + use: [ + { + loader: 'file-loader', + options: { + name: 'css/[name].css', + } + }, + {loader:'sass-loader'} + ] + }] + } +}; diff --git a/modules/ppcp-save-payment-methods/yarn.lock b/modules/ppcp-save-payment-methods/yarn.lock new file mode 100644 index 000000000..2171c2b89 --- /dev/null +++ b/modules/ppcp-save-payment-methods/yarn.lock @@ -0,0 +1,2247 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" + integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== + +"@babel/core@^7.19": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" + integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helpers" "^7.23.2" + "@babel/parser" "^7.23.0" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== + dependencies: + "@babel/types" "^7.23.0" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" + integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" + integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" + integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + +"@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-member-expression-to-functions@^7.22.15": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + +"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" + integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-remap-async-to-generator@^7.22.20", "@babel/helper-remap-async-to-generator@^7.22.5": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" + +"@babel/helpers@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" + integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" + integrity sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz#2aeb91d337d4e1a1e7ce85b76a37f5301781200f" + integrity sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.15" + +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-import-assertions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" + integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-async-generator-functions@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz#054afe290d64c6f576f371ccc321772c8ea87ebb" + integrity sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-transform-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + +"@babel/plugin-transform-block-scoped-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-block-scoping@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022" + integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" + integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" + integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz#aaf4753aee262a232bbc95451b4bdf9599c65a0b" + integrity sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" + +"@babel/plugin-transform-destructuring@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" + integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dotall-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-duplicate-keys@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dynamic-import@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" + integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-export-namespace-from@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" + integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz#f64b4ccc3a4f131a996388fae7680b472b306b29" + integrity sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== + dependencies: + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-json-strings@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" + integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-transform-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-logical-assignment-operators@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" + integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-amd@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88" + integrity sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw== + dependencies: + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-commonjs@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" + integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== + dependencies: + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + +"@babel/plugin-transform-modules-systemjs@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160" + integrity sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/plugin-transform-modules-umd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-new-target@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" + integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" + integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz#21a95db166be59b91cde48775310c0df6e1da56f" + integrity sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.15" + +"@babel/plugin-transform-object-super@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + +"@babel/plugin-transform-optional-catch-binding@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" + integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.22.15", "@babel/plugin-transform-optional-chaining@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz#73ff5fc1cf98f542f09f29c0631647d8ad0be158" + integrity sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz#719ca82a01d177af358df64a514d64c2e3edb114" + integrity sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-methods@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" + integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" + integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-display-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" + integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-jsx-development@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" + integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.22.5" + +"@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz#7e6266d88705d7c49f11c98db8b9464531289cd6" + integrity sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/types" "^7.22.15" + +"@babel/plugin-transform-react-pure-annotations@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz#1f58363eef6626d6fa517b95ac66fe94685e32c0" + integrity sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" + integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-reserved-words@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-shorthand-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-template-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typeof-symbol@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-escapes@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" + integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" + integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" + integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/preset-env@^7.19": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.2.tgz#1f22be0ff0e121113260337dbc3e58fafce8d059" + integrity sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ== + dependencies: + "@babel/compat-data" "^7.23.2" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.22.5" + "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.23.2" + "@babel/plugin-transform-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions" "^7.22.5" + "@babel/plugin-transform-block-scoping" "^7.23.0" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.11" + "@babel/plugin-transform-classes" "^7.22.15" + "@babel/plugin-transform-computed-properties" "^7.22.5" + "@babel/plugin-transform-destructuring" "^7.23.0" + "@babel/plugin-transform-dotall-regex" "^7.22.5" + "@babel/plugin-transform-duplicate-keys" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.11" + "@babel/plugin-transform-exponentiation-operator" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.11" + "@babel/plugin-transform-for-of" "^7.22.15" + "@babel/plugin-transform-function-name" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.11" + "@babel/plugin-transform-literals" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" + "@babel/plugin-transform-member-expression-literals" "^7.22.5" + "@babel/plugin-transform-modules-amd" "^7.23.0" + "@babel/plugin-transform-modules-commonjs" "^7.23.0" + "@babel/plugin-transform-modules-systemjs" "^7.23.0" + "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" + "@babel/plugin-transform-numeric-separator" "^7.22.11" + "@babel/plugin-transform-object-rest-spread" "^7.22.15" + "@babel/plugin-transform-object-super" "^7.22.5" + "@babel/plugin-transform-optional-catch-binding" "^7.22.11" + "@babel/plugin-transform-optional-chaining" "^7.23.0" + "@babel/plugin-transform-parameters" "^7.22.15" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.11" + "@babel/plugin-transform-property-literals" "^7.22.5" + "@babel/plugin-transform-regenerator" "^7.22.10" + "@babel/plugin-transform-reserved-words" "^7.22.5" + "@babel/plugin-transform-shorthand-properties" "^7.22.5" + "@babel/plugin-transform-spread" "^7.22.5" + "@babel/plugin-transform-sticky-regex" "^7.22.5" + "@babel/plugin-transform-template-literals" "^7.22.5" + "@babel/plugin-transform-typeof-symbol" "^7.22.5" + "@babel/plugin-transform-unicode-escapes" "^7.22.10" + "@babel/plugin-transform-unicode-property-regex" "^7.22.5" + "@babel/plugin-transform-unicode-regex" "^7.22.5" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" + "@babel/preset-modules" "0.1.6-no-external-plugins" + "@babel/types" "^7.23.0" + babel-plugin-polyfill-corejs2 "^0.4.6" + babel-plugin-polyfill-corejs3 "^0.8.5" + babel-plugin-polyfill-regenerator "^0.5.3" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.18.6": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.15.tgz#9a776892b648e13cc8ca2edf5ed1264eea6b6afc" + integrity sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-transform-react-display-name" "^7.22.5" + "@babel/plugin-transform-react-jsx" "^7.22.15" + "@babel/plugin-transform-react-jsx-development" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.22.5" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.8.4": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" + integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.15", "@babel/template@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.4.4": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.19" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@paypal/paypal-js@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@paypal/paypal-js/-/paypal-js-6.0.1.tgz#5d68d5863a5176383fee9424bc944231668fcffd" + integrity sha512-bvYetmkg2GEC6onsUJQx1E9hdAJWff2bS3IPeiZ9Sh9U7h26/fIgMKm240cq/908sbSoDjHys75XXd8at9OpQA== + dependencies: + promise-polyfill "^8.3.0" + +"@types/eslint-scope@^3.7.3": + version "3.7.5" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.5.tgz#e28b09dbb1d9d35fdfa8a884225f00440dfc5a3e" + integrity sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.44.4" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.4.tgz#28eaff82e1ca0a96554ec5bb0188f10ae1a74c2f" + integrity sha512-lOzjyfY/D9QR4hY9oblZ76B90MYTB3RrQ4z2vBIJKj9ROCRqdkYl2gSUx1x1a4IWPjKJZLL4Aw1Zfay7eMnmnA== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.2.tgz#ff02bc3dc8317cd668dfec247b750ba1f1d62453" + integrity sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA== + +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8": + version "7.0.13" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" + integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== + +"@types/node@*": + version "20.8.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.6.tgz#0dbd4ebcc82ad0128df05d0e6f57e05359ee47fa" + integrity sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ== + dependencies: + undici-types "~5.25.1" + +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== + +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== + +"@woocommerce/dependency-extraction-webpack-plugin@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@woocommerce/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-2.2.0.tgz#230d674a67585bc32e31bc28485bec99b41dbd1f" + integrity sha512-0wDY3EIUwWrPm0KrWvt1cf2SZDSX7CzBXvv4TyCqWOPuVPvC/ajyY8kD1HTFI80q6/RHoxWf3BYCmhuBzPbe9A== + dependencies: + "@wordpress/dependency-extraction-webpack-plugin" "^3.3.0" + +"@wordpress/dependency-extraction-webpack-plugin@^3.3.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-3.7.0.tgz#e52ef31f66b8c4add3d773a87e11007375127b04" + integrity sha512-SHyp88D1ICSaRVMfs/kKEicjKXWf1y2wecUeZIiMtkfAi8Bnk3JsnUo11LH7drJIXfjmDoer2B2rrBMZmRm8VA== + dependencies: + json2php "^0.0.4" + webpack-sources "^3.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.7.1, acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +babel-loader@^8.2: + version "8.3.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" + integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^2.0.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-plugin-polyfill-corejs2@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" + integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.3" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.5.tgz#a75fa1b0c3fc5bd6837f9ec465c0f48031b8cab1" + integrity sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.3" + core-js-compat "^3.32.2" + +babel-plugin-polyfill-regenerator@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" + integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.14.5, browserslist@^4.21.9, browserslist@^4.22.1: + version "4.22.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" + integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== + dependencies: + caniuse-lite "^1.0.30001541" + electron-to-chromium "^1.4.535" + node-releases "^2.0.13" + update-browserslist-db "^1.0.13" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +caniuse-lite@^1.0.30001541: + version "1.0.30001549" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz#7d1a3dce7ea78c06ed72c32c2743ea364b3615aa" + integrity sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +"chokidar@>=3.0.0 <4.0.0": + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +colorette@^2.0.14: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +core-js-compat@^3.31.0, core-js-compat@^3.32.2: + version "3.33.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.0.tgz#24aa230b228406450b2277b7c8bfebae932df966" + integrity sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw== + dependencies: + browserslist "^4.22.1" + +core-js@^3.25.0: + version "3.33.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.0.tgz#70366dbf737134761edb017990cf5ce6c6369c40" + integrity sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw== + +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.1, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +electron-to-chromium@^1.4.535: + version "1.4.556" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.556.tgz#97385917eb6ea3ac6a3378cf87bb39ee1db96e76" + integrity sha512-6RPN0hHfzDU8D56E72YkDvnLw5Cj2NMXZGg3UkgyoHxjVhG99KZpsKgBWMmTy0Ei89xwan+rbRsVB9yzATmYzQ== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +enhanced-resolve@^5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +envinfo@^7.7.3: + version "7.10.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" + integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== + +es-module-lexer@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1" + integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" + integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== + +immutable@^4.0.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json2php@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/json2php/-/json2php-0.0.4.tgz#6bd85a1dda6a5dd7e91022bb24403cc1b7c2ee34" + integrity sha512-hFzejhs28f70sGnutcsRS459MnAsjRVI85RgPAL1KQIZEpjiDitc27CZv4IgOtaR86vrqOVlu9vJNew2XyTH4g== + +json5@^2.1.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +promise-polyfill@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.3.0.tgz#9284810268138d103807b11f4e23d5e945a4db63" + integrity sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +regenerate-unicode-properties@^10.1.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.14.2, resolve@^1.9.0: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +sass-loader@^12.1.0: + version "12.6.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" + integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA== + dependencies: + klona "^2.0.4" + neo-async "^2.6.2" + +sass@^1.42.1: + version "1.69.3" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.3.tgz#f8a0c488697e6419519834a13335e7b65a609c11" + integrity sha512-X99+a2iGdXkdWn1akFPs0ZmelUzyAQfvqYc2P/MPTrJRuIRoTffGzT9W9nFqG00S+c8hXzVmgxhUuHFdrwxkhQ== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +semver@^6.0.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +"source-map-js@>=0.6.2 <2.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" + +terser@^5.16.8: + version "5.22.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.22.0.tgz#4f18103f84c5c9437aafb7a14918273310a8a49d" + integrity sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +undici-types@~5.25.1: + version "5.25.3" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" + integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +webpack-cli@^4.10: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-merge@^5.7.3: + version "5.10.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== + dependencies: + clone-deep "^4.0.1" + flat "^5.0.2" + wildcard "^2.0.0" + +webpack-sources@^3.2.2, webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.76: + version "5.89.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" + integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.9.0" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.15.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.2.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== diff --git a/modules/ppcp-saved-payment-checker/extensions.php b/modules/ppcp-saved-payment-checker/extensions.php index dad4983b4..e712a03fc 100644 --- a/modules/ppcp-saved-payment-checker/extensions.php +++ b/modules/ppcp-saved-payment-checker/extensions.php @@ -10,12 +10,12 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\SavedPaymentChecker; use WooCommerce\PayPalCommerce\Onboarding\State; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; return array( 'wcgateway.settings.fields' => function ( ContainerInterface $container, array $fields ): array { - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); $insert_after = function( array $array, string $key, array $new ): array { diff --git a/modules/ppcp-saved-payment-checker/src/PaymentTokenChecker.php b/modules/ppcp-saved-payment-checker/src/PaymentTokenChecker.php index 0da73b51b..a94fe0d92 100644 --- a/modules/ppcp-saved-payment-checker/src/PaymentTokenChecker.php +++ b/modules/ppcp-saved-payment-checker/src/PaymentTokenChecker.php @@ -16,7 +16,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken; use WooCommerce\PayPalCommerce\ApiClient\Repository\OrderRepository; -use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; +use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; diff --git a/modules/ppcp-saved-payment-checker/src/SavedPaymentCheckerModule.php b/modules/ppcp-saved-payment-checker/src/SavedPaymentCheckerModule.php index f04143ebc..6a6ae3c79 100644 --- a/modules/ppcp-saved-payment-checker/src/SavedPaymentCheckerModule.php +++ b/modules/ppcp-saved-payment-checker/src/SavedPaymentCheckerModule.php @@ -11,7 +11,7 @@ namespace WooCommerce\PayPalCommerce\SavedPaymentChecker; use Psr\Log\LoggerInterface; use WC_Order; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider; use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface; use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface; @@ -43,7 +43,7 @@ class SavedPaymentCheckerModule implements ModuleInterface { add_filter( 'woocommerce_paypal_payments_order_intent', function( string $intent ) use ( $c ) { - $subscription_helper = $c->get( 'subscription.helper' ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); if ( $subscription_helper->cart_contains_subscription() || $subscription_helper->current_product_is_subscription() ) { @@ -60,7 +60,7 @@ class SavedPaymentCheckerModule implements ModuleInterface { add_action( 'woocommerce_paypal_payments_before_handle_payment_success', function( WC_Order $wc_order ) use ( $c ) { - $subscription_helper = $c->get( 'subscription.helper' ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); if ( $subscription_helper->has_subscription( $wc_order->get_id() ) ) { @@ -93,7 +93,7 @@ class SavedPaymentCheckerModule implements ModuleInterface { add_action( 'woocommerce_email_before_order_table', function( WC_Order $order ) use ( $c ) { - $subscription_helper = $c->get( 'subscription.helper' ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); $logger = $c->get( 'woocommerce.logger.woocommerce' ); assert( $logger instanceof LoggerInterface ); @@ -119,7 +119,7 @@ class SavedPaymentCheckerModule implements ModuleInterface { add_action( 'woocommerce_email_after_order_table', function( WC_Order $order ) use ( $c ) { - $subscription_helper = $c->get( 'subscription.helper' ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); $logger = $c->get( 'woocommerce.logger.woocommerce' ); assert( $logger instanceof LoggerInterface ); diff --git a/modules/ppcp-status-report/src/StatusReportModule.php b/modules/ppcp-status-report/src/StatusReportModule.php index 4c2d3c8ae..f26412778 100644 --- a/modules/ppcp-status-report/src/StatusReportModule.php +++ b/modules/ppcp-status-report/src/StatusReportModule.php @@ -9,7 +9,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\StatusReport; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider; use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface; use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface; @@ -65,7 +65,7 @@ class StatusReportModule implements ModuleInterface { $messages_apply = $c->get( 'button.helper.messages-apply' ); /* @var SubscriptionHelper $subscription_helper The subscription helper class. */ - $subscription_helper = $c->get( 'subscription.helper' ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); $last_webhook_storage = $c->get( 'webhook.last-webhook-storage' ); assert( $last_webhook_storage instanceof WebhookEventStorage ); diff --git a/modules/ppcp-subscription/services.php b/modules/ppcp-subscription/services.php deleted file mode 100644 index 8ddad1fe6..000000000 --- a/modules/ppcp-subscription/services.php +++ /dev/null @@ -1,74 +0,0 @@ - static function ( ContainerInterface $container ): SubscriptionHelper { - return new SubscriptionHelper( $container->get( 'wcgateway.settings' ) ); - }, - 'subscription.renewal-handler' => static function ( ContainerInterface $container ): RenewalHandler { - $logger = $container->get( 'woocommerce.logger.woocommerce' ); - $repository = $container->get( 'vaulting.repository.payment-token' ); - $endpoint = $container->get( 'api.endpoint.order' ); - $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' ); - $payer_factory = $container->get( 'api.factory.payer' ); - $environment = $container->get( 'onboarding.environment' ); - $settings = $container->get( 'wcgateway.settings' ); - $authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' ); - return new RenewalHandler( - $logger, - $repository, - $endpoint, - $purchase_unit_factory, - $container->get( 'api.factory.shipping-preference' ), - $payer_factory, - $environment, - $settings, - $authorized_payments_processor - ); - }, - 'subscription.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository { - $factory = $container->get( 'api.factory.payment-token' ); - $endpoint = $container->get( 'api.endpoint.payment-token' ); - return new PaymentTokenRepository( $factory, $endpoint ); - }, - 'subscription.api-handler' => static function( ContainerInterface $container ): SubscriptionsApiHandler { - return new SubscriptionsApiHandler( - $container->get( 'api.endpoint.catalog-products' ), - $container->get( 'api.factory.product' ), - $container->get( 'api.endpoint.billing-plans' ), - $container->get( 'api.factory.billing-cycle' ), - $container->get( 'api.factory.payment-preferences' ), - $container->get( 'api.shop.currency' ), - $container->get( 'woocommerce.logger.woocommerce' ) - ); - }, - 'subscription.module.url' => static function ( ContainerInterface $container ): string { - /** - * The path cannot be false. - * - * @psalm-suppress PossiblyFalseArgument - */ - return plugins_url( - '/modules/ppcp-subscription/', - dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php' - ); - }, - 'subscription.deactivate-plan-endpoint' => static function ( ContainerInterface $container ): DeactivatePlanEndpoint { - return new DeactivatePlanEndpoint( - $container->get( 'button.request-data' ), - $container->get( 'api.endpoint.billing-plans' ) - ); - }, -); diff --git a/modules/ppcp-vaulting/services.php b/modules/ppcp-vaulting/services.php index 101e0bb4c..44d042a7e 100644 --- a/modules/ppcp-vaulting/services.php +++ b/modules/ppcp-vaulting/services.php @@ -31,7 +31,7 @@ return array( }, 'vaulting.credit-card-handler' => function( ContainerInterface $container ): VaultedCreditCardHandler { return new VaultedCreditCardHandler( - $container->get( 'subscription.helper' ), + $container->get( 'wc-subscriptions.helper' ), $container->get( 'vaulting.repository.payment-token' ), $container->get( 'api.factory.purchase-unit' ), $container->get( 'api.factory.payer' ), diff --git a/modules/ppcp-vaulting/src/CustomerApprovalListener.php b/modules/ppcp-vaulting/src/CustomerApprovalListener.php index 1b922511b..2241d038d 100644 --- a/modules/ppcp-vaulting/src/CustomerApprovalListener.php +++ b/modules/ppcp-vaulting/src/CustomerApprovalListener.php @@ -13,7 +13,7 @@ use Exception; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Exception\AlreadyVaultedException; -use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; +use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; /** * Class CustomerApprovalListener diff --git a/modules/ppcp-vaulting/src/VaultedCreditCardHandler.php b/modules/ppcp-vaulting/src/VaultedCreditCardHandler.php index 04b1c8d5d..59e60b912 100644 --- a/modules/ppcp-vaulting/src/VaultedCreditCardHandler.php +++ b/modules/ppcp-vaulting/src/VaultedCreditCardHandler.php @@ -19,8 +19,8 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory; use WooCommerce\PayPalCommerce\Onboarding\Environment; -use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor; use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait; use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait; diff --git a/modules/ppcp-vaulting/src/VaultingModule.php b/modules/ppcp-vaulting/src/VaultingModule.php index 4da9a32bb..c9e7bd40a 100644 --- a/modules/ppcp-vaulting/src/VaultingModule.php +++ b/modules/ppcp-vaulting/src/VaultingModule.php @@ -51,7 +51,7 @@ class VaultingModule implements ModuleInterface { $listener->listen(); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); add_action( 'woocommerce_created_customer', function( int $customer_id ) use ( $subscription_helper ) { @@ -137,6 +137,8 @@ class VaultingModule implements ModuleInterface { } try { + do_action( 'woocommerce_paypal_payments_before_delete_payment_token', $token->get_token() ); + $payment_token_endpoint = $container->get( 'api.endpoint.payment-token' ); $payment_token_endpoint->delete_token_by_id( $token->get_token() ); } catch ( RuntimeException $exception ) { @@ -191,7 +193,10 @@ class VaultingModule implements ModuleInterface { 'woocommerce_available_payment_gateways', function( array $methods ): array { global $wp; - if ( isset( $wp->query_vars['add-payment-method'] ) ) { + if ( + isset( $wp->query_vars['add-payment-method'] ) + && apply_filters( 'woocommerce_paypal_payments_disable_add_payment_method', true ) + ) { unset( $methods[ PayPalGateway::ID ] ); } diff --git a/modules/ppcp-wc-gateway/extensions.php b/modules/ppcp-wc-gateway/extensions.php index 45a488d86..aca11f1b1 100644 --- a/modules/ppcp-wc-gateway/extensions.php +++ b/modules/ppcp-wc-gateway/extensions.php @@ -60,7 +60,6 @@ return array( $source ); }, - 'wcgateway.settings.fields' => function ( ContainerInterface $container, array $fields ): array { $files = array( 'paypal-smart-button-fields.php', diff --git a/modules/ppcp-wc-gateway/resources/css/common.scss b/modules/ppcp-wc-gateway/resources/css/common.scss index 259ecc672..aa9ec7f43 100644 --- a/modules/ppcp-wc-gateway/resources/css/common.scss +++ b/modules/ppcp-wc-gateway/resources/css/common.scss @@ -1,3 +1,4 @@ +@use "../../../ppcp-button/resources/css/mixins/apm-button" as apm-button; .ppcp-field-hidden { display: none !important; @@ -15,3 +16,12 @@ padding-left: 20px; } } + +// Prevents spacing after button group. +.ppcp-button-preview-inner { + line-height: 0; +} + +.ppcp-button-apm { + @include apm-button.button; +} diff --git a/modules/ppcp-wc-gateway/resources/js/common.js b/modules/ppcp-wc-gateway/resources/js/common.js index ba763605b..9b412ff70 100644 --- a/modules/ppcp-wc-gateway/resources/js/common.js +++ b/modules/ppcp-wc-gateway/resources/js/common.js @@ -15,9 +15,6 @@ document.addEventListener( jQuery( '*[data-ppcp-display]' ).each( (index, el) => { const rules = jQuery(el).data('ppcpDisplay'); - - // console.log('rules', rules); - for (const rule of rules) { displayManager.addRule(rule); } diff --git a/modules/ppcp-wc-gateway/resources/js/gateway-settings.js b/modules/ppcp-wc-gateway/resources/js/gateway-settings.js index 65b96e1d1..7d8132cfa 100644 --- a/modules/ppcp-wc-gateway/resources/js/gateway-settings.js +++ b/modules/ppcp-wc-gateway/resources/js/gateway-settings.js @@ -310,11 +310,11 @@ document.addEventListener( loadPaypalScript(oldScriptSettings, () => { const payLaterMessagingLocations = ['product', 'cart', 'checkout', 'shop', 'home', 'general']; - const paypalButtonLocations = ['product', 'cart', 'checkout', 'mini-cart', 'general']; + const paypalButtonLocations = ['product', 'cart', 'checkout', 'mini-cart', 'cart-block', 'checkout-block-express', 'general']; paypalButtonLocations.forEach((location) => { const inputNamePrefix = location === 'checkout' ? '#ppcp-button' : '#ppcp-button_' + location; - let wrapperName = location.charAt(0).toUpperCase() + location.slice(1); + const wrapperName = location.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(''); const fields = { 'color': inputNamePrefix + '_color', 'shape': inputNamePrefix + '_shape', @@ -323,9 +323,8 @@ document.addEventListener( 'layout': inputNamePrefix + '_layout', } - if (location === 'mini-cart') { + if (document.querySelector(inputNamePrefix + '_height')) { fields['height'] = inputNamePrefix + '_height'; - wrapperName = 'MiniCart'; } createButtonPreview(() => getButtonSettings('#ppcp' + wrapperName + 'ButtonPreview', fields)); @@ -354,5 +353,41 @@ document.addEventListener( }, 'card')); }); } + + // Logic to handle the "Check available features" button. + ((props) => { + const $btn = jQuery(props.button); + + $btn.click(async () => { + $btn.prop('disabled', true); + + const response = await fetch( + props.endpoint, + { + method: 'POST', + credentials: 'same-origin', + headers: { + 'content-type': 'application/json' + }, + body: JSON.stringify( + { + nonce: props.nonce, + } + ) + } + ); + + const responseData = await response.json(); + + if (!responseData.success) { + alert(responseData.data.message); + $btn.prop('disabled', false); + } else { + window.location.reload(); + } + }); + + })(PayPalCommerceGatewaySettings.ajax.refresh_feature_status); + } ); diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 8a0348a80..0edfeb699 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -21,7 +21,8 @@ use WooCommerce\PayPalCommerce\Common\Pattern\SingletonDecorator; use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer; use WooCommerce\PayPalCommerce\Onboarding\State; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\WcGateway\Admin\FeesRenderer; use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn; @@ -76,7 +77,7 @@ return array( $refund_processor = $container->get( 'wcgateway.processor.refunds' ); $state = $container->get( 'onboarding.state' ); $transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' ); $payment_token_repository = $container->get( 'vaulting.repository.payment-token' ); $environment = $container->get( 'onboarding.environment' ); @@ -97,7 +98,9 @@ return array( $payment_token_repository, $logger, $api_shop_country, - $container->get( 'api.endpoint.order' ) + $container->get( 'api.endpoint.order' ), + $container->get( 'api.factory.paypal-checkout-url' ), + $container->get( 'wcgateway.place-order-button-text' ) ); }, 'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway { @@ -109,7 +112,7 @@ return array( $refund_processor = $container->get( 'wcgateway.processor.refunds' ); $state = $container->get( 'onboarding.state' ); $transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); $payments_endpoint = $container->get( 'api.endpoint.payments' ); $logger = $container->get( 'woocommerce.logger.woocommerce' ); $vaulted_credit_card_handler = $container->get( 'vaulting.credit-card-handler' ); @@ -137,18 +140,20 @@ return array( $container->get( 'wcgateway.processor.refunds' ), $container->get( 'onboarding.state' ), $container->get( 'wcgateway.transaction-url-provider' ), - $container->get( 'subscription.helper' ), + $container->get( 'wc-subscriptions.helper' ), $container->get( 'wcgateway.settings.allow_card_button_gateway.default' ), $container->get( 'onboarding.environment' ), $container->get( 'vaulting.repository.payment-token' ), - $container->get( 'woocommerce.logger.woocommerce' ) + $container->get( 'woocommerce.logger.woocommerce' ), + $container->get( 'api.factory.paypal-checkout-url' ), + $container->get( 'wcgateway.place-order-button-text' ) ); }, 'wcgateway.disabler' => static function ( ContainerInterface $container ): DisableGateways { $session_handler = $container->get( 'session.handler' ); $settings = $container->get( 'wcgateway.settings' ); $settings_status = $container->get( 'wcgateway.settings.status' ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); return new DisableGateways( $session_handler, $settings, $settings_status, $subscription_helper ); }, @@ -340,7 +345,7 @@ return array( $settings = $container->get( 'wcgateway.settings' ); $environment = $container->get( 'onboarding.environment' ); $logger = $container->get( 'woocommerce.logger.woocommerce' ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); $order_helper = $container->get( 'api.order-helper' ); return new OrderProcessor( $session_handler, @@ -352,7 +357,10 @@ return array( $logger, $environment, $subscription_helper, - $order_helper + $order_helper, + $container->get( 'api.factory.purchase-unit' ), + $container->get( 'api.factory.payer' ), + $container->get( 'api.factory.shipping-preference' ) ); }, 'wcgateway.processor.refunds' => static function ( ContainerInterface $container ): RefundProcessor { @@ -368,7 +376,7 @@ return array( $logger = $container->get( 'woocommerce.logger.woocommerce' ); $notice = $container->get( 'wcgateway.notice.authorize-order-action' ); $settings = $container->get( 'wcgateway.settings' ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); return new AuthorizedPaymentsProcessor( $order_endpoint, $payments_endpoint, @@ -448,7 +456,7 @@ return array( $onboarding_options_renderer = $container->get( 'onboarding.render-options' ); assert( $onboarding_options_renderer instanceof OnboardingOptionsRenderer ); - $subscription_helper = $container->get( 'subscription.helper' ); + $subscription_helper = $container->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); $fields = array( @@ -996,6 +1004,13 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ) ); }, + 'wcgateway.endpoint.refresh-feature-status' => static function ( ContainerInterface $container ) : RefreshFeatureStatusEndpoint { + return new RefreshFeatureStatusEndpoint( + $container->get( 'wcgateway.settings' ), + new Cache( 'ppcp-timeout' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, 'wcgateway.transaction-url-sandbox' => static function ( ContainerInterface $container ): string { return 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s'; @@ -1158,6 +1173,34 @@ return array( ); }, + 'wcgateway.use-place-order-button' => function ( ContainerInterface $container ) : bool { + /** + * Whether to use the standard "Place order" button with redirect to PayPal instead of the PayPal smart buttons. + */ + return apply_filters( + 'woocommerce_paypal_payments_use_place_order_button', + false + ); + }, + 'wcgateway.place-order-button-text' => function ( ContainerInterface $container ) : string { + /** + * The text for the standard "Place order" button, when the "Place order" button mode is enabled. + */ + return apply_filters( + 'woocommerce_paypal_payments_place_order_button_text', + __( 'Proceed to PayPal', 'woocommerce-paypal-payments' ) + ); + }, + 'wcgateway.place-order-button-description' => function ( ContainerInterface $container ) : string { + /** + * The text for additional description, when the "Place order" button mode is enabled. + */ + return apply_filters( + 'woocommerce_paypal_payments_place_order_button_description', + __( 'Clicking "Proceed to PayPal" will redirect you to PayPal to complete your purchase.', 'woocommerce-paypal-payments' ) + ); + }, + 'wcgateway.helper.vaulting-scope' => static function ( ContainerInterface $container ): bool { try { $token = $container->get( 'api.bearer' )->bearer(); @@ -1379,7 +1422,9 @@ return array( ); }, 'wcgateway.settings.pay-later.default-messaging-locations' => static function( ContainerInterface $container ): array { - return array_keys( $container->get( 'wcgateway.settings.pay-later.messaging-locations' ) ); + $locations = $container->get( 'wcgateway.settings.pay-later.messaging-locations' ); + unset( $locations['home'] ); + return array_keys( $locations ); }, 'wcgateway.settings.pay-later.button-locations' => static function( ContainerInterface $container ): array { $settings = $container->get( 'wcgateway.settings' ); diff --git a/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php b/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php index 37571c184..5fae9c0c9 100644 --- a/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php +++ b/modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php @@ -10,9 +10,11 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcGateway\Assets; use WooCommerce\PayPalCommerce\Onboarding\Environment; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; +use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint; /** * Class SettingsPageAssets @@ -184,7 +186,7 @@ class SettingsPageAssets { } $screen = get_current_screen(); - if ( $screen->id !== 'woocommerce_page_wc-settings' ) { + if ( ! $screen || $screen->id !== 'woocommerce_page_wc-settings' ) { return false; } @@ -237,6 +239,13 @@ class SettingsPageAssets { 'disabled_sources' => $this->disabled_sources, 'all_funding_sources' => $this->all_funding_sources, 'components' => array( 'buttons', 'funding-eligibility', 'messages' ), + 'ajax' => array( + 'refresh_feature_status' => array( + 'endpoint' => \WC_AJAX::get_endpoint( RefreshFeatureStatusEndpoint::ENDPOINT ), + 'nonce' => wp_create_nonce( RefreshFeatureStatusEndpoint::nonce() ), + 'button' => '.ppcp-refresh-feature-status', + ), + ), ) ) ); diff --git a/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php b/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php index 6afa24f31..de07ecfef 100644 --- a/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php +++ b/modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php @@ -11,7 +11,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Checkout; use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; diff --git a/modules/ppcp-wc-gateway/src/Endpoint/RefreshFeatureStatusEndpoint.php b/modules/ppcp-wc-gateway/src/Endpoint/RefreshFeatureStatusEndpoint.php new file mode 100644 index 000000000..5831fcb51 --- /dev/null +++ b/modules/ppcp-wc-gateway/src/Endpoint/RefreshFeatureStatusEndpoint.php @@ -0,0 +1,115 @@ +settings = $settings; + $this->cache = $cache; + $this->logger = $logger; + } + + /** + * Returns the nonce. + * + * @return string + */ + public static function nonce(): string { + return self::ENDPOINT; + } + + /** + * Handles the incoming request. + */ + public function handle_request(): void { + $now = time(); + $last_request_time = $this->cache->get( self::CACHE_KEY ) ?: 0; + $seconds_missing = $last_request_time + self::TIMEOUT - $now; + + if ( ! $this->verify_nonce() ) { + wp_send_json_error( + array( + 'message' => __( 'Expired request.', 'woocommerce-paypal-payments' ), + ) + ); + } + + if ( $seconds_missing > 0 ) { + wp_send_json_error( + array( + 'message' => sprintf( + // translators: %1$s is the number of seconds remaining. + __( 'Wait %1$s seconds before trying again.', 'woocommerce-paypal-payments' ), + $seconds_missing + ), + ) + ); + } + + $this->cache->set( self::CACHE_KEY, $now, self::TIMEOUT ); + do_action( 'woocommerce_paypal_payments_clear_apm_product_status', $this->settings ); + wp_send_json_success(); + } + + /** + * Verifies the nonce. + * + * @return bool + */ + private function verify_nonce(): bool { + $json = json_decode( file_get_contents( 'php://input' ) ?: '', true ); + return wp_verify_nonce( $json['nonce'] ?? '', self::nonce() ) !== false; + } +} diff --git a/modules/ppcp-wc-gateway/src/Endpoint/ReturnUrlEndpoint.php b/modules/ppcp-wc-gateway/src/Endpoint/ReturnUrlEndpoint.php index 3efe16542..9d5f98ec7 100644 --- a/modules/ppcp-wc-gateway/src/Endpoint/ReturnUrlEndpoint.php +++ b/modules/ppcp-wc-gateway/src/Endpoint/ReturnUrlEndpoint.php @@ -85,14 +85,18 @@ class ReturnUrlEndpoint { // phpcs:enable WordPress.Security.NonceVerification.Recommended $order = $this->order_endpoint->order( $token ); + if ( $order->status()->is( OrderStatus::APPROVED ) + || $order->status()->is( OrderStatus::COMPLETED ) + ) { + $this->session_handler->replace_order( $order ); + } + $wc_order_id = (int) $order->purchase_units()[0]->custom_id(); if ( ! $wc_order_id ) { // We cannot finish processing here without WC order, but at least go into the continuation mode. if ( $order->status()->is( OrderStatus::APPROVED ) || $order->status()->is( OrderStatus::COMPLETED ) ) { - $this->session_handler->replace_order( $order ); - wp_safe_redirect( wc_get_checkout_url() ); exit(); } diff --git a/modules/ppcp-wc-gateway/src/Exception/PayPalOrderMissingException.php b/modules/ppcp-wc-gateway/src/Exception/PayPalOrderMissingException.php new file mode 100644 index 000000000..6a14e13dd --- /dev/null +++ b/modules/ppcp-wc-gateway/src/Exception/PayPalOrderMissingException.php @@ -0,0 +1,18 @@ +id = self::ID; - $this->settings_renderer = $settings_renderer; - $this->order_processor = $order_processor; - $this->config = $config; - $this->session_handler = $session_handler; - $this->refund_processor = $refund_processor; - $this->state = $state; - $this->transaction_url_provider = $transaction_url_provider; - $this->subscription_helper = $subscription_helper; - $this->default_enabled = $default_enabled; - $this->environment = $environment; - $this->onboarded = $state->current_state() === State::STATE_ONBOARDED; - $this->payment_token_repository = $payment_token_repository; - $this->logger = $logger; + $this->id = self::ID; + $this->settings_renderer = $settings_renderer; + $this->order_processor = $order_processor; + $this->config = $config; + $this->session_handler = $session_handler; + $this->refund_processor = $refund_processor; + $this->state = $state; + $this->transaction_url_provider = $transaction_url_provider; + $this->subscription_helper = $subscription_helper; + $this->default_enabled = $default_enabled; + $this->environment = $environment; + $this->onboarded = $state->current_state() === State::STATE_ONBOARDED; + $this->payment_token_repository = $payment_token_repository; + $this->logger = $logger; + $this->paypal_checkout_url_factory = $paypal_checkout_url_factory; + $this->order_button_text = $place_order_button_text; $this->supports = array( 'refunds', @@ -294,18 +308,20 @@ class CardButtonGateway extends \WC_Payment_Gateway { //phpcs:enable WordPress.Security.NonceVerification.Recommended try { - if ( ! $this->order_processor->process( $wc_order ) ) { - return $this->handle_payment_failure( - $wc_order, - new Exception( - $this->order_processor->last_error() - ) + try { + $this->order_processor->process( $wc_order ); + + do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order ); + + return $this->handle_payment_success( $wc_order ); + } catch ( PayPalOrderMissingException $exc ) { + $order = $this->order_processor->create_order( $wc_order ); + + return array( + 'result' => 'success', + 'redirect' => ( $this->paypal_checkout_url_factory )( $order->id() ), ); } - - do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order ); - - return $this->handle_payment_success( $wc_order ); } catch ( PayPalApiException $error ) { return $this->handle_payment_failure( $wc_order, @@ -315,7 +331,7 @@ class CardButtonGateway extends \WC_Payment_Gateway { $error ) ); - } catch ( RuntimeException $error ) { + } catch ( Exception $error ) { return $this->handle_payment_failure( $wc_order, $error ); } } diff --git a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php index 1b99b9d05..5b35aef1a 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php @@ -11,14 +11,14 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway; use Exception; use Psr\Log\LoggerInterface; -use WC_Customer; use WC_Order; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; use WooCommerce\PayPalCommerce\Vaulting\VaultedCreditCardHandler; use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException; @@ -32,7 +32,7 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; */ class CreditCardGateway extends \WC_Payment_Gateway_CC { - use ProcessPaymentTrait, GatewaySettingsRendererTrait; + use ProcessPaymentTrait, GatewaySettingsRendererTrait, TransactionIdHandlingTrait; const ID = 'ppcp-credit-card-gateway'; @@ -181,18 +181,25 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { ); if ( $this->config->has( 'vault_enabled_dcc' ) && $this->config->get( 'vault_enabled_dcc' ) ) { - array_push( + $supports = apply_filters( + 'woocommerce_paypal_payments_credit_card_gateway_vault_supports', + array( + 'subscriptions', + 'subscription_cancellation', + 'subscription_suspension', + 'subscription_reactivation', + 'subscription_amount_changes', + 'subscription_date_changes', + 'subscription_payment_method_change', + 'subscription_payment_method_change_customer', + 'subscription_payment_method_change_admin', + 'multiple_subscriptions', + ) + ); + + $this->supports = array_merge( $this->supports, - 'subscriptions', - 'subscription_cancellation', - 'subscription_suspension', - 'subscription_reactivation', - 'subscription_amount_changes', - 'subscription_date_changes', - 'subscription_payment_method_change', - 'subscription_payment_method_change_customer', - 'subscription_payment_method_change_admin', - 'multiple_subscriptions' + $supports ); } } @@ -358,6 +365,17 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { ); } + $saved_payment_card = WC()->session->get( 'ppcp_saved_payment_card' ); + if ( $saved_payment_card ) { + if ( $saved_payment_card['payment_source'] === 'card' && $saved_payment_card['status'] === 'COMPLETED' ) { + $this->update_transaction_id( $saved_payment_card['order_id'], $wc_order ); + $wc_order->payment_complete(); + WC()->session->set( 'ppcp_saved_payment_card', null ); + + return $this->handle_payment_success( $wc_order ); + } + } + /** * If customer has chosen a saved credit card payment. */ @@ -387,14 +405,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { //phpcs:enable WordPress.Security.NonceVerification.Recommended try { - if ( ! $this->order_processor->process( $wc_order ) ) { - return $this->handle_payment_failure( - $wc_order, - new Exception( - $this->order_processor->last_error() - ) - ); - } + $this->order_processor->process( $wc_order ); do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order ); @@ -408,7 +419,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { $error ) ); - } catch ( RuntimeException $error ) { + } catch ( Exception $error ) { return $this->handle_payment_failure( $wc_order, $error ); } } diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php index b17e48a7a..741436c22 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php @@ -20,10 +20,11 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException; +use WooCommerce\PayPalCommerce\WcGateway\Exception\PayPalOrderMissingException; use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway; use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait; @@ -163,24 +164,33 @@ class PayPalGateway extends \WC_Payment_Gateway { */ private $order_endpoint; + /** + * The function return the PayPal checkout URL for the given order ID. + * + * @var callable(string):string + */ + private $paypal_checkout_url_factory; + /** * PayPalGateway constructor. * - * @param SettingsRenderer $settings_renderer The Settings Renderer. - * @param FundingSourceRenderer $funding_source_renderer The funding source renderer. - * @param OrderProcessor $order_processor The Order Processor. - * @param ContainerInterface $config The settings. - * @param SessionHandler $session_handler The Session Handler. - * @param RefundProcessor $refund_processor The Refund Processor. - * @param State $state The state. - * @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order. - * @param SubscriptionHelper $subscription_helper The subscription helper. - * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page. - * @param Environment $environment The environment. - * @param PaymentTokenRepository $payment_token_repository The payment token repository. - * @param LoggerInterface $logger The logger. - * @param string $api_shop_country The api shop country. - * @param OrderEndpoint $order_endpoint The order endpoint. + * @param SettingsRenderer $settings_renderer The Settings Renderer. + * @param FundingSourceRenderer $funding_source_renderer The funding source renderer. + * @param OrderProcessor $order_processor The Order Processor. + * @param ContainerInterface $config The settings. + * @param SessionHandler $session_handler The Session Handler. + * @param RefundProcessor $refund_processor The Refund Processor. + * @param State $state The state. + * @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order. + * @param SubscriptionHelper $subscription_helper The subscription helper. + * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page. + * @param Environment $environment The environment. + * @param PaymentTokenRepository $payment_token_repository The payment token repository. + * @param LoggerInterface $logger The logger. + * @param string $api_shop_country The api shop country. + * @param OrderEndpoint $order_endpoint The order endpoint. + * @param callable(string):string $paypal_checkout_url_factory The function return the PayPal checkout URL for the given order ID. + * @param string $place_order_button_text The text for the standard "Place order" button. */ public function __construct( SettingsRenderer $settings_renderer, @@ -197,24 +207,28 @@ class PayPalGateway extends \WC_Payment_Gateway { PaymentTokenRepository $payment_token_repository, LoggerInterface $logger, string $api_shop_country, - OrderEndpoint $order_endpoint + OrderEndpoint $order_endpoint, + callable $paypal_checkout_url_factory, + string $place_order_button_text ) { - $this->id = self::ID; - $this->settings_renderer = $settings_renderer; - $this->funding_source_renderer = $funding_source_renderer; - $this->order_processor = $order_processor; - $this->config = $config; - $this->session_handler = $session_handler; - $this->refund_processor = $refund_processor; - $this->state = $state; - $this->transaction_url_provider = $transaction_url_provider; - $this->subscription_helper = $subscription_helper; - $this->page_id = $page_id; - $this->environment = $environment; - $this->onboarded = $state->current_state() === State::STATE_ONBOARDED; - $this->payment_token_repository = $payment_token_repository; - $this->logger = $logger; - $this->api_shop_country = $api_shop_country; + $this->id = self::ID; + $this->settings_renderer = $settings_renderer; + $this->funding_source_renderer = $funding_source_renderer; + $this->order_processor = $order_processor; + $this->config = $config; + $this->session_handler = $session_handler; + $this->refund_processor = $refund_processor; + $this->state = $state; + $this->transaction_url_provider = $transaction_url_provider; + $this->subscription_helper = $subscription_helper; + $this->page_id = $page_id; + $this->environment = $environment; + $this->onboarded = $state->current_state() === State::STATE_ONBOARDED; + $this->payment_token_repository = $payment_token_repository; + $this->logger = $logger; + $this->api_shop_country = $api_shop_country; + $this->paypal_checkout_url_factory = $paypal_checkout_url_factory; + $this->order_button_text = $place_order_button_text; if ( $this->onboarded ) { $this->supports = array( 'refunds', 'tokenization' ); @@ -261,8 +275,9 @@ class PayPalGateway extends \WC_Payment_Gateway { if ( $order && ( $order->status()->is( OrderStatus::APPROVED ) || $order->status()->is( OrderStatus::COMPLETED ) ) ) { - $this->title = $this->funding_source_renderer->render_name( $funding_source ); - $this->description = $this->funding_source_renderer->render_description( $funding_source ); + $this->title = $this->funding_source_renderer->render_name( $funding_source ); + $this->description = $this->funding_source_renderer->render_description( $funding_source ); + $this->order_button_text = null; } } @@ -546,19 +561,20 @@ class PayPalGateway extends \WC_Payment_Gateway { return $this->handle_payment_success( $wc_order ); } + try { + $this->order_processor->process( $wc_order ); - if ( ! $this->order_processor->process( $wc_order ) ) { - return $this->handle_payment_failure( - $wc_order, - new Exception( - $this->order_processor->last_error() - ) + do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order ); + + return $this->handle_payment_success( $wc_order ); + } catch ( PayPalOrderMissingException $exc ) { + $order = $this->order_processor->create_order( $wc_order ); + + return array( + 'result' => 'success', + 'redirect' => ( $this->paypal_checkout_url_factory )( $order->id() ), ); } - - do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order ); - - return $this->handle_payment_success( $wc_order ); } catch ( PayPalApiException $error ) { $retry_keys_messages = array( 'INSTRUMENT_DECLINED' => __( 'Instrument declined.', 'woocommerce-paypal-payments' ), @@ -593,12 +609,9 @@ class PayPalGateway extends \WC_Payment_Gateway { ); } - $host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ? - 'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/'; - $url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id(); return array( 'result' => 'success', - 'redirect' => $url, + 'redirect' => ( $this->paypal_checkout_url_factory )( $this->session_handler->order()->id() ), ); } @@ -610,7 +623,7 @@ class PayPalGateway extends \WC_Payment_Gateway { $error ) ); - } catch ( RuntimeException $error ) { + } catch ( Exception $error ) { return $this->handle_payment_failure( $wc_order, $error ); } } diff --git a/modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php b/modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php index db86034d6..e84a80b92 100644 --- a/modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php +++ b/modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php @@ -22,7 +22,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\Money; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice; diff --git a/modules/ppcp-wc-gateway/src/Processor/OrderMetaTrait.php b/modules/ppcp-wc-gateway/src/Processor/OrderMetaTrait.php index 47348eca3..b18468d7b 100644 --- a/modules/ppcp-wc-gateway/src/Processor/OrderMetaTrait.php +++ b/modules/ppcp-wc-gateway/src/Processor/OrderMetaTrait.php @@ -59,12 +59,7 @@ trait OrderMetaTrait { private function get_payment_source( Order $order ): ?string { $source = $order->payment_source(); if ( $source ) { - if ( $source->card() ) { - return 'card'; - } - if ( $source->wallet() ) { - return 'wallet'; - } + return $source->name(); } return null; diff --git a/modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php b/modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php index 1fb10ed8c..26defd836 100644 --- a/modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php +++ b/modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php @@ -9,19 +9,26 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcGateway\Processor; +use Exception; use Psr\Log\LoggerInterface; use WC_Order; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; +use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory; +use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; +use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; +use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory; use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderHelper; use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure; use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; +use WooCommerce\PayPalCommerce\WcGateway\Exception\PayPalOrderMissingException; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; @@ -88,13 +95,6 @@ class OrderProcessor { */ private $settings; - /** - * The last error. - * - * @var string - */ - private $last_error = ''; - /** * A logger. * @@ -116,6 +116,27 @@ class OrderProcessor { */ private $order_helper; + /** + * The PurchaseUnit factory. + * + * @var PurchaseUnitFactory + */ + private $purchase_unit_factory; + + /** + * The payer factory. + * + * @var PayerFactory + */ + private $payer_factory; + + /** + * The shipping_preference factory. + * + * @var ShippingPreferenceFactory + */ + private $shipping_preference_factory; + /** * Array to store temporary order data changes to restore after processing. * @@ -136,6 +157,9 @@ class OrderProcessor { * @param Environment $environment The environment. * @param SubscriptionHelper $subscription_helper The subscription helper. * @param OrderHelper $order_helper The order helper. + * @param PurchaseUnitFactory $purchase_unit_factory The PurchaseUnit factory. + * @param PayerFactory $payer_factory The payer factory. + * @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory. */ public function __construct( SessionHandler $session_handler, @@ -147,7 +171,10 @@ class OrderProcessor { LoggerInterface $logger, Environment $environment, SubscriptionHelper $subscription_helper, - OrderHelper $order_helper + OrderHelper $order_helper, + PurchaseUnitFactory $purchase_unit_factory, + PayerFactory $payer_factory, + ShippingPreferenceFactory $shipping_preference_factory ) { $this->session_handler = $session_handler; @@ -160,60 +187,57 @@ class OrderProcessor { $this->logger = $logger; $this->subscription_helper = $subscription_helper; $this->order_helper = $order_helper; + $this->purchase_unit_factory = $purchase_unit_factory; + $this->payer_factory = $payer_factory; + $this->shipping_preference_factory = $shipping_preference_factory; } /** * Processes a given WooCommerce order and captured/authorizes the connected PayPal orders. * - * @param \WC_Order $wc_order The WooCommerce order. + * @param WC_Order $wc_order The WooCommerce order. * - * @return bool + * @throws PayPalOrderMissingException If no PayPal order. + * @throws Exception If processing fails. */ - public function process( \WC_Order $wc_order ): bool { - // phpcs:ignore WordPress.Security.NonceVerification - $order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY ) ?: wc_clean( wp_unslash( $_POST['paypal_order_id'] ?? '' ) ); - $order = $this->session_handler->order(); - if ( ! $order && is_string( $order_id ) && $order_id ) { - $order = $this->order_endpoint->order( $order_id ); - } + public function process( WC_Order $wc_order ): void { + $order = $this->session_handler->order(); if ( ! $order ) { - $order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY ); - if ( ! $order_id ) { + // phpcs:ignore WordPress.Security.NonceVerification + $order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY ) ?: wc_clean( wp_unslash( $_POST['paypal_order_id'] ?? '' ) ); + if ( is_string( $order_id ) && $order_id ) { + try { + $order = $this->order_endpoint->order( $order_id ); + } catch ( RuntimeException $exception ) { + throw new Exception( __( 'Could not retrieve PayPal order.', 'woocommerce-paypal-payments' ) ); + } + } else { $this->logger->warning( sprintf( 'No PayPal order ID found in order #%d meta.', $wc_order->get_id() ) ); - $this->last_error = __( 'Could not retrieve order. Maybe it was already completed or this browser is not supported. Please check your email or try again with a different browser.', 'woocommerce-paypal-payments' ); - return false; - } - try { - $order = $this->order_endpoint->order( $order_id ); - } catch ( RuntimeException $exception ) { - $this->last_error = __( 'Could not retrieve PayPal order.', 'woocommerce-paypal-payments' ); - return false; + throw new PayPalOrderMissingException( + __( + 'Could not retrieve order. Maybe it was already completed or this browser is not supported. Please check your email or try again with a different browser.', + 'woocommerce-paypal-payments' + ) + ); } } $this->add_paypal_meta( $wc_order, $order, $this->environment ); - $error_message = null; if ( $this->order_helper->contains_physical_goods( $order ) && ! $this->order_is_ready_for_process( $order ) ) { - $error_message = __( - 'The payment is not ready for processing yet.', - 'woocommerce-paypal-payments' + throw new Exception( + __( + 'The payment is not ready for processing yet.', + 'woocommerce-paypal-payments' + ) ); } - if ( $error_message ) { - $this->last_error = sprintf( - // translators: %s is the message of the error. - __( 'Payment error: %s', 'woocommerce-paypal-payments' ), - $error_message - ); - return false; - } $order = $this->patch_order( $wc_order, $order ); @@ -242,8 +266,30 @@ class OrderProcessor { if ( $this->capture_authorized_downloads( $order ) ) { $this->authorized_payments_processor->capture_authorized_payment( $wc_order ); } - $this->last_error = ''; - return true; + + do_action( 'woocommerce_paypal_payments_after_order_processor', $wc_order, $order ); + } + + /** + * Creates a PayPal order for the given WC order. + * + * @param WC_Order $wc_order The WC order. + * @return Order + * @throws RuntimeException If order creation fails. + */ + public function create_order( WC_Order $wc_order ): Order { + $pu = $this->purchase_unit_factory->from_wc_order( $wc_order ); + $shipping_preference = $this->shipping_preference_factory->from_state( $pu, 'checkout' ); + $order = $this->order_endpoint->create( + array( $pu ), + $shipping_preference, + $this->payer_factory->from_wc_order( $wc_order ), + null, + '', + ApplicationContext::USER_ACTION_PAY_NOW + ); + + return $order; } /** @@ -280,25 +326,15 @@ class OrderProcessor { return true; } - /** - * Returns the last error. - * - * @return string - */ - public function last_error(): string { - - return $this->last_error; - } - /** * Patches a given PayPal order with a WooCommerce order. * - * @param \WC_Order $wc_order The WooCommerce order. - * @param Order $order The PayPal order. + * @param WC_Order $wc_order The WooCommerce order. + * @param Order $order The PayPal order. * * @return Order */ - public function patch_order( \WC_Order $wc_order, Order $order ): Order { + public function patch_order( WC_Order $wc_order, Order $order ): Order { $this->apply_outbound_order_filters( $wc_order ); $updated_order = $this->order_factory->from_wc_order( $wc_order, $order ); $this->restore_order_from_filters( $wc_order ); @@ -316,12 +352,16 @@ class OrderProcessor { * @return bool */ private function order_is_ready_for_process( Order $order ): bool { - if ( $order->status()->is( OrderStatus::APPROVED ) || $order->status()->is( OrderStatus::CREATED ) ) { return true; } - if ( ! $order->payment_source() || ! $order->payment_source()->card() ) { + $payment_source = $order->payment_source(); + if ( ! $payment_source ) { + return false; + } + + if ( $payment_source->name() !== 'card' ) { return false; } diff --git a/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php b/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php index 4a7e3ac6a..d9513f9c6 100644 --- a/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php +++ b/modules/ppcp-wc-gateway/src/Settings/Fields/connection-tab-fields.php @@ -390,6 +390,16 @@ return function ( ContainerInterface $container, array $fields ): array { '' ), ), + 'refresh_feature_status' => array( + 'title' => __( 'Refresh feature availability status', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-text', + 'text' => '', + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => Settings::CONNECTION_TAB_ID, + ), 'ppcp_dcc_status' => array( 'title' => __( 'Advanced Credit and Debit Card Payments', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-text', diff --git a/modules/ppcp-wc-gateway/src/Settings/Fields/paypal-smart-button-fields.php b/modules/ppcp-wc-gateway/src/Settings/Fields/paypal-smart-button-fields.php index b5a7e527c..aad87730f 100644 --- a/modules/ppcp-wc-gateway/src/Settings/Fields/paypal-smart-button-fields.php +++ b/modules/ppcp-wc-gateway/src/Settings/Fields/paypal-smart-button-fields.php @@ -802,6 +802,242 @@ return function ( ContainerInterface $container, array $fields ): array { 'requirements' => array(), 'gateway' => 'paypal', ), + + // Block express checkout settings. + 'button_checkout-block-express_heading' => array( + 'heading' => __( 'Block Express Checkout Buttons', 'woocommerce-paypal-payments' ), + 'description' => sprintf( + // translators: %1$s and %2$s are the opening and closing of HTML tag. + __( + 'Customize the appearance of the PayPal smart buttons on the %1$sBlock Express Checkout%2$s.', + 'woocommerce-paypal-payments' + ), + '', + '' + ), + 'type' => 'ppcp-heading', + 'screens' => array( State::STATE_START, State::STATE_ONBOARDED ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_checkout-block-express_label' => array( + 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ), + 'type' => 'select', + 'class' => array(), + 'input_class' => array( 'wc-enhanced-select' ), + /** + * Returns default label ID of the PayPal button in block express checkout. + */ + 'default' => apply_filters( 'woocommerce_paypal_payments_button_checkout_block_express_label_default', 'paypal' ), + 'desc_tip' => true, + 'description' => __( + 'This controls the label on the primary button.', + 'woocommerce-paypal-payments' + ), + 'options' => array( + 'paypal' => __( 'PayPal', 'woocommerce-paypal-payments' ), + 'checkout' => __( 'Checkout', 'woocommerce-paypal-payments' ), + 'buynow' => __( 'PayPal Buy Now', 'woocommerce-paypal-payments' ), + 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ), + ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_checkout-block-express_color' => array( + 'title' => __( 'Color', 'woocommerce-paypal-payments' ), + 'type' => 'select', + 'class' => array(), + 'input_class' => array( 'wc-enhanced-select' ), + 'default' => 'gold', + 'desc_tip' => true, + 'description' => __( + 'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.', + 'woocommerce-paypal-payments' + ), + 'options' => array( + 'gold' => __( 'Gold (Recommended)', 'woocommerce-paypal-payments' ), + 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ), + 'silver' => __( 'Silver', 'woocommerce-paypal-payments' ), + 'black' => __( 'Black', 'woocommerce-paypal-payments' ), + 'white' => __( 'White', 'woocommerce-paypal-payments' ), + ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_checkout-block-express_shape' => array( + 'title' => __( 'Shape', 'woocommerce-paypal-payments' ), + 'type' => 'select', + 'class' => array(), + 'input_class' => array( 'wc-enhanced-select' ), + 'default' => 'rect', + 'desc_tip' => true, + 'description' => __( + 'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.', + 'woocommerce-paypal-payments' + ), + 'options' => array( + 'pill' => __( 'Pill', 'woocommerce-paypal-payments' ), + 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ), + ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_checkout-block-express_height' => array( + 'title' => __( 'Button Height', 'woocommerce-paypal-payments' ), + 'type' => 'number', + 'default' => '48', + 'custom_attributes' => array( + 'min' => 40, + 'max' => 55, + ), + 'desc_tip' => true, + 'description' => __( 'Set a value from 40 to 55.', 'woocommerce-paypal-payments' ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_checkout-block-express_preview' => array( + 'type' => 'ppcp-text', + 'text' => $render_preview_element( 'ppcpCheckoutBlockExpressButtonPreview' ), + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + + // Block cart settings. + 'button_cart-block_heading' => array( + 'heading' => __( 'Block Cart Buttons', 'woocommerce-paypal-payments' ), + 'description' => sprintf( + // translators: %1$s and %2$s are the opening and closing of HTML tag. + __( + 'Customize the appearance of the PayPal smart buttons on the %1$sBlock Cart%2$s.', + 'woocommerce-paypal-payments' + ), + '', + '' + ), + 'type' => 'ppcp-heading', + 'screens' => array( State::STATE_START, State::STATE_ONBOARDED ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_cart-block_label' => array( + 'title' => __( 'Button Label', 'woocommerce-paypal-payments' ), + 'type' => 'select', + 'class' => array(), + 'input_class' => array( 'wc-enhanced-select' ), + /** + * Returns default label ID of the PayPal button in block cart. + */ + 'default' => apply_filters( 'woocommerce_paypal_payments_button_cart_block_label_default', 'paypal' ), + 'desc_tip' => true, + 'description' => __( + 'This controls the label on the primary button.', + 'woocommerce-paypal-payments' + ), + 'options' => array( + 'paypal' => __( 'PayPal', 'woocommerce-paypal-payments' ), + 'checkout' => __( 'Checkout', 'woocommerce-paypal-payments' ), + 'buynow' => __( 'PayPal Buy Now', 'woocommerce-paypal-payments' ), + 'pay' => __( 'Pay with PayPal', 'woocommerce-paypal-payments' ), + ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_cart-block_color' => array( + 'title' => __( 'Color', 'woocommerce-paypal-payments' ), + 'type' => 'select', + 'class' => array(), + 'input_class' => array( 'wc-enhanced-select' ), + 'default' => 'gold', + 'desc_tip' => true, + 'description' => __( + 'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.', + 'woocommerce-paypal-payments' + ), + 'options' => array( + 'gold' => __( 'Gold (Recommended)', 'woocommerce-paypal-payments' ), + 'blue' => __( 'Blue', 'woocommerce-paypal-payments' ), + 'silver' => __( 'Silver', 'woocommerce-paypal-payments' ), + 'black' => __( 'Black', 'woocommerce-paypal-payments' ), + 'white' => __( 'White', 'woocommerce-paypal-payments' ), + ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_cart-block_shape' => array( + 'title' => __( 'Shape', 'woocommerce-paypal-payments' ), + 'type' => 'select', + 'class' => array(), + 'input_class' => array( 'wc-enhanced-select' ), + 'default' => 'rect', + 'desc_tip' => true, + 'description' => __( + 'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.', + 'woocommerce-paypal-payments' + ), + 'options' => array( + 'pill' => __( 'Pill', 'woocommerce-paypal-payments' ), + 'rect' => __( 'Rectangle', 'woocommerce-paypal-payments' ), + ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_cart-block_height' => array( + 'title' => __( 'Button Height', 'woocommerce-paypal-payments' ), + 'type' => 'number', + 'default' => '48', + 'custom_attributes' => array( + 'min' => 40, + 'max' => 55, + ), + 'desc_tip' => true, + 'description' => __( 'Set a value from 40 to 55.', 'woocommerce-paypal-payments' ), + 'screens' => array( + State::STATE_START, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'button_cart-block_preview' => array( + 'type' => 'ppcp-text', + 'text' => $render_preview_element( 'ppcpCartBlockButtonPreview' ), + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), ); return array_merge( $fields, $smart_button_fields ); diff --git a/modules/ppcp-wc-gateway/src/WCGatewayModule.php b/modules/ppcp-wc-gateway/src/WCGatewayModule.php index 66587d6af..6af49c778 100644 --- a/modules/ppcp-wc-gateway/src/WCGatewayModule.php +++ b/modules/ppcp-wc-gateway/src/WCGatewayModule.php @@ -13,7 +13,8 @@ use Psr\Log\LoggerInterface; use Throwable; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider; use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface; use WC_Order; @@ -177,7 +178,7 @@ class WCGatewayModule implements ModuleInterface { $assets = new SettingsPageAssets( $c->get( 'wcgateway.url' ), $c->get( 'ppcp.asset-version' ), - $c->get( 'subscription.helper' ), + $c->get( 'wc-subscriptions.helper' ), $c->get( 'button.client_id_for_admin' ), $c->get( 'api.shop.currency' ), $c->get( 'api.shop.country' ), @@ -255,6 +256,16 @@ class WCGatewayModule implements ModuleInterface { } ); + add_action( + 'wc_ajax_' . RefreshFeatureStatusEndpoint::ENDPOINT, + static function () use ( $c ) { + $endpoint = $c->get( 'wcgateway.endpoint.refresh-feature-status' ); + assert( $endpoint instanceof RefreshFeatureStatusEndpoint ); + + $endpoint->handle_request(); + } + ); + add_action( 'woocommerce_paypal_payments_gateway_migrate', static function () use ( $c ) { diff --git a/modules/ppcp-subscription/.gitignore b/modules/ppcp-wc-subscriptions/.gitignore similarity index 100% rename from modules/ppcp-subscription/.gitignore rename to modules/ppcp-wc-subscriptions/.gitignore diff --git a/modules/ppcp-wc-subscriptions/composer.json b/modules/ppcp-wc-subscriptions/composer.json new file mode 100644 index 000000000..3cf50034b --- /dev/null +++ b/modules/ppcp-wc-subscriptions/composer.json @@ -0,0 +1,17 @@ +{ + "name": "woocommerce/ppcp-wc-subscriptions", + "type": "dhii-mod", + "description": "Module for WC Subscriptions plugin integration", + "license": "GPL-2.0", + "require": { + "php": "^7.2 | ^8.0", + "dhii/module-interface": "^0.3.0-alpha1" + }, + "autoload": { + "psr-4": { + "WooCommerce\\PayPalCommerce\\WcSubscriptions\\": "src" + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/modules/ppcp-subscription/extensions.php b/modules/ppcp-wc-subscriptions/extensions.php similarity index 58% rename from modules/ppcp-subscription/extensions.php rename to modules/ppcp-wc-subscriptions/extensions.php index 37b6d423a..d9df212e7 100644 --- a/modules/ppcp-subscription/extensions.php +++ b/modules/ppcp-wc-subscriptions/extensions.php @@ -2,7 +2,7 @@ /** * The extensions. * - * @package WooCommerce\PayPalCommerce\Subscription + * @package WooCommerce\PayPalCommerce\WcSubscriptions */ declare(strict_types=1); diff --git a/modules/ppcp-subscription/module.php b/modules/ppcp-wc-subscriptions/module.php similarity index 55% rename from modules/ppcp-subscription/module.php rename to modules/ppcp-wc-subscriptions/module.php index 1db299a49..a298bac91 100644 --- a/modules/ppcp-subscription/module.php +++ b/modules/ppcp-wc-subscriptions/module.php @@ -2,15 +2,15 @@ /** * The module. * - * @package WooCommerce\PayPalCommerce\Subscription + * @package WooCommerce\PayPalCommerce\WcSubscriptions */ declare(strict_types=1); -namespace WooCommerce\PayPalCommerce\Subscription; +namespace WooCommerce\PayPalCommerce\WcSubscriptions; use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface; return static function (): ModuleInterface { - return new SubscriptionModule(); + return new WcSubscriptionsModule(); }; diff --git a/modules/ppcp-wc-subscriptions/services.php b/modules/ppcp-wc-subscriptions/services.php new file mode 100644 index 000000000..47aaf1772 --- /dev/null +++ b/modules/ppcp-wc-subscriptions/services.php @@ -0,0 +1,48 @@ + static function ( ContainerInterface $container ): SubscriptionHelper { + return new SubscriptionHelper( $container->get( 'wcgateway.settings' ) ); + }, + 'wc-subscriptions.renewal-handler' => static function ( ContainerInterface $container ): RenewalHandler { + $logger = $container->get( 'woocommerce.logger.woocommerce' ); + $repository = $container->get( 'vaulting.repository.payment-token' ); + $endpoint = $container->get( 'api.endpoint.order' ); + $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' ); + $payer_factory = $container->get( 'api.factory.payer' ); + $environment = $container->get( 'onboarding.environment' ); + $settings = $container->get( 'wcgateway.settings' ); + $authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' ); + return new RenewalHandler( + $logger, + $repository, + $endpoint, + $purchase_unit_factory, + $container->get( 'api.factory.shipping-preference' ), + $payer_factory, + $environment, + $settings, + $authorized_payments_processor + ); + }, + 'wc-subscriptions.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository { + $factory = $container->get( 'api.factory.payment-token' ); + $endpoint = $container->get( 'api.endpoint.payment-token' ); + return new PaymentTokenRepository( $factory, $endpoint ); + }, +); diff --git a/modules/ppcp-subscription/src/FreeTrialHandlerTrait.php b/modules/ppcp-wc-subscriptions/src/FreeTrialHandlerTrait.php similarity index 95% rename from modules/ppcp-subscription/src/FreeTrialHandlerTrait.php rename to modules/ppcp-wc-subscriptions/src/FreeTrialHandlerTrait.php index d528ff554..f36851781 100644 --- a/modules/ppcp-subscription/src/FreeTrialHandlerTrait.php +++ b/modules/ppcp-wc-subscriptions/src/FreeTrialHandlerTrait.php @@ -2,12 +2,12 @@ /** * Helper trait for the subscriptions handling. * - * @package WooCommerce\PayPalCommerce\Subscription + * @package WooCommerce\PayPalCommerce\WcSubscriptions */ declare(strict_types=1); -namespace WooCommerce\PayPalCommerce\Subscription; +namespace WooCommerce\PayPalCommerce\WcSubscriptions; use WC_Order; use WC_Subscriptions_Product; diff --git a/modules/ppcp-subscription/src/Helper/SubscriptionHelper.php b/modules/ppcp-wc-subscriptions/src/Helper/SubscriptionHelper.php similarity index 98% rename from modules/ppcp-subscription/src/Helper/SubscriptionHelper.php rename to modules/ppcp-wc-subscriptions/src/Helper/SubscriptionHelper.php index b71156f86..4d4f1a956 100644 --- a/modules/ppcp-subscription/src/Helper/SubscriptionHelper.php +++ b/modules/ppcp-wc-subscriptions/src/Helper/SubscriptionHelper.php @@ -4,12 +4,12 @@ * whether the cart contains a subscription, the current product is * a subscription or the subscription plugin is activated in the first place. * - * @package WooCommerce\PayPalCommerce\Subscription\Helper + * @package WooCommerce\PayPalCommerce\WcSubscriptions\Helper */ declare(strict_types=1); -namespace WooCommerce\PayPalCommerce\Subscription\Helper; +namespace WooCommerce\PayPalCommerce\WcSubscriptions\Helper; use WC_Product; use WC_Product_Subscription_Variation; diff --git a/modules/ppcp-subscription/src/RenewalHandler.php b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php similarity index 77% rename from modules/ppcp-subscription/src/RenewalHandler.php rename to modules/ppcp-wc-subscriptions/src/RenewalHandler.php index f4a9a6cbd..7440074f9 100644 --- a/modules/ppcp-subscription/src/RenewalHandler.php +++ b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php @@ -2,16 +2,18 @@ /** * Handles subscription renewals. * - * @package WooCommerce\PayPalCommerce\Subscription + * @package WooCommerce\PayPalCommerce\WcSubscriptions */ declare(strict_types=1); -namespace WooCommerce\PayPalCommerce\Subscription; +namespace WooCommerce\PayPalCommerce\WcSubscriptions; use WC_Subscription; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; +use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; +use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; @@ -21,6 +23,7 @@ use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; +use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor; use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait; use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait; @@ -181,13 +184,8 @@ class RenewalHandler { * @throws \Exception If customer cannot be read/found. */ private function process_order( \WC_Order $wc_order ): void { - $user_id = (int) $wc_order->get_customer_id(); $customer = new \WC_Customer( $user_id ); - $token = $this->get_token_for_customer( $customer, $wc_order ); - if ( ! $token ) { - return; - } $purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order ); $payer = $this->payer_factory->from_customer( $customer ); @@ -196,36 +194,86 @@ class RenewalHandler { 'renewal' ); + $token = $this->get_token_for_customer( $customer, $wc_order ); + if ( $token ) { + if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) { + $stored_credentials = array( + 'payment_initiator' => 'MERCHANT', + 'payment_type' => 'RECURRING', + 'usage' => 'SUBSEQUENT', + ); + + $subscriptions = wcs_get_subscriptions_for_renewal_order( $wc_order ); + foreach ( $subscriptions as $post_id => $subscription ) { + $previous_transaction_reference = $subscription->get_meta( 'ppcp_previous_transaction_reference' ); + if ( $previous_transaction_reference ) { + $stored_credentials['previous_transaction_reference'] = $previous_transaction_reference; + break; + } + } + + $payment_source = new PaymentSource( + 'card', + (object) array( + 'vault_id' => $token->id(), + 'stored_credential' => $stored_credentials, + ) + ); + + $order = $this->order_endpoint->create( + array( $purchase_unit ), + $shipping_preference, + $payer, + null, + '', + ApplicationContext::USER_ACTION_CONTINUE, + '', + array(), + $payment_source + ); + + $this->handle_paypal_order( $wc_order, $order ); + + $this->logger->info( + sprintf( + 'Renewal for order %d is completed.', + $wc_order->get_id() + ) + ); + + return; + } + + $order = $this->order_endpoint->create( + array( $purchase_unit ), + $shipping_preference, + $payer, + $token + ); + + $this->handle_paypal_order( $wc_order, $order ); + + $this->logger->info( + sprintf( + 'Renewal for order %d is completed.', + $wc_order->get_id() + ) + ); + + return; + } + + if ( apply_filters( 'woocommerce_paypal_payments_subscription_renewal_return_before_create_order_without_token', true ) ) { + return; + } + $order = $this->order_endpoint->create( array( $purchase_unit ), $shipping_preference, - $payer, - $token + $payer ); - $this->add_paypal_meta( $wc_order, $order, $this->environment ); - - if ( $order->intent() === 'AUTHORIZE' ) { - $order = $this->order_endpoint->authorize( $order ); - $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' ); - } - - $transaction_id = $this->get_paypal_order_transaction_id( $order ); - if ( $transaction_id ) { - $this->update_transaction_id( $transaction_id, $wc_order ); - - $subscriptions = wcs_get_subscriptions_for_order( $wc_order->get_id(), array( 'order_type' => 'any' ) ); - foreach ( $subscriptions as $id => $subscription ) { - $subscription->update_meta_data( 'ppcp_previous_transaction_reference', $transaction_id ); - $subscription->save(); - } - } - - $this->handle_new_order_status( $order, $wc_order ); - - if ( $this->capture_authorized_downloads( $order ) ) { - $this->authorized_payments_processor->capture_authorized_payment( $wc_order ); - } + $this->handle_paypal_order( $wc_order, $order ); $this->logger->info( sprintf( @@ -317,4 +365,38 @@ class RenewalHandler { } return true; } + + /** + * Handles PayPal order creation and updates WC order accordingly. + * + * @param \WC_Order $wc_order WC order. + * @param Order $order PayPal order. + * @return void + * @throws NotFoundException When something goes wrong while handling the order. + */ + private function handle_paypal_order( \WC_Order $wc_order, Order $order ): void { + $this->add_paypal_meta( $wc_order, $order, $this->environment ); + + if ( $order->intent() === 'AUTHORIZE' ) { + $order = $this->order_endpoint->authorize( $order ); + $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' ); + } + + $transaction_id = $this->get_paypal_order_transaction_id( $order ); + if ( $transaction_id ) { + $this->update_transaction_id( $transaction_id, $wc_order ); + + $subscriptions = wcs_get_subscriptions_for_order( $wc_order->get_id(), array( 'order_type' => 'any' ) ); + foreach ( $subscriptions as $id => $subscription ) { + $subscription->update_meta_data( 'ppcp_previous_transaction_reference', $transaction_id ); + $subscription->save(); + } + } + + $this->handle_new_order_status( $order, $wc_order ); + + if ( $this->capture_authorized_downloads( $order ) ) { + $this->authorized_payments_processor->capture_authorized_payment( $wc_order ); + } + } } diff --git a/modules/ppcp-subscription/src/SubscriptionsHandlerTrait.php b/modules/ppcp-wc-subscriptions/src/SubscriptionsHandlerTrait.php similarity index 78% rename from modules/ppcp-subscription/src/SubscriptionsHandlerTrait.php rename to modules/ppcp-wc-subscriptions/src/SubscriptionsHandlerTrait.php index ae9b35bfb..47140396a 100644 --- a/modules/ppcp-subscription/src/SubscriptionsHandlerTrait.php +++ b/modules/ppcp-wc-subscriptions/src/SubscriptionsHandlerTrait.php @@ -2,12 +2,12 @@ /** * Helper trait for the free trial subscriptions handling. * - * @package WooCommerce\PayPalCommerce\Subscription + * @package WooCommerce\PayPalCommerce\WcSubscriptions */ declare(strict_types=1); -namespace WooCommerce\PayPalCommerce\Subscription; +namespace WooCommerce\PayPalCommerce\WcSubscriptions; use WC_Subscriptions; diff --git a/modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php b/modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php new file mode 100644 index 000000000..c5fb04541 --- /dev/null +++ b/modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php @@ -0,0 +1,311 @@ +renew( $order, $c ); + }, + 10, + 2 + ); + + add_action( + 'woocommerce_scheduled_subscription_payment_' . CreditCardGateway::ID, + /** + * Param types removed to avoid third-party issues. + * + * @psalm-suppress MissingClosureParamType + */ + function ( $amount, $order ) use ( $c ) { + $this->renew( $order, $c ); + }, + 10, + 2 + ); + + add_action( + 'woocommerce_subscription_payment_complete', + /** + * Param types removed to avoid third-party issues. + * + * @psalm-suppress MissingClosureParamType + */ + function ( $subscription ) use ( $c ) { + $paypal_subscription_id = $subscription->get_meta( 'ppcp_subscription' ) ?? ''; + if ( $paypal_subscription_id ) { + return; + } + + $payment_token_repository = $c->get( 'vaulting.repository.payment-token' ); + $logger = $c->get( 'woocommerce.logger.woocommerce' ); + + $this->add_payment_token_id( $subscription, $payment_token_repository, $logger ); + + if ( count( $subscription->get_related_orders() ) === 1 ) { + $parent_order = $subscription->get_parent(); + if ( is_a( $parent_order, WC_Order::class ) ) { + $order_repository = $c->get( 'api.repository.order' ); + $order = $order_repository->for_wc_order( $parent_order ); + $transaction_id = $this->get_paypal_order_transaction_id( $order ); + if ( $transaction_id ) { + $subscription->update_meta_data( 'ppcp_previous_transaction_reference', $transaction_id ); + $subscription->save(); + } + } + } + } + ); + + add_filter( + 'woocommerce_gateway_description', + /** + * Param types removed to avoid third-party issues. + * + * @psalm-suppress MissingClosureParamType + */ + function ( $description, $id ) use ( $c ) { + $payment_token_repository = $c->get( 'vaulting.repository.payment-token' ); + $settings = $c->get( 'wcgateway.settings' ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); + + return $this->display_saved_paypal_payments( $settings, (string) $id, $payment_token_repository, (string) $description, $subscription_helper ); + }, + 10, + 2 + ); + + add_filter( + 'woocommerce_credit_card_form_fields', + /** + * Param types removed to avoid third-party issues. + * + * @psalm-suppress MissingClosureParamType + */ + function ( $default_fields, $id ) use ( $c ) { + $payment_token_repository = $c->get( 'vaulting.repository.payment-token' ); + $settings = $c->get( 'wcgateway.settings' ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); + + return $this->display_saved_credit_cards( $settings, $id, $payment_token_repository, $default_fields, $subscription_helper ); + }, + 20, + 2 + ); + } + + /** + * Returns the key for the module. + * + * @return string|void + */ + public function getKey() { + } + + /** + * Handles a Subscription product renewal. + * + * @param WC_Order $order WooCommerce order. + * @param ContainerInterface $container The container. + * @return void + */ + protected function renew( WC_Order $order, ContainerInterface $container ) { + $handler = $container->get( 'wc-subscriptions.renewal-handler' ); + assert( $handler instanceof RenewalHandler ); + + $handler->renew( $order ); + } + + /** + * Adds Payment token ID to subscription. + * + * @param \WC_Subscription $subscription The subscription. + * @param PaymentTokenRepository $payment_token_repository The payment repository. + * @param LoggerInterface $logger The logger. + */ + protected function add_payment_token_id( + \WC_Subscription $subscription, + PaymentTokenRepository $payment_token_repository, + LoggerInterface $logger + ): void { + try { + $tokens = $payment_token_repository->all_for_user_id( $subscription->get_customer_id() ); + if ( $tokens ) { + $latest_token_id = end( $tokens )->id() ? end( $tokens )->id() : ''; + $subscription->update_meta_data( 'payment_token_id', $latest_token_id ); + $subscription->save(); + } + } catch ( RuntimeException $error ) { + $message = sprintf( + // translators: %1$s is the payment token Id, %2$s is the error message. + __( + 'Could not add token Id to subscription %1$s: %2$s', + 'woocommerce-paypal-payments' + ), + $subscription->get_id(), + $error->getMessage() + ); + + $logger->log( 'warning', $message ); + } + } + + /** + * Displays saved PayPal payments. + * + * @param Settings $settings The settings. + * @param string $id The payment gateway Id. + * @param PaymentTokenRepository $payment_token_repository The payment token repository. + * @param string $description The payment gateway description. + * @param SubscriptionHelper $subscription_helper The subscription helper. + * @return string + */ + protected function display_saved_paypal_payments( + Settings $settings, + string $id, + PaymentTokenRepository $payment_token_repository, + string $description, + SubscriptionHelper $subscription_helper + ): string { + if ( $settings->has( 'vault_enabled' ) + && $settings->get( 'vault_enabled' ) + && PayPalGateway::ID === $id + && $subscription_helper->is_subscription_change_payment() + ) { + $tokens = $payment_token_repository->all_for_user_id( get_current_user_id() ); + if ( ! $tokens || ! $payment_token_repository->tokens_contains_paypal( $tokens ) ) { + return esc_html__( + 'No PayPal payments saved, in order to use a saved payment you first need to create it through a purchase.', + 'woocommerce-paypal-payments' + ); + } + + $output = sprintf( + '

'; + + return $output; + } + + return $description; + } + + /** + * Displays saved credit cards. + * + * @param Settings $settings The settings. + * @param string $id The payment gateway Id. + * @param PaymentTokenRepository $payment_token_repository The payment token repository. + * @param array $default_fields Default payment gateway fields. + * @param SubscriptionHelper $subscription_helper The subscription helper. + * @return array|mixed|string + * @throws NotFoundException When setting was not found. + */ + protected function display_saved_credit_cards( + Settings $settings, + string $id, + PaymentTokenRepository $payment_token_repository, + array $default_fields, + SubscriptionHelper $subscription_helper + ) { + + if ( $settings->has( 'vault_enabled_dcc' ) + && $settings->get( 'vault_enabled_dcc' ) + && $subscription_helper->is_subscription_change_payment() + && CreditCardGateway::ID === $id + ) { + $tokens = $payment_token_repository->all_for_user_id( get_current_user_id() ); + if ( ! $tokens || ! $payment_token_repository->tokens_contains_card( $tokens ) ) { + $default_fields = array(); + $default_fields['saved-credit-card'] = esc_html__( + 'No Credit Card saved, in order to use a saved Credit Card you first need to create it through a purchase.', + 'woocommerce-paypal-payments' + ); + return $default_fields; + } + + $output = sprintf( + '

'; + + $default_fields = array(); + $default_fields['saved-credit-card'] = $output; + return $default_fields; + } + + return $default_fields; + } +} diff --git a/modules/ppcp-webhooks/src/Handler/BillingPlanPricingChangeActivated.php b/modules/ppcp-webhooks/src/Handler/BillingPlanPricingChangeActivated.php index 7a1461caf..8716f8714 100644 --- a/modules/ppcp-webhooks/src/Handler/BillingPlanPricingChangeActivated.php +++ b/modules/ppcp-webhooks/src/Handler/BillingPlanPricingChangeActivated.php @@ -71,7 +71,6 @@ class BillingPlanPricingChangeActivated implements RequestHandler { $plan_id = wc_clean( wp_unslash( $request['resource']['id'] ?? '' ) ); if ( $plan_id && ! empty( $request['resource']['billing_cycles'] ) ) { - $this->logger->info( 'Starting stuff...' ); $args = array( // phpcs:ignore WordPress.DB.SlowDBQuery 'meta_key' => 'ppcp_subscription_plan', diff --git a/modules/ppcp-webhooks/src/Handler/CheckoutOrderApproved.php b/modules/ppcp-webhooks/src/Handler/CheckoutOrderApproved.php index 177bda0ad..d93ca5b4c 100644 --- a/modules/ppcp-webhooks/src/Handler/CheckoutOrderApproved.php +++ b/modules/ppcp-webhooks/src/Handler/CheckoutOrderApproved.php @@ -15,6 +15,7 @@ use WC_Session_Handler; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; use Psr\Log\LoggerInterface; +use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\Session\MemoryWcSession; use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer; @@ -228,12 +229,14 @@ class CheckoutOrderApproved implements RequestHandler { continue; } - if ( ! $this->order_processor->process( $wc_order ) ) { + try { + $this->order_processor->process( $wc_order ); + } catch ( RuntimeException $exception ) { return $this->failure_response( sprintf( 'Failed to process WC order %s: %s.', (string) $wc_order->get_id(), - $this->order_processor->last_error() + $exception->getMessage() ) ); } diff --git a/package.json b/package.json index a4d6ea019..8e534d0b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "woocommerce-paypal-payments", - "version": "2.4.1", + "version": "2.4.3", "description": "WooCommerce PayPal Payments", "repository": "https://github.com/woocommerce/woocommerce-paypal-payments", "license": "GPL-2.0", @@ -14,7 +14,8 @@ "install:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn install", "install:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn install", "install:modules:ppcp-order-tracking": "cd modules/ppcp-order-tracking && yarn install", - "install:modules:ppcp-subscription": "cd modules/ppcp-subscription && yarn install", + "install:modules:ppcp-paypal-subscriptions": "cd modules/ppcp-paypal-subscriptions && yarn install", + "install:modules:ppcp-save-payment-methods": "cd modules/ppcp-save-payment-methods && yarn install", "install:modules:ppcp-onboarding": "cd modules/ppcp-onboarding && yarn install", "install:modules:ppcp-compat": "cd modules/ppcp-compat && yarn install", "install:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn install", @@ -25,7 +26,8 @@ "build:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn run build", "build:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn run build", "build:modules:ppcp-order-tracking": "cd modules/ppcp-order-tracking && yarn run build", - "build:modules:ppcp-subscription": "cd modules/ppcp-subscription && yarn run build", + "build:modules:ppcp-save-payment-methods": "cd modules/ppcp-save-payment-methods && yarn run build", + "build:modules:ppcp-paypal-subscriptions": "cd modules/ppcp-paypal-subscriptions && yarn run build", "build:modules:ppcp-onboarding": "cd modules/ppcp-onboarding && yarn run build", "build:modules:ppcp-compat": "cd modules/ppcp-compat && yarn run build", "build:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn run build", @@ -37,7 +39,8 @@ "watch:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn run watch", "watch:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn run watch", "watch:modules:ppcp-order-tracking": "cd modules/ppcp-order-tracking && yarn run watch", - "watch:modules:ppcp-subscription": "cd modules/ppcp-subscription && yarn run watch", + "watch:modules:ppcp-paypal-subscriptions": "cd modules/ppcp-paypal-subscriptions && yarn run watch", + "watch:modules:ppcp-save-payment-methods": "cd modules/ppcp-save-payment-methods && yarn run watch", "watch:modules:ppcp-onboarding": "cd modules/ppcp-onboarding && yarn run watch", "watch:modules:ppcp-compat": "cd modules/ppcp-compat && yarn run watch", "watch:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn run watch", diff --git a/readme.txt b/readme.txt index 7d1d2e955..d37ec2657 100644 --- a/readme.txt +++ b/readme.txt @@ -2,9 +2,9 @@ Contributors: woocommerce, automattic, inpsyde Tags: woocommerce, paypal, payments, ecommerce, checkout, cart, pay later, apple pay, subscriptions, debit card, credit card, google pay Requires at least: 5.3 -Tested up to: 6.3 +Tested up to: 6.4 Requires PHP: 7.2 -Stable tag: 2.4.1 +Stable tag: 2.4.3 License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -177,9 +177,40 @@ If you encounter issues with the PayPal buttons not appearing after an update, p 5. Click "Connect to PayPal" to link your site to your PayPal account. 6. Main settings screen. - == Changelog == += 2.4.3 - xxxx-xx-xx = +* Fix - PayPal Subscription initiated without a WooCommerce order #1907 +* Fix - Block Checkout reloads when submitting order with empty fields #1904 +* Fix - "Send checkout billing and shipping data to Apple Pay" displayed when Apple Pay is disabled #1883 +* Fix - "Order does not contain intent" error for ACDC renewals when triggering 3D Secure #1888 +* Enhancement - Add button to reload feature eligibility status from Connection tab #1902 +* Enhancement - Apple Pay validation message improvements #1901 +* Enhancement - Improve support for Classic Cart & Classic Checkout blocks #1894 +* Enhancement - Ensure uniform button appearance for PayPal, Google Pay, and Apple Pay buttons #1900 +* Enhancement - remove string translations for package tracking carriers from repository #1885 +* Enhancement - Incorrect margins when PayPal buttons are rendered as separate gateways. #1908 +* Feature preview - Save payment methods (Vault v3) integration #1779 + += 2.4.2 - 2023-12-04 = +* Fix - Action callback arguments count in ShipStation tracking integration #1841 +* Fix - Google Pay scripts loading on unrelated admin pages #1834 +* Fix - Do not ignore disabled APMs list in blocks #1865 +* Fix - Display Package Tracking metabox below Order actions when HPOS is active #1850 +* Fix - ApplePay use checkout form data to update shipping and billing #1832 +* Fix - Fix Apple Pay CSS #1872 +* Enhancement - Allow redirect to PayPal with "Place order" button if smart buttons failed to load #1840 #1870 +* Enhancement - Extend list of supported countries for Package Tracking v2 integration #1848 +* Enhancement - Improve Block Theme support for Pay Later messaging #1855 +* Enhancement - Render block buttons separately and add block style settings #1858 +* Enhancement - Enable Block Cart and Block Express Checkout button locations by default #1852 +* Enhancement - Improve single product page button placement with Block themes #1847 +* Enhancement - Remove the Home location from default enabled Pay Later messaging locations #1856 +* Enhancement - Chrome browser detected as eligible for Apple Pay on settings page #1828 +* Enhancement - Hide Apple Pay & Google Pay for subscription type products #1835 +* Enhancement - Add Standard Card Button gateway styling settings & preview #1827 +* Feature preview - Upgrade to new Hosted Card Fields for Advanced Card Processing #1843 + = 2.4.1 - 2023-11-14 = * Fix - Error "PayPal order ID not found in meta" prevents automations from triggering when buying subscription via third-party payment gateway #1822 * Fix - Card button subscription support declaration #1796 diff --git a/tests/PHPUnit/Api/CreateOrderForWcOrderTest.php b/tests/PHPUnit/Api/CreateOrderForWcOrderTest.php new file mode 100644 index 000000000..b2d16caf7 --- /dev/null +++ b/tests/PHPUnit/Api/CreateOrderForWcOrderTest.php @@ -0,0 +1,52 @@ +orderProcesor = Mockery::mock(OrderProcessor::class); + + $this->bootstrapModule([ + 'wcgateway.order-processor' => function () { + return $this->orderProcesor; + }, + ]); + } + + public function testSuccess(): void { + $wcOrder = Mockery::mock(WC_Order::class); + $ret = Mockery::mock(Order::class); + $this->orderProcesor + ->expects('create_order') + ->with($wcOrder) + ->andReturn($ret) + ->once(); + + self::assertEquals($ret, ppcp_create_paypal_order_for_wc_order($wcOrder)); + } + + public function testFailure(): void { + $wcOrder = Mockery::mock(WC_Order::class); + $this->orderProcesor + ->expects('create_order') + ->with($wcOrder) + ->andThrow(new RuntimeException()) + ->once(); + + $this->expectException(RuntimeException::class); + + ppcp_create_paypal_order_for_wc_order($wcOrder); + } +} diff --git a/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php b/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php index 5041bf16a..557551f8f 100644 --- a/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php +++ b/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php @@ -26,7 +26,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\ErrorResponse; use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository; use Mockery; use Psr\Log\LoggerInterface; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNet; use function Brain\Monkey\Functions\expect; @@ -1149,6 +1149,7 @@ class OrderEndpointTest extends TestCase $logger = Mockery::mock(LoggerInterface::class); $logger->shouldReceive('log'); $logger->shouldReceive('debug'); + $logger->shouldReceive('warning'); $applicationContext = Mockery::mock(ApplicationContext::class); $applicationContext ->expects('to_array') diff --git a/tests/PHPUnit/ApiClient/Endpoint/OrderTest.php b/tests/PHPUnit/ApiClient/Endpoint/OrderTest.php index e2c120751..6c8abb05f 100644 --- a/tests/PHPUnit/ApiClient/Endpoint/OrderTest.php +++ b/tests/PHPUnit/ApiClient/Endpoint/OrderTest.php @@ -34,9 +34,6 @@ class OrderTest extends TestCase ->expects('to_array') ->andReturn(['applicationContext']); $paymentSource = Mockery::mock(PaymentSource::class); - $paymentSource - ->expects('to_array') - ->andReturn(['paymentSource']); $testee = new Order( $id, @@ -68,8 +65,7 @@ class OrderTest extends TestCase 'create_time' => $createTime->format($this->dateFormat), 'update_time' => $updateTime->format($this->dateFormat), 'payer' => ['payer'], - 'application_context' => ['applicationContext'], - 'payment_source' => ['paymentSource'] + 'application_context' => ['applicationContext'] ]; $this->assertEquals($expected, $testee->to_array()); } diff --git a/tests/PHPUnit/Button/Helper/ThreeDSecureTest.php b/tests/PHPUnit/Button/Helper/ThreeDSecureTest.php index 406e9fd64..bfe6f4e85 100644 --- a/tests/PHPUnit/Button/Helper/ThreeDSecureTest.php +++ b/tests/PHPUnit/Button/Helper/ThreeDSecureTest.php @@ -3,15 +3,12 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\Button\Helper; - use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Entity\CardAuthenticationResult; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource; -use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSourceCard; +use WooCommerce\PayPalCommerce\ApiClient\Factory\CardAuthenticationResultFactory; use WooCommerce\PayPalCommerce\TestCase; -use Mockery\Mock; -use function Brain\Monkey\Functions\when; class ThreeDSecureTest extends TestCase { @@ -23,21 +20,35 @@ class ThreeDSecureTest extends TestCase */ public function testDefault(int $expected, string $liabilityShift, string $authenticationResult, string $enrollment) { - $result = \Mockery::mock(CardAuthenticationResult::class); - $result->shouldReceive('liability_shift')->andReturn($liabilityShift); - $result->shouldReceive('authentication_result')->andReturn($authenticationResult); - $result->shouldReceive('enrollment_status')->andReturn($enrollment); - $result->shouldReceive('to_array')->andReturn(['foo' => 'bar',]); - $card = \Mockery::mock(PaymentSourceCard::class); - $card->shouldReceive('authentication_result')->andReturn($result); - $source = \Mockery::mock(PaymentSource::class); - $source->shouldReceive('card')->andReturn($card); - $order = \Mockery::mock(Order::class); - $order->shouldReceive('payment_source')->andReturn($source); - $logger = \Mockery::mock(LoggerInterface::class); - $logger->shouldReceive('info'); + $authResult = \Mockery::mock(CardAuthenticationResult::class); + $authResult->shouldReceive('liability_shift')->andReturn($liabilityShift); + $authResult->shouldReceive('authentication_result')->andReturn($authenticationResult); + $authResult->shouldReceive('enrollment_status')->andReturn($enrollment); + $authResult->shouldReceive('to_array')->andReturn(['foo' => 'bar',]); - $testee = new ThreeDSecure($logger); + $authenticationResultFactory = \Mockery::mock(CardAuthenticationResultFactory::class); + $authenticationResultFactory->shouldReceive('from_paypal_response') + ->andReturn($authResult); + + $source = \Mockery::mock(PaymentSource::class); + $authentication_result = (object)[ + 'brand' => 'visa', + 'authentication_result' => (object)array( + 'liability_shift' => $liabilityShift, + 'authentication_result' => $authenticationResult, + 'enrollment_status' => $enrollment + ), + ]; + + $source->shouldReceive('properties')->andReturn($authentication_result); + + $order = \Mockery::mock(Order::class); + $order->shouldReceive('payment_source')->andReturn($source); + + $logger = \Mockery::mock(LoggerInterface::class); + $logger->shouldReceive('info'); + + $testee = new ThreeDSecure($authenticationResultFactory, $logger); $result = $testee->proceed_with_order($order); $this->assertEquals($expected, $result); } diff --git a/tests/PHPUnit/ModularTestCase.php b/tests/PHPUnit/ModularTestCase.php index 61583c4e1..a880acfbe 100644 --- a/tests/PHPUnit/ModularTestCase.php +++ b/tests/PHPUnit/ModularTestCase.php @@ -41,7 +41,9 @@ class ModularTestCase extends TestCase $wpdb->postmeta = ''; !defined('PAYPAL_API_URL') && define('PAYPAL_API_URL', 'https://api-m.paypal.com'); + !defined('PAYPAL_URL') && define( 'PAYPAL_URL', 'https://www.paypal.com' ); !defined('PAYPAL_SANDBOX_API_URL') && define('PAYPAL_SANDBOX_API_URL', 'https://api-m.sandbox.paypal.com'); + !defined('PAYPAL_SANDBOX_URL') && define( 'PAYPAL_SANDBOX_URL', 'https://www.sandbox.paypal.com' ); !defined('PAYPAL_INTEGRATION_DATE') && define('PAYPAL_INTEGRATION_DATE', '2020-10-15'); !defined('PPCP_FLAG_SUBSCRIPTION') && define('PPCP_FLAG_SUBSCRIPTION', true); diff --git a/tests/PHPUnit/Vaulting/VaultedCreditCardHandlerTest.php b/tests/PHPUnit/Vaulting/VaultedCreditCardHandlerTest.php index 8a7f9de51..fa92f6f89 100644 --- a/tests/PHPUnit/Vaulting/VaultedCreditCardHandlerTest.php +++ b/tests/PHPUnit/Vaulting/VaultedCreditCardHandlerTest.php @@ -20,7 +20,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory; use WooCommerce\PayPalCommerce\Onboarding\Environment; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; use WooCommerce\PayPalCommerce\Vaulting\VaultedCreditCardHandler; @@ -118,10 +118,11 @@ class VaultedCreditCardHandlerTest extends TestCase $order = Mockery::mock(Order::class); $order->shouldReceive('id')->andReturn('1'); $order->shouldReceive('intent')->andReturn('CAPTURE'); + $paymentSource = Mockery::mock(PaymentSource::class); - $paymentSourceCard = Mockery::mock(PaymentSourceCard::class); - $paymentSource->shouldReceive('card')->andReturn($paymentSourceCard); + $paymentSource->shouldReceive('name')->andReturn('card'); $order->shouldReceive('payment_source')->andReturn($paymentSource); + $orderStatus = Mockery::mock(OrderStatus::class); $orderStatus->shouldReceive('is')->andReturn(true); $order->shouldReceive('status')->andReturn($orderStatus); diff --git a/tests/PHPUnit/WcGateway/Assets/SettingsPagesAssetsTest.php b/tests/PHPUnit/WcGateway/Assets/SettingsPagesAssetsTest.php index f5066db40..1cfcab8a9 100644 --- a/tests/PHPUnit/WcGateway/Assets/SettingsPagesAssetsTest.php +++ b/tests/PHPUnit/WcGateway/Assets/SettingsPagesAssetsTest.php @@ -4,7 +4,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Assets; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\Onboarding\Environment; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\TestCase; use function Brain\Monkey\Functions\when; use Mockery; diff --git a/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php b/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php index 5e2a8bbc7..f76438f98 100644 --- a/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php +++ b/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php @@ -10,7 +10,7 @@ use WC_Order; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint; use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\Vaulting\VaultedCreditCardHandler; use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor; @@ -83,6 +83,7 @@ class CreditCardGatewayTest extends TestCase when('WC')->justReturn($woocommerce); $woocommerce->session = $session; $session->shouldReceive('set')->andReturn([]); + $session->shouldReceive('get')->andReturn(''); $this->orderProcessor->shouldReceive('process') ->with($wc_order) @@ -106,6 +107,7 @@ class CreditCardGatewayTest extends TestCase when('WC')->justReturn($woocommerce); $woocommerce->session = $session; $session->shouldReceive('set')->andReturn([]); + $session->shouldReceive('get')->andReturn(''); $savedCreditCard = 'abc123'; $_POST['saved_credit_card'] = $savedCreditCard; diff --git a/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php b/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php index aa9057c67..5239af7dc 100644 --- a/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php +++ b/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcGateway\Gateway; +use Exception; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; @@ -10,7 +11,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository; use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer; @@ -106,7 +107,11 @@ class WcGatewayTest extends TestCase $this->paymentTokenRepository, $this->logger, $this->apiShopCountry, - $this->orderEndpoint + $this->orderEndpoint, + function ($id) { + return 'checkoutnow=' . $id; + }, + 'Pay via PayPal' ); } @@ -204,13 +209,10 @@ class WcGatewayTest extends TestCase public function testProcessPaymentFails() { $orderId = 1; $wcOrder = Mockery::mock(\WC_Order::class); - $lastError = 'some-error'; + $error = 'some-error'; $this->orderProcessor ->expects('process') - ->andReturnFalse(); - $this->orderProcessor - ->expects('last_error') - ->andReturn($lastError); + ->andThrow(new Exception($error)); $this->subscriptionHelper->shouldReceive('has_subscription')->with($orderId)->andReturn(true); $this->subscriptionHelper->shouldReceive('is_subscription_change_payment')->andReturn(true); $wcOrder->shouldReceive('update_status')->andReturn(true); @@ -223,7 +225,7 @@ class WcGatewayTest extends TestCase $this->sessionHandler ->shouldReceive('destroy_session_data'); expect('wc_add_notice') - ->with($lastError, 'error'); + ->with($error, 'error'); $redirectUrl = 'http://example.com/checkout'; diff --git a/tests/PHPUnit/WcGateway/Processor/AuthorizedPaymentsProcessorTest.php b/tests/PHPUnit/WcGateway/Processor/AuthorizedPaymentsProcessorTest.php index 0d5fd386a..f65338f67 100644 --- a/tests/PHPUnit/WcGateway/Processor/AuthorizedPaymentsProcessorTest.php +++ b/tests/PHPUnit/WcGateway/Processor/AuthorizedPaymentsProcessorTest.php @@ -19,7 +19,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments; use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use Mockery; diff --git a/tests/PHPUnit/WcGateway/Processor/OrderProcessorTest.php b/tests/PHPUnit/WcGateway/Processor/OrderProcessorTest.php index 97ceca9b5..d27ec6ff7 100644 --- a/tests/PHPUnit/WcGateway/Processor/OrderProcessorTest.php +++ b/tests/PHPUnit/WcGateway/Processor/OrderProcessorTest.php @@ -3,7 +3,10 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcGateway\Processor; - +use Exception; +use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; +use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; +use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory; use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\Dictionary; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; @@ -20,7 +23,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderHelper; use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure; use WooCommerce\PayPalCommerce\Onboarding\Environment; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; @@ -143,7 +146,10 @@ class OrderProcessorTest extends TestCase $logger, $this->environment, $subscription_helper, - $order_helper + $order_helper, + Mockery::mock(PurchaseUnitFactory::class), + Mockery::mock(PayerFactory::class), + Mockery::mock(ShippingPreferenceFactory::class) ); $wcOrder @@ -173,7 +179,9 @@ class OrderProcessorTest extends TestCase $order_helper->shouldReceive('contains_physical_goods')->andReturn(true); - $this->assertTrue($testee->process($wcOrder)); + $testee->process($wcOrder); + + $this->expectNotToPerformAssertions(); } public function testCapture() { @@ -268,7 +276,10 @@ class OrderProcessorTest extends TestCase $logger, $this->environment, $subscription_helper, - $order_helper + $order_helper, + Mockery::mock(PurchaseUnitFactory::class), + Mockery::mock(PayerFactory::class), + Mockery::mock(ShippingPreferenceFactory::class) ); $wcOrder @@ -293,7 +304,9 @@ class OrderProcessorTest extends TestCase $order_helper->shouldReceive('contains_physical_goods')->andReturn(true); - $this->assertTrue($testee->process($wcOrder)); + $testee->process($wcOrder); + + $this->expectNotToPerformAssertions(); } public function testError() { @@ -375,7 +388,10 @@ class OrderProcessorTest extends TestCase $logger, $this->environment, $subscription_helper, - $order_helper + $order_helper, + Mockery::mock(PurchaseUnitFactory::class), + Mockery::mock(PayerFactory::class), + Mockery::mock(ShippingPreferenceFactory::class) ); $wcOrder @@ -394,8 +410,8 @@ class OrderProcessorTest extends TestCase $order_helper->shouldReceive('contains_physical_goods')->andReturn(true); - $this->assertFalse($testee->process($wcOrder)); - $this->assertNotEmpty($testee->last_error()); + $this->expectException(Exception::class); + $testee->process($wcOrder); } diff --git a/tests/PHPUnit/Subscription/RenewalHandlerTest.php b/tests/PHPUnit/WcSubscriptions/RenewalHandlerTest.php similarity index 97% rename from tests/PHPUnit/Subscription/RenewalHandlerTest.php rename to tests/PHPUnit/WcSubscriptions/RenewalHandlerTest.php index 84ecb0447..3899fa0f7 100644 --- a/tests/PHPUnit/Subscription/RenewalHandlerTest.php +++ b/tests/PHPUnit/WcSubscriptions/RenewalHandlerTest.php @@ -1,7 +1,7 @@ shouldReceive('payment_source') ->andReturn(null); + $wcOrder + ->shouldReceive('get_payment_method') + ->andReturn(''); $wcOrder ->shouldReceive('get_meta') ->andReturn(''); diff --git a/tests/Playwright/tests/save-payment-methods.spec.js b/tests/Playwright/tests/save-payment-methods.spec.js new file mode 100644 index 000000000..4648eebca --- /dev/null +++ b/tests/Playwright/tests/save-payment-methods.spec.js @@ -0,0 +1,42 @@ +const {test, expect} = require('@playwright/test'); +const {loginAsCustomer} = require("./utils/user"); +const {openPaypalPopup, loginIntoPaypal, completePaypalPayment} = require("./utils/paypal-popup"); +const {fillCheckoutForm, expectOrderReceivedPage} = require("./utils/checkout"); + +const { + PRODUCT_URL, +} = process.env; + +async function expectContinuation(page) { + await expect(page.locator('#payment_method_ppcp-gateway')).toBeChecked(); + + await expect(page.locator('.component-frame')).toHaveCount(0); +} + +async function completeContinuation(page) { + await expectContinuation(page); + + await Promise.all([ + page.waitForNavigation(), + page.locator('#place_order').click(), + ]); +} + +test('Save during purchase', async ({page}) => { + await loginAsCustomer(page) + + await page.goto(PRODUCT_URL); + const popup = await openPaypalPopup(page); + + await loginIntoPaypal(popup); + await completePaypalPayment(popup); + await fillCheckoutForm(page); + + await completeContinuation(page); + + await expectOrderReceivedPage(page); +}); + + + + diff --git a/woocommerce-paypal-payments.php b/woocommerce-paypal-payments.php index 5e89cbae4..aeb358895 100644 --- a/woocommerce-paypal-payments.php +++ b/woocommerce-paypal-payments.php @@ -3,13 +3,13 @@ * Plugin Name: WooCommerce PayPal Payments * Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/ * Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage. - * Version: 2.4.1 + * Version: 2.4.3 * Author: WooCommerce * Author URI: https://woocommerce.com/ * License: GPL-2.0 * Requires PHP: 7.2 * WC requires at least: 3.9 - * WC tested up to: 8.2 + * WC tested up to: 8.3 * Text Domain: woocommerce-paypal-payments * * @package WooCommerce\PayPalCommerce @@ -22,8 +22,10 @@ namespace WooCommerce\PayPalCommerce; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; define( 'PAYPAL_API_URL', 'https://api-m.paypal.com' ); +define( 'PAYPAL_URL', 'https://www.paypal.com' ); define( 'PAYPAL_SANDBOX_API_URL', 'https://api-m.sandbox.paypal.com' ); -define( 'PAYPAL_INTEGRATION_DATE', '2023-11-06' ); +define( 'PAYPAL_SANDBOX_URL', 'https://www.sandbox.paypal.com' ); +define( 'PAYPAL_INTEGRATION_DATE', '2023-12-18' ); ! defined( 'CONNECT_WOO_CLIENT_ID' ) && define( 'CONNECT_WOO_CLIENT_ID', 'AcCAsWta_JTL__OfpjspNyH7c1GGHH332fLwonA5CwX4Y10mhybRZmHLA0GdRbwKwjQIhpDQy0pluX_P' ); ! defined( 'CONNECT_WOO_SANDBOX_CLIENT_ID' ) && define( 'CONNECT_WOO_SANDBOX_CLIENT_ID', 'AYmOHbt1VHg-OZ_oihPdzKEVbU3qg0qXonBcAztuzniQRaKE0w1Hr762cSFwd4n8wxOl-TCWohEa0XM_' );