Passed
Push — master ( c24352...fabb71 )
by Brian
14:05 queued 08:38
created

wpinv_checkout_form_get_user()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 22
nc 12
nop 1
dl 0
loc 37
rs 8.0555
c 1
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
        'worldpay' => array(
21
            'admin_label'    => __( 'Worldpay', 'invoicing' ),
22
            'checkout_label' => __( 'Worldpay - Credit Card / Debit Card', 'invoicing' ),
23
            'ordering'       => 5,
24
        ),
25
        'bank_transfer' => array(
26
            'admin_label'    => __( 'Pre Bank Transfer', 'invoicing' ),
27
            'checkout_label' => __( 'Pre Bank Transfer', 'invoicing' ),
28
            'ordering'       => 11,
29
        ),
30
    );
31
32
    return apply_filters( 'wpinv_payment_gateways', $gateways );
33
}
34
35
function wpinv_payment_gateway_titles( $all_gateways ) {
36
    global $wpinv_options;
37
38
    $gateways = array();
39
    foreach ( $all_gateways as $key => $gateway ) {
40
        if ( !empty( $wpinv_options[$key . '_title'] ) ) {
41
            $all_gateways[$key]['checkout_label'] = __( $wpinv_options[$key . '_title'], 'invoicing' );
42
        }
43
44
        $gateways[$key] = isset( $wpinv_options[$key . '_ordering'] ) ? $wpinv_options[$key . '_ordering'] : ( isset( $gateway['ordering'] ) ? $gateway['ordering'] : '' );
45
    }
46
47
    asort( $gateways );
48
49
    foreach ( $gateways as $gateway => $key ) {
50
        $gateways[$gateway] = $all_gateways[$gateway];
51
    }
52
53
    return $gateways;
54
}
55
add_filter( 'wpinv_payment_gateways', 'wpinv_payment_gateway_titles', 1000, 1 );
56
57
function wpinv_get_enabled_payment_gateways( $sort = false ) {
58
    $gateways = wpinv_get_payment_gateways();
59
    $enabled  = wpinv_get_option( 'gateways', false );
60
61
    $gateway_list = array();
62
63
    foreach ( $gateways as $key => $gateway ) {
64
        if ( isset( $enabled[ $key ] ) && $enabled[ $key ] == 1 ) {
65
            $gateway_list[ $key ] = $gateway;
66
        }
67
    }
68
69
    if ( true === $sort ) {
70
        uasort( $gateway_list, 'wpinv_sort_gateway_order' );
71
        
72
        // Reorder our gateways so the default is first
73
        $default_gateway_id = wpinv_get_default_gateway();
74
75
        if ( wpinv_is_gateway_active( $default_gateway_id ) ) {
76
            $default_gateway    = array( $default_gateway_id => $gateway_list[ $default_gateway_id ] );
77
            unset( $gateway_list[ $default_gateway_id ] );
78
79
            $gateway_list = array_merge( $default_gateway, $gateway_list );
80
        }
81
    }
82
83
    return apply_filters( 'wpinv_enabled_payment_gateways', $gateway_list );
84
}
85
86
function wpinv_sort_gateway_order( $a, $b ) {
87
    return $a['ordering'] - $b['ordering'];
88
}
89
90
function wpinv_is_gateway_active( $gateway ) {
91
    $gateways = wpinv_get_enabled_payment_gateways();
92
93
    $ret = is_array($gateways) && $gateway ?  array_key_exists( $gateway, $gateways ) : false;
94
95
    return apply_filters( 'wpinv_is_gateway_active', $ret, $gateway, $gateways );
96
}
97
98
function wpinv_get_default_gateway() {
99
    $default = wpinv_get_option( 'default_gateway', 'paypal' );
100
101
    if ( !wpinv_is_gateway_active( $default ) ) {
102
        $gateways = wpinv_get_enabled_payment_gateways();
103
        $gateways = array_keys( $gateways );
104
        $default  = reset( $gateways );
105
    }
106
107
    return apply_filters( 'wpinv_default_gateway', $default );
108
}
109
110
function wpinv_get_gateway_admin_label( $gateway ) {
111
    $gateways = wpinv_get_payment_gateways();
112
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['admin_label'] : $gateway;
113
    $payment  = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : false;
114
115
    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...
116
        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

116
        if( !( (float)/** @scrutinizer ignore-deprecated */ wpinv_payment_total( $payment ) > 0 ) ) {
Loading history...
117
            $label = __( 'Free Purchase', 'invoicing' );
118
        }
119
    }
120
121
    return apply_filters( 'wpinv_gateway_admin_label', $label, $gateway );
122
}
123
124
function wpinv_get_gateway_description( $gateway ) {
125
    global $wpinv_options;
126
127
    $description = ! empty( $wpinv_options[$gateway . '_desc'] ) ? $wpinv_options[$gateway . '_desc'] : '';
128
129
    return apply_filters( 'wpinv_gateway_description', $description, $gateway );
130
}
131
132
function wpinv_get_gateway_button_label( $gateway ) {
133
    return apply_filters( 'wpinv_gateway_' . $gateway . '_button_label', '' );
134
}
135
136
function wpinv_get_gateway_checkout_label( $gateway ) {
137
    $gateways = wpinv_get_payment_gateways();
138
    $label    = isset( $gateways[ $gateway ] ) ? $gateways[ $gateway ]['checkout_label'] : $gateway;
139
140
    if( $gateway == 'manual' ) {
141
        $label = __( 'Manual Payment', 'invoicing' );
142
    }
143
144
    return apply_filters( 'wpinv_gateway_checkout_label', ucfirst( $label ), $gateway );
145
}
146
147
function wpinv_settings_sections_gateways( $settings ) {
148
    $gateways = wpinv_get_payment_gateways();
149
    
150
    if (!empty($gateways)) {
151
        foreach  ($gateways as $key => $gateway) {
152
            $settings[$key] = $gateway['admin_label'];
153
        }
154
    }
155
    
156
    return $settings;    
157
}
158
add_filter( 'wpinv_settings_sections_gateways', 'wpinv_settings_sections_gateways', 10, 1 );
159
160
function wpinv_settings_gateways( $settings ) {
161
    $gateways = wpinv_get_payment_gateways();
162
    
163
    if (!empty($gateways)) {
164
        foreach  ($gateways as $key => $gateway) {
165
            $setting = array();
166
            $setting[$key . '_header'] = array(
167
                    'id'   => 'gateway_header',
168
                    'name' => '<h3>' . wp_sprintf( __( '%s Settings', 'invoicing' ), $gateway['admin_label'] ) . '</h3>',
169
                    'custom' => $key,
170
                    'type' => 'gateway_header',
171
                );
172
            $setting[$key . '_active'] = array(
173
                    'id'   => $key . '_active',
174
                    'name' => __( 'Active', 'invoicing' ),
175
                    'desc' => wp_sprintf( __( 'Enable %s', 'invoicing' ), $gateway['admin_label'] ),
176
                    'type' => 'checkbox',
177
                );
178
                
179
            $setting[$key . '_title'] = array(
180
                    'id'   => $key . '_title',
181
                    'name' => __( 'Title', 'invoicing' ),
182
                    'desc' => __( 'This controls the title which the user sees during checkout.', 'invoicing' ),
183
                    'type' => 'text',
184
                    'std' => isset($gateway['checkout_label']) ? $gateway['checkout_label'] : ''
185
                );
186
            
187
            $setting[$key . '_desc'] = array(
188
                    'id'   => $key . '_desc',
189
                    'name' => __( 'Description', 'invoicing' ),
190
                    'desc' => __( 'This controls the description which the user sees during checkout.', 'invoicing' ),
191
                    'type' => 'text',
192
                    'size' => 'large'
193
                );
194
                
195
            $setting[$key . '_ordering'] = array(
196
                    'id'   => $key . '_ordering',
197
                    'name' => __( 'Display Order', 'invoicing' ),
198
                    'type' => 'number',
199
                    'size' => 'small',
200
                    'std'  => isset($gateway['ordering']) ? $gateway['ordering'] : '10',
201
                    'min'  => '-100000',
202
                    'max'  => '100000',
203
                    'step' => '1'
204
                );
205
                
206
            $setting = apply_filters( 'wpinv_gateway_settings', $setting, $key );
207
            $setting = apply_filters( 'wpinv_gateway_settings_' . $key, $setting );
208
            
209
            $settings[$key] = $setting;
210
        }
211
    }
212
    
213
    return $settings;    
214
}
215
add_filter( 'wpinv_settings_gateways', 'wpinv_settings_gateways', 10, 1 );
216
217
function wpinv_gateway_header_callback( $args ) {
218
    echo '<input type="hidden" id="wpinv_settings[save_gateway]" name="wpinv_settings[save_gateway]" value="' . esc_attr( $args['custom'] ) . '" />';
219
}
220
221
function wpinv_get_gateway_supports( $gateway ) {
222
    $gateways = wpinv_get_enabled_payment_gateways();
223
    $supports = isset( $gateways[ $gateway ]['supports'] ) ? $gateways[ $gateway ]['supports'] : array();
224
    return apply_filters( 'wpinv_gateway_supports', $supports, $gateway );
225
}
226
227
function wpinv_gateway_supports_buy_now( $gateway ) {
228
    $supports = wpinv_get_gateway_supports( $gateway );
229
    $ret = in_array( 'buy_now', $supports );
230
    return apply_filters( 'wpinv_gateway_supports_buy_now', $ret, $gateway );
231
}
232
233
function wpinv_shop_supports_buy_now() {
234
    $gateways = wpinv_get_enabled_payment_gateways();
235
    $ret      = false;
236
237
    if ( !wpinv_use_taxes()  && $gateways ) {
238
        foreach ( $gateways as $gateway_id => $gateway ) {
239
            if ( wpinv_gateway_supports_buy_now( $gateway_id ) ) {
240
                $ret = true;
241
                break;
242
            }
243
        }
244
    }
245
246
    return apply_filters( 'wpinv_shop_supports_buy_now', $ret );
247
}
248
249
250
function wpinv_show_gateways() {
251
    $gateways = wpinv_get_enabled_payment_gateways();
252
    $show_gateways = false;
253
254
    $chosen_gateway = isset( $_GET['payment-mode'] ) ? preg_replace('/[^a-zA-Z0-9-_]+/', '', $_GET['payment-mode'] ) : false;
255
256
    if ( count( $gateways ) > 1 && empty( $chosen_gateway ) ) {
257
        $show_gateways = true;
258
        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

258
        if ( /** @scrutinizer ignore-deprecated */ wpinv_get_cart_total() <= 0 ) {
Loading history...
259
            $show_gateways = false;
260
        }
261
    }
262
    
263
    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

263
    if ( !$show_gateways && /** @scrutinizer ignore-deprecated */ wpinv_cart_has_recurring_item() ) {
Loading history...
264
        $show_gateways = true;
265
    }
266
267
    return apply_filters( 'wpinv_show_gateways', $show_gateways );
268
}
269
270
function wpinv_get_chosen_gateway( $invoice_id = 0 ) {
271
	$gateways = array_keys( wpinv_get_enabled_payment_gateways() );
272
273
    $chosen = false;
274
    if ( $invoice_id > 0 && $invoice = wpinv_get_invoice( $invoice_id ) ) {
275
        $chosen = $invoice->get_gateway();
276
    }
277
278
	$chosen   = isset( $_REQUEST['payment-mode'] ) ? sanitize_text_field( $_REQUEST['payment-mode'] ) : $chosen;
279
280
	if ( false !== $chosen ) {
281
		$chosen = preg_replace('/[^a-zA-Z0-9-_]+/', '', $chosen );
282
	}
283
284
	if ( ! empty ( $chosen ) ) {
285
		$enabled_gateway = urldecode( $chosen );
286
	} else if (  !empty( $invoice ) && (float)$invoice->get_subtotal() <= 0 ) {
287
		$enabled_gateway = 'manual';
288
	} else {
289
		$enabled_gateway = wpinv_get_default_gateway();
290
	}
291
    
292
    if ( !wpinv_is_gateway_active( $enabled_gateway ) && !empty( $gateways ) ) {
293
        if(wpinv_is_gateway_active( wpinv_get_default_gateway()) ){
294
            $enabled_gateway = wpinv_get_default_gateway();
295
        }else{
296
            $enabled_gateway = $gateways[0];
297
        }
298
299
    }
300
301
	return apply_filters( 'wpinv_chosen_gateway', $enabled_gateway );
302
}
303
304
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

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

Used in variable context

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

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...
732
733
    foreach ( $data as $key => $value ) {
734
        if ( false !== strpos( $key, 'amp;' ) ) {
735
            $new_key = str_replace( '&amp;', '&', $key );
736
            $new_key = str_replace( 'amp;', '&' , $new_key );
737
738
            unset( $data[ $key ] );
739
            $data[ $new_key ] = sanitize_text_field( $value );
740
        }
741
    }
742
    
743
    return $data;
744
}
745
746
/**
747
 * Checks if a given gateway supports subscription payments.
748
 */
749
function wpinv_gateway_support_subscription( $gateway ) {
750
    $supports = false;
751
752
    if ( wpinv_is_gateway_active( $gateway ) ) {
753
        $supports = apply_filters( 'wpinv_' . $gateway . '_support_subscription', $supports );
754
        $supports = apply_filters( 'getapid_gateway_supports_subscription', $supports, $gateway );
755
    }
756
757
    return $supports;
758
}
759
760
/**
761
 * Filters payment form gateways.
762
 * 
763
 * @param array $gateways an array of gateways.
764
 * @param GetPaid_Payment_Form $form payment form.
765
 */
766
function wpinv_payment_gateways_on_cart( $gateways, $form ) {
767
768
    if ( $form->is_recurring() ) {
769
770
        foreach ( array_keys( $gateways ) as $gateway ) {
771
772
            if ( ! wpinv_gateway_support_subscription( $gateway ) ) {
773
                unset( $gateways[$gateway] );
774
            }
775
776
        }
777
778
    }
779
780
    return $gateways;
781
}
782
add_filter( 'getpaid_payment_form_gateways', 'wpinv_payment_gateways_on_cart', 10, 2 );
783
784
/**
785
 * Validates checkout fields.
786
 *
787
 * @param GetPaid_Payment_Form_Submission $submission
788
 */
789
function wpinv_checkout_validate_gateway( $submission ) {
790
791
    $data = $submission->get_data();
792
793
    // Non-recurring gateways should not be allowed to process recurring invoices.
794
    if ( $submission->has_recurring && ! wpinv_gateway_support_subscription( $data['wpi-gateway'] ) ) {
795
        wpinv_set_error( 'invalid_gateway', __( 'The selected payment gateway does not support subscription payment.', 'invoicing' ) );
796
    }
797
798
    if ( ! wpinv_is_gateway_active( $data['wpi-gateway'] ) ) {
799
        wpinv_set_error( 'invalid_gateway', __( 'The selected payment gateway is not active', 'invoicing' ) );
800
    }
801
802
}
803
804
/**
805
 * Validates a zip code.
806
 */
807
function wpinv_checkout_validate_cc_zip( $zip = 0, $country_code = '' ) {
808
809
    if ( empty( $zip ) || empty( $country_code ) ){
810
        return false;
811
    }
812
813
    // Prepare the country code.
814
    $country_code = strtoupper( trim( $country_code ) );
815
816
    // Fetch the regexes.
817
    $zip_regex = wpinv_get_data( 'zip-regexes' );
818
819
    // Check if it is valid.
820
    $is_valid = ! isset ( $zip_regex[ $country_code ] ) || preg_match( "/" . $zip_regex[ $country_code ] . "/i", $zip );
821
822
    return apply_filters( 'wpinv_is_zip_valid', $is_valid, $zip, $country_code );
823
}
824
825
function wpinv_checkout_validate_agree_to_terms() {
826
    // Validate agree to terms
827
    if ( ! isset( $_POST['wpi_agree_to_terms'] ) || $_POST['wpi_agree_to_terms'] != 1 ) {
828
        // User did not agree
829
        wpinv_set_error( 'agree_to_terms', apply_filters( 'wpinv_agree_to_terms_text', __( 'You must agree to the terms of use', 'invoicing' ) ) );
830
    }
831
}
832
833
function wpinv_checkout_validate_invoice_user() {
834
    global $wpi_cart, $user_ID;
835
836
    if(empty($wpi_cart)){
837
        $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

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