← 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 ), |