geppert
Forum Replies Created
-
Follow-up: Root cause identified after source code analysis
I’ve had a chance to dig into the plugin source code (v9.0.60) and can now provide a more precise description of what’s happening.
Root cause
The bug originates in
ppcp_regular_create_order_request()insideclass-ppcp-paypal-checkout-for-woocommerce-request.php.When a customer pays via direct credit/debit card entry (not PayPal login),
process_payment()inclass-ppcp-paypal-checkout-for-woocommerce-gateway-cc.phpcallsppcp_regular_create_order_request($woo_order_id)(line 232). This function correctly fetches order details viappcp_get_details_from_order()(line 2343), which reads$order->get_shipping_total()— so the shipping amount is present in$cart['shipping']at this point.However, the entire
amount.breakdownblock — including the shipping field — is wrapped inside asend_itemsgate (line 2376):PHP
if ($this->send_items === true) { // item_total, shipping, tax_total, discount are all set here }If
send_itemsis disabled in the plugin settings, the entire breakdown is skipped. Theamount.valuestill uses$cart['order_total']fromppcp_get_details(), which correctly includes shipping in the total — but since the breakdown is absent, PayPal receives a total that includes shipping with no breakdown to account for it, causing PayPal to recordshipping: 0.00internally.Additionally, even when
send_itemsis enabled, theppcp_get_details()reconciliation logic (lines 1202–1260) can produce a negativeship_discount_amountto balance rounding differences, which may further suppress the shipping value in the breakdown.The trigger:
SET_PROVIDED_ADDRESSmodeThe issue is specifically triggered during the checkout page flow.
ppcp_shipping_preference()(line 264) returnsSET_PROVIDED_ADDRESSwhen$page === 'checkout'(line 302). In this mode, PayPal does not recalculate shipping from its own address data — it relies entirely on what the plugin sends in the breakdown. If the breakdown is missing or incomplete, PayPal silently recordsshipping: 0.00.In contrast, the
GET_FROM_FILEmode (used for cart/product page PayPal button flows) triggers a PayPal-side shipping recalculation, which is why those orders are processed correctly.Affected code paths
class-ppcp-paypal-checkout-for-woocommerce-gateway-cc.php→process_payment()→ppcp_regular_create_order_request()class-ppcp-paypal-checkout-for-woocommerce-request.php→ppcp_regular_create_order_request()lines 2376–2415class-ppcp-paypal-checkout-for-woocommerce-request.php→ppcp_shipping_preference()lines 264–306
Suggested fix
The shipping amount should be added to the breakdown unconditionally when
SET_PROVIDED_ADDRESSis used and$cart['shipping'] > 0, regardless of thesend_itemssetting. Thesend_itemsflag should control whether line items are sent, but should not suppress the shipping amount in the breakdown — these are two separate concerns.A minimal targeted fix would be to move the shipping breakdown assignment outside of the
send_itemsblock inppcp_regular_create_order_request():PHP
// Outside of the send_items block: if (isset($cart['shipping']) && $cart['shipping'] > 0) { $body_request['purchase_units'][0]['amount']['breakdown']['shipping'] = array( 'currency_code' => apply_filters('wpg_ppcp_woocommerce_currency', $this->ppcp_get_currency($woo_order_id), $cart['shipping']), 'value' => $cart['shipping'], ); }This same issue likely affects
ppcp_create_order_request()(line 483) for the same reason.I am fully aware that I can translate the plugin, but I use no plugins for multi-language, just different pages.
Ideally it’d look something like an option in the shortcode [webbabooking language=english] [webbabooking language=german] but that does not seem to exist