PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.1
1.7.1 1.7.0 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 All 51 releases
← All changes | app/Modules/PaymentMethods/StripeGateway/Stripe.php +55 -23 1.6.2 → 1.7.1 View file →
@@ -55,9 +55,9 @@
55 55
56 56 public function meta(): array
57 57 {
58 58 return [
59 - 'title' => 'Card',
59 + 'title' => __('Card', 'fluent-cart'),
60 60 'route' => 'stripe',
61 61 'slug' => 'stripe',
62 62 'label' => 'Stripe',
63 63 'admin_title' => 'Stripe',
@@ -91,8 +91,9 @@
91 91 'description' => $storeName . ' #' . $order->invoice_no, // @todo: We will replace with order summary with item names later
92 92 'customer_email' => $paymentInstance->order->email,
93 93 'success_url' => $paymentInstance->transaction->getSuccessUrl(),
94 94 'gateway_return_url' => Processor::getOnsiteGatewayReturnUrl($paymentInstance->transaction),
95 + 'trx_hash' => $paymentInstance->transaction->uuid,
95 96 'custom_payment_url' => PaymentHelper::getCustomPaymentLink($paymentInstance->order->uuid)
96 97 );
97 98
98 99 if ($paymentInstance->subscription) {
@@ -480,8 +481,11 @@
480 481 'redirecting for action' => __('redirecting for action', 'fluent-cart'),
481 482 'You will be redirected to Stripe to complete your payment securely.' => __('You will be redirected to Stripe to complete your payment securely.', 'fluent-cart'),
482 483 'Something went wrong' => __('Something went wrong', 'fluent-cart'),
483 484 'Payment confirmation failed' => __('Payment confirmation failed', 'fluent-cart'),
485 + 'Payment failed. Please try again.' => __('Payment failed. Please try again.', 'fluent-cart'),
486 + 'We could not record that failed attempt. Please reload the page before trying again.' => __('We could not record that failed attempt. Please reload the page before trying again.', 'fluent-cart'),
487 + 'We could not verify your payment status. Please do not pay again. Contact the store to check your order status.' => __('We could not verify your payment status. Please do not pay again. Contact the store to check your order status.', 'fluent-cart'),
484 488 ]
485 489 ]
486 490 ];
487 491 }
@@ -635,8 +639,23 @@
635 639 ],
636 640 'tooltip' => __('Choose between Embedded and Hosted checkout modes. Embedded mode is recommended for most use cases. For Bank transfers, use Hosted mode. (checkout.session.completed webhook event will be triggered only for hosted mode)', 'fluent-cart'),
637 641 'description' => __("Embedded checkout is recommended for most use cases. For Bank transfers , or if any payment methods are not showing up on embedded checkout, try Hosted checkout. ('checkout.session.completed' webhook event will be triggered only for hosted checkout)", 'fluent-cart')
638 642 ),
643 + 'submit_type' => array(
644 + 'value' => 'auto',
645 + 'label' => __('Submit Button Label', 'fluent-cart'),
646 + 'type' => 'select',
647 + 'filterable' => false,
648 + 'options' => [
649 + ['value' => 'auto', 'label' => __('Automatic (Pay / Subscribe)', 'fluent-cart')],
650 + ['value' => 'pay', 'label' => __('Pay', 'fluent-cart')],
651 + ['value' => 'book', 'label' => __('Book', 'fluent-cart')],
652 + ['value' => 'donate', 'label' => __('Donate', 'fluent-cart')],
653 + ['value' => 'subscribe', 'label' => __('Subscribe', 'fluent-cart')],
654 + ],
655 + 'tooltip' => __('Stripe customises the submit button and surrounding copy from this. Applies to Stripe Hosted Checkout only.', 'fluent-cart'),
656 + 'description' => __('Applies to Stripe Hosted Checkout only, and is ignored when a card is being saved without a charge. Automatic gives one-time orders the "Buy" button and subscriptions the "Subscribe" button.', 'fluent-cart')
657 + ),
639 658 'webhook_desc' => array(
640 659 'value' => Webhook::webhookInstruction(),
641 660 'label' => __('Webhook URL', 'fluent-cart'),
642 661 'type' => 'html_attr'
@@ -789,13 +808,11 @@
789 808 ], 422);
790 809 }
791 810
792 811 $paymentArgs['public_key'] = $publicKey;
812 + $appearance = $this->getElementsAppearance();
813 + $fonts = $this->getElementsFonts();
793 814
794 - // Allow filtering the appearance configuration for Stripe Elements
795 - $appearance = ['theme' => 'stripe'];
796 - $appearance = apply_filters('fluent_cart/stripe_appearance', $appearance);
797 -
798 815 $storeCurrency = CurrencySettings::get('currency');
799 816 $intentAmount = (int)$totalPrice;
800 817
801 818 if ($storeCurrency && CurrenciesHelper::isZeroDecimal($storeCurrency)) {
@@ -826,11 +843,13 @@
826 843 // mode — a zero-amount payment mode is invalid — and consent becomes a
827 844 // required checkbox: without a saved card the trial can never bill.
828 845 $payableNow = \FluentCart\App\Services\OrderService::getItemsAmountTotal($cart->cart_data ?? [], false, false);
829 846 if ($payableNow <= 0) {
847 + // Match the SetupIntent usage even when the optional save-card flag is set.
830 848 $intentData = [
831 - 'mode' => 'setup',
832 - 'currency' => strtolower($storeCurrency),
849 + 'mode' => 'setup',
850 + 'currency' => strtolower($storeCurrency),
851 + 'setup_future_usage' => 'off_session',
833 852 ];
834 853 $consentRequired = true;
835 854 }
836 855 }
@@ -841,22 +860,20 @@
841 860 } elseif (empty($intentData['setup_future_usage']) && Arr::get($data, 'save_payment_method') === 'yes') {
842 861 $intentData['setup_future_usage'] = 'on_session';
843 862 }
844 863
845 - // The browser cannot pass setup_future_usage per-request (this endpoint
846 - // receives no body), so extensions that vault cards (e.g. saved payment
847 - // methods) resolve it here, server-side. Must be matched on the actual
848 - // PaymentIntent at place-order (fluent_cart/payments/stripe_onetime_intent_args)
849 - // or Stripe rejects the confirmation for a setup_future_usage mismatch.
850 - $setupFutureUsage = apply_filters(
851 - 'fluent_cart/stripe/client_setup_future_usage',
852 - Arr::get($intentData, 'setup_future_usage'),
853 - ['data' => $data, 'has_subscription' => $hasSubscription]
854 - );
855 - if ($setupFutureUsage) {
856 - $intentData['setup_future_usage'] = $setupFutureUsage;
857 - } else {
858 - unset($intentData['setup_future_usage']);
864 + // a one-time payment may be changed here.
865 + if ($intentData['mode'] === 'payment') {
866 + $setupFutureUsage = apply_filters(
867 + 'fluent_cart/stripe/client_setup_future_usage',
868 + Arr::get($intentData, 'setup_future_usage'),
869 + ['data' => $data, 'has_subscription' => $hasSubscription]
870 + );
871 + if ($setupFutureUsage) {
872 + $intentData['setup_future_usage'] = $setupFutureUsage;
873 + } else {
874 + unset($intentData['setup_future_usage']);
875 + }
859 876 }
860 877
861 878 wp_send_json(
862 879 [
@@ -865,8 +882,9 @@
865 882 'data' => [],
866 883 'payment_args' => $paymentArgs,
867 884 'intent' => $intentData,
868 885 'appearance' => $appearance,
886 + 'fonts' => $fonts,
869 887 'system_consent' => $systemConsent,
870 888 'consent_required' => $consentRequired,
871 889 ],
872 890 200
@@ -872,8 +890,22 @@
872 890 200
873 891 );
874 892 }
875 893
894 + public function getElementsAppearance(): array
895 + {
896 + $appearance = ['theme' => 'stripe'];
897 +
898 + return (array) apply_filters('fluent_cart/stripe_appearance', $appearance);
899 + }
900 +
901 + public function getElementsFonts(): array
902 + {
903 + $fonts = (array) apply_filters('fluent_cart/stripe_elements_fonts', []);
904 +
905 + return array_values(array_filter($fonts, 'is_array'));
906 + }
907 +
876 908 public function getConnectInfo(): array
877 909 {
878 910 return ConnectConfig::getConnectConfig();
879 911 }
@@ -895,9 +927,9 @@
895 927 public function acceptRemoteDispute($transaction, $args = [])
896 928 {
897 929 $disputeId = Arr::get($transaction->meta, 'dispute_id');
898 930 if (!$disputeId) {
899 - $charge = (new API())->getStripeObject('payment_intents/' . $transaction->vendor_charge_id, ['expand' => ['latest_charge']]);
931 + $charge = (new API())->getStripeObject('payment_intents/' . $transaction->vendor_charge_id, ['expand' => ['latest_charge']], $transaction->payment_mode);
900 932
901 933 if (is_wp_error($charge) || empty($charge['dispute'])) {
902 934 new \WP_Error('No dispute ID found!', __('Please check stripe if the dispute is already accepted or not!', 'fluent-cart'));
903 935 }
@@ -904,9 +936,9 @@
904 936
905 937 $disputeId = Arr::get($charge, 'dispute', '');
906 938 }
907 939
908 - $closeDispute = (new API())->createStripeObject('disputes/' . $disputeId . '/close');
940 + $closeDispute = (new API())->createStripeObject('disputes/' . $disputeId . '/close', [], $transaction->payment_mode);
909 941
910 942 if (is_wp_error($closeDispute)) {
911 943 return $closeDispute;
912 944 }