0

I have a web application (written in PHP) that offers 3 subscription types in order to use the web application. The subscription types are: Monthly, 6 Months and Yearly. All the users that utilize the demo version (similar to a trial period) of my web application must sign up, so I have their name and they are assigned an ID, which is stored in a session variable and on the db. After the "trial" period is up, they have an option to either subscribe or their demo account is automatically deleted by the system.

I have tried to use the PayPal "Smart Buttons", and they did work. The problem was that I have no idea which user subscribed and which subscription plan they chose. I can look it up directly on PayPal but that doesn't do me any good because I need that information to be stored in my db. I read about the implementing webhooks for the subscription but that has me so lost. So I decided to write my own API using PHP to communicate with PayPal.

It retrieves the access token using my sandbox credentials. Then I create the product (which is one of the subscription types) and get the product_id. I then create the subscription plan which sets the billing cycles and amount of the plan. Each request works. I have the activate subscription and capture authorized payment Api's set up. The activate subscription and the capture authorized payment I presume are used after the user has subscribed.

My Question: How do I create the PayPal buttons that display the PayPal, Venmo, and Credit Card buttons (without using the PayPal Smart Buttons) and have them link to the product and subscription plan using the API that I had started? And how do I pass along the Users ID so that I may track which subscription they have chosen? I know next to nothing about javascript, so using the javascript SDK or the NODE JS is really out of the question for me.

Everything I have found is always directing me to the PayPal site and creating the "Smart Buttons". That is all nice and dandy, but I have no way of telling which of my users had created the subscription. Much less getting real time subscription information as the process is happening.

I'm new to all this API stuff and I'm trying to figure it all out. Perhaps my workflow is wrong?

This is what I currently have for a work flow:

A guest user can go to the subscription page where they have the 3 options for subscriptions. They click on the monthly plan. It takes them to my "checkOut" page. On this page is where the "PayPal" buttons should be. Or a "Subscribe Now" button? How do I make the buttons that have the 3 different payment options so that the PayPal window pops up for the user to complete the transaction?

I know I'm missing something to make this all work, but I don't even really know what to ask to find what I'm missing. If that makes any sense.

UPDATE I have found https://stackoverflow.com/questions/63899329/paypal-smart-subscribe-server-side this but I am not following what they are talking about.

Preston PHX
  • 27,642
  • 4
  • 24
  • 44

1 Answers1

0

There are two ways to create Subscription buttons. Either way will accomplish what you need.

  • With the https://www.paypal.com/billing/plans interface you've already used. In the generated code add a custom_id parameter with any additional metadata you need for the subscription. This value will be returned in all future notifications for that subscription.
  • Create the button yourself by first creating a plan as you've already discussed, and then doing the same as the above with your own code (instead of having the PayPal site generate it for you). This is step #3 of the Subscriptions guide.

Whether or not you use the PayPal site to generate the plan and button code, the remaining steps of populating a custom_id in the createSubscription request and integrating webhooks to receive PAYMENT.SALE.COMPLETED events are the same. Ensure you use the same app/client-id as the button when registering for webhook events (a different client-id from the button will not receive its events).

Preston PHX
  • 27,642
  • 4
  • 24
  • 44
  • Since I am creating my own API, will the subscriber be redirected to the PP site once I implement the button? Or am I setting this all up to be done from my site without the user leaving my site? This is a ton of information to learn and to try to figure out. – Cavalier Horsemanship Jun 27 '23 at 20:09
  • JS SDK Subscription buttons open an in-context window (mini browser) for payers to approve the subscription. So a PayPal window does open, but there is no redirect away from your site. – Preston PHX Jun 27 '23 at 20:14
  • I have also made the create Subscription API. Should this be done after the user clicks on the button or on the same page as the subscribe now button? When and where to use the API is partly what is confusing me now. – Cavalier Horsemanship Jun 27 '23 at 20:19
  • and the JS SDK, is that part of the form for the buttons that I copy to my site? As I stated, I'm rather javascript illiterate. – Cavalier Horsemanship Jun 27 '23 at 20:21
  • When a subscription button is clicked, its `createSubscription` callback function is called. This needs to return a created subscription for the checkout to proceed. There are two ways to create that subscription, either `return actions.subscription.create({....` to do so on the client side, or `return fetch('/path/on/your/server/that/creates/a/subscription/using/the/REST/api/and/returns/the/result'....`. So if you want to create the subscription for approval yourself using the API, you'll need to fetch it from the JS. Either creation method will work. – Preston PHX Jun 27 '23 at 20:24
  • Ok... This is where I'm getting a little lost on the process flow. On the page that has the subscribe now buttons (which it offers 3 choices - 3 buttons) Is it this page the I use the API to create the product, create the plan and create the subscription? Or should the buttons direct to a page that would process all the API's and redirect to a success page or cancel page? – Cavalier Horsemanship Jun 27 '23 at 20:35
  • I wish there was a tutorial I could find to go from start to finish, step by step to implement the entire work flow for the subscriptions. What to have on each page, which api's to use on which page and to handle redirects... It feels like I'm dealing with a puzzle and trying to put all the pieces together with it upside down. :) – Cavalier Horsemanship Jun 27 '23 at 20:36
  • So I need to set up a page that will directly handle the process. That way I can get the return information to update my db? – Cavalier Horsemanship Jun 27 '23 at 20:38
  • The product and plan should be created beforehand. That's an initial one time setup. When createSubscription is called (i.e. the user clicked JS button), the existing plan_id should be used to create a subscription. Most simply, use the code from https://www.paypal.com/billing/plans or in the Step 3 of the guide for this, which does not involve an API call. Add the `custom_id` parameter with a value that means something to you when creating the subscription. Then using the same app/client-id as what rendered the buttons, register for webhook events -- particularly PAYMENT.SALE.COMPLETED – Preston PHX Jun 27 '23 at 20:40
  • On the webhook documentation, it says: "To configure a webhook, define your webhook listener URL". What is a webhook listener URL and what should be on that page? and how would it get called on the server side? Only thing I can think of is to have a class defenition that is called each time a user loads a page and a method does an api call to paypal to check for subscription changes. But that does not seem like it would fall under the webhook URL... – Cavalier Horsemanship Jun 27 '23 at 20:51
  • Webhooks are a separate notification, from PayPal to your server. You can register a webhook URL in the app(client-id) settings https://developer.paypal.com/dashboard/applications , or using the webhooks API. – Preston PHX Jun 27 '23 at 20:56
  • As for what should be done at that URL, the only response it needs to give is an HTTP 200 OK for the webhook to be marked as successfully delivered. Beyond that, verify the webhook came from PayPal and use the event body to update your records, i.e. for PAYMENT.SALE.COMPLETED a payment was received. – Preston PHX Jun 27 '23 at 20:57
  • If I use the fetch(path/to/my/api/) to create the subscription from the paypal buttons, I could get the return information right then? correct? – Cavalier Horsemanship Jun 27 '23 at 21:10
  • why is the subscription create time 5 hours off from my time? I'm in CST but the return info is showing 5 hours in the future... or +5 UTC – Cavalier Horsemanship Jun 27 '23 at 21:13
  • No. Creating the subscription for approval is not the same as receiving a notification that it was approved and is active (as well as of future payments); those are quite different things. – Preston PHX Jun 27 '23 at 21:33
  • Let's see if I am understanding the webhook thing. Using the webhooks URL page, I can retrieve all the subscription information from the webhook (using a REST api) automatically when a user subscribes? And on the webhook page is where I could do all of my server side updates once I get the information? – Cavalier Horsemanship Jun 28 '23 at 00:46
  • I have replaced the return actions.subscription.create() with this: fetch('h ttp://cavalierhorsemanship.com/clients-dev/api/API.php?plan_id=&custom_id='); But I am getting a huge error in the console that says: Expected a subscription id to be passed to createSubscription. I thought by pressing the paypal button to subscribe and it fetching the createSubscription. Or do I have to echo it out? or what??? I'm sooooo lost with this stuff.... :( – Cavalier Horsemanship Jun 28 '23 at 03:12
  • One other thing. I do not yet have my SSL certificate, so at the moment I can't use the webhooks :( – Cavalier Horsemanship Jun 28 '23 at 03:25
  • Creating a plan is not the same as creating a subscription using that plan. For most purposes a plan should be created exactly once. After it's been created, use the same given plan_id for all subscription creation, regardless of whether that subscription creation involves a server API call or not. With actions.subscription.create it would not. If fetching a created subscription from a server, the server must return a valid JSON object with an `id`, and the JS must make use of that returned id. See https://developer.paypal.com/demo/checkout/#/pattern/server for an example of fetching an id. – Preston PHX Jun 28 '23 at 06:25
  • A webhook URL is not a "page". It should not return nor output anything except an HTTP 200 success code. When it receives a posted webhook event of interest (PAYMENT.SALE.COMPLETED) it should (after verifying the posted webhook is from PayPal) record the associated subscription as active/another month paid in your system/database. – Preston PHX Jun 28 '23 at 06:26
  • is there any documentation/tutorials that utilize PHP to manage webhooks? The documentation on paypal for webhooks uses Java and I'm not a Java person at all. – Cavalier Horsemanship Jun 28 '23 at 14:29
  • The Java code is just example pseudocode, to be implemented in the language of your choice. Alternatively you can post the event back to the webhook verification API – Preston PHX Jun 28 '23 at 15:53