nopCommerce version
4.90 (plugin Payments.PayPalCommerce v4.90.20). Reproduced on our production store running a backport of the same plugin; the affected code in 4.90.20 is identical.
Steps to reproduce
- Configure the PayPal Commerce plugin with buttons displayed on the shopping cart page (
DisplayButtonsOnShoppingCart = true).
- Make sure
ShippingSettings.AllowPickupInStore is disabled.
- As a guest (or any customer without a saved shipping address), add a shippable product to the cart.
- On the cart page, click the PayPal button.
Actual result: the AJAX call to PayPalCommercePublic/CreateOrder returns the error "No available shipping options" and the PayPal popup closes/never opens. Guests can never use the express buttons — which is their primary use case, since the address is supposed to be collected by PayPal.
Expected result: the PayPal order is created, the buyer picks/confirms their address in the PayPal popup (the plugin already sends shipping_preference = GET_FROM_FILE for the Cart/Product placements), and the shipping options are computed by the existing onShippingAddressChange → UpdateOrderShipping callback.
Root cause
PayPalCommerceServiceManager.PrepareShippingDetailsAsync:
- For the Cart/Product placement it calls
PrepareShippingOptionsAsync(details).
PrepareShippingOptionsAsync returns an empty result when details.ShippingAddress is null && !_shippingSettings.AllowPickupInStore — which is always the case for a guest, because details.ShippingAddress comes from customer.ShippingAddressId in GetCartDetailsAsync.
PrepareShippingDetailsAsync then throws new NopException("No available shipping options"), which aborts CreateOrder.
So the order creation requires a shipping address that, by design of the express flow (GET_FROM_FILE), doesn't exist yet.
Notes
- Registered customers with a saved shipping address are unaffected, which is probably why this slipped through.
- The buttons on the checkout payment-method page are unaffected (
SET_PROVIDED_ADDRESS branch returns before the options are computed).
- Stores with
AllowPickupInStore enabled are partially masked from the bug because pickup points populate the options list.
nopCommerce version
4.90 (plugin Payments.PayPalCommerce v4.90.20). Reproduced on our production store running a backport of the same plugin; the affected code in 4.90.20 is identical.
Steps to reproduce
DisplayButtonsOnShoppingCart = true).ShippingSettings.AllowPickupInStoreis disabled.Actual result: the AJAX call to
PayPalCommercePublic/CreateOrderreturns the error "No available shipping options" and the PayPal popup closes/never opens. Guests can never use the express buttons — which is their primary use case, since the address is supposed to be collected by PayPal.Expected result: the PayPal order is created, the buyer picks/confirms their address in the PayPal popup (the plugin already sends
shipping_preference = GET_FROM_FILEfor the Cart/Product placements), and the shipping options are computed by the existingonShippingAddressChange→UpdateOrderShippingcallback.Root cause
PayPalCommerceServiceManager.PrepareShippingDetailsAsync:PrepareShippingOptionsAsync(details).PrepareShippingOptionsAsyncreturns an empty result whendetails.ShippingAddress is null && !_shippingSettings.AllowPickupInStore— which is always the case for a guest, becausedetails.ShippingAddresscomes fromcustomer.ShippingAddressIdinGetCartDetailsAsync.PrepareShippingDetailsAsyncthen throwsnew NopException("No available shipping options"), which abortsCreateOrder.So the order creation requires a shipping address that, by design of the express flow (
GET_FROM_FILE), doesn't exist yet.Notes
SET_PROVIDED_ADDRESSbranch returns before the options are computed).AllowPickupInStoreenabled are partially masked from the bug because pickup points populate the options list.