I have created a custom AngularJS form with Stripe integration using a directive. You can view the Fiddle for this project here: https://jsfiddle.net/u5h1uece/.
HTML:
<body ng-app="angularjs-starter">
<script src="https://js.stripe.com/v3/"></script>
<div ng-controller="MainCtrl">
<form name="regForm" id="register-form">
<label>Email</label>
<input ng-model="reg.email" type="email" name="username">
<div stripe-validator
stripe-complete="stripeCompleted"
stripe-form-id="register-form"></div>
<br>
<button ng-model="reg.btn" ng-disabled="stripeCompleted === false || !regForm.username.$valid">Register</button>
</form>
</div>
</body>
JS:
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope, $rootScope) {
//Initialize stripe state within the controller
$scope.stripeCompleted = false;
});
app.directive('stripeValidator', function() {
return {
restrict: 'A',
template: `
<div id="stripe-wrapper">
<div id="card-element"></div>
</div>
<small id="card-errors" class="text-danger" role="alert">{{ ccErrMsg }}</small>
<input type="hidden" name="stripeToken" ng-value="stripeToken" />`,
scope: {
"stripeComplete": '=',
"stripeFormId": '@',
"stripeError": '=',
"stripeToken": '=',
},
link: function(scope, element, attrs) {
//Initialization
var stripe = Stripe("pk_test_6pRNASCoBOKtIshFeQd4XMUh");
var elements = stripe.elements();
var card = elements.create("card");
var form = document.getElementById(scope.stripeFormId);
//Mount the card element https://stripe.com/docs/stripe-js/reference#element-mount
card.mount("#card-element");
//Add event listener
card.addEventListener('change', function(event) {
//Check for errors
if (event.error) {
scope.ccErrMsg = event.error.message;
} else {
scope.ccErrMsg = '';
}
//Check for completion
scope.stripeComplete = event.complete ? true : false;
//Apply scope
scope.$apply();
});
//Inject form submit event
form.addEventListener("submit", function(event) {
//Prevent default form submission
event.preventDefault();
//Handle token creation, error handling, and form submission forwarding
stripe.createToken(card).then(function(result) {
if (result.error) {
scope.ccErrMsg = event.error.message;
scope.stripeToken = '';
} else {
scope.ccErrMsg = '';
scope.stripeToken = result.token;
}
//Apply scope
scope.$apply();
//Forward the form submit
form.submit();
})
});
}
}
});
Rather than using form.submit()
, I would like to utilize $http.post()
to send the form data to my backend, then handle the response data within a .then()
function. The parameters to be sent include the value of reg.email
.
How can I achieve this setup with my current form structure? I prefer to use ng-submit
, but if that is not feasible, is there an alternative approach?