Would implementing openssl prevent users from changing the button values? - paypal

Would implementing openssl prevent users from changing the button values?
I've researched into encrypting buttons, from hosted to using openssl.
Using hosted buttons would provide security at the cost of flexibility although there are variables that you can override, but still you cant override the important ones.
would using and implementing openssl on my webserver prevent users from changing a non-hosted paypal button ?
or would it just be better to fall back to a hosted button and use/validate using IPN?

My answer is non–PayPal specific (applies to any kind of HTTP form input), but the short answer is no. Even SSL cannot prevent the browser from modifying the form values that it receives.
A user could use a bookmarklet to execute a JavaScript program of her choice on your page after it has loaded, which has the ability to change form values. Because SSL only protects the transport between the browser and the server, not after the page has been processed by the browser, it makes no difference at all whether you use it.
This could be automated with Greasemonkey, which is the same idea, except makes it even easier for users to install other people’s JavaScript programs to run on your web page. As above, using SSL does not affect this at all, because it is all execute client side, which you, as the server, have no control over.
As you alluded to, using encrypted PayPal buttons would solve the problem, as any modification of the button parameters would invalidate the checksum, and PayPal would not accept the item.

The best solution would be using Express Checkout. This allows you a great deal more flexibility than standard buttons can ever offer you.
If you're thinking if doing IPN, you're probably capable enough to integrate Express Checkout. All it really is, is 1 API call, followed by a redirect to PayPal, and a minimum of 1 more API call to finalize the payment.
A typical flow would look as follows:
Call the SetExpressCheckout API. If you're new to this, it's made dead-easy with PayPal's NVP API interface. You can just send the data as a GET NVP string to https://api-3t.paypal.com/nvp and get a response back in the same format.
Take the token from the response, and redirect to https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=XXXXXXX (https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=XXXXXXX for Sandbox testing)
As soon as the buyer is returned, PayPal will append a PAYERID to your RETURNURL. If you can't find it, call the GetExpressCheckoutDetails API and supply your token to retrieve it.
With the PAYERID and TOKEN, call DoExpressCheckoutPayment to finalize the payment.
To get started with this, I'd suggest taking a looking at the PHP NVP SDK they offer at https://www.x.com/community/ppx/sdks#NVP

Related

Is there a way to authorize orders calling the paypal api directly

For my users to be able to send money to each other on my website I figured the following flow:
User is authenticated with paypal connect
"Clicks on a pay button" calling my api
In the api
Create an order calling /v2/checkout/orders
what returns HATEOAS links, order id. And, I need the user to follow the authorize order
link from the HATEOAS links to authorize the order.
User follows the link.
I capture the order calling /v2/checkout/orders/{id}/capture
And, here is a question: how do I know when users follow the authorize order link to call the capture api? If that is not possible, is there a way to authorize orders calling the paypal api directly without making users following some links?
First of all, what you are actually talking about is user "approval", not authorizing.
The best approval flow to use is this one: https://developer.paypal.com/demo/checkout/#/pattern/server
This way, they don't follow a link and are not redirected away from your site. Your site stays loaded, but is just greyed out while they are presented with an in-context approval flow, and return to your site's JS, which will do a fetch call to your server, which can then do the capture.
An alternative legacy flow is to provide a return_url in your initial create call, where the payer will be redirected back to after approval. This is not recommended, the above solution (that uses no redirects at all) is much more modern and preferred.

How to use PayPal API credentials?

I need to add PayPal button on client's website. It is first time I am doing this and I asked for credentials he gave me API signature, API username and API password. I was checking lots of tutorials how to add PayPal button, they use sandbox/live Client ID and Secret. Can I use this API credentials instead?
I searched a lot but couldn't find an answer.
I am coding in CodeIgniter 3.
Thanks
Username, Password, and Signature are related to Classic API integration.
Client ID and Secret are related to the REST API integration.
Which one do you want to work with?
Or, the easiest option is to use PayPal Standard Payment Buttons, but that will also be the most limiting.
We actually have a PayPal CodeIgniter Library that you might be interested in. It was built for the Classic API.
The general PayPal PHP SDK that it's based on is now available with Composer, so I would recommend installing it that way.
We'll be releasing an update to that library before the end of the year that adds all of the REST APIs. It's available in the dev branch on GitHub already.

REST API: Providing redirect URIs to external services using client app domain

Background
I have a RESTful API accessed through the domain http://restapi.com
I have a client app using http://restapi.com. The client app has the domain http://myapp.com
The way I have my HATEOAS setup is that the API presents URIs without a domain. So instead of http://restapi.com/some/resource, it contains links to resources like so /some/resource. Example API json resource below:
{"_links":{"self":{"href":"/some/resource"}}}
The benefit this has is that the API doesn't need to know about the client app, and the client app has to do very little to get the correct resource from the API and doesn't have to reformat all the URIs in the resource. For example, in the client app, the following URI would be used by the browser http://myapp.com/some/resource. When the app gets the request, it then needs to call the API to get the resource and simply swaps the domain i.e. http://restapi.com/some/resource.
This has been successful so for, and allows a lot of flexibility to have different clients use the API with the only knowledge required being the initial end point (domain) of the API. It also completely decouples the API from the client apps.
The problem I have run into is that I have started using some external services (specifically PayPal adaptive payments) where I need to provide a redirect URL for cancelled payments and successful payments. For example, the browser navigates to http://myapp.com/payment. The resource returned by http://restapi.com/payment presents a link to PayPal. Without going into too much detail, the API has to ask PayPal for a payment ID, which can then be used to create a link to a PayPal payment e.g. http://paypal.com?PayId-123456. Part of the creation process requires that URLs are provided to redirect on payment cancellation or success. Again, don't want to go into details, but when requesting a PayId from PayPal, the redirect URLs are sent as variables to PayPal, and I guess PayPal stores them against the specific PayId created.
The browser navigates to the link returned in the resource - http://paypal.com?PayId-12345. Payment is made and PayPal then uses the redirect URLs as needed to redirect back to my app e.g. on successful completion of payment, PayPal should redirect to http://myapp.com/paymentcomplete. Note: I realise that this is not a restfully named URI, but it simplifies building up the description of my problem
Problem
The problem I have may now be obvious. I need to redirect back to http://myapp.com/paymentcomplete, BUT its the API that provides the redirect URL to PayPal. It has no knowledge of the client application. Since PayPal is an external service, the full URL must be provided. The best the API can do is send http://restapi.com/paymentcomplete as the redirect URL, but if PayPal redirects to this, the resulting response will be a JSON string (the output format of my API) not the nicely formatted page of the client app.
My question is, what is a good way to correctly provide the redirect URL to PayPal?
One thought I had was to make the client application handle creating the PayPal PayId, but I don't like this option as I would like to keep the creation of the PayPal payment ID on the API side. It would also require every client app to provide its own implementation, something I also don't want.
The other option I though of was to ask the client to provide its domain in the request. Currently the request the client makes to get the resource with the link to PayPal is GET http://restapi.com/payment, but I could use POST http://restapi.com/payment with the client providing its domain as a param. The API can then use this to construct the correct redirect URL. I don't really like this idea either as its seems a bit hackish and also requires the app to know that is must fill in this field i.e. a human user wouldn't fill the domain input in.
Additional solutions, or thoughts greatly welcomed.
As you had already mentioned, PayPal is an external api that requires this additional parameter and you do not have control over it. Looks like the client is the only party that can provide the Redirect URI Information.
Couple of ideas come to mind.
The client could send the redirect uri to restapi via header and thus
keeping your rest urls intact. This is a grey area and not a violation of restful api
in my opinion. (Then again, its just my opinion).
The restapi could return the response with a placeholder for the
client to fill in before rendering. This way the API need not know
about the redirect uri and the responsibility is left to the client
which has this information.
It would be nicer if you could implement option 2 with executing couple of lines on Javascript code on the browser to fill-in the placeholder. Which is easy. Ultimately, only 2 end points of this transaction would be aware of the redirect uri - browser & paypal.
This alleviates most of your concerns. The job of handling PayPal id will continue to remain with your API.
You should be able to use the Referer header to determine the client's full URI. It might be populated automatically for you. If not, you can add it yourself. The URI class has methods to pull out the client's host for you. When the API builds the PayPal URI to return to the client, it can include the client's host.
Note that referer is not always included and sometimes gets stripped by intermediaries, as detailed on the wiki page. Since you control both the client and the server in this case, you should be able to tell everybody to play nicely.
I would keep the GET http://restapi.com/payment and pass in a query param with the client domain
GET http://restapi.com/payment?domain=http://myapp.com (of course, the "http://myapp.com" needs to be encoded)

Correct API for accepting credit cards directly on my site using PayPal?

We need to accept credit cards (from anywhere in the world) directly on our website. We'd like to use PayPal, but NOT require a PayPal account. The user should be able to simply type in the credit card, date and cvv directly on our site and go. I'm having a hard time figuring out what PayPal API I need to use for this, to integrate with our Java-based server. Turns out PayPal has an overwhelming number of APIs and documentation.
It looks like this link is what I'm looking for... sort of. But can I post this directly from JavaScript? It includes account name and password, which would be in the clear for anyone to see, so I'm thinking this must be server-side code. So the idea is to use a REST API to do this? So the client must pass the credit card information to my server, which then calls PayPal's server?
I'm a little lost, when looking at all the APIs at the Rest API page. Which ones exactly do I need to use?
There is also this link but I'm not familiar with "curl" -- looking for Java. Maybe the distinction is minor and easy to convert from one to the other?
Vern, if you look at the top of this page, you'll see Java (click Java) as one of the languages supported by the PayPal REST Payment API:
https://developer.paypal.com/webapps/developer/docs/api/
You will see related sample requests that use the Java SDK:
https://github.com/paypal/rest-api-sdk-java

PayPal CUSTREF Not Appearing in PayFlow Pro Transactions with Secure Token (Transparent Redirect)

I'm using PayPal PayFlow Pro to process transactions. We've opted to use the secure token with transparent redirects to try and address PCI-Compliance issues.
In my token request, I am specifying the CUSTREF parameter like so:
&CUSTREF=461
I have also created a hidden field for this in the transaction form. I have the HTTPS proxy enabled for Fiddler and I can see these values coming through in both the secure token and transaction requests. The transactions complete successfully on the live PayFlow gateway.
However, when I view the transactions under https://manager.paypal.com/ > Reports > Daily Activity, the Cust Ref #: field on the detail page is empty.
The parameter is discussed for use in inquiry transactions on page 71 of this document:
https://www.paypalobjects.com/webstatic/en_US/developer/docs/pdf/payflowgateway_guide.pdf
I couldn't find much documentation on this field other than this. I had a look at some code samples, and it looks like the CUSTREF parameter should be passed in the transaction request (which was the first thing I tried), e.g.
https://github.com/angelleye/paypal/blob/master/PayFlowTransaction.php
Has anyone encountered this before? I have a ticket open with PayPal.
I received confirmation from PayPal that this is a bug.
This appears to work with the regular Payflow Pro API calls, but fails when passing the CUSTREF using a Secure Token API call or hosted pages (using Secure Token).
The recommended work-around was to pass the field through in the comments.