PluginProbe
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More / 2.4.1
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More v2.4.1
2.4.1 2.4.0 2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.2 2.2.1 2.2.0 2.1.2 2.1.1 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 All 68 releases
← All changes | includes/Admin/Elementor/Form_Actions/Paypal_Integration.php +16 -10 2.3.2 → 2.4.1 View file →
@@ -4,8 +4,9 @@
4 4
5 5 use Better_Payment\Lite\Admin\DB;
6 6 use Better_Payment\Lite\Campaign\CampaignStats;
7 7 use Better_Payment\Lite\Classes\Handler;
8 +use Better_Payment\Lite\Classes\PaymentRequestGuard;
8 9 use Better_Payment\Lite\Traits\Helper;
9 10 use Elementor\Controls_Manager;
10 11 use ElementorPro\Modules\Forms\Classes\Action_Base;
11 12 use ElementorPro\Modules\Forms\Classes\Ajax_Handler;
@@ -183,22 +184,24 @@
183 184 $ajax_handler->add_error_message( 'Amount field is required!' );
184 185 return false;
185 186 }
186 187
187 - $amount = isset( $sent_data['payment_amount'] ) ? floatval($sent_data['payment_amount']) : 0;
188 + // Amount and quantity come from the form's field settings, never from the
189 + // request — see PaymentRequestGuard.
190 + $guarded = ( new PaymentRequestGuard() )->resolve_elementor_form_payment( (array) $el_form_form_settings, (array) $sent_data );
188 191
189 - if ( empty( $amount ) && ! empty( $sent_data['primary_payment_amount_radio'] ) ) {
190 - $amount = floatval( $sent_data['primary_payment_amount_radio'] );
192 + if ( is_wp_error( $guarded ) ) {
193 + $ajax_handler->add_error_message( $guarded->get_error_message() );
194 + return false;
191 195 }
192 196
193 - $quantity = 1;
194 - if ( !empty( $sent_data[ 'pay_quantity' ] ) ) {
195 - $quantity = intval( $sent_data[ 'pay_quantity' ] );
196 - }
197 + // PayPal takes the per-unit amount and multiplies by `quantity` itself.
198 + $amount = $guarded['unit_amount'];
199 + $quantity = $guarded['quantity'];
197 200
198 201 $return_url = get_the_permalink() . '?better_payment_paypal_status=success&better_payment_widget_id=' . sanitize_text_field( $record->get( 'form_settings' )[ 'id' ] );
199 202 $cancel_url = get_the_permalink() . '?better_payment_error_status=error&better_payment_widget_id=' . sanitize_text_field( $record->get( 'form_settings' )[ 'id' ] );
200 - $order_id = 'paypal_' . uniqid();
203 + $order_id = Handler::new_order_id( 'paypal' );
201 204
202 205 $paypal_unsupported_currencies = $this->bp_unsupported_currencies( 'paypal' );
203 206 $currency_code = sanitize_text_field( $record->get_form_settings( 'better_payment_form_paypal_currency' ) );
204 207 if ( is_array( $paypal_unsupported_currencies ) && in_array( $currency_code, $paypal_unsupported_currencies ) ) {
@@ -234,16 +237,19 @@
234 237 'referer_page_id' => $page_id,
235 238 'referer_widget_id' => $widget_id,
236 239 'source' => 'paypal',
237 240 'paypal_business_email' => sanitize_email( $email ),
241 + // The PayPal environment the order was sent to; the IPN must come from the same one.
242 + 'paypal_mode' => 'yes' === $live_mode ? 'live' : 'sandbox',
238 243 ];
239 244
240 245 // Get campaign_id from form data if available
241 - $campaign_id = ! empty( $sent_data['campaign_id'] ) ? sanitize_text_field( $sent_data['campaign_id'] ) : '';
246 + $campaign_id = $guarded['campaign_id'];
242 247
243 248 Handler::payment_create(
244 249 [
245 - 'amount' => $amount,
250 + // The whole order, so the IPN's `mc_gross >= amount` check also holds the quantity.
251 + 'amount' => $guarded['amount'],
246 252 'order_id' => $order_id,
247 253 'payment_date' => date( 'Y-m-d H:i:s' ),
248 254 'source' => 'paypal',
249 255 'form_fields_info' => maybe_serialize( $better_form_fields ),