Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

billing: automated billing & pay as you go usage billing #1773

Merged
merged 96 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
4c0cbb7
billing: overusage
gioelecerati Jun 15, 2023
b394021
handle expired subscriptions and null usage
gioelecerati Jun 15, 2023
4ac2d3d
get subscription status
gioelecerati Jun 15, 2023
ab43ba6
timestamp to millis
gioelecerati Jun 15, 2023
91e3ac7
0 on null usage
gioelecerati Jun 15, 2023
668c292
usage: handle null usage
gioelecerati Jul 28, 2023
66b5a03
default billing usage
gioelecerati Jun 15, 2023
290a95c
null usage
gioelecerati Jun 15, 2023
d98b099
overusage
gioelecerati Jul 28, 2023
73a5532
overusage
gioelecerati Jun 20, 2023
4e0a42b
overusage
gioelecerati Jul 28, 2023
d8ff517
overusage
gioelecerati Jun 20, 2023
30f9a1a
overusage
gioelecerati Jun 20, 2023
7f88d2f
billing: debug
gioelecerati Jun 20, 2023
4e5e6da
billing: debug
gioelecerati Jun 20, 2023
21ef3c8
billing: connected prod products
gioelecerati Jun 26, 2023
d42a0aa
billing: added migration apis
gioelecerati Jun 26, 2023
1b18a25
stripe.js to stripe.ts & usage report
gioelecerati Jun 27, 2023
b00cb2c
allow staging plan select
gioelecerati Jun 27, 2023
1b30b3c
tmp subscription item
gioelecerati Jun 27, 2023
716a1ee
tmp switch to product id
gioelecerati Jul 28, 2023
e606698
tmp: fixed billing cycle for tests
gioelecerati Jun 28, 2023
6b8e563
billing: calculate overusage into upcoming invoice
gioelecerati Jun 29, 2023
0524753
billing: deprecated property on products
gioelecerati Jun 29, 2023
732b062
billing: added pay as you go items to update subscription
gioelecerati Jun 29, 2023
1b31161
billing: bill at the end of the cycle
gioelecerati Jun 29, 2023
fc5b551
billing: upcoming invoice
gioelecerati Jun 29, 2023
b6c69e2
billing: fix
gioelecerati Jun 29, 2023
892e36d
billing: fix
gioelecerati Jun 29, 2023
7d2122b
billing: clear usage on update only when product is metered
gioelecerati Jun 29, 2023
5589d59
billing: pay as you go lookup keys
gioelecerati Jun 29, 2023
61f5e71
billing: restore plan select
gioelecerati Jun 29, 2023
2ab3822
billing: report usage for each subscription item correctly
gioelecerati Jun 29, 2023
854be95
billing: retrieve upcoming invoices directly from stripe
gioelecerati Jun 29, 2023
9d2b53f
billing: upcoming invoice
gioelecerati Jun 29, 2023
7985849
billing: added stripeCustomerId to upcoming invoice api
gioelecerati Jun 29, 2023
501ca18
billing: fix upcoming invoice request!
gioelecerati Jun 29, 2023
4d0a47c
billing: display stripe upcoming invoice total
gioelecerati Jul 28, 2023
c86ba7a
billing: return subscription items
gioelecerati Jun 29, 2023
579ec29
billing: display invoice breakdown in billing page
gioelecerati Jun 29, 2023
e670d98
billing: display invoice breakdown in billing page
gioelecerati Jun 29, 2023
340c370
billing: display invoice breakdown in billing page
gioelecerati Jun 29, 2023
0ef03eb
billing: better upcoming invoice
gioelecerati Jun 29, 2023
0186b65
billing: billing page
gioelecerati Jun 29, 2023
6aa7e57
billing: show prices and limits on upcoming invoice table
gioelecerati Jun 29, 2023
473cb45
billing: better units display
gioelecerati Jun 29, 2023
7b89153
billing: fix position of monthly price
gioelecerati Jun 29, 2023
5e963af
billing: fix position of monthly price
gioelecerati Jun 29, 2023
3316802
billing: fix position of monthly price
gioelecerati Jun 29, 2023
6ab2897
billing: address some ui comments
gioelecerati Jun 29, 2023
e0a5f85
billing: address some ui comments
gioelecerati Jun 29, 2023
e487ea5
billing: address some ui comments
gioelecerati Jun 29, 2023
3dfaeb5
billing: address some ui comments
gioelecerati Jun 29, 2023
2a5e177
billing: address some ui comments
gioelecerati Jun 29, 2023
dd17bec
billing: address some ui comments
gioelecerati Jun 29, 2023
21a736e
billing: reset billing cycle on subscription update
gioelecerati Jun 29, 2023
c669510
billing: empty usage
gioelecerati Jun 29, 2023
b01417a
billing: empy usage
gioelecerati Jun 30, 2023
89d523f
billing: debug empty usage
gioelecerati Jun 30, 2023
a917615
usage: report usage cron
gioelecerati Jul 5, 2023
d77f456
usage: fixed billing cycle for report usage testing
gioelecerati Jul 5, 2023
4f5251b
usage: fixed pay as you go plans for staging
gioelecerati Jul 5, 2023
6328e01
usage: fix report usage query
gioelecerati Jul 5, 2023
546c18f
usage: fix report query
gioelecerati Jul 6, 2023
8bd08f5
usage: report usage fix
gioelecerati Jul 6, 2023
41c4ad4
usage: added ingest origin for billing usage call
gioelecerati Jul 6, 2023
04e0148
usage: report usage subscription items
gioelecerati Jul 6, 2023
f9f5229
usage: report usage cron
gioelecerati Jul 6, 2023
fd30450
usage: report usage cron response
gioelecerati Jul 6, 2023
3355417
usage: report quantity of usage as number
gioelecerati Jul 6, 2023
46e919d
usage: fix report timestamp & response
gioelecerati Jul 6, 2023
cdc8eb9
usage: report usage response
gioelecerati Jul 6, 2023
1bad128
usage: cron: use api token for billing usage call
gioelecerati Jul 6, 2023
175dc96
usage: fix name of delivery product for usage report
gioelecerati Jul 6, 2023
9294bd1
usage: remove test timestamps & update migration api to work in batches
gioelecerati Jul 7, 2023
9cea0fa
billing: migrate test products users to prod, in batches
gioelecerati Jul 7, 2023
8ca85b7
billing: migrate personal users to hacker api fix
gioelecerati Jul 7, 2023
d3e1341
billing: do not migrate users with a canceled or inactive subscription
gioelecerati Jul 7, 2023
012d1ca
billing: check if subscription exists on migrate api
gioelecerati Jul 7, 2023
4d20a6d
billing: added subscription items to migration sub update
gioelecerati Jul 7, 2023
1c64530
billing: added api to migrate Pro users to hacker plan + pay as you go
gioelecerati Jul 7, 2023
221109b
billing: avoid migration apis to run forever
gioelecerati Jul 7, 2023
ea1f1f3
billing: modify the migration apis to address review comments
gioelecerati Jul 13, 2023
d548e6f
billing: skip user migration when subscription is canceled or missing
gioelecerati Jul 13, 2023
626d08b
billing: keep track of inactive subscriptions
gioelecerati Jul 14, 2023
2250127
billing: fix query boolean
gioelecerati Jul 14, 2023
f4acbf6
billing: fix user check
gioelecerati Jul 14, 2023
73fccd0
billing: added migration api to revert users to personal for testing
gioelecerati Jul 14, 2023
6c60437
billing: select null active subscription as well on migration
gioelecerati Jul 21, 2023
95cf599
billing: don't migrate if stripe customer is missing
gioelecerati Jul 21, 2023
f40f882
billing: added migrations log
gioelecerati Jul 21, 2023
e7e93bc
billing: exclude june users from personal migration
gioelecerati Jul 21, 2023
777e7d6
billing: fix query
gioelecerati Jul 21, 2023
db11514
fix conflicts
gioelecerati Jul 28, 2023
b0ddb04
billing: update pay as you go prices
gioelecerati Jul 28, 2023
77d2ebe
usage: restore charts
gioelecerati Jul 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 163 additions & 10 deletions packages/api/src/config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
exports.products = {
prod_0: {
deprecated: true,
order: 0,
name: "Personal",
lookupKeys: ["price_0"],
Expand All @@ -8,22 +9,52 @@ exports.products = {
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0.0,
limit: 1_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0.0,
limit: 1_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0.0,
limit: 1_000,
},
],
monthlyPrice: 0,
},
prod_1: {
deprecated: true,
order: 1,
name: "Pro",
lookupKeys: ["price_1"],
usage: [
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0.005,
price: 0.0055,
limit: 3_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0.0005,
limit: 100_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0.0035,
limit: 10_000,
},
],
monthlyPrice: 0,
},
prod_2: {
deprecated: true,
order: 2,
name: "Business",
lookupKeys: ["price_2"],
Expand All @@ -34,28 +65,34 @@ exports.products = {
price: 0.0,
},
],
monthlyPrice: 0,
},
hacker_1: {
order: 3,
name: "Hacker",
lookupKeys: ["hacker_1"],
price: 0,
usage: [
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0,
limit: 1_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0,
limit: 1_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0,
limit: 1_000,
},
],
monthlyPrice: 0,
},
growth_1: {
order: 4,
Expand All @@ -65,19 +102,24 @@ exports.products = {
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0,
price: 0.0055,
limit: 3_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0,
price: 0.0005,
limit: 100_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0,
price: 0.0035,
limit: 10_000,
},
],
monthlyPrice: 100,
payAsYouGo: true,
},
scale_1: {
order: 5,
Expand All @@ -87,19 +129,24 @@ exports.products = {
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0,
price: 0.0055,
limit: 20_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0,
price: 0.0005,
limit: 500_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0,
price: 0.0035,
limit: 50_000,
},
],
monthlyPrice: 500,
payAsYouGo: true,
},
pay_as_you_go_1: {
order: 6,
Expand All @@ -109,21 +156,23 @@ exports.products = {
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0.005,
price: 0.0055,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0.0004,
price: 0.0005,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0.003,
price: 0.0035,
},
],
monthlyPrice: 0,
},
prod_4: {
deprecated: true,
order: 7,
name: "Enterprise",
lookupKeys: ["enterprise_1"],
Expand All @@ -144,5 +193,109 @@ exports.products = {
price: 0,
},
],
monthlyPrice: 0,
},
prod_O9XuIjn7EqYRVW: {
order: 8,
name: "Hacker",
lookupKeys: ["hacker_1"],
usage: [
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0,
limit: 1_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0,
limit: 1_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0,
limit: 1_000,
},
],
monthlyPrice: 0,
},
prod_O9XtHhI6rbTT1B: {
order: 9,
name: "Growth",
lookupKeys: ["growth_1"],
usage: [
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0.0055,
limit: 3_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0.0005,
limit: 100_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0.0035,
limit: 10_000,
},
],
monthlyPrice: 100,
payAsYouGo: true,
},
prod_O9XtcfOSMjSD5L: {
order: 10,
name: "Scale",
lookupKeys: ["scale_1"],
usage: [
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0.0055,
limit: 20_000,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0.0005,
limit: 500_000,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0.0035,
limit: 50_000,
},
],
monthlyPrice: 500,
payAsYouGo: true,
},
prod_O9XuWMU1Up6QKf: {
order: 11,
name: "Pay-As-You-Go",
lookupKeys: ["transcoding_usage", "tstreaming_usage", "tstorage_usage"],
usage: [
{
name: "Transcoding",
description: "Transcoding (minutes)",
price: 0.0055,
},
{
name: "Delivery",
description: "Delivery (minutes)",
price: 0.0005,
},
{
name: "Storage",
description: "Storage (minutes)",
price: 0.0035,
},
],
monthlyPrice: 0,
},
};
23 changes: 23 additions & 0 deletions packages/api/src/controllers/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,29 @@ export async function sendgridEmail({
await SendgridMail.send(msg);
}

export async function sendgridEmailPaymentFailed({
email,
sendgridApiKey,
userId,
invoiceId,
}) {
const [supportName, supportEmail] = email;
const msg = {
text: `User ${userId} failed to pay invoice ${invoiceId}`,
from: {
email: supportEmail,
name: supportName,
},
reply_to: {
email: supportEmail,
name: supportName,
},
};

SendgridMail.setApiKey(sendgridApiKey);
await SendgridMail.send(msg);
}

export function sendgridValidateEmail(email: string, validationApiKey: string) {
if (!validationApiKey) {
return;
Expand Down
Loading
Loading