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.42.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 collectDeviceData: true,
106 email: "#{jid.sub(/@cheogram.com$/, "").gsub(/(%5[cC])|\\/, "=")}@smtp.cheogram.com"
107 }
108 }, function(err, payload) {
109 if(err) {
110 console.log(err);
111 button.disabled = false;
112 button.style.display = "block";
113 } else {
114 instance._mainView.showLoadingIndicator();
115 e.target.braintree_nonce.value = payload.nonce;
116 fetch("", {
117 "method": "POST",
118 "body": new FormData(e.target)
119 }).then(function(response) {
120 button.disabled = false;
121 button.style.display = "block";
122 instance._mainView.hideLoadingIndicator();
123
124 if(response.status === 200) {
125 if (window.xmpp_xep0050) window.xmpp_xep0050.execute();
126 } else {
127 return Promise.reject(response);
128 }
129 }).catch(function(err) {
130 button.disabled = false;
131 button.style.display = "block";
132 if(!(err instanceof Response)) return Promise.reject(err);
133
134 return err.text().then(function(msg) {
135 console.log(msg);
136 instance._mainView.hideLoadingIndicator();
137 instance.clearSelectedPaymentMethod();
138 instance._mainView.showSheetError(msg);
139 var errEl = instance._mainView.sheetErrorText;
140 if(errEl.innerHTML === instance._mainView.strings.genericError) {
141 errEl.innerHTML = "Card Issuer Says: " + msg;
142 }
143 });
144 }).catch(function(err) {
145 button.disabled = false;
146 button.style.display = "block";
147 console.log(err);
148 instance._mainView.hideLoadingIndicator();
149 instance.clearSelectedPaymentMethod();
150 instance._mainView.showSheetError();
151 Sentry.captureException(err);
152 });
153 }
154 });
155 });
156 });