From 79d48af3d4483b4f2adf29e46e609a6550a14b79 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Thu, 30 Jan 2025 15:14:20 +0000 Subject: [PATCH] Need to specify schedule ID, not object. --- classes/Stripe.php | 16 ++++++++++ classes/Subscription.php | 17 ++++++++--- classes/TestStripe.php | 59 +++++++++++++++++++++++++++++++++++- tests/AcceptApiTest.php | 24 +++++++++++++++ www/docs/api/cancel-plan.php | 6 +--- 5 files changed, 111 insertions(+), 11 deletions(-) diff --git a/classes/Stripe.php b/classes/Stripe.php index 2c1562ec13..44d00e5912 100644 --- a/classes/Stripe.php +++ b/classes/Stripe.php @@ -38,4 +38,20 @@ public function createSubscription($args) { public function getInvoices($args) { return \Stripe\Invoice::all($args); } + + public function createSchedule($id) { + return \Stripe\SubscriptionSchedule::create(['from_subscription' => $id]); + } + + public function updateSchedule($id, $phases) { + return \Stripe\SubscriptionSchedule::update($id, ['phases' => $phases]); + } + + public function releaseSchedule($id) { + \Stripe\SubscriptionSchedule::release($id); + } + + public function updateSubscription($id, $args) { + \Stripe\Subscription::update($id, $args); + } } diff --git a/classes/Subscription.php b/classes/Subscription.php index 3eef7ffc37..f074764fa4 100644 --- a/classes/Subscription.php +++ b/classes/Subscription.php @@ -124,9 +124,9 @@ private function update_subscription($form_data) { if ($old_price >= $new_price) { if ($this->stripe->schedule) { - \Stripe\SubscriptionSchedule::release($this->stripe->schedule); + $this->api->releaseSchedule($this->stripe->schedule->id); } - $schedule = \Stripe\SubscriptionSchedule::create(['from_subscription' => $this->stripe->id]); + $schedule = $this->api->createSchedule($this->stripe->id); $phases = [ [ 'items' => [['price' => $schedule->phases[0]->items[0]->price]], @@ -149,7 +149,7 @@ private function update_subscription($form_data) { if ($form_data['coupon']) { $phases[1]['coupon'] = $form_data['coupon']; } - \Stripe\SubscriptionSchedule::update($schedule->id, ['phases' => $phases]); + $this->api->updateSchedule($schedule->id, $phases); } if ($old_price < $new_price) { @@ -166,9 +166,9 @@ private function update_subscription($form_data) { $args['coupon'] = ''; } if ($this->stripe->schedule) { - \Stripe\SubscriptionSchedule::release($this->stripe->schedule); + $this->api->releaseSchedule($this->stripe->schedule->id); } - \Stripe\Subscription::update($this->stripe->id, $args); + $this->api->updateSubscription($this->stripe->id, $args); } } @@ -233,6 +233,13 @@ private function add_subscription($form_data) { ]); } + public function cancel_subscription() { + if ($this->stripe->schedule) { + $this->api->releaseSchedule($this->stripe->schedule->id); + } + $this->api->updateSubscription($this->stripe->id, ['cancel_at_period_end' => true]); + } + public function invoices() { $invoices = $this->api->getInvoices([ 'subscription' => $this->stripe->id, diff --git a/classes/TestStripe.php b/classes/TestStripe.php index 92b84e764f..0b66a1a99d 100644 --- a/classes/TestStripe.php +++ b/classes/TestStripe.php @@ -31,6 +31,34 @@ public function getSubscription($args) { ], ], ], null); + } elseif ($args['id'] == 'sub_456') { + return \Stripe\Util\Util::convertToStripeObject([ + 'id' => 'sub_456', + 'discount' => null, + 'schedule' => [ + 'id' => 'sub_sched', + 'phases' => [ + ], + ], + 'plan' => [ + 'amount' => '4167', + 'id' => 'twfy-5k', + 'nickname' => 'Many calls per month', + 'interval' => 'month', + ], + 'cancel_at_period_end' => false, + 'created' => time(), + 'current_period_end' => time(), + 'latest_invoice' => [], + 'customer' => [ + 'id' => 'cus_456', + 'balance' => 0, + 'default_source' => [], + 'invoice_settings' => [ + 'default_payment_method' => [], + ], + ], + ], null); } return \Stripe\Util\Util::convertToStripeObject([], null); } @@ -51,8 +79,37 @@ public function updateCustomer($id, $args) { } public function createSubscription($args) { + if ($args['plan'] == 'twfy-5k') { + $id = 'sub_456'; + } else { + $id = 'sub_123'; + } + return \Stripe\Util\Util::convertToStripeObject([ + 'id' => $id, + ], null); + } + + public function createSchedule($id) { return \Stripe\Util\Util::convertToStripeObject([ - 'id' => 'sub_123', + 'id' => 'schedule_1', + 'phases' => [ + [ + 'start_date' => time(), + 'end_date' => time(), + 'discounts' => null, + 'items' => [ + [ + 'price' => '5000', + ], + ], + ], + ], ], null); } + + public function updateSchedule($id, $phases) {} + + public function releaseSchedule($id) {} + + public function updateSubscription($id, $args) {} } diff --git a/tests/AcceptApiTest.php b/tests/AcceptApiTest.php index 2f6aa4479a..5d2f5ce570 100644 --- a/tests/AcceptApiTest.php +++ b/tests/AcceptApiTest.php @@ -156,4 +156,28 @@ public function testApiKeySignup() { $this->assertStringContainsString('It costs you £0/month.', $page); $this->assertStringContainsString('100% discount applied.', $page); } + + public function testApiKeyDowngrade() { + $page = $this->post_page('update-plan', [ + 'stripeToken' => 'TOKEN', + 'plan' => 'twfy-5k', + 'charitable_tick' => 'on', + 'charitable' => 'c', + 'charity_number' => '123456', + 'tandcs_tick' => 'on', + ]); + $this->assertEquals('Location: /api/key?updated=1', $page); + $page = $this->get_page('key', ['updated' => 1]); + $this->assertStringContainsString('Your current plan is Many calls per month.', $page); + $this->assertStringContainsString('It costs you £50/month.', $page); + + $page = $this->post_page('update-plan', [ + 'plan' => 'twfy-1k', + 'charitable_tick' => 'on', + 'charitable' => 'c', + 'charity_number' => '123456', + 'tandcs_tick' => 'on', + ]); + $page = $this->get_page('key', ['updated' => 1]); + } } diff --git a/www/docs/api/cancel-plan.php b/www/docs/api/cancel-plan.php index bcfe383a01..d070cba52b 100644 --- a/www/docs/api/cancel-plan.php +++ b/www/docs/api/cancel-plan.php @@ -18,11 +18,7 @@ print 'CSRF validation failure!'; exit; } - - if ($subscription->stripe->schedule) { - \Stripe\SubscriptionSchedule::release($subscription->stripe->schedule); - } - \Stripe\Subscription::update($subscription->stripe->id, ['cancel_at_period_end' => true]); + $subscription->cancel_subscription(); redirect('/api/key?cancelled=1'); }