PayPal makes it possible to accept payments via just a few pieces of HTML on your site with its Website Payments Standard service. This service includes a Subscriptions button to sell products or services with recurring payments.
The trouble is, PayPal doesn’t make it as easy to cancel a subscription on your site. The documentation on cancelling a subscription only provides instructions for manually cancelling a subscription from the PayPal administration interface.
The good news is, there is another, undocumented method to cancel subscriptions on your site.
Enter Express Checkout
Although PayPal Standard has no API for cancelling a subscription, PayPal offers another product which has a more comprehensive API – Express Checkout.
The gotcha here is that although Website Payments Standard and Express Checkout have distinct branding and documentation, some PayPal Express Checkout API operations can actually be performed with the values of a PayPal Standard transaction.
The API operation for cancelling subscriptions is ManageRecurringPaymentsProfileStatus.
ManageRecurringPaymentsProfileStatus
When a customer creates a subscription with PayPal Standard, PayPal notifies your site with an IPN request. The request contains a set of name values pairs which will look something like this:
[txn_type] => subscr_signup [subscr_id] => I-NARPL1C00000 [last_name] => User [residence_country] => US [mc_currency] => USD [item_name] => Digital Subscription [business] => seller@example.com [recurring] => 1 [verify_sign] => AFcWxV21C7fd0v3bYYYRCpSSRl31AEFeAejFlhh0AvqwNRts6zLECRVi [payer_status] => verified [test_ipn] => 1 [payer_email] => buyer@example.com [first_name] => Test [receiver_email] => seller@example.com [payer_id] => K48P3FBQAAAAA [invoice] => your_invoice_id [reattempt] => 1 [recur_times] => 4 [subscr_date] => 18:13:30 Apr 17, 2012 PDT [custom] => 25 [charset] => windows-1252 [notify_version] => 3.4 [period1] => 1 D [mc_amount1] => 11.00 [period3] => 1 D [mc_amount3] => 5.50 [ipn_track_id] => baca1234
The most important part of this request is the subscr_id
. This field is actually equivalent to a PayPal Express Checkout Recurring Payment Profile ID and can be passed as the PROFILEID
of a ManageRecurringPaymentsProfileStatus
NVP API operation.
Example
The full documentation on the ManageRecurringPaymentsProfileStatus
NVP API operation is available here. Unfortunately it lacks an example.
Here’s an example function in PHP for calling the ManageRecurringPaymentsProfileStatus
API operation:
/** * Performs an Express Checkout NVP API operation as passed in $action. * * Although the PayPal Standard API provides no facility for cancelling a subscription, the PayPal * Express Checkout NVP API can be used. */ function change_subscription_status( $profile_id, $action ) { $api_request = 'USER=' . urlencode( 'api_username' ) . '&PWD=' . urlencode( 'api_password' ) . '&SIGNATURE=' . urlencode( 'api_signature' ) . '&VERSION=76.0' . '&METHOD=ManageRecurringPaymentsProfileStatus' . '&PROFILEID=' . urlencode( $profile_id ) . '&ACTION=' . urlencode( $action ) . '&NOTE=' . urlencode( 'Profile cancelled at store' ); $ch = curl_init(); curl_setopt( $ch, CURLOPT_URL, 'https://api-3t.sandbox.paypal.com/nvp' ); // For live transactions, change to 'https://api-3t.paypal.com/nvp' curl_setopt( $ch, CURLOPT_VERBOSE, 1 ); // Uncomment these to turn off server and peer verification // curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); // curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( $ch, CURLOPT_POST, 1 ); // Set the API parameters for this transaction curl_setopt( $ch, CURLOPT_POSTFIELDS, $api_request ); // Request response from PayPal $response = curl_exec( $ch ); // If no response was received from PayPal there is no point parsing the response if( ! $response ) die( 'Calling PayPal to change_subscription_status failed: ' . curl_error( $ch ) . '(' . curl_errno( $ch ) . ')' ); curl_close( $ch ); // An associative array is more usable than a parameter string parse_str( $response, $parsed_response ); return $parsed_response; }
Usage
To use this function, you will need to replace 'api_username'
, 'api_password'
and 'api_signature'
with your PayPal API credentials.
To cancel the subscription responsible for the IPN request above, we just pass in the value from the subscr_id
field in the IPN request.
change_subscription_status( 'I-NARPL1C00000', 'Cancel' );
We can also use it to suspend a profile:
change_subscription_status( 'I-NARPL1C00000', 'Suspend' );
Or reactivate a suspended profile:
change_subscription_status( 'I-NARPL1C00000', 'Reactivate' );
Limitations
There are still a few limitations for which I haven’t been able to find a work around.
Shooting in the Dark
To suspend a subscription, it must be active. To reactivate a subscription, it must be suspended. Express Checkout provides an API operation to find the current state of a subscription – GetRecurringPaymentsProfileDetails
(documented here).
Unfortunately, PayPal doesn’t allow this operation to use a subscr_id
value as a PROFILEID
. As a result, you’ll need to just shoot blind when managing a subscription and deal with any failures.
For reference, the parsed response of a failed ManageRecurringPaymentsProfileStatus
request will look something like this:
[TIMESTAMP] => 2012-06-29T06:54:22Z [CORRELATIONID] => ebe0a10c134 [ACK] => Failure [VERSION] => 76.0 [BUILD] => 3067390 [L_ERRORCODE0] => 11556 [L_SHORTMESSAGE0] => Invalid profile status for cancel action; profile should be active or suspended [L_LONGMESSAGE0] => Invalid profile status for cancel action; profile should be active or suspended [L_SEVERITYCODE0] => Error
No IPN
Compounding the problem above, PayPal sends no IPN message when a profile is suspended. If a user suspends a profile with PayPal directly, the profile will fall out of sync with your site.
You should also record the subscription status as suspended when making a successful ManageRecurringPaymentsProfileStatus
request, instead of waiting for an IPN request.
An Easier Way to Sell Subscriptions
If you want to sell subscriptions with PayPal, but you don’t know a server-side programming language, or you just value your sanity enough to avoid the PayPal API, then checkout my WooCommerce Subscriptions extension.
Combined with the featured-packed WooCommerce and ease-of-use of WordPress, Subscriptions makes it easy to sell products & services with recurring payments. And it uses the method described here, so even subscriptions created with PayPal Standard can be cancelled, suspended and reactivated directly from your store.
UPDATE 11 Feburary 2013
There is one caveat – the subscription must have been purchased after 2009 for this method to work.
wow.. the best explanation ive found so far to manage paypal subcription. Do you have any article how to create the subscription? Read your other article, but it seems you use URL parameter? I usually use form _xclick-subscription! And bit confuse about subscr_payment and recurring_payment. if you care to explain include tutorial would be great 😀
Hi Tono, take a look at the HTML Variables for Subscriptions section.
These are all the options you can send along with
_xclick-subscriptions
. They can be sent either through a HTML form, e.g add a one month free trial period:Or as GET parameters in a URL string, e.g. add a one month free trial period:
Hi Brent, thanks it helps a lot..
Do you know the difference ‘subscr_payment’ and ‘recurring_payment’?
And Do you know how to set Initial payment for subscription? at the moment i use trial fee as initial payment. Dont know wether its the right option to do..
I think
subscr_payment
payment is for subscriptions created with PayPal Standard whilerecurring_payment
is for those created with Express Checkout.Regarding initial payments. There is no option to create an initial payment for subscriptions created in Website Payments Standard, so I’ve done the same thing you do (which is use the trial period to add it to the first payment only).
Good post. What I do not understand why my all subscription payments id start with S- and not with I-. When I post for example PROFILEID=S-7J596251UT364050T I get the error “The profile ID is invalid”.
A payment transaction ID is different to a subscription’s Profile ID. Make sure you are using the Profile ID for the subscription and not the transaction ID for a payment which forms part of that subscription.
I’m getting this response from PayPal. Guess they’ve shut down the ManageRecurringPaymentsProfileStatus method for express checkout? Any help would be greatly appreciated…
ACK: Failure
L_ERRORCODE0: 81002
L_SHORTMESSAGE0: Unspecified Method
L_LONGMESSAGE0: Method Specified is not Supported
L_SEVERITYCODE0: Error
Hi Alexander, I just tested it again and it’s still working for me. All I can suggest is to make sure each of your NVP variables & values are correct – PayPal has been known to provide an error message that has nothing to do with the real problem.
Hi Brent,
I have used your code to cancel the subscription using its profile ID like I-GY3M2WDV****. But, I’m getting the following Error from Paypal Sandbox.
[TIMESTAMP] => 2012-12-05T05:04:33Z
[CORRELATIONID] => b2d9399f85ff6
[ACK] => Failure
[VERSION] => 76.0
[BUILD] => 4181146
[L_ERRORCODE0] => 11552
[L_SHORTMESSAGE0] => Invalid profile ID
[L_LONGMESSAGE0] => The profile ID is invalid
[L_SEVERITYCODE0] => Error
I’m sure, I have that profile Id in my paypal sandbox. Even though, its returning error as such. Could you please tell me about the problem with me??
Thanks
Hi Mohan, all I can do is suggest checking the request and making sure the profile ID is being sent as you see it (i.e. not have any URL encoding/HTML escaping issues). If that fails, try creating a new profile and testing with that ID. I have since learned that only profiles created after 2009 will work via this method, so that might be the problem?
Pingback: [PHP]Paypal APIで月額課金を止める方法と不正利用されない方法 | 田舎暮らしフリーランスへの道
Great! This is very well explained and most important it has a code example.
Thank you very much!
Hi
I have created a recurring profile using subscribe button of Paypal on sandbox. But when i try to cancel it using the following code
$api_request = ‘USER=’ . urlencode( ‘api_username’ )
. ‘&PWD=’ . urlencode( ‘api_password’ )
. ‘&SIGNATURE=’ . urlencode( ‘api_signature’ )
. ‘&VERSION=76.0’
. ‘&METHOD=ManageRecurringPaymentsProfileStatus’
. ‘&PROFILEID=’ . urlencode( $profile_id )
. ‘&ACTION=’ . urlencode( $action )
. ‘&NOTE=’ . urlencode( ‘Profile cancelled at store’ );
it gives me the following error
Array
(
[TIMESTAMP] => 2013-02-08T10:19:58Z
[CORRELATIONID] => 66adc7d019253
[ACK] => Failure
[VERSION] => 76.0
[BUILD] => 5060305
[L_ERRORCODE0] => 11552
[L_SHORTMESSAGE0] => Invalid profile ID
[L_LONGMESSAGE0] => The profile ID is invalid
[L_SEVERITYCODE0] => Error
)
does “ManageRecurringPaymentsProfileStatus” this method not cancel the recurring created by standard paypal? if it cancels, then what to do? Please help.
Based on the error message, I’d say check the Subscription ID/Profile ID you’re using in the request. Make sure it’s not the transaction ID.
Hi Brent –
Thanks for your response. I am using the following
Profile start date Feb 7, 2013 | Profile ID No. I-XNEK7EVPSW4M
I have copied it from my paypal account.
Can we cancel the recurring created by PayPal standard by using ManageRecurringPaymentsProfileStatus
?
Please confirm.
Thanks
Yes, you should be able too. That’s what the article is about.
Hi
Can it be done on sandbox?
Yes
Hi Brent –
We created the recurring using the following code .
and the profile id that created was Profile ID No. I-XNEK7EVPSW4M.
when i used the above mentioned code i.e. ManageRecurringPaymentsProfileStatus to remove the recurring, it did not work.
Can you please tell me where I am wrong?
Thanks
I have no idea why it’s not working for you and you’ll need to figure that out for yourself now. PayPal is notoriously complicated, undocumented & inconsistent, so it could be how you’re creating the profile, the country your account is registered in or something completely different. I’d suggest contacting PayPal support and if you still can’t get it to work, use PayPal Express Checkout.
Hi Brent –
Thanks for your help. When i created a new profile in sandbox paypal and used its credentials then it started to work. Thanks you for your support.
Thanks so much. Paypal should hire you to explain their messy system! I pity those who don’t find this explanation!
Excellent Its work . I am implement this code in vb.net and its work properly.
Thanks Brent
Fun fact: when using the “GetRecurringPaymentsProfileDetails” operation, you may receive this error: “Subscription Profiles not supported by Recurring Payment APIs”
Apparently you can only get profile details for users created by the Classic API (“CreateRecurringPaymentsProfile” call). Another head scratcher from PayPal. Luckily this is the furthest I have to go down the rabbit hole as I have IPN data for the client (thankfully!) and can use “ManageRecurringPaymentsProfileStatus” to suspend profiles while I move the users to Stripe subscriptions (which I love). The old “S-” style profile IDs (pre-2009), as you mentioned, won’t work so I have to create a ticket for our support staff to remove them manually; worth it to get rid of PayPal.
Oh by the way, Brent, thank you for this resource. lt got me pointed in the right direction for sure…something worth it’s weight in gold in PayPal’s world! 😛
Thanks for sharing. Sounds about right for PayPal. 😦
Amen.
Thank you.
Excellent!!! Its very comprehensive and I could implement in my application in just 10 minutes
Hi
I AM Getting Error :
[L_ERRORCODE0] => 11552
[L_SHORTMESSAGE0] => Invalid profile ID
[L_LONGMESSAGE0] => The profile ID is invalid
[L_SEVERITYCODE0] => Error
Make sure you’re using a valid Subscription Profile ID. A few more debugging tips are here.
I never created a PayPal account, nor used one, but periodically I get an email saying the account is suspended because someone tried to use the account. I cannot log on to unsubscribe because I do not because of course PayPal doesn’t recognize my name, etc. I’d like to wipe out this annoyance, but how? PayPal will not make this easy
Hi Bill, I’d contact PayPal customer support to ask why you receive these emails, but they may just be spam/phishing emails not originating form PayPal.
great job putting this together, problem with paypal is not lack of information its rather to much of information without any productive direction
> Compounding the problem above, PayPal sends no IPN message when a profile is suspended.
What about subscription cancellations? Is “No IPN” just for suspension, or for the whole shebang?
I’m pretty sure they send an IPN message for a cancellation.
Hi I’m getting this error,
[TIMESTAMP] => 2014-04-04T06:20:11Z
[CORRELATIONID] => e2de55e795808
[ACK] => Failure
[VERSION] => 76.0
[BUILD] => 10433064
[L_ERRORCODE0] => 11552
[L_SHORTMESSAGE0] => Invalid profile ID
[L_LONGMESSAGE0] => The profile ID is invalid
[L_SEVERITYCODE0] => Error
See my answer to this comment with a visitor having the same error.
are the recurring_payment_id and the subscr_id the same thing?
From memory,
recurring_payment_id
is used for Express Checkout transactions whilesubscr_id
is for PayPal Standard Subscriptions.so if i user the standard sub button but want to cancel the recursion i can still use ManageRecurringPaymentsProfileStatus but just supply the subscr id
Yep.
thank you 🙂
Hello,
I hope someone can help. I have installed the latest version of WooCommerce and the Subscriptions extensions and everything is working perfectly except that when a customer cancels their subscription via the My Account or I do via the Subscriptions page, the actual subscription on PayPal is never cancelled.
When a customer signs up it moves it over to Processing and when I refund from PayPal it shows refunded in WooCommerce (Note: I have the Token installed that bypasses the IPN).
I have checked all my settings a dozen times. Any ideas?
Here is the error PayPal is giving in the logs:
07-07-2014 @ 12:23:36 – Calling PayPal to change_subscription_status has Failed: The profile ID is invalid
07-07-2014 @ 12:26:24 – Checking IPN response is valid via https://www.paypal.com/cgi-bin/webscr…
07-07-2014 @ 12:26:24 – IPN Request: Array
(
Hi Travis,
Please submit a support ticket at https://support.woothemes.com and we’ll help you out there. Include a complete copy of the PayPal log on the ticket.
This error is usually caused by incorrect PayPal API Credentials. However, based on the error log, it looks like the PayPal Profile ID might not have been saved on the order correctly.
Hi Brent,
Thanks for the response! I posted a ticket yesterday around 11pm EST. I have worked on this for days and checked the settings multiple times. The ticket ID is 196105.
I will go in and update with the full ticket log.
Thanks!
On another note: When viewing the log, some subscriptions on there are from subscribers who are still signing up through the Subscription button from PayPal. Those generally throw out this error: 07-07-2014 @ 17:48:33 – Subscription IPN Error: Order Key does not match invoice.
So I made a discovery … When I cancel a Subscription in PayPal … It will cancel the subscription in the Store.
However, if I try to cancel a subscription in the Store … it doesn’t cancel in PayPal and if a customer cancels in the My Account page … it doesn’t cancel in PayPal. This is all I have left to figure out.
Thanks
Hi Brent,
I posted a ticket two days ago. I don’t mean to be impatient but I am really trying to get this going. What is the average wait time for a response? I don’t mind paying you directly to get this issue resolved.
Thanks
What is the ticket ID?
The ticket ID is 196105.
Thanks. Looking at the logs, it looks like subscription profile IDs start with an
S-
not anI-
.I’ve seen this once before, and to have it resolved, the customer had to contact PayPal customer support and request they update the PayPal account (for PayPal’s reference, the Incident number for that ticket was 140610-000213).
You will need to do the same as there is no way for subscriptions with an
S-
prefix to be used with the suspension/cancellation APIs. Based on information online, I was under the impression PayPal stopped issuing those IDs after 2009, but apparently not.Okay I will look into that. We didn’t start our Company until 2011/2012 so something is still keep those on. I will contact PayPal.
Thanks!
Today’s Update [RESOLVED] – Okay so I have good news. My primary PP account was created in 2007. PayPal recommend that I open a new account which would give me the I- subscriptions instead of the S-. By doing this, they also linked both paypal accounts together so the funds will be sent to the main account automatically.
I did a test and it worked 🙂 I will post more updates on anything.
Okay I think I understand
From what I have seen since working with subscriptions via PayPal is that PP will try and charge the account 2-3 times and then the next attempt they issue a failed notice and the subscription is cancelled.
Hey Brent,
New question … On the checkout page … is it possible to change the text on the button to something else other than Proceed to PayPal? I would like to change it to Subscribe Now or something to that effect.
Thanks!
Hey Brent,
New question … On the checkout page … is it possible to change the text on the button to something else other than Proceed to PayPal? I would like to change it to Subscribe Now or something to that effect.
Thanks!
Yep it will be, but I think only with custom code. I just had a look to see if I could figure it out quickly, but it wasn’t immediately obvious where or how it’s being set, so you’ll need to hire a developer to help you make that change. Codeable has helped a lot of folks looking for small tweaks like this.
So to confirm .. This does work with PayPal Standard right? This nice lady from PayPal (she is a Supervisor) says that PayPal Standard does not work. She states that I would need a Pro product.
I have PayPal Standard with Enhanced Recurring Payments. She states that I need Reoccurring Payments through PayPal Pro. She states that you can edit or reactivate Standard Subscriptions.
She states that the reason I have the S- is because I am using PayPal Standard. Maybe its an older version?
Can you advise?
Hopefully what I said makes sense … but in essence she stated that the reason I have S- is because of PayPal Standard Subscriptions. She said you must have PayPal Pro with some form of Recurring Payments to get the I- based subscriptions.
I get pretty confused when trying to look and compare all of those options so if you could provide any insight I would be greatly appreciated.
Ask her for a link to some public documentation stating that. It might be new and they just didn’t both to tell anyone. But I’ve certainly never heard of that.
There are thousands of sites using Subscriptions with PayPal Standard and the profile IDs all start with an
I-
, not anS-
.The only public information I’ve found even referring to the
S-
prefix is from this stackoverflow question stating from someone I think is a PayPal staff member that:Is it possible that it is giving the a subscription because I have paypal standard and enhanced recurring payments? I have that so customers can signup using a credit card and not use a paypal account.
Yep, anything is possible with PayPal. I’ve never seen any information to that effect, but that doesn’t mean it’s not the case.
You could ask the PayPal rep and send her the information I provided above?
I am wondering if maybe I just need to create a new PayPal Account? Its possible my paypal account is old. It really wouldn’t matter because the WooCommerce store won’t work with any new subscriptions.
Correction .. Old subscriptions
Okay just want to provide an update before I hit the sack for tonight …
I have been on the phone with PayPal a lot and they are advising that in order to get the I- transaction, you must be on the PayPal Pro plan. I am going to speak to their integration team tomorrow and this will give me the final answer. I will probably be able to upgrade pretty easily and be on my way. I will post with any new updates tomorrow.
Thank you.
Hi Brent,
I wanted to post a follow up email today. So I spoke with PayPal’s integration team and they advised me that the best thing to do was to setup a new PayPal Account and they would link together the two. My primary PP account was setup in 2007 which is why I think it was still pulling the old S- subscriptions. By setting up a new account, the I- subscriptions started coming in and WooCommerce+WooSubscriptions appears to be working now 🙂 The funds are automatically sent over from my new PayPal account to the primary one and we kept the same rates so all is well.
Great to hear.
Brent,
One last question … What happens when PayPal skips a payment? PayPal usually issues three 2-3 skipped payments before cancelling the recurring subscription.
Thanks
Subscriptions requests PayPal suspend a subscription as soon as a payment fails (i.e. do no retry failed payments). It then listens for the
subscr_failed
,recurring_payment_suspended_due_to_max_failed_payment
andsubscr_payment
(with a status offailed
) PayPal IPN messages. If it receives any of those, it will initiate it’s own Failed Payment Handling process (suspend the subscription and email the customer requesting they login to make a payment to fix it up).Unfortunately, PayPal really aren’t clear on how they handle failed/skipped payments. A few of fellow developers looking for answers: https://go.developer.ebay.com/taxonomy/term/5346 & http://stackoverflow.com/questions/12866602/correct-paypal-ipn-variable-for-suspended-subscriptions
So despite Subscriptions requesting the payment be suspended immediately, it may take a day or even up to a week before PayPal issue one of those “failed payment” IPN messages and the subscription is updated in your store.
Hey Brent,
We have been using the Subscriptions plugin for about a month and everything has been running smoothly. I have a quick question though … All of the new subscriptions we have received, when notified via woocommerce, say a new a customer order. However, just today a few have come in saying new subscription renewal. I see now that it is actually the next payment for the customer.
I also noticed that I have to go in the order section and mark them as completed manually. Anyway not to do that?
I was thinking you would not have to do anything manually for when the recurring payment came in.
Have a read of this FAQ.
Brent,
I also was reading the documentation on failed payments. I know PayPal subscriptions will try 2 times and then if it tries to charge the account on the third attempt and cannot, it will suspend the subscription. We had one fail this morning and by reading the documentation, woo won’t attempt to try and charge the subscription again. So basically at this point, the customers account is suspended correct?
Almost, Subscriptions asks PayPal to suspend it immediately in order to have a consistent “failed payment handling” system for all payment gateways. For more details on this system, read over the renewal process guide, especially the info and links in the Failed Payment Handling section.
Hi Brent,
Thanks for your replies. I did a lot of research on the topic before you responded and had pretty much got the grasp of everything.
I do have one lingering question. A customer who’s subscription failed, appeared to have went in and renewed her subscription. However, she did it with an echeck. These take a few days to clear and this morning it cleared however immediately before we got a profile cancelled on her. Now the echeck has cleared and she is showing active in woocommerce subscriptions. However, in paypal when I search her email she has two recurring payments showing as cancelled … one before the echeck clearance and one after. Note: Prior to the echeck clearing, woocommerce showed the order as on hold.
Any insights to this?
Hi Travis, please submit a support ticket with:
Hi Brent,
I appreciate all your help thus far. WooCommerce is making our lives much easier.
I do have another question … I recently activated the tax section of our Store because we are starting an online store where we will need to charge sales tax. I went through all of the subscription and deactivated the tax portion on those. However, I had one customer who appeared to have a failed subscription go back in and somehow renew the transaction. It did not come in as a new automatic payment but as a payment received. I also got a profile cancelled notification however it showed active in WooCommerce. The tax was also added which shouldn’t be on a subscription.
Any insight to this?
Thanks!
Please submit a support ticket with the information requested above: http://support.woothemes.com/
The comments section of an unrelated blog post really isn’t the best place or way to provide support.
Hi Brent,
Can we setup a tutorial session for you to go through your plugin with me so I can ask questions? I would be more than happy for it to be paid. We could do this over Skype?
Hi Travis, I’ve written 30,000 words of documentation and recorded 30 minutes of video tutorials because I can’t provide one-on-one coaching to the thousands of people using Subscriptions. Just about everything I know is in those docs. If there is a question not answered there, submit it to support and we’ll get it answered (and written up in the docs for others). 🙂