Skip to content

Instantly share code, notes, and snippets.

@akshayas
Created September 30, 2017 18:56
Show Gist options
  • Save akshayas/516c64def43ba25d5f59ef066c99441e to your computer and use it in GitHub Desktop.
Save akshayas/516c64def43ba25d5f59ef066c99441e to your computer and use it in GitHub Desktop.
BigCommerce Bolt Stencil Integration
<!-- 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