{"id":3699,"date":"2017-10-17T11:29:17","date_gmt":"2017-10-17T11:29:17","guid":{"rendered":"http:\/\/www.nikola-breznjak.com\/blog\/?p=3699"},"modified":"2017-10-17T11:34:25","modified_gmt":"2017-10-17T11:34:25","slug":"add-paypal-ionic-1-apps","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/javascript\/ionic\/add-paypal-ionic-1-apps\/","title":{"rendered":"How to add PayPal to Ionic 1 apps"},"content":{"rendered":"<h2>TL;DR<\/h2>\n<p>In this tutorial, I&#8217;m going to show you how to add the option of paying with PayPal to your Ionic 1 apps.<\/p>\n<p>The demo project is <a href=\"https:\/\/github.com\/Hitman666\/IonicPayPalDemo\">on Github<\/a>.<\/p>\n<h2>How to create this yourself step by step<\/h2>\n<ul>\n<li>Start a new Ionic 1 project<\/li>\n<\/ul>\n<p><code>ionic start IonicPayPalDemo<\/code><\/p>\n<ul>\n<li>Add the <a href=\"https:\/\/github.com\/paypal\/PayPal-Cordova-Plugin\">PayPal Cordova Plugin<\/a><\/li>\n<\/ul>\n<p><code>cordova plugin add com.paypal.cordova.mobilesdk<\/code><\/p>\n<p>As the official docs say:<\/p>\n<blockquote><p>\n  The PayPal SDK Cordova\/Phonegap Plugin adds 2 JavaScript files to your project:<\/p>\n<ul>\n<li><code>cdv-plugin-paypal-mobile-sdk.js<\/code> &#8211; a wrapper around the native SDK. The PayPalMobile object is immediately available to use in your .js files. You <strong>don&#8217;t<\/strong> need to reference it in <code>index.html<\/code><\/li>\n<li><code>paypal-mobile-js-helper.js<\/code> &#8211; a helper file which defines the <code>PayPalPayment<\/code>, <code>PayPalPaymentDetails<\/code> and <code>PayPalConfiguration<\/code> classes for use with PayPalMobile<\/li>\n<\/ul>\n<p>  You must add <code>&lt;script type=\"text\/javascript\" src=\"js\/paypal-mobile-js-helper.js\"&gt;&lt;\/script&gt;<\/code> to your <code>www\/index.html<\/code> file, after the <code>cordova.js<\/code> import.\n<\/p><\/blockquote>\n<p>So, following the official advice, our <code>www\/index.html<\/code> file will now look like this:<\/p>\n<pre><code>&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;meta charset=\"utf-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width\"&gt;\n    &lt;title&gt;&lt;\/title&gt;\n\n    &lt;link rel=\"manifest\" href=\"manifest.json\"&gt;\n    &lt;link href=\"lib\/ionic\/css\/ionic.css\" rel=\"stylesheet\"&gt;\n    &lt;link href=\"css\/style.css\" rel=\"stylesheet\"&gt;\n\n    &lt;script src=\"lib\/ionic\/js\/ionic.bundle.js\"&gt;&lt;\/script&gt;\n    &lt;script src=\"cordova.js\"&gt;&lt;\/script&gt;\n    &lt;script type=\"text\/javascript\" src=\"js\/paypal-mobile-js-helper.js\"&gt;&lt;\/script&gt;\n\n    &lt;script src=\"js\/app.js\"&gt;&lt;\/script&gt;\n    &lt;script src=\"js\/controllers.js\"&gt;&lt;\/script&gt;\n    &lt;script src=\"js\/services.js\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n\n&lt;body ng-app=\"starter\"&gt;\n    &lt;ion-nav-bar class=\"bar-stable\"&gt;\n        &lt;ion-nav-back-button&gt;\n        &lt;\/ion-nav-back-button&gt;\n    &lt;\/ion-nav-bar&gt;\n    &lt;ion-nav-view&gt;&lt;\/ion-nav-view&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n<p>Next, set the contents of the <code>www\/templates\/tab-dash.html<\/code> to:<\/p>\n<pre><code>&lt;ion-view view-title=\"Dashboard\"&gt;\n    &lt;ion-content class=\"padding\"&gt;\n        &lt;div class=\"list\"&gt;\n            &lt;label class=\"item item-input\"&gt;\n                Price: \u00a0&lt;input type=\"text\" ng-model=\"subscriptionPrice\"\/&gt;\n            &lt;\/label&gt;\n            &lt;label class=\"item item-input\"&gt;\n                Subscription: \u00a0&lt;input type=\"text\" ng-model=\"subscriptionName\"\/&gt;\n            &lt;\/label&gt;\n        &lt;\/div&gt;\n\n        &lt;button class=\"button button-positive button-block\" ng-click=\"payWithPayPal()\"&gt;\n            &lt;i class=\"icon ion-card\"&gt;&lt;\/i&gt;\n            Pay with PayPal\n        &lt;\/button&gt;\n    &lt;\/ion-content&gt;\n&lt;\/ion-view&gt;\n<\/code><\/pre>\n<p>Set the contents <code>DashCtrl<\/code> controller in the <code>www\/js\/controllers.js<\/code> file to:<\/p>\n<pre><code>.controller('DashCtrl', function($scope, PaypalFactory) {\n    $scope.subscriptionName = 'Some subscription';\n    $scope.subscriptionPrice = 5;\n\n    $scope.payWithPayPal = function() {\n        PaypalFactory.initPaymentUI().then(function() {\n            PaypalFactory.makePayment($scope.subscriptionPrice, $scope.subscriptionName).then(function(data) {\n                console.dir(data);\n\n                \/\/make some additional logic based on returned data like saving to your database, showing a message to the user, etc.\n                navigator.notification.alert(\n                    \"PayPal purchase completed successfully.\",\n                    null,\n                    \"Paypal Purchase\",\n                    \"OK\"\n                );\n            }, function(err) {\n                console.dir(err);\n                navigator.notification.alert(\n                    err,\n                    null,\n                    \"Paypal Purchase Canceled\",\n                    \"Try Again\"\n                );\n            });\n        });\n    };\n})\n<\/code><\/pre>\n<p>You can see that we&#8217;re importing the PaypalFactory through dependency injection. We define this factory in <code>js\/services.js<\/code> file like this:<\/p>\n<pre><code>.factory('PaypalFactory', ['$q', '$filter', '$timeout', '$ionicPlatform', 'APP_CONSTS', function($q, $filter, $timeout, $ionicPlatform, APP_CONSTS) {\n        var init_defer;\n\n        var that = {};\n\n        \/**\n        * @ngdoc method\n        * @name initPaymentUI\n        * @methodOf app.PaypalFactory\n        * @description\n        * Inits the payapl ui with certain envs.\n        * \n        * @returns {object} Promise paypal ui init done\n        *\/\n        that.initPaymentUI = function() {\n            init_defer = $q.defer();\n            $ionicPlatform.ready().then(function() {\n\n                var clientIDs = {\n                    \"PayPalEnvironmentProduction\": APP_CONSTS.payPalProductionId,\n                    \"PayPalEnvironmentSandbox\": APP_CONSTS.payPalSandboxId\n                };\n                PayPalMobile.init(clientIDs, that.onPayPalMobileInit);\n            });\n\n            return init_defer.promise;\n        }\n\n        \/**\n        * @ngdoc method\n        * @name createPayment\n        * @methodOf app.PaypalFactory\n        * @param {string|number} total total sum. Pattern 12.23\n        * @param {string} name name of the item in paypal\n        * @description\n        * Creates a paypal payment object \n        *\n        * @returns {object} PayPalPaymentObject\n        *\/\n        var createPayment = function(total, name) {\n            \/\/ \"Sale  == &gt;  immediate payment\n            \/\/ \"Auth\" for payment authorization only, to be captured separately at a later time.\n            \/\/ \"Order\" for taking an order, with authorization and capture to be done separately at a later time.\n            var payment = new PayPalPayment(\"\" + total, \"USD\", \"\" + name, \"Sale\");\n            return payment;\n        }\n\n        \/**\n        * @ngdoc method\n        * @name configuration\n        * @methodOf app.PaypalFactory\n        * @description\n        * Helper to create a paypal configuration object\n        *\n        * \n        * @returns {object} PayPal configuration\n        *\/\n        var configuration = function() {\n            \/\/ for more options see `paypal-mobile-js-helper.js`\n            var config = new PayPalConfiguration({ merchantName: APP_CONSTS.payPalShopName, merchantPrivacyPolicyURL: APP_CONSTS.payPalMerchantPrivacyPolicyURL, merchantUserAgreementURL: APP_CONSTS.payPalMerchantUserAgreementURL });\n            return config;\n        }\n\n        that.onPayPalMobileInit = function() {\n            $ionicPlatform.ready().then(function() {\n                PayPalMobile.prepareToRender(APP_CONSTS.payPalEnv, configuration(), function() {\n                    $timeout(function() {\n                        init_defer.resolve();\n                    });\n                });\n            });\n        }\n\n        \/**\n        * @ngdoc method\n        * @name makePayment\n        * @methodOf app.PaypalFactory\n        * @param {string|number} total total sum. Pattern 12.23\n        * @param {string} name name of the item in paypal\n        * @description\n        * Performs a paypal single payment \n        *\n        * \n        * @returns {object} Promise gets resolved on successful payment, rejected on error \n        *\/\n        that.makePayment = function(total, name) {\n            var defer = $q.defer();\n            total = $filter('number')(total, 2);\n            $ionicPlatform.ready().then(function() {\n                PayPalMobile.renderSinglePaymentUI(createPayment(total, name), function(result) {\n                    $timeout(function() {\n                        defer.resolve(result);\n                    });\n                }, function(error) {\n                    $timeout(function() {\n                        defer.reject(error);\n                    });\n                });\n            });\n\n            return defer.promise;\n        }\n\n        \/**\n        * @ngdoc method\n        * @name makeFuturePayment\n        * @methodOf app.PaypalFactory\n        * @description\n        * Performs a paypal future payment \n        * \n        * @returns {object} Promise gets resolved on successful payment, rejected on error \n        *\/\n        that.makeFuturePayment = function(total, name) {\n            var defer = $q.defer();\n            $ionicPlatform.ready().then(function() {\n                PayPalMobile.renderFuturePaymentUI(\n                    function(authorization) {\n                        defer.resolve(authorization);\n                    },\n                    function(cancelReason) {\n                        defer.reject(cancelReason);\n                    });\n            });\n\n            return defer.promise;\n        }\n\n        return that;\n    }])\n<\/code><\/pre>\n<p>Also, you may notice that here we&#8217;re importing <code>APP_CONSTS<\/code> constant which we have to define in <code>app.js<\/code> file like this:<\/p>\n<pre><code>.constant('APP_CONSTS', {\n    payPalSandboxId: 'Bfiudw1_kauwqxV8vqsPXyWv-6rbudyhnwbKd2Qhb57Rdwoj0NLT8dOGwOYug5g-vHL28aqVWLMkErdVop',\n    payPalProductionId: '',\n    payPalEnv: 'PayPalEnvironmentSandbox', \/\/ for testing: PayPalEnvironmentSandbox, for production PayPalEnvironmentProduction\n    payPalShopName: 'Demo Shop',\n    payPalMerchantPrivacyPolicyURL: 'https:\/\/www.demoshop.com\/privacy',\n    payPalMerchantUserAgreementURL: 'https:\/\/www.demoshop.com\/terms'\n  })\n<\/code><\/pre>\n<p>Of course, <strong>these won&#8217;t work<\/strong> and for the demo to work you need to change them to your settings. You can get these by registering your application over at <a href=\"developer.paypal.com\/\">PayPal Developers<\/a> portal.<\/p>\n<h2>Running the application<\/h2>\n<p>When you run the application you should see a screen like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/jCfPzhzl.png\" alt=\"\" \/><\/p>\n<p>Then, if you click on the <code>Pay with PayPal<\/code> button you&#8217;ll get a nice looking interface:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/KNlSgoNl.png\" alt=\"\" \/><\/p>\n<p>Cool thing is that it also supports the option to take a picture of your credit card and automatically fill the fields (in case you would pay with a credit card):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i.imgur.com\/UEKbrU7l.png\" alt=\"\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>Hope this demo app helps to show you how easy it is to add PayPal payments to your Ionic 1 app.<\/p>\n<p>The demo only showcases the usage of a one-time payment. The so-called future payment UI is ready, but to get this fully working, you will need to implement proper functions on the backend as well. You can read more about this <a href=\"https:\/\/developer.paypal.com\/docs\/integration\/mobile\/make-future-payment\/\">here<\/a>.<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\">How to add PayPal to Ionic 1 apps <a href=\"https:\/\/twitter.com\/Ionicframework?ref_src=twsrc%5Etfw\">@ionicframework<\/a> <a href=\"https:\/\/t.co\/nwLE2vUxAu\">https:\/\/t.co\/nwLE2vUxAu<\/a><\/p>\n<p>&mdash; Nikola Bre\u017enjak (@HitmanHR) <a href=\"https:\/\/twitter.com\/HitmanHR\/status\/920251518640623617?ref_src=twsrc%5Etfw\">October 17, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR In this tutorial, I&#8217;m going to show you how to add the option of paying with PayPal to your Ionic 1 apps. The demo project is on&hellip;<\/p>\n","protected":false},"author":1,"featured_media":3700,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43],"tags":[],"class_list":["post-3699","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ionic"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3699","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/comments?post=3699"}],"version-history":[{"count":4,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3699\/revisions"}],"predecessor-version":[{"id":3704,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3699\/revisions\/3704"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/3700"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=3699"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=3699"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=3699"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}