diff --git a/Billable.php b/Billable.php index 15353cb..6a0771a 100644 --- a/Billable.php +++ b/Billable.php @@ -7,6 +7,7 @@ use InvalidArgumentException; use Stripe\Charge; use Stripe\Customer; +use Stripe\Error\Card; use Stripe\Error\InvalidRequest; use Stripe\Invoice as StripeInvoice; use Stripe\InvoiceItem as StripeInvoiceItem; @@ -37,11 +38,11 @@ trait Billable * @param int $amount * @param array $options * - * @return \Stripe\Charge + * @return Charge * - * @throws \Stripe\Error\Card + * @throws Card */ - public function charge($amount, array $options = []) + public function charge($amount, array $options = []): Charge { $options = array_merge([ 'currency' => $this->preferredCurrency(), @@ -49,8 +50,8 @@ public function charge($amount, array $options = []) $options['amount'] = $amount; - if (!array_key_exists('source', $options) && $this->stripeId) { - $options['customer'] = $this->stripeId; + if (!array_key_exists('source', $options) && $this->stripe_id) { + $options['customer'] = $this->stripe_id; } if (!array_key_exists('source', $options) && !array_key_exists('customer', $options)) { @@ -68,7 +69,7 @@ public function charge($amount, array $options = []) * * @return StripeRefund */ - public function refund($charge, array $options = []) + public function refund($charge, array $options = []): StripeRefund { $options['charge'] = $charge; @@ -80,9 +81,9 @@ public function refund($charge, array $options = []) * * @return bool */ - public function hasCardOnFile() + public function hasCardOnFile(): bool { - return (bool)$this->cardBrand; + return (bool) $this->card_brand; } /** @@ -92,18 +93,18 @@ public function hasCardOnFile() * @param int $amount * @param array $options * - * @return bool + * @return bool|StripeInvoice * - * @throws \Stripe\Error\Card + * @throws Card */ public function invoiceFor($description, $amount, array $options = []) { - if (!$this->stripeId) { + if (!$this->stripe_id) { throw new InvalidArgumentException('User is not a customer. See the createAsStripeCustomer method.'); } $options = array_merge([ - 'customer' => $this->stripeId, + 'customer' => $this->stripe_id, 'amount' => $amount, 'currency' => $this->preferredCurrency(), 'description' => $description, @@ -124,7 +125,7 @@ public function invoiceFor($description, $amount, array $options = []) * * @return SubscriptionBuilder */ - public function newSubscription($subscription, $plan) + public function newSubscription(string $subscription, string $plan): SubscriptionBuilder { return new SubscriptionBuilder($this, $subscription, $plan); } @@ -137,7 +138,7 @@ public function newSubscription($subscription, $plan) * * @return bool */ - public function onTrial($subscription = 'default', $plan = null) + public function onTrial(string $subscription = 'default', ?string $plan = null): bool { if (func_num_args() === 0 && $this->onGenericTrial()) { return true; @@ -148,7 +149,7 @@ public function onTrial($subscription = 'default', $plan = null) } return $subscription && $subscription->onTrial() && - $subscription->stripePlan === $plan; + $subscription->stripePlan === $plan; } /** @@ -156,9 +157,9 @@ public function onTrial($subscription = 'default', $plan = null) * * @return bool */ - public function onGenericTrial() + public function onGenericTrial(): bool { - return $this->trialEndAt && Carbon::now()->lt(Carbon::createFromFormat('Y-m-d H:i:s', $this->trialEndAt)); + return $this->trial_ends_at && Carbon::now()->lt(Carbon::createFromFormat('Y-m-d H:i:s', $this->trial_ends_at)); } /** @@ -169,18 +170,20 @@ public function onGenericTrial() * * @return bool */ - public function subscribed($subscription = 'default', $plan = null) + public function subscribed(string $subscription = 'default', ?string $plan = null): bool { $subscription = $this->subscription($subscription); + if (is_null($subscription)) { return false; } + if (is_null($plan)) { return $subscription->valid(); } return $subscription->valid() && - $subscription->stripePlan === $plan; + $subscription->stripe_plan === $plan; } /** @@ -190,7 +193,7 @@ public function subscribed($subscription = 'default', $plan = null) * * @return SubscriptionModel|null */ - public function subscription($subscription = 'default') + public function subscription(string $subscription = 'default'): ?SubscriptionModel { return $this->getSubscriptions()->where(['name' => $subscription])->one(); } @@ -200,19 +203,19 @@ public function subscription($subscription = 'default') */ public function getSubscriptions() { - return $this->hasMany(SubscriptionModel::className(), ['userId' => 'id'])->orderBy(['createdAt' => SORT_DESC]); + return $this->hasMany(SubscriptionModel::class, ['user_id' => 'id'])->orderBy(['created_at' => SORT_DESC]); } /** * Invoice the billable entity outside of regular billing cycle. * - * @return bool + * @return bool|StripeInvoice */ public function invoice() { - if ($this->stripeId) { + if ($this->stripe_id) { try { - return StripeInvoice::create(['customer' => $this->stripeId], $this->getStripeKey())->pay(); + return StripeInvoice::create(['customer' => $this->stripe_id], $this->getStripeKey())->pay(); } catch (InvalidRequest $e) { return false; } @@ -226,11 +229,11 @@ public function invoice() * * @return Invoice|null */ - public function upcomingInvoice() + public function upcomingInvoice(): ?Invoice { try { $stripeInvoice = StripeInvoice::upcoming( - ['customer' => $this->stripeId], ['api_key' => $this->getStripeKey()] + ['customer' => $this->stripe_id], ['api_key' => $this->getStripeKey()] ); return new Invoice($this, $stripeInvoice); @@ -245,7 +248,7 @@ public function upcomingInvoice() * * @return Invoice|null */ - public function findInvoice($id) + public function findInvoice(string $id): Invoice { try { return new Invoice($this, StripeInvoice::retrieve($id, $this->getStripeKey())); @@ -262,7 +265,7 @@ public function findInvoice($id) * * @throws NotFoundHttpException */ - public function findInvoiceOrFail($id) + public function findInvoiceOrFail(string $id) { $invoice = $this->findInvoice($id); @@ -281,7 +284,7 @@ public function findInvoiceOrFail($id) * * @return Response */ - public function downloadInvoice($id, array $data) + public function downloadInvoice(string $id, array $data) { return $this->findInvoiceOrFail($id)->download($data); } @@ -294,7 +297,7 @@ public function downloadInvoice($id, array $data) * * @return array */ - public function invoices($includePending = false, $parameters = []) + public function invoices(bool $includePending = false, array $parameters = []): array { $invoices = []; @@ -323,7 +326,7 @@ public function invoices($includePending = false, $parameters = []) * * @return array */ - public function invoicesIncludingPending(array $parameters = []) + public function invoicesIncludingPending(array $parameters = []): array { return $this->invoices(true, $parameters); } @@ -333,7 +336,7 @@ public function invoicesIncludingPending(array $parameters = []) * * @param string $token */ - public function updateCard($token) + public function updateCard(string $token): void { $customer = $this->asStripeCustomer(); $token = Token::retrieve($token, ['api_key' => $this->getStripeKey()]); @@ -376,8 +379,8 @@ public function updateCardFromStripe() if ($defaultCard) { $this->fillCardDetails($defaultCard)->save(); } else { - $this->cardBrand = null; - $this->cardLastFour = null; + $this->card_brand = null; + $this->card_last_four = null; $this->update(false); } @@ -394,8 +397,8 @@ public function updateCardFromStripe() protected function fillCardDetails($card) { if ($card) { - $this->cardBrand = $card->brand; - $this->cardLastFour = $card->last4; + $this->card_brand = $card->brand; + $this->card_last_four = $card->last4; } return $this; @@ -423,7 +426,7 @@ public function applyCoupon($coupon) * * @return bool */ - public function subscribedToPlan($plans, $subscription = 'default') + public function subscribedToPlan($plans, $subscription = 'default'): bool { $subscription = $this->subscription($subscription); @@ -431,8 +434,8 @@ public function subscribedToPlan($plans, $subscription = 'default') return false; } - foreach ((array)$plans as $plan) { - if ($subscription->stripePlan === $plan) { + foreach ((array) $plans as $plan) { + if ($subscription->stripe_plan === $plan) { return true; } } @@ -447,9 +450,9 @@ public function subscribedToPlan($plans, $subscription = 'default') * * @return bool */ - public function onPlan($plan) + public function onPlan($plan): bool { - $plan = $this->getSubscriptions()->where(['stripePlan' => $plan])->one(); + $plan = $this->getSubscriptions()->where(['stripe_plan' => $plan])->one(); return !is_null($plan) && $plan->valid(); } @@ -459,9 +462,9 @@ public function onPlan($plan) * * @return bool */ - public function hasStripeId() + public function hasStripeId(): bool { - return !is_null($this->stripeId); + return !is_null($this->stripe_id); } /** @@ -472,7 +475,7 @@ public function hasStripeId() * * @return Customer */ - public function createAsStripeCustomer($token, array $options = []) + public function createAsStripeCustomer(string $token, array $options = []): Customer { $options = array_key_exists('email', $options) ? $options : array_merge($options, ['email' => $this->email]); @@ -482,7 +485,7 @@ public function createAsStripeCustomer($token, array $options = []) // and allow us to retrieve users from Stripe later when we need to work. $customer = Customer::create($options, $this->getStripeKey()); - $this->stripeId = $customer->id; + $this->stripe_id = $customer->id; $this->save(); @@ -499,11 +502,11 @@ public function createAsStripeCustomer($token, array $options = []) /** * Get the Stripe customer for the user. * - * @return \Stripe\Customer + * @return Customer */ - public function asStripeCustomer() + public function asStripeCustomer(): Customer { - return Customer::retrieve($this->stripeId, $this->getStripeKey()); + return Customer::retrieve($this->stripe_id, $this->getStripeKey()); } /** @@ -511,7 +514,7 @@ public function asStripeCustomer() * * @return string */ - public function preferredCurrency() + public function preferredCurrency(): string { return Cashier::usesCurrency(); } @@ -521,7 +524,7 @@ public function preferredCurrency() * * @return int */ - public function taxPercentage() + public function taxPercentage(): int { return 0; } @@ -531,7 +534,7 @@ public function taxPercentage() * * @return string */ - public static function getStripeKey() + public static function getStripeKey(): string { return static::$stripeKey ?: Yii::$app->params['stripe']['apiKey']; } @@ -539,9 +542,9 @@ public static function getStripeKey() /** * Set the Stripe API key. * - * @param string $key + * @param string $key */ - public static function setStripeKey($key) + public static function setStripeKey($key): void { static::$stripeKey = $key; } diff --git a/Cashier.php b/Cashier.php index 805a411..20b3f36 100644 --- a/Cashier.php +++ b/Cashier.php @@ -38,8 +38,10 @@ class Cashier * * @param string $currency * @param string|null $symbol + * + * @throws Exception */ - public static function useCurrency($currency, $symbol = null) + public static function useCurrency(string $currency, ?string $symbol = null): void { static::$currency = $currency; static::useCurrencySymbol($symbol ?: static::guessCurrencySymbol($currency)); @@ -54,7 +56,7 @@ public static function useCurrency($currency, $symbol = null) * * @throws Exception */ - protected static function guessCurrencySymbol($currency) + protected static function guessCurrencySymbol(string $currency): string { switch (strtolower($currency)) { case 'usd': @@ -75,7 +77,7 @@ protected static function guessCurrencySymbol($currency) * * @return string */ - public static function usesCurrency() + public static function usesCurrency(): string { return static::$currency; } @@ -85,7 +87,7 @@ public static function usesCurrency() * * @param string $symbol */ - public static function useCurrencySymbol($symbol) + public static function useCurrencySymbol(string $symbol): void { static::$currencySymbol = $symbol; } @@ -95,7 +97,7 @@ public static function useCurrencySymbol($symbol) * * @return string */ - public static function usesCurrencySymbol() + public static function usesCurrencySymbol(): string { return static::$currencySymbol; } @@ -105,7 +107,7 @@ public static function usesCurrencySymbol() * * @param callable $callback */ - public static function formatCurrencyUsing(callable $callback) + public static function formatCurrencyUsing(callable $callback): void { static::$formatCurrencyUsing = $callback; } @@ -117,7 +119,7 @@ public static function formatCurrencyUsing(callable $callback) * * @return string */ - public static function formatAmount($amount) + public static function formatAmount(int $amount): string { if (static::$formatCurrencyUsing) { return call_user_func(static::$formatCurrencyUsing, $amount); diff --git a/README.md b/README.md index 459671a..6df8ebf 100644 --- a/README.md +++ b/README.md @@ -46,23 +46,23 @@ if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } -$this->createTable('subscription', [ +$this->createTable('subscriptions', [ 'id' => $this->primaryKey(), - 'userId' => $this->integer()->notNull(), + 'user_id' => $this->integer()->notNull(), 'name' => $this->string()->notNull(), - 'stripeId' => $this->string()->notNull(), - 'stripePlan' => $this->string()->notNull(), + 'stripe_id' => $this->string()->notNull(), + 'stripe_plan' => $this->string()->notNull(), 'quantity' => $this->integer()->notNull(), - 'trialEndAt' => $this->timestamp()->null(), - 'endAt' => $this->timestamp()->null(), - 'createdAt' => $this->timestamp()->null(), - 'updatedAt' => $this->timestamp()->null() + 'trial_ends_at' => $this->timestamp()->null(), + 'ends_at' => $this->timestamp()->null(), + 'created_at' => $this->timestamp()->null(), + 'updated_at' => $this->timestamp()->null() ], $tableOptions); -$this->addColumn('user', 'stripeId', $this->string()); -$this->addColumn('user', 'cardBrand', $this->string()); -$this->addColumn('user', 'cardLastFour', $this->string()); -$this->addColumn('user', 'trialEndAt', $this->timestamp()->null()); +$this->addColumn('users', 'stripe_id', $this->string()); +$this->addColumn('users', 'card_brand', $this->string()); +$this->addColumn('users', 'card_last_four', $this->string()); +$this->addColumn('users', 'trial_ends_at', $this->timestamp()->null()); ``` > Also you can apply migration by the following command: @@ -307,7 +307,7 @@ If you would like to offer trial periods without collecting the user's payment m ```php $user = new User([ // Populate other user properties... - 'trialEndAt' => Carbon::now()->addDays(10), + 'trial_ends_at' => Carbon::now()->addDays(10), ]); ``` diff --git a/SubscriptionBuilder.php b/SubscriptionBuilder.php index 3eb7749..a8bfe3d 100644 --- a/SubscriptionBuilder.php +++ b/SubscriptionBuilder.php @@ -183,13 +183,13 @@ public function create($token = null, array $options = []) $trialEndsAt = $this->trialDays ? Carbon::now()->addDays($this->trialDays) : null; } $subscriptionModel = new SubscriptionModel([ - 'userId' => $this->user->id, + 'user_id' => $this->user->id, 'name' => $this->name, - 'stripeId' => $subscription->id, - 'stripePlan' => $this->plan, + 'stripe_id' => $subscription->id, + 'stripe_plan' => $this->plan, 'quantity' => $this->quantity, - 'trialEndAt' => $trialEndsAt, - 'endAt' => null, + 'trial_ends_at' => $trialEndsAt, + 'ends_at' => null, ]); if ($subscriptionModel->save()) { return $subscriptionModel; @@ -208,7 +208,7 @@ public function create($token = null, array $options = []) */ protected function getStripeCustomer($token = null, array $options = []) { - if (!$this->user->stripeId) { + if (!$this->user->stripe_id) { $customer = $this->user->createAsStripeCustomer( $token, array_merge($options, array_filter(['coupon' => $this->coupon])) ); diff --git a/composer.json b/composer.json index f9e108f..a31d9ce 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ } ], "require": { + "php": ">=7.1", "yiisoft/yii2": "~2.0.14", "yii2mod/yii2-behaviors": "*", "stripe/stripe-php": "~4.0", diff --git a/controllers/WebhookController.php b/controllers/WebhookController.php index d9291a7..6338694 100644 --- a/controllers/WebhookController.php +++ b/controllers/WebhookController.php @@ -30,7 +30,7 @@ public function behaviors() { return [ 'verbs' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => [ 'handle-webhook' => ['post'], ], @@ -46,15 +46,18 @@ public function behaviors() public function actionHandleWebhook() { $payload = json_decode(Yii::$app->request->getRawBody(), true); + if (!$this->eventExistsOnStripe($payload['id'])) { return; } + $method = 'handle' . Inflector::camelize(str_replace('.', '_', $payload['type'])); + if (method_exists($this, $method)) { return $this->{$method}($payload); - } else { - return $this->missingMethod(); } + + return $this->missingMethod(); } /** @@ -71,7 +74,7 @@ protected function handleCustomerSubscriptionDeleted(array $payload) $subscriptions = $user->getSubscriptions()->all(); /* @var $subscription SubscriptionModel */ foreach ($subscriptions as $subscription) { - if ($subscription->stripeId === $payload['data']['object']['id']) { + if ($subscription->stripe_id === $payload['data']['object']['id']) { $subscription->markAsCancelled(); } } @@ -94,7 +97,7 @@ protected function getUserByStripeId($stripeId) { $model = Yii::$app->user->identityClass; - return $model::findOne(['stripeId' => $stripeId]); + return $model::findOne(['stripe_id' => $stripeId]); } /** diff --git a/migrations/m180321_213759_rename_subscription_table.php b/migrations/m180321_213759_rename_subscription_table.php new file mode 100644 index 0000000..06af0b5 --- /dev/null +++ b/migrations/m180321_213759_rename_subscription_table.php @@ -0,0 +1,25 @@ +renameTable('subscription', 'subscriptions'); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->renameTable('subscriptions', 'subscription'); + } +} diff --git a/migrations/m180321_213856_rename_subscription_columns.php b/migrations/m180321_213856_rename_subscription_columns.php new file mode 100644 index 0000000..93c3f3a --- /dev/null +++ b/migrations/m180321_213856_rename_subscription_columns.php @@ -0,0 +1,51 @@ +renameColumn('subscriptions', 'userId', 'user_id'); + $this->renameColumn('subscriptions', 'stripeId', 'stripe_id'); + $this->renameColumn('subscriptions', 'stripePlan', 'stripe_plan'); + $this->renameColumn('subscriptions', 'trialEndAt', 'trial_ends_at'); + $this->renameColumn('subscriptions', 'endAt', 'ends_at'); + $this->renameColumn('subscriptions', 'createdAt', 'created_at'); + $this->renameColumn('subscriptions', 'updatedAt', 'updated_at'); + + if (Yii::$app->db->schema->getTableSchema('user')) { + $this->renameColumn('user', 'stripeId', 'stripe_id'); + $this->renameColumn('user', 'cardBrand', 'card_brand'); + $this->renameColumn('user', 'cardLastFour', 'card_last_four'); + $this->renameColumn('user', 'trialEndAt', 'trial_ends_at'); + } + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->renameColumn('subscriptions', 'user_id', 'userId'); + $this->renameColumn('subscriptions', 'stripe_id', 'stripeId'); + $this->renameColumn('subscriptions', 'stripe_plan', 'stripePlan'); + $this->renameColumn('subscriptions', 'trial_ends_at', 'trialEndAt'); + $this->renameColumn('subscriptions', 'ends_at', 'endAt'); + $this->renameColumn('subscriptions', 'created_at', 'createdAt'); + $this->renameColumn('subscriptions', 'updated_at', 'updatedAt'); + + if (Yii::$app->db->schema->getTableSchema('user')) { + $this->renameColumn('user', 'stripe_id', 'stripeId'); + $this->renameColumn('user', 'card_brand', 'cardBrand'); + $this->renameColumn('user', 'card_last_four', 'cardLastFour'); + $this->renameColumn('user', 'trial_ends_at', 'trialEndAt'); + } + } +} diff --git a/models/SubscriptionModel.php b/models/SubscriptionModel.php index 837deb5..b46ca2e 100644 --- a/models/SubscriptionModel.php +++ b/models/SubscriptionModel.php @@ -7,22 +7,21 @@ use LogicException; use Yii; use yii\db\ActiveRecord; -use yii\db\Expression; use yii2mod\behaviors\CarbonBehavior; /** - * This is the model class for table "Subscription". + * This is the model class for table "subscriptions". * * @property int $id - * @property int $userId + * @property int $user_id * @property string $name - * @property string $stripeId - * @property string $stripePlan + * @property string $stripe_id + * @property string $stripe_plan * @property int $quantity - * @property Carbon $trialEndAt - * @property Carbon $endAt - * @property int $createdAt - * @property int $updatedAt + * @property Carbon $trial_ends_at + * @property Carbon $ends_at + * @property int $created_at + * @property int $updated_at * @property \yii\db\ActiveRecord $user */ class SubscriptionModel extends ActiveRecord @@ -44,77 +43,73 @@ class SubscriptionModel extends ActiveRecord /** * @inheritdoc */ - public static function tableName() + public static function tableName(): string { - return 'subscription'; + return 'subscriptions'; } /** * @inheritdoc */ - public function rules() + public function rules(): array { return [ - [['userId', 'name', 'stripeId', 'stripePlan', 'quantity'], 'required'], - [['userId', 'quantity'], 'integer'], - [['trialEndAt', 'endAt'], 'safe'], - [['name', 'stripeId', 'stripePlan'], 'string', 'max' => 255], + [['user_id', 'name', 'stripe_id', 'stripe_plan', 'quantity'], 'required'], + [['user_id', 'quantity'], 'integer'], + [['trial_ends_at', 'ends_at'], 'safe'], + [['name', 'stripe_id', 'stripe_plan'], 'string', 'max' => 255], ]; } /** * @inheritdoc */ - public function attributeLabels() + public function attributeLabels(): array { return [ 'id' => Yii::t('app', 'ID'), - 'userId' => Yii::t('app', 'User ID'), + 'user_id' => Yii::t('app', 'User ID'), 'name' => Yii::t('app', 'Name'), - 'stripeId' => Yii::t('app', 'Stripe ID'), - 'stripePlan' => Yii::t('app', 'Stripe Plan'), + 'stripe_id' => Yii::t('app', 'Stripe ID'), + 'stripe_plan' => Yii::t('app', 'Stripe Plan'), 'quantity' => Yii::t('app', 'Quantity'), - 'trialEndAt' => Yii::t('app', 'Trial End At'), - 'endAt' => Yii::t('app', 'End At'), - 'createdAt' => Yii::t('app', 'Created At'), - 'updatedAt' => Yii::t('app', 'Updated At'), + 'trial_ends_at' => Yii::t('app', 'Trial End At'), + 'ends_at' => Yii::t('app', 'End At'), + 'created_at' => Yii::t('app', 'Created At'), + 'updated_at' => Yii::t('app', 'Updated At'), ]; } /** * @inheritdoc */ - public function behaviors() + public function behaviors(): array { return [ 'timestamp' => [ 'class' => 'yii\behaviors\TimestampBehavior', - 'createdAtAttribute' => 'createdAt', - 'updatedAtAttribute' => 'updatedAt', + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', 'value' => function () { - $currentDateExpression = Yii::$app->db->getDriverName() === 'sqlite' ? "DATETIME('now')" : 'NOW()'; - - return new Expression($currentDateExpression); + return Carbon::now()->toDateTimeString(); }, ], 'carbon' => [ - 'class' => CarbonBehavior::className(), + 'class' => CarbonBehavior::class, 'attributes' => [ - 'trialEndAt', - 'endAt', + 'trial_ends_at', + 'ends_at', ], ], ]; } /** - * User relation - * * @return \yii\db\ActiveQuery */ public function getUser() { - return $this->hasOne(Yii::$app->user->identityClass, ['id' => 'userId']); + return $this->hasOne(Yii::$app->user->identityClass, ['id' => 'user_id']); } /** @@ -122,7 +117,7 @@ public function getUser() * * @return bool */ - public function valid() + public function valid(): bool { return $this->active() || $this->onTrial() || $this->onGracePeriod(); } @@ -132,9 +127,9 @@ public function valid() * * @return bool */ - public function active() + public function active(): bool { - return is_null($this->endAt) || $this->onGracePeriod(); + return is_null($this->ends_at) || $this->onGracePeriod(); } /** @@ -142,9 +137,9 @@ public function active() * * @return bool */ - public function cancelled() + public function cancelled(): bool { - return !is_null($this->endAt); + return !is_null($this->ends_at); } /** @@ -152,10 +147,10 @@ public function cancelled() * * @return bool */ - public function onTrial() + public function onTrial(): bool { - if (!is_null($this->trialEndAt)) { - return Carbon::today()->lt($this->trialEndAt); + if (!is_null($this->trial_ends_at)) { + return Carbon::today()->lt($this->trial_ends_at); } else { return false; } @@ -166,9 +161,9 @@ public function onTrial() * * @return bool */ - public function onGracePeriod() + public function onGracePeriod(): bool { - if (!is_null($endAt = $this->endAt)) { + if (!is_null($endAt = $this->ends_at)) { return Carbon::now()->lt(Carbon::instance($endAt)); } else { return false; @@ -182,7 +177,7 @@ public function onGracePeriod() * * @return $this */ - public function incrementQuantity($count = 1) + public function incrementQuantity(int $count = 1) { $this->updateQuantity($this->quantity + $count); @@ -196,7 +191,7 @@ public function incrementQuantity($count = 1) * * @return $this */ - public function incrementAndInvoice($count = 1) + public function incrementAndInvoice(int $count = 1) { $this->incrementQuantity($count); $this->user->invoice(); @@ -211,7 +206,7 @@ public function incrementAndInvoice($count = 1) * * @return $this */ - public function decrementQuantity($count = 1) + public function decrementQuantity(int $count = 1) { $this->updateQuantity(max(1, $this->quantity - $count)); @@ -225,7 +220,7 @@ public function decrementQuantity($count = 1) * * @return $this */ - public function updateQuantity($quantity) + public function updateQuantity(int $quantity) { $subscription = $this->asStripeSubscription(); $subscription->quantity = $quantity; @@ -253,7 +248,7 @@ public function noProrate() /** * Change the billing cycle anchor on a plan change. * - * @param int|string $date + * @param int|string $date * * @return $this */ @@ -271,11 +266,11 @@ public function anchorBillingCycleOn($date = 'now') /** * Swap the subscription to a new Stripe plan. * - * @param string $plan + * @param string $plan * * @return $this */ - public function swap($plan) + public function swap(string $plan) { $subscription = $this->asStripeSubscription(); @@ -291,7 +286,7 @@ public function swap($plan) // to maintain the current trial state, whether that is "active" or to run // the swap out with the exact number of days left on this current plan. if ($this->onTrial()) { - $subscription->trial_end = $this->trialEndAt->getTimestamp(); + $subscription->trial_end = $this->trial_ends_at->getTimestamp(); } else { $subscription->trial_end = 'now'; } @@ -307,8 +302,8 @@ public function swap($plan) $this->user->invoice(); - $this->stripePlan = $plan; - $this->endAt = null; + $this->stripe_plan = $plan; + $this->ends_at = null; $this->save(); return $this; @@ -329,9 +324,9 @@ public function cancel() // would have ended. Otherwise, we'll retrieve the end of the billing period // period and make that the end of the grace period for this current user. if ($this->onTrial()) { - $this->endAt = $this->trialEndAt; + $this->ends_at = $this->trial_ends_at; } else { - $this->endAt = Carbon::createFromTimestamp( + $this->ends_at = Carbon::createFromTimestamp( $subscription->current_period_end ); } @@ -360,9 +355,9 @@ public function cancelNow() /** * Mark the subscription as cancelled. */ - public function markAsCancelled() + public function markAsCancelled(): void { - $this->endAt = Carbon::now(); + $this->ends_at = Carbon::now(); $this->save(); } @@ -384,10 +379,10 @@ public function resume() // To resume the subscription we need to set the plan parameter on the Stripe // subscription object. This will force Stripe to resume this subscription // where we left off. Then, we'll set the proper trial ending timestamp. - $subscription->plan = $this->stripePlan; + $subscription->plan = $this->stripe_plan; if ($this->onTrial()) { - $subscription->trial_end = $this->trialEndAt->getTimestamp(); + $subscription->trial_end = $this->trial_ends_at->getTimestamp(); } else { $subscription->trial_end = 'now'; } @@ -397,7 +392,7 @@ public function resume() // Finally, we will remove the ending timestamp from the user's record in the // local database to indicate that the subscription is active again and is // no longer "cancelled". Then we will save this record in the database. - $this->endAt = null; + $this->ends_at = null; $this->save(); return $this; @@ -410,6 +405,6 @@ public function resume() */ public function asStripeSubscription() { - return $this->user->asStripeCustomer()->subscriptions->retrieve($this->stripeId); + return $this->user->asStripeCustomer()->subscriptions->retrieve($this->stripe_id); } } diff --git a/tests/CashierTest.php b/tests/CashierTest.php index 413fc59..5f78d2d 100644 --- a/tests/CashierTest.php +++ b/tests/CashierTest.php @@ -32,7 +32,7 @@ public function testSubscriptionsCanBeCreated() $user->newSubscription('main', 'monthly-10-1')->create($this->getTestToken()); $this->assertEquals(1, count($user->subscriptions)); - $this->assertNotNull($user->subscription('main')->stripeId); + $this->assertNotNull($user->subscription('main')->stripe_id); $this->assertTrue($user->subscribed('main')); $this->assertTrue($user->subscribedToPlan('monthly-10-1', 'main')); $this->assertFalse($user->subscribedToPlan('monthly-10-1', 'something')); @@ -52,13 +52,13 @@ public function testSubscriptionsCanBeCreated() $this->assertTrue($subscription->onGracePeriod()); // Modify Ends Date To Past - $oldGracePeriod = $subscription->endAt; - $subscription->updateAttributes(['endAt' => Carbon::now()->subDays(5)]); + $oldGracePeriod = $subscription->ends_at; + $subscription->updateAttributes(['ends_at' => Carbon::now()->subDays(5)]); $this->assertFalse($subscription->active()); $this->assertTrue($subscription->cancelled()); $this->assertFalse($subscription->onGracePeriod()); - $subscription->updateAttributes(['endAt' => $oldGracePeriod]); + $subscription->updateAttributes(['ends_at' => $oldGracePeriod]); // Resume Subscription $subscription->resume(); @@ -79,7 +79,7 @@ public function testSubscriptionsCanBeCreated() // Swap Plan $subscription->swap('monthly-10-2'); - $this->assertEquals('monthly-10-2', $subscription->stripePlan); + $this->assertEquals('monthly-10-2', $subscription->stripe_plan); // Invoice Tests $invoice = $user->invoices()[1]; @@ -97,7 +97,9 @@ public function testCreatingSubscriptionWithCoupons() // Create Subscription $user->newSubscription('main', 'monthly-10-1') - ->withCoupon('coupon-1')->create($this->getTestToken()); + ->withCoupon('coupon-1') + ->create($this->getTestToken()); + $subscription = $user->subscription('main'); $this->assertTrue($user->subscribed('main')); @@ -120,9 +122,11 @@ public function testGenericTrials() { $user = new User(); $this->assertFalse($user->onGenericTrial()); - $user->trialEndAt = Carbon::tomorrow(); + + $user->trial_ends_at = Carbon::tomorrow(); $this->assertTrue($user->onGenericTrial()); - $user->trialEndAt = Carbon::today()->subDays(5); + + $user->trial_ends_at = Carbon::today()->subDays(5); $this->assertFalse($user->onGenericTrial()); } @@ -132,12 +136,14 @@ public function testCreatingSubscriptionWithTrial() // Create Subscription $user->newSubscription('main', 'monthly-10-1') - ->trialDays(7)->create($this->getTestToken()); + ->trialDays(7) + ->create($this->getTestToken()); + $subscription = $user->subscription('main'); $this->assertTrue($subscription->active()); $this->assertTrue($subscription->onTrial()); - $this->assertEquals(Carbon::today()->addDays(7)->day, $subscription->trialEndAt->day); + $this->assertEquals(Carbon::today()->addDays(7)->day, $subscription->trial_ends_at->day); // Cancel Subscription $subscription->cancel(); @@ -151,7 +157,7 @@ public function testCreatingSubscriptionWithTrial() $this->assertTrue($subscription->active()); $this->assertFalse($subscription->onGracePeriod()); $this->assertTrue($subscription->onTrial()); - $this->assertEquals(Carbon::today()->addDays(7)->day, $subscription->trialEndAt->day); + $this->assertEquals(Carbon::today()->addDays(7)->day, $subscription->trial_ends_at->day); } public function testApplyingCouponsToExistingCustomers() @@ -181,8 +187,8 @@ public function testMarkingAsCancelledFromWebhook() 'type' => 'customer.subscription.deleted', 'data' => [ 'object' => [ - 'id' => $subscription->stripeId, - 'customer' => $user->stripeId, + 'id' => $subscription->stripe_id, + 'customer' => $user->stripe_id, ], ], ]); diff --git a/tests/TestCase.php b/tests/TestCase.php index 4026ee9..c18f2f4 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -85,30 +85,30 @@ protected function setupTestDbData() // Structure : - $db->createCommand()->createTable('subscription', [ + $db->createCommand()->createTable('subscriptions', [ 'id' => 'pk', - 'userId' => 'integer not null', + 'user_id' => 'integer not null', 'name' => 'string not null', - 'stripeId' => 'string not null', - 'stripePlan' => 'string not null', + 'stripe_id' => 'string not null', + 'stripe_plan' => 'string not null', 'quantity' => 'integer not null', - 'trialEndAt' => 'timestamp null default null', - 'endAt' => 'timestamp null default null', - 'createdAt' => 'timestamp null default null', - 'updatedAt' => 'timestamp null default null', + 'trial_ends_at' => 'timestamp null default null', + 'ends_at' => 'timestamp null default null', + 'created_at' => 'timestamp null default null', + 'updated_at' => 'timestamp null default null', ])->execute(); - $db->createCommand()->createTable('user', [ + $db->createCommand()->createTable('users', [ 'id' => 'pk', 'username' => 'string', 'email' => 'string', - 'stripeId' => 'string', - 'cardBrand' => 'string', - 'cardLastFour' => 'string', - 'trialEndAt' => 'timestamp null default null', + 'stripe_id' => 'string', + 'card_brand' => 'string', + 'card_last_four' => 'string', + 'trial_ends_at' => 'timestamp null default null', ])->execute(); - $db->createCommand()->insert('user', [ + $db->createCommand()->insert('users', [ 'username' => 'John Doe', 'email' => 'johndoe@domain.com', ])->execute(); diff --git a/tests/data/User.php b/tests/data/User.php index f2445db..14cff9e 100644 --- a/tests/data/User.php +++ b/tests/data/User.php @@ -20,7 +20,7 @@ class User extends ActiveRecord implements IdentityInterface */ public static function tableName() { - return 'user'; + return 'users'; } /**