简体   繁体   中英

PayPal Subscription IPN Next Billing Date

My web app uses PayPal monthly subscriptions. I receive IPN notifications when payments are made, users signup/cancel, etc and this all seems to work well.

One thing that appears to be missing from the IPN messages is any sort of indication about the next billing date. https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNandPDTVariables/#id091EB0901HT

At first I thought that since it's a monthly subscription, I can simply add a month to the previous date, but PayPal seems to have a funky way of figuring out the next payment date - it's not always 30 or 31 days or a month.

The next billing date is available from within PayPal itself, but doesn't seem to be sent along in any IPN messages.

Does anyone know of a simple way to work this out from the information that is available in the IPN messages?

I recently came across this issue too. I'm not sure one can get a consistent scheme as to what a "month" of subscription means. For instance, if you sign up for your service on the 31st of March, is the next payment due on the 30th of April or on the 1st of May? You just have to pick one and communicate clearly it to your users. Its unfortunate PayPal doesn't afford us this courtesy.

In the end I decided to give the users access to the service for 32 days or 367 days, for monthly and annual subscriptions respectively. I know you may "lose" out on a day or two here and there but I think its better to allow some grace access rather than risk giving the user less time than paid for.

If all goes well, it doesn't actually matter how long you activated the account for if you also listen for the subscr_eot and subscr_payment IPNs (see https://stackoverflow.com/a/1195246/1852838 ). I renew the above period from the date of the next payment so that the subscription is always in sync with the PayPal payment cycle. PayPal will send you the eot IPN when the last paid period ends so you can terminate the subscription on the server side. This means it doesn't matter so much how much "grace" you decide to give them.

In terms of a providing a "paid until" I would simply provide the "grace" date as you are the one who actually decides how long this is. I would, however, recommend that you also let them know that they should make a payment by the next most conservative estimate for the next payment. This would be 30 days after the last payment or the end of the month if that falls after it.

this might help you. to specify exactly days, do not use paypal's MONTHLY type. instead specify DAY like this:

following will charge the client each 30 days:

    ->setfrequency_interval('30')
    ->setfrequency('DAY')

Monthly recurring payments were collected roughly every 30 days.

If the subscription terms are $25.99 USD a month and the subscriber signs up on Thursday, July 31. The subscriber is billed as follows:

  • Thursday, July 31 = $25.99 USD
  • Saturday, August 31 = $25.99 USD
  • Wednesday, October 1= $25.99 USD
  • Saturday, November 1= $25.99 USD

Worst case scenario is when the original subscription date is on the 31st of the month .

I was allowing for a month and then +1 day just to be safe, but then this happened.

Subscription started on 31st

The customer subscribed and paid on 31 Jan. Because that's the last day of the month, PayPal charged them again on 28 Feb. My code then figured next payment date (+1 day grace) = 29 March. But, of course it's not. It's 31 Mar.

I keep track of that "next payment date" even though it's not 100% accurate and show it on the user's profile page. It seems crazy to me that PayPal don't include this vital piece of information in the IPN data.

Solution 1

One option is to allow a longer grace period, or to make exceptions if the payment date is the last day of any given month. This works okay, but shows slightly wrong info to the user some of the time.

Solution 2

Track the day-of-month value of the original date of the subscription. That way you can always refer back to it. So in my example, that day-of-month is 31. I keep that value, and then whenever I need to update the "next payment date" I can just use that day of the month on the upcoming month. For shorter months, just use the last day of the month if it is < the stored day-of-month.

 let m  = moment.utc('2021-05-31T06:52:19Z')
 for (let i = 0; i < 20; i++) {
   const date = m.get('date')
   m.add(3, 'month') // any number of months
   if ((date === 29 || date === 30) && m.get('month') === 1) {
     m.add(1, 'day')
   }
   console.log(m.format())
}

If it is incorrect, let me know, please. I tested it on real subscriptions for 1, 2, 3 and 4 months. At least first next billing date is same

Also it matches with examples from docs, except this:

Example: Monthly recurring payments due and collected on the 31st If the subscription terms are $25.99 USD a month and the subscriber signs up on Thursday, July 31. The subscriber is billed as follows:

Thursday, July 31 = $25.99 USD Saturday, August 31 = $25.99 USD Wednesday, October 1 = $25.99 USD Saturday, November 1 = $25.99 USD and so on

But matches this:

Recurring payments are collected on the same day of the month. If the initial recurring payment falls on the 31st, PayPal eventually adjusts the billing cycle to the last of the month. If the initial recurring payment falls on the 29th or 30th, PayPal adjusts the billing cycle to the first of the month on the following February.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM