Adaptive Payments without modal box or popups? - paypal

Is it possible to launch the payflow entirely inline (a la Express Checkout)? How?
We're using chained payments and everything works on non-iOS-mobile devices (and in Chrome for iOS), but we're making a web app, so we need this to work on phones. Testing on the iPhone, we have this problem with PayPal's code that I've already asked about, as well as the fact that when I get around that bug by doing a location.replace with the URL to PayPal (or loading it in a lightbox of my own design), iOS and mobile Safari kill the "Log In" popup (without giving the user an opportunity to view it if they so choose).
In short, is there any way I can use Adaptive Payments without ridiculous 1990s-era popups???

Here's what I'm doing to use PayPal's mobile web flow. I'm testing on Android and it's working well. The only hang up is the callbackFunction is not firing in mobile browsers and works fine in desktop browsers. (I'm still working on this part. Let me know if you solve it.) Here's an example on how to do it using expType=mini to launch the PayPal mini browser experience.
First include the Javascript for the Mini flow:
<script src="http://www.paypalobjects.com/js/external/apdg.js"></script>
Then a link to launch the redirect:
<a id="payPalRedirect" href="https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/pay?paykey={paykey}&expType=mini" target="_blank">Complete PayPal Payment</a>
<br /><br />
<div id="resultDiv"></div>
And some Javascript to initiate the Mini Flow process and the callbackFunction:
var returnFromPayPal = function () {
alert("Returned from PayPal");
var div = document.getElementById('resultDiv');
div.innerHTML = "Returned from PayPal!";
// Here you would need to pass on the payKey to your server side handle to call the PaymentDetails API to make sure Payment has been successful or not
// based on the payment status- redirect to your success or cancel/failed urls
}
var dgFlowMini = new PAYPAL.apps.DGFlowMini({ trigger: 'payPalRedirect', expType: 'mini', callbackFunction: 'returnFromPayPal' });
More insights and solution options to this issue can be found here:
Paypal Embedded Flow not using returnUrl or cancelUrl

Related

Codenameone browser issues with paypal checkout express

So I've been trying to find an API to integrate PayPal Payment into my Codename One App, except that I didn't find enough documentation to use the Purchase builtin feature. So I tried to use a WebView of a page hosted on my server and implemented using the paypal "checkout.js" Api.
When I load the page into Chrome, it works perfectly and the transaction is complete. But when I load it using the codename one BrowserComponent it gets stuck (See screenshot). What is the root of this problem ? Is it the fact that the browser does not support popus ? and Is there a way to fix it ?
Button payButton = new Button("Checkout");
payButton.addActionListener((ActionEvent evt) -> {
Form payForm = new Form("Payment", new BorderLayout());
WebBrowser webBrowser = new WebBrowser("http://localhost/paymentserver/web/app_dev.php/payerParticipation/5");
payForm.add(BorderLayout.CENTER, webBrowser);
payForm.show();
});
Screenshot
Try embedding firebug into the of your page to see if it reports any errors:
<script>
if (!document.getElementById('FirebugLite')){E = document['createElement' + 'NS'] && document.documentElement.namespaceURI;E = E ? document'createElement' + 'NS' : document'createElement';E'setAttribute';E'setAttribute';E'setAttribute';(document'getElementsByTagName'[0] || document'getElementsByTagName'[0]).appendChild(E);E = new Image;E'setAttribute';}
</script>
Thanks for the help everybody,
I finally found a turnaround and implemented this feature on a PHP server using PayPal PHP SDK. I used the browser Navigation Callback in order to check when the payment was successful/failed.
browser.setNavigationCallback((url)->{
if (url.indexOf("success=true")!=-1){
System.out.println("Payment complete");
}
else if (url.indexOf("success=false")!=-1){
System.out.println("Payment failed");
}
return true;
});
I don't have an answer for that but I did implement Braintree support for Codename One which is the official PayPal mobile API. I have a cn1lib for it implemented but I didn't get around to publishing it because of the bootcamp. Keep an eye on the blog I'll probably publish it in the next couple of weeks.

Go back to Ionic application after payment success from Paypal

I have created an Ionic app. I have some items to order. Payment is done using Paypal. I have called a web url using window.open(url) which is redirecting me to the Paypal.
I'm able to do the payment successfully, but Can anyone please let me know how I can come back to my ionic app after successful payment.
Note: I have not used Paypal plugin as it is not developed for windows
Few days back even i was facing the same issue, i was able to do payment where the ionic app drags to the third party api but after the payment it was not redirecting to the ionic app in the mobile/smartphone.
after soing dome R and D i got the solution that when the app is running on the mobile it will not be having any port number running on i,e., http://localhost/dashboard instead of http:localhost:8100/dashboard, where 8100 is the port number running for the ionic server.
after specifying the return back url as http://localhost/dashboard i was able to redirect back to the ionic app.
Use loadsart event of the InAppBrowser to catch the urls when load pages after payment was done. Then you can process your tasks according to those urls and their parameters as you prefer. As an example, when you have the payment successful url you can navigate back to your app after closing the open browser. Also you can have the data passing back when the payment is success or fail, into your application using this way. Hope this will help to you.
addEventListener('loadstart', function(event) { var currentUrl = event.url /*do the rest according to the url inside your application */});
I just add a pseudo-code below.
browserRef.addEventListener('loadstart', function(event) {
var param = getParameters(event.url); //Read the parameters from the url
if (isCorrectParameters(param)) { //Check parameters agaist the payment gateway response url
browserRef.close(); // colse the browser
//Handle the success and failed scenarios
if(success){
$state.go('test');
}else{
// handle fail scenario
}
}
});

PayPal Web Payments Pro Hosted - Credit Card payment confirmation page

I've implemented Website Payments Pro Hosted on my website. I can pay using the PayPal log in and it gives me the link to return to my store which is fine as I then display my order confirmation page to the user.
When the user decides to pay via credit card:
They are then redirected to a confirmation page I don't seem to have any control over:
What I've tried:
Setting auto return on in my preferences and setting a return url (both via the Profile and in my initial API call when generating the button.
Changing the Web Payments Pro confirmation page setting to On my sites confirmation page.
When the payment is taken via credit card, I'd like to redirect the user to my actual payment confirmation page. Is this possible?
It turns out that showHostedThankyouPage=true was causing this issue.
I am using the .NET button API to generate the request for the iFrame like so:
var service = new PayPalAPIInterfaceServiceService(GetConfig(request));
var createButtonResponse = service.BMCreateButton(new BMCreateButtonReq
{
BMCreateButtonRequest = new BMCreateButtonRequestType
{
ButtonType = ButtonTypeType.PAYMENT,
ButtonCode = ButtonCodeType.TOKEN,
ButtonCountry = countryCodeType,
ButtonVar = new List<string>
{
String.Format("subtotal={0}", _salesOrderPriceService.GetGrossTotal(request.Order)),
String.Format("notify_url={0}", request.NotifyUrl),
String.Format("return={0}", request.ReturnUrl),
String.Format("invoice={0}", request.Order.Id),
String.Format("currency_code={0}", request.Order.Currency.Code),
String.Format("cancel_return={0}", request.CancelReturnUrl),
"billing_first_name=test",
"billing_last_name=tset",
"billing_address1=test",
"billing_city=test",
"billing_state=tes",
"billing_zip=test",
"billing_country=GB",
"template=templateD",
"paymentaction=sale",
"business=tset"
}
}
});
I had showHostedThankyouPage=true included in the name value pairs which was causing the issue. Removing it sorted it out.

PayPal Adaptive Payments: two payments from one sender in two browser tabs

I use PayPal Adaptive Payments (parallel) on my website and I've encountered a strange problem with two payments in two different browser tabs from the same sender. The similar question was asked before, but nobody answered there.
The scenario which reproduces the problem
The user opens the first browser tab of the website and starts a payment process to the first seller.
PayPal's lightbox with Login button appears.
The user opens the second browser tab of the website and starts a payment process to the second seller.
Again, PyaPal's lightbox with Login button appears.
The user returns to the first browser tab and login to PayPal.
After login to PayPal in the first browser tab the user sees payment details to the second seller.
After login to PayPal in the second browser tab the user sees payment details to the second seller.
It seems that PayPal Adaptive Payments support only one transaction from one sender.
How it works
The website works with Ruby on Rails and I use paypal_adaptive gem for payments with PayPal. The payment flow is quite simple:
The user clicks on Buy button on the website. The client makes AJAX request which handled by payment controller in Ruby on Rails.
In the controller the app makes Pay request to PayPal API using paypal_adaptive gem and receives a PayKey (see the code below).
The server responds to the client with the PayKey and the client uses it in PayPal form to start payment process through PayPal's lightbox (see the code below).
That's it. After that I do not control anything (the payment process goes through PayPal's external webpage).
Additional notes
I'm sure that the data for Pay request is different on the server side in the test scenario listed above.
I've tried different PayPal's dialog options besides PayPal's lightbox: mini-browser and popup. These options doesn't affect on this bug and it is still reproducable.
The client code
<script src="https://www.paypalobjects.com/js/external/dg.js" type="text/javascript"></script>
<form action="https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/pay" class="paypal-hidden-form" target="PPDGFrame">
<button id="paypal-submit"></button>
<input id="type" type="hidden" name="expType" value="light">
<!-- Insert PayKey here and click on the form's submit button using jQuery after server's response. -->
<input id="paypal-key" type="hidden" name="paykey" value="">
</form>
<!-- Paypal -->
<script type="text/javascript" charset="utf-8">
var dgFlow = new PAYPAL.apps.DGFlow({ trigger: "paypal-submit", expType: "light" });
function MyEmbeddedFlow(embeddedFlow) {
this.embeddedPPObj = embeddedFlow;
this.paymentSuccess = function(paymentStatus) {
this.embeddedPPObj.closeFlow();
// More UI code here...
};
this.paymentCanceled = function() {
this.embeddedPPObj.closeFlow();
// More UI code here...
};
}
var myEmbeddedPaymentFlow = new MyEmbeddedFlow(dgFlow);
</script>
The server code
# Make a Pay request to PayPal API.
paypal_payment_thread = Thread.new do
# Some preparation code goes here...
pay_request = PaypalAdaptive::Request.new
process_guid = SecureRandom.uuid
# Construct Pay API request data.
data = {
:returnUrl => "#{PAYPAL_RETURN_URL}?process_guid=#{process_guid}",
:cancelUrl => "#{PAYPAL_CANCEL_URL}?process_guid=#{process_guid}",
:requestEnvelope => {
:errorLanguage => "en_US"
},
:currencyCode => "USD",
:receiverList => {
:receiver => [{
# seller_paypal value is different for two payments.
# But in fact we do the last payment for both payments.
:email => seller_paypal,
:amount => ORDER_SELLER_AMOUNT,
:paymentType => "DIGITALGOODS"
}, {
:email => PAYPAL_MARKETPLACE_EMAIL,
:amount => ORDER_MARKETPLACE_AMOUNT,
:paymentType => "DIGITALGOODS"
}]
},
:actionType => "PAY",
:ipnNotificationUrl => PAYPAL_NOTIFY_URL,
:reverseAllParallelPaymentsOnError => "true",
:trackingId => process_guid
}
# Make a Pay API request.
pay_response = pay_request.pay(data)
if pay_response.success?
# Everything is ok. Update database here...
else
raise Exceptions::PaypalPaymentError
end
end
I've removed some unimportant code just to be clear, how it really works.
Thanks in advance for the help!
Looks like it is by design. I've tried the same test here on the website of one of PayPal's employees and it is reproducible there.
PayPal's support answered me that the problem in using Lightbox. However I've tried Mini-Browser and Popup options as I described in my post without no effect.
Also, PayPal's support answered me that this is by design and adviced me to contact with Technical Support. Maybe it will be useful for someone else.
Hi Michael, Thanks, yes I was able to reproduce it as well. However
it’s important to understand that PayPal is not made for handling 2
payment flows at the same time. If you want to get further on that,
you can contact our Technical Support : https://ppmts.custhelp.com/
They have other tools to debug and may be able to give you a better
understanding of the technical problem.
Finally I've blocked simultaneous payments using a special flag in HTML5 Local Storage and dgFlow.isOpen() method of PAYPAL.apps.DGFlow object to detect PayPal window. On window close I reset this flag using onunload and onbeforeunload events of window.
I close this question. Thanks.

Paypal Adaptive payment for mobile web

Im integrating Paypal Adaptive Payment API for a mobile website.
But when Im submitting payment to
https://www.paypal.com/webscr?cmd=_ap-payment&paykey=value
( For Sandbox : https://www.sandbox.paypal.com/cgi-bin/webscr )
Its always redirecting to Paypal Main Web. Not to Paypal Mobile website.
How to redirect client to paypal mobile web?
Try redirecting your site to
https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/pay?paykey=AP-XYZ&expType=mini
Fill your pay key in place of AP-XYZ
Let me know if it works.
The best approach I found was mini browser experience. But I had a variety of different issues on mobile devices implementing it (which is what it was meant for in the first place). You will see many similar questions about adaptive payments and all sorts of issues with using lightbox and mini browser experience.
But FINALLY... I have figured it out after hours upon hours, days upon days! This should solve everyone's problems of all different varieties when it comes to issues with PayPal Adaptive Payments and the issues with:
The default redirected paypal page is NOT mobile responsive and looks horrible on mobile devices.
The lightbox gets "hung up" and does not close on some mobile devices.
The mini browser doesn't close after completing payment or cancelling.
The mini browser doesn't redirect to the callBackFunction from paypal apdg.js script.
Not redirecting to returnUrl and cancelUrl after payment completion (or when cancelling)
Chrome for ios (iphones) doesn't initiate the callbackfunction and therefore after payment completion or cancellation, it just keeps you at the page you launched the paypal payment page from which prevents you from validating success or failure of payment.
Drum roll please.... here it is!! This replaces any need for PayPal javascript files etc. All you need is what is below along with your own method of obtaining the PayKey to add to the redirect url. My live website, with adaptive payments working correctly using below code, is https://www.trackabill.com.
<div>
<?php $payUrl = 'https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=mini&paykey=' . $payKey ?>
<button onclick="loadPayPalPage('<?php echo $payUrl; ?>')" title="Pay online with PayPal">PayPal</button>
</div>
<script>
function loadPayPalPage(paypalURL)
{
var ua = navigator.userAgent;
var pollingInterval = 0;
var win;
// mobile device
if (ua.match(/iPhone|iPod|Android|Blackberry.*WebKit/i)) {
//VERY IMPORTANT - You must use '_blank' and NOT name the window if you want it to work with chrome ios on iphone
//See this bug report from google explaining the issue: https://code.google.com/p/chromium/issues/detail?id=136610
win = window.open(paypalURL,'_blank');
pollingInterval = setInterval(function() {
if (win && win.closed) {
clearInterval(pollingInterval);
returnFromPayPal();
}
} , 1000);
}
else
{
//Desktop device
var width = 400,
height = 550,
left,
top;
if (window.outerWidth) {
left = Math.round((window.outerWidth - width) / 2) + window.screenX;
top = Math.round((window.outerHeight - height) / 2) + window.screenY;
} else if (window.screen.width) {
left = Math.round((window.screen.width - width) / 2);
top = Math.round((window.screen.height - height) / 2);
}
//VERY IMPORTANT - You must use '_blank' and NOT name the window if you want it to work with chrome ios on iphone
//See this bug report from google explaining the issue: https://code.google.com/p/chromium/issues/detail?id=136610
win = window.open(paypalURL,'_blank','top=' + top + ', left=' + left + ', width=' + width + ', height=' + height + ', location=0, status=0, toolbar=0, menubar=0, resizable=0, scrollbars=1');
pollingInterval = setInterval(function() {
if (win && win.closed) {
clearInterval(pollingInterval);
returnFromPayPal();
}
} , 1000);
}
}
var returnFromPayPal = function()
{
location.replace("www.yourdomain.com/paypalStatusCheck.php");
// Here you would need to pass on the payKey to your server side handle (use session variable) to call the PaymentDetails API to make sure Payment has been successful
// based on the payment status- redirect to your success or cancel/failed page
}
</script>
There is actually a simple solution to this that isn't documented anywhere. We were in discussion with PayPal about adding it a while back so I am wondering if it eventually got implemented.
Anyway, simply just redirect the user to the following URL and they will be redirected back to your site on completion:
https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/preapproval?preapprovalKey=PA-XXXXX&expType=redirect
The difference here is using expType=redirect rather that expType=mini. I'm not sure when this was added but after a bit of reverse engineering and some experimenting we have a surprisingly simple solution.
that's right - the Adaptive Payments UI is not Mobile optimized. But the closest to that it offers is what we call the MiniBrowser experience. You can try and see if that serves your needs. You can find the how-to guide here on X.com: Implementing the Mini-Browser Option