SolidusStripe.Elements = function() { SolidusStripe.Payment.call(this); this.form = this.element.parents('form'); this.errorElement = this.form.find('#card-errors'); this.submitButton = this.form.find('input[type="submit"]'); }; SolidusStripe.Elements.prototype = Object.create(SolidusStripe.Payment.prototype); Object.defineProperty(SolidusStripe.Elements.prototype, 'constructor', { value: SolidusStripe.Elements, enumerable: false, writable: true }); SolidusStripe.Elements.prototype.init = function() { this.initElements(); }; SolidusStripe.Elements.prototype.initElements = function() { var cardExpiry = this.elements.create('cardExpiry', this.cardExpiryElementOptions()); cardExpiry.mount('#card_expiry'); var cardCvc = this.elements.create('cardCvc', this.cardCvcElementOptions()); cardCvc.mount('#card_cvc'); this.cardNumber = this.elements.create('cardNumber', this.cardNumberElementOptions()); this.cardNumber.mount('#card_number'); this.form.bind('submit', this.onFormSubmit.bind(this)); // Listen for errors from each input field. // Adapted from https://github.com/stripe/elements-examples/blob/master/js/index.js var savedErrors = {}; [cardExpiry, cardCvc, this.cardNumber].forEach(function(element, idx) { element.on('change', function(event) { if (event.error) { savedErrors[idx] = event.error.message; this.showError(event.error.message); } else { savedErrors[idx] = null; // Loop over the saved errors and find the first one, if any. var nextError = Object.keys(savedErrors) .sort() .reduce(function(maybeFoundError, key) { return maybeFoundError || savedErrors[key]; }, null); if (nextError) { // Now that they've fixed the current error, show another one. this.showError(nextError); } else { // The user fixed the last error; no more errors. this.errorElement.hide().text(''); } } }.bind(this)); }.bind(this)); }; SolidusStripe.Elements.prototype.baseStyle = function () { return { base: { color: 'black', fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: 'antialiased', fontSize: '14px', '::placeholder': { color: 'silver' } }, invalid: { color: 'red', iconColor: 'red' } }; }; SolidusStripe.Elements.prototype.cardNumberElementOptions = function () { return { style: this.baseStyle() } } SolidusStripe.Elements.prototype.cardExpiryElementOptions = function () { return { style: this.baseStyle() } } SolidusStripe.Elements.prototype.cardCvcElementOptions = function () { return { style: this.baseStyle() } } SolidusStripe.Elements.prototype.showError = function(error) { var message = error.message || error; this.errorElement.text(message).show(); this.submitButton.removeAttr('disabled').removeClass('disabled'); }; SolidusStripe.Elements.prototype.onFormSubmit = function(event) { if (this.element.is(':visible')) { event.preventDefault(); var onTokenCreate = function(result) { if (result.error) { this.showError(result.error.message); } else { this.elementsTokenHandler(result.token); this.form[0].submit(); } }; this.stripe.createToken(this.cardNumber).then(onTokenCreate.bind(this)); } }; SolidusStripe.Elements.prototype.elementsTokenHandler = function(token) { var mapCC = function(ccType) { if (ccType === 'MasterCard' || ccType === 'mastercard') { return 'mastercard'; } else if (ccType === 'Visa' || ccType === 'visa') { return 'visa'; } else if (ccType === 'American Express' || ccType === 'amex') { return 'amex'; } else if (ccType === 'Discover' || ccType === 'discover') { return 'discover'; } else if (ccType === 'Diners Club' || ccType === 'diners') { return 'dinersclub'; } else if (ccType === 'JCB' || ccType === 'jcb') { return 'jcb'; } else if (ccType === 'Unionpay' || ccType === 'unionpay') { return 'unionpay'; } }; var baseSelector = `<input type='hidden' class='stripeToken' name='payment_source[${this.config.id}]`; this.element.append(`${baseSelector}[gateway_payment_profile_id]' value='${token.id}'/>`); this.element.append(`${baseSelector}[last_digits]' value='${token.card.last4}'/>`); this.element.append(`${baseSelector}[month]' value='${token.card.exp_month}'/>`); this.element.append(`${baseSelector}[year]' value='${token.card.exp_year}'/>`); this.form.find('input#cc_type').val(mapCC(token.card.brand || token.card.type)); };