PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.2.4
GiveWP – Donation Plugin and Fundraising Platform v2.2.4
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / gateways / paypal-standard.php
give / includes / gateways Last commit date
actions.php 7 years ago functions.php 8 years ago manual.php 8 years ago offline-donations.php 7 years ago paypal-standard.php 7 years ago
paypal-standard.php
711 lines
1 <?php
2 /**
3 * PayPal Standard Gateway
4 *
5 * @package Give
6 * @subpackage Gateways
7 * @copyright Copyright (c) 2016, WordImpress
8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 * @since 1.0
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 /**
17 * Toggle PayPal CC Billing Detail Fieldset.
18 *
19 * @param int $form_id Form ID.
20 *
21 * @since 1.8.5
22 *
23 * @return bool
24 */
25 function give_paypal_standard_billing_fields( $form_id ) {
26
27 if ( give_is_setting_enabled( give_get_option( 'paypal_standard_billing_details' ) ) ) {
28 give_default_cc_address_fields( $form_id );
29
30 return true;
31 }
32
33 return false;
34
35 }
36
37 add_action( 'give_paypal_cc_form', 'give_paypal_standard_billing_fields' );
38
39 /**
40 * Process PayPal Payment.
41 *
42 * @param array $payment_data Payment data.
43 *
44 * @since 1.0
45 *
46 * @return void
47 */
48 function give_process_paypal_payment( $payment_data ) {
49
50 // Validate nonce.
51 give_validate_nonce( $payment_data['gateway_nonce'], 'give-gateway' );
52
53 $payment_id = give_create_payment( $payment_data );
54
55 // Check payment.
56 if ( empty( $payment_id ) ) {
57 // Record the error.
58 give_record_gateway_error( __( 'Payment Error', 'give' ), sprintf( /* translators: %s: payment data */
59 __( 'Payment creation failed before sending donor to PayPal. Payment data: %s', 'give' ), json_encode( $payment_data ) ), $payment_id );
60 // Problems? Send back.
61 give_send_back_to_checkout( '?payment-mode=' . $payment_data['post_data']['give-gateway'] );
62 }
63
64 // Redirect to PayPal.
65 wp_redirect( give_build_paypal_url( $payment_id, $payment_data ) );
66 exit;
67 }
68
69 add_action( 'give_gateway_paypal', 'give_process_paypal_payment' );
70
71 /**
72 * Listens for a PayPal IPN requests and then sends to the processing function.
73 *
74 * @since 1.0
75 * @return void
76 */
77 function give_listen_for_paypal_ipn() {
78
79 // Regular PayPal IPN.
80 if ( isset( $_GET['give-listener'] ) && 'IPN' === $_GET['give-listener'] ) {
81 /**
82 * Fires while verifying PayPal IPN
83 *
84 * @since 1.0
85 */
86 do_action( 'give_verify_paypal_ipn' );
87 }
88 }
89
90 add_action( 'init', 'give_listen_for_paypal_ipn' );
91
92 /**
93 * Process PayPal IPN
94 *
95 * @since 1.0
96 * @return void
97 */
98 function give_process_paypal_ipn() {
99
100 // Check the request method is POST.
101 if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
102 return;
103 }
104
105 // Set initial post data to empty string.
106 $post_data = '';
107
108 // Fallback just in case post_max_size is lower than needed.
109 if ( ini_get( 'allow_url_fopen' ) ) {
110 $post_data = file_get_contents( 'php://input' );
111 } else {
112 // If allow_url_fopen is not enabled, then make sure that post_max_size is large enough.
113 ini_set( 'post_max_size', '12M' );
114 }
115 // Start the encoded data collection with notification command.
116 $encoded_data = 'cmd=_notify-validate';
117
118 // Get current arg separator.
119 $arg_separator = give_get_php_arg_separator_output();
120
121 // Verify there is a post_data.
122 if ( $post_data || strlen( $post_data ) > 0 ) {
123 // Append the data.
124 $encoded_data .= $arg_separator . $post_data;
125 } else {
126 // Check if POST is empty.
127 if ( empty( $_POST ) ) {
128 // Nothing to do.
129 return;
130 } else {
131 // Loop through each POST.
132 foreach ( $_POST as $key => $value ) {
133 // Encode the value and append the data.
134 $encoded_data .= $arg_separator . "$key=" . urlencode( $value );
135 }
136 }
137 }
138
139 // Convert collected post data to an array.
140 parse_str( $encoded_data, $encoded_data_array );
141
142 foreach ( $encoded_data_array as $key => $value ) {
143
144 if ( false !== strpos( $key, 'amp;' ) ) {
145 $new_key = str_replace( '&amp;', '&', $key );
146 $new_key = str_replace( 'amp;', '&', $new_key );
147
148 unset( $encoded_data_array[ $key ] );
149 $encoded_data_array[ $new_key ] = $value;
150 }
151 }
152
153 $api_response = false;
154
155 // Validate IPN request w/ PayPal if user hasn't disabled this security measure.
156 if ( give_is_setting_enabled( give_get_option( 'paypal_verification' ) ) ) {
157
158 $remote_post_vars = array(
159 'method' => 'POST',
160 'timeout' => 45,
161 'redirection' => 5,
162 'httpversion' => '1.1',
163 'blocking' => true,
164 'headers' => array(
165 'host' => 'www.paypal.com',
166 'connection' => 'close',
167 'content-type' => 'application/x-www-form-urlencoded',
168 'post' => '/cgi-bin/webscr HTTP/1.1',
169
170 ),
171 'sslverify' => false,
172 'body' => $encoded_data_array,
173 );
174
175 // Validate the IPN.
176 $api_response = wp_remote_post( give_get_paypal_redirect(), $remote_post_vars );
177
178 if ( is_wp_error( $api_response ) ) {
179 give_record_gateway_error( __( 'IPN Error', 'give' ), sprintf( /* translators: %s: Paypal IPN response */
180 __( 'Invalid IPN verification response. IPN data: %s', 'give' ), json_encode( $api_response ) ) );
181
182 return; // Something went wrong.
183 }
184
185 if ( 'VERIFIED' !== $api_response['body'] ) {
186 give_record_gateway_error( __( 'IPN Error', 'give' ), sprintf( /* translators: %s: Paypal IPN response */
187 __( 'Invalid IPN verification response. IPN data: %s', 'give' ), json_encode( $api_response ) ) );
188
189 return; // Response not okay.
190 }
191 }// End if().
192
193 // Check if $post_data_array has been populated.
194 if ( ! is_array( $encoded_data_array ) && ! empty( $encoded_data_array ) ) {
195 return;
196 }
197
198 $defaults = array(
199 'txn_type' => '',
200 'payment_status' => '',
201 );
202
203 $encoded_data_array = wp_parse_args( $encoded_data_array, $defaults );
204
205 $payment_id = isset( $encoded_data_array['custom'] ) ? absint( $encoded_data_array['custom'] ) : 0;
206 $txn_type = $encoded_data_array['txn_type'];
207
208 // Check for PayPal IPN Notifications and update data based on it.
209 $current_timestamp = current_time( 'timestamp' );
210 $paypal_ipn_vars = array(
211 'auth_status' => isset( $api_response['body'] ) ? $api_response['body'] : 'N/A',
212 'transaction_id' => isset( $encoded_data_array['txn_id'] ) ? $encoded_data_array['txn_id'] : 'N/A',
213 'payment_id' => $payment_id,
214 );
215 update_option( 'give_last_paypal_ipn_received', $paypal_ipn_vars, false );
216 give_insert_payment_note( $payment_id, sprintf(
217 __( 'IPN received on %s at %s', 'give' ),
218 date_i18n( 'm/d/Y', $current_timestamp ),
219 date_i18n( 'H:i', $current_timestamp )
220 )
221 );
222 give_update_meta( $payment_id, 'give_last_paypal_ipn_received', $current_timestamp );
223
224 if ( has_action( 'give_paypal_' . $txn_type ) ) {
225 /**
226 * Fires while processing PayPal IPN $txn_type.
227 *
228 * Allow PayPal IPN types to be processed separately.
229 *
230 * @since 1.0
231 *
232 * @param array $encoded_data_array Encoded data.
233 * @param int $payment_id Payment id.
234 */
235 do_action( "give_paypal_{$txn_type}", $encoded_data_array, $payment_id );
236 } else {
237 /**
238 * Fires while process PayPal IPN.
239 *
240 * Fallback to web accept just in case the txn_type isn't present.
241 *
242 * @since 1.0
243 *
244 * @param array $encoded_data_array Encoded data.
245 * @param int $payment_id Payment id.
246 */
247 do_action( 'give_paypal_web_accept', $encoded_data_array, $payment_id );
248 }
249 exit;
250 }
251
252 add_action( 'give_verify_paypal_ipn', 'give_process_paypal_ipn' );
253
254 /**
255 * Process web accept (one time) payment IPNs.
256 *
257 * @since 1.0
258 *
259 * @param array $data The IPN Data.
260 * @param int $payment_id The payment ID from Give.
261 *
262 * @return void
263 */
264 function give_process_paypal_web_accept( $data, $payment_id ) {
265
266 // Only allow through these transaction types.
267 if ( 'web_accept' !== $data['txn_type'] && 'cart' !== $data['txn_type'] && 'refunded' !== strtolower( $data['payment_status'] ) ) {
268 return;
269 }
270
271 // Need $payment_id to continue.
272 if ( empty( $payment_id ) ) {
273 return;
274 }
275
276 // Collect donation payment details.
277 $paypal_amount = $data['mc_gross'];
278 $payment_status = strtolower( $data['payment_status'] );
279 $currency_code = strtolower( $data['mc_currency'] );
280 $business_email = isset( $data['business'] ) && is_email( $data['business'] ) ? trim( $data['business'] ) : trim( $data['receiver_email'] );
281 $payment_meta = give_get_payment_meta( $payment_id );
282
283 // Must be a PayPal standard IPN.
284 if ( 'paypal' !== give_get_payment_gateway( $payment_id ) ) {
285 return;
286 }
287
288 // Verify payment recipient.
289 if ( strcasecmp( $business_email, trim( give_get_option( 'paypal_email' ) ) ) !== 0 ) {
290
291 give_record_gateway_error( __( 'IPN Error', 'give' ), sprintf( /* translators: %s: Paypal IPN response */
292 __( 'Invalid business email in IPN response. IPN data: %s', 'give' ), json_encode( $data ) ), $payment_id );
293 give_update_payment_status( $payment_id, 'failed' );
294 give_insert_payment_note( $payment_id, __( 'Payment failed due to invalid PayPal business email.', 'give' ) );
295
296 return;
297 }
298
299 // Verify payment currency.
300 if ( $currency_code !== strtolower( $payment_meta['currency'] ) ) {
301
302 give_record_gateway_error( __( 'IPN Error', 'give' ), sprintf( /* translators: %s: Paypal IPN response */
303 __( 'Invalid currency in IPN response. IPN data: %s', 'give' ), json_encode( $data ) ), $payment_id );
304 give_update_payment_status( $payment_id, 'failed' );
305 give_insert_payment_note( $payment_id, __( 'Payment failed due to invalid currency in PayPal IPN.', 'give' ) );
306
307 return;
308 }
309
310 // Process refunds & reversed.
311 if ( 'refunded' === $payment_status || 'reversed' === $payment_status ) {
312 give_process_paypal_refund( $data, $payment_id );
313
314 return;
315 }
316
317 // Only complete payments once.
318 if ( 'publish' === get_post_status( $payment_id ) ) {
319 return;
320 }
321
322 // Retrieve the total donation amount (before PayPal).
323 $payment_amount = give_donation_amount( $payment_id );
324
325 // Check that the donation PP and local db amounts match.
326 if ( number_format( (float) $paypal_amount, 2 ) < number_format( (float) $payment_amount, 2 ) ) {
327 // The prices don't match
328 give_record_gateway_error( __( 'IPN Error', 'give' ), sprintf( /* translators: %s: Paypal IPN response */
329 __( 'Invalid payment amount in IPN response. IPN data: %s', 'give' ), json_encode( $data ) ), $payment_id );
330 give_update_payment_status( $payment_id, 'failed' );
331 give_insert_payment_note( $payment_id, __( 'Payment failed due to invalid amount in PayPal IPN.', 'give' ) );
332
333 return;
334 }
335
336 // Process completed donations.
337 if ( 'completed' === $payment_status || give_is_test_mode() ) {
338
339 give_insert_payment_note( $payment_id, sprintf( /* translators: %s: Paypal transaction ID */
340 __( 'PayPal Transaction ID: %s', 'give' ), $data['txn_id'] ) );
341 give_set_payment_transaction_id( $payment_id, $data['txn_id'] );
342 give_update_payment_status( $payment_id, 'publish' );
343
344 } elseif ( 'pending' === $payment_status && isset( $data['pending_reason'] ) ) {
345
346 // Look for possible pending reasons, such as an echeck.
347 $note = give_paypal_get_pending_donation_note( strtolower( $data['pending_reason'] ) );
348
349 if ( ! empty( $note ) ) {
350 give_insert_payment_note( $payment_id, $note );
351 }
352 }
353
354 }
355
356 add_action( 'give_paypal_web_accept', 'give_process_paypal_web_accept', 10, 2 );
357
358 /**
359 * Process PayPal IPN Refunds
360 *
361 * @since 1.0
362 *
363 * @param array $data IPN Data
364 * @param int $payment_id The payment ID.
365 *
366 * @return void
367 */
368 function give_process_paypal_refund( $data, $payment_id = 0 ) {
369
370 // Collect payment details.
371 if ( empty( $payment_id ) ) {
372 return;
373 }
374
375 // Only refund payments once.
376 if ( 'refunded' === get_post_status( $payment_id ) ) {
377 return;
378 }
379
380 $payment_amount = give_donation_amount( $payment_id );
381 $refund_amount = $data['payment_gross'] * - 1;
382
383 if ( number_format( (float) $refund_amount, 2 ) < number_format( (float) $payment_amount, 2 ) ) {
384
385 give_insert_payment_note( $payment_id, sprintf( /* translators: %s: Paypal parent transaction ID */
386 __( 'Partial PayPal refund processed: %s', 'give' ), $data['parent_txn_id'] ) );
387
388 return; // This is a partial refund
389
390 }
391
392 give_insert_payment_note( $payment_id, sprintf( /* translators: 1: Paypal parent transaction ID 2. Paypal reason code */
393 __( 'PayPal Payment #%1$s Refunded for reason: %2$s', 'give' ), $data['parent_txn_id'], $data['reason_code'] ) );
394 give_insert_payment_note( $payment_id, sprintf( /* translators: %s: Paypal transaction ID */
395 __( 'PayPal Refund Transaction ID: %s', 'give' ), $data['txn_id'] ) );
396 give_update_payment_status( $payment_id, 'refunded' );
397 }
398
399 /**
400 * Get PayPal Redirect
401 *
402 * @since 1.0
403 *
404 * @param bool $ssl_check Is SSL?
405 *
406 * @return string
407 */
408 function give_get_paypal_redirect( $ssl_check = false ) {
409
410 if ( is_ssl() || ! $ssl_check ) {
411 $protocol = 'https://';
412 } else {
413 $protocol = 'http://';
414 }
415
416 // Check the current payment mode
417 if ( give_is_test_mode() ) {
418 // Test mode
419 $paypal_uri = $protocol . 'www.sandbox.paypal.com/cgi-bin/webscr';
420 } else {
421 // Live mode
422 $paypal_uri = $protocol . 'www.paypal.com/cgi-bin/webscr';
423 }
424
425 return apply_filters( 'give_paypal_uri', $paypal_uri );
426 }
427
428 /**
429 * Set the Page Style for offsite PayPal page.
430 *
431 * @since 1.0
432 * @return string
433 */
434 function give_get_paypal_page_style() {
435 $page_style = trim( give_get_option( 'paypal_page_style', 'PayPal' ) );
436
437 return apply_filters( 'give_paypal_page_style', $page_style );
438 }
439
440 /**
441 * PayPal Success Page
442 *
443 * Shows "Donation Processing" message for PayPal payments that are still pending on site return
444 *
445 * @since 1.0
446 *
447 * @param $content
448 *
449 * @return string
450 */
451 function give_paypal_success_page_content( $content ) {
452
453 if ( ! isset( $_GET['payment-id'] ) && ! give_get_purchase_session() ) {
454 return $content;
455 }
456
457 $payment_id = isset( $_GET['payment-id'] ) ? absint( $_GET['payment-id'] ) : false;
458
459 if ( ! $payment_id ) {
460 $session = give_get_purchase_session();
461 $payment_id = give_get_donation_id_by_key( $session['purchase_key'] );
462 }
463
464 $payment = get_post( $payment_id );
465 if ( $payment && 'pending' === $payment->post_status ) {
466
467 // Payment is still pending so show processing indicator to fix the race condition.
468 ob_start();
469
470 give_get_template_part( 'payment', 'processing' );
471
472 $content = ob_get_clean();
473
474 }
475
476 return $content;
477
478 }
479
480 add_filter( 'give_payment_confirm_paypal', 'give_paypal_success_page_content' );
481
482 /**
483 * Given a transaction ID, generate a link to the PayPal transaction ID details
484 *
485 * @since 1.0
486 *
487 * @param string $transaction_id The Transaction ID
488 * @param int $payment_id The payment ID for this transaction
489 *
490 * @return string A link to the PayPal transaction details
491 */
492 function give_paypal_link_transaction_id( $transaction_id, $payment_id ) {
493
494 $paypal_base_url = 'https://history.paypal.com/cgi-bin/webscr?cmd=_history-details-from-hub&id=';
495 $transaction_url = '<a href="' . esc_url( $paypal_base_url . $transaction_id ) . '" target="_blank">' . $transaction_id . '</a>';
496
497 return apply_filters( 'give_paypal_link_payment_details_transaction_id', $transaction_url );
498
499 }
500
501 add_filter( 'give_payment_details_transaction_id-paypal', 'give_paypal_link_transaction_id', 10, 2 );
502
503
504 /**
505 * Get pending donation note.
506 *
507 * @since 1.6.3
508 *
509 * @param $pending_reason
510 *
511 * @return string
512 */
513 function give_paypal_get_pending_donation_note( $pending_reason ) {
514
515 $note = '';
516
517 switch ( $pending_reason ) {
518
519 case 'echeck' :
520
521 $note = __( 'Payment made via eCheck and will clear automatically in 5-8 days.', 'give' );
522
523 break;
524
525 case 'address' :
526
527 $note = __( 'Payment requires a confirmed donor address and must be accepted manually through PayPal.', 'give' );
528
529 break;
530
531 case 'intl' :
532
533 $note = __( 'Payment must be accepted manually through PayPal due to international account regulations.', 'give' );
534
535 break;
536
537 case 'multi-currency' :
538
539 $note = __( 'Payment received in non-shop currency and must be accepted manually through PayPal.', 'give' );
540
541 break;
542
543 case 'paymentreview' :
544 case 'regulatory_review' :
545
546 $note = __( 'Payment is being reviewed by PayPal staff as high-risk or in possible violation of government regulations.', 'give' );
547
548 break;
549
550 case 'unilateral' :
551
552 $note = __( 'Payment was sent to non-confirmed or non-registered email address.', 'give' );
553
554 break;
555
556 case 'upgrade' :
557
558 $note = __( 'PayPal account must be upgraded before this payment can be accepted.', 'give' );
559
560 break;
561
562 case 'verify' :
563
564 $note = __( 'PayPal account is not verified. Verify account in order to accept this donation.', 'give' );
565
566 break;
567
568 case 'other' :
569
570 $note = __( 'Payment is pending for unknown reasons. Contact PayPal support for assistance.', 'give' );
571
572 break;
573
574 }// End switch().
575
576 return $note;
577
578 }
579
580 /**
581 * Build paypal url
582 *
583 * @param int $payment_id Payment ID
584 * @param array $payment_data Array of payment data.
585 *
586 * @return mixed|string
587 */
588 function give_build_paypal_url( $payment_id, $payment_data ) {
589 // Only send to PayPal if the pending payment is created successfully.
590 $listener_url = add_query_arg( 'give-listener', 'IPN', home_url( 'index.php' ) );
591
592 // Get the success url.
593 $return_url = add_query_arg( array(
594 'payment-confirmation' => 'paypal',
595 'payment-id' => $payment_id,
596
597 ), get_permalink( give_get_option( 'success_page' ) ) );
598
599 // Get the PayPal redirect uri.
600 $paypal_redirect = trailingslashit( give_get_paypal_redirect() ) . '?';
601
602 // Item name.
603 $item_name = give_payment_gateway_item_title( $payment_data );
604
605 // Setup PayPal API params.
606 $paypal_args = array(
607 'business' => give_get_option( 'paypal_email', false ),
608 'first_name' => $payment_data['user_info']['first_name'],
609 'last_name' => $payment_data['user_info']['last_name'],
610 'email' => $payment_data['user_email'],
611 'invoice' => $payment_data['purchase_key'],
612 'amount' => $payment_data['price'],
613 'item_name' => stripslashes( $item_name ),
614 'no_shipping' => '1',
615 'shipping' => '0',
616 'no_note' => '1',
617 'currency_code' => give_get_currency( $payment_id, $payment_data ),
618 'charset' => get_bloginfo( 'charset' ),
619 'custom' => $payment_id,
620 'rm' => '2',
621 'return' => $return_url,
622 'cancel_return' => give_get_failed_transaction_uri( '?payment-id=' . $payment_id ),
623 'notify_url' => $listener_url,
624 'page_style' => give_get_paypal_page_style(),
625 'cbt' => get_bloginfo( 'name' ),
626 'bn' => 'givewp_SP',
627 );
628
629 // Add user address if present.
630 if ( ! empty( $payment_data['user_info']['address'] ) ) {
631 $default_address = array(
632 'line1' => '',
633 'line2' => '',
634 'city' => '',
635 'state' => '',
636 'zip' => '',
637 'country' => '',
638 );
639
640 $address = wp_parse_args( $payment_data['user_info']['address'], $default_address );
641
642 $paypal_args['address1'] = $address['line1'];
643 $paypal_args['address2'] = $address['line2'];
644 $paypal_args['city'] = $address['city'];
645 $paypal_args['state'] = $address['state'];
646 $paypal_args['zip'] = $address['zip'];
647 $paypal_args['country'] = $address['country'];
648 }
649
650 // Donations or regular transactions?
651 $paypal_args['cmd'] = give_get_paypal_button_type();
652
653 /**
654 * Filter the paypal redirect args.
655 *
656 * @param array $paypal_args PayPal Arguments.
657 * @param array $payment_data Payment Data.
658 *
659 * @since 1.8
660 */
661 $paypal_args = apply_filters( 'give_paypal_redirect_args', $paypal_args, $payment_data );
662
663 // Build query.
664 $paypal_redirect .= http_build_query( $paypal_args );
665
666 // Fix for some sites that encode the entities.
667 $paypal_redirect = str_replace( '&amp;', '&', $paypal_redirect );
668
669 return $paypal_redirect;
670 }
671
672
673 /**
674 * Get paypal button type.
675 *
676 * @since 1.8
677 * @return string
678 */
679 function give_get_paypal_button_type() {
680 // paypal_button_type can be donation or standard.
681 $paypal_button_type = '_donations';
682 if ( 'standard' === give_get_option( 'paypal_button_type' ) ) {
683 $paypal_button_type = '_xclick';
684 }
685
686 return $paypal_button_type;
687 }
688
689 /**
690 * Update Purchase key for specific gateway.
691 *
692 * @since 2.2.4
693 *
694 * @param string $custom_purchase_key
695 * @param string $gateway
696 * @param string $purchase_key
697 *
698 * @return string
699 */
700 function give_paypal_purchase_key( $custom_purchase_key, $gateway, $purchase_key ) {
701
702 if ( 'paypal' === $gateway ) {
703 $invoice_id_prefix = give_get_option( 'paypal_invoice_prefix', 'GIVE-' );
704 $custom_purchase_key = $invoice_id_prefix . $purchase_key;
705 }
706
707 return $custom_purchase_key;
708 }
709
710 add_filter( 'give_donation_purchase_key', 'give_paypal_purchase_key', 10, 3 );
711