PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.8
GiveWP – Donation Plugin and Fundraising Platform v4.16.8
4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 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 / payments / class-give-payment.php
give / includes / payments Last commit date
actions.php 1 year ago backward-compatibility.php 11 months ago class-give-payment.php 1 week ago class-give-sequential-donation-number.php 11 months ago class-payment-stats.php 11 months ago class-payments-query.php 11 months ago functions.php 1 month ago
class-give-payment.php
2125 lines
1 <?php
2 /**
3 * Payments
4 *
5 * @package Give
6 * @subpackage Classes/Give_Payment
7 * @copyright Copyright (c) 2016, GiveWP
8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 * @since 1.5
10 */
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Give_Payment Class
19 *
20 * This class is for working with payments in Give.
21 *
22 * @property int $ID
23 * @property bool $new
24 * @property string $number
25 * @property string $mode
26 * @property string $import
27 * @property string $key
28 * @property string $form_title
29 * @property string|int $form_id
30 * @property string|int $campaign_id
31 * @property string|int $price_id
32 * @property string|int $total
33 * @property string|int $subtotal
34 * @property string|int $fees
35 * @property string|int $fees_total
36 * @property string $post_status
37 * @property string $date
38 * @property string $post_date
39 * @property string $status
40 * @property string $email
41 * @property array $payment_meta
42 * @property string $customer_id
43 * @property string $donor_id
44 * @property string $completed_date
45 * @property string $currency
46 * @property string $ip
47 * @property array $user_info
48 * @property string $gateway
49 * @property string $user_id
50 * @property string $title_prefix
51 * @property string $first_name
52 * @property string $last_name
53 * @property string $parent_payment
54 * @property string $transaction_id
55 * @property string $old_status
56 *
57 * @since 1.5
58 */
59 final class Give_Payment {
60
61 /**
62 * The Payment ID.
63 *
64 * @since 1.5
65 *
66 * @var int
67 */
68 public $ID = 0;
69
70 /**
71 * Protected non-read $_ID.
72 *
73 * @var int
74 */
75 protected $_ID = 0;
76
77 /**
78 * Identify if the payment is a new one or existing.
79 *
80 * @since 1.5
81 * @access protected
82 *
83 * @var boolean
84 */
85 protected $new = false;
86
87 /**
88 * The Payment number (for use with sequential payments).
89 *
90 * @since 1.5
91 * @access protected
92 *
93 * @var string
94 */
95 protected $number = '';
96
97 /**
98 * The Gateway mode the payment was made in.
99 *
100 * @since 1.5
101 * @access protected
102 *
103 * @var string
104 */
105 protected $mode = 'live';
106
107 /**
108 * Is donations is Import or not.
109 *
110 * @since 1.8.13
111 * @access protected
112 *
113 * @var bool
114 */
115 protected $import = false;
116
117 /**
118 * The unique donation payment key.
119 *
120 * @since 1.5
121 * @access protected
122 *
123 * @var string
124 */
125 protected $key = '';
126
127 /**
128 * The Donation Form Title
129 *
130 * @since 1.5
131 * @access protected
132 *
133 * @var string
134 */
135 protected $form_title = 0;
136
137 /**
138 * The Donation Form ID
139 *
140 * @since 1.5
141 * @access protected
142 *
143 * @var string
144 */
145 protected $form_id = 0;
146
147 /**
148 * The Donation Campaign ID
149 *
150 * @since 4.3.2
151 * @access protected
152 *
153 * @var string|int
154 */
155 protected $campaign_id = 0;
156
157 /**
158 * The Donation Form Price ID
159 *
160 * @since 1.5
161 * @access protected
162 *
163 * @var string|int
164 */
165 protected $price_id = 0;
166
167 /**
168 * The total amount of the donation payment.
169 *
170 * @since 1.5
171 * @access protected
172 *
173 * @var float
174 */
175 protected $total = 0.00;
176
177 /**
178 * The Subtotal fo the payment.
179 *
180 * @since 1.5
181 * @access protected
182 *
183 * @var float
184 */
185 protected $subtotal = 0;
186
187 /**
188 * The date the payment was created
189 *
190 * @since 1.5
191 * @access protected
192 *
193 * @var string
194 */
195 protected $date = '';
196
197 /**
198 * The date the payment post was created.
199 *
200 * @var string
201 */
202 protected $post_date = '';
203
204 /**
205 * The date the payment was marked as 'complete'.
206 *
207 * @since 1.5
208 * @access protected
209 *
210 * @var string
211 */
212 protected $completed_date = '';
213
214 /**
215 * The status of the donation payment.
216 *
217 * @since 1.5
218 * @access protected
219 *
220 * @var string
221 */
222 protected $status = 'pending';
223
224 /**
225 * Donation Status.
226 *
227 * @var string
228 */
229 protected $post_status = 'pending'; // Same as $status but here for backwards compat.
230
231 /**
232 * When updating, the old status prior to the change
233 *
234 * @since 1.5
235 * @access protected
236 *
237 * @var string
238 */
239 protected $old_status = '';
240
241 /**
242 * The display name of the current payment status.
243 *
244 * @since 1.5
245 * @access protected
246 *
247 * @var string
248 */
249 protected $status_nicename = '';
250
251 /**
252 * The donor ID that made the payment.
253 *
254 * @since 1.5
255 * @access protected
256 *
257 * @var integer
258 */
259 protected $customer_id = null;
260
261 /**
262 * The Donor ID (if logged in) that made the payment
263 *
264 * @since 1.8.13
265 * @access protected
266 *
267 * @var integer
268 */
269 protected $donor_id = 0;
270
271 /**
272 * The User ID (if logged in) that made the payment
273 *
274 * @since 1.5
275 * @access protected
276 *
277 * @var integer
278 */
279 protected $user_id = 0;
280
281 /**
282 * The Title Prefix/Salutation of the Donor.
283 *
284 * @since 2.2
285 *
286 * @var string
287 */
288 protected $title_prefix = '';
289
290 /**
291 * The first name of the payee
292 *
293 * @since 1.5
294 * @access protected
295 *
296 * @var string
297 */
298 protected $first_name = '';
299
300 /**
301 * The last name of the payee
302 *
303 * @since 1.5
304 * @access protected
305 *
306 * @var string
307 */
308 protected $last_name = '';
309
310 /**
311 * The email used for the payment
312 *
313 * @since 1.5
314 * @access protected
315 *
316 * @var string
317 */
318 protected $email = '';
319
320 /**
321 * Legacy (not to be accessed) array of user information
322 *
323 * @since 1.5
324 * @access private
325 *
326 * @var array
327 */
328 private $user_info = [];
329
330 /**
331 * Legacy (not to be accessed) payment meta array
332 *
333 * @since 1.5
334 * @access private
335 *
336 * @var array
337 */
338 private $payment_meta = [];
339
340 /**
341 * The physical address used for the payment if provided
342 *
343 * @since 1.5
344 * @access protected
345 *
346 * @var array
347 */
348 protected $address = [];
349
350 /**
351 * The transaction ID returned by the gateway
352 *
353 * @since 1.5
354 * @access protected
355 *
356 * @var string
357 */
358 protected $transaction_id = '';
359
360 /**
361 * IP Address payment was made from
362 *
363 * @since 1.5
364 * @access protected
365 *
366 * @var string
367 */
368 protected $ip = '';
369
370 /**
371 * The gateway used to process the payment
372 *
373 * @since 1.5
374 * @access protected
375 *
376 * @var string
377 */
378 protected $gateway = '';
379
380 /**
381 * The the payment was made with
382 *
383 * @since 1.5
384 * @access protected
385 *
386 * @var string
387 */
388 protected $currency = '';
389
390 /**
391 * Array of items that have changed since the last save() was run.
392 * This is for internal use, to allow fewer update_payment_meta calls to be run.
393 *
394 * @since 1.5
395 * @access private
396 *
397 * @var array
398 */
399 private $pending;
400
401 /**
402 * The parent payment (if applicable)
403 *
404 * @since 1.5
405 * @access protected
406 *
407 * @var integer
408 */
409 protected $parent_payment = 0;
410
411 /**
412 * Setup the Give Payments class
413 *
414 * @since 1.5
415 * @access public
416 *
417 * @param int|bool $payment_id A given payment.
418 *
419 * @return mixed void|false
420 */
421 public function __construct( $payment_id = false ) {
422
423 if ( empty( $payment_id ) ) {
424 return false;
425 }
426
427 $this->setup_payment( $payment_id );
428 }
429
430 /**
431 * Magic GET function.
432 *
433 * @since 1.5
434 * @access public
435 *
436 * @param string $key The property.
437 *
438 * @return mixed The value.
439 */
440 public function __get( $key ) {
441
442 if ( method_exists( $this, 'get_' . $key ) ) {
443
444 $value = call_user_func( [ $this, 'get_' . $key ] );
445
446 } else {
447
448 $value = $this->$key;
449
450 }
451
452 return $value;
453 }
454
455 /**
456 * Magic SET function
457 *
458 * Sets up the pending array for the save method
459 *
460 * @since 1.5
461 * @access public
462 *
463 * @param string $key The property name.
464 * @param mixed $value The value of the property.
465 */
466 public function __set( $key, $value ) {
467 $ignore = [ '_ID' ];
468
469 if ( 'status' === $key ) {
470 $this->old_status = $this->status;
471 }
472
473 if ( ! in_array( $key, $ignore ) ) {
474 $this->pending[ $key ] = $value;
475 }
476
477 if ( '_ID' !== $key ) {
478 $this->$key = $value;
479 }
480 }
481
482 /**
483 * Magic ISSET function, which allows empty checks on protected elements
484 *
485 * @since 1.5
486 * @access public
487 *
488 * @param string $name The attribute to get.
489 *
490 * @return boolean|null If the item is set or not
491 */
492 public function __isset( $name ) {
493 if ( property_exists( $this, $name ) ) {
494 return false === empty( $this->$name );
495 } else {
496 return null;
497 }
498 }
499
500 /**
501 * Setup payment properties
502 *
503 * @since 1.5
504 * @access private
505 *
506 * @param int $payment_id The payment ID.
507 *
508 * @return bool If the setup was successful or not
509 */
510 private function setup_payment( $payment_id ) {
511 $this->pending = [];
512
513 if ( empty( $payment_id ) ) {
514 return false;
515 }
516
517 $payment = get_post( absint( $payment_id ) );
518
519 if ( ! $payment || is_wp_error( $payment ) ) {
520 return false;
521 }
522
523 if ( 'give_payment' !== $payment->post_type ) {
524 return false;
525 }
526
527 Give_Payments_Query::update_meta_cache( [ $payment_id ] );
528
529 /**
530 * Fires before payment setup.
531 *
532 * Allow extensions to perform actions before the payment is loaded.
533 *
534 * @since 1.5
535 *
536 * @param Give_Payment $this Payment object.
537 * @param int $payment_id The ID of the payment.
538 */
539 do_action( 'give_pre_setup_payment', $this, $payment_id );
540
541 // Get payment from cache.
542 $donation_vars = Give_Cache::get_group( $payment_id, 'give-donations' );
543
544 if ( is_null( $donation_vars ) ) {
545 // Primary Identifier.
546 $this->ID = absint( $payment_id );
547
548 // Protected ID that can never be changed.
549 $this->_ID = absint( $payment_id );
550
551 // We have a payment, get the generic payment_meta item to reduce calls to it.
552 $this->payment_meta = $this->get_meta();
553
554 // Status and Dates.
555 $this->date = $payment->post_date;
556 $this->post_date = $payment->post_date;
557 $this->completed_date = $this->setup_completed_date();
558 $this->status = $payment->post_status;
559 $this->post_status = $this->status;
560 $this->mode = $this->setup_mode();
561 $this->import = $this->setup_import();
562 $this->parent_payment = $payment->post_parent;
563
564 $all_payment_statuses = give_get_payment_statuses();
565 $this->status_nicename = array_key_exists( $this->status, $all_payment_statuses ) ? $all_payment_statuses[ $this->status ] : ucfirst( $this->status );
566
567 // Currency Based.
568 $this->total = $this->setup_total();
569 $this->subtotal = $this->setup_subtotal();
570 $this->currency = $this->setup_currency();
571
572 // Gateway based.
573 $this->gateway = $this->setup_gateway();
574 $this->transaction_id = $this->setup_transaction_id();
575
576 // User based.
577 $this->ip = $this->setup_ip();
578 $this->customer_id = $this->setup_donor_id(); // Backward compatibility.
579 $this->donor_id = $this->setup_donor_id();
580 $this->user_id = $this->setup_user_id();
581 $this->email = $this->setup_email();
582 $this->user_info = $this->setup_user_info();
583 $this->address = $this->setup_address();
584 $this->first_name = $this->user_info['first_name'];
585 $this->last_name = $this->user_info['last_name'];
586 $this->title_prefix = isset( $this->user_info['title'] ) ? $this->user_info['title'] : '';
587
588 // Other Identifiers.
589 $this->form_title = $this->setup_form_title();
590 $this->form_id = $this->setup_form_id();
591 $this->campaign_id = $this->setup_campaign_id();
592 $this->price_id = $this->setup_price_id();
593 $this->key = $this->setup_payment_key();
594 $this->number = $this->setup_payment_number();
595
596 Give_Cache::set_group( $this->ID, get_object_vars( $this ), 'give-donations' );
597 } else {
598
599 foreach ( $donation_vars as $donation_var => $value ) {
600 $this->$donation_var = $value;
601 }
602 } // End if().
603
604 /**
605 * Fires after payment setup.
606 *
607 * Allow extensions to add items to this object via hook.
608 *
609 * @since 1.5
610 *
611 * @param Give_Payment $this Payment object.
612 * @param int $payment_id The ID of the payment.
613 */
614 do_action( 'give_setup_payment', $this, $payment_id );
615
616 return true;
617 }
618
619
620 /**
621 * Payment class object is storing various meta value in object parameter.
622 * So if user is updating payment meta but not updating payment object, then payment meta values will not reflect/changes on payment meta automatically
623 * and you can still access payment meta old value in any old payment object ( previously created ) which can cause to show or save wrong payment data.
624 * To prevent that user can use this function after updating any payment meta value ( in bulk or single update ).
625 *
626 * @since 1.6
627 * @access public
628 *
629 * @param int $payment_id Payment ID.
630 *
631 * @return void
632 */
633 public function update_payment_setup( $payment_id ) {
634 // Delete cache.
635 Give_Cache::delete_group( $this->ID, 'give-donations' );
636
637 $this->setup_payment( $payment_id );
638 }
639
640 /**
641 * Create the base of a payment.
642 *
643 * @since 4.16.7.2 Sanitize first, last, and title name values before storing donor meta.
644 * @since 1.5
645 * @access private
646 *
647 * @return int|bool False on failure, the payment ID on success.
648 */
649 private function insert_payment() {
650
651 // Construct the payment title.
652 $payment_title = '';
653 if ( ! empty( $this->first_name ) && ! empty( $this->last_name ) ) {
654 $payment_title = $this->first_name . ' ' . $this->last_name;
655 } elseif ( ! empty( $this->first_name ) && empty( $this->last_name ) ) {
656 $payment_title = $this->first_name;
657 } elseif ( ! empty( $this->email ) && is_email( $this->email ) ) {
658 $payment_title = $this->email;
659 }
660
661 // Set Key.
662 if ( empty( $this->key ) ) {
663
664 $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
665 $this->key = strtolower( md5( $this->email . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'give', true ) ) ); // Unique key.
666 $this->pending['key'] = $this->key;
667 }
668
669 // Set IP.
670 if ( empty( $this->ip ) ) {
671
672 $this->ip = give_get_ip();
673 $this->pending['ip'] = $this->ip;
674
675 }
676
677 // @todo: payment data exist here only for backward compatibility
678 // issue: https://github.com/impress-org/give/issues/1132
679 $payment_data = [
680 'price' => $this->total,
681 'date' => $this->date,
682 'user_email' => $this->email,
683 'purchase_key' => $this->key,
684 'form_title' => $this->form_title,
685 'form_id' => $this->form_id,
686 'donor_id' => $this->donor_id,
687 'price_id' => $this->price_id,
688 'currency' => $this->currency,
689 'user_info' => [
690 'id' => $this->user_id,
691 'title' => $this->title_prefix,
692 'email' => $this->email,
693 'first_name' => $this->first_name,
694 'last_name' => $this->last_name,
695 'address' => $this->address,
696 ],
697 'status' => $this->status,
698 ];
699
700 $args = apply_filters(
701 'give_insert_payment_args',
702 [
703 'post_title' => $payment_title,
704 'post_status' => $this->status,
705 'post_type' => 'give_payment',
706 'post_date' => ! empty( $this->date ) ? $this->date : null,
707 'post_date_gmt' => ! empty( $this->date ) ? get_gmt_from_date( $this->date ) : null,
708 'post_parent' => $this->parent_payment,
709 ],
710 $payment_data
711 );
712
713 // Create a blank payment.
714 $payment_id = wp_insert_post( $args );
715
716 if ( ! empty( $payment_id ) ) {
717
718 $this->ID = $payment_id;
719 $this->_ID = $payment_id;
720
721 $donor = new stdClass();
722
723 if ( did_action( 'give_pre_process_donation' ) && is_user_logged_in() ) {
724 $donor = new Give_Donor( get_current_user_id(), true );
725
726 // Donor is logged in but used a different email to purchase with so assign to their donor record.
727 if ( ! empty( $donor->id ) && $this->email !== $donor->email ) {
728 $donor->add_email( $this->email );
729 }
730 }
731
732 if ( empty( $donor->id ) ) {
733 $donor = new Give_Donor( $this->email );
734 }
735
736 if ( empty( $donor->id ) ) {
737
738 $donor_data = [
739 'name' => ! is_email( $payment_title ) ? $this->first_name . ' ' . $this->last_name : '',
740 'email' => $this->email,
741 'user_id' => $this->user_id,
742 ];
743
744 $donor->create( $donor_data );
745
746 }
747
748 /**
749 * Filters the donor object after donation is completed but before donor table is updated.
750 *
751 * @since 1.8.13
752 * @since 2.4.2 Moved location of filter to occur after donor is hydrated.
753 *
754 * @param Give_Donor $donor Donor object.
755 * @param int $payment_id Payment ID.
756 * @param array $payment_data Payment data array.
757 * @param array $args Payment args.
758 */
759 $donor = apply_filters( 'give_update_donor_information', $donor, $payment_id, $payment_data, $args );
760
761 // Update Donor Meta once donor is created.
762 $donor->update_meta( '_give_donor_first_name', sanitize_text_field( $this->first_name ) );
763 $donor->update_meta( '_give_donor_last_name', sanitize_text_field( $this->last_name ) );
764 $donor->update_meta( '_give_donor_title_prefix', sanitize_text_field( $this->title_prefix ) );
765
766 $this->customer_id = $donor->id;
767 $this->pending['customer_id'] = $this->customer_id;
768 $donor->attach_payment( $this->ID, false );
769
770 $this->payment_meta = apply_filters( 'give_payment_meta', $this->payment_meta, $payment_data );
771
772 /**
773 * _give_payment_meta backward compatibility.
774 *
775 * @since 2.0.1
776 */
777 $custom_payment_meta = array_diff(
778 array_map( 'maybe_serialize', $this->payment_meta ),
779 array_map( 'maybe_serialize', $payment_data )
780 );
781
782 if ( ! empty( $custom_payment_meta ) ) {
783 give_doing_it_wrong( '_give_payment_meta', __( 'This custom meta key has been deprecated for performance reasons. Your custom meta data will still be stored but we recommend updating your code to store meta keys individually from GiveWP 2.0.0.', 'give' ) );
784
785 $this->update_meta( '_give_payment_meta', array_map( 'maybe_unserialize', $custom_payment_meta ) );
786 }
787
788 $give_company = ( ! empty( $_REQUEST['give_company_name'] ) ? give_clean( $_REQUEST['give_company_name'] ) : '' );
789
790 // Check $page_url is not empty.
791 if ( $give_company ) {
792 give_update_meta( $payment_id, '_give_donation_company', $give_company );
793
794 $donor_id = absint( $donor->id );
795 if ( ! empty( $donor_id ) ) {
796 Give()->donor_meta->update_meta( $donor_id, '_give_donor_company', $give_company );
797 }
798 }
799
800 $this->new = true;
801 } // End if().
802
803 return $this->ID;
804
805 }
806
807 /**
808 * Save
809 *
810 * Once items have been set, an update is needed to save them to the database.
811 *
812 * @since 4.16.7.2 Sanitize first and last name values when saving billing meta.
813 * @access public
814 *
815 * @return bool True of the save occurred, false if it failed or wasn't needed
816 */
817 public function save() {
818 $saved = false;
819
820 // Must have an ID.
821 if ( empty( $this->ID ) ) {
822
823 $payment_id = $this->insert_payment();
824
825 if ( false === $payment_id ) {
826 $saved = false;
827 } else {
828 $this->ID = $payment_id;
829 }
830 }
831
832 // Set ID if not matching.
833 if ( $this->ID !== $this->_ID ) {
834 $this->ID = $this->_ID;
835 }
836
837 // If we have something pending, let's save it.
838 if ( ! empty( $this->pending ) ) {
839
840 $total_increase = 0;
841 $total_decrease = 0;
842
843 foreach ( $this->pending as $key => $value ) {
844
845 switch ( $key ) {
846
847 case 'donations':
848 // Update totals for pending donations.
849 foreach ( $this->pending[ $key ] as $item ) {
850
851 $quantity = isset( $item['quantity'] ) ? $item['quantity'] : 1;
852 $price_id = isset( $item['price_id'] ) ? $item['price_id'] : 0;
853
854 switch ( $item['action'] ) {
855
856 case 'add':
857 $price = $item['price'];
858
859 if ( 'publish' === $this->status || 'complete' === $this->status ) {
860
861 // Add donation to logs.
862 $log_date = date_i18n( 'Y-m-d G:i:s', current_time( 'timestamp' ) );
863 give_record_donation_in_log( $item['id'], $this->ID, $price_id, $log_date );
864
865 $form = new Give_Donate_Form( $item['id'] );
866 $form->increase_sales( $quantity );
867 $form->increase_earnings( $price, $this->ID );
868
869 $total_increase += $price;
870 }
871 break;
872
873 case 'remove':
874 if ( 'publish' === $this->status || 'complete' === $this->status ) {
875 $form = new Give_Donate_Form( $item['id'] );
876 $form->decrease_sales( $quantity );
877 $form->decrease_earnings( $item['amount'], $this->ID );
878
879 $total_decrease += $item['amount'];
880 }
881 break;
882
883 }// End switch().
884 }// End foreach().
885 break;
886
887 case 'status':
888 $this->update_status( $this->status );
889 break;
890
891 case 'gateway':
892 $this->update_meta( '_give_payment_gateway', $this->gateway );
893 break;
894
895 case 'mode':
896 $this->update_meta( '_give_payment_mode', $this->mode );
897 break;
898
899 case 'transaction_id':
900 $this->update_meta( '_give_payment_transaction_id', $this->transaction_id );
901 break;
902
903 case 'ip':
904 $this->update_meta( '_give_payment_donor_ip', $this->ip );
905 break;
906
907 case 'customer_id':
908 $this->update_meta( '_give_payment_donor_id', $this->customer_id );
909 break;
910
911 case 'form_title':
912 $this->update_meta( '_give_payment_form_title', $this->form_title );
913 break;
914
915 case 'form_id':
916 $this->update_meta( '_give_payment_form_id', $this->form_id );
917 break;
918
919 case 'campaign_id':
920 $this->update_meta( '_give_campaign_id', $this->campaign_id );
921 break;
922
923 case 'price_id':
924 $this->update_meta( '_give_payment_price_id', $this->price_id );
925 break;
926
927 case 'first_name':
928 $this->update_meta( '_give_donor_billing_first_name', sanitize_text_field( $this->first_name ) );
929 break;
930
931 case 'last_name':
932 $this->update_meta( '_give_donor_billing_last_name', sanitize_text_field( $this->last_name ) );
933 break;
934
935 case 'currency':
936 $this->update_meta( '_give_payment_currency', $this->currency );
937 break;
938
939 case 'address':
940 if ( ! empty( $this->address ) ) {
941 foreach ( $this->address as $address_name => $address ) {
942 switch ( $address_name ) {
943 case 'line1':
944 $this->update_meta( '_give_donor_billing_address1', $address );
945 break;
946
947 case 'line2':
948 $this->update_meta( '_give_donor_billing_address2', $address );
949 break;
950
951 default:
952 $this->update_meta( "_give_donor_billing_{$address_name}", $address );
953 }
954 }
955 }
956 break;
957
958 case 'email':
959 $this->update_meta( '_give_payment_donor_email', $this->email );
960 break;
961
962 case 'title_prefix':
963 $this->update_meta( '_give_payment_donor_title_prefix', $this->title_prefix );
964 break;
965
966 case 'key':
967 $this->update_meta( '_give_payment_purchase_key', $this->key );
968 break;
969
970 case 'number':
971 // @todo: remove unused meta data.
972 // Core is using post_title to store donation serial code ( fi enabled ) instead this meta key.
973 // Do not use this meta key in your logic, can be remove in future
974 $this->update_meta( '_give_payment_number', $this->number );
975 break;
976
977 case 'date':
978 $args = [
979 'ID' => $this->ID,
980 'post_date' => date( 'Y-m-d H:i:s', strtotime( $this->date ) ),
981 'post_date_gmt' => get_gmt_from_date( $this->date ),
982 'edit_date' => true,
983 ];
984
985 wp_update_post( $args );
986 break;
987
988 case 'completed_date':
989 $this->update_meta( '_give_completed_date', $this->completed_date );
990 break;
991
992 case 'parent_payment':
993 $args = [
994 'ID' => $this->ID,
995 'post_parent' => $this->parent_payment,
996 ];
997
998 wp_update_post( $args );
999 break;
1000
1001 case 'total':
1002 $this->update_meta( '_give_payment_total', give_sanitize_amount_for_db( $this->total ) );
1003 break;
1004
1005 default:
1006 /**
1007 * Fires while saving payment.
1008 *
1009 * @since 1.7
1010 *
1011 * @param Give_Payment $this Payment object.
1012 */
1013 do_action( 'give_payment_save', $this, $key );
1014 break;
1015 } // End switch().
1016 } // End foreach().
1017
1018 if ( 'pending' !== $this->status ) {
1019
1020 $donor = new Give_Donor( $this->customer_id );
1021
1022 $total_change = $total_increase - $total_decrease;
1023 if ( $total_change < 0 ) {
1024
1025 $total_change = - ( $total_change );
1026
1027 // Decrease the donor's donation stats.
1028 $donor->decrease_value( $total_change );
1029 give_decrease_total_earnings( $total_change );
1030
1031 $donor->decrease_donation_count();
1032
1033 } elseif ( $total_change > 0 ) {
1034
1035 // Increase the donor's donation stats.
1036 $donor->increase_value( $total_change );
1037 give_increase_total_earnings( $total_change );
1038
1039 $donor->increase_purchase_count();
1040
1041 }
1042
1043 // Verify and update form meta based on the form status.
1044 give_set_form_closed_status( $this->form_id );
1045 }
1046
1047 $this->pending = [];
1048 $saved = true;
1049 } // End if().
1050
1051 if ( true === $saved ) {
1052 $this->setup_payment( $this->ID );
1053 }
1054
1055 return $saved;
1056 }
1057
1058 /**
1059 * Add a donation to a given payment
1060 *
1061 * @since 1.5
1062 * @access public
1063 *
1064 * @param int $form_id The donation form to add.
1065 * @param array $args Other arguments to pass to the function.
1066 * @param array $options List of donation options.
1067 *
1068 * @return bool True when successful, false otherwise
1069 */
1070 public function add_donation( $form_id = 0, $args = [], $options = [] ) {
1071
1072 $donation = new Give_Donate_Form( $form_id );
1073
1074 // Bail if this post isn't a give donation form.
1075 if ( ! $donation || 'give_forms' !== $donation->post_type ) {
1076 return false;
1077 }
1078
1079 // Set some defaults.
1080 $defaults = [
1081 'price' => false,
1082 'price_id' => false,
1083 ];
1084
1085 $args = wp_parse_args( apply_filters( 'give_payment_add_donation_args', $args, $donation->ID ), $defaults );
1086
1087 // Allow overriding the price.
1088 if ( false !== $args['price'] ) {
1089 $donation_amount = $args['price'];
1090 } else {
1091
1092 // Deal with variable pricing.
1093 if ( give_has_variable_prices( $donation->ID ) ) {
1094 $prices = give_get_meta( $form_id, '_give_donation_levels', true );
1095 $donation_amount = '';
1096
1097 // Loop through prices.
1098 foreach ( $prices as $price ) {
1099 // Find a match between price_id and level_id.
1100 // First verify array keys exists THEN make the match.
1101 if (
1102 isset( $args['price_id'] ) &&
1103 isset( $price['_give_id']['level_id'] ) &&
1104 $args['price_id'] === (int) $price['_give_id']['level_id']
1105 ) {
1106 $donation_amount = $price['_give_amount'];
1107 }
1108 }
1109
1110 // Fallback to the lowest price point.
1111 if ( '' === $donation_amount ) {
1112 $donation_amount = give_get_lowest_price_option( $donation->ID );
1113 $args['price_id'] = give_get_lowest_price_id( $donation->ID );
1114 }
1115 } else {
1116 // Simple form price.
1117 $donation_amount = give_get_form_price( $donation->ID );
1118 }
1119 }
1120
1121 // Sanitizing the price here so we don't have a dozen calls later.
1122 $donation_amount = give_maybe_sanitize_amount( $donation_amount );
1123 $total = round( $donation_amount, give_get_price_decimals( $this->ID ) );
1124
1125 // Add Options.
1126 $default_options = [];
1127 if ( false !== $args['price_id'] ) {
1128 $default_options['price_id'] = (int) $args['price_id'];
1129 }
1130 $options = wp_parse_args( $options, $default_options );
1131
1132 // Do not allow totals to go negative.
1133 if ( $total < 0 ) {
1134 $total = 0;
1135 }
1136
1137 $donation = [
1138 'name' => $donation->post_title,
1139 'id' => $donation->ID,
1140 'price' => round( $total, give_get_price_decimals( $this->ID ) ),
1141 'subtotal' => round( $total, give_get_price_decimals( $this->ID ) ),
1142 'price_id' => $args['price_id'],
1143 'action' => 'add',
1144 'options' => $options,
1145 ];
1146
1147 $this->pending['donations'][] = $donation;
1148
1149 $this->increase_subtotal( $total );
1150
1151 return true;
1152
1153 }
1154
1155 /**
1156 * Remove a donation from the payment
1157 *
1158 * @since 1.5
1159 * @access public
1160 *
1161 * @param int $form_id The form ID to remove.
1162 * @param array $args Arguments to pass to identify (quantity, amount, price_id).
1163 *
1164 * @return bool If the item was removed or not
1165 */
1166 public function remove_donation( $form_id, $args = [] ) {
1167
1168 // Set some defaults.
1169 $defaults = [
1170 'quantity' => 1,
1171 'price' => false,
1172 'price_id' => false,
1173 ];
1174 $args = wp_parse_args( $args, $defaults );
1175
1176 $form = new Give_Donate_Form( $form_id );
1177
1178 // Bail if this post isn't a valid give donation form.
1179 if ( ! $form || 'give_forms' !== $form->post_type ) {
1180 return false;
1181 }
1182
1183 $pending_args = $args;
1184 $pending_args['id'] = $form_id;
1185 $pending_args['amount'] = $this->total;
1186 $pending_args['price_id'] = false !== $args['price_id'] ? (int) $args['price_id'] : false;
1187 $pending_args['quantity'] = $args['quantity'];
1188 $pending_args['action'] = 'remove';
1189
1190 $this->pending['donations'][] = $pending_args;
1191
1192 $this->decrease_subtotal( $this->total );
1193
1194 return true;
1195 }
1196
1197
1198 /**
1199 * Add a note to a payment
1200 *
1201 * @since 1.5
1202 * @access public
1203 *
1204 * @param string|bool $note The note to add.
1205 *
1206 * @return bool If the note was specified or not
1207 */
1208 public function add_note( $note = false ) {
1209 // Bail if no note specified.
1210 if ( ! $note ) {
1211 return false;
1212 }
1213
1214 give_insert_payment_note( $this->ID, $note );
1215 }
1216
1217 /**
1218 * Increase the payment's subtotal
1219 *
1220 * @since 1.5
1221 * @access private
1222 *
1223 * @param float $amount The amount to increase the payment subtotal by.
1224 *
1225 * @return void
1226 */
1227 private function increase_subtotal( $amount = 0.00 ) {
1228 $amount = (float) $amount;
1229 $this->subtotal += $amount;
1230
1231 $this->recalculate_total();
1232 }
1233
1234 /**
1235 * Decrease the payment's subtotal.
1236 *
1237 * @since 1.5
1238 * @access private
1239 *
1240 * @param float $amount The amount to decrease the payment subtotal by.
1241 *
1242 * @return void
1243 */
1244 private function decrease_subtotal( $amount = 0.00 ) {
1245 $amount = (float) $amount;
1246 $this->subtotal -= $amount;
1247
1248 if ( $this->subtotal < 0 ) {
1249 $this->subtotal = 0;
1250 }
1251
1252 $this->recalculate_total();
1253 }
1254
1255 /**
1256 * Set or update the total for a payment.
1257 *
1258 * @since 1.5
1259 * @since 2.1.4 reset total in pending property
1260 * @access private
1261 *
1262 * @return void
1263 */
1264 private function recalculate_total() {
1265 $this->pending['total'] = $this->total = $this->subtotal;
1266 }
1267
1268 /**
1269 * Set the payment status and run any status specific changes necessary.
1270 *
1271 * @since 1.5
1272 * @access public
1273 *
1274 * @param string|bool $status The status to set the payment to.
1275 *
1276 * @return bool $updated Returns if the status was successfully updated.
1277 */
1278 public function update_status( $status = false ) {
1279
1280 // standardize the 'complete(d)' status.
1281 if ( 'completed' === $status || 'complete' === $status ) {
1282 $status = 'publish';
1283 }
1284
1285 $old_status = ! empty( $this->old_status ) ? $this->old_status : false;
1286
1287 if ( $old_status === $status ) {
1288 return false; // Don't permit status changes that aren't changes.
1289 }
1290
1291 $do_change = apply_filters( 'give_should_update_payment_status', true, $this->ID, $status, $old_status );
1292
1293 $updated = false;
1294
1295 if ( $do_change ) {
1296
1297 /**
1298 * Fires before changing payment status.
1299 *
1300 * @since 1.5
1301 *
1302 * @param int $payment_id Payments ID.
1303 * @param string $status The new status.
1304 * @param string $old_status The old status.
1305 */
1306 do_action( 'give_before_payment_status_change', $this->ID, $status, $old_status );
1307
1308 $update_fields = [
1309 'ID' => $this->ID,
1310 'post_status' => $status,
1311 'edit_date' => current_time( 'mysql' ),
1312 ];
1313
1314 $updated = wp_update_post( apply_filters( 'give_update_payment_status_fields', $update_fields ) );
1315
1316 $all_payment_statuses = give_get_payment_statuses();
1317 $this->status_nicename = array_key_exists( $status, $all_payment_statuses ) ? $all_payment_statuses[ $status ] : ucfirst( $status );
1318
1319 // Process any specific status functions.
1320 $this->process_status( $status );
1321
1322 /**
1323 * Fires after changing payment status.
1324 *
1325 * @since 1.5
1326 *
1327 * @param int $payment_id Payment ID.
1328 * @param string $status The new status.
1329 * @param string $old_status The old status.
1330 */
1331 do_action( 'give_update_payment_status', $this->ID, $status, $old_status );
1332
1333 } // End if().
1334
1335 return $updated;
1336
1337 }
1338
1339 /**
1340 * Change the status of the payment to refunded, and run the necessary changes
1341 *
1342 * @since 1.5
1343 * @access public
1344 *
1345 * @return void
1346 */
1347 public function refund() {
1348 $this->old_status = $this->status;
1349 $this->status = 'refunded';
1350 $this->pending['status'] = $this->status;
1351
1352 $this->save();
1353 }
1354
1355 /**
1356 * Get a post meta item for the payment
1357 *
1358 * @since 1.5
1359 * @access public
1360 *
1361 * @param string $meta_key The Meta Key.
1362 * @param boolean $single Return single item or array.
1363 *
1364 * @return mixed The value from the post meta
1365 */
1366 public function get_meta( $meta_key = '_give_payment_meta', $single = true ) {
1367 if (
1368 ! has_filter( 'get_post_metadata', 'give_bc_v20_get_payment_meta' ) &&
1369 ! doing_filter( 'get_post_metadata' )
1370 ) {
1371 add_filter( 'get_post_metadata', 'give_bc_v20_get_payment_meta', 999, 4 );
1372 }
1373
1374 $meta = give_get_meta( $this->ID, $meta_key, $single );
1375
1376 /**
1377 * Filter the specific meta key value.
1378 *
1379 * @since 1.5
1380 */
1381 $meta = apply_filters( "give_get_payment_meta_{$meta_key}", $meta, $this->ID );
1382
1383 // Security check.
1384 if ( is_serialized( $meta ) ) {
1385 preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $meta, $matches );
1386 if ( ! empty( $matches ) ) {
1387 $meta = [];
1388 }
1389 }
1390
1391 /**
1392 * Filter the all meta keys.
1393 *
1394 * @since 1.5
1395 */
1396 return apply_filters( 'give_get_payment_meta', $meta, $this->ID, $meta_key );
1397 }
1398
1399 /**
1400 * Update the post meta
1401 *
1402 * @since 1.5
1403 * @access public
1404 *
1405 * @param string $meta_key The meta key to update.
1406 * @param string $meta_value The meta value.
1407 * @param string $prev_value Previous meta value.
1408 *
1409 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure
1410 */
1411 public function update_meta( $meta_key = '', $meta_value = '', $prev_value = '' ) {
1412 if ( empty( $meta_key ) ) {
1413 return false;
1414 }
1415
1416 /**
1417 * Filter the single meta key while updating
1418 *
1419 * @since 1.5
1420 */
1421 $meta_value = apply_filters( "give_update_payment_meta_{$meta_key}", $meta_value, $this->ID );
1422
1423 return give_update_meta( $this->ID, $meta_key, $meta_value, $prev_value );
1424 }
1425
1426 /**
1427 * Process Donation Status.
1428 *
1429 * @param string $status Donation Status.
1430 *
1431 * @since 2.0.2
1432 * @access private
1433 *
1434 * @return void
1435 */
1436 private function process_status( $status ) {
1437 $process = true;
1438
1439 // Bailout, if changed from completed to preapproval/processing.
1440 // Bailout, if current status = previous status or status is publish.
1441 if (
1442 'preapproval' === $status ||
1443 'processing' === $status ||
1444 'publish' !== $this->old_status ||
1445 $status !== $this->status
1446 ) {
1447 $process = false;
1448 }
1449
1450 // Allow extensions to filter for their own payment types, Example: Recurring Payments.
1451 $process = apply_filters( "give_should_process_{$status}", $process, $this );
1452
1453 if ( false === $process ) {
1454 return;
1455 }
1456
1457 /**
1458 * Fires before processing donation status.
1459 *
1460 * @param Give_Payment $this Payment object.
1461 *
1462 * @since 1.5
1463 */
1464 do_action( "give_pre_{$status}_payment", $this );
1465
1466 $decrease_earnings = apply_filters( "give_decrease_earnings_on_{$status}", true, $this );
1467 $decrease_donor_value = apply_filters( "give_decrease_donor_value_on_{$status}", true, $this );
1468 $decrease_donation_count = apply_filters( "give_decrease_donors_donation_count_on_{$status}", true, $this );
1469
1470 $this->maybe_alter_stats( $decrease_earnings, $decrease_donor_value, $decrease_donation_count );
1471
1472 // @todo: Refresh only range related stat cache
1473 give_delete_donation_stats();
1474
1475 /**
1476 * Fires after processing donation status.
1477 *
1478 * @param Give_Payment $this Payment object.
1479 *
1480 * @since 1.5
1481 */
1482 do_action( "give_post_{$status}_payment", $this );
1483 }
1484
1485 /**
1486 * Used during the process of moving to refunded or pending, to decrement stats
1487 *
1488 * @since 1.5
1489 * @access private
1490 *
1491 * @param bool $alter_store_earnings If the method should alter the store earnings.
1492 * @param bool $alter_customer_value If the method should reduce the donor value.
1493 * @param bool $alter_customer_purchase_count If the method should reduce the donor's purchase count.
1494 *
1495 * @return void
1496 */
1497 private function maybe_alter_stats( $alter_store_earnings, $alter_customer_value, $alter_customer_purchase_count ) {
1498
1499 give_undo_donation( $this->ID );
1500
1501 // Decrease store earnings.
1502 if ( true === $alter_store_earnings ) {
1503 give_decrease_total_earnings( $this->total );
1504 }
1505
1506 // Decrement the stats for the donor.
1507 if ( ! empty( $this->customer_id ) ) {
1508
1509 $donor = new Give_Donor( $this->customer_id );
1510
1511 if ( true === $alter_customer_value ) {
1512 $donor->decrease_value( $this->total );
1513 }
1514
1515 if ( true === $alter_customer_purchase_count ) {
1516 $donor->decrease_donation_count();
1517 }
1518 }
1519
1520 }
1521
1522 /**
1523 * Setup functions only, these are not to be used by developers.
1524 * These functions exist only to allow the setup routine to be backwards compatible with our old
1525 * helper functions.
1526 *
1527 * These will run whenever setup_payment is called, which should only be called once.
1528 * To update an attribute, update it directly instead of re-running the setup routine
1529 */
1530
1531 /**
1532 * Setup the payment completed date
1533 *
1534 * @since 1.5
1535 * @access private
1536 *
1537 * @return string The date the payment was completed
1538 */
1539 private function setup_completed_date() {
1540 $payment = get_post( $this->ID );
1541
1542 if ( 'pending' === $payment->post_status || 'preapproved' === $payment->post_status ) {
1543 return false; // This payment was never completed.
1544 }
1545
1546 $date = ( $date = $this->get_meta( '_give_completed_date', true ) ) ? $date : $payment->modified_date;
1547
1548 return $date;
1549 }
1550
1551 /**
1552 * Setup the payment mode
1553 *
1554 * @since 1.5
1555 * @access private
1556 *
1557 * @return string The payment mode
1558 */
1559 private function setup_mode() {
1560 return $this->get_meta( '_give_payment_mode' );
1561 }
1562
1563 /**
1564 * Setup the payment import data
1565 *
1566 * @since 1.8.13
1567 * @access private
1568 *
1569 * @return bool The payment import
1570 */
1571 private function setup_import() {
1572 return (bool) $this->get_meta( '_give_payment_import' );
1573 }
1574
1575 /**
1576 * Setup the payment total
1577 *
1578 * @since 1.5
1579 * @access private
1580 *
1581 * @return float The payment total
1582 */
1583 private function setup_total() {
1584 $amount = $this->get_meta( '_give_payment_total', true );
1585
1586 return round( floatval( $amount ), give_get_price_decimals( $this->ID ) );
1587 }
1588
1589 /**
1590 * Setup the payment subtotal
1591 *
1592 * @since 1.5
1593 * @access private
1594 *
1595 * @return float The subtotal of the payment
1596 */
1597 private function setup_subtotal() {
1598 $subtotal = $this->total;
1599
1600 return $subtotal;
1601 }
1602
1603 /**
1604 * Setup the currency code
1605 *
1606 * @since 1.5
1607 * @since 2.0 Set currency from _give_payment_currency meta key
1608 * @access private
1609 *
1610 * @return string The currency for the payment
1611 */
1612 private function setup_currency() {
1613 $currency = $this->get_meta( '_give_payment_currency', true );
1614 $currency = ! empty( $currency ) ?
1615 $currency :
1616 /**
1617 * Filter the default donation currency
1618 *
1619 * @since 1.5
1620 */
1621 apply_filters(
1622 'give_payment_currency_default',
1623 give_get_currency( $this->form_id, $this ),
1624 $this
1625 );
1626
1627 return $currency;
1628 }
1629
1630 /**
1631 * Setup the gateway used for the payment
1632 *
1633 * @since 1.5
1634 * @access private
1635 *
1636 * @return string The gateway
1637 */
1638 private function setup_gateway() {
1639 $gateway = $this->get_meta( '_give_payment_gateway', true );
1640
1641 return $gateway;
1642 }
1643
1644 /**
1645 * Setup the donation ID
1646 *
1647 * @since 1.5
1648 * @access private
1649 *
1650 * @return string The donation ID
1651 */
1652 private function setup_transaction_id() {
1653 $transaction_id = $this->get_meta( '_give_payment_transaction_id', true );
1654
1655 if ( empty( $transaction_id ) ) {
1656 $gateway = $this->gateway;
1657 $transaction_id = apply_filters( "give_get_payment_transaction_id-{$gateway}", $this->ID );
1658 }
1659
1660 return $transaction_id;
1661 }
1662
1663 /**
1664 * Setup the IP Address for the payment
1665 *
1666 * @since 1.5
1667 * @since 2.0 Set ip address from _give_payment_donor_ip meta key
1668 * @access private
1669 *
1670 * @return string The IP address for the payment
1671 */
1672 private function setup_ip() {
1673 $ip = $this->get_meta( '_give_payment_donor_ip', true );
1674
1675 return $ip;
1676 }
1677
1678 /**
1679 * Setup the donor ID.
1680 *
1681 * @since 1.5
1682 * @since 2.0 Set id from _give_payment_donor_id meta key
1683 * @access private
1684 *
1685 * @return int The Donor ID.
1686 */
1687 private function setup_donor_id() {
1688 $donor_id = $this->get_meta( '_give_payment_donor_id', true );
1689
1690 return $donor_id;
1691 }
1692
1693 /**
1694 * Setup the User ID associated with the donation
1695 *
1696 * @since 1.5
1697 * @since 2.0 Get user id connect to donor from donor table instead of payment meta.
1698 *
1699 * @access private
1700 *
1701 * @return int The User ID
1702 */
1703 private function setup_user_id() {
1704
1705 $donor = Give()->donors->get_donor_by( 'id', $this->donor_id );
1706 $user_id = $donor ? absint( $donor->user_id ) : 0;
1707
1708 return $user_id;
1709 }
1710
1711 /**
1712 * Setup the email address for the donation.
1713 *
1714 * @since 1.5
1715 * @since 2.0 Set email from _give_payment_donor_email meta key
1716 *
1717 * @access private
1718 *
1719 * @return string The email address for the payment.
1720 */
1721 private function setup_email() {
1722 $email = $this->get_meta( '_give_payment_donor_email', true );
1723
1724 if ( empty( $email ) && $this->customer_id ) {
1725 $email = Give()->donors->get_column( 'email', $this->customer_id );
1726 }
1727
1728 return $email;
1729 }
1730
1731 /**
1732 * Setup the user info.
1733 *
1734 * @since 1.5
1735 * @access private
1736 *
1737 * @return array The user info associated with the payment.
1738 */
1739 private function setup_user_info() {
1740 $defaults = [
1741 'title' => $this->title_prefix,
1742 'first_name' => $this->first_name,
1743 'last_name' => $this->last_name,
1744 ];
1745
1746 $user_info = isset( $this->payment_meta['user_info'] ) ? $this->payment_meta['user_info'] : [];
1747
1748 if ( is_serialized( $user_info ) ) {
1749 preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $user_info, $matches );
1750 if ( ! empty( $matches ) ) {
1751 $user_info = [];
1752 }
1753 }
1754
1755 $user_info = wp_parse_args( $user_info, $defaults );
1756
1757 if ( empty( $user_info ) ) {
1758 // Get the donor, but only if it's been created.
1759 $donor = new Give_Donor( $this->customer_id );
1760
1761 if ( $donor->id > 0 ) {
1762 $user_info = [
1763 'first_name' => $donor->get_first_name(),
1764 'last_name' => $donor->get_last_name(),
1765 'email' => $donor->email,
1766 'discount' => 'none',
1767 ];
1768 }
1769 } else {
1770 // Get the donor, but only if it's been created.
1771 $donor = new Give_Donor( $this->customer_id );
1772
1773 if ( $donor->id > 0 ) {
1774 foreach ( $user_info as $key => $value ) {
1775 if ( ! empty( $value ) ) {
1776 continue;
1777 }
1778
1779 switch ( $key ) {
1780 case 'title':
1781 $user_info[ $key ] = Give()->donor_meta->get_meta( $donor->id, '_give_donor_title_prefix', true );
1782 break;
1783
1784 case 'first_name':
1785 $user_info[ $key ] = $donor->get_first_name();
1786 break;
1787
1788 case 'last_name':
1789 $user_info[ $key ] = $donor->get_last_name();
1790 break;
1791
1792 case 'email':
1793 $user_info[ $key ] = $donor->email;
1794 break;
1795 }
1796 }
1797 }
1798 }// End if().
1799
1800 return $user_info;
1801
1802 }
1803
1804 /**
1805 * Setup the Address for the payment.
1806 *
1807 * @since 1.5
1808 * @access private
1809 *
1810 * @return array The Address information for the payment.
1811 */
1812 private function setup_address() {
1813 $address['line1'] = give_get_meta( $this->ID, '_give_donor_billing_address1', true, '' );
1814 $address['line2'] = give_get_meta( $this->ID, '_give_donor_billing_address2', true, '' );
1815 $address['city'] = give_get_meta( $this->ID, '_give_donor_billing_city', true, '' );
1816 $address['state'] = give_get_meta( $this->ID, '_give_donor_billing_state', true, '' );
1817 $address['zip'] = give_get_meta( $this->ID, '_give_donor_billing_zip', true, '' );
1818 $address['country'] = give_get_meta( $this->ID, '_give_donor_billing_country', true, '' );
1819
1820 return $address;
1821 }
1822
1823 /**
1824 * Setup the form title.
1825 *
1826 * @since 1.5
1827 * @access private
1828 *
1829 * @return string The Form Title.
1830 */
1831 private function setup_form_title() {
1832
1833 $form_id = $this->get_meta( '_give_payment_form_title', true );
1834
1835 return $form_id;
1836 }
1837
1838 /**
1839 * Setup the form ID.
1840 *
1841 * @since 1.5
1842 * @access private
1843 *
1844 * @return int The Form ID
1845 */
1846 private function setup_form_id() {
1847
1848 $form_id = $this->get_meta( '_give_payment_form_id', true );
1849
1850 return $form_id;
1851 }
1852
1853 /**
1854 * Setup the campaign ID.
1855 *
1856 * @since 4.3.2
1857 * @access private
1858 *
1859 * @return int The Campaign ID
1860 */
1861 private function setup_campaign_id() {
1862
1863 $campaign_id = $this->get_meta( '_give_campaign_id', true );
1864
1865 return empty( $campaign_id ) ? 0 : $campaign_id;
1866 }
1867
1868 /**
1869 * Setup the price ID.
1870 *
1871 * @since 1.5
1872 * @access private
1873 *
1874 * @return int The Form Price ID.
1875 */
1876 private function setup_price_id() {
1877 $price_id = $this->get_meta( '_give_payment_price_id', true );
1878
1879 return $price_id;
1880 }
1881
1882 /**
1883 * Setup the payment key.
1884 *
1885 * @since 1.5
1886 * @access private
1887 *
1888 * @return string The Payment Key.
1889 */
1890 private function setup_payment_key() {
1891 $key = $this->get_meta( '_give_payment_purchase_key', true );
1892
1893 return $key;
1894 }
1895
1896 /**
1897 * Setup the payment number.
1898 *
1899 * @since 1.5
1900 * @access private
1901 *
1902 * @return int|string Integer by default, or string if sequential order numbers is enabled.
1903 */
1904 private function setup_payment_number() {
1905 return $this->get_serial_code();
1906 }
1907
1908 /**
1909 * Converts this object into an array for special cases.
1910 *
1911 * @access public
1912 *
1913 * @return array The payment object as an array.
1914 */
1915 public function array_convert() {
1916 return get_object_vars( $this );
1917 }
1918
1919
1920 /**
1921 * Flag to check if donation is completed or not.
1922 *
1923 * @since 1.8
1924 * @access public
1925 *
1926 * @return bool
1927 */
1928 public function is_completed() {
1929 return ( 'publish' === $this->status && $this->completed_date );
1930 }
1931
1932 /**
1933 * Retrieve payment completion date.
1934 *
1935 * @since 1.5
1936 * @access private
1937 *
1938 * @return string Date payment was completed.
1939 */
1940 private function get_completed_date() {
1941 return apply_filters( 'give_payment_completed_date', $this->completed_date, $this->ID, $this );
1942 }
1943
1944 /**
1945 * Retrieve payment subtotal.
1946 *
1947 * @since 1.5
1948 * @access private
1949 *
1950 * @return float Payment subtotal.
1951 */
1952 private function get_subtotal() {
1953 return apply_filters( 'give_get_payment_subtotal', $this->subtotal, $this->ID, $this );
1954 }
1955
1956 /**
1957 * Retrieve payment currency.
1958 *
1959 * @since 1.5
1960 * @access private
1961 *
1962 * @return string Payment currency code.
1963 */
1964 private function get_currency() {
1965 return apply_filters( 'give_payment_currency_code', $this->currency, $this->ID, $this );
1966 }
1967
1968 /**
1969 * Retrieve payment gateway.
1970 *
1971 * @since 1.5
1972 * @access private
1973 *
1974 * @return string Gateway used.
1975 */
1976 private function get_gateway() {
1977 return apply_filters( 'give_payment_gateway', $this->gateway, $this->ID, $this );
1978 }
1979
1980 /**
1981 * Retrieve donation ID.
1982 *
1983 * @since 1.5
1984 * @access private
1985 *
1986 * @return string Donation ID from merchant processor.
1987 */
1988 private function get_transaction_id() {
1989 return apply_filters( 'give_get_payment_transaction_id', $this->transaction_id, $this->ID, $this );
1990 }
1991
1992 /**
1993 * Retrieve payment IP
1994 *
1995 * @since 1.5
1996 * @access private
1997 *
1998 * @return string Payment IP address
1999 */
2000 private function get_ip() {
2001 return apply_filters( 'give_payment_user_ip', $this->ip, $this->ID, $this );
2002 }
2003
2004 /**
2005 * Retrieve payment donor ID.
2006 *
2007 * @since 1.5
2008 * @access private
2009 *
2010 * @return int Payment donor ID.
2011 */
2012 private function get_donor_id() {
2013 return apply_filters( 'give_payment_customer_id', $this->customer_id, $this->ID, $this );
2014 }
2015
2016 /**
2017 * Retrieve payment user ID.
2018 *
2019 * @since 1.5
2020 * @access private
2021 *
2022 * @return int Payment user ID.
2023 */
2024 private function get_user_id() {
2025 return apply_filters( 'give_payment_user_id', $this->user_id, $this->ID, $this );
2026 }
2027
2028 /**
2029 * Retrieve payment email.
2030 *
2031 * @since 1.5
2032 * @access private
2033 *
2034 * @return string Payment donor email.
2035 */
2036 private function get_email() {
2037 return apply_filters( 'give_payment_user_email', $this->email, $this->ID, $this );
2038 }
2039
2040 /**
2041 * Retrieve payment user info.
2042 *
2043 * @since 1.5
2044 * @access private
2045 *
2046 * @return array Payment user info.
2047 */
2048 private function get_user_info() {
2049 return apply_filters( 'give_payment_meta_user_info', $this->user_info, $this->ID, $this );
2050 }
2051
2052 /**
2053 * Retrieve payment billing address.
2054 *
2055 * @since 1.5
2056 * @access private
2057 *
2058 * @return array Payment billing address.
2059 */
2060 private function get_address() {
2061 return apply_filters( 'give_payment_address', $this->address, $this->ID, $this );
2062 }
2063
2064 /**
2065 * Retrieve payment key.
2066 *
2067 * @since 1.5
2068 * @access private
2069 *
2070 * @return string Payment key.
2071 */
2072 private function get_key() {
2073 return apply_filters( 'give_payment_key', $this->key, $this->ID, $this );
2074 }
2075
2076 /**
2077 * Retrieve payment form id
2078 *
2079 * @since 1.5
2080 * @access private
2081 *
2082 * @return string Payment form id
2083 */
2084 private function get_form_id() {
2085 return apply_filters( 'give_payment_form_id', $this->form_id, $this->ID, $this );
2086 }
2087
2088 /**
2089 * Retrieve payment campaign id
2090 *
2091 * @since 4.3.2
2092 * @access private
2093 *
2094 * @return string|int Payment campaign id
2095 */
2096 private function get_campaign_id() {
2097 return apply_filters( 'give_payment_campaign_id', $this->campaign_id, $this->ID, $this );
2098 }
2099
2100 /**
2101 * Retrieve payment number
2102 *
2103 * @since 1.5
2104 * @access private
2105 *
2106 * @return int|string Payment number
2107 */
2108 private function get_number() {
2109 return apply_filters( 'give_payment_number', $this->number, $this->ID, $this );
2110 }
2111
2112 /**
2113 * Get serial code
2114 *
2115 * @since 2.1
2116 *
2117 * @param array $args List of arguments.
2118 *
2119 * @return string
2120 */
2121 public function get_serial_code( $args = [] ) {
2122 return Give()->seq_donation_number->get_serial_code( $this, $args );
2123 }
2124 }
2125