Why are my PayPal Checkout buttons not opening a link to the PayPal Sandbox? - paypal

I am trying for the first time to implement a PayPal Checkout solution (aka PayPal Commerce Platform for Business) in an ASP.NET Web Application, using Web Forms. I've set up a new REST API for the Sandbox and followed PayPal's Set up server-side SDK guidance to install the SDK in my .NET project. PayPal's button demo now lets me log into the Sandbox with a newly created Sandbox user name and make a test payment, which is confirmed as being successful. So far, so good.
My next step was to create a PayPalButton.aspx page containing exactly the same code as used on Paypal's button demo page. All my updated code was then uploaded to my live site. That's when I hit a problem, as the PayPal buttons don't work on my live site (the PayPal log in window just briefly flashes and then disappears). Being a total newbie to the Paypal Checkout process, it's highly likely that I have made some very basic error.
The only thing I can think of is that my problem might have something to do with the section in Set up server-side SDK that refers to modifying HTTP request headers? I didn't understand what that section was asking me to do.

What routes/paths did you implement the create order and capture order functions at? What data do they return? Update your question with this information. For the create order route, is the data a valid JSON object with a PayPal order ID in the id key?
Have you set the paths in your "PayPalButton.aspx" HTML/JS code to call the aforementioned routes? Your question does not include any specific information about what is going on, i.e. your button code and the result (Response body) of the fetch calls from the browser's developer tools 'Network' tab.

This morning, I managed to resolve the problem with my PayPalButton.aspx page just briefly flashing the PayPal login page. As previously mentioned, it contains a script copied from PayPal's button demo. I then realised that it was different from the sample script provided on the Integrate Checkout page.
I created a new PayPalButton2.aspx page containing this alternative script and, unlike PayPalButton.aspx, it worked fine. In both cases, I had substituted my own Sandbox ClientID.

Related

How to move PayPal Checkout to live production?

I've set up a PayPal Checkout button with my sandbox account, which works, and now I want to change it to use my live business account. There seems to be conflicting information out there on what to do next:
The docs say that I need to submit my app for approval (but it doesn't say how)
This stack question says that with PayPal Checkout you don't need to submit your app for approval
In paypal.php (I'm using laravel) there is a parameter called PAYPAL_LIVE_APP_ID, which I didn't need with the sandbox and I've been trying to find. This stack question from 2016 tries to find the app id but all links provided there are broken. Do I need the app id for PayPal Checkout?
I don't know what I'm doing wrong but when I set the PAYPAL_MODE in .env from sandbox to live, the PayPal button in my app stops working and shows:
Uncaught Error: INVALID_RESOURCE_ID
at https://www.sandbox.paypal.com/smart/buttons?style.layout=vertical&style.color=gold&style.shape=rect&style.tagline=false&style.height=45&style.menuPlacement=below&sdkVersion=5.0.332&components.0=buttons&locale.country=GB&locale.lang=en&sdkMeta=eyJ1cmwiOiJodHRwczovL3d3dy5wYXlwYWwuY29tL3Nkay9qcz9jbGllbnQtaWQ9QVNWTnlaeTZ0TkdYTnJ4aFhzSXdGLUhKckN4U1NZb1VHVlozd3NqNXVRN3FmMGp4RFAtLXBmTHlUcjUxUnNGVzh0bXFtcnNtYlB4N0VBUWYmZGlzYWJsZS1mdW5kaW5nPWNhcmQsZ2lyb3BheSxzZXBhLHNvZm9ydCZjdXJyZW5jeT1FVVIiLCJhdHRycyI6eyJkYXRhLXVpZCI6InVpZF93cXN2eHlzd3lwcmp6YWdpc21haWduaGlxZXdyZmkifX0&clientID=ASVNyZy6tNGXNrxhXsIwF-HJrCxSSYoUGVZ3wsj5uQ7qf0jxDP--pfLyTr51RsFW8tmqmrsmbPx7EAQf&sdkCorrelationID=f374804ab30b1&storageID=uid_9a4b452c76_mdc6mdi6mjm&sessionID=uid_7aec7bdf11_mdk6nda6nde&buttonSessionID=uid_79a5ce6aa1_mdk6nda6nde&env=sandbox&buttonSize=medium&fundingEligibility=eyJwYXlwYWwiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sInBheWxhdGVyIjp7ImVsaWdpYmxlIjpmYWxzZSwicHJvZHVjdHMiOnsicGF5SW4zIjp7ImVsaWdpYmxlIjpmYWxzZSwidmFyaWFudCI6bnVsbH0sInBheUluNCI6eyJlbGlnaWJsZSI6ZmFsc2UsInZhcmlhbnQiOm51bGx9LCJwYXlsYXRlciI6eyJlbGlnaWJsZSI6ZmFsc2UsInZhcmlhbnQiOm51bGx9fX0sImNhcmQiOnsiZWxpZ2libGUiOmZhbHNlLCJicmFuZGVkIjp0cnVlLCJpbnN0YWxsbWVudHMiOmZhbHNlLCJ2ZW5kb3JzIjp7InZpc2EiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sIm1hc3RlcmNhcmQiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sImFtZXgiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sImRpc2NvdmVyIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfSwiaGlwZXIiOnsiZWxpZ2libGUiOmZhbHNlLCJ2YXVsdGFibGUiOmZhbHNlfSwiZWxvIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfSwiamNiIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfX0sImd1ZXN0RW5hYmxlZCI6ZmFsc2V9LCJ2ZW5tbyI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJpdGF1Ijp7ImVsaWdpYmxlIjpmYWxzZX0sImNyZWRpdCI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJhcHBsZXBheSI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJzZXBhIjp7ImVsaWdpYmxlIjpmYWxzZX0sImlkZWFsIjp7ImVsaWdpYmxlIjpmYWxzZX0sImJhbmNvbnRhY3QiOnsiZWxpZ2libGUiOmZhbHNlfSwiZ2lyb3BheSI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJlcHMiOnsiZWxpZ2libGUiOmZhbHNlfSwic29mb3J0Ijp7ImVsaWdpYmxlIjpmYWxzZX0sIm15YmFuayI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJwMjQiOnsiZWxpZ2libGUiOmZhbHNlfSwiemltcGxlciI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJ3ZWNoYXRwYXkiOnsiZWxpZ2libGUiOmZhbHNlfSwicGF5dSI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJibGlrIjp7ImVsaWdpYmxlIjpmYWxzZX0sInRydXN0bHkiOnsiZWxpZ2libGUiOmZhbHNlfSwib3h4byI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJtYXhpbWEiOnsiZWxpZ2libGUiOmZhbHNlfSwiYm9sZXRvIjp7ImVsaWdpYmxlIjpmYWxzZX0sImJvbGV0b2JhbmNhcmlvIjp7ImVsaWdpYmxlIjpmYWxzZX0sIm1lcmNhZG9wYWdvIjp7ImVsaWdpYmxlIjpmYWxzZX0sIm11bHRpYmFuY28iOnsiZWxpZ2libGUiOmZhbHNlfX0&platform=mobile&experiment.enableVenmo=false&experiment.enableVenmoAppLabel=false&flow=purchase&currency=EUR&intent=capture&commit=true&vault=false&disableFunding.0=card&disableFunding.1=giropay&disableFunding.2=sepa&disableFunding.3=sofort&renderedButtons.0=paypal&debug=false&applePaySupport=false&supportsPopups=true&supportedNativeBrowser=true&experience=&allowBillingPayments=true:1320:46529
at n.dispatch (https://www.sandbox.paypal.com/smart/buttons?style.layout=vertical&style.color=gold&style.shape=rect&style.tagline=false&style.height=45&style.menuPlacement=below&sdkVersion=5.0.332&components.0=buttons&locale.country=GB&locale.lang=en&sdkMeta=eyJ1cmwiOiJodHRwczovL3d3dy5wYXlwYWwuY29tL3Nkay9qcz9jbGllbnQtaWQ9QVNWTnlaeTZ0TkdYTnJ4aFhzSXdGLUhKckN4U1NZb1VHVlozd3NqNXVRN3FmMGp4RFAtLXBmTHlUcjUxUnNGVzh0bXFtcnNtYlB4N0VBUWYmZGlzYWJsZS1mdW5kaW5nPWNhcmQsZ2lyb3BheSxzZXBhLHNvZm9ydCZjdXJyZW5jeT1FVVIiLCJhdHRycyI6eyJkYXRhLXVpZCI6InVpZF93cXN2eHlzd3lwcmp6YWdpc21haWduaGlxZXdyZmkifX0&clientID=ASVNyZy6tNGXNrxhXsIwF-HJrCxSSYoUGVZ3wsj5uQ7qf0jxDP--pfLyTr51RsFW8tmqmrsmbPx7EAQf&sdkCorrelationID=f374804ab30b1&storageID=uid_9a4b452c76_mdc6mdi6mjm&sessionID=uid_7aec7bdf11_mdk6nda6nde&buttonSessionID=uid_79a5ce6aa1_mdk6nda6nde&env=sandbox&buttonSize=medium&fundingEligibility=eyJwYXlwYWwiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sInBheWxhdGVyIjp7ImVsaWdpYmxlIjpmYWxzZSwicHJvZHVjdHMiOnsicGF5SW4zIjp7ImVsaWdpYmxlIjpmYWxzZSwidmFyaWFudCI6bnVsbH0sInBheUluNCI6eyJlbGlnaWJsZSI6ZmFsc2UsInZhcmlhbnQiOm51bGx9LCJwYXlsYXRlciI6eyJlbGlnaWJsZSI6ZmFsc2UsInZhcmlhbnQiOm51bGx9fX0sImNhcmQiOnsiZWxpZ2libGUiOmZhbHNlLCJicmFuZGVkIjp0cnVlLCJpbnN0YWxsbWVudHMiOmZhbHNlLCJ2ZW5kb3JzIjp7InZpc2EiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sIm1hc3RlcmNhcmQiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sImFtZXgiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sImRpc2NvdmVyIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfSwiaGlwZXIiOnsiZWxpZ2libGUiOmZhbHNlLCJ2YXVsdGFibGUiOmZhbHNlfSwiZWxvIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfSwiamNiIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfX0sImd1ZXN0RW5hYmxlZCI6ZmFsc2V9LCJ2ZW5tbyI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJpdGF1Ijp7ImVsaWdpYmxlIjpmYWxzZX0sImNyZWRpdCI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJhcHBsZXBheSI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJzZXBhIjp7ImVsaWdpYmxlIjpmYWxzZX0sImlkZWFsIjp7ImVsaWdpYmxlIjpmYWxzZX0sImJhbmNvbnRhY3QiOnsiZWxpZ2libGUiOmZhbHNlfSwiZ2lyb3BheSI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJlcHMi
and:
GET https://b.sbox.stats.paypal.com/v2/counter.cgi?p=uid_7aec7bdf11_mdk6nda6nde&s=SMART_PAYMENT_BUTTONS net::ERR_ADDRESS_UNREACHABLE
The information on that doc page is out of date. An "app id" is only used by Adaptive Payments integrations, which are obsolete and cannot be used for new integrations anyway.
For REST applications, a live "client id" and "secret" can be created in the dashboard My Apps & Credentials. They do not require any additional approval/registration unless you are using partner (multi-party) or log in with PayPal features.
The error "INVALID_RESOURCE_ID" is usually caused by mixing things from sandbox and live. Ensure that:
The <script> element with src https://www.paypal.com/sdk/js?client-id= specifies a live client ID, not a sandbox/test one.
Any fetch calls the button code might make (if using a server integration pattern) retrieve a newly-created and valid live order ID or classic API EC token, not a sandbox one. The browser dev tools "Network" tab is useful for debugging and verifying such an XHR is working.
Any plan_id (if using a Subscription button) was created with the corresponding live client ID .. not a different client ID nor a sandbox one.

Rendering an official PayPal button that uses REST APIs

I am beginning an integration using the PayPal REST API as I need full control over the checkout process.
I assumed that I'd be coding everything server side, so I cannot see how I should be adding the PayPal button which essentially should just call my own code which will set up the order via the API and redirect to the PayPal URL?
There is lots of online help on how to add the smart buttons etc but these look to initiate the quick checkout process via the Javascrip SDK.
Essentially I want to render an official PayPal button, but have it call a local server side page.
Follow the Set up standard payments guide, particularly #5 of "Add and modify the code".
Be sure to read that section and click through to the demo code sample for the approval flow, https://developer.paypal.com/demo/checkout/#/pattern/server
That's for a pure HTML/JS client -- there are also some framework-specific options..
react-paypal-js Storybook
Angular and Vue, see here
A package manager such as NPM, paypal-js

API for completing PayPal one-time payments

I'm looking for ways to make a PayPal payment using PHP. I understand there are deprecated APIs and current one. so I've found several ways to do so. but lots documents lead me into labyrinth. I'm quite confuse de.g. client button rendering, how to call our PHP script/ what is a PayPal-Request-Id and to get it/ what can we do with a token from webscr ==> cmd=_express-checkout&token=EC-7BA65327KY8480517 and etc.
I tried to use a button on my page to submit some few paypal-required parameters using html form. The receiving php file formed payment record as need, then create order. I got the order-id, but what is it for? so I set up a new parameters, conformed the PayPal needs to create a payment. This give me 4 links, one I choose to get redirected for client logging in and continuing. with this one I got to landing page then I executed a payment but each payment on sandbox dashboard says pending.
I am then confused how to get completed payment. Right here there is my data with THB currency
{"id":"PAYID-MAKU2OI7RR56034B9692111L","intent":"sale","state":"created","payer":{"payment_method":"paypal"},"transactions":[{"amount":{"total":"1126.15","currency":"THB","details":{"subtotal":"979.26","tax":"146.89","shipping":"0.00","insurance":"0.00","handling_fee":"0.00","shipping_discount":"0.00"}},"description":"aonang to","custom":"0","invoice_number":"kbv.starlight_12","soft_descriptor":"MFWD","payment_options":{"allowed_payment_method":"INSTANT_FUNDING_SOURCE","recurring_flag":false,"skip_fmf":false},"item_list":{"items":[{"name":"MFWD","sku":"kbv.starlight_12","description":"aonang to ","price":"979.26","currency":"THB","tax":"146.89","quantity":1}]},"related_resources":[]}],"note_to_payer":"Contact us for any questions on your order.","create_time":"2021-01-30T12:12:40Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAYID-MAKU2OI7RR56034B9692111L","rel":"self","method":"GET"},{"href":"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-1G552540DR9655320","rel":"approval_url","method":"REDIRECT"},{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAYID-MAKU2OI7RR56034B9692111L/execute","rel":"execute","method":"POST"}]}
Sandbox account interface screenshot
You mention the classic Express Checkout API and the deprecated v1/payments API, but the right solution is to use the current API, v2/checkout/orders
Create two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here. These routes should return JSON data (and only JSON data) when called by an XHR/fetch.
Pair your two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server

Roadblocks with using PayPal Recurring Payment Subscription with ASP.Net Membership?

I'm using ASP.Net Membership Provider for logging into the premium content of this web site. The content isn't downloads, it's web pages of information and discounts, etc. That part is done. We want them to also have a PayPal Subscription annual payment to see the premium content. I would like ASP Membership and PayPal Subscription to work together as much as possible, but for the minimum I am thinking they will have to create a MemberId before they pay. Then I will send that MemberId to PayPal to associate the two.
I think I can do that like this:
Set "Auto Return" on in the interface so that it will redirect to return URL when payment is made.
Set "return URL" query string to MemberId. This requires not using the precompiled "Saved" buttons. I'll have to set it in Code Behind with Name Value Pairs, "NVP" to PayPal. I was hoping to just paste the stupid button.
But then, there were those "Advanced Variables" in the Button maker. Problem was they are compiled into the Saved button, so I can't change them for each person. But maybe that one parameter could be separate from the compiled parameters? Is this better than hacking the return URL? Are "Advanced Variables" good for anything?
All the details about the transaction will be POSTed to the return URL if I put in the right code, which might be rm=2. (Right?) Then I can record it.
This process is said to be unreliable, though, and PayPal recommends using a secondary system that they have, "IPN". PayPal sends the transaction details to me. I send them back http 200 code. Then I send it back to them in the same order I got it. Then they send me http 200. Then we all know it's good. This sounds like a few hours research to me, but if you've already done it once, it sounds like copy and paste. I hate reinventing the wheel. Is there a .Net sample of this IPN handshake/dance?
Also, if I do the IPN thing, maybe I don't need Auto Return. Maybe I add MemberId to "notify" URL instead of "return" URL. Then PayPal can handle the confirmation page, email, etc. Is that better?
Assuming we get the Subscription paid for and recorded with the MemberId, at least once per user session, after they log in, I have to check if they have paid their PayPal subscription and if it's up to date. "GetRecurringPaymentsProfileDetails" does this, but it is an API operation. That makes sense, but I was hoping to avoid learning their REST API. (Is there a "NVP" version?)
REST API OAUTH tokens expire every few minutes, but the only way it tells to get one is by using "Bash" to "cURL" some Linux commands. Again, this seems like the kind of thing that would only ever have to be written once. Does this already exist as a sample code somewhere?
(I don't want to use the API to do the Subscribe, because I don't want the Credit Card numbers to ever go to our site. Too much liability. That's why I wanted PayPal.)
Will this even work? I know PayPal has 18 ways to do everything and they all exclude each other, and I'm just getting the feeling that I'm creating a patchwork of unrelated ideas to fool myself into believing there's a light at the end of the tunnel. I've already been researching and experimenting for 10 hours or so. I really thought, going in, I'd just be pasting a stupid button.
If you want to just "copy the stupid button" then you'll have to stick to Payments Standard, and then you'll be limited with what you can do. For example, you won't be able to use GetRecurringPaymentsProfileDetails for a standard subscription.
Instead, you'll need to use Express Checkout and / or Payments Pro. There is indeed an NVP API available for these, and there is also a SOAP/XML version. Details on those can be found here: https://developer.paypal.com/docs/classic/api/
Specifically, for Express Checkout, you'll want SetExpressCheckout, GetExpressCheckoutDetails, DoExpressCheckoutPayment, and CreateRecurringPaymentsProfile. Some of those calls are optional depending on how exactly you're configuring things with the checkout flow.
For Payments Pro you'll use either DoDirectPayment / CreateRecurringPaymentsProfile or PayFlow depending on what version they put you on.
In any case, IPN is definitely the way to go for post-transaction processing.
.NET IPN Sample - https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.asp

Make payment at PayPal before SubmitOrder

This question is based on a project done through the MvcMusicStore tutorial.
Same technologies are also implemented in my site e.g. (MVC3, Sql Server 2008 SSMS & EF Code First)
I have implemented PayPal Web Standards payment at my project. Thanks to #Arun, i have referred to his site here http://www.arunrana.net/2012/01/paypal-integration-in-mvc3-and-razor.html
Situation at MvcMusicStore:
My project is similar to the data flow of MvcMusicStore. As you can see in this link, http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-9
In this tutorial, Jon Galloway has inserted a Payment field in the AddressAndPayment.cshtml page (but for simplicity purposes he made all products to be purchased for free by typing the keyword 'Free' - which would allow the user to checkout by clicking SubmitOrder and saving the Order in database)
Situation at My Project:
My question is about the workflow that i intend to apply.
When user adds items to shopping cart and reviews items in the Cart.
I want to:
Redirect user to PayPal to make payment upon clicking Checkout
After User make payment, return the user to AddressAndPayment.cshtml page
User then enters information and submit order
Is this work flow even right to begin with?
If yes, how do i convert these variables from my project;
Product.Title
Product.Quantity
Product.UnitPrice
to match these PayPal variables?
Item_Name
Amount
Quantity
Well i figured it out myself.
My first question, "Is this work flow even right to begin with?"
I have implemented it successfully. I cant say it is 100% right way of implementing it. It depends on your own system workflow. As for MvcMusicStudio, i cannot think of any other methods than this.
As for the second question, all i did was call a foreach loop and looped the PayPal variables. You will see it in more detail on Arun's website (link provided in the question thread above).
Thank you.