189 lines
5.7 KiB
PHP
189 lines
5.7 KiB
PHP
<?php
|
|
|
|
namespace App\Traits;
|
|
|
|
use App\Helpers\DateHelper;
|
|
use Laravel\Cashier\Billable;
|
|
use App\Helpers\InstanceHelper;
|
|
use App\Exceptions\StripeException;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
trait Subscription
|
|
{
|
|
use Billable;
|
|
|
|
/**
|
|
* Process the upgrade payment.
|
|
*
|
|
* @param string $payment_method
|
|
* @param string $planName
|
|
* @return bool|string
|
|
*/
|
|
public function subscribe(string $payment_method, string $planName)
|
|
{
|
|
$plan = InstanceHelper::getPlanInformationFromConfig($planName);
|
|
|
|
return $this->stripeCall(function () use ($payment_method, $plan) {
|
|
$this->newSubscription($plan['name'], $plan['id'])
|
|
->create($payment_method, [
|
|
'email' => auth()->user()->email,
|
|
]);
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check if the account is currently subscribed to a plan.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isSubscribed()
|
|
{
|
|
if ($this->has_access_to_paid_version_for_free) {
|
|
return true;
|
|
}
|
|
|
|
return $this->subscribed(config('monica.paid_plan_monthly_friendly_name'))
|
|
|| $this->subscribed(config('monica.paid_plan_annual_friendly_name'));
|
|
}
|
|
|
|
/**
|
|
* Get the subscription the account is subscribed to.
|
|
*
|
|
* @return \Laravel\Cashier\Subscription|null
|
|
*/
|
|
public function getSubscribedPlan()
|
|
{
|
|
$subscription = $this->subscription(config('monica.paid_plan_monthly_friendly_name'));
|
|
|
|
if (! $subscription) {
|
|
$subscription = $this->subscription(config('monica.paid_plan_annual_friendly_name'));
|
|
}
|
|
|
|
return $subscription;
|
|
}
|
|
|
|
/**
|
|
* Get the id of the plan the account is subscribed to.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getSubscribedPlanId()
|
|
{
|
|
$plan = $this->getSubscribedPlan();
|
|
|
|
if (! is_null($plan)) {
|
|
return $plan->stripe_plan;
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Get the friendly name of the plan the account is subscribed to.
|
|
*
|
|
* @return string|null
|
|
*/
|
|
public function getSubscribedPlanName(): ?string
|
|
{
|
|
$plan = $this->getSubscribedPlan();
|
|
|
|
return is_null($plan) ? null : $plan->name;
|
|
}
|
|
|
|
/**
|
|
* Cancel the plan the account is subscribed to.
|
|
*
|
|
* @return bool|string
|
|
*/
|
|
public function subscriptionCancel()
|
|
{
|
|
$plan = $this->getSubscribedPlan();
|
|
|
|
if (! is_null($plan)) {
|
|
return $this->stripeCall(function () use ($plan) {
|
|
$plan->cancelNow();
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the account has invoices linked to this account.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasInvoices()
|
|
{
|
|
return $this->subscriptions()->count() > 0;
|
|
}
|
|
|
|
/**
|
|
* Get the next billing date for the account.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getNextBillingDate()
|
|
{
|
|
// Weird method to get the next billing date from Laravel Cashier
|
|
// see https://stackoverflow.com/questions/41576568/get-next-billing-date-from-laravel-cashier
|
|
return $this->stripeCall(function () {
|
|
$subscriptions = $this->asStripeCustomer()['subscriptions'];
|
|
if (! $subscriptions || count($subscriptions->data) <= 0) {
|
|
return '';
|
|
}
|
|
$timestamp = $subscriptions->data[0]['current_period_end'];
|
|
|
|
return DateHelper::getFullDate($timestamp);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Call stripe.
|
|
*
|
|
* @param callable $callback
|
|
* @return mixed
|
|
*/
|
|
private function stripeCall($callback)
|
|
{
|
|
try {
|
|
return $callback();
|
|
} catch (\Stripe\Exception\CardException $e) {
|
|
// Since it's a decline, \Stripe\Error\Card will be caught
|
|
$body = $e->getJsonBody();
|
|
$err = $body['error'];
|
|
$errorMessage = trans('settings.stripe_error_card', ['message' => $err['message']]);
|
|
Log::error('Stripe card decline error: '.(string) $e, $e->getJsonBody() ?: []);
|
|
} catch (\Stripe\Exception\RateLimitException $e) {
|
|
// Too many requests made to the API too quickly
|
|
$errorMessage = trans('settings.stripe_error_rate_limit');
|
|
Log::error('Stripe RateLimit error: '.(string) $e, $e->getJsonBody() ?: []);
|
|
} catch (\Stripe\Exception\InvalidRequestException $e) {
|
|
// Invalid parameters were supplied to Stripe's API
|
|
$errorMessage = trans('settings.stripe_error_invalid_request');
|
|
Log::error('Stripe InvalidRequest error: '.(string) $e, $e->getJsonBody() ?: []);
|
|
} catch (\Stripe\Exception\AuthenticationException $e) {
|
|
// Authentication with Stripe's API failed
|
|
// (maybe you changed API keys recently)
|
|
$errorMessage = trans('settings.stripe_error_authentication');
|
|
Log::error('Stripe Authentication error: '.(string) $e, $e->getJsonBody() ?: []);
|
|
} catch (\Stripe\Exception\ApiConnectionException $e) {
|
|
// Network communication with Stripe failed
|
|
$errorMessage = trans('settings.stripe_error_api_connection_error');
|
|
Log::error('Stripe ApiConnection error: '.(string) $e, $e->getJsonBody() ?: []);
|
|
} catch (\Stripe\Exception\ApiErrorException $e) {
|
|
$errorMessage = $e->getMessage();
|
|
Log::error('Stripe error: '.(string) $e, $e->getJsonBody() ?: []);
|
|
} catch (\Exception $e) {
|
|
$errorMessage = $e->getMessage();
|
|
Log::error('Stripe error: '.(string) $e);
|
|
}
|
|
|
|
throw new StripeException($errorMessage);
|
|
}
|
|
}
|