Created
September 30, 2017 18:56
-
-
Save akshayas/516c64def43ba25d5f59ef066c99441e to your computer and use it in GitHub Desktop.
BigCommerce Bolt Stencil Integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- BOLT INTEGRATION: BEGIN --> | |
<script src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-3.min.js"></script> | |
<script id="bolt_main_script"> | |
var BOLT_MERCHANT_KEY = '<insert merchant key>'; | |
(function() { | |
var oldOpen = XMLHttpRequest.prototype.open; | |
XMLHttpRequest.prototype.open = function(method, url) { | |
this.addEventListener('load', function(event){ | |
if (/checkout\/payments/.test(url)) { | |
setTimeout(replacePayment); | |
} | |
}) | |
oldOpen.apply(this, arguments); | |
} | |
function replacePayment() { | |
hideTestPaymentGateway(); | |
addBoltButton(); | |
injectBoltScript(function() { | |
instantinateBoltCart(); | |
}); | |
} | |
function hideTestPaymentGateway() { | |
/* Hide the stripe gateway */ | |
var el = document.getElementById('radio-stripe'); | |
if (!el) { | |
return log('Test payment gateway not found(1)'); | |
} | |
var $el = angular.element(el); | |
var $testPaymentEl = lookParentWhile($el, function(el) { return el.hasClass('form-checklist-item')}); | |
if (!$testPaymentEl) { | |
return log('Test payment gateway not found(2)'); | |
} | |
$testPaymentEl.css('display', 'none'); | |
} | |
/* util */ | |
function lookParentWhile(el, test) { | |
if (test(el)) return el; | |
if (!el) return null; | |
return lookParentWhile(el.parent(), test); | |
} | |
function addBoltButton() { | |
var paymentElement; | |
try { | |
paymentElement = document.querySelector('li.checkout-step--payment legend.form-legend'); | |
} catch (ex) { | |
return log('Couldn\'t find payment block'); | |
} | |
angular.element(paymentElement).after('<div class="bolt-checkout-button with-cards" style="margin-left: -10px; margin-bottom: 10px"/>'); | |
} | |
function injectBoltScript(cb) { | |
var existingScript = document.getElementById('bolt-connect'); | |
if (existingScript) { | |
return cb(); | |
} | |
var $script = angular.element(document.getElementById('bolt_main_script')); | |
var boltScript = document.createElement('script'); | |
boltScript.id = 'bolt-connect'; | |
boltScript.src = 'https://connect.boltapp.com/connect.js'; | |
boltScript.setAttribute('data-publishable-key', BOLT_MERCHANT_KEY); | |
boltScript.setAttribute('data-shopping-cart-id', 'BC'); | |
var trackScript = document.createElement('script'); | |
trackScript.id = 'bolt-track'; | |
trackScript.src = 'https://connect.boltapp.com/track.js'; | |
trackScript.setAttribute('data-publishable-key', BOLT_MERCHANT_KEY); | |
$script.after(trackScript); | |
$script.after(boltScript); | |
boltScript.addEventListener('load', cb); | |
} | |
function instantinateBoltCart() { | |
var controller = angular.element(document.querySelector('li.checkout-step--payment .checkout-view-content')).controller(); | |
if (!(controller && controller.cart)) { | |
return log('Couldn\'t retreive cart'); | |
} | |
var cart = controller.cart; | |
var bolt_cart = {}; | |
try { | |
bolt_cart.items = cart.items.map(function(item){ | |
return { | |
name: item.name, | |
reference: item.id, | |
image: item.imageUrl, | |
quantity: item.quantity, | |
total: item.integerAmount, | |
price: round2(item.amount / item.quantity) | |
} | |
}); | |
if (cart.taxTotal.integerAmount) { | |
bolt_cart.tax = { | |
name: 'Tax', | |
price: cart.taxTotal.amount | |
}; | |
} | |
bolt_cart.shipping = { | |
name: 'Shipping', | |
price: cart.shipping.amount | |
} | |
bolt_cart.discounts = []; | |
if (cart.coupon.discountedAmount) { | |
bolt_cart.discounts.push({ | |
description: 'Coupon', | |
amount: cart.coupon.discountedAmount | |
}); | |
} | |
if (cart.giftCertificate.totalDiscountedAmount) { | |
bolt_cart.discounts.push({ | |
description: 'Gift Certificate', | |
amount: cart.giftCertificate.totalDiscountedAmount | |
}) | |
} | |
if (cart.discount.amount) { | |
bolt_cart.discounts.push({ | |
description: 'Discount', | |
amount: cart.discount.amount | |
}); | |
} | |
bolt_cart.total = String(cart.grandTotal.amount); | |
} catch(ex) { | |
console.error(ex); | |
log('Couldn\'t process cart', ex); | |
} | |
var user_data = {}; | |
try { | |
var customer = angular.element(document.querySelector('li.checkout-step--customer .checkout-view-header')) | |
.controller().customer; | |
var shipping = angular.element(document.querySelector('li.checkout-step--shipping .checkout-view-header')) | |
.controller().editingAddress; | |
var billing = angular.element(document.querySelector('li.checkout-step--billing .checkout-view-header')) | |
.controller().editingAddress; | |
user_data.first_name = customer.firstName || shipping.firstName || billing.firstName; | |
user_data.last_name = customer.lastName || shipping.lastName || billing.lastName; | |
user_data.email = customer.email; | |
user_data.shipping = transformShipping(shipping); | |
user_data.billing = transformShipping(billing); | |
user_data.phone = customer.phoneNumber || shipping.phone || billing.phone; | |
} catch(ex) { | |
console.error(ex); | |
log('Couldn\'t parse user data', ex); | |
} | |
BoltConnect.process(bolt_cart, user_data, BoltCallbacks); | |
} | |
function transformShipping(shipping) { | |
if (shipping == null) return null; | |
return { | |
AddressLine1: shipping.addressLine1, | |
AddressLine2: shipping.addressLine2, | |
Country: shipping.country, | |
CountryCode: shipping.countryCode, | |
City: shipping.city, | |
State: shipping.province, | |
FirstName: shipping.firstName, | |
LastName: shipping.lastName, | |
Phone: shipping.phone | |
}; | |
} | |
function mul(num) { | |
return Number(num + 'e2'); | |
} | |
function round2(num) { | |
return Number( | |
Math.round(mul(num)) + 'e-2' | |
); | |
} | |
function triggerEvent(name, element) { | |
if ('createEvent' in document) { | |
var evt = document.createEvent("HTMLEvents"); | |
evt.initEvent(name, false, true); | |
element.dispatchEvent(evt); | |
} else { | |
element.fireEvent('on' + name); | |
} | |
} | |
var BoltCallbacks = window.boltcbs = { | |
success: function(transaction, callback) { | |
if (!transaction) { | |
log('no transaction in response'); | |
} | |
if (!transaction.reference) { | |
log('no transaction reference in response payload', {transaction: transaction}); | |
} | |
fakeTestGateway(transaction.reference); | |
} | |
}; | |
function fakeTestGateway(id) { | |
document.getElementById('radio-stripe').click(); | |
var payment = document.querySelector('li.checkout-step--billing .checkout-view-content'); | |
var orderService = angular.element(payment).injector().get('orderService'); | |
var order = orderService.getOrder(); | |
order.customerMessage = (order.customerMessage ? order.customerMessage : '') +'\nPayment Transaction ID ' + id; | |
setInterval(function(){ | |
var ccn = document.getElementById('ccNumber'); | |
ccn.value = '4111111111111111'; | |
triggerEvent('change', ccn); | |
var ccexp = document.getElementById('ccExpiry'); | |
ccexp.value = '01/22'; | |
triggerEvent('change', ccexp); | |
var ccname = document.getElementById('ccName'); | |
ccname.value = 'Bolt Test'; | |
triggerEvent('change', ccname); | |
var cccvv = document.getElementById('ccCvv'); | |
cccvv.value = '111'; | |
triggerEvent('change', cccvv); | |
document.getElementById('checkout-payment-continue').click(); | |
}, 100); | |
} | |
function log(message, error) { | |
if (window.Bugsnag) { | |
window.Bugsnag.apiKey = "36ddd41e8e86611e102c051fe094efe4"; | |
window.Bugsnag.releaseStage = "production"; | |
if (window.BoltConnect) { | |
window.Bugsnag.appVersion = BoltConnect.getVersion(); | |
} | |
if (error && error instanceof Error) { | |
window.Bugsnag.notifyException( | |
error, { | |
message: message | |
}); | |
} else { | |
window.Bugsnag.notifyException(new Error(message), error); | |
} | |
} | |
} | |
})(); | |
</script> | |
<!-- BOLT INTEGRATION: END --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment