I am trying to set up a recurring payment with PayPal Subscription REST API. I'm following the Basic Integration in PayPal Developer Portal, using as suggested the Smart Payment Button. Besides, I'm using a WebHook to "capture" events related to subscription.
As the tutoria suggest, I created a Product and a Plan.
Now, I rendered the Smart Payment Button in a page (using the example), and when clicked it triggers the PayPal authorization flow. When the user complete the subscription process, the BILLING.SUBSCRIPTION.CREATED event is triggered. Later, also the PAYMENT.SALE.COMPLETED and BILLING.SUBSCRIPTION.ACTIVATED are triggered, and I receive data in my WebHook. Now, I have troubles in identifying which user activated the subscription. My idea is to pass a custom variable (with something allows me to identify the user) and retrive it later when the WebHook post me data, but I can't undertand how to do it. Anyway, is this the best way to do it? Or there is another solution?
I solved this using "custom_id" in the smart button:
return actions.subscription.create({
'plan_id': 'PLAN_ID',
'custom_id': 'CUSTOM_ID'
});
Then, I receive custom_id from webhooks or querying the subscription.
Related
I'm trying to implement the PayPal Subscription API but I'm not sure about the process flow.
I use the react-paypal-js package to generate the subscription button.
The way the users are created on my website is only through the Paypal subscription.
The process is as follow:
The user choose a plan and click on the subscribe button
The PayPal window open and the user follows the subscription process on Paypal
The user is redirected to my website
Using webhooks or with the onApprove callback, I receive the newly created subscription, create a user on my website with the Paypal email address associated with the subscription.
It all works. My problem is that I need to check, before accepting the subscription, if I already have a local user with given email and in this case, I don't want to accept the subscription (as I would then have 2 subscriptions for the same user) and display a message saying that their is already an active (or suspended) subscription associated with the given email.
As far as I can tell, when the onApprove is called or the webhook is called, the subscription has already been processed and activated.
Thanks!
You don't have to design a system in which the PayPal email used to make the payment, and the email of the user used to log into your site, have a 1:1 relationship. Instead you can have the user log and create their account with you first (as they will always need that to manage something subscription-based) and then you will know there is no subscription associated with that user before displaying the PayPal Subscribe button. Then they can pay with any PayPal account (might be the same email, might be different)
As far as I can tell, when the onApprove is called or the webhook is called, the subscription has already been processed and activated.
That is the default behavior, yes. Per the above it shouldn't be ncessary, but you can change the subscription to start in an inactive state, and show a final review step on your site that will activate it via API. This is controlled by setting application_context -> user_action -> CONTINUE (vs default SUBSCRIBE_NOW). See the API reference for subscription create, and you would of course need to use the subscription activate API call as a final step after confirmation.
From a developer perspective, what is the best way to capture (webhook wise) a user cancelling their PayPal subscription via their dashboard (and/or subscription payment failing)?
I've had some discussions with PayPal support and have learnt the following:
Subscription button:
-simple, elegant, works well to let user subscribe
-however, when user cancels subscription via their dashboard does NOT fire a BILLING.SUBSCRIPTION.CANCELLED webhook. Only an IPN HTTP "webhook" gets fired. From the paypal docs, IPN seems harder to integrate (not REST, and for example the IPN simulator doesn't even have "subscription cancellation" events)
Using API (PayPal PHP SDK):
-DOES fire BILLING.SUBSCRIPTION.CANCELLED webhook events when user cancels their subscription via their PayPal dashboard (why this doesn't work for button-created subscriptions I do not understand)
-However, seems much more complex to set up than the button (what does the web flow look like?)
Just some thoughts on the best approach would be appreciated.
It depends on the type of 'Subscribe' button.
Legacy 'Subscribe' buttons created via e.g. https://www.paypal.com/buttons , will not fire a BILLING.SUBSCRIPTION.CANCELLED webhook. Those buttons predate webhooks by 10 years, and only use the very old IPN service. Stay away...
Current smart subscribe buttons, created via e.g. https://www.paypal.com/billing/plans or following the documentation do trigger the BILLING.SUBSCRIPTION.CANCELLED webhook.
In general, you can make use of the CANCELLED webhook and track this status if you want to but it's not necessary. The most important best practice is to make use of PAYMENT.SALE.COMPLETED and record when a subscription was last actually successfully paid for. If it doesn't get paid for again on time, then it's lapsed and you treat it accordingly.
When creating a subscription, along with the plan_id you can pass a custom_id which will be returned in all the webhooks. This can be useful for reconciliation purposes so you know which user it's for.
Using API (PayPal PHP SDK):
That SDK is deprecated, don't use it. Any API calls should be done directly via HTTPS.
I haven't tested in live, but currently I have a webhook subscribed to the following events
Billing subscription cancelled
Billing subscription created
Billing subscription re-activated
Billing subscription suspended
Billing subscription updated
I'm receiving Webhook events for CREATED but nothing is being sent when a user cancels the subscription from their PayPal dashboard.
Is this expected behavior? is there another event I should be subscribe to to capture that user action?
Is there a debug id that you can share so we can trouble shoot?
Thanks,
Usha
From Paypal support (I still don't understand why the BILLING.SUBSCRIPTION.CANCELLED doesn't fire when a user cancels from their dashboard, similar issue here: BILLING.SUBSCRIPTION.CANCELLED does not fire upon user action?)
"But surely users subscribing via the button is the most common method of subscribing (how else would they subscribe?). The IPN route seems like a completely non-developer-friendly one (seeing as there isn't even simulator events for it)"
If you integrate a solution which is not based on our REST API's and want to receive HTTP notifications, you need to use instant payment notification (IPN). The IPN simulator may not provide a method of simulating the events, but you can create subscriptions in our sandbox environment and setup a sandbox business account with IPN and test cancelling the subscriptions, which will generate an IPN for the cancellation. We have a sandbox testing guide available here if you're not familiar with that environment and want to get started.
"So why would webhooks ONLY fire for API-based subscriptions (and why would a business website subscribe users using the API rather than the simple button)? What is the logic behind this?"
It depends on the integration and needs of the individual business. Some businesses only use our REST-based API solutions for their complete integration, from checkout payments to subscriptions and logically, this makes sense to them to only have to use one set of API's for their complete integration. Other business only want / need a more simple solution such as using buttons and as these are legacy solutions which are not REST-based, they use our legacy HTTP notification service which is instant payment notification (IPN).
Is there a way to stop paypal subscription via HTML form?
(E.g. there is a form on my website that is submit somewhere on paypal.com)
I do not use API, but I use notify (IPN) URL and have subscription ID I want to cancel.
PayPal Standard Subscriptions do not have any API available to cancel profiles. You would need to be using the Recurring Payments API in order to have that ability.
as stated here: Detecting Paypal Subscription Cancellation api can be used to detect a paypal subscription cancellation. what about the opposite? using magento, i have code that creates the paypal subscription but when i cancel the subscription (in the cart), the cancellation is not passed to paypal and i must then go to paypal to cancel.
it would be great to avoid the extra step of double canceling and just only have to cancel from my cart (as admin and as customer via api sent to paypal)
You can use the ManageRecurringPaymentsProfileStatus API to cancel "I-" profiles. As far as if Magento supports this, or if there is a plugin that you can use I don't know of one off hand. However, it is possible. All that needs to happen is that your cart just needs to make API call.