PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.4
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.4
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Modules / Payments / PaymentMethods / Stripe / StripeProcessor.php

StripeProcessor.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.4, at app/Modules/Payments/PaymentMethods/Stripe/StripeProcessor.php

768 lines 27.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Modules\Payments\PaymentMethods\Stripe;
4
5 if (!defined('ABSPATH')) {
6 exit; // Exit if accessed directly.
7 }
8
9 use FluentForm\App\Helpers\Helper;
10 use FluentForm\App\Models\Submission;
11 use FluentForm\App\Models\Transaction;
12 use FluentForm\App\Services\FormBuilder\ShortCodeParser;
13 use FluentForm\Framework\Helpers\ArrayHelper;
14 use FluentForm\App\Modules\Payments\PaymentHelper;
15 use FluentForm\App\Modules\Payments\PaymentMethods\BaseProcessor;
16 use FluentForm\App\Modules\Payments\PaymentMethods\Stripe\API\CheckoutSession;
17 use FluentForm\App\Modules\Payments\PaymentMethods\Stripe\API\Plan;
18
19 class StripeProcessor extends BaseProcessor
20 {
21 public $method = 'stripe';
22
23 protected $form;
24
25 public function init()
26 {
27 add_action('fluentform/process_payment_stripe_hosted', array($this, 'handlePaymentAction'), 10, 6);
28 add_action('fluentform/payment_frameless_' . $this->method, array($this, 'handleSessionRedirectBack'));
29 }
30
31 public function handlePaymentAction($submissionId, $submissionData, $form, $methodSettings, $hasSubscriptions, $totalPayable)
32 {
33 $this->setSubmissionId($submissionId);
34 $this->form = $form;
35 $submission = $this->getSubmission();
36 $paymentTotal = $this->getAmountTotal();
37
38 if (!$paymentTotal && !$hasSubscriptions) {
39 return false;
40 }
41
42 // Create the initial transaction here
43 $transaction = $this->createInitialPendingTransaction($submission, $hasSubscriptions);
44
45 $this->handleCheckoutSession($transaction, $submission, $form, $methodSettings);
46 }
47
48 public function handleCheckoutSession($transaction, $submission, $form, $methodSettings)
49 {
50
51 $formSettings = PaymentHelper::getFormSettings($form->id);
52
53 $args = [
54 'fluentform_payment' => $submission->id,
55 'payment_method' => $this->method,
56 'transaction_hash' => $transaction->transaction_hash,
57 'type' => 'success'
58 ];
59
60
61 $successUrl = add_query_arg($args, site_url('index.php'));
62
63 $cancelUrl = $submission->source_url;
64
65 if (!wp_http_validate_url($cancelUrl)) {
66 $cancelUrl = site_url($cancelUrl);
67 }
68
69
70 $checkoutArgs = [
71 'cancel_url' => wp_sanitize_redirect($cancelUrl),
72 'success_url' => wp_sanitize_redirect($successUrl),
73 'locale' => 'auto',
74 'billing_address_collection' => 'auto',
75 'client_reference_id' => $submission->id,
76 'customer_email' => $transaction->payer_email,
77 'metadata' => [
78 'submission_id' => $submission->id,
79 'form_id' => $form->id,
80 'transaction_id' => ($transaction) ? $transaction->id : ''
81 ]
82 ];
83
84 if (ArrayHelper::get($methodSettings, 'settings.require_billing_info.value') == 'yes') {
85 $checkoutArgs['billing_address_collection'] = 'required';
86 }
87
88 if (ArrayHelper::get($methodSettings, 'settings.require_shipping_info.value') == 'yes') {
89 $checkoutArgs['shipping_address_collection'] = [
90 'allowed_countries' => StripeSettings::supportedShippingCountries()
91 ];
92 }
93
94 if ($lineItems = $this->getFormattedItems($submission->currency)) {
95 $checkoutArgs['line_items'] = $lineItems;
96 }
97
98 $receiptEmail = PaymentHelper::getCustomerEmail($submission, $form);
99
100 if ($receiptEmail) {
101 $checkoutArgs['customer_email'] = $receiptEmail;
102 }
103
104 if ($transaction->transaction_type == 'subscription') {
105 unset($checkoutArgs['submit_type']);
106
107 $subscriptions = $this->getSubscriptions();
108 $subscription = $subscriptions[0];
109
110 if ($subscription->initial_amount) {
111 if (!isset($checkoutArgs['line_items'])) {
112 $checkoutArgs['line_items'] = [];
113 }
114 $price = $subscription->initial_amount;
115 if (PaymentHelper::isZeroDecimal($transaction->currency)) {
116 $price = intval($price / 100);
117 }
118 $checkoutArgs['line_items'][] = [
119 'amount' => $price,
120 'currency' => $transaction->currency,
121 /* translators: %s is the plan name */
122 'name' => sprintf(__('Signup fee for %s', 'fluentform'), $subscription->plan_name),
123 'quantity' => 1
124 ];
125 }
126
127 $stripePlan = Plan::getSubscriptionPlanBySubscription($subscription, $transaction->currency);
128
129 if(is_wp_error($stripePlan)) {
130 $this->handlePaymentChargeError($stripePlan->get_error_message(), $submission, $transaction);
131 }
132
133 $this->updateSubscription($subscription->id, [
134 'vendor_plan_id' => $stripePlan->id
135 ]);
136
137 $subsArgs = [
138 'items' => [
139 [
140 'plan' => $stripePlan->id,
141 'quantity' => $subscription->quantity ? $subscription->quantity : 1
142 ]
143 ]
144 ];
145
146 if ($subscription->trial_days) {
147 $subsArgs['trial_period_days'] = $subscription->trial_days;
148 }
149
150 $subsArgs['metadata'] = $this->getIntentMetaData($submission, $form, $transaction);
151
152 $checkoutArgs['subscription_data'] = $subsArgs;
153
154 } else {
155 $checkoutArgs['submit_type'] = 'auto';
156 $checkoutArgs['payment_intent_data'] = $this->getPaymentIntentData($transaction, $submission, $form);
157 if ($receiptEmail && ArrayHelper::get($formSettings, 'disable_stripe_payment_receipt') != 'yes') {
158 $checkoutArgs['payment_intent_data']['receipt_email'] = $receiptEmail;
159 }
160 }
161 if ($formSettings['transaction_type'] == 'donation' && $transaction->transaction_type != 'subscription') {
162 $checkoutArgs['submit_type'] = 'donate';
163 }
164
165 $checkoutArgs = apply_filters_deprecated(
166 'fluentform_stripe_checkout_args',
167 [
168 $checkoutArgs,
169 $submission,
170 $transaction,
171 $form
172 ],
173 FLUENTFORM_FRAMEWORK_UPGRADE,
174 'fluentform/stripe_checkout_args',
175 'Use fluentform/stripe_checkout_args instead of fluentform_stripe_checkout_args.'
176 );
177
178 $checkoutArgs = apply_filters('fluentform/stripe_checkout_args', $checkoutArgs, $submission, $transaction, $form);
179
180 // If FluentForm Pro is not installed, apply the fee 1.9%
181 if (!Helper::hasPro()) {
182 if ($transaction->transaction_type == 'subscription') {
183 $checkoutArgs['subscription_data']['application_fee_percent'] = 1.9; // 1.9%
184 } else {
185 // Total amount of 1.9%
186 $applicationFeeAmount = (int) ($transaction->payment_total * 0.019);
187 $checkoutArgs['payment_intent_data']['application_fee_amount'] = $applicationFeeAmount;
188 }
189 }
190
191 $session = CheckoutSession::create($checkoutArgs);
192
193 if (!empty($session->error) || is_wp_error($session)) {
194 $error = __('Something is wrong', 'fluentform');
195 if (is_wp_error($session)) {
196 $error = $session->get_error_message();
197 } else if (!empty($session->error->message)) {
198 $error = $session->error->message;
199 }
200 $errorMessage = __('Stripe Error: ', 'fluentform') . $error;
201 wp_send_json([
202 'errors' => apply_filters('fluentform/payment_error_message', $errorMessage, $submission, $this->form)
203 ], 423);
204 }
205
206 $this->setMetaData('stripe_session_id', $session->id);
207
208 $logData = [
209 'parent_source_id' => $submission->form_id,
210 'source_type' => 'submission_item',
211 'source_id' => $submission->id,
212 'component' => 'Payment',
213 'status' => 'info',
214 'title' => __('Redirect to Stripe', 'fluentform'),
215 'description' => __('User redirect to Stripe for completing the payment', 'fluentform')
216 ];
217 do_action('fluentform/log_data', $logData);
218
219 wp_send_json_success([
220 'nextAction' => 'payment',
221 'actionName' => 'stripeRedirectToCheckout',
222 'sessionId' => $session->id,
223 'message' => __('You are redirecting to stripe.com to complete the purchase. Please wait while you are redirecting....', 'fluentform'),
224 'result' => [
225 'insert_id' => $submission->id
226 ]
227 ], 200);
228 }
229
230 protected function getPaymentIntentData($transaction, $submission, $form)
231 {
232 $data = [
233 'capture_method' => 'automatic',
234 'description' => $form->title,
235 'statement_descriptor_suffix' => StripeSettings::getPaymentDescriptor($form),
236 ];
237
238 $paymentSettings = PaymentHelper::getFormSettings($form->id, 'admin');
239 $intentMeta = $this->getIntentMetaData($submission, $form, $transaction, $paymentSettings);
240
241 $data['metadata'] = $intentMeta;
242 return $data;
243 }
244
245 public function getFormattedItems($currency)
246 {
247 $orderItems = $this->getOrderItems();
248
249 $discountItems = $this->getDiscountItems();
250
251 $discountTotal = 0;
252 foreach ($discountItems as $item) {
253 $discountTotal += $item->line_total;
254 }
255
256 $orderTotal = 0;
257 foreach ($orderItems as $orderItem) {
258 $orderTotal += $orderItem->line_total;
259 }
260
261 $formattedItems = [];
262 $discountDistributed = 0;
263 $itemCount = count($orderItems);
264
265 foreach ($orderItems as $index => $item) {
266 $price = $item->item_price;
267 $quantity = $item->quantity ?: 1;
268
269 if ($discountTotal && $orderTotal) {
270 if ($index === $itemCount - 1) {
271 // Last item absorbs any remaining discount not yet distributed.
272 // intval floors the per-unit price, so (unitPrice * quantity) may be
273 // less than lineTotal. The difference (remainder) is 0..quantity-1 cents.
274 // When remainder > 0 we split into two Stripe line items:
275 // (quantity - remainder) units at the floor price, and
276 // remainder units at floor + 1 cent,
277 // so the total adds up exactly. e.g. $28.00 / 3 → 2×$9.33 + 1×$9.34 = $28.00
278 $remainingDiscount = $discountTotal - $discountDistributed;
279 $lineTotal = ($price * $quantity) - $remainingDiscount;
280 $unitPrice = intval($lineTotal / $quantity);
281 $remainder = $lineTotal - ($unitPrice * $quantity);
282
283 if ($remainder > 0 && $quantity > 1) {
284 $basePrice = $unitPrice;
285 $extraPrice = $unitPrice + 1;
286
287 if (PaymentHelper::isZeroDecimal($currency)) {
288 $basePrice = intval($basePrice / 100);
289 $extraPrice = intval($extraPrice / 100);
290 }
291
292 $formattedItems[] = [
293 'amount' => $basePrice,
294 'currency' => $currency,
295 'name' => $item->item_name,
296 'quantity' => $quantity - $remainder
297 ];
298 $formattedItems[] = [
299 'amount' => $extraPrice,
300 'currency' => $currency,
301 'name' => $item->item_name,
302 'quantity' => $remainder
303 ];
304 continue;
305 }
306
307 $price = $unitPrice;
308 } else {
309 $itemDiscount = (int) round(($discountTotal / $orderTotal) * $price);
310 $discountDistributed += $itemDiscount * $quantity;
311 $price = $price - $itemDiscount;
312 }
313 }
314
315 if (PaymentHelper::isZeroDecimal($currency)) {
316 $price = intval($price / 100);
317 }
318
319 $stripeLine = [
320 'amount' => $price,
321 'currency' => $currency,
322 'name' => $item->item_name,
323 'quantity' => $quantity
324 ];
325
326 $formattedItems[] = $stripeLine;
327 }
328
329 return $formattedItems;
330 }
331
332 public function handleSessionRedirectBack($data)
333 {
334 $type = sanitize_text_field($data['type']);
335 $submissionId = intval($data['fluentform_payment']);
336 $this->setSubmissionId($submissionId);
337
338 $submission = $this->getSubmission();
339
340 if (!$submission) {
341 return;
342 }
343
344 if ($type == 'success') {
345 if ($this->getMetaData('is_form_action_fired') == 'yes') {
346 $returnData = $this->getReturnData();
347 } else {
348 $sessionId = $this->getMetaData('stripe_session_id');
349 $session = CheckoutSession::retrieve($sessionId, [
350 'expand' => [
351 'subscription.latest_invoice.payment_intent',
352 'payment_intent'
353 ]
354 ], $submission->form_id);
355
356 if ($session && !is_wp_error($session) && $session->customer) {
357 $transactionHash = sanitize_text_field($data['transaction_hash']);
358 $transaction = $this->getTransaction($transactionHash, 'transaction_hash');
359 $returnData = $this->processStripeSession($session, $submission, $transaction);
360 } else {
361 $error = __('Sorry! No Valid payment session found. Please try again','fluentform');
362 if (is_wp_error($session)) {
363 $error = $session->get_error_message();
364 }
365 $returnData = [
366 'insert_id' => $submission->id,
367 'title' => __('Failed to retrieve session data', 'fluentform'),
368 'result' => false,
369 'error' => $error
370 ];
371 }
372 }
373 } else {
374 $returnData = [
375 'insert_id' => $submission->id,
376 'result' => false,
377 'error' => apply_filters('fluentform/stripe_payment_cancelled_message', __('Looks like you have cancelled the payment. Please try again!', 'fluentform'), $submission, $this->form)
378 ];
379 }
380
381 $returnData['type'] = $type;
382
383 if (!isset($returnData['is_new'])) {
384 $returnData['is_new'] = false;
385 }
386
387 $this->showPaymentView($returnData);
388 }
389
390 public function processStripeSession($session, $submission, $transaction)
391 {
392 $this->setSubmissionId($submission->id);
393
394 if ($transaction->status == 'paid' && $submission->payment_status == 'paid') {
395 return $this->getReturnData();
396 }
397
398 $invoice = empty($session->subscription->latest_invoice) ? $session : $session->subscription->latest_invoice;
399
400 $paymentStatus = $this->getIntentSuccessName($invoice->payment_intent);
401
402 $this->changeSubmissionPaymentStatus($paymentStatus);
403
404 if($transaction->transaction_type == 'subscription') {
405 $subscriptions = $this->getSubscriptions();
406
407 if($subscriptions) {
408 $this->processSubscriptionSuccess($subscriptions, $invoice, $submission);
409
410 $vendorSubscription = $session->subscription;
411 if($vendorSubscription) {
412 Plan::maybeSetCancelAt($subscriptions[0], $vendorSubscription);
413 }
414 }
415 }
416
417 $this->processOneTimeSuccess($invoice, $transaction, $paymentStatus);
418
419 $returnData = $this->completePaymentSubmission(false);
420 $this->recalculatePaidTotal();
421 $returnData['is_new'] = $this->getMetaData('is_form_action_fired') === 'yes';
422
423 return $returnData;
424 }
425
426 protected function getIntentSuccessName($intent)
427 {
428 if (!$intent || !$intent->status) {
429 return false;
430 }
431
432 $successStatuses = [
433 'succeeded' => 'paid',
434 'requires_capture' => 'requires_capture'
435 ];
436
437 if (isset($successStatuses[$intent->status])) {
438 return $successStatuses[$intent->status];
439 }
440
441 return false;
442 }
443
444 protected function getDescriptor($title)
445 {
446 $illegal = array('<', '>', '"', "'");
447 // Remove slashes
448 $descriptor = stripslashes($title);
449 // Remove illegal characters
450 $descriptor = str_replace($illegal, '', $descriptor);
451 // Trim to 22 characters max
452 return substr($descriptor, 0, 22);
453 }
454
455 protected function formatAddress($address)
456 {
457 $addressArray = [
458 'line1' => $address->line1,
459 'line2' => $address->line2,
460 'city' => $address->city,
461 'state' => $address->state,
462 'postal_code' => $address->postal_code,
463 'country' => $address->country,
464 ];
465 return implode(', ', array_filter($addressArray));
466 }
467
468 public function handleRefund($event)
469 {
470 $data = $event->data->object;
471
472 $chargeId = $data->payment_intent;
473 // Get the Transaction from database
474 $transaction = Transaction::where('charge_id', $chargeId)
475 ->where('payment_method', 'stripe')
476 ->first();
477
478 if (!$transaction) {
479 // Not our transaction
480 return;
481 }
482
483 $submission = Submission::find($transaction->submission_id);
484
485 if (!$submission) {
486 return;
487 }
488
489 $this->setSubmissionId($submission->id);
490 $amountRefunded = $data->amount_refunded;
491 if (PaymentHelper::isZeroDecimal($data->currency)) {
492 $amountRefunded = $amountRefunded * 100;
493 }
494
495 // Remove All Existing Refunds
496 Transaction::bySubmission($submission->id)->refunds()->delete();
497
498 $this->refund($amountRefunded, $transaction, $submission, 'stripe', $chargeId, 'Refund from Stripe');
499
500 }
501
502 public function getPaymentMode()
503 {
504 $stripeSettings = StripeSettings::getSettings();
505 return $stripeSettings['payment_mode'];
506 }
507
508 public function processSubscriptionSuccess($subscriptions, $invoice, $submission)
509 {
510 foreach ($subscriptions as $subscription) {
511 $subscriptionStatus = 'active';
512
513 if ($subscription->trial_days) {
514 $subscriptionStatus = 'trialling';
515 }
516
517 $updateData = [
518 'vendor_customer_id' => $invoice->customer,
519 'vendor_response' => maybe_serialize($invoice),
520 ];
521
522 if(!$subscription->bill_count && $subscriptionStatus == 'active') {
523 $updateData['bill_count'] = 1;
524 }
525
526 if (!$subscription->vendor_subscription_id) {
527 $updateData['vendor_subscription_id'] = $invoice->subscription;
528 }
529
530 $this->updateSubscription($subscription->id, $updateData);
531 $subscription = fluentFormApi('submissions')->getSubscription($subscription->id);
532 $this->updateSubscriptionStatus($subscription, $subscriptionStatus);
533 }
534
535 $logData = [
536 'parent_source_id' => $submission->form_id,
537 'source_type' => 'submission_item',
538 'source_id' => $submission->id,
539 'component' => 'Payment',
540 'status' => 'success',
541 'title' => __('Stripe Subscription Charged', 'fluentform'),
542 'description' => __('Stripe recurring subscription successfully initiated', 'fluentform')
543 ];
544
545 do_action('fluentform/log_data', $logData);
546
547 if (!empty($invoice->payment_intent->charges->data[0])) {
548 $charge = $invoice->payment_intent->charges->data[0];
549 $this->recordStripeBillingAddress($charge, $submission);
550 }
551 }
552
553 protected function recordStripeBillingAddress($charge, $submission)
554 {
555 if(!is_array($submission->response)) {
556 $submission->response = json_decode($submission->response, true);
557 }
558
559 if (isset($submission->response['__checkout_billing_address_details'])) {
560 return;
561 }
562
563 if (empty($charge->billing_details)) {
564 return;
565 }
566
567 $billingDetails = $charge->billing_details;
568 if (!empty($billingDetails->address)) {
569 $submission->response['__checkout_billing_address_details'] = $billingDetails->address;
570 }
571 if (!empty($billingDetails->phone)) {
572 $submission->response['__stripe_phone'] = $billingDetails->phone;
573 }
574 if (!empty($billingDetails->name)) {
575 $submission->response['__stripe_name'] = $billingDetails->name;
576 }
577 if (!empty($billingDetails->email)) {
578 $submission->response['__stripe_email'] = $billingDetails->email;
579 }
580
581 $this->updateSubmission($submission->id, [
582 'response' => json_encode($submission->response)
583 ]);
584
585 $logData = [
586 'parent_source_id' => $submission->form_id,
587 'source_type' => 'submission_item',
588 'source_id' => $submission->id,
589 'component' => 'Payment',
590 'status' => 'info',
591 'title' => __('Stripe Billing Address Logged', 'fluentform'),
592 'description' => __('Billing address from stripe has been logged in the submission data', 'fluentform')
593 ];
594
595 do_action('fluentform/log_data', $logData);
596 }
597
598 protected function processOneTimeSuccess($invoice, $transaction, $paymentStatus)
599 {
600 if ($transaction) {
601 $updateData = [
602 'charge_id' => $invoice->payment_intent ? $invoice->payment_intent->id : null,
603 'status' => 'paid',
604 'payment_note' => maybe_serialize($invoice->payment_intent)
605 ];
606
607 $updateData = array_merge($updateData, $this->retrieveCustomerDetailsFromInvoice($invoice));
608
609 $this->updateTransaction($transaction->id, $updateData);
610
611 $this->changeTransactionStatus($transaction->id, $paymentStatus);
612 }
613 }
614
615 protected function getIntentMetaData($submission, $form, $transaction, $paymentSettings = false)
616 {
617 if (!$paymentSettings) {
618 $paymentSettings = PaymentHelper::getFormSettings($form->id, 'admin');
619 }
620
621 $intentMeta = [
622 'submission_id' => $submission->id,
623 'form_id' => $form->id,
624 'transaction_id' => $transaction->id,
625 'wp_plugin' => 'Fluent Forms Pro',
626 'form_title' => $form->title
627 ];
628
629 $metaItems = ArrayHelper::get($paymentSettings, 'stripe_meta_data', []);
630 if ((ArrayHelper::get($paymentSettings, 'push_meta_to_stripe') == 'yes') && !empty($metaItems)) {
631
632 foreach ($metaItems as $metaItem) {
633 if ($itemValue = ArrayHelper::get($metaItem, 'item_value')) {
634 $metaData[ArrayHelper::get($metaItem, 'label', 'item')] = $itemValue;
635 }
636 }
637
638 $metaData = ShortCodeParser::parse($metaData, $submission->id, $submission->response);
639
640 $metaData = array_filter($metaData);
641
642 foreach ($metaData as $itemKey => $value) {
643 if (is_string($value) || is_numeric($value)) {
644 $metaData[$itemKey] = wp_strip_all_tags($value);
645 }
646 }
647
648 $intentMeta = array_merge($intentMeta, $metaData);
649 }
650
651 return $intentMeta;
652 }
653
654 protected function retrieveCustomerDetailsFromInvoice($invoice)
655 {
656 $customer = [];
657
658 if (!empty($invoice->payment_intent->charges->data[0])) {
659 $charge = $invoice->payment_intent->charges->data[0];
660
661 $customer = $this->retrieveCustomerDetailsFromCharge($charge);
662
663 $customerName = isset($charge->billing_details->name) &&
664 !empty($charge->billing_details->name) ?
665 $charge->billing_details->name : (
666 isset($invoice->customer_name) &&
667 !empty($invoice->customer_name) ?
668 $invoice->customer_name : ''
669 );
670
671 $customer = array_merge($customer, [
672 'payer_email' => $invoice->customer_email,
673 'payer_name' => $customerName,
674 ]);
675 }
676
677 return $customer;
678 }
679
680 protected function retrieveCustomerDetailsFromCharge($charge)
681 {
682 $customer = [];
683
684 if (!empty($charge->billing_details)) {
685 $customer['billing_address'] = $this->formatAddress($charge->billing_details->address);
686 }
687
688 if (!empty($charge->shipping) && !empty($charge->shipping->address)) {
689 $customer['shipping_address'] = $this->formatAddress($charge->shipping->address);
690 }
691
692 if (!empty($charge->payment_method_details->card)) {
693 $card = $charge->payment_method_details->card;
694 $customer['card_brand'] = $card->brand;
695 $customer['card_last_4'] = $card->last4;
696 }
697
698 return $customer;
699 }
700
701 protected function handlePaymentChargeError($message, $submission, $transaction, $charge = false, $type = 'general')
702 {
703 do_action_deprecated(
704 'fluentform_payment_stripe_failed',
705 [
706 $submission,
707 $transaction,
708 $this->form->id,
709 $charge,
710 $type
711 ],
712 FLUENTFORM_FRAMEWORK_UPGRADE,
713 'fluentform/payment_stripe_failed',
714 'Use fluentform/payment_stripe_failed instead of fluentform_payment_stripe_failed.'
715 );
716
717 do_action('fluentform/payment_stripe_failed', $submission, $transaction, $this->form->id, $charge, $type);
718
719 do_action_deprecated(
720 'fluentform_payment_failed',
721 [
722 $submission,
723 $transaction,
724 $this->form->id,
725 $charge,
726 $type
727 ],
728 FLUENTFORM_FRAMEWORK_UPGRADE,
729 'fluentform/payment_failed',
730 'Use fluentform/payment_failed instead of fluentform_payment_failed.'
731 );
732 do_action('fluentform/payment_failed', $submission, $transaction, $this->form->id, $charge, $type);
733
734 if ($transaction) {
735 $this->changeTransactionStatus($transaction->id, 'failed');
736 }
737
738 $this->changeSubmissionPaymentStatus('failed');
739
740 if ($message) {
741 $logData = [
742 'parent_source_id' => $submission->form_id,
743 'source_type' => 'submission_item',
744 'source_id' => $submission->id,
745 'component' => 'Payment',
746 'status' => 'error',
747 'title' => __('Stripe Payment Error', 'fluentform'),
748 'description' => $message
749 ];
750
751 do_action('fluentform/log_data', $logData);
752 }
753
754 wp_send_json([
755 'errors' => __('Stripe Error: ', 'fluentform') . $message,
756 'append_data' => [
757 '__entry_intermediate_hash' => Helper::getSubmissionMeta($submission->id, '__entry_intermediate_hash')
758 ]
759 ], 423);
760 }
761
762 public function recordSubscriptionCharge($subscription, $transactionData)
763 {
764 $this->setSubmissionId($subscription->submission_id);
765 return $this->maybeInsertSubscriptionCharge($transactionData);
766 }
767 }
768