Paypal webhooks and subscription expiration dates - paypal

I'm listening for the BILLING.SUBSCRIPTION.ACTIVATED event and everything gets stored in my backend. This event contains a property called next_billing_time, which is all good. Then whenever a user makes a payment to that subscription ID it is shown in the PAYMENT.SALE.COMPLETED event, this event however has no next_billing_time property. My question is, how do I keep track of the new billing time after payment is made? Do I have to use the old next_billing_time and calculate that manually?

The simplest design is to go off PAYMENT.SALE.COMPLETED. Use it to mark a subscription good for 1 month or whatever term (maybe a day of grace time), and if you don't receive a new PAYMENT.SALE.COMPLETED soon enough, consider the subscription lapsed on your end.

Related

Paypal Webhook is created sufficient to imply activated

Paypal with active webhooks. We use a subscription plan.
When a customer
subscribes to the subscription plan PayPal's webhook sends us a BILLING.SUBSCRIPTION.CREATED. 

We do not get a BILLING.SUBSCRIPTION.ACTIVATED. Can I expect it being activated when it is
created or do I need to double check that?
(Side note, when trying to send an api request to activate it, an error message informs me that the subscription plan is not “suspended”. So that looks like it is already activated. Logging into PayPal also confirms it is activated.)

The documentation on it is a little vague.
Created means the user clicked the button to subscribe. It does not mean they entered any payment details, or finished subscribing.
If you are not receiving a BILLING.SUBSCRIPTION.ACTIVATED event but the subscription is active, perhaps you did not subscribe to that event?
In any case, the most useful event to listen for is PAYMENT.SALE.COMPLETED. This will occur for the first payment as well as every future payment on the schedule. You can build all your business logic with only PAYMENT.SALE.COMPLETED , using every receipt of this event to mark how long the subscription is valid for in your system (e.g. 1 month from receipt)

Stripe's "cancel_at_period_end" equivalent in paypal?

I implement a subscription site in which the subscriptions plans are monthly.
I use IPN to handle subscription events.
Now, If a recurring payment failed, I will get the relevant event and will cancel the subscription in my side.
But, what should I do when a user cancels his subscription via my site, and he still has time left in his subscription, and I want to cancel the subscription only in the end of the subscription period?
What can I do if the user cancels his subscription via PayPal and still has time left in his subscription?
In stripe you simply set "cancel_at_period_end=true" and then it's the same scenario.
There is no equivalent, PayPal doesn't keep track of anything for you. You'll receive cancel events whenever a profile is cancelled.
If you want to keep track of paid-through periods, that logic is up to you.

PayPal immediate payment (intent="sale") expiration time

I'm using the Express Checkout flow with the advanced server integration.
So I reserve items in real time once user has clicked the "Checkout" button and wait for the success\fail response. User can just close the browser tab and it will look like a long payment process (there is no way for the JS code to call the onCancel handler).
So it looks like I don't know if user has closed the browser or just fell asleep. Problem that I can't wait too long (more than ~5 mins) and I want to cancel the payment after this time. And it seems that I can't cancel the Payment myself. So user can come back and pay after N minutes (N > 5) for the item which has been un-reserved and is already out of stock.
This answer says:
user has three hours to approve of the PayPal payment
Answer about 3 hours is a bit old so do we have any fresh DOCS about the immediate payment lifetime? Is it still 3 hours for the REST Express Checkout flow?
3 hours is too long period for me. Is there a way to setup the expiration time or timeout for the payment during creation?
Is there a way to cancel the Payment? Payments API has no reference about it.
You can do a GET on the PAY-XXXX id.
https://developer.paypal.com/docs/api/payments/#payment_get
The response comes with a create_time field. You should be able to check the delta from create_time -> now, and if it's > 5 minutes, don't accept the PAY-XXXX id / cancel the transaction in your database.
Does that work for your use case?
Also note: No money is moved until you call execute, so long as you prevent execute calls for old transactions, you should be ok.
I think it is still 3 hours and there is no way to set it up during the payment creation. But i would assume that buyer cannot pay until he returns back to your site either by approving or without approving. So is it not possible to put a check in between the step where buyer comes back and then call to complete the payment is made?

Using PayPal subscription IPN fields to manage user accounts

I'm using PayPal to take subscription payments for access to a website service.
I'm using PayPal's IPN to manage the payments and user accounts.
I'm sending a custom random key to PayPal, unique to each user, when the subscription is first instantiated so the same key is sent back with every IPN. This means I can bind together my users table with my PayPal notifications very positively.
Accordingly I can now generate from my database a list of user_ids and notification details.
So now I need to figure out the best logic to use to calculate each users current payment status and, as a consequence, what to do with their account - whether to continue allowing access, suspend or even delete their user account. This decision will all come down to whether their payments are still coming through or not.
A bunch of interesting an varied data comes through on PayPal's IPN - most looks irrelevant in terms of user account management but a couple of columns look quite useful. Specifically...
Field outstanding_balance appears to contain exactly that - a value to 2dp of money still owing. So far during my testing this figure has only ever been 0.00
Field txn_type shows me any from a selection of different codes: subscr_signup (when the user initially sets up the subscription), subscr_payment (when a payment appears to be successful), subscr_cancel (this seems to appear whether the customer or vendor cancels the subscription), and subscr_eot (end of term - this one crops up shortly after the subscription is cancelled).
My impulse is to search the table for the most recent txn_type="subscr_payment" entry for each user account, and check the date this last notification arrived. If it is date stamped over, say, 28 days ago the account can be suspended... if it's over 56 days the account can be deleted.
Is this a good idea? Or is there better logic I can employ?
I've done this. Quite simple:
Don't grant access until you receive the first payment. You can get the intial signup and payment in either order.
PayPal will notify you if they cancel their subscription or it expires. When you get either of those, deny access as from the effective date.
If the most recent payment status on an account is 'reverse', suspend access until you either get 'cancel reverse' or the situation is sorted out in some other way.
Don't count the days. PayPal counts the days. All you can get from repeating that yourself is a disagreement, and guess who's right? PayPal. And guess who isn't wrong? The customer. You don't want to penalise the customer because PayPal got behind or had a different idea of 28 days from yours. You've handed responsibility for collections and renewals to PayPal: let them do it.
Beware of building policy into this. It should just be a mechanism, and it should be manually overridable. For example, the actual evaluation of whether this user has access to this product now mustn't be a computation over their payment history. Just a simple lookup of another table, which your IPN code can modify, but so can humans. For example: there is a dispute. You lost. You might well as a matter of business want to keep the customer alive for a grace period anyway. Alternatively you might in extremis want to fire the customer immediately, e.g. for usage violations.
You can ignore the balance field. The only important thing is the txn_type.

Subscriptions with Paypal IPN

I am adding subscriptions to a site using Paypal IPN which works very well, I can successfully create a new subscription and verify it. The subscription has a two week free trial. The guide was unfortunately a little vague on subscription statuses.
At the moment, the users account gets subscribed status once subscr_signup or subscr_payment is received and gets removed when either subscr_cancel or subscr_failed is received. I believe this is correct but it's best to make sure.
Also what is subscr_eot? the IPN guide describes it as "subscription’s end-of-term." Does this get triggered after the trial period is over?
subscr_eot is sent when a user's last paid interval has expired. subscr_cancel is sent as soon as the use cancels the subscription - for example:
User signs up on day 1 for a subscription which is billed once a month.
subscr_signup is sent immediately, subscr_payment is sent as soon as payment goes through (usually immediately as well).
On day 13, the user cancels. subscr_cancel is immediately sent, although the user has technically paid through to day 30. Cancelling at this point is up to you.
On day 30, subscr_eot is sent - the user has cancelled, and this is the day which his last payment paid until.
Not much changes with trial subscriptions - if a user cancels before a trial subscription is up, subscr_cancel is sent immediately, and subscr_eot is sent at the end of the trial.
Also, one interesting detail is how subscr_eot works with subscr_failed.
It looks like subscr_eot comes after the FINAL subscr_failed. So if in your account you set it to automatically retry failed payments 3 times, then it should go like this:
first failed payment => subscr_failed
second failed payment => subscr_failed
third failed payment => subscr_failed and subscr_eot
so basically in your code you can set subscr_failed to trigger an email like
hi user,
please take moment to check
your payment info, you may need to
update the credit card expiration
date, etc. You still have access,
we'll try again in a few days.
And setup subscr_eot to actually turn their subscription off and trigger an email like
Sorry, we still havent' gotten payment
and have taken your profile down. You
can still reactivate it by logging in and updating your payment info
Basically this is the "nice" way of doing it so customers have a grace period, and their account isn't shut off unexpectedly just because of an expired credit card or something like that.
The thread posted by Chris has been updated recently.
Sometime in 2010, PayPal stopped using subscr_eot when a user cancelled their account. After a number of complaints, they reinstated this, but took 6 months to do so. All this means is that you can once again handle your subscription notifications as described by Peter in the accepted answer.
From a PayPal representative:
subscr_cancel means the profile is
canceled and there will not be future
payments. However, if the buyer has
already paid for the current billing
cycle as they are charged up-front,
then you can use the subscr_eot to
terminate the profile.
Still unsure what happens in the event of multiple failed payment attempts, however. PayPal documentation at the moment is terrible.
It depends on the account if it is new or not whether subscr_eot gets sent, which is kinda beyond me?
I haven't found the proper way to manage subscriptions yet. Calculating the dates on the server could go wrong very fast if there is a delay in payment.