Your IP : 216.73.216.43


Current Path : /var/www/www.indacotrentino.com/www/vendor/stripe/module-payments/Model/
Upload File :
Current File : /var/www/www.indacotrentino.com/www/vendor/stripe/module-payments/Model/PaymentMethod.php

<?php

namespace StripeIntegration\Payments\Model;

use Magento\Framework\Exception\LocalizedException;
use Magento\Payment\Model\InfoInterface;
use StripeIntegration\Payments\Exception\GenericException;
use StripeIntegration\Payments\Exception\RefundOfflineException;
use StripeIntegration\Payments\Exception\SCANeededException;
use StripeIntegration\Payments\Helper\Data as HelperData;
use StripeIntegration\Payments\Helper\PaymentMethod as HelperPaymentMethod;

class PaymentMethod extends \Magento\Payment\Model\Method\Adapter
{
    protected $_code                 = "stripe_payments";
    protected $_isInitializeNeeded      = false;
    protected $_canUseForMultishipping  = false;
    protected $config;

    private $paymentElement;
    private $paymentIntent;
    private $multishippingHelper;
    private $refundsHelper;
    private $subscriptionsHelper;
    private $helper;
    private $stripePaymentMethod;
    private $api;
    private $paymentIntentHelper;
    private $setupIntentHelper;

    protected $helperData;
    protected $helperPaymentMethod;

    public function __construct(
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface $valueHandlerPool,
        \Magento\Payment\Gateway\Data\PaymentDataObjectFactory $paymentDataObjectFactory,
        string $code,
        string $formBlockType,
        string $infoBlockType,
        \StripeIntegration\Payments\Model\Config $config,
        \StripeIntegration\Payments\Model\PaymentElement $paymentElement,
        \StripeIntegration\Payments\Model\PaymentIntent $paymentIntent,
        \StripeIntegration\Payments\Model\Stripe\PaymentMethod $stripePaymentMethod,
        \StripeIntegration\Payments\Helper\Generic $helper,
        \StripeIntegration\Payments\Helper\Subscriptions $subscriptionsHelper,
        \StripeIntegration\Payments\Helper\Multishipping $multishippingHelper,
        \StripeIntegration\Payments\Helper\Refunds $refundsHelper,
        \StripeIntegration\Payments\Helper\Api $api,
        \StripeIntegration\Payments\Helper\PaymentIntent $paymentIntentHelper,
        \StripeIntegration\Payments\Helper\SetupIntent $setupIntentHelper,
        HelperData $helperData,
        HelperPaymentMethod $helperPaymentMethod,
        \Magento\Payment\Gateway\Command\CommandPoolInterface $commandPool = null,
        \Magento\Payment\Gateway\Validator\ValidatorPoolInterface $validatorPool = null
    ) {
        $this->config = $config;
        $this->paymentElement = $paymentElement;
        $this->paymentIntent = $paymentIntent;
        $this->stripePaymentMethod = $stripePaymentMethod;
        $this->helper = $helper;
        $this->subscriptionsHelper = $subscriptionsHelper;
        $this->multishippingHelper = $multishippingHelper;
        $this->refundsHelper = $refundsHelper;
        $this->api = $api;
        $this->paymentIntentHelper = $paymentIntentHelper;
        $this->helperData = $helperData;
        $this->helperPaymentMethod = $helperPaymentMethod;
        $this->setupIntentHelper = $setupIntentHelper;

        if ($this->helper->isMultiShipping())
            $formBlockType = 'StripeIntegration\Payments\Block\Multishipping\Billing';
        else if ($this->helper->isAdmin())
            $formBlockType = 'StripeIntegration\Payments\Block\Adminhtml\Payment\Form';
        else
            $formBlockType = 'Magento\Payment\Block\Form';

        parent::__construct(
            $eventManager,
            $valueHandlerPool,
            $paymentDataObjectFactory,
            $code,
            $formBlockType,
            $infoBlockType,
            $commandPool,
            $validatorPool
        );
    }

    public function assignData(\Magento\Framework\DataObject $data)
    {
        parent::assignData($data);

        if ($this->config->getIsStripeAPIKeyError())
            $this->helper->dieWithError("Invalid API key provided");

        $additionalData = $data->getAdditionalData();

        $info = $this->getInfoInstance();

        $this->helper->assignPaymentData($info, $additionalData);

        return $this;
    }

    public function checkIfCartIsSupported(\Magento\Payment\Model\InfoInterface $payment, $amount)
    {
        if (!$this->helper->hasTrialSubscriptions())
            return;

        if ($this->subscriptionsHelper->isZeroAmountOrder($payment->getOrder()))
            return;

        if ($payment->getOrder()->getDiscountAmount() < 0)
        {
            // The cart includes both trial subscriptions and regular products. In the case of expiring discounts, the full discount will be applied
            // on the initial payment which is incorrect. We need to apply only the discount which applies to the regular product, without applying
            // the discount that applies on the trial subscription. Currently this is not supported.
            if ($this->subscriptionsHelper->hasExpiringDiscountCoupons())
            {
                throw new LocalizedException(__("Limited-time discount coupons cannot be applied on carts that include both regular products and trial subscriptions."));
            }
        }
    }

    public function order(\Magento\Payment\Model\InfoInterface $payment, $amount)
    {
        $customer = $this->helper->getCustomerModel();
        $customer->createStripeCustomerIfNotExists(false, $payment->getOrder());

        $createParams = $this->setupIntentHelper->getCreateParams($this->helper->getQuote(), $payment->getOrder());
        $confirmParams = $this->setupIntentHelper->getConfirmParams($payment->getOrder());

        // Load the setup intent from the customer session
        $setupIntentId = $this->helper->getCheckoutSession()->getStripeSetupIntentId();
        if (!$setupIntentId)
        {
            $setupIntent = $this->config->getStripeClient()->setupIntents->create($createParams);
        }
        else
        {
            $paymentMethodId = $payment->getAdditionalInformation("token");
            $setupIntent = $this->config->getStripeClient()->setupIntents->retrieve($setupIntentId, []);
            $this->helper->getCheckoutSession()->setStripeSetupIntentId(null);

            if ($setupIntent->payment_method != $paymentMethodId)
            {
                $setupIntent = $this->config->getStripeClient()->setupIntents->create($createParams);
            }
        }

        if ($setupIntent->status == "requires_action")
        {
            // Save the setup intent ID in the customer session
            $this->helper->getCheckoutSession()->setStripeSetupIntentId($setupIntent->id);
            return $this->helper->dieWithError("Authentication Required: " . $setupIntent->client_secret);
        }
        else if ($setupIntent->status == "requires_confirmation")
        {
            $setupIntent = $this->config->getStripeClient()->setupIntents->confirm($setupIntentId, $confirmParams);
        }
        else if ($setupIntent->status == "canceled")
        {
            return $this->helper->dieWithError("The payment method could not be saved. Please try again.");
        }
        else if (in_array($setupIntent->status, ["succeeded", "processing"]))
        {
            // Processing or succeeded status
            $payment->setAdditionalInformation("customer_stripe_id", $customer->getStripeId());
            $payment->setAdditionalInformation("payment_action", $this->config->getPaymentAction());
        }
        else
        {
            throw new GenericException(__("Something went wrong. Please try again."));
        }

        return $this;
    }

    public function authorize(\Magento\Payment\Model\InfoInterface $payment, $amount)
    {
        $this->checkIfCartIsSupported($payment, $amount);

        if ($amount > 0)
        {
            if ($this->subscriptionsHelper->isSubscriptionUpdate())
            {
                $this->subscriptionsHelper->updateSubscription($payment);
            }
            else if ($this->helper->isMultiShipping())
            {
                $this->doNotPay($payment);
            }
            else if ($payment->getAdditionalInformation('is_migrated_subscription'))
            {
                $this->doNotPay($payment);
            }
            else
            {
                $this->pay($payment, $amount);
            }
        }

        return $this;
    }

    public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount)
    {
        $this->checkIfCartIsSupported($payment, $amount);

        if ($amount > 0)
        {
            // We get in here when the store is configured in Authorize Only mode and we are capturing a payment from the admin
            $token = $payment->getTransactionId();
            if (empty($token))
            {
                $token = $payment->getLastTransId(); // In case where the transaction was not created during the checkout, i.e. with a Stripe Webhook redirect
            }

            if ($payment->getAdditionalInformation('payment_action') == "order")
            {
                $this->api->createNewCharge($payment, $amount);
            }
            else if ($token)
            {
                // Capture an authorized payment from the admin area

                $token = $this->helper->cleanToken($token);

                $orders = $this->helper->getOrdersByTransactionId($token);
                $quoteId = (($payment->getOrder() && $payment->getOrder()->getQuoteId()) ? $payment->getOrder()->getQuoteId() : null);
                if (count($orders) > 1 && $this->multishippingHelper->isMultishippingQuote($quoteId))
                    $this->multishippingHelper->captureOrdersFromAdminArea($orders, $token, $payment, $amount, $this->config->retryWithSavedCard());
                else
                    $this->helper->capture($token, $payment, $amount, $this->config->retryWithSavedCard());
            }
            else if ($payment->getAdditionalInformation('is_migrated_subscription'))
            {
                return $this->helper->dieWithError(__("It is not possible to capture subscription orders that were created from the CLI."));
            }
            else if ($this->helper->isAdmin() && $payment->getOrder()->getState() == "pending_payment")
            {
                return $this->helper->dieWithError(__("It is not possible to capture the payment because the transaction has not yet been authorized."));
            }
            else if ($this->subscriptionsHelper->isSubscriptionUpdate())
            {
                $this->subscriptionsHelper->updateSubscription($payment);
            }
            else if ($this->helper->isMultiShipping())
            {
                $this->doNotPay($payment);
            }
            else
            {
                $this->pay($payment, $amount);
            }
        }

        return $this;
    }

    public function doNotPay(\Magento\Payment\Model\InfoInterface $payment)
    {
        $payment->setIsFraudDetected(false);
        $payment->setIsTransactionPending(true); // not authorized yet
        $payment->setIsTransactionClosed(false); // not captured
        $payment->getOrder()->setCanSendNewEmailFlag(false);
    }

    public function pay(InfoInterface $payment, $amount)
    {
        if ($payment->getAdditionalInformation("is_recurring_subscription"))
            return $this;

        if (!$payment->getAdditionalInformation("token"))
            return $this->helper->dieWithError(__("Cannot place order because a payment method was not provided."));

        try
        {
            // Update the payment intent by loading it from cache - the load method with update it if its different.
            $this->paymentElement->fromQuoteId($payment->getOrder()->getQuoteId());
            $this->paymentElement->updateFromOrder($payment->getOrder(), $payment->getAdditionalInformation("token"));
            $this->paymentElement->cancelInvalidOrders($payment->getOrder());

            $result = $this->paymentElement->confirm($payment->getOrder());

            if ($result && isset($result->charges->data[0])) {
                $this->helperData->setRiskDataToOrder($result, $payment->getOrder());
                $this->helperPaymentMethod->insertPaymentMethods($result, $payment->getOrder());
            }

            if (!empty($result->client_secret)) // Trial subscriptions will not have a client secret
            {
                $payment->setAdditionalInformation("client_secret", $result->client_secret);
            }
        }
        catch (\Exception $e)
        {
            $this->helper->sendPaymentFailedEmail($this->helper->getQuote(), $e->getMessage());
            throw $e;
        }

        if ($this->paymentIntent->requiresAction($result))
        {
            if ($this->helper->isAdmin())
            {
                return $this->helper->dieWithError(__("This payment method cannot be used because it requires a customer authentication. To avoid authentication in the admin area, please contact Stripe support to request access to the MOTO gate for your Stripe account."));
            }

            if ($this->shouldAuthenticateManually($payment, $result))
            {
                // Certain versions of Magento such as 2.4.4 and 2.4.6 cause order increment ID skipping after a payment failure.
                // We save the quote so that the order increment ID is saved. We intentionally do not use the quotes repository,
                // because that triggers a bug in older versions of Magento (2.4.2), where configurable products with a QTY of 1
                // would fail order placement with an error that the product quantity is not available.
                $this->helper->getQuote()->save();

                return $this->helper->dieWithError("Authentication Required: {$result->client_secret}");
            }

            $this->paymentIntent->processPendingOrder($payment->getOrder(), $result);
        }
        else if ($this->paymentElement->isTrialSubscription())
        {
            $this->paymentIntent->processTrialSubscriptionOrder($payment->getOrder(), $this->paymentElement->getSubscription());
        }
        else if ($this->paymentElement->getPaymentIntent())
        {
            if ($this->paymentIntentHelper->isSuccessful($result))
            {
                $this->paymentIntent->processSuccessfulOrder($payment->getOrder(), $result);
            }
            else
            {
                $this->paymentIntent->processPendingOrder($payment->getOrder(), $result);
            }
            $payment->setAdditionalInformation("server_side_transaction_id", $result->id);
        }
        else if ($this->paymentElement->getSetupIntent())
        {
            $this->paymentIntent->processPendingOrder($payment->getOrder(), $result);
        }
        else if ($result->object == "subscription" && empty($result->latest_invoice))
        {
            // The subscription starts at a future date
            $this->paymentIntent->processFutureSubscriptionOrder($payment->getOrder(), $result);
        }
    }

    public function shouldAuthenticateManually($payment, $intent)
    {
        if (!$payment->getAdditionalInformation("payment_element"))
        {
            // Backwards compatible front-end case (Payment Request API, REST API, GraphQL API), this will trigger the 3DS modal.
            return true;
        }

        if ($payment->getAdditionalInformation("manual_authentication"))
        {
            $methods = explode(",", $payment->getAdditionalInformation("manual_authentication"));

            // Added from v3.4.0 for manual customer authentication
            if (!empty($intent->payment_method) && is_string($intent->payment_method))
            {
                $paymentMethod = $this->stripePaymentMethod->fromPaymentMethodId($intent->payment_method)->getStripeObject();

                if (in_array($paymentMethod->type, $methods))
                {
                    return true;
                }
            }
        }

        return false;
    }

    public function cancel(InfoInterface $payment, $amount = null)
    {
        if ($payment->getCancelOfflineWithComment())
        {
            $this->helper->overrideCancelActionComment($payment, $payment->getCancelOfflineWithComment());
            return $this;
        }

        try
        {
            $paymentIntentId = $this->refundsHelper->getTransactionId($payment);
            $paymentIntent = $this->config->getStripeClient()->paymentIntents->retrieve($paymentIntentId, []);

            if ($this->multishippingHelper->isMultishippingPayment($paymentIntent) && $paymentIntent->status == "requires_capture")
            {
                $this->refundsHelper->refundMultishipping($paymentIntent, $payment, $amount);
            }
            else
            {
                $this->refundsHelper->refund($payment, $amount);
            }
        }
        catch (RefundOfflineException $e)
        {
            if ($this->helper->isAdmin())
            {
                $this->helper->addWarning($e->getMessage());
            }

            if ($this->refundsHelper->isCancelation($payment))
                $this->helper->overrideCancelActionComment($payment, $e->getMessage());
            else
                $this->helper->addOrderComment($e->getMessage(), $payment->getOrder());
        }
        catch (\Exception $e)
        {
            $this->helper->dieWithError(__('Could not refund payment: %1', $e->getMessage()), $e);
        }

        return $this;
    }

    public function cancelInvoice($invoice)
    {
        return $this;
    }

    public function refund(InfoInterface $payment, $amount)
    {
        $this->cancel($payment, $amount);

        return $this;
    }

    public function void(InfoInterface $payment)
    {
        $this->cancel($payment);

        return $this;
    }

    public function acceptPayment(InfoInterface $payment)
    {
        return parent::acceptPayment($payment);
    }

    public function denyPayment(InfoInterface $payment)
    {
        return parent::denyPayment($payment);
    }

    public function canCapture()
    {
        return parent::canCapture();
    }

    public function isApplePay()
    {
        $info = $this->getInfoInstance();
        if ($info)
            return $info->getAdditionalInformation("is_prapi");

        return false;
    }

    public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null)
    {
        if ($quote && $quote->getIsRecurringOrder())
            return true;

        if ($this->subscriptionsHelper->isSubscriptionUpdate())
            return true;

        if (!$this->config->isEnabled())
            return false;

        if ($this->helper->isAdmin())
            return parent::isAvailable($quote);

        if ($this->config->isRedirectPaymentFlow() && !$this->isApplePay() && !$this->helper->isMultiShipping())
            return false;

        return parent::isAvailable($quote);
    }

    public function getConfigPaymentAction()
    {
        $info = $this->getInfoInstance();
        if ($info && $info->getAdditionalInformation("is_migrated_subscription") ||
            $this->subscriptionsHelper->isSubscriptionUpdate())
        {
            return \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE;
        }

        // Subscriptions do not support authorize only mode
        if ($this->helper->hasSubscriptions())
        {
            return \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE_CAPTURE;
        }

        return $this->config->getPaymentAction();
    }

    public function canEdit()
    {
        $info = $this->getInfoInstance();

        if (!empty($info->getTransactionId()))
            return false;

        if (!empty($info->getLastTransId()))
            return false;

        if (empty($info->getAdditionalInformation("token")))
            return false;

        if (empty($info->getAdditionalInformation("customer_stripe_id")))
            return false;

        $token = $info->getAdditionalInformation("token");

        if (strpos($token, "pm_") !== 0)
            return false;

        return true;
    }
}