This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||||
2 | /** |
||||
3 | * Contains the Main Checkout Class. |
||||
4 | * |
||||
5 | */ |
||||
6 | |||||
7 | defined( 'ABSPATH' ) || exit; |
||||
8 | |||||
9 | /** |
||||
10 | * Main Checkout Class. |
||||
11 | * |
||||
12 | */ |
||||
13 | class GetPaid_Checkout { |
||||
14 | |||||
15 | /** |
||||
16 | * @var GetPaid_Payment_Form_Submission |
||||
17 | */ |
||||
18 | protected $payment_form_submission; |
||||
19 | |||||
20 | /** |
||||
21 | * Class constructor. |
||||
22 | * |
||||
23 | * @param GetPaid_Payment_Form_Submission $submission |
||||
24 | */ |
||||
25 | public function __construct( $submission ) { |
||||
26 | $this->payment_form_submission = $submission; |
||||
27 | } |
||||
28 | |||||
29 | /** |
||||
30 | * Processes the checkout. |
||||
31 | * |
||||
32 | */ |
||||
33 | public function process_checkout() { |
||||
34 | |||||
35 | // Validate the submission. |
||||
36 | $this->validate_submission(); |
||||
37 | |||||
38 | // Prepare the invoice. |
||||
39 | $items = $this->get_submission_items(); |
||||
40 | $invoice = $this->get_submission_invoice(); |
||||
41 | $invoice = $this->process_submission_invoice( $invoice, $items ); |
||||
42 | $prepared = $this->prepare_submission_data_for_saving(); |
||||
43 | |||||
44 | $this->prepare_billing_info( $invoice ); |
||||
45 | |||||
46 | $shipping = $this->prepare_shipping_info( $invoice ); |
||||
47 | |||||
48 | // Save the invoice. |
||||
49 | $invoice->set_is_viewed( true ); |
||||
50 | $invoice->recalculate_total(); |
||||
51 | $invoice->save(); |
||||
52 | |||||
53 | do_action( 'getpaid_checkout_invoice_updated', $invoice ); |
||||
54 | |||||
55 | // Send to the gateway. |
||||
56 | $this->post_process_submission( $invoice, $prepared, $shipping ); |
||||
57 | } |
||||
58 | |||||
59 | /** |
||||
60 | * Validates the submission. |
||||
61 | * |
||||
62 | */ |
||||
63 | protected function validate_submission() { |
||||
64 | |||||
65 | $submission = $this->payment_form_submission; |
||||
66 | $data = $submission->get_data(); |
||||
67 | |||||
68 | // Do we have an error? |
||||
69 | if ( ! empty( $submission->last_error ) ) { |
||||
70 | wp_send_json_error( $submission->last_error ); |
||||
71 | } |
||||
72 | |||||
73 | // We need a billing email. |
||||
74 | if ( ! $submission->has_billing_email() ) { |
||||
75 | wp_send_json_error( __( 'Provide a valid billing email.', 'invoicing' ) ); |
||||
76 | } |
||||
77 | |||||
78 | // Non-recurring gateways should not be allowed to process recurring invoices. |
||||
79 | if ( $submission->should_collect_payment_details() && $submission->has_recurring && ! wpinv_gateway_support_subscription( $data['wpi-gateway'] ) ) { |
||||
80 | wp_send_json_error( __( 'The selected payment gateway does not support subscription payments.', 'invoicing' ) ); |
||||
81 | } |
||||
82 | |||||
83 | // Ensure the gateway is active. |
||||
84 | if ( $submission->should_collect_payment_details() && ! wpinv_is_gateway_active( $data['wpi-gateway'] ) ) { |
||||
85 | wp_send_json_error( __( 'The selected payment gateway is not active', 'invoicing' ) ); |
||||
86 | } |
||||
87 | |||||
88 | // Clear any existing errors. |
||||
89 | wpinv_clear_errors(); |
||||
90 | |||||
91 | // Allow themes and plugins to hook to errors |
||||
92 | do_action( 'getpaid_checkout_error_checks', $submission ); |
||||
93 | |||||
94 | // Do we have any errors? |
||||
95 | if ( wpinv_get_errors() ) { |
||||
96 | wp_send_json_error( getpaid_get_errors_html() ); |
||||
97 | } |
||||
98 | |||||
99 | } |
||||
100 | |||||
101 | /** |
||||
102 | * Retrieves submission items. |
||||
103 | * |
||||
104 | * @return GetPaid_Form_Item[] |
||||
105 | */ |
||||
106 | protected function get_submission_items() { |
||||
107 | |||||
108 | $items = $this->payment_form_submission->get_items(); |
||||
109 | |||||
110 | // Ensure that we have items. |
||||
111 | if ( empty( $items ) && ! $this->payment_form_submission->has_fees() ) { |
||||
112 | wp_send_json_error( __( 'Please provide at least one item or amount.', 'invoicing' ) ); |
||||
113 | } |
||||
114 | |||||
115 | return $items; |
||||
116 | } |
||||
117 | |||||
118 | /** |
||||
119 | * Retrieves submission invoice. |
||||
120 | * |
||||
121 | * @return WPInv_Invoice |
||||
122 | */ |
||||
123 | protected function get_submission_invoice() { |
||||
124 | $submission = $this->payment_form_submission; |
||||
125 | |||||
126 | if ( ! $submission->has_invoice() ) { |
||||
127 | $invoice = new WPInv_Invoice(); |
||||
128 | $invoice->set_created_via( 'payment_form' ); |
||||
129 | return $invoice; |
||||
130 | } |
||||
131 | |||||
132 | $invoice = $submission->get_invoice(); |
||||
133 | |||||
134 | // Make sure that it is neither paid or refunded. |
||||
135 | if ( $invoice->is_paid() || $invoice->is_refunded() ) { |
||||
136 | wp_send_json_error( __( 'This invoice has already been paid for.', 'invoicing' ) ); |
||||
137 | } |
||||
138 | |||||
139 | return $invoice; |
||||
140 | } |
||||
141 | |||||
142 | /** |
||||
143 | * Processes the submission invoice. |
||||
144 | * |
||||
145 | * @param WPInv_Invoice $invoice |
||||
146 | * @param GetPaid_Form_Item[] $items |
||||
147 | * @return WPInv_Invoice |
||||
148 | */ |
||||
149 | protected function process_submission_invoice( $invoice, $items ) { |
||||
150 | |||||
151 | $submission = $this->payment_form_submission; |
||||
152 | |||||
153 | // Set-up the invoice details. |
||||
154 | $invoice->set_email( sanitize_email( $submission->get_billing_email() ) ); |
||||
155 | $invoice->set_user_id( $this->get_submission_customer() ); |
||||
156 | $invoice->set_submission_id( $submission->id ); |
||||
157 | $invoice->set_payment_form( absint( $submission->get_payment_form()->get_id() ) ); |
||||
158 | $invoice->set_items( $items ); |
||||
159 | $invoice->set_fees( $submission->get_fees() ); |
||||
160 | $invoice->set_taxes( $submission->get_taxes() ); |
||||
161 | $invoice->set_discounts( $submission->get_discounts() ); |
||||
162 | $invoice->set_gateway( $submission->get_field( 'wpi-gateway' ) ); |
||||
0 ignored issues
–
show
|
|||||
163 | $invoice->set_currency( $submission->get_currency() ); |
||||
164 | |||||
165 | if ( $submission->has_shipping() ) { |
||||
166 | $invoice->set_shipping( $submission->get_shipping() ); |
||||
167 | } |
||||
168 | |||||
169 | $address_confirmed = $submission->get_field( 'confirm-address' ); |
||||
0 ignored issues
–
show
Are you sure the assignment to
$address_confirmed is correct as $submission->get_field('confirm-address') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
170 | $invoice->set_address_confirmed( ! empty( $address_confirmed ) ); |
||||
171 | |||||
172 | if ( $submission->has_discount_code() ) { |
||||
173 | $invoice->set_discount_code( $submission->get_discount_code() ); |
||||
174 | } |
||||
175 | |||||
176 | getpaid_maybe_add_default_address( $invoice ); |
||||
177 | return $invoice; |
||||
178 | } |
||||
179 | |||||
180 | /** |
||||
181 | * Retrieves the submission's customer. |
||||
182 | * |
||||
183 | * @return int The customer id. |
||||
184 | */ |
||||
185 | protected function get_submission_customer() { |
||||
186 | $submission = $this->payment_form_submission; |
||||
187 | |||||
188 | // If this is an existing invoice... |
||||
189 | if ( $submission->has_invoice() ) { |
||||
190 | return $submission->get_invoice()->get_user_id(); |
||||
191 | } |
||||
192 | |||||
193 | // (Maybe) create the user. |
||||
194 | $user = get_current_user_id(); |
||||
195 | |||||
196 | if ( empty( $user ) ) { |
||||
197 | $user = get_user_by( 'email', $submission->get_billing_email() ); |
||||
198 | } |
||||
199 | |||||
200 | if ( empty( $user ) ) { |
||||
201 | $name = array( $submission->get_field( 'wpinv_first_name', 'billing' ), $submission->get_field( 'wpinv_last_name', 'billing' ) ); |
||||
0 ignored issues
–
show
Are you sure the usage of
$submission->get_field('..._last_name', 'billing') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() Are you sure the usage of
$submission->get_field('...first_name', 'billing') targeting GetPaid_Payment_Form_Submission::get_field() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
202 | $name = implode( '', array_filter( $name ) ); |
||||
203 | $user = wpinv_create_user( $submission->get_billing_email(), $name ); |
||||
204 | |||||
205 | // (Maybe) send new user notification. |
||||
206 | $should_send_notification = wpinv_get_option( 'disable_new_user_emails' ); |
||||
207 | if ( ! empty( $user ) && is_numeric( $user ) && apply_filters( 'getpaid_send_new_user_notification', empty( $should_send_notification ), $user ) ) { |
||||
0 ignored issues
–
show
|
|||||
208 | wp_send_new_user_notifications( $user, 'user' ); |
||||
209 | } |
||||
210 | } |
||||
211 | |||||
212 | if ( is_wp_error( $user ) ) { |
||||
213 | wp_send_json_error( $user->get_error_message() ); |
||||
214 | } |
||||
215 | |||||
216 | if ( is_numeric( $user ) ) { |
||||
217 | return $user; |
||||
218 | } |
||||
219 | |||||
220 | return $user->ID; |
||||
221 | |||||
222 | } |
||||
223 | |||||
224 | /** |
||||
225 | * Prepares submission data for saving to the database. |
||||
226 | * |
||||
227 | * @return array |
||||
228 | */ |
||||
229 | public function prepare_submission_data_for_saving() { |
||||
230 | |||||
231 | $submission = $this->payment_form_submission; |
||||
232 | |||||
233 | // Prepared submission details. |
||||
234 | $prepared = array( |
||||
235 | 'all' => array(), |
||||
236 | 'meta' => array(), |
||||
237 | ); |
||||
238 | |||||
239 | // Raw submission details. |
||||
240 | $data = $submission->get_data(); |
||||
241 | |||||
242 | // Loop through the submitted details. |
||||
243 | foreach ( $submission->get_payment_form()->get_elements() as $field ) { |
||||
244 | |||||
245 | // Skip premade fields. |
||||
246 | if ( ! empty( $field['premade'] ) ) { |
||||
247 | continue; |
||||
248 | } |
||||
249 | |||||
250 | // Ensure address is provided. |
||||
251 | if ( 'address' === $field['type'] ) { |
||||
252 | $address_type = isset( $field['address_type'] ) && 'shipping' === $field['address_type'] ? 'shipping' : 'billing'; |
||||
253 | |||||
254 | foreach ( $field['fields'] as $address_field ) { |
||||
255 | |||||
256 | if ( ! empty( $address_field['visible'] ) && ! empty( $address_field['required'] ) && '' === trim( $_POST[ $address_type ][ $address_field['name'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing |
||||
257 | wp_send_json_error( __( 'Please fill all required fields.', 'invoicing' ) ); |
||||
258 | } |
||||
259 | } |
||||
260 | } |
||||
261 | |||||
262 | // If it is required and not set, abort. |
||||
263 | if ( ! $submission->is_required_field_set( $field ) ) { |
||||
264 | wp_send_json_error( __( 'Please fill all required fields.', 'invoicing' ) ); |
||||
265 | } |
||||
266 | |||||
267 | // Handle misc fields. |
||||
268 | if ( isset( $data[ $field['id'] ] ) ) { |
||||
269 | |||||
270 | // Uploads. |
||||
271 | if ( 'file_upload' === $field['type'] ) { |
||||
272 | $max_file_num = empty( $field['max_file_num'] ) ? 1 : absint( $field['max_file_num'] ); |
||||
273 | |||||
274 | if ( count( $data[ $field['id'] ] ) > $max_file_num ) { |
||||
275 | wp_send_json_error( __( 'Maximum number of allowed files exceeded.', 'invoicing' ) ); |
||||
276 | } |
||||
277 | |||||
278 | $value = array(); |
||||
279 | |||||
280 | foreach ( $data[ $field['id'] ] as $url => $name ) { |
||||
281 | $value[] = sprintf( |
||||
282 | '<a href="%s" target="_blank">%s</a>', |
||||
283 | esc_url_raw( $url ), |
||||
284 | esc_html( $name ) |
||||
285 | ); |
||||
286 | } |
||||
287 | |||||
288 | $value = implode( ' | ', $value ); |
||||
289 | |||||
290 | } elseif ( 'checkbox' === $field['type'] ) { |
||||
291 | $value = ! empty( $data[ $field['id'] ] ) ? __( 'Yes', 'invoicing' ) : __( 'No', 'invoicing' ); |
||||
292 | } else { |
||||
293 | $value = wp_kses_post( $data[ $field['id'] ] ); |
||||
294 | } |
||||
295 | |||||
296 | $label = $field['id']; |
||||
297 | |||||
298 | if ( isset( $field['label'] ) ) { |
||||
299 | $label = $field['label']; |
||||
300 | } |
||||
301 | |||||
302 | if ( ! empty( $field['add_meta'] ) ) { |
||||
303 | $prepared['meta'][ wpinv_clean( $label ) ] = wp_kses_post_deep( $value ); |
||||
304 | } |
||||
305 | $prepared['all'][ wpinv_clean( $label ) ] = wp_kses_post_deep( $value ); |
||||
306 | |||||
307 | } |
||||
308 | } |
||||
309 | |||||
310 | return $prepared; |
||||
311 | |||||
312 | } |
||||
313 | |||||
314 | /** |
||||
315 | * Retrieves address details. |
||||
316 | * |
||||
317 | * @return array |
||||
318 | * @param WPInv_Invoice $invoice |
||||
319 | * @param string $type |
||||
320 | */ |
||||
321 | public function prepare_address_details( $invoice, $type = 'billing' ) { |
||||
322 | |||||
323 | $data = $this->payment_form_submission->get_data(); |
||||
324 | $type = sanitize_key( $type ); |
||||
325 | $address = array(); |
||||
326 | $prepared = array(); |
||||
327 | |||||
328 | if ( ! empty( $data[ $type ] ) ) { |
||||
329 | $address = $data[ $type ]; |
||||
330 | } |
||||
331 | |||||
332 | // Clean address details. |
||||
333 | foreach ( $address as $key => $value ) { |
||||
334 | $key = sanitize_key( $key ); |
||||
335 | $key = str_replace( 'wpinv_', '', $key ); |
||||
336 | $value = wpinv_clean( $value ); |
||||
337 | $prepared[ $key ] = apply_filters( "getpaid_checkout_{$type}_address_$key", $value, $this->payment_form_submission, $invoice ); |
||||
338 | } |
||||
339 | |||||
340 | // Filter address details. |
||||
341 | $prepared = apply_filters( "getpaid_checkout_{$type}_address", $prepared, $this->payment_form_submission, $invoice ); |
||||
342 | |||||
343 | // Remove non-whitelisted values. |
||||
344 | return array_filter( $prepared, 'getpaid_is_address_field_whitelisted', ARRAY_FILTER_USE_KEY ); |
||||
345 | |||||
346 | } |
||||
347 | |||||
348 | /** |
||||
349 | * Prepares the billing details. |
||||
350 | * |
||||
351 | * @return array |
||||
352 | * @param WPInv_Invoice $invoice |
||||
353 | */ |
||||
354 | protected function prepare_billing_info( &$invoice ) { |
||||
355 | |||||
356 | $billing_address = $this->prepare_address_details( $invoice, 'billing' ); |
||||
357 | |||||
358 | // Update the invoice with the billing details. |
||||
359 | $invoice->set_props( $billing_address ); |
||||
360 | |||||
361 | } |
||||
362 | |||||
363 | /** |
||||
364 | * Prepares the shipping details. |
||||
365 | * |
||||
366 | * @return array |
||||
367 | * @param WPInv_Invoice $invoice |
||||
368 | */ |
||||
369 | protected function prepare_shipping_info( $invoice ) { |
||||
370 | |||||
371 | $data = $this->payment_form_submission->get_data(); |
||||
372 | |||||
373 | if ( empty( $data['same-shipping-address'] ) ) { |
||||
374 | return $this->prepare_address_details( $invoice, 'shipping' ); |
||||
375 | } |
||||
376 | |||||
377 | return $this->prepare_address_details( $invoice, 'billing' ); |
||||
378 | |||||
379 | } |
||||
380 | |||||
381 | /** |
||||
382 | * Confirms the submission is valid and send users to the gateway. |
||||
383 | * |
||||
384 | * @param WPInv_Invoice $invoice |
||||
385 | * @param array $prepared_payment_form_data |
||||
386 | * @param array $shipping |
||||
387 | */ |
||||
388 | protected function post_process_submission( $invoice, $prepared_payment_form_data, $shipping ) { |
||||
389 | |||||
390 | // Ensure the invoice exists. |
||||
391 | if ( ! $invoice->exists() ) { |
||||
392 | wp_send_json_error( __( 'An error occured while saving your invoice. Please try again.', 'invoicing' ) ); |
||||
393 | } |
||||
394 | |||||
395 | // Save payment form data. |
||||
396 | $prepared_payment_form_data = apply_filters( 'getpaid_prepared_payment_form_data', $prepared_payment_form_data, $invoice ); |
||||
397 | delete_post_meta( $invoice->get_id(), 'payment_form_data' ); |
||||
398 | delete_post_meta( $invoice->get_id(), 'additional_meta_data' ); |
||||
399 | if ( ! empty( $prepared_payment_form_data ) ) { |
||||
400 | |||||
401 | if ( ! empty( $prepared_payment_form_data['all'] ) ) { |
||||
402 | update_post_meta( $invoice->get_id(), 'payment_form_data', $prepared_payment_form_data['all'] ); |
||||
403 | } |
||||
404 | |||||
405 | if ( ! empty( $prepared_payment_form_data['meta'] ) ) { |
||||
406 | update_post_meta( $invoice->get_id(), 'additional_meta_data', $prepared_payment_form_data['meta'] ); |
||||
407 | } |
||||
408 | } |
||||
409 | |||||
410 | // Save payment form data. |
||||
411 | $shipping = apply_filters( 'getpaid_checkout_shipping_details', $shipping, $this->payment_form_submission ); |
||||
412 | if ( ! empty( $shipping ) ) { |
||||
413 | update_post_meta( $invoice->get_id(), 'shipping_address', $shipping ); |
||||
414 | } |
||||
415 | |||||
416 | // Backwards compatibility. |
||||
417 | add_filter( 'wp_redirect', array( $this, 'send_redirect_response' ) ); |
||||
418 | |||||
419 | try { |
||||
420 | $this->process_payment( $invoice ); |
||||
421 | } catch ( Exception $e ) { |
||||
422 | wpinv_set_error( 'payment_error', $e->getMessage() ); |
||||
423 | } |
||||
424 | |||||
425 | // If we are here, there was an error. |
||||
426 | wpinv_send_back_to_checkout( $invoice ); |
||||
427 | |||||
428 | } |
||||
429 | |||||
430 | /** |
||||
431 | * Processes the actual payment. |
||||
432 | * |
||||
433 | * @param WPInv_Invoice $invoice |
||||
434 | */ |
||||
435 | protected function process_payment( $invoice ) { |
||||
436 | |||||
437 | // Clear any checkout errors. |
||||
438 | wpinv_clear_errors(); |
||||
439 | |||||
440 | // No need to send free invoices to the gateway. |
||||
441 | if ( $invoice->is_free() ) { |
||||
442 | $this->process_free_payment( $invoice ); |
||||
443 | } |
||||
444 | |||||
445 | $submission = $this->payment_form_submission; |
||||
446 | |||||
447 | // Fires before sending to the gateway. |
||||
448 | do_action( 'getpaid_checkout_before_gateway', $invoice, $submission ); |
||||
449 | |||||
450 | // Allow the sumission data to be modified before it is sent to the gateway. |
||||
451 | $submission_data = $submission->get_data(); |
||||
452 | $submission_gateway = apply_filters( 'getpaid_gateway_submission_gateway', $invoice->get_gateway(), $submission, $invoice ); |
||||
453 | $submission_data = apply_filters( 'getpaid_gateway_submission_data', $submission_data, $submission, $invoice ); |
||||
454 | |||||
455 | // Validate the currency. |
||||
456 | if ( ! apply_filters( "getpaid_gateway_{$submission_gateway}_is_valid_for_currency", true, $invoice->get_currency() ) ) { |
||||
457 | wpinv_set_error( 'invalid_currency' ); |
||||
458 | } |
||||
459 | |||||
460 | // Check to see if we have any errors. |
||||
461 | if ( wpinv_get_errors() ) { |
||||
462 | wpinv_send_back_to_checkout( $invoice ); |
||||
463 | } |
||||
464 | |||||
465 | // Send info to the gateway for payment processing |
||||
466 | do_action( "getpaid_gateway_$submission_gateway", $invoice, $submission_data, $submission ); |
||||
467 | |||||
468 | // Backwards compatibility. |
||||
469 | wpinv_send_to_gateway( $submission_gateway, $invoice ); |
||||
0 ignored issues
–
show
The function
wpinv_send_to_gateway() has been deprecated.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
470 | |||||
471 | } |
||||
472 | |||||
473 | /** |
||||
474 | * Marks the invoice as paid in case the checkout is free. |
||||
475 | * |
||||
476 | * @param WPInv_Invoice $invoice |
||||
477 | */ |
||||
478 | protected function process_free_payment( $invoice ) { |
||||
479 | |||||
480 | $invoice->set_gateway( 'none' ); |
||||
481 | $invoice->add_note( __( "This is a free invoice and won't be sent to the payment gateway", 'invoicing' ), false, false, true ); |
||||
482 | $invoice->mark_paid(); |
||||
483 | wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) ); |
||||
484 | |||||
485 | } |
||||
486 | |||||
487 | /** |
||||
488 | * Sends a redrect response to payment details. |
||||
489 | * |
||||
490 | */ |
||||
491 | public function send_redirect_response( $url ) { |
||||
492 | $url = rawurlencode( $url ); |
||||
493 | wp_send_json_success( $url ); |
||||
494 | } |
||||
495 | |||||
496 | } |
||||
497 |
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.