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

Lemon Squeezy support #947

Merged
merged 21 commits into from
Aug 6, 2024
Merged

Lemon Squeezy support #947

merged 21 commits into from
Aug 6, 2024

Conversation

deanpcmad
Copy link
Contributor

@deanpcmad deanpcmad commented Jan 24, 2024

This PR adds support for Lemon Squeezy, a Merchant of Record payment provider. Their site is here > https://www.lemonsqueezy.com/

It uses a Ruby library I built, lemonsqueezy.

This is a rewrite of #898 from what I've learnt with integrating Paddle Billing. The Lemon Squeezy API is quite similar to Paddle's Billing API. I have noticed a few things though:

  • Trial Subscriptions have the status of on_trial. Not sure if you want to set it as that or replace the status with trialing when saving?
  • They don't support cancelling subscriptions immediately.
  • Card expiry dates aren't listed in the API, just the brand and last 4
  • Charges cannot be created from the API

This is a WIP.

@harrison-broadbent
Copy link

Keen!

@excid3
Copy link
Collaborator

excid3 commented Jan 29, 2024

trialing would be nice to make it consistent everywhere which is helpful for querying. Although I don't like modifying data from the API if we can help it. I would say we should map it.

We can raise an error for cancel_now if they don't support immediate cancellations.

What else do we need to implement?

@deanpcmad
Copy link
Contributor Author

Another oddity I've found, is that they don't list card expiry dates in the API, just the brand and last 4 🤔

@excid3
Copy link
Collaborator

excid3 commented Jan 29, 2024

Another oddity I've found, is that they don't list card expiry dates in the API, just the brand and last 4 🤔

That is very odd.

@deanpcmad
Copy link
Contributor Author

trialing would be nice to make it consistent everywhere which is helpful for querying. Although I don't like modifying data from the API if we can help it. I would say we should map it.

So when a subscription is a trial, set the status as trialing or keep it as is?

@deanpcmad
Copy link
Contributor Author

Have just pushed a couple more commits, including initial work on docs. Feel free to give it a go.

I've noticed they don't have an API for creating charges, so I've sent them an email requesting this plus a few other minor details such as card expiry dates.

@deanpcmad
Copy link
Contributor Author

As for linking a subscription to a LS Customer, it appears that setting the email address in the URL links it, but I've added support for passthroughs just like Paddle Classic. This is another thing I've asked about, seeing if we can just pass the Customer ID to link it.

An example payment link I've been using has been in this format:

https://voupedev.lemonsqueezy.com/checkout/buy/xxx?embed=1&checkout[email]=yyy&checkout[custom][passthrough]=zzz

You should replace xxx with the UUID of the product, which can be viewed when clicking the Share button.

@deanpcmad deanpcmad marked this pull request as ready for review January 31, 2024 16:19
@deanpcmad
Copy link
Contributor Author

Have just heard back from Lemon Squeezy.

  • They don't support charging through the API as all orders/subscriptions must be created through their checkout.
  • Passing the email address of a customer links it to a customer created in Lemon Squeezy

This means a passthrough isn't required, but it may be best to keep it for if a customer doesn't exist?
Thoughts @excid3?

@excid3
Copy link
Collaborator

excid3 commented Feb 5, 2024

  1. That's fine, just have the charge method raise an error?
  2. I don't think we need the passthrough

@excid3
Copy link
Collaborator

excid3 commented Feb 8, 2024

LemonSqueezy.js 2.0 is out now. https://github.com/lmsqueezy/lemonsqueezy.js/releases/tag/v2.0.0

@deanpcmad
Copy link
Contributor Author

Ha, I just received an email from them saying that 😅 I believe that's their official API library, not Lemon.js which is used for checkout overlays.

@deanpcmad
Copy link
Contributor Author

Yeah 😆 - Lemon.js is the client-slide library - https://docs.lemonsqueezy.com/help/lemonjs/what-is-lemonjs

@excid3
Copy link
Collaborator

excid3 commented Feb 8, 2024

And to think they could have called the Node SDK "lemonode.js". Such a shame.

Edit: Hah, someone beat me to it: https://www.npmjs.com/package/lemonode

@deanpcmad
Copy link
Contributor Author

Wow published 11 years ago 😅

@nduplessis
Copy link

I would love to help get this over the line, is there anything still outstanding that's required for a merge?

@joshfester
Copy link

Does this mean lemon squeezy support will be coming to Jumpstart? 👀

@deanpcmad
Copy link
Contributor Author

There are still a few tweaks that need to make such as removing the passthrough code, but I'd say it's ready for you to check over @excid3?

@Gary-H9
Copy link

Gary-H9 commented Apr 8, 2024

👋 Similar to @nduplessis, I'd like to help here if possible/necessary.

@5andu
Copy link

5andu commented Jun 2, 2024

Any updates or help needed for this? :)

@deanpcmad
Copy link
Contributor Author

I believe it's ready for people to test, so feel free to give it a go

@5andu
Copy link

5andu commented Jun 2, 2024

Thanks!

@k0va1
Copy link

k0va1 commented Jun 17, 2024

Hi @deanpcmad! Thanks for a great job! I've tested this branch and bumped into one error:

Could you take a look at it? Ping me if you need help with this PR, I really want to merge it 😀

@deanpcmad
Copy link
Contributor Author

Ah good spot, will change that

@k0va1
Copy link

k0va1 commented Jun 18, 2024

This means a passthrough isn't required, but it may be best to keep it for if a customer doesn't exist?

@deanpcmad I'm not quite sure if it's a valid approach but I'm looking for a customer like this k0va1@4cae510

Passthrough might be not a bad option tho

@deanpcmad
Copy link
Contributor Author

Yeah, maybe it would be best to keep the passthrough there

@deanpcmad
Copy link
Contributor Author

@k0va1 feel free to test it now. I've reverted the commit that removes the passthrough code & docs

@deanpcmad
Copy link
Contributor Author

@excid3 have you had chance to take a look at this yet? 😄

@excid3
Copy link
Collaborator

excid3 commented Jul 1, 2024

A little, but need to build an end-to-end implementation to test it.


def self.sync(charge_id, object: nil, try: 0, retries: 1)
# Skip loading the latest subscription invoice details from the API if we already have it
object ||= ::LemonSqueezy::SubscriptionInvoice.retrieve(id: charge_id)
Copy link

Choose a reason for hiding this comment

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

what if we don't find any invoice and got 404 error? i suppose this case should be handled

I bumped into an Error 404: No results were found for your request. '[{"status"=>"404", "title"=>"Not Found"}]' (LemonSqueezy::Error) while accidentally sending test webhook to production server

@deanpcmad
Copy link
Contributor Author

Well, Stripe just acquired Lemon Squeezy - https://www.lemonsqueezy.com/blog/stripe-acquires-lemon-squeezy

@excid3
Copy link
Collaborator

excid3 commented Jul 26, 2024

Saw that, super exciting!

@excid3 excid3 merged commit 3169b22 into pay-rails:main Aug 6, 2024
36 checks passed
@deanpcmad deanpcmad deleted the lemon-squeezy branch August 7, 2024 11:34
@@ -8,7 +8,7 @@ def process!
Pay::Webhooks.instrument type: "#{processor}.#{event_type}", event: rehydrated_event

# Remove after successfully processing
destroy
# destroy
Copy link

@nflorentin nflorentin Aug 29, 2024

Choose a reason for hiding this comment

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

I was wondering why the addition of lemon_squeezy is commenting this line of code which seems to impact all processors.

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

Successfully merging this pull request may close these issues.

10 participants