Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/job-board.corals.io/Corals/modules/Subscriptions/Classes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/job-board.corals.io/Corals/modules/Subscriptions/Classes/Subscription.php
<?php

namespace Corals\Modules\Subscriptions\Classes;


use Carbon\Carbon;
use Corals\Modules\Payment\Common\Message\AbstractResponse;
use Corals\Modules\Payment\Payment;
use Corals\Modules\Subscriptions\Events\SubscriptionCreated;
use Corals\Modules\Subscriptions\Facades\SubscriptionsManager;
use Corals\Modules\Subscriptions\Models\Plan;
use Corals\User\Models\User;

class Subscription
{
    public $gateway;

    /**
     * Subscriptions constructor.
     * @param $gateway_key
     * @param array $params
     * @throws \Exception
     */
    function __construct($gateway_key, array $params = [])
    {
        $gateway = Payment::create($gateway_key);
        $config = config('payment_' . strtolower($gateway_key));
        if (!$config) {
            throw new \Exception(trans('Subscriptions::exception.subscription.invalid_gateway'));
        }

        $this->gateway = $gateway;

        $this->gateway->setAuthentication();

        foreach ($params as $key => $value) {
            $this->gateway->setParameter($key, $value);
        }
    }

    /**
     * @param User $user
     * @param array $extra_params
     * @return bool
     * @throws \Exception
     */
    public function createCustomer(User $user, $extra_params = [])
    {
        $parameters = $this->gateway->prepareCustomerParameters($user, $extra_params);

        \Actions::do_action('pre_create_customer', $this, $user, $parameters);

        $parameters = \Filters::do_filter('create_customer_parameters', $parameters, $user, $this->gateway);

        $request = $this->gateway->createCustomer($parameters);

        // check if gateway support create/update customer request
        if ($request) {
            $response = $request->send();
            if ($response->isSuccessful()) {
                //"Gateway createCustomer was successful.\n";
                // Find the customer ID and update user if not null
                $customer_id = $response->getCustomerReference();
                $payment_method_token = "";
                if ($this->gateway->getConfig('capture_payment_method')) {
                    $payment_method_token = $response->getPaymentMethodReference();
                }
                $user->update([
                    'integration_id' => $customer_id,
                    'payment_method_token' => $payment_method_token,
                    'gateway' => $this->gateway->getName()
                ]);

                \Actions::do_action('post_create_customer', $this, $user, $response);

                return $customer_id;
            } else {
                throw new \Exception(trans('Subscriptions::exception.subscription.create_customer_failed',
                    ['message' => $response->getMessage()]));
            }
        } else {
            return true;
        }
    }

    /**
     * @param User $user
     * @param array $extra_params
     * @return bool
     * @throws \Exception
     */
    public function updateCustomer(User $user, $extra_params = [])
    {
        $parameters = $this->gateway->prepareCustomerParameters($user, $extra_params);

        \Actions::do_action('pre_update_customer', $this, $user, $parameters);

        $parameters = \Filters::do_filter('update_customer_parameters', $parameters, $user, $this->gateway);


        $request = $this->gateway->updateCustomer($parameters);

        // check if gateway support create/update customer request
        if ($request) {
            $response = $request->send();

            if ($response->isSuccessful()) {
                //"Gateway updateCustomer was successful.\n";
                // Find the customer ID and update user if not null
                $customer_id = $response->getCustomerReference();
                $payment_method_token = '';
                if ($this->gateway->getConfig('capture_payment_method')) {
                    $payment_method_token = $response->getPaymentMethodReference();
                }
                $user->update([
                    'integration_id' => $customer_id,
                    'payment_method_token' => $payment_method_token,
                    'gateway' => $this->gateway->getName()
                ]);

                if ($this->gateway->getConfig('require_default_payment_set')) {
                    $parameters = $this->gateway->prepareCustomerParameters($user);
                    $request = $this->gateway->updateCustomer($parameters);

                    $this->gateway->updateCustomer($parameters);
                    $response = $request->send();
                    if (!$response->isSuccessful()) {
                        throw new \Exception(trans('Subscriptions::exception.subscription.payment_set_failed',
                            ['message' => $response->getMessage()]));
                    }
                }

                \Actions::do_action('post_update_customer', $this, $response, $user);

                return $customer_id;
            } else {
                throw new \Exception(trans('Subscriptions::exception.subscription.update_customer_failed',
                    ['message' => $response->getMessage()]));
            }
        } else {
            return true;
        }
    }

    /**
     * @return mixed
     */
    public function fetchCustomer()
    {
    }

    /**
     * @param User $user
     * @param array $extra_params
     * @return bool
     * @throws \Exception
     */
    public function deleteCustomer(User $user, $extra_params = [])
    {
        $parameters = $this->gateway->prepareCustomerParameters($user, $extra_params = []);

        \Actions::do_action('pre_delete_customer', $this, $user, $parameters);

        $parameters = \Filters::do_filter('delete_customer_parameters', $parameters, $user, $this->gateway);

        $request = $this->gateway->deleteCustomer(array_merge($parameters, $extra_params));
        // check if gateway support create/update/delete customer request
        if ($request) {
            $response = $request->send();

            if ($response->isSuccessful()) {
                //"Gateway deleteCustomer was successful.\n";
                // Find the customer ID and update user if not null
                \Actions::do_action('post_delete_customer', $this, $response, $user);

                return true;
            } else {
                throw new \Exception(trans('Subscriptions::exception.subscription.delete_customer_failed',
                    ['message' => $response->getMessage()]));
            }
        } else {
            return true;
        }
    }

    /**
     * @param Plan $plan
     * @param User|null $user
     * @return bool
     * @throws \Exception
     */
    public function createSubscription(Plan $plan, User $user = null, $subscription_data = null)
    {
        if (is_null($user)) {
            $user = user();
        }

        $trial_ends_at = null;
        $subscription = null;


        $parameters = $this->gateway->prepareSubscriptionParameters($plan, $user, null, $subscription_data);

        \Actions::do_action('pre_create_subscription', $this, $user, $parameters, $plan);

        $parameters = \Filters::do_filter('create_subscription_parameters', $parameters, $user, $plan, $this->gateway);

        $request = $this->gateway->createSubscription($parameters);
        $response = $request->send();
        if ($response->isSuccessful()) {
            // Subscription was created successful
            if (!empty($plan->trial_period)) {
                $trial_ends_at = Carbon::now()->addDays($plan->trial_period);
            }
            $subscriber_data = [
                'plan_id' => $plan->id,
                'gateway' => $this->gateway->getName(),
                'subscription_reference' => $response->getSubscriptionReference(),
                'trial_ends_at' => $trial_ends_at,
                'properties' => [
                    'notes' => data_get($subscription_data, 'notes'),
                ]
            ];

            if (!$this->gateway->supportCards()) {
                $subscriber_data['properties']['redirect_payment_url'] = $response->getRedirectPaymentURL();
                $subscriber_data['properties']['subscription_identifier_code'] = session()->get('subscription_identifier_code');
            }


            if ($this->gateway->getConfig('default_subscription_status')) {
                $subscriber_data['status'] = $this->gateway->getConfig('default_subscription_status');
            }

            $subscription = $user->subscriptions()->create($subscriber_data);

            $this->fireSubscriptionCreatedEvent($subscription, $this->gateway, $response);

            $user->update([
                'trial_ends_at' => $trial_ends_at
            ]);

            event('notifications.subscription.created', ['user' => $user, 'subscription' => $subscription]);
            \Actions::do_action('post_create_subscription', $subscription);
        } else {
            throw new \Exception(trans('Subscriptions::exception.subscription.create_subscription_failed',
                ['message' => $response->getMessage()]));
        }


        return $subscription;
    }

    /**
     * @return mixed
     */
    public function fetchSubscription()
    {
    }

    /**
     * @param Plan $plan
     * @param User $user
     * @return mixed
     * @throws \Exception
     */
    public function createSubscriptionToken(Plan $plan, User $user)
    {
        $parameters = $this->gateway->prepareSubscriptionTokenParameters($plan, $user);

        $request = $this->gateway->prepareSubscription($parameters);

        $response = $request->send();


        if ($response->isSuccessful()) {
            $token = $response->getSubscriptionTokenReference();
            return $token;
        } else {
            throw new \Exception(trans('Subscriptions::exception.subscription.create_subscription_token_failed',
                ['message' => $response->getDataText()]));
        }
    }


    /**
     * @param Plan $plan
     * @param User|null $user
     * @param null $subscription_data
     * @return bool
     * @throws \Exception
     */
    public function swapSubscription(Plan $plan, User $user = null, $subscription_data = null)
    {
        if (is_null($user)) {
            $user = user();
        }

        $product_subscription = $user->currentSubscription($plan->product_id);

        if (!$product_subscription) {
            throw new \Exception(trans('Subscriptions::exception.subscription.invalid_subscription'));
        }

        \Actions::do_action('pre_swap_subscription', $user, $plan);


        $trial_ends_at = $product_subscription->trial_ends_at;

        if ($product_subscription->onGracePeriod() && !$this->gateway->getConfig('supports_swap_in_grace_period')) {
            $product_subscription->markAsCancelled();

            $subscription = $this->createSubscription($plan, $user);
        } else {
            $parameters = $this->gateway->prepareSubscriptionParameters($plan, $user, $product_subscription, $subscription_data);

            $parameters = \Filters::do_filter('swap_subscription_parameters', $parameters, $user, $plan,
                $product_subscription, $this->gateway);

            if ($this->gateway->getConfig('supports_swap')) {
                $request = $this->gateway->updateSubscription($parameters);
            } else {
                $this->cancelSubscription($product_subscription->plan, $user);
                $request = $this->gateway->createSubscription($parameters);
            }


            $response = $request->send();

            if ($response->isSuccessful()) {
                $product_subscription->markAsCancelled();

                $subscriber_data = [
                    'plan_id' => $plan->id,
                    'subscription_reference' => $response->getSubscriptionReference(),
                    'trial_ends_at' => $trial_ends_at,
                    'gateway' => $this->gateway->getName(),
                    'properties' => [
                        'notes' => data_get($subscription_data, 'notes')
                    ]
                ];

                if ($this->gateway->getConfig('default_subscription_status')) {
                    $subscriber_data['status'] = $this->gateway->getConfig('default_subscription_status');
                }

                if (!$this->gateway->supportCards()) {
                    $subscriber_data['properties']['redirect_payment_url'] = $response->getRedirectPaymentURL();
                    $subscriber_data['properties']['subscription_identifier_code'] = session()->get('subscription_identifier_code');
                }

                $subscription = $user->subscriptions()->create($subscriber_data);

                $this->fireSubscriptionCreatedEvent($subscription, $this->gateway, $response);

                event('notifications.subscription.swapped',
                    ['user' => $user, 'subscription' => $subscription, 'old_subscription' => $product_subscription]);
            } else {
                throw new \Exception(trans('Subscriptions::exception.subscription.update_subscription_failed',
                    ['message' => $response->getMessage()]));
            }
        }

        \Actions::do_action('post_swap_subscription', $user, $plan, $subscription);

        return $subscription;
    }

    /**
     * @param Plan $plan
     * @param User|null $user
     * @return bool
     * @throws \Exception
     */
    public function cancelSubscription(Plan $plan, User $user = null)
    {
        if (is_null($user)) {
            $user = user();
        }

        $plan_subscription = $user->currentSubscription(null, $plan->id);

        if (!$plan_subscription) {
            throw new \Exception(trans('Subscriptions::exception.subscription.invalid_subscription'));
        }

        \Actions::do_action('pre_cancel_subscription', $user, $plan);

        $isSelfManaged = $this->gateway->getConfig('subscription_self_managed');

        $response = null;

        if (!$isSelfManaged) {
            $parameters = $this->gateway->prepareSubscriptionCancellationParameters($user, $plan_subscription);

            $parameters = \Filters::do_filter('cancel_subscription_parameters', $parameters, $user, $plan_subscription,
                $this->gateway);

            $request = $this->gateway->cancelSubscription($parameters);

            $response = $request->send();
        }

        if ($isSelfManaged || ($response && $response->isSuccessful())) {
            if ($plan_subscription->status === 'pending') {
                $ends_at = now();
            } elseif ($plan_subscription->onTrial()) {
                $ends_at = $plan_subscription->trial_ends_at;
            } else {
                $current_period_end = $response ? $response->getCurrentPeriodEndReference() : (($nextCycleDate = $plan_subscription->getNextCycleDate()) ? $nextCycleDate->timestamp : null);
                $ends_at = Carbon::createFromTimestamp($current_period_end);
            }

            $plan_subscription->update([
                'ends_at' => $ends_at,
                'status' => 'canceled'
            ]);

            $invoice = $plan_subscription->invoice;

            if ($invoice && $invoice->status != 'paid') {
                $invoice->markAsCancelled();
            }

            event('notifications.subscription.cancelled', ['user' => $user, 'subscription' => $plan_subscription]);

            \Actions::do_action('post_cancel_subscription', $plan_subscription);
            return true;
        } else {
            throw new \Exception(trans('Subscriptions::exception.subscription.cancel_subscription_failed',
                ['message' => $response ? $response->getMessage() : 'Not self managed and no gateway response.']));
        }
    }

    /**
     * @param Plan $plan
     * @return mixed
     * @throws \Exception
     */
    public function createPlan(Plan $plan)
    {
        \Actions::do_action('pre_create_plan', $plan, $this->gateway);

        $parameters = $this->gateway->preparePlanParameters($plan);

        $parameters = \Filters::do_filter('create_plan_parameters', $parameters, $plan, $this->gateway);


        $request = $this->gateway->createPlan($parameters);

        $response = $request->send();

        if ($response->isSuccessful()) {
            // Plan was created successful
            $planId = $response->getPlanId();
            $plan->setGatewayStatus($this->gateway->getName(), 'CREATED', null, $planId);

            if ($this->gateway->getConfig('require_plan_activation')) {
                $parameters = $this->gateway->preparePlanActivationParameters($plan);
                $request = $this->gateway->activatePlan($parameters);
                $response = $request->send();
            }

            \Actions::do_action('post_create_plan', $plan, $this->gateway);

            if (!$response->isSuccessful()) {
                $message = trans('Subscriptions::exception.subscription.update_gateway_status_failed',
                    ['message' => $response->getMessage()]);
                throw new \Exception($message);
            }
        } else {
            // Create Plan failed
            $message = trans('Subscriptions::exception.subscription.create_gateway_fail',
                ['message' => $response->getMessage()]);

            $plan->setGatewayStatus($this->gateway->getName(), 'CREATE_FAILED', $message);

            throw new \Exception($message);
        }
    }

    /**
     * @param Plan $plan
     * @return mixed
     * @throws \Exception
     */
    public function updatePlan(Plan $plan)
    {
        \Actions::do_action('pre_update_plan', $plan, $this->gateway);

        $parameters = $this->gateway->preparePlanParameters($plan);
        $parameters = \Filters::do_filter('update_plan_parameters', $parameters, $plan, $this->gateway);

        $request = $this->gateway->updatePlan($parameters);

        $response = $request->send();

        if ($response->isSuccessful()) {
            // Plan was created successful
            $plan->setGatewayStatus($this->gateway->getName(), 'UPDATED');

            \Actions::do_action('post_update_plan', $plan, $this->gateway);

            return $response->getPlanId();
        } else {
            // Create Plan failed
            $message = trans('Subscriptions::exception.subscription.update_gateway_plan_failed',
                ['message' => $response->getMessage()]);

            $plan->setGatewayStatus($this->gateway->getName(), 'UPDATE_FAILED', $message);

            throw new \Exception($message);
        }
    }

    /**
     * @param Plan $plan
     * @param $gateway
     * @return bool
     */
    public function fetchPlan(Plan $plan, $gateway, $throwException = true)
    {
        \Actions::do_action('pre_fetch_plan', $plan, $this->gateway);

        $parameters = $this->gateway->preparePlanParameters($plan);
        $parameters = \Filters::do_filter('fetch_plan_parameters', $parameters, $plan, $this->gateway);

        $request = $this->gateway->fetchPlan($parameters);

        $response = $request->send();

        if ($response->isSuccessful()) {
            // Plan was created successful
            $data = $response->getData();
            $data = \Filters::do_filter('fetch_plan_response', $data, $plan, $this->gateway);

            \Actions::do_action('post_fetch_plan', $plan, $this->gateway);

            return $data;
        } else {
            if ($throwException) {
                // Fetch Plan failed
                $message = trans('Subscriptions::exception.subscription.fetch_gateway_plan_failed',
                    ['message' => $response->getMessage()]);
                log_exception(null, 'requested plan: ' . $plan->name, 'fetchPlan', $message);
                session()->forget('flash_notification');
            }


            return false;
        }
    }

    /**
     * @param $plan
     * @param $gateway
     * @return bool
     */
    public function deletePlan($plan, $gateway)
    {
        $parameters = $this->gateway->preparePlanParameters($plan);

        \Actions::do_action('pre_delete_plan', $plan, $this->gateway);

        $parameters = \Filters::do_filter('delete_plan_parameters', $parameters, $plan, $this->gateway);

        $request = $this->gateway->deletePlan($parameters);

        $response = $request->send();

        if ($response->isSuccessful()) {
            // Plan was created successful
            $plan->setGatewayStatus($this->gateway->getName(), 'DELETED');

            \Actions::do_action('post_delete_plan', $plan, $this->gateway);

            return $response->getData();
        } else {
            // Create Plan failed
            $message = trans('Subscriptions::exception.subscription.delete_gateway_failed',
                ['message' => $response->getMessage()]);

            $plan->setGatewayStatus($this->gateway->getName(), 'DELETE_FAILED', $message);

            log_exception(null, 'requested plan: ' . $plan->name, 'deletePlan', $message);

            return false;
        }
    }

    /**
     * @param User|null $user
     * @param Plan $plan
     * @return mixed
     * @throws \Exception
     */
    public function createInvoice(User $user = null, Plan $plan)
    {
        if (is_null($user)) {
            $user = user();
        }

        \Actions::do_action('pre_create_invoice', $plan, $user, $this->gateway);

        $attributes = $this->gateway->prepareInvoiceParameters($user, $plan);
        $attributes = \Filters::do_filter('create_invoice_parameters', $attributes, $plan, $user, $this->gateway);

        $request = $this->gateway->createInvoice($attributes);

        $response = $request->send();

        if ($response->isSuccessful()) {
            \Actions::do_action('post_create_invoice', $plan, $user, $this->gateway);
            return $response->getInvoiceReference();
        } else {
            // Create Invoice failed
            $message = trans('Subscriptions::exception.subscription.create_invoice_failed',
                ['arg' => $user->integration_id, 'message' => $response->getMessage()]);
            return false;
            //throw new \Exception($message);
        }
    }

    /**
     * @return mixed
     */
    public function fetchInvoice()
    {
    }

    /**
     * @return mixed
     */
    public function listInvoices()
    {
    }

    /**
     * @param $invoiceReference
     * @return bool
     * @throws \Exception
     */
    public function payInvoice($invoiceReference)
    {
        \Actions::do_action('pre_pay_invoice', $invoiceReference, $this->gateway);

        $parameters = ['invoiceReference' => $invoiceReference];
        $parameters = \Filters::do_filter('pay_invoice_parameters', $parameters, $this->gateway);

        $request = $this->gateway->payInvoice($parameters);

        $response = $request->send();

        if ($response->isSuccessful()) {
            \Actions::do_action('post_pay_invoice', $invoiceReference, $this->gateway);
            return true;
        } else {
            // Pay Invoice failed
            $message = trans('Subscriptions::exception.subscription.pay_invoice_failed',
                ['arg' => $invoiceReference, 'message' => $response->getMessage()]);

            throw new \Exception($message);
        }
    }

    /**
     * @param Plan $plan
     * @param User $user
     * @return boolean
     */
    public function isValidSubscription(Plan $plan, User $user = null)
    {
        \Actions::do_action('pre_subscription_check', $this, $plan, $user);

        if ($plan->free_plan) {
            return true;
        }

        if ($this->gateway->getConfig('create_remote_customer') && (is_null($user->integration_id))) {
            return false;
        }

        if ($this->gateway->getConfig('require_payment_token') && (!session()->get('checkoutToken'))) {
            return false;
        }

        return true;
    }

    /**
     * @param mixed ...$parameters
     */
    public function fireSubscriptionCreatedEvent(...$parameters): void
    {
        SubscriptionCreated::dispatch(...$parameters);
    }

    public function renewSubscription($subscription)
    {
        $response = $this->gateway->renewSubscription($subscription);

        if ($response) {
            if ($response instanceof AbstractResponse) {
                $referenceId = $response->getChargeReference();
                $response = $response->getData();
            } else {
                $referenceId = data_get($response, 'referenceId');
            }

            SubscriptionsManager::generateInvoice($subscription, $this->gateway, $response, $referenceId);
            return true;
        } else {
            throw new \Exception('Something went wrong in renewal');
        }
    }
}

Spamworldpro Mini