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	label#amount style="#{'display:none;' unless params['amount']}"
 28		div Amount of initial deposit (minimum $15)
 29		input type="number" name="amount" min="15" value="#{params.fetch('amount', '')}"
 30
 31	fieldset
 32		legend Auto top-up when account balance is low?
 33		label
 34			| When balance drops below $5, add $
 35			input type="number" name="auto_top_up_amount" min="15" max="35" value=auto_top_up
 36			small Leave blank for no auto top-up.
 37
 38	input type="hidden" name="customer_id" value=customer_id
 39	input type="hidden" name="atfd" value=antifraud
 40	input type="hidden" name="braintree_nonce"
 41
 42script src="https://js.braintreegateway.com/web/dropin/1.33.0/js/dropin.js"
 43javascript:
 44	document.querySelector("#braintree").innerHTML = "";
 45
 46	if(window.localStorage) {
 47		var atfd = localStorage.getItem("atfd");
 48		if(!atfd) {
 49			atfd = "#{antifraud}";
 50			localStorage.setItem("atfd", atfd);
 51		}
 52		document.querySelector("input[name=atfd]").value = atfd;
 53	}
 54
 55	var button = document.createElement("button");
 56	button.innerHTML = "Save";
 57	document.querySelector("form").appendChild(button);
 58
 59	if (window.xmpp_xep0050) {
 60		xmpp_xep0050.preventDefault();
 61
 62		window.addEventListener("message", (ev) => {
 63			if (ev.data === "xmpp_xep0050/next" && !button.disabled) {
 64				document.querySelector("form").requestSubmit();
 65			}
 66			if (ev.data === "xmpp_xep0050/cancel") {
 67				window.xmpp_xep0050.execute("cancel");
 68			}
 69			if (ev.data === "xmpp_xep0050/prev") {
 70				window.xmpp_xep0050.execute("prev");
 71			}
 72			if (ev.data === "xmpp_xep0050/complete") {
 73				window.xmpp_xep0050.execute("complete");
 74			}
 75		});
 76	}
 77
 78	braintree.dropin.create({
 79		authorization: #{{token.to_json}},
 80		container: "#braintree",
 81		card: { vault: { vaultCard: false } },
 82		vaultManager: true,
 83		threeDSecure: true,
 84		translations: {
 85			payWithCard: "Add a Card",
 86			payingWith: "Default payment source",
 87			chooseAnotherWayToPay: "Add a different payment source"
 88		}
 89	}, function (createErr, instance) {
 90		if(createErr) {
 91			console.log(createErr);
 92			Sentry.captureException(createErr);
 93		}
 94
 95		document.querySelector("form").addEventListener("submit", function(e) {
 96			button.disabled = true;
 97			button.style.display = "none";
 98			e.preventDefault();
 99			instance._mainView.hideSheetError();
100
101			instance.requestPaymentMethod({
102				threeDSecure: {
103					amount: document.querySelector("input[name=amount]").value || "0.0",
104					requireChallenge: true
105				}
106			}, function(err, payload) {
107				if(err) {
108					console.log(err);
109					button.disabled = false;
110					button.style.display = "block";
111				} else {
112					instance._mainView.showLoadingIndicator();
113					e.target.braintree_nonce.value = payload.nonce;
114					fetch("", {
115						"method": "POST",
116						"body": new FormData(e.target)
117					}).then(function(response) {
118						button.disabled = false;
119						button.style.display = "block";
120						instance._mainView.hideLoadingIndicator();
121
122						if(response.status === 200) {
123							if (window.xmpp_xep0050) window.xmpp_xep0050.execute();
124						} else {
125							return Promise.reject(response);
126						}
127					}).catch(function(err) {
128						button.disabled = false;
129						button.style.display = "block";
130						if(!(err instanceof Response)) return Promise.reject(err);
131
132						return err.text().then(function(msg) {
133							console.log(msg);
134							instance._mainView.hideLoadingIndicator();
135							instance.clearSelectedPaymentMethod();
136							instance._mainView.showSheetError(msg);
137							var errEl = instance._mainView.sheetErrorText;
138							if(errEl.innerHTML === instance._mainView.strings.genericError) {
139								errEl.innerHTML = "Card Issuer Says: " + msg;
140							}
141						});
142					}).catch(function(err) {
143						button.disabled = false;
144						button.style.display = "block";
145						console.log(err);
146						instance._mainView.hideLoadingIndicator();
147						instance.clearSelectedPaymentMethod();
148						instance._mainView.showSheetError();
149						Sentry.captureException(err);
150					});
151				}
152			});
153		});
154	});