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="braintree_nonce"
36
37script src="https://js.braintreegateway.com/web/dropin/1.26.0/js/dropin.min.js"
38javascript:
39	document.querySelector("#braintree").innerHTML = "";
40
41	var button = document.createElement("button");
42	button.innerHTML = "Save";
43	document.querySelector("form").appendChild(button);
44	braintree.dropin.create({
45		authorization: #{{token.to_json}},
46		container: "#braintree",
47		vaultManager: true,
48		translations: {
49			payWithCard: "Add a Card",
50			payingWith: "Default payment source",
51			chooseAnotherWayToPay: "Add a different payment source"
52		}
53	}, function (createErr, instance) {
54		if(createErr) console.log(createErr);
55
56		document.querySelector("form").addEventListener("submit", function(e) {
57			e.preventDefault();
58			instance._mainView.hideSheetError();
59			instance._mainView.showLoadingIndicator();
60
61			instance.requestPaymentMethod(function(err, payload) {
62				if(err) {
63					console.log(err);
64					instance._mainView.hideLoadingIndicator();
65					instance._mainView.showSheetError();
66				} else {
67					e.target.braintree_nonce.value = payload.nonce;
68					fetch("", {
69						"method": "POST",
70						"body": new FormData(e.target)
71					}).then(function(response) {
72						instance._mainView.hideLoadingIndicator();
73
74						if(response.status !== 200) {
75							return Promise.reject(response);
76						}
77					}).catch(function(err) {
78							console.log(err);
79							instance._mainView.hideLoadingIndicator();
80							instance._mainView.showSheetError();
81					});
82				}
83			});
84		});
85	});