From 909b04c3828a3e3ee8b1b5104981c0835070a162 Mon Sep 17 00:00:00 2001 From: rai Date: Tue, 29 Sep 2020 12:45:18 +0200 Subject: [PATCH 1/3] cuopon option for stripe checkout session subscription, customer portal feature, subscription callback handler to setup from user code --- Billable.php | 38 +++++++++++++++++++++++++++++++ controllers/WebhookController.php | 6 +++++ 2 files changed, 44 insertions(+) diff --git a/Billable.php b/Billable.php index a4bd6f6..2169a70 100644 --- a/Billable.php +++ b/Billable.php @@ -99,6 +99,10 @@ public function createCheckoutSessionForSubscription($planID, array $optionsPara 'cancel_url' => $url_base . $controller_url_name . 'cancel', ]; + if(array_key_exists('couponID', $optionsParam)){ + $options['subscription_data']['coupon'] = $optionsParam['couponID'] ; + } + if(array_key_exists('success_url', $optionsParam)){ $options['success_url'] = $optionsParam['success_url']; } @@ -120,6 +124,40 @@ public function createCheckoutSessionForSubscription($planID, array $optionsPara return $session; } + /** + * Logic code for Yii app. To be overwritten + */ + public function handlerAfterSubscriptionsUpdated(): void + { + + } + + /** + * Creates a Stripe's customer portal session and get and url to redirect + * + * @param array $options['return_url'] url to return after customer portal + * + * @return \Stripe\Checkout\Session + * + * @throws Card + */ + public function createCustomerPortalSession( array $optionsParam = []): \Stripe\BillingPortal\Session + { + $customer = $this->getStripeCustomer(); + if (!$this->stripe_id) { + throw new InvalidArgumentException('No stripe customer provided.'); + } + + $options = [ 'customer' => $this->stripe_id ]; + if(array_key_exists('return_url', $optionsParam)){ + $options['return_url'] = $optionsParam['return_url']; + } + + \Stripe\Stripe::setApiKey(Yii::$app->params['stripe']['apiKey']); + $session = \Stripe\BillingPortal\Session::create($options); + return $session; + } + /** * Make a "one off" charge on the customer for the given amount. * diff --git a/controllers/WebhookController.php b/controllers/WebhookController.php index 2cad2a2..9580b34 100644 --- a/controllers/WebhookController.php +++ b/controllers/WebhookController.php @@ -81,13 +81,18 @@ protected function handleCustomerSubscriptionDeleted(array $payload) { $user = $this->getUserByStripeId($payload['data']['object']['customer']); if ($user) { + $hasUpdated = false; $subscriptions = $user->getSubscriptions()->all(); /* @var $subscription SubscriptionModel */ foreach ($subscriptions as $subscription) { if ($subscription->stripe_id === $payload['data']['object']['id']) { $subscription->markAsCancelled(); + $hasUpdated = true; } } + if($hasUpdated){ + $user->handlerAfterSubscriptionsUpdated(); + } } return new Response([ @@ -112,6 +117,7 @@ protected function handleCheckoutSessionCompleted(array $payload) $subscriptionModel = $user->subscriptionByStripeID($dataObj['subscription']); if (!$subscriptionModel) { $subscriptionModel = $user->loadSubscriptionModel($dataObj['subscription'], $dataObj['client_reference_id']); + $user->handlerAfterSubscriptionsUpdated(); } } } From 1570b7bca613dc5aba6266a6838e31534bddb0f9 Mon Sep 17 00:00:00 2001 From: rai Date: Thu, 22 Dec 2022 16:12:14 +0100 Subject: [PATCH 2/3] test changes --- tests/CashierTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CashierTest.php b/tests/CashierTest.php index 3bc873f..36b1eb8 100644 --- a/tests/CashierTest.php +++ b/tests/CashierTest.php @@ -18,7 +18,7 @@ protected function getTestToken() 'card' => [ 'number' => '4242424242424242', 'exp_month' => 5, - 'exp_year' => 2020, + 'exp_year' => 2032, 'cvc' => '123', ], ], ['api_key' => Yii::$app->params['stripe']['apiKey']])->id; From a5bad3a8f9c6d4866c6da17c82d670385bf5710e Mon Sep 17 00:00:00 2001 From: rai Date: Thu, 22 Dec 2022 16:33:13 +0100 Subject: [PATCH 3/3] lib yii2mod/yii2-behaviors removed! --- behaviors/CarbonBehavior.php | 126 +++++++++++++++++++++++++++++++++++ composer.json | 1 - models/SubscriptionModel.php | 7 +- 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 behaviors/CarbonBehavior.php diff --git a/behaviors/CarbonBehavior.php b/behaviors/CarbonBehavior.php new file mode 100644 index 0000000..a8b584e --- /dev/null +++ b/behaviors/CarbonBehavior.php @@ -0,0 +1,126 @@ + CarbonBehavior::className(), + * 'attributes' => [ + * 'createdAt' + * ], + * ], + * ]; + * } + * + * $user = UserModel::findOne(1); + * + * var_dump($user->createdAt->year); + * var_dump($user->createdAt->month); + * var_dump($user->createdAt->day); + * + * // change date + * + * $user->createdAt->addYear(); + * $user->save(); + * + * ``` + * + * @see http://carbon.nesbot.com/docs/#api-introduction + * + * @package yii2mod\behaviors + */ +class CarbonBehavior extends Behavior +{ + /** + * @var ActiveRecord the owner of this behavior + */ + public $owner; + + /** + * @var array list of attributes that will be converted to carbon instance + */ + public $attributes = []; + + /** + * @var string date format for carbon + */ + public $dateFormat = 'Y-m-d H:i:s'; + + /** + * @return array + */ + public function events() + { + return [ + ActiveRecord::EVENT_AFTER_FIND => 'attributesToCarbon', + ActiveRecord::EVENT_BEFORE_UPDATE => 'attributesToDefaultFormat', + ActiveRecord::EVENT_AFTER_UPDATE => 'attributesToCarbon', + ]; + } + + /** + * Convert the model's attributes to an Carbon instance. + * + * @param $event + * + * @return static + */ + public function attributesToCarbon($event) + { + foreach ($this->attributes as $attribute) { + $value = $this->owner->$attribute; + if (!empty($value)) { + // If this value is an integer, we will assume it is a UNIX timestamp's value + // and format a Carbon object from this timestamp. + if (is_numeric($value)) { + $this->owner->$attribute = Carbon::createFromTimestamp($value); + } + + // If the value is in simply year, month, day format, we will instantiate the + // Carbon instances from that format. + elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value)) { + $this->owner->$attribute = Carbon::createFromFormat('Y-m-d', $value)->startOfDay(); + } else { + $this->owner->$attribute = Carbon::createFromFormat($this->dateFormat, $this->owner->$attribute); + } + } + } + } + + /** + * Handles owner 'beforeUpdate' event for converting attributes values to the default format + * + * @param $event + * + * @return bool + */ + public function attributesToDefaultFormat($event) + { + $oldAttributes = $this->owner->oldAttributes; + foreach ($this->attributes as $attribute) { + $oldAttributeValue = $oldAttributes[$attribute]; + + if ($this->owner->$attribute instanceof Carbon) { + //If old attribute value is an integer, then we convert the current attribute value to the timestamp for prevent db errors + if (is_numeric($oldAttributeValue)) { + $this->owner->$attribute = $this->owner->$attribute->timestamp; + } + } + } + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index f23560e..237a97b 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ "require": { "php": ">=7.1", "yiisoft/yii2": "~2.0.14", - "yii2mod/yii2-behaviors": "~2.0", "stripe/stripe-php": "~7.0", "nesbot/carbon": "~2.29.1", "dompdf/dompdf": "^0.8.0" diff --git a/models/SubscriptionModel.php b/models/SubscriptionModel.php index 914c0fa..b153b3d 100644 --- a/models/SubscriptionModel.php +++ b/models/SubscriptionModel.php @@ -7,7 +7,12 @@ use LogicException; use Yii; use yii\db\ActiveRecord; -use yii2mod\behaviors\CarbonBehavior; + +// OLD lib +// from composer.json => "yii2mod/yii2-behaviors": "~2.0", +// use yii2mod\behaviors\CarbonBehavior; + +use yii2mod\cashier\behaviors\CarbonBehavior; /** * This is the model class for table "subscriptions".