Skip to content

Commit

Permalink
Move from Stripe Plans to Prices.
Browse files Browse the repository at this point in the history
No change in functionality.
  • Loading branch information
dracos committed Oct 10, 2024
1 parent 370651f commit 8acbeb0
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 68 deletions.
49 changes: 25 additions & 24 deletions classes/Subscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class Subscription {
public $upcoming;
public $has_payment_data = false;

private static $plans = ['twfy-1k', 'twfy-5k', 'twfy-10k', 'twfy-0k'];
private static $prices = [2000, 5000, 10000, 30000];
private static $prices = ['twfy-1k', 'twfy-5k', 'twfy-10k', 'twfy-0k'];
private static $amounts = [2000, 5000, 10000, 30000];

public function __construct($arg) {
# User ID
Expand Down Expand Up @@ -63,9 +63,10 @@ public function __construct($arg) {
'customer.default_source',
'customer.invoice_settings.default_payment_method',
'latest_invoice.payment_intent',
'schedule.phases.items.plan',
'schedule.phases.items.price',
],
]);
$this->stripe->price = $this->stripe->items[0]->price;
} catch (\Stripe\Exception\InvalidRequestException $e) {
$this->db->query('DELETE FROM api_subscription WHERE stripe_id = :stripe_id', [':stripe_id' => $id]);
$this->delete_from_redis();
Expand All @@ -82,12 +83,12 @@ public function __construct($arg) {
$data = $this->stripe;
if ($data->discount && $data->discount->coupon && $data->discount->coupon->percent_off) {
$this->actual_paid = add_vat(floor(
$data->plan->amount * (100 - $data->discount->coupon->percent_off) / 100
$data->price->unit_amount * (100 - $data->discount->coupon->percent_off) / 100
));
$data->plan->amount = add_vat($data->plan->amount);
$data->price->unit_amount = add_vat($data->price->unit_amount);
} else {
$data->plan->amount = add_vat($data->plan->amount);
$this->actual_paid = $data->plan->amount;
$data->price->unit_amount = add_vat($data->price->unit_amount);
$this->actual_paid = $data->price->unit_amount;
}

try {
Expand All @@ -101,17 +102,17 @@ private function update_subscription($form_data) {
$this->update_payment_method($form_data['payment_method']);
}

foreach ($this::$plans as $i => $plan) {
if ($plan == $form_data['plan']) {
$new_price = $this::$prices[$i];
foreach ($this::$prices as $i => $price) {
if ($price == $form_data['price']) {
$new_price = $this::$amounts[$i];
if ($form_data['coupon'] == 'charitable100') {
$new_price = 0;
} elseif ($form_data['coupon'] == 'charitable50') {
$new_price /= 2;
}
}
if ($plan == $this->stripe->plan->id) {
$old_price = $this::$prices[$i];
if ($price == $this->stripe->price->id) {
$old_price = $this::$amounts[$i];
if ($this->stripe->discount && ($coupon = $this->stripe->discount->coupon)) {
if ($coupon->percent_off == 100) {
$old_price = 0;
Expand All @@ -136,7 +137,7 @@ private function update_subscription($form_data) {
'default_tax_rates' => [STRIPE_TAX_RATE],
],
[
'items' => [['price' => $form_data['plan']]],
'items' => [['price' => $form_data['price']]],
'iterations' => 1,
'metadata' => $form_data['metadata'],
'proration_behavior' => 'none',
Expand All @@ -155,7 +156,7 @@ private function update_subscription($form_data) {
if ($old_price < $new_price) {
$args = [
'payment_behavior' => 'allow_incomplete',
'plan' => $form_data['plan'],
'items' => [['price' => $form_data['price']]],
'metadata' => $form_data['metadata'],
'cancel_at_period_end' => false, # Needed in Stripe 2018-02-28
'proration_behavior' => 'always_invoice',
Expand Down Expand Up @@ -212,7 +213,7 @@ private function add_subscription($form_data) {

$customer = $obj->id;

if (!$form_data['stripeToken'] && !($form_data['plan'] == $this::$plans[0] && $form_data['coupon'] == 'charitable100')) {
if (!$form_data['stripeToken'] && !($form_data['price'] == $this::$prices[0] && $form_data['coupon'] == 'charitable100')) {
exit(1); # Should never reach here!
}

Expand All @@ -221,7 +222,7 @@ private function add_subscription($form_data) {
'expand' => ['latest_invoice.payment_intent'],
'default_tax_rates' => [STRIPE_TAX_RATE],
'customer' => $customer,
'plan' => $form_data['plan'],
'items' => [['price' => $form_data['price']]],
'coupon' => $form_data['coupon'],
'metadata' => $form_data['metadata'],
]);
Expand All @@ -243,21 +244,21 @@ public function invoices() {
}

private function getFields() {
$fields = ['plan', 'charitable_tick', 'charitable', 'charity_number', 'description', 'tandcs_tick', 'stripeToken', 'payment_method'];
$fields = ['price', 'charitable_tick', 'charitable', 'charity_number', 'description', 'tandcs_tick', 'stripeToken', 'payment_method'];
$this->form_data = [];
foreach ($fields as $field) {
$this->form_data[$field] = get_http_var($field);
}
}

private function checkValidPlan() {
return ($this->form_data['plan'] && in_array($this->form_data['plan'], $this::$plans));
private function checkValidPrice() {
return ($this->form_data['price'] && in_array($this->form_data['price'], $this::$prices));
}

private function checkPaymentGivenIfNeeded() {
$payment_data = $this->form_data['stripeToken'] || $this->form_data['payment_method'];
return ($this->has_payment_data || $payment_data || (
$this->form_data['plan'] == $this::$plans[0]
$this->form_data['price'] == $this::$prices[0]
&& in_array($this->form_data['charitable'], ['c', 'i'])
));
}
Expand All @@ -271,7 +272,7 @@ public function checkForErrors() {
$form_data['charitable'] = '';
}

if (!$this->checkValidPlan()) {
if (!$this->checkValidPrice()) {
$errors[] = 'Please pick a plan';
}

Expand Down Expand Up @@ -306,7 +307,7 @@ public function createOrUpdateFromForm() {
$form_data['coupon'] = null;
if (in_array($form_data['charitable'], ['c', 'i'])) {
$form_data['coupon'] = 'charitable50';
if ($form_data['plan'] == $this::$plans[0]) {
if ($form_data['price'] == $this::$prices[0]) {
$form_data['coupon'] = 'charitable100';
}
}
Expand All @@ -324,8 +325,8 @@ public function createOrUpdateFromForm() {
}
}

public function redis_update_max($plan) {
preg_match('#^twfy-(\d+)k#', $plan, $m);
public function redis_update_max($price) {
preg_match('#^twfy-(\d+)k#', $price, $m);
$max = $m[1] * 1000;
$this->redis->set("$this->redis_prefix:max", $max);
$this->redis->del("$this->redis_prefix:blocked");
Expand Down
14 changes: 8 additions & 6 deletions classes/TestStripe.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ public function getSubscription($args) {
'coupon' => ['percent_off' => 100],
'end' => null,
],
'plan' => [
'amount' => '2000',
'id' => 'twfy-1k',
'nickname' => 'Some calls per month',
'interval' => 'month',
],
'items' => [ [
'price' => [
'unit_amount' => '2000',
'id' => 'twfy-1k',
'nickname' => 'Some calls per month',
'interval' => 'month',
],
] ]
'cancel_at_period_end' => false,
'created' => time(),
'current_period_end' => time(),
Expand Down
2 changes: 1 addition & 1 deletion tests/AcceptApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function testApiKeySignup() {
$page = $this->post_page('key');
$this->assertStringContainsString('Subscribe to a plan', $page);
$page = $this->post_page('update-plan', [
'plan' => 'twfy-1k',
'price' => 'twfy-1k',
'charitable_tick' => 'on',
'charitable' => 'c',
'charity_number' => '123456',
Expand Down
6 changes: 3 additions & 3 deletions www/docs/api/hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
} elseif ($event->type == 'customer.subscription.updated') {
$sub = new \MySociety\TheyWorkForYou\Subscription($obj->id);
if ($sub->stripe) {
$sub->redis_update_max($obj->plan->id);
$sub->redis_update_max($obj->items[0]->price->id);
}
} elseif ($event->type == 'invoice.payment_failed' && $obj->billing_reason == 'subscription_cycle' && stripe_twfy_sub($obj)) {
$customer = \Stripe\Customer::retrieve($obj->customer);
Expand All @@ -51,7 +51,7 @@
$sub = new \MySociety\TheyWorkForYou\Subscription($obj->subscription);
}
if ($sub->stripe) {
$sub->redis_update_max($sub->stripe->plan->id);
$sub->redis_update_max($sub->stripe->items[0]->price->id);
}
try {
# Update the invoice's PaymentIntent and Charge to say it came from TWFY (for CSV export)
Expand Down Expand Up @@ -83,7 +83,7 @@ function stripe_twfy_sub($invoice) {
return false;
}
$stripe_sub = \Stripe\Subscription::retrieve($invoice->subscription);
return substr($stripe_sub->plan->id, 0, 4) == 'twfy';
return substr($stripe_sub->items[0]->price->id, 0, 4) == 'twfy';
}

function stripe_reset_quota($subscription) {
Expand Down
2 changes: 1 addition & 1 deletion www/docs/api/update-plan.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
$errors = [];

MySociety\TheyWorkForYou\Utility\Session::start();
if (get_http_var('plan')) {
if (get_http_var('price')) {
if (!Volnix\CSRF\CSRF::validate($_POST)) {
print 'CSRF validation failure!';
exit;
Expand Down
28 changes: 14 additions & 14 deletions www/docs/js/payment.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
(function() {

function plan_cost() {
var plan = document.querySelector('input[name=plan]:checked'),
function price_cost() {
var price = document.querySelector('input[name=price]:checked'),
ctick = document.getElementById('id_charitable_tick'),
charitable = document.querySelector('input[name=charitable]:checked');
plan = plan ? plan.value : '';
price = price ? price.value : '';
ctick = ctick ? ctick.checked : '';
charitable = charitable ? charitable.value : '';

var num = 20;
if (plan === 'twfy-5k') {
if (price === 'twfy-5k') {
num = 50;
} else if (plan === 'twfy-10k') {
} else if (price === 'twfy-10k') {
num = 100;
} else if (plan === 'twfy-0k') {
} else if (price === 'twfy-0k') {
num = 300;
}
if (ctick) {
Expand All @@ -29,7 +29,7 @@ function plan_cost() {
}

function need_stripe() {
var num = plan_cost();
var num = price_cost();
if (num === 0 || document.getElementById('js-payment').getAttribute('data-has-payment-data')) {
return false;
}
Expand All @@ -46,11 +46,11 @@ function toggle_stripe() {
}
}

if (document.getElementById('id_plan_0')) {
document.getElementById('id_plan_0').addEventListener('change', toggle_stripe);
document.getElementById('id_plan_1').addEventListener('change', toggle_stripe);
document.getElementById('id_plan_2').addEventListener('change', toggle_stripe);
document.getElementById('id_plan_3').addEventListener('change', toggle_stripe);
if (document.getElementById('id_price_0')) {
document.getElementById('id_price_0').addEventListener('change', toggle_stripe);
document.getElementById('id_price_1').addEventListener('change', toggle_stripe);
document.getElementById('id_price_2').addEventListener('change', toggle_stripe);
document.getElementById('id_price_3').addEventListener('change', toggle_stripe);
document.getElementById('id_charitable_tick').addEventListener('click', function(e) {
if (this.checked) {
document.getElementById('charitable-qns').style.display = 'block';
Expand Down Expand Up @@ -185,8 +185,8 @@ form && form.addEventListener('submit', function(e) {
e.preventDefault();

var errors = 0;
var plan = document.querySelector('input[name=plan]:checked');
errors += err_highlight(document.querySelector('label[for=id_plan_0]'), !plan);
var price = document.querySelector('input[name=price]:checked');
errors += err_highlight(document.querySelector('label[for=id_price_0]'), !price);
var ctick = document.getElementById('id_charitable_tick').checked;
var c = document.querySelector('input[name=charitable]:checked');
errors += err_highlight(document.querySelector('label[for=id_charitable_0]'), ctick && !c);
Expand Down
8 changes: 4 additions & 4 deletions www/includes/easyparliament/templates/html/api/check.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
Sorry, your card has been declined. Perhaps you can try another?
</div>

<?php if ($subscription->stripe->plan) { ?>
<p>You are subscribing to <strong><?= $subscription->stripe->plan->nickname ?></strong>,
<?php if ($subscription->stripe->price) { ?>
<p>You are subscribing to <strong><?= $subscription->stripe->price->nickname ?></strong>,

costing £<?= $subscription->actual_paid ?>/<?= $subscription->stripe->plan->interval ?>.
costing £<?= $subscription->actual_paid ?>/<?= $subscription->stripe->price->interval ?>.
<?php if ($subscription->stripe->discount) { ?>
<?= $subscription->stripe->plan->amount ?>/<?= $subscription->stripe->plan->interval ?> with
<?= $subscription->stripe->price->unit_amount ?>/<?= $subscription->stripe->price->interval ?> with
<?= $subscription->stripe->discount->coupon->percent_off ?>% discount applied.)
<?php } ?>
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<?php if ($quota_status['blocked']) { ?>
<?php if ($quota_status['quota'] > 0 && $quota_status['count'] > $quota_status['quota']) { ?>
<p class="attention-box warning">
You have used up your quota for the <?= $subscription->stripe->plan->interval ?>.
You have used up your quota for the <?= $subscription->stripe->price->interval ?>.
Please <a href="/api/update-plan">upgrade</a>
or <a href="/contact/">contact us</a>.
</p>
Expand All @@ -29,19 +29,19 @@
<?php } ?>
<?php } ?>

<?php if ($subscription->stripe->plan) { ?>
<?php if ($subscription->stripe->price) { ?>

<p>Your current plan is <strong><?= $subscription->stripe->plan->nickname ?></strong>.</p>
<p>Your current plan is <strong><?= $subscription->stripe->price->nickname ?></strong>.</p>

<p>It costs you £<?= $subscription->actual_paid ?>/<?= $subscription->stripe->plan->interval ?>.
<p>It costs you £<?= $subscription->actual_paid ?>/<?= $subscription->stripe->price->interval ?>.
<?php if ($subscription->stripe->discount) { ?>
<?= $subscription->stripe->plan->amount ?>/<?= $subscription->stripe->plan->interval ?> with
<?= $subscription->stripe->price->unit_amount ?>/<?= $subscription->stripe->price->interval ?> with
<?= $subscription->stripe->discount->coupon->percent_off ?>% discount applied.)
<?php } ?>
</p>

<?php if ($subscription->stripe->schedule->phases[1] && $subscription->stripe->schedule->phases[1]->items[0]->plan->nickname != $subscription->stripe->plan->nickname) { ?>
<p>You are switching to <strong><?php $subscription->stripe->schedule->phases[1]->items[0]->plan->nickname ?></strong> at the end of your current period.</p>
<?php if ($subscription->stripe->schedule->phases[1] && $subscription->stripe->schedule->phases[1]->items[0]->price->nickname != $subscription->stripe->price->nickname) { ?>
<p>You are switching to <strong><?php $subscription->stripe->schedule->phases[1]->items[0]->price->nickname ?></strong> at the end of your current period.</p>
<?php } ?>

<?php if ($subscription->stripe->discount && $subscription->stripe->discount->end) { ?>
Expand Down Expand Up @@ -79,7 +79,7 @@
<h3>Your usage</h3>

<p>
This <?= $subscription->stripe->plan->interval ?>:
This <?= $subscription->stripe->price->interval ?>:
<?= number_format($quota_status['count']) ?>
<?php if ($quota_status['quota'] > 0) { ?>
out of <?= number_format($quota_status['quota']) ?>
Expand Down
14 changes: 7 additions & 7 deletions www/includes/easyparliament/templates/html/api/update.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ function rdio($name, $value, $text, $id, $required = false, $checked = false) {


<div class="row">
<label for="id_plan_0">Please choose a plan (all prices include VAT):</label>
<ul id="id_plan">
<label for="id_price_0">Please choose a plan (all prices include VAT):</label>
<ul id="id_price">
<?php
$plan = $stripe ? $stripe->plan->id : get_http_var('plan');
rdio('plan', 'twfy-1k', '£20/mth – 1,000 calls per month', 'id_plan_0', 1, $plan);
rdio('plan', 'twfy-5k', '£50/mth – 5,000 calls per month', 'id_plan_1', 1, $plan);
rdio('plan', 'twfy-10k', '£100/mth – 10,000 calls per month', 'id_plan_2', 1, $plan);
rdio('plan', 'twfy-0k', '£300/mth – Unlimited calls', 'id_plan_3', 1, $plan);
$price = $stripe ? $stripe->price->id : get_http_var('price');
rdio('price', 'twfy-1k', '£20/mth – 1,000 calls per month', 'id_price_0', 1, $price);
rdio('price', 'twfy-5k', '£50/mth – 5,000 calls per month', 'id_price_1', 1, $price);
rdio('price', 'twfy-10k', '£100/mth – 10,000 calls per month', 'id_price_2', 1, $price);
rdio('price', 'twfy-0k', '£300/mth – Unlimited calls', 'id_price_3', 1, $price);
?>
</ul>
</div>
Expand Down

0 comments on commit 8acbeb0

Please sign in to comment.