Charge tax on products (#4361)

* Initial Anrok integration

* Query cache, fmt, clippy

* Fmt

* Use payment intent function in edit_subscription

* Attach Anrok client, use payments in index_billing

* Integrate Anrok with refunds

* Bug fixes

* More bugfixes

* Fix resubscriptions

* Medal promotion bugfixes

* Use stripe metadata constants everywhere

* Pre-fill values in products_tax_identifiers

* Cleanup billing route module

* Cleanup

* Email notification for tax charge

* Don't charge tax on users which haven't been notified of tax change

* Fix taxnotification.amount templates

* Update .env.docker-compose

* Update .env.local

* Clippy

* Fmt

* Query cache

* Periodically update tax amount on upcoming charges

* Fix queries

* Skip indexing tax amount on charges if no charges to process

* chore: query cache, clippy, fmt

* Fix a lot of things

* Remove test code

* chore: query cache, clippy, fmt

* Fix money formatting

* Fix conflicts

* Extra documentation, handle tax association properly

* Track loss in tax drift

* chore: query cache, clippy, fmt

* Add subscription.id variable

* chore: query cache, clippy, fmt

* chore: query cache, clippy, fmt
This commit is contained in:
François-Xavier Talbot
2025-09-25 12:29:29 +01:00
committed by GitHub
parent 47020f34b6
commit 4228a193e9
44 changed files with 3438 additions and 1330 deletions

View File

@@ -0,0 +1,24 @@
ALTER TABLE charges ADD COLUMN tax_amount BIGINT NOT NULL DEFAULT 0;
ALTER TABLE charges ADD COLUMN tax_platform_id TEXT;
ALTER TABLE products ADD COLUMN name TEXT;
CREATE TABLE products_tax_identifiers (
id SERIAL PRIMARY KEY,
tax_processor_id TEXT NOT NULL,
product_id BIGINT REFERENCES products (id) NOT NULL
);
INSERT INTO products_tax_identifiers (tax_processor_id, product_id)
SELECT
'modrinth-servers' AS tax_processor_id,
id AS product_id
FROM products
WHERE metadata ->> 'type' = 'pyro';
INSERT INTO products_tax_identifiers (tax_processor_id, product_id)
SELECT
'modrinth-plus' AS tax_processor_id,
id AS product_id
FROM products
WHERE metadata ->> 'type' = 'midas';

View File

@@ -0,0 +1,45 @@
ALTER TABLE charges ADD COLUMN tax_last_updated TIMESTAMPTZ;
ALTER TABLE charges ADD COLUMN tax_drift_loss BIGINT;
INSERT INTO notifications_types
(name, delivery_priority, expose_in_user_preferences, expose_in_site_notifications)
VALUES ('tax_notification', 2, FALSE, FALSE);
INSERT INTO users_notifications_preferences (user_id, channel, notification_type, enabled)
VALUES (NULL, 'email', 'tax_notification', TRUE);
INSERT INTO notifications_templates
(channel, notification_type, subject_line, body_fetch_url, plaintext_fallback)
VALUES
(
'email',
'tax_notification',
'Your subscription''s tax is changing',
'https://modrinth.com/email/subscription-tax-change',
CONCAT(
'Hi {user.name},',
CHR(10),
CHR(10),
'Your {taxnotification.service} subscription''s tax rate is changing. Starting with your next {taxnotification.billing_interval} payment, your {taxnotification.service} subscription''s, your charge and all future charges will be updated as follows:',
CHR(10),
CHR(10),
'Current subtotal: {taxnotification.old_amount}',
CHR(10),
'Current tax: {taxnotification.old_tax_amount}',
CHR(10),
'Current TOTAL: {taxnotification.old_total_amount}',
CHR(10),
CHR(10),
'New subtotal: {taxnotification.new_amount}',
CHR(10),
'New tax: {taxnotification.new_tax_amount}',
CHR(10),
'New TOTAL: {taxnotification.new_total_amount}',
CHR(10),
CHR(10),
'Note that the pre-tax price of your subscription has not changed, only the tax charged has changed as required by local tax regulations.',
CHR(10),
CHR(10),
'Thank your for using {taxnotification.service}.'
)
);