10BC0 [draft] init payments by atharvadeosthale · Pull Request #10573 · appwrite/appwrite · GitHub
[go: up one dir, main page]

Skip to content

Conversation

atharvadeosthale
Copy link
Member

No description provided.

@atharvadeosthale atharvadeosthale marked this pull request as draft September 30, 2025 18:15
Copy link
Contributor
coderabbitai bot commented Sep 30, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch auth-subscriptions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
pkg-pr-new bot commented Sep 30, 2025

Open in StackBlitz

npm i https://pkg.pr.new/appwrite/appwrite/@appwrite.io/console@10573

commit: d49bad0

Copy link
github-actions bot commented Sep 30, 2025

Security Scan Results for PR

Docker Image Scan Results

Package Version Vulnerability Severity
libexpat 2.7.1-r0 CVE-2025-59375 HIGH
golang.org/x/crypto v0.31.0 CVE-2025-22869 HIGH
golang.org/x/oauth2 v0.24.0 CVE-2025-22868 HIGH
stdlib 1.22.10 CVE-2025-47907 HIGH

Source Code Scan Results

🎉 No vulnerabilities found!

Copy link

✨ Benchmark results

  • Requests per second: 1,155
  • Requests with 200 status code: 207,858
  • P99 latency: 0.168969618

⚡ Benchmark Comparison

Metric This PR Latest version
RPS 1,155 967
200 207,858 174,083
P99 0.168969618 0.199045559

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be called auth_plans. It should live in one of the existing files. In tis case the projects.php file because each project will need to have these collections.

'filters' => [],
],
[
'$id' => ID::custom('planId'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for a planId, we should always rely on the built-in _uid (aka "$id").

'filters' => [],
],
[
'$id' => ID::custom('stripePriceId'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should never tie Appwrite to a specific vendor. This is how vendor locking gets created. Instead it should be providerType, providerId or something like that. You should check if we have a similar pattern in another collection and follow it for consistency. Consistency is a huge part in creating great DX. People want to leverage knowledge they gained from using something like Appwrite Messaging and feel like Appwrite Payments works the same way.

'filters' => [],
],
[
'$id' => ID::custom('stripeMeterId'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for all mentions of Stripe in the source code.

'filters' => [],
],
[
'$id' => ID::custom('interval'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What unit is being used here? Let's add a comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple intervals are supported (daily, weekly, monthly, yearly)

'filters' => ['json'],
],
[
'$id' => ID::custom('usageCap'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this include the base plan price or not?

],
],
],
'auth_usage_events' => [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this for measuring usage? We might better use our own usage or rely on the provider's solution all together.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's crucial to use both - we enforce usage caps.

Stripe's ingestion is asynchronous and does not reflect immediately, so, someone can manage to spam their way out of usage caps.

If we use our own meters, we will need to handle billing the user at the end of cycle, not a headache worth having.

It's in DB for instant updates to apps, and also sent to Stripe for billing to occur.

'filters' => ['datetime'],
],
[
'$id' => ID::custom('authSubscriptionsEnabled'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issues with vendor locking and stripe, Imagine tomorrow a new product called UltraPayments comes in to the picture and is better than Stripe in every aspect, we need to be able to switch or support both,

'filters' => ['datetime'],
],
[
'$id' => ID::custom('authSubscriptionsEnabled'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be easier here to follow what we do for auth and just have a single json attribute for payments containing all the configs we need.

'filters' => ['datetime'],
],
[
'$id' => ID::custom('planId'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stripe vendor locking here again. Also, we don't want to couple plans with specific users, we need to fine a solution to be able to use them for both users or teams. I would avoid changing teams and users collections and rely one the new collections to create the link, this link is probably a subscriptions collection.

Copy link
Member
@eldadfux eldadfux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should rely on auth, but you should avoid trying to extend /v1/account as much ass possible. It’s better for us to treat this as a totally new service. v1/payments

For v1/payments - we should imitate how new services in Appwrite are built. Look at Functions or Sites for inspiration we use a class based format to define routes unlike what we do in old controllers. We also have a test classes per route and not per service. You can use something like cursor with proper example to the agent to easily convert between the two.

We should find a way to attach a plan or payment to either a team or a user. Teams are crucial for multi-tenant saas products.

'optional' => false,
'icon' => '',
],
'authPlans' => [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a service in Appwrite. As mentioned on the PR comment, we should create a new v1/payments service to centralize all these APIs.

return $response->noContent();
});

App::get('/v1/account/subscription')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a REST compatible API. In rest entities should be plurals.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0