-
-
Notifications
You must be signed in to change notification settings - Fork 349
Description
Apologies if I'm thinking about this the wrong way or if this is related to Jumpstart instead of Pay. I'm pretty new to Rails, and this issue seems to be related to Pay, but I discovered it in Jumpstart.
Bug Report
Describe the Bug:
When creating a Pay Customer the processor_id must be unique. In Paddle Billing, the customer_id ("ctm_xyz") is used as the processor_id.
In Paddle Billing a customer can only have 1 email, but multiple Subscriptions. However the base Pay Customer has a uniqueness validation on it that prevents Account-based subscriptions, like what's found in Jumpstart, from creating additional Pay Subscriptions after the first one is created.
pay/app/models/pay/customer.rb
Line 14 in fdfc73e
| validates :processor_id, allow_blank: true, uniqueness: {scope: :processor, case_sensitive: true} |
Additionally, even if this uniqueness validator is removed, the sync method in the Paddle Billing subscription.rb used by webhooks to update/activate/cancel subscriptions will only ever find the first Pay Customer (Account in Jumpstart) for a given Paddle Billing Customer, not the Pay Customer by looking at the first row with the processor_id included in the webhook event:
| pay_customer = Pay::Customer.find_by(processor: :paddle_billing, processor_id: object.customer_id) |
The Pay Customer type and id is stored in the custom_data property of the Paddle Billing customer
With that custom data we should be able to look up the correct Pay Customer with that information instead of the processor_id (Paddle Billing customer_id). So the above pay_customer query should become:
pay_customer = Pay::Customer.find_by(processor: :paddle_billing, owner_id: object.custom_data.account) // account is Jumpstart specific. I assume this would become whatever model the Subscription is attached to
To Reproduce:
The easiest way to reproduce would be to use a Jumpstart account and a Paddle Sandbox account
- In Paddle Sanbox, create a Product with a Price
- Create a Plan in Jumpstart with that associated Paddle Product id
- Create a new Jumpstart user
- Subscribe to the Plan with the user's personal account
- Create a Team Account
- Create a Subscription with that Team Account
You'll see a Processor already taken validation failed on api_record due to the update! calls
Change the update! to update and the user will be able to create a subscription due to update skipping validations. However instead of being in the Team Account, The Personal account will contain both Subscriptions.
Expected Behavior:
This may be a misunderstanding on my part, but I would assume the Paddle Customer could have n active subscriptions where n is the number of Accounts their user has in Jumpstart. For example, a User could be paying for a personal account and 2 team accounts.
Actual Behavior:
A user can create n accounts, but can only have a single subscribed account due to the the uniqueness constraint preventing the processor_id, which is a customer_id associated with the email of the User who owns the n accounts, from being attached to the Pay Customer record associated with an account.
Environment:
-
Pay gem version: 10.0
-
Ruby version: 3.4.4
-
Rails version: 8.0.2
-
Operating System: Ubuntu WSL2
Possible Fix:
Remove the uniqueness validation on the processor_id for Paddle Billing, and attach the Subscription to the correct Pay Customer by using the custom_data property in the webhook object instead of the processor_id which will always return the first instance with that processor_id.
Steps to Reproduce with Fix (if available):
Related Issues:
Pay Gem Issue with Paddle Billing and Multiple Accounts to a Single User
Labels to Apply:
Bug
Checklist:
- I have searched for similar issues and couldn't find any
- I have checked the documentation for relevant information
- I have included all the required information

