credit_cards.slim

  1scss:
  2	form {
  3		margin: auto;
  4		max-width: 40em;
  5		text-align: center;
  6
  7		fieldset {
  8			max-width: 25em;
  9			margin: 2em auto;
 10			label { display: block; }
 11			input[type=number] { max-width: 3em; }
 12			small { display: block; }
 13		}
 14
 15		button {
 16			display: block;
 17			width: 10em;
 18			margin: auto;
 19		}
 20
 21	}
 22
 23form method="post" action=""
 24	#braintree
 25		| Unfortunately, our credit card processor requires JavaScript.
 26
 27	fieldset
 28		legend Auto top-up when account balance is low?
 29		label
 30			| When balance drops below $5, add $
 31			input type="number" name="auto_top_up_amount" min="15" value=auto_top_up
 32			small Leave blank for no auto top-up.
 33
 34	input type="hidden" name="customer_id" value=customer_id
 35	input type="hidden" name="atfd" value=antifraud
 36	input type="hidden" name="braintree_nonce"
 37
 38script src="https://js.braintreegateway.com/web/dropin/1.33.0/js/dropin.js"
 39javascript:
 40	document.querySelector("#braintree").innerHTML = "";
 41
 42	if(window.localStorage) {
 43		var atfd = localStorage.getItem("atfd");
 44		if(!atfd) {
 45			atfd = "#{antifraud}";
 46			localStorage.setItem("atfd", atfd);
 47		}
 48		document.querySelector("input[name=atfd]").value = atfd;
 49	}
 50
 51	if (window.xmpp_xep0050) {
 52		xmpp_xep0050.preventDefault();
 53
 54		window.addEventListener("message", (ev) => {
 55			if (ev.data === "xmpp_xep0050/next") {
 56				document.querySelector("form").requestSubmit();
 57			}
 58		});
 59	}
 60
 61	var button = document.createElement("button");
 62	button.innerHTML = "Save";
 63	document.querySelector("form").appendChild(button);
 64	braintree.dropin.create({
 65		authorization: #{{token.to_json}},
 66		container: "#braintree",
 67		card: { vault: { vaultCard: false } },
 68		vaultManager: true,
 69		threeDSecure: true,
 70		translations: {
 71			payWithCard: "Add a Card",
 72			payingWith: "Default payment source",
 73			chooseAnotherWayToPay: "Add a different payment source"
 74		}
 75	}, function (createErr, instance) {
 76		if(createErr) {
 77			console.log(createErr);
 78			Sentry.captureException(createErr);
 79		}
 80
 81		document.querySelector("form").addEventListener("submit", function(e) {
 82			e.preventDefault();
 83			instance._mainView.hideSheetError();
 84
 85			instance.requestPaymentMethod({
 86				threeDSecure: {
 87					amount: "0.0",
 88					requireChallenge: true
 89				}
 90			}, function(err, payload) {
 91				if(err) {
 92					console.log(err);
 93				} else {
 94					instance._mainView.showLoadingIndicator();
 95					e.target.braintree_nonce.value = payload.nonce;
 96					fetch("", {
 97						"method": "POST",
 98						"body": new FormData(e.target)
 99					}).then(function(response) {
100						instance._mainView.hideLoadingIndicator();
101
102						if(response.status === 200) {
103							if (window.xmpp_xep0050) window.xmpp_xep0050.execute();
104						} else {
105							return Promise.reject(response);
106						}
107					}).catch(function(err) {
108						if(!(err instanceof Response)) return Promise.reject(err);
109
110						return err.text().then(function(msg) {
111							console.log(msg);
112							instance._mainView.hideLoadingIndicator();
113							instance.clearSelectedPaymentMethod();
114							instance._mainView.showSheetError(msg);
115							var errEl = instance._mainView.sheetErrorText;
116							if(errEl.innerHTML === instance._mainView.strings.genericError) {
117								errEl.innerHTML = "Card Issuer Says: " + msg;
118							}
119						});
120					}).catch(function(err) {
121						console.log(err);
122						instance._mainView.hideLoadingIndicator();
123						instance.clearSelectedPaymentMethod();
124						instance._mainView.showSheetError();
125						Sentry.captureException(err);
126					});
127				}
128			});
129		});
130	});