Passed
Pull Request — master (#388)
by Brian
05:00
created

wpinv_ipn_url_callback()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Contains gateway functions.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Returns an array of payment gateways.
11
 */
12
function wpinv_get_payment_gateways() {
13
    // Default, built-in gateways
14
    $gateways = array(
15
        'authorizenet' => array(
16
            'admin_label'    => __( 'Authorize.Net (AIM)', 'invoicing' ),
17
            'checkout_label' => __( 'Authorize.Net - Credit Card / Debit Card', 'invoicing' ),
18
            'ordering'       => 4,
19
        ),
20
        'bank_transfer' => array(
21
            'admin_label'    => __( 'Pre Bank Transfer', 'invoicing' ),
22
            'checkout_label' => __( 'Pre Bank Transfer', 'invoicing' ),
23
            'ordering'       => 11,
24
        ),
25
    );
26
27
    $gateways = apply_filters( 'wpinv_payment_gateways', $gateways );
28
    return is_array( $gateways ) ? $gateways : array();
29
}
30
31
function wpinv_payment_gateway_titles( $all_gateways ) {
32
    global $wpinv_options;
33
34
    $gateways = array();
35
    foreach ( $all_gateways as $key => $gateway ) {
36
        if ( !empty( $wpinv_options[$key . '_title'] ) ) {
37
            $all_gateways[$key]['checkout_label'] = __( $wpinv_options[$key . '_title'], 'invoicing' );
38
        }
39
40
        $gateways[$key] = isset( $wpinv_options[$key . '_ordering'] ) ? $wpinv_options[$key . '_ordering'] : ( isset( $gateway['ordering'] ) ? $gateway['ordering'] : '' );
41
    }
42
43
    asort( $gateways );
44
45
    foreach ( $gateways as $gateway => $key ) {
46
        $gateways[$gateway] = $all_gateways[$gateway];
47
    }
48
49
    return $gateways;
50
}
51
add_filter( 'wpinv_payment_gateways', 'wpinv_payment_gateway_titles', 1000, 1 );
52
53
function wpinv_get_enabled_payment_gateways( $sort = false ) {
54
    $gateways = wpinv_get_payment_gateways();
55
    $enabled  = wpinv_get_option( 'gateways', false );
56
57
    $gateway_list = array();
58
59
    foreach ( $gateways as $key => $gateway ) {
60
        if ( isset( $enabled[ $key ] ) && $enabled[ $key ] == 1 ) {
61
            $gateway_list[ $key ] = $gateway;
62
        }
63
    }
64
65
    if ( true === $sort ) {
66
        uasort( $gateway_list, 'wpinv_sort_gateway_order' );
67
        
68
        // Reorder our gateways so the default is first
69
        $default_gateway_id = wpinv_get_default_gateway();
70
71
        if ( wpinv_is_gateway_active( $default_gateway_id ) ) {
72
            $default_gateway    = array( $default_gateway_id => $gateway_list[ $default_gateway_id ] );
73
            unset( $gateway_list[ $default_gateway_id ] );
74
75
            $gateway_list = array_merge( $default_gateway, $gateway_list );
76
        }
77
    }
78
79
    return apply_filters( 'wpinv_enabled_payment_gateways', $gateway_list );
80
}
81
82
function wpinv_sort_gateway_order( $a, $b ) {
83
    return $a['ordering'] - $b['ordering'];
84
}
85
86
function wpinv_is_gateway_active( $gateway ) {
87
    $gateways = wpinv_get_enabled_payment_gateways();
88
89
    $ret = is_array($gateways) && $gateway ?  array_key_exists( $gateway, $gateways ) : false;
90
91
    return apply_filters( 'wpinv_is_gateway_active', $ret, $gateway, $gateways );
92
}
93
94
function wpinv_get_default_gateway() {
95
    $default = wpinv_get_option( 'default_gateway', 'paypal' );
96
97
    if ( !wpinv_is_gateway_active( $default ) ) {
98
        $gateways = wpinv_get_enabled_payment_gateways();
99
        $gateways = array_keys( $gateways );
100
        $default  = reset( $gateways );
101
    }
102
103
    return apply_filters( 'wpinv_default_gateway', $default );
104
}
105
106
function wpinv_get_gateway_admin_label( $gateway ) {
107
    $gateways = wpinv_get_payment_gateways();
108
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['admin_label'] : $gateway;
109
    $payment  = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : false;
110
111
    if( $gateway == 'manual' && $payment ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
112
        if( !( (float)wpinv_payment_total( $payment ) > 0 ) ) {
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_payment_total() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

112
        if( !( (float)/** @scrutinizer ignore-deprecated */ wpinv_payment_total( $payment ) > 0 ) ) {
Loading history...
113
            $label = __( 'Free Purchase', 'invoicing' );
114
        }
115
    }
116
117
    return apply_filters( 'wpinv_gateway_admin_label', $label, $gateway );
118
}
119
120
function wpinv_get_gateway_description( $gateway ) {
121
    global $wpinv_options;
122
123
    $description = ! empty( $wpinv_options[$gateway . '_desc'] ) ? $wpinv_options[$gateway . '_desc'] : '';
124
125
    return apply_filters( 'wpinv_gateway_description', $description, $gateway );
126
}
127
128
function wpinv_get_gateway_button_label( $gateway ) {
129
    return apply_filters( 'wpinv_gateway_' . $gateway . '_button_label', '' );
130
}
131
132
function wpinv_get_gateway_checkout_label( $gateway ) {
133
    $gateways = wpinv_get_payment_gateways();
134
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['checkout_label'] : $gateway;
135
136
    if( $gateway == 'manual' ) {
137
        $label = __( 'Manual Payment', 'invoicing' );
138
    }
139
140
    return apply_filters( 'wpinv_gateway_checkout_label', ucfirst( $label ), $gateway );
141
}
142
143
function wpinv_settings_sections_gateways( $settings ) {
144
    $gateways = wpinv_get_payment_gateways();
145
    
146
    if (!empty($gateways)) {
147
        foreach  ($gateways as $key => $gateway) {
148
            $settings[$key] = $gateway['admin_label'];
149
        }
150
    }
151
    
152
    return $settings;    
153
}
154
add_filter( 'wpinv_settings_sections_gateways', 'wpinv_settings_sections_gateways', 10, 1 );
155
156
/**
157
 * Adds GateWay settings.
158
 */
159
function wpinv_settings_gateways( $settings ) {
160
161
    // Loop through each gateway.
162
    foreach  ( wpinv_get_payment_gateways() as $key => $gateway ) {
163
164
        $gateway_settings = array(
165
166
            // Header.
167
            "{$key}_header" => array(
168
169
                'id'     => "{$key}_gateway_header",
170
                'name'   => '<h3>' . wp_sprintf( __( '%s Settings', 'invoicing' ), $gateway['admin_label'] ) . '</h3>',
171
                'custom' => $key,
172
                'type'   => 'gateway_header',
173
174
            ),
175
176
            // Activate/Deactivate a gateway.
177
            "{$key}_active" => array(
178
                'id'   => $key . '_active',
179
                'name' => __( 'Activate', 'invoicing' ),
180
                'desc' => wp_sprintf( __( 'Enable %s', 'invoicing' ), $gateway['admin_label'] ),
181
                'type' => 'checkbox',
182
            ),
183
184
            // Activate/Deactivate sandbox.
185
            "{$key}_sandbox" => array(
186
                'id'   => $key . '_sandbox',
187
                'name' => __( 'Sandbox', 'invoicing' ),
188
                'desc' => __( 'Enable sandbox to test payments', 'invoicing' ),
189
                'type' => 'checkbox',
190
            ),
191
192
            // Checkout title.
193
            "{$key}_title" => array(
194
                'id'   => $key . '_title',
195
                'name' => __( 'Checkout Title', 'invoicing' ),
196
                'std'  => isset( $gateway['checkout_label'] ) ? $gateway['checkout_label'] : '',
197
                'type' => 'text',
198
            ),
199
200
            // Checkout description.
201
            "{$key}_desc" => array(
202
                'id'   => $key . '_desc',
203
                'name' => __( 'Checkout Description', 'invoicing' ),
204
                'std'  => apply_filters( "getpaid_default_{$key}_checkout_description", '' ),
205
                'type' => 'text',
206
            ),
207
208
            // Checkout order.
209
            "{$key}_ordering" => array(
210
                'id'   => $key . '_ordering',
211
                'name' => __( 'Priority', 'invoicing' ),
212
                'std'  => apply_filters( "getpaid_default_{$key}_checkout_description", '' ),
213
                'type' => 'number',
214
                'step' => '1',
215
                'min'  => '-100000',
216
                'max'  => '100000',
217
                'std'  => isset( $gateway['ordering'] ) ? $gateway['ordering'] : '10',
218
            ),
219
220
        );
221
222
        // Maybe remove the sandbox.
223
        if ( ! apply_filters( "wpinv_{$key}_supports_sandbox", false ) ) {
224
            unset( $gateway_settings["{$key}_sandbox"] );
225
        }
226
  
227
        $gateway_settings = apply_filters( 'wpinv_gateway_settings', $gateway_settings, $key, $gateway );
228
        $gateway_settings = apply_filters( 'wpinv_gateway_settings_' . $key, $gateway_settings, $gateway );
229
        
230
        $settings[$key] = $gateway_settings;
231
    }
232
233
    return $settings;
234
235
}
236
add_filter( 'wpinv_settings_gateways', 'wpinv_settings_gateways', 10, 1 );
237
238
function wpinv_gateway_header_callback( $args ) {
239
    echo '<input type="hidden" id="wpinv_settings[save_gateway]" name="wpinv_settings[save_gateway]" value="' . esc_attr( $args['custom'] ) . '" />';
240
}
241
242
function wpinv_get_gateway_supports( $gateway ) {
243
    $gateways = wpinv_get_enabled_payment_gateways();
244
    $supports = isset( $gateways[ $gateway ]['supports'] ) ? $gateways[ $gateway ]['supports'] : array();
245
    return apply_filters( 'wpinv_gateway_supports', $supports, $gateway );
246
}
247
248
function wpinv_gateway_supports_buy_now( $gateway ) {
249
    $supports = wpinv_get_gateway_supports( $gateway );
250
    $ret = in_array( 'buy_now', $supports );
251
    return apply_filters( 'wpinv_gateway_supports_buy_now', $ret, $gateway );
252
}
253
254
function wpinv_shop_supports_buy_now() {
255
    $gateways = wpinv_get_enabled_payment_gateways();
256
    $ret      = false;
257
258
    if ( !wpinv_use_taxes()  && $gateways ) {
259
        foreach ( $gateways as $gateway_id => $gateway ) {
260
            if ( wpinv_gateway_supports_buy_now( $gateway_id ) ) {
261
                $ret = true;
262
                break;
263
            }
264
        }
265
    }
266
267
    return apply_filters( 'wpinv_shop_supports_buy_now', $ret );
268
}
269
270
271
function wpinv_show_gateways() {
272
    $gateways = wpinv_get_enabled_payment_gateways();
273
    $show_gateways = false;
274
275
    $chosen_gateway = isset( $_GET['payment-mode'] ) ? preg_replace('/[^a-zA-Z0-9-_]+/', '', $_GET['payment-mode'] ) : false;
276
277
    if ( count( $gateways ) > 1 && empty( $chosen_gateway ) ) {
278
        $show_gateways = true;
279
        if ( wpinv_get_cart_total() <= 0 ) {
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_get_cart_total() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

279
        if ( /** @scrutinizer ignore-deprecated */ wpinv_get_cart_total() <= 0 ) {
Loading history...
280
            $show_gateways = false;
281
        }
282
    }
283
    
284
    if ( !$show_gateways && wpinv_cart_has_recurring_item() ) {
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_cart_has_recurring_item() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

284
    if ( !$show_gateways && /** @scrutinizer ignore-deprecated */ wpinv_cart_has_recurring_item() ) {
Loading history...
285
        $show_gateways = true;
286
    }
287
288
    return apply_filters( 'wpinv_show_gateways', $show_gateways );
289
}
290
291
function wpinv_get_chosen_gateway( $invoice_id = 0 ) {
292
	$gateways = array_keys( wpinv_get_enabled_payment_gateways() );
293
294
    $chosen = false;
295
    if ( $invoice_id > 0 && $invoice = wpinv_get_invoice( $invoice_id ) ) {
296
        $chosen = $invoice->get_gateway();
297
    }
298
299
	$chosen   = isset( $_REQUEST['payment-mode'] ) ? sanitize_text_field( $_REQUEST['payment-mode'] ) : $chosen;
300
301
	if ( false !== $chosen ) {
302
		$chosen = preg_replace('/[^a-zA-Z0-9-_]+/', '', $chosen );
303
	}
304
305
	if ( ! empty ( $chosen ) ) {
306
		$enabled_gateway = urldecode( $chosen );
307
	} else if (  !empty( $invoice ) && (float)$invoice->get_subtotal() <= 0 ) {
308
		$enabled_gateway = 'manual';
309
	} else {
310
		$enabled_gateway = wpinv_get_default_gateway();
311
	}
312
    
313
    if ( !wpinv_is_gateway_active( $enabled_gateway ) && !empty( $gateways ) ) {
314
        if(wpinv_is_gateway_active( wpinv_get_default_gateway()) ){
315
            $enabled_gateway = wpinv_get_default_gateway();
316
        }else{
317
            $enabled_gateway = $gateways[0];
318
        }
319
320
    }
321
322
	return apply_filters( 'wpinv_chosen_gateway', $enabled_gateway );
323
}
324
325
function wpinv_record_gateway_error( $title = '', $message = '', $parent = 0 ) {
0 ignored issues
show
Unused Code introduced by
The parameter $parent is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

325
function wpinv_record_gateway_error( $title = '', $message = '', /** @scrutinizer ignore-unused */ $parent = 0 ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
326
    return wpinv_error_log( $message, $title );
0 ignored issues
show
Bug introduced by
Are you sure the usage of wpinv_error_log($message, $title) is correct as it 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 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.

Loading history...
327
}
328
329
function wpinv_count_sales_by_gateway( $gateway_id = 'paypal', $status = 'publish' ) {
330
	$ret  = 0;
331
	$args = array(
332
		'meta_key'    => '_wpinv_gateway',
333
		'meta_value'  => $gateway_id,
334
		'nopaging'    => true,
335
		'post_type'   => 'wpi_invoice',
336
		'post_status' => $status,
337
		'fields'      => 'ids'
338
	);
339
340
	$payments = new WP_Query( $args );
341
342
	if( $payments )
0 ignored issues
show
introduced by
$payments is of type WP_Query, thus it always evaluated to true.
Loading history...
343
		$ret = $payments->post_count;
344
	return $ret;
345
}
346
347
function wpinv_settings_update_gateways( $input ) {
348
    global $wpinv_options;
349
    
350
    if ( !empty( $input['save_gateway'] ) ) {
351
        $gateways = wpinv_get_option( 'gateways', false );
352
        $gateways = !empty($gateways) ? $gateways : array();
353
        $gateway = $input['save_gateway'];
354
        
355
        if ( !empty( $input[$gateway . '_active'] ) ) {
356
            $gateways[$gateway] = 1;
357
        } else {
358
            if ( isset( $gateways[$gateway] ) ) {
359
                unset( $gateways[$gateway] );
360
            }
361
        }
362
        
363
        $input['gateways'] = $gateways;
364
    }
365
    
366
    if ( !empty( $input['default_gateway'] ) ) {
367
        $gateways = wpinv_get_payment_gateways();
368
        
369
        foreach ( $gateways as $key => $gateway ) {
370
            $active   = 0;
371
            if ( !empty( $input['gateways'] ) && !empty( $input['gateways'][$key] ) ) {
372
                $active = 1;
373
            }
374
            
375
            $input[$key . '_active'] = $active;
376
            
377
            if ( empty( $wpinv_options[$key . '_title'] ) ) {
378
                $input[$key . '_title'] = $gateway['checkout_label'];
379
            }
380
            
381
            if ( !isset( $wpinv_options[$key . '_ordering'] ) && isset( $gateway['ordering'] ) ) {
382
                $input[$key . '_ordering'] = $gateway['ordering'];
383
            }
384
        }
385
    }
386
    
387
    return $input;
388
}
389
add_filter( 'wpinv_settings_tab_gateways_sanitize', 'wpinv_settings_update_gateways', 10, 1 );
390
391
// PayPal Standard settings
392
function wpinv_gateway_settings_paypal( $setting ) {    
393
    $setting['paypal_active']['desc'] = $setting['paypal_active']['desc'] . ' ' . __( '( Supported Currencies: AUD, BRL, CAD, CZK, DKK, EUR, HKD, HUF, ILS, JPY, MYR, MXN, NOK, NZD, PHP, PLN, GBP, SGD, SEK, CHF, TWD, THB, USD )', 'invoicing' );
394
    $setting['paypal_desc']['std'] = __( 'Pay via PayPal: you can pay with your credit card if you don\'t have a PayPal account.', 'invoicing' );
395
    
396
    $setting['paypal_sandbox'] = array(
397
            'type' => 'checkbox',
398
            'id'   => 'paypal_sandbox',
399
            'name' => __( 'PayPal Sandbox', 'invoicing' ),
400
            'desc' => __( 'PayPal sandbox can be used to test payments.', 'invoicing' ),
401
            'std'  => 1
402
        );
403
        
404
    $setting['paypal_email'] = array(
405
            'type' => 'text',
406
            'id'   => 'paypal_email',
407
            'name' => __( 'PayPal Email', 'invoicing' ),
408
            'desc' => __( 'Please enter your PayPal account\'s email address. Ex: [email protected]', 'invoicing' ),
409
            'std' => __( '[email protected]', 'invoicing' ),
410
        );
411
    /*
412
    $setting['paypal_ipn_url'] = array(
413
            'type' => 'text',
414
            'id'   => 'paypal_ipn_url',
415
            'name' => __( 'PayPal IPN Url', 'invoicing' ),
416
            'desc' => __( 'Configure Instant Payment Notifications(IPN) url at PayPal. Ex: http://yoursite.com/?wpi-ipn=paypal', 'invoicing' ),
417
            'size' => 'large'
418
        );
419
    */
420
        
421
    return $setting;
422
}
423
add_filter( 'wpinv_gateway_settings_paypal', 'wpinv_gateway_settings_paypal', 10, 1 );
424
425
// Pre Bank Transfer settings
426
function wpinv_gateway_settings_bank_transfer( $setting ) {
427
    $setting['bank_transfer_desc']['std'] = __( 'Make your payment directly into our bank account. Please use your Invoice ID as the payment reference. Your invoice won\'t be processed until the funds have cleared in our account.', 'invoicing' );
428
    
429
    $setting['bank_transfer_ac_name'] = array(
430
            'type' => 'text',
431
            'id' => 'bank_transfer_ac_name',
432
            'name' => __( 'Account Name', 'invoicing' ),
433
            'desc' => __( 'Enter the bank account name to which you want to transfer payment.', 'invoicing' ),
434
            'std'  =>  __( 'Mr. John Martin', 'invoicing' ),
435
        );
436
    
437
    $setting['bank_transfer_ac_no'] = array(
438
            'type' => 'text',
439
            'id' => 'bank_transfer_ac_no',
440
            'name' => __( 'Account Number', 'invoicing' ),
441
            'desc' => __( 'Enter your bank account number.', 'invoicing' ),
442
            'std'  =>  __( 'TEST1234567890', 'invoicing' ),
443
        );
444
    
445
    $setting['bank_transfer_bank_name'] = array(
446
            'type' => 'text',
447
            'id'   => 'bank_transfer_bank_name',
448
            'name' => __( 'Bank Name', 'invoicing' ),
449
            'desc' => __( 'Enter the bank name to which you want to transfer payment.', 'invoicing' ),
450
            'std' => __( 'ICICI Bank', 'invoicing' ),
451
        );
452
    
453
    $setting['bank_transfer_ifsc'] = array(
454
            'type' => 'text',
455
            'id'   => 'bank_transfer_ifsc',
456
            'name' => __( 'IFSC Code', 'invoicing' ),
457
            'desc' => __( 'Enter your bank IFSC code.', 'invoicing' ),
458
            'std'  =>  __( 'ICIC0001234', 'invoicing' ),
459
        );
460
        
461
    $setting['bank_transfer_iban'] = array(
462
            'type' => 'text',
463
            'id'   => 'bank_transfer_iban',
464
            'name' => __( 'IBAN', 'invoicing' ),
465
            'desc' => __( 'Enter your International Bank Account Number(IBAN).', 'invoicing' ),
466
            'std'  =>  __( 'GB29NWBK60161331926819', 'invoicing' ),
467
        );
468
        
469
    $setting['bank_transfer_bic'] = array(
470
            'type' => 'text',
471
            'id'   => 'bank_transfer_bic',
472
            'name' => __( 'BIC/Swift Code', 'invoicing' ),
473
            'std'  =>  __( 'ICICGB2L129', 'invoicing' ),
474
        );
475
476
    $setting['bank_transfer_sort_code'] = array(
477
        'type' => 'text',
478
        'id'   => 'bank_transfer_sort_code',
479
        'name' => __( 'Sort Code', 'invoicing' ),
480
        'std'  =>  __( '12-34-56', 'invoicing' ),
481
    );
482
        
483
    $setting['bank_transfer_info'] = array(
484
            'id'   => 'bank_transfer_info',
485
            'name' => __( 'Instructions', 'invoicing' ),
486
            'desc' => __( 'Instructions that will be added to the thank you page and emails.', 'invoicing' ),
487
            'type' => 'textarea',
488
            'std' => __( 'Make your payment directly into our bank account. Please use your Invoice ID as the payment reference. Your invoice won\'t be processed until the funds have cleared in our account.', 'invoicing' ),
489
            'cols' => 37,
490
            'rows' => 5
491
        );
492
        
493
    return $setting;
494
}
495
add_filter( 'wpinv_gateway_settings_bank_transfer', 'wpinv_gateway_settings_bank_transfer', 10, 1 );
496
497
// Authorize.Net settings
498
function wpinv_gateway_settings_authorizenet( $setting ) {
499
    $setting['authorizenet_active']['desc'] = $setting['authorizenet_active']['desc'] . ' ' . __( '( Supported Currencies: AUD, CAD, CHF, DKK, EUR, GBP, JPY, NOK, NZD, PLN, SEK, USD, ZAR )', 'invoicing' );
500
    $setting['authorizenet_desc']['std'] = __( 'Pay using a Authorize.Net to process Credit card / Debit card transactions.', 'invoicing' );
501
    
502
    $setting['authorizenet_sandbox'] = array(
503
            'type' => 'checkbox',
504
            'id'   => 'authorizenet_sandbox',
505
            'name' => __( 'Authorize.Net Test Mode', 'invoicing' ),
506
            'desc' => __( 'Enable Authorize.Net test mode to test payments.', 'invoicing' ),
507
            'std'  => 1
508
        );
509
        
510
    $setting['authorizenet_login_id'] = array(
511
            'type' => 'text',
512
            'id'   => 'authorizenet_login_id',
513
            'name' => __( 'API Login ID', 'invoicing' ),
514
            'desc' => __( 'API Login ID can be obtained from Authorize.Net Account > Settings > Security Settings > General Security Settings > API Credentials & Keys. Example : 2j4rBekUnD', 'invoicing' ),
515
            'std' => '2j4rBekUnD',
516
        );
517
    
518
    $setting['authorizenet_transaction_key'] = array(
519
            'type' => 'text',
520
            'id'   => 'authorizenet_transaction_key',
521
            'name' => __( 'Transaction Key', 'invoicing' ),
522
            'desc' => __( 'Transaction Key can be obtained from Authorize.Net Account > Settings > Security Settings > General Security Settings > API Credentials & Keys. Example : 4vyBUOJgR74679xa', 'invoicing' ),
523
            'std' => '4vyBUOJgR74679xa',
524
        );
525
        
526
    $setting['authorizenet_md5_hash'] = array(
527
            'type' => 'text',
528
            'id'   => 'authorizenet_md5_hash',
529
            'name' => __( 'MD5-Hash', 'invoicing' ),
530
            'desc' => __( 'The MD5 Hash security feature allows to authenticate transaction responses from the Authorize.Net for recurring payments. It can be obtained from Authorize.Net Account > Settings > Security Settings > General Settings > MD5 Hash.', 'invoicing' ),
531
            'std' => '',
532
        );
533
534
    $setting['authorizenet_transaction_type'] = array(
535
        'id'          => 'authorizenet_transaction_type',
536
        'name'        => __( 'Transaction Type', 'invoicing' ),
537
        'desc'        => __( 'Choose transaction type.', 'invoicing' ),
538
        'type'        => 'select',
539
        'class'       => 'wpi_select2',
540
        'options'     => array(
541
            'authorize_capture' => __( 'Authorize And Capture', 'invoicing' ),
542
            'authorize_only' => __( 'Authorize Only', 'invoicing' ),
543
        ),
544
        'std'         => 'authorize_capture'
545
    );
546
547
    $setting['authorizenet_transaction_type_recurring'] = array(
548
        'id'          => 'authorizenet_transaction_type_recurring',
549
        'name'        => __( 'Transaction Type for Recurring', 'invoicing' ),
550
        'desc'        => __( 'Choose transaction type for recurring payments.', 'invoicing' ),
551
        'type'        => 'select',
552
        'class'       => 'wpi_select2',
553
        'options'     => array(
554
            'authorize_capture' => __( 'Authorize And Capture', 'invoicing' ),
555
            'authorize_only' => __( 'Authorize Only', 'invoicing' ),
556
        ),
557
        'std'         => 'authorize_only'
558
    );
559
        
560
    $setting['authorizenet_ipn_url'] = array(
561
            'type' => 'ipn_url',
562
            'id'   => 'authorizenet_ipn_url',
563
            'name' => __( 'Silent Post URL', 'invoicing' ),
564
            'std' => wpinv_get_ipn_url( 'authorizenet' ),
565
            'desc' => __( 'If you are accepting recurring payments then you must set this url at Authorize.Net Account > Settings > Transaction Format Settings > Transaction Response Settings > Silent Post URL.', 'invoicing' ),
566
            'size' => 'large',
567
            'custom' => 'authorizenet',
568
            'readonly' => true
569
        );
570
        
571
    return $setting;
572
}
573
add_filter( 'wpinv_gateway_settings_authorizenet', 'wpinv_gateway_settings_authorizenet', 10, 1 );
574
575
function wpinv_ipn_url_callback( $args ) {    
576
    $sanitize_id = wpinv_sanitize_key( $args['id'] );
577
    
578
    $attrs = $args['readonly'] ? ' readonly' : '';
579
580
    $html = '<input style="background-color:#fefefe" type="text" ' . $attrs . ' value="' . esc_attr( $args['std'] ) . '" name="wpinv_settings[' . $sanitize_id . ']" id="wpinv_settings[' . $sanitize_id . ']" class="large-text">';
581
    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']">'  . $args['desc'] . '</label>';
582
583
    echo $html;
584
}
585
586
function wpinv_is_test_mode( $gateway = '' ) {
587
    if ( empty( $gateway ) ) {
588
        return false;
589
    }
590
    
591
    $is_test_mode = wpinv_get_option( $gateway . '_sandbox', false );
592
    
593
    return apply_filters( 'wpinv_is_test_mode', $is_test_mode, $gateway );
594
}
595
596
function wpinv_get_ipn_url( $gateway = '', $args = array() ) {
597
    $data = array( 'wpi-listener' => 'IPN' );
598
    
599
    if ( !empty( $gateway ) ) {
600
        $data['wpi-gateway'] = wpinv_sanitize_key( $gateway );
601
    }
602
    
603
    $args = !empty( $args ) && is_array( $args ) ? array_merge( $data, $args ) : $data;
604
    
605
    $ipn_url = add_query_arg( $args,  home_url( 'index.php' ) );
606
    
607
    return apply_filters( 'wpinv_ipn_url', $ipn_url );
608
}
609
610
function wpinv_listen_for_payment_ipn() {
611
    // Regular PayPal IPN
612
    if ( isset( $_GET['wpi-listener'] ) && $_GET['wpi-listener'] == 'IPN' ) {
613
        do_action( 'wpinv_verify_payment_ipn' );
614
        
615
        if ( !empty( $_GET['wpi-gateway'] ) ) {
616
            wpinv_error_log( sanitize_text_field( $_GET['wpi-gateway'] ), 'WP Invoicing IPN', __FILE__, __LINE__ );
617
            do_action( 'wpinv_verify_' . sanitize_text_field( $_GET['wpi-gateway'] ) . '_ipn' );
618
        }
619
    }
620
}
621
add_action( 'init', 'wpinv_listen_for_payment_ipn' );
622
623
function wpinv_get_bank_instructions() {
624
    $bank_instructions = wpinv_get_option( 'bank_transfer_info' );
625
    
626
    return apply_filters( 'wpinv_bank_instructions', $bank_instructions );
627
}
628
629
function wpinv_get_bank_info( $filtered = false ) {
630
    $bank_fields = array(
631
        'bank_transfer_ac_name'     => __( 'Account Name', 'invoicing' ),
632
        'bank_transfer_ac_no'       => __( 'Account Number', 'invoicing' ),
633
        'bank_transfer_bank_name'   => __( 'Bank Name', 'invoicing' ),
634
        'bank_transfer_ifsc'        => __( 'IFSC code', 'invoicing' ),
635
        'bank_transfer_iban'        => __( 'IBAN', 'invoicing' ),
636
        'bank_transfer_bic'         => __( 'BIC/Swift code', 'invoicing' ),
637
        'bank_transfer_sort_code'   => __( 'Sort Code', 'invoicing' )
638
    );
639
    
640
    $bank_info = array();
641
    foreach ( $bank_fields as $field => $label ) {
642
        if ( $filtered && !( $value = wpinv_get_option( $field ) ) ) {
643
            continue;
644
        }
645
        
646
        $bank_info[$field] = array( 'label' => $label, 'value' => $value );
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $value seems to be defined later in this foreach loop on line 642. Are you sure it is defined here?
Loading history...
647
    }
648
    
649
    return apply_filters( 'wpinv_bank_info', $bank_info, $filtered );
650
}
651
652
function wpinv_get_post_data( $method = 'request' ) {
653
    $data       = array();
654
    $request    = $_REQUEST;
655
    
656
    if ( $method == 'post' ) {
657
        if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'POST' ) {
658
            return $data;
659
        }
660
        
661
        $request = $_POST;
662
    }
663
    
664
    if ( $method == 'get' ) {
665
        if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'GET' ) {
666
            return $data;
667
        }
668
        
669
        $request = $_GET;
670
    }
671
    
672
    // Set initial post data to empty string
673
    $post_data = '';
674
    
675
    // Fallback just in case post_max_size is lower than needed
676
    if ( ini_get( 'allow_url_fopen' ) ) {
677
        $post_data = file_get_contents( 'php://input' );
678
    } else {
679
        // If allow_url_fopen is not enabled, then make sure that post_max_size is large enough
680
        ini_set( 'post_max_size', '12M' );
681
    }
682
    // Start the encoded data collection with notification command
683
    $encoded_data = 'cmd=_notify-validate';
684
685
    // Get current arg separator
686
    $arg_separator = wpinv_get_php_arg_separator_output();
687
688
    // Verify there is a post_data
689
    if ( $post_data || strlen( $post_data ) > 0 ) {
690
        // Append the data
691
        $encoded_data .= $arg_separator . $post_data;
692
    } else {
693
        // Check if POST is empty
694
        if ( empty( $request ) ) {
695
            // Nothing to do
696
            return;
697
        } else {
698
            // Loop through each POST
699
            foreach ( $request as $key => $value ) {
700
                // Encode the value and append the data
701
                $encoded_data .= $arg_separator . "$key=" . urlencode( $value );
702
            }
703
        }
704
    }
705
706
    // Convert collected post data to an array
707
    wp_parse_str( $encoded_data, $data );
0 ignored issues
show
Security Variable Injection introduced by
$encoded_data can contain request data and is used in variable name context(s) leading to a potential security vulnerability.

3 paths for user data to reach this point

  1. Path: Read from $_GET, and $_GET is assigned to $request in includes/wpinv-gateway-functions.php on line 669
  1. Read from $_GET, and $_GET is assigned to $request
    in includes/wpinv-gateway-functions.php on line 669
  2. $request is assigned to $value
    in includes/wpinv-gateway-functions.php on line 699
  3. Data is passed through urlencode(), and $arg_separator . $key.'=' . urlencode($value) is assigned to $encoded_data
    in includes/wpinv-gateway-functions.php on line 701
  2. Path: Read from $_POST, and $_POST is assigned to $request in includes/wpinv-gateway-functions.php on line 661
  1. Read from $_POST, and $_POST is assigned to $request
    in includes/wpinv-gateway-functions.php on line 661
  2. $request is assigned to $value
    in includes/wpinv-gateway-functions.php on line 699
  3. Data is passed through urlencode(), and $arg_separator . $key.'=' . urlencode($value) is assigned to $encoded_data
    in includes/wpinv-gateway-functions.php on line 701
  3. Path: Read from $_REQUEST, and $_REQUEST is assigned to $request in includes/wpinv-gateway-functions.php on line 654
  1. Read from $_REQUEST, and $_REQUEST is assigned to $request
    in includes/wpinv-gateway-functions.php on line 654
  2. $request is assigned to $value
    in includes/wpinv-gateway-functions.php on line 699
  3. Data is passed through urlencode(), and $arg_separator . $key.'=' . urlencode($value) is assigned to $encoded_data
    in includes/wpinv-gateway-functions.php on line 701

Used in variable context

  1. wp_parse_str() is called
    in includes/wpinv-gateway-functions.php on line 707
  2. Enters via parameter $string
    in wordpress/wp-includes/formatting.php on line 4938
  3. parse_str() is called
    in wordpress/wp-includes/formatting.php on line 4939

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
708
709
    foreach ( $data as $key => $value ) {
710
        if ( false !== strpos( $key, 'amp;' ) ) {
711
            $new_key = str_replace( '&amp;', '&', $key );
712
            $new_key = str_replace( 'amp;', '&' , $new_key );
713
714
            unset( $data[ $key ] );
715
            $data[ $new_key ] = sanitize_text_field( $value );
716
        }
717
    }
718
    
719
    return $data;
720
}
721
722
/**
723
 * Checks if a given gateway supports subscription payments.
724
 */
725
function wpinv_gateway_support_subscription( $gateway ) {
726
    $supports = false;
727
728
    if ( wpinv_is_gateway_active( $gateway ) ) {
729
        $supports = apply_filters( 'wpinv_' . $gateway . '_support_subscription', $supports );
730
        $supports = apply_filters( 'getapid_gateway_supports_subscription', $supports, $gateway );
731
    }
732
733
    return $supports;
734
}
735
736
/**
737
 * Filters payment form gateways.
738
 * 
739
 * @param array $gateways an array of gateways.
740
 * @param GetPaid_Payment_Form $form payment form.
741
 */
742
function wpinv_payment_gateways_on_cart( $gateways, $form ) {
743
744
    if ( $form->is_recurring() ) {
745
746
        foreach ( array_keys( $gateways ) as $gateway ) {
747
748
            if ( ! wpinv_gateway_support_subscription( $gateway ) ) {
749
                unset( $gateways[$gateway] );
750
            }
751
752
        }
753
754
    }
755
756
    return $gateways;
757
}
758
add_filter( 'getpaid_payment_form_gateways', 'wpinv_payment_gateways_on_cart', 10, 2 );
759
760
/**
761
 * Validates checkout fields.
762
 *
763
 * @param GetPaid_Payment_Form_Submission $submission
764
 */
765
function wpinv_checkout_validate_gateway( $submission ) {
766
767
    $data = $submission->get_data();
768
769
    // Non-recurring gateways should not be allowed to process recurring invoices.
770
    if ( $submission->has_recurring && ! wpinv_gateway_support_subscription( $data['wpi-gateway'] ) ) {
771
        wpinv_set_error( 'invalid_gateway', __( 'The selected payment gateway does not support subscription payment.', 'invoicing' ) );
772
    }
773
774
    if ( ! wpinv_is_gateway_active( $data['wpi-gateway'] ) ) {
775
        wpinv_set_error( 'invalid_gateway', __( 'The selected payment gateway is not active', 'invoicing' ) );
776
    }
777
778
}
779
780
/**
781
 * Validates a zip code.
782
 */
783
function wpinv_checkout_validate_cc_zip( $zip = 0, $country_code = '' ) {
784
785
    if ( empty( $zip ) || empty( $country_code ) ){
786
        return false;
787
    }
788
789
    // Prepare the country code.
790
    $country_code = strtoupper( trim( $country_code ) );
791
792
    // Fetch the regexes.
793
    $zip_regex = wpinv_get_data( 'zip-regexes' );
794
795
    // Check if it is valid.
796
    $is_valid = ! isset ( $zip_regex[ $country_code ] ) || preg_match( "/" . $zip_regex[ $country_code ] . "/i", $zip );
797
798
    return apply_filters( 'wpinv_is_zip_valid', $is_valid, $zip, $country_code );
799
}
800
801
function wpinv_checkout_validate_agree_to_terms() {
802
    // Validate agree to terms
803
    if ( ! isset( $_POST['wpi_agree_to_terms'] ) || $_POST['wpi_agree_to_terms'] != 1 ) {
804
        // User did not agree
805
        wpinv_set_error( 'agree_to_terms', apply_filters( 'wpinv_agree_to_terms_text', __( 'You must agree to the terms of use', 'invoicing' ) ) );
806
    }
807
}
808
809
function wpinv_checkout_validate_invoice_user() {
810
    global $wpi_cart, $user_ID;
811
812
    if(empty($wpi_cart)){
813
        $wpi_cart = wpinv_get_invoice_cart();
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_get_invoice_cart() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

813
        $wpi_cart = /** @scrutinizer ignore-deprecated */ wpinv_get_invoice_cart();
Loading history...
814
    }
815
816
    $invoice_user = (int)$wpi_cart->get_user_id();
817
    $valid_user_data = array(
818
        'user_id' => $invoice_user
819
    );
820
821
    // If guest checkout allowed
822
    if ( !wpinv_require_login_to_checkout() ) {
823
        return $valid_user_data;
824
    }
825
    
826
    // Verify there is a user_ID
827
    if ( $user_ID == $invoice_user ) {
828
        // Get the logged in user data
829
        $user_data = get_userdata( $user_ID );
830
        $required_fields  = wpinv_checkout_required_fields();
831
832
        // Loop through required fields and show error messages
833
         if ( !empty( $required_fields ) ) {
834
            foreach ( $required_fields as $field_name => $value ) {
835
                if ( in_array( $value, $required_fields ) && empty( $_POST[ 'wpinv_' . $field_name ] ) ) {
836
                    wpinv_set_error( $value['error_id'], $value['error_message'] );
837
                }
838
            }
839
        }
840
841
        // Verify data
842
        if ( $user_data ) {
843
            // Collected logged in user data
844
            $valid_user_data = array(
845
                'user_id'     => $user_ID,
846
                'email'       => isset( $_POST['wpinv_email'] ) ? sanitize_email( $_POST['wpinv_email'] ) : $user_data->user_email,
847
                'first_name'  => isset( $_POST['wpinv_first_name'] ) && ! empty( $_POST['wpinv_first_name'] ) ? sanitize_text_field( $_POST['wpinv_first_name'] ) : $user_data->first_name,
848
                'last_name'   => isset( $_POST['wpinv_last_name'] ) && ! empty( $_POST['wpinv_last_name']  ) ? sanitize_text_field( $_POST['wpinv_last_name']  ) : $user_data->last_name,
849
            );
850
851
            if ( !empty( $_POST[ 'wpinv_email' ] ) && !is_email( $_POST[ 'wpinv_email' ] ) ) {
852
                wpinv_set_error( 'invalid_email', __( 'Please enter a valid email address', 'invoicing' ) );
853
            }
854
        } else {
855
            // Set invalid user error
856
            wpinv_set_error( 'invalid_user', __( 'The user billing information is invalid', 'invoicing' ) );
857
        }
858
    } else {
859
        // Set invalid user error
860
        wpinv_set_error( 'invalid_user_id', __( 'The invalid invoice user id', 'invoicing' ) );
861
    }
862
863
    // Return user data
864
    return $valid_user_data;
865
}
866
867
function wpinv_checkout_validate_current_user() {
868
    global $wpi_cart;
869
870
    $data = array();
871
    
872
    if ( is_user_logged_in() ) {
873
        if ( !wpinv_require_login_to_checkout() || ( wpinv_require_login_to_checkout() && (int)$wpi_cart->get_user_id() === (int)get_current_user_id() ) ) {
874
            $data['user_id'] = (int)get_current_user_id();
875
        } else {
876
            wpinv_set_error( 'logged_in_only', __( 'You are not allowed to pay for this invoice', 'invoicing' ) );
877
        }
878
    } else {
879
        // If guest checkout allowed
880
        if ( !wpinv_require_login_to_checkout() ) {
881
            $data['user_id'] = 0;
882
        } else {
883
            wpinv_set_error( 'logged_in_only', __( 'You must be logged in to pay for this invoice', 'invoicing' ) );
884
        }
885
    }
886
887
    return $data;
888
}
889
890
891
/**
892
 * Processes checkout payments.
893
 *
894
 * @param WPInv_Invoice $invoice
895
 * @param GetPaid_Payment_Form_Submission $submission
896
 */
897
function wpinv_process_checkout( $invoice, $submission ) {
898
899
    // No need to send free invoices to the gateway.
900
    if ( $invoice->is_free() ) {
901
        $invoice->set_gateway( 'none' );
902
        $invoice->add_note( __( "This is a free invoice and won't be sent to the payment gateway", 'invoicing' ), false, false, true );
903
        $invoice->mark_paid();
904
        wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) );
905
    }
906
907
    // Clear an checkout errors.
908
    wpinv_clear_errors();
909
910
    // Fires before sending to the gateway.
911
    do_action( 'getpaid_checkout_before_gateway', $invoice, $submission );
912
913
    // Allow the sumission data to be modified before it is sent to the gateway.
914
    $submission_data    = $submission->get_data();
915
    $submission_gateway = apply_filters( 'getpaid_gateway_submission_gateway', $submission_data['wpi-gateway'], $submission, $invoice );
916
    $submission_data    = apply_filters( 'getpaid_gateway_submission_data', $submission_data, $submission, $invoice );
917
918
    // Validate the currency.
919
    if ( ! apply_filters( "getpaid_gateway_{$submission_gateway}_is_valid_for_currency", true, $invoice->get_currency() ) ) {
920
        wpinv_set_error( 'invalid_currency', __( 'The chosen payment gateway does not support the invoice currency', 'invoicing' ) );
921
    }
922
923
    // Check to see if we have any errors.
924
    if ( wpinv_get_errors() ) {
925
        wpinv_send_back_to_checkout();
926
    }
927
928
    // Send info to the gateway for payment processing
929
    do_action( "getpaid_gateway_$submission_gateway", $invoice, $submission_data, $submission );
930
931
    // Backwards compatibility.
932
    do_action( "wpinv_gateway_$submission_gateway", null, $invoice, $submission_data, $submission );
933
934
}
935