<!DOCTYPE html>
<html>
<head>
<title>Angular.JS BrainTree Drop In Integration Sample</title>
<script data-require="angular.js@1.4.3" data-semver="1.4.7" src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script data-require="ui-router@*" data-semver="0.2.15" src="//rawgit.com/angular-ui/ui-router/0.2.15/release/angular-ui-router.js"></script>
<script src="//rawgit.com/ocombe/ocLazyLoad/1.0.8/dist/ocLazyLoad.min.js"></script>
<script data-require="angular-ui-bootstrap@0.14.3" data-semver="0.14.3" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.3.js"></script>
<link data-require="bootstrap-css@3.3.1" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
</head>
<body ng-app="braintreeApp" ng-strict-di="">
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" ui-sref="home">Angular Braintree Example</a>
</div>
</nav>
<div class="container">
<div ui-view></div>
</div>
<div class="text-center">
<p>A tutorial by <a href="http://sysgears.com" target="_blank">SysGears</a></p>
<p>View the tutorial: <a href="http://sysgears.com/articles/braintree-and-angular-js-drop-in-integration/" target="_blank">Angular.JS Braintree Integration</a></p>
</div>
<script type="text/ng-template" id="home.html">
<div class="jumbotron text-center">
<h1>Home Page</h1>
<p>This page demonstrates drop-in Angular.JS integration with Braintree</p>
<a href="javascript:void(0);" ng-click="ctrl.openModal()" class="btn btn-primary">Open Payment Modal</a>
</div>
</script>
<script type="text/ng-template" id="modal.html">
<form name="paymentForm" novalidate role="form">
<div class="modal-header">
<h3 class="modal-title">Payment Modal Demo</h3>
</div>
<div class="modal-body">
<input type="number" name="quantity" placeholder="Enter any quantity" ng-model="ctrl.quantity" required></input>
<div id="payment-form"></div>
<hr/>
<span>{{ctrl.serverError}}</span>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="submit" ng-disabled="ctrl.disablePay">Submit</button>
<button class="btn btn-warning" type="button" ng-click="ctrl.cancel()">Cancel</button>
</div>
</form>
</script>
<script>
var braintreeApp = angular.module('braintreeApp', ['ui.router', 'ui.bootstrap', 'oc.lazyLoad']);
braintreeApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html',
controller: 'HomeCtrl as ctrl'
});
}]);
braintreeApp.controller('ModalCtrl', ['$uibModalInstance', '$log', '$scope', '$q', '$timeout', 'token', function ($uibModalInstance, $log, $scope, $q, $timeout, token) {
var vm = this;
vm.disablePay = true;
braintree.setup(token, 'dropin', {
container: 'payment-form',
onPaymentMethodReceived: (data) => vm.submit($scope.paymentForm, data.nonce),
onReady: () => {
$timeout(() => {
vm.disablePay = false;
}, 0);
},
onError: (type, message) => {
$timeout(() => {
vm.serverError = message;
}, 0);
}
});
// Send to server nonce and custom data to execute payment
vm.executePayment = function(nonce, quantity) {
$log.debug('Send request to your server to execute payment');
return $q.when('');
}
vm.submit = function(form, nonce) {
if (form.$valid) {
vm.executePayment(nonce, parseInt(quantity, 10)).then((result) => {
delete vm.serverError;
}, (error) => {
form.$setPristine();
vm.serverError = error;
});
}
}
vm.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}]);
braintreeApp.controller('HomeCtrl', ['$uibModal', '$ocLazyLoad', '$log', function ($uibModal, $ocLazyLoad, $log) {
var vm = this;
// Get token from server
vm.generateToken = function() {
$log.debug('Send request to your server to generate new braintree token and return response');
return '{"userToken":"eyJ2ZXJzaW9uIjoyLCJhdXRob3JpemF0aW9uRmluZ2VycHJpbnQiOiJmMzVhNjQ4Nzk3ZWNlMzkxZjhmMDA2MWE0MTRjNzBjYzNiNGYyNDhjNWI4NmYxNTA1OGNiNGRlNGZkMzc1YTM2fGNyZWF0ZWRfYXQ9MjAxNS0xMS0yMFQxNTo0OToyNS4wNDcwNjIwNDcrMDAwMFx1MDAyNmN1c3RvbWVyX2lkPTEyMDY3MzMxXHUwMDI2bWVyY2hhbnRfaWQ9cHpuYjJyd2NjZ2c0cnZiclx1MDAyNnB1YmxpY19rZXk9amNqeHBrcTdrc3ZzcHdxciIsImNvbmZpZ1VybCI6Imh0dHBzOi8vYXBpLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb206NDQzL21lcmNoYW50cy9wem5iMnJ3Y2NnZzRydmJyL2NsaWVudF9hcGkvdjEvY29uZmlndXJhdGlvbiIsImNoYWxsZW5nZXMiOltdLCJlbnZpcm9ubWVudCI6InNhbmRib3giLCJjbGllbnRBcGlVcmwiOiJodHRwczovL2FwaS5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tOjQ0My9tZXJjaGFudHMvcHpuYjJyd2NjZ2c0cnZici9jbGllbnRfYXBpIiwiYXNzZXRzVXJsIjoiaHR0cHM6Ly9hc3NldHMuYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhdXRoVXJsIjoiaHR0cHM6Ly9hdXRoLnZlbm1vLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhbmFseXRpY3MiOnsidXJsIjoiaHR0cHM6Ly9jbGllbnQtYW5hbHl0aWNzLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb20ifSwidGhyZWVEU2VjdXJlRW5hYmxlZCI6dHJ1ZSwidGhyZWVEU2VjdXJlIjp7Imxvb2t1cFVybCI6Imh0dHBzOi8vYXBpLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb206NDQzL21lcmNoYW50cy9wem5iMnJ3Y2NnZzRydmJyL3RocmVlX2Rfc2VjdXJlL2xvb2t1cCJ9LCJwYXlwYWxFbmFibGVkIjp0cnVlLCJwYXlwYWwiOnsiZGlzcGxheU5hbWUiOiJDb3JDb20gVGVjaG5vbG9naWVzIiwiY2xpZW50SWQiOm51bGwsInByaXZhY3lVcmwiOiJodHRwOi8vZXhhbXBsZS5jb20vcHAiLCJ1c2VyQWdyZWVtZW50VXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL3RvcyIsImJhc2VVcmwiOiJodHRwczovL2Fzc2V0cy5icmFpbnRyZWVnYXRld2F5LmNvbSIsImFzc2V0c1VybCI6Imh0dHBzOi8vY2hlY2tvdXQucGF5cGFsLmNvbSIsImRpcmVjdEJhc2VVcmwiOm51bGwsImFsbG93SHR0cCI6dHJ1ZSwiZW52aXJvbm1lbnROb05ldHdvcmsiOnRydWUsImVudmlyb25tZW50Ijoib2ZmbGluZSIsInVudmV0dGVkTWVyY2hhbnQiOmZhbHNlLCJicmFpbnRyZWVDbGllbnRJZCI6Im1hc3RlcmNsaWVudDMiLCJiaWxsaW5nQWdyZWVtZW50c0VuYWJsZWQiOmZhbHNlLCJtZXJjaGFudEFjY291bnRJZCI6InY2aG1jZmtucjQ0a3FmcWoiLCJjdXJyZW5jeUlzb0NvZGUiOiJVU0QifSwiY29pbmJhc2VFbmFibGVkIjpmYWxzZSwibWVyY2hhbnRJZCI6InB6bmIycndjY2dnNHJ2YnIiLCJ2ZW5tbyI6Im9mZiJ9","success":true}';
}
vm.openModal = function () {
var modal = $uibModal.open({
templateUrl: 'modal.html',
controller: 'ModalCtrl as ctrl',
resolve: {
braintree: () => $ocLazyLoad.load('https://js.braintreegateway.com/v2/braintree.js'),
token: () => vm.generateToken()
},
});
};
}]);
</script>
</body>
</html>