-
Notifications
You must be signed in to change notification settings - Fork 34
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
Implement subscriber sync from Paddle API #19
base: master
Are you sure you want to change the base?
Conversation
Django 2 requires an app_name variable to be set on urls.py when using include(). https://stackoverflow.com/questions/48608894/impropyconfigurederror-about-app-name-when-using-namespace-in-include
Next bill date can be null if a subscription != active
Next bill date can be null if a subscription != active
Apologies for the messy commit history - it seems GH automatically merged another commit into my pull. |
Added a few other bugfixes:
|
Fix mistyped parameter in update_or_create
More bugfixes:
|
@matteing A potential problem i see here is that the email used for Paddle checkout may not match the local user's email. A clean way of doing this would be to send a unique local user id as a passthrough argument when initializing the Paddle JS snippet (see https://paddle.com/docs/paddle-checkout-web/ - section "Sending additional user data"), this will then be included in the However, Paddle currently only includes this passthrough string in the Webhook, not in the List-Subscriptions API endpoint*. So if anything goes wrong during the webhook, it will not be possible to manually sync via Django command later (or we will have to fallback to email matching). *I've already contacted Paddle about including the passthrough argument is the API endpoint, was told they see that it would be useful but they can't provide a ETA. Just something to consider. |
I actually absolutely agree with @kennell on this subject (I face this problem on production), however I didn't find that the current code did this linking using the user_id argument - so I didn't implement it as to keep feature parity (see here). If given a green light I think I can take a shot at adding user_id linking. Edit: Reading more carefully, noted on the endpoint issue not returning webhook data. |
"""Call sync_from_paddle_data for each subscriber returned by api_list.""" | ||
for sub_data in Subscription.api_list(): | ||
sub = Subscription.sync_from_paddle_data(sub_data) | ||
print("Synchronized {0}".format(str(sub))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- since it can become a lot of subscriptions, this statement might be too verbose. Please make it a summary or add a parameter for verbose output
- let's switch to
self.stdout.write(self.style.SUCCESS('...'))
- I'll change this in the plan-command as well
@@ -0,0 +1,18 @@ | |||
# Generated by Django 3.0.5 on 2020-04-10 00:56 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- please squash migrations
|
||
def handle(self, *args, **options): | ||
"""Call sync_from_paddle_data for each subscriber returned by api_list.""" | ||
for sub_data in Subscription.api_list(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- let's call it
subscription_data
def sync_from_paddle_data(cls, data): | ||
pk = data.get('subscription_id', None) | ||
# First, find and drop current sub with this data. | ||
cls.objects.filter(pk=pk).delete() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please initialize kwargs
with all parameters needed to create/update the Subscription except pk
, then use update_or_create
instead of deleting the Subscription right away.
- [ } use
update_or_create
update_url = data.get('update_url'), | ||
**kwargs | ||
) | ||
return sub |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- please rename to
instance
orsubscription
data["subscriber"], created = settings.get_subscriber_model().objects.get_or_create( | ||
email=payload["email"] | ||
) | ||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Subscriber = settings.get_subscriber_model()
if subscriber_id not in ["", None]:
try:
data[ "subscriber"] = Subscriber.objects.get(email=payload["email"])
except settings.get_subscriber_model().DoesNotExist:
data[ "subscriber"] = None
try: | ||
kwargs['plan'] = Plan.objects.get(pk=data.get("plan_id")) | ||
except Plan.DoesNotExist: | ||
print("Skipping, plan not found.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- please use
log.warn
or make it a comment - please return
None
quantity=data.get("last_payment", {}).get("amount", 0), | ||
source="", # ??? | ||
status=data.get("state"), | ||
unit_price=0.00, # ??? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matteing shall we rather make this a default in the model field?
@matteing thanks for your good work! I added some comments. However, it would be great to have a test for it. I'd like to see our test-coverage reach a reasonable level soon. |
Agree. This is another good argument to make the matching of subscribers configurable with a sane default (e.g. email-matching). So the developer that implements dj-paddle into his project can decide how to handle it for his respective use-case. |
I need this feature. Are the owners of the repo active lately? I don't want to put in the work if they aren't reviewing pull requests. |
Package seems long unmaintained. I'm unsure of any alternatives. It's been a while since this thread! :) |
@matteing thanks for the reply and the initial work!
ugh, forking it is then. |
That's a good approach! Although no shade on the original authors -- they did great work pushing support for Paddle with Django. I hope the Paddle API primitives haven't changed since then! |
Totally true. My comment was rude. The authors don't owe nobody their time and the project is of great value as it is. |
No worries homie! Hope my work helps as well.
…Sent from my iPhone
On May 26, 2023, at 4:22 PM, Juan Olvera ***@***.***> wrote:
That's a good approach! Although no shade on the original authors -- they did great work pushing support for Paddle with Django.
Totally true. My comment was rude. The authors don't owe nobody their time and the project is of great value as it is.
—
Reply to this email directly, view it on GitHub<#19 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AB4XGZNWZJ366LPPPRQ6QP3XIEGGZANCNFSM4MFENADA>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@j0lv3r4 I ended up forking for a fix/features I needed semi-recently. Don't know if you are interested in any of those changes: https://github.com/saschwarz/dj-paddle/commits/master |
@saschwarz awesome, thank you. I will check it out. |
Just FYI i started a alternative implementation a while ago: https://github.com/kennell/django-paddle Far from feature complete, but perhaps a alternative to some -- or at least a inspiration ;) |
Hi, I decided to implement subscriber sync.
A few things to note.
As a side note, I implemented a partial fix to bullet point 2: this seemed very worrying.
Code review welcome. So far it seems to be working fine, but it certainly isn't perfect.