text-align:center;
}
+/* Stripe's payment form */
+#payment_form
+{
+ background-color: [% css_colors.accent_ultralight %];
+ width: 75%;
+}
+#card-element
+{
+ padding: 10px;
+}
+
/* text to state what is seen on cc statement */
.cc_disclaimer
{
--- /dev/null
+ <form method="post" id="payment_form" action='#payment'>
+ <input type="hidden" name="last_chance" value="1" />
+ [% FOR xact IN CGI.param('xact') %]
+ <input type="hidden" name="xact" value="[% xact | html %]" />
+ [% END %]
+ [% FOR xact IN CGI.param('xact_misc') %]
+ <input type="hidden" name="xact_misc" value="[% xact | html %]" />
+ [% END %]
+ [% IF ctx.use_stripe %]
+ <input type="hidden" name="stripe_token" id="stripe_token" />
+ [% END %]
+
+ <table id="billing_info_table" class="table table-hover">
+ <thead>
+ <th colspan='2'><strong>[% l('Billing Information') %]</strong></th>
+ </thead>
+ <tbody>
+
+ <tr>
+ <td><label for="payment-first-name">[% l('First Name') %]</label></td>
+ <td><input name="given-name" type="text" name="billing_first" id="payment-first-name"
+ value="[% ctx.user.first_given_name | html %]" class="form-control"/></td>
+ </tr>
+ <tr>
+ <td><label for="payment-last-name">[% l('Last Name') %]</label></td>
+ <td><input name="family-name" type="text" name="billing_last" id="payment-last-name"
+ value="[% ctx.user.family_name | html %]" class="form-control"/></td>
+ </tr>
+
+ <tr>
+ <td><label for="payment-email-addr">[% l('Email Address') %]</label></td>
+ <td>
+
+ <input id="payment-email-addr" type="text"
+ value="[% ctx.user.email | html %]" disabled="disabled"
+ readonly="readonly" class="form-control" name="email"/>
+ <a title="[% l('Update Email Address') %]"
+ href="[% ctx.opac_root %]/myopac/update_email?return_to_referer=1">[% l("Update") %]</a>
+ </td>
+ </tr>
+ <tr>
+ <td><label for="payment-billing-address">[% l('Street Address') %]</label></td>
+ <td><input type="text" name="billing_address" id="payment-billing-address"
+ value="[% ctx.user.billing_address.street1 _ ctx.user.billing_address.street2 | html %]" class="form-control"/></td>
+ </tr>
+ <tr>
+ <td><label for="payment-billing-city">[% l('City' )%]</label></td>
+ <td><input type="text" name="billing_city" id="payment-billing-city"
+ value="[% ctx.user.billing_address.city | html %]" class="form-control"/></td>
+ </tr>
+ <tr>
+ <td><label for="payment-billing-state">[% l('State or Province') %]</label></td>
+ <td><input type="text" name="billing_state" id="payment-billing-state"
+ value="[% ctx.user.billing_address.state | html %]" class="form-control" /></td>
+ </tr>
+ <tr>
+ <td><label for="paymenet-billing-zip">[% l('Postal Code') %]</label></td>
+ [% USE zip=String(ctx.user.billing_address.post_code) %]
+ <td><input type="tel" pattern="[/^[a-zA-Z0-9 _-]{7}$/]*" maxlength="7" size="7" name="billing_zip" id="paymenet-billing-zip"
+ value="[% zip.truncate(5) %]" class="form-control"/></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <table id="credit_card_info_table" class="table">
+ <thead>
+ <th colspan='2'><strong>[% l('Credit Card Information') %]</strong></th>
+ </thead>
+ <tbody>
+
+ <tr>
+ <td><label for="payment-credit-card">[% l('Credit Card #') %]</label></td>
+
+ <!-- Make type tel, which prompts for numbers in mobile -->
+ <td><input class="form-control" type="tel" pattern="[0-9]*" maxlength="16" id="payment-credit-card" required name="number" /></td>
+ </tr>
+ <tr>
+ <td><label for="payment-security-code">[% l('Security Code') %]</label></td>
+ <td>
+ <!-- Make type tel, which prompts for numbers in mobile -->
+ <input class="form-control" type="tel" pattern="[0-9]*" size="4" maxlength="5" id="payment-security-code" name="cvv2" /></td>
+ </tr>
+ <tr>
+ <td><label for="payment-expire-month">[% l('Expiration Month') %]</label></td>
+ <td>
+ <select class="form-control" id="payment-expire-month" required
+ [% IF ctx.use_stripe %]
+ data-stripe="exp_month"
+ [% ELSE %]
+ name="expire_month"
+ [% END %]
+ >
+ <option value="-1"></option>
+ <option value="01">[% l("January (1)") %]</option>
+ <option value="02">[% l("February (2)") %]</option>
+ <option value="03">[% l("March (3)") %]</option>
+ <option value="04">[% l("April (4)") %]</option>
+ <option value="05">[% l("May (5)") %]</option>
+ <option value="06">[% l("June (6)") %]</option>
+ <option value="07">[% l("July (7)") %]</option>
+ <option value="08">[% l("August (8)") %]</option>
+ <option value="09">[% l("September (9)") %]</option>
+ <option value="10">[% l("October (10)") %]</option>
+ <option value="11">[% l("November (11)") %]</option>
+ <option value="12">[% l("December (12)") %]</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td><label for="payment-expire-year">[% l('Expiration Year') %]</label></td>
+ <td>
+ <select class="form-control" id="payment-expire-year" name="expire_year" >
+ [% year = date.format(date.now, '%Y');
+ y = year;
+ WHILE y < year + 10; # show ten years starting now %]
+ <option value="[% y %]">[% y %]</option>
+ [% y = y + 1; END %]
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td colspan='2'>
+ <div id="payment_actions">
+ [% l('Total amount:') %]
+ <strong>[% money(ctx.fines.balance_owed) %]</strong><br />
+
+ <button type="submit" id="payment_submit" class="btn btn-confirm"><i class="fas fa-arrow-circle-right"></i> [% l('Next') %]</button>
+ <a href="[% mkurl(ctx.opac_root _ '/myopac/main', {}, 1) %]" class="btn btn-deny"><i class="fas fa-ban"></i> [% l('Cancel') %]</a>
+ <br/>
+ </div>
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ [% INCLUDE "opac/parts/myopac/main_refund_policy.tt2" %]
+ </form>
+
--- /dev/null
+ <h3>[% l("Confirm Payment") %]</h3>
+
+ <form action="[% ctx.opac_root %]/myopac/main_pay_init" method="post">
+ [% FOR k IN CGI.Vars;
+ NEXT UNLESS k;
+ FOR val IN CGI.param(k) %]
+ <input type="hidden" name="[% k | html %]" value="[% val | html %]" />
+ [% END; END %]
+
+ <button type="submit" class="btn btn-confirm"><i class="fas fa-check"></i> [% l('Confirm') %]</button>
+ <a href="[% mkurl(ctx.opac_root _ '/myopac/main#selected_fines', {}, 1) %]" class="btn btn-deny"><i class="fas fa-ban"></i> [% l('Cancel') %]</a>
+ <p class="my-2"><big>[% l("Are you sure you are ready to charge ") %]
+ <strong> [% l("[_1] ", money(ctx.fines.balance_owed))%]</strong>
+ [% l("to your credit card?") %]</big></p>
+ <table title="[% l('List of Transactions') %]" id="acct_fines_confirm_header"
+ class="table my-2">
+ <thead>
+ <tr>
+ <th>[% l('Charge/Fee') %]</th>
+ <th class="text-right"><span>[% l('Amount') %]</th>
+ </tr>
+ </thead>
+ <tbody>
+ [%
+ FOR f IN ctx.fines.circulation;
+ NEXT IF CGI.param('xact').size &&
+ !CGI.param('xact').grep(f.xact.id).size;
+ attrs = {marc_xml => f.marc_xml};
+ IF f.marc_xml;
+ PROCESS get_marc_attrs args=attrs;
+ ELSIF f.xact.reservation;
+ attrs.title = f.xact.reservation.target_resource_type.name;
+ END %]
+ <tr>
+ <td>[% attrs.title | html %]</td>
+ <td class="text-right">[% money(f.xact.balance_owed) %]</td>
+ </tr>
+ [%
+ END;
+ FOR f IN ctx.fines.grocery;
+ NEXT IF CGI.param('xact_misc').size &&
+ !CGI.param('xact_misc').grep(f.xact.id).size %]
+ <tr>
+ <td>[% f.xact.last_billing_type | html %]</td>
+ <td class="text-right">[% money(f.xact.balance_owed) %]</td>
+ </tr>
+ [% END %]
+ </tbody>
+ </table>
[% l("The minimum amount you can pay is \$0.01.") %]
</div>
[% ELSE %]
-[% IF ctx.use_stripe %]
-<noscript>
- [% l("Your browser does not have Javascript enabled, and we cannot " _
- "process credit card payments without it. Please change your " _
- "browser settings and try again.") %]
-</noscript>
-[% END %]
<div class="container">
<hr>
-<div id="pay_fines_now"[% IF ctx.use_stripe %] class="hide_me"[% END %]>
- [% IF last_chance %]
- <h3>[% l("Confirm Payment") %]</h3>
-
- <form action="[% ctx.opac_root %]/myopac/main_pay_init" method="post">
- [% FOR k IN CGI.Vars;
- NEXT UNLESS k;
- FOR val IN CGI.param(k) %]
- <input type="hidden" name="[% k | html %]" value="[% val | html %]" />
- [% END; END %]
-
- <button type="submit" class="btn btn-confirm"><i class="fas fa-check"></i> [% l('Confirm') %]</button>
- <a href="[% mkurl(ctx.opac_root _ '/myopac/main#selected_fines', {}, 1) %]" class="btn btn-deny"><i class="fas fa-ban"></i> [% l('Cancel') %]</a>
- <p class="my-2"><big>[% l("Are you sure you are ready to charge ") %]
- <strong> [% l("[_1] ", money(ctx.fines.balance_owed))%]</strong>
- [% l("to your credit card?") %]</big></p>
- <table title="[% l('List of Transactions') %]" id="acct_fines_confirm_header"
- class="table my-2">
- <thead>
- <tr>
- <th>[% l('Charge/Fee') %]</th>
- <th class="text-right"><span>[% l('Amount') %]</th>
- </tr>
- </thead>
- <tbody>
- [%
- FOR f IN ctx.fines.circulation;
- NEXT IF CGI.param('xact').size &&
- !CGI.param('xact').grep(f.xact.id).size;
- attrs = {marc_xml => f.marc_xml};
- IF f.marc_xml;
- PROCESS get_marc_attrs args=attrs;
- ELSIF f.xact.reservation;
- attrs.title = f.xact.reservation.target_resource_type.name;
- END %]
- <tr>
- <td>[% attrs.title | html %]</td>
- <td class="text-right">[% money(f.xact.balance_owed) %]</td>
- </tr>
- [%
- END;
- FOR f IN ctx.fines.grocery;
- NEXT IF CGI.param('xact_misc').size &&
- !CGI.param('xact_misc').grep(f.xact.id).size %]
- <tr>
- <td>[% f.xact.last_billing_type | html %]</td>
- <td class="text-right">[% money(f.xact.balance_owed) %]</td>
- </tr>
- [% END %]
- </tbody>
- </table>
-
- [% ELSE %]
-
- <form method="post" id="payment_form" action='#payment'
- [% IF ctx.use_stripe %]
- onsubmit="return stripe_onsubmit();"
- [% END %]
- >
- <input type="hidden" name="last_chance" value="1" />
- [% FOR xact IN CGI.param('xact') %]
- <input type="hidden" name="xact" value="[% xact | html %]" />
- [% END %]
- [% FOR xact IN CGI.param('xact_misc') %]
- <input type="hidden" name="xact_misc" value="[% xact | html %]" />
- [% END %]
+<div id="pay_fines_now">
+ [% IF last_chance %]
+ [% PROCESS "opac/myopac/last_chance_form.tt2"; %]
+ [% ELSE %]
[% IF ctx.use_stripe %]
- <input type="hidden" name="stripe_token" id="stripe_token" />
+ [% PROCESS "opac/myopac/stripe_payment_form.tt2"; %]
+ [% ELSE %]
+ [% PROCESS "opac/myopac/generic_payment_form.tt2"; %]
[% END %]
-
- <table id="billing_info_table" class="table table-hover">
- <thead>
- <th colspan='2'><strong>[% l('Billing Information') %]</strong></th>
- </thead>
- <tbody>
-
- <tr>
- <td><label for="payment-first-name">[% l('First Name') %]</label></td>
- <td><input name="given-name" type="text" name="billing_first" id="payment-first-name"
- value="[% ctx.user.first_given_name | html %]" class="form-control"/></td>
- </tr>
- <tr>
- <td><label for="payment-last-name">[% l('Last Name') %]</label></td>
- <td><input name="family-name" type="text" name="billing_last" id="payment-last-name"
- value="[% ctx.user.family_name | html %]" class="form-control"/></td>
- </tr>
-
- <tr>
- <td><label for="payment-email-addr">[% l('Email Address') %]</label></td>
- <td>
-
- <input id="payment-email-addr" type="text"
- value="[% ctx.user.email | html %]" disabled="disabled"
- readonly="readonly" class="form-control" name="email"/>
- <a title="[% l('Update Email Address') %]"
- href="[% ctx.opac_root %]/myopac/update_email?return_to_referer=1">[% l("Update") %]</a>
- </td
- </tr>
- <tr>
- <td><label for="payment-billing-address">[% l('Street Address') %]</label></td>
- <td><input type="text" name="billing_address" id="payment-billing-address"
- value="[% ctx.user.billing_address.street1 _ ctx.user.billing_address.street2 | html %]" class="form-control"/></td>
- </tr>
- <tr>
- <td><label for="payment-billing-city">[% l('City' )%]</label></td>
- <td><input type="text" name="billing_city" id="payment-billing-city"
- value="[% ctx.user.billing_address.city | html %]" class="form-control"/></td>
- </tr>
- <tr>
- <td><label for="payment-billing-state">[% l('State or Province') %]</label></td>
- <td><input type="text" name="billing_state" id="payment-billing-state"
- value="[% ctx.user.billing_address.state | html %]" class="form-control" /></td>
- </tr>
- <tr>
- <td><label for="paymenet-billing-zip">[% l('Postal Code') %]</label></td>
- [% USE zip=String(ctx.user.billing_address.post_code) %]
- <td><input type="tel" pattern="[/^[a-zA-Z0-9 _-]{7}$/]*" maxlength="7" size="7" name="billing_zip" id="paymenet-billing-zip"
- value="[% zip.truncate(5) %]" class="form-control"/></td>
- </tr>
- </tbody>
- </table>
-
- <table id="credit_card_info_table" class="table">
- <thead>
- <th colspan='2'><strong>[% l('Credit Card Information') %]</strong></th>
- </thead>
- <tbody>
-
- <tr>
- <td><label for="payment-credit-card">[% l('Credit Card #') %]</label></td>
-
- <!-- Make type tel, which prompts for numbers in mobile -->
- <td><input class="form-control" type="tel" pattern="[0-9]*" maxlength="16" id="payment-credit-card" required
- [% IF ctx.use_stripe %]
- data-stripe="number"
- [% ELSE %]
- name="number"
- [% END %]
- /></td>
- </tr>
- <tr>
- <td><label for="payment-security-code">[% l('Security Code') %]</label></td>
- <td>
- <!-- Make type tel, which prompts for numbers in mobile -->
- <input class="form-control" type="tel" pattern="[0-9]*" size="4" maxlength="5" id="payment-security-code"
- [% IF ctx.use_stripe %]
- data-stripe="cvc"
- [% ELSE %]
- name="cvv2"
- [% END %]
- /></td>
- </tr>
- <tr>
- <td><label for="payment-expire-month">[% l('Expiration Month') %]</label></td>
- <td>
- <select class="form-control" id="payment-expire-month" required
- [% IF ctx.use_stripe %]
- data-stripe="exp_month"
- [% ELSE %]
- name="expire_month"
- [% END %]
- >
- <option value="-1"></option>
- <option value="01">[% l("January (1)") %]</option>
- <option value="02">[% l("February (2)") %]</option>
- <option value="03">[% l("March (3)") %]</option>
- <option value="04">[% l("April (4)") %]</option>
- <option value="05">[% l("May (5)") %]</option>
- <option value="06">[% l("June (6)") %]</option>
- <option value="07">[% l("July (7)") %]</option>
- <option value="08">[% l("August (8)") %]</option>
- <option value="09">[% l("September (9)") %]</option>
- <option value="10">[% l("October (10)") %]</option>
- <option value="11">[% l("November (11)") %]</option>
- <option value="12">[% l("December (12)") %]</option>
- </select>
- </td>
- </tr>
- <tr>
- <td><label for="payment-expire-year">[% l('Expiration Year') %]</label></td>
- <td>
- <select class="form-control" id="payment-expire-year"
- [%- IF ctx.use_stripe %]
- data-stripe="exp_year"
- [% ELSE %]
- name="expire_year"
- [% END -%]
- >
- [% year = date.format(date.now, '%Y');
- y = year;
- WHILE y < year + 10; # show ten years starting now %]
- <option value="[% y %]">[% y %]</option>
- [% y = y + 1; END %]
- </select>
- </td>
- </tr>
- <tr>
- <td colspan='2'>
- <div id="payment_actions">
- [% l('Total amount:') %]
- <strong>[% money(ctx.fines.balance_owed) %]</strong><br />
-
- <button type="submit" id="payment_submit" class="btn btn-confirm"><i class="fas fa-arrow-circle-right"></i> [% l('Next') %]</button>
- <a href="[% mkurl(ctx.opac_root _ '/myopac/main', {}, 1) %]" class="btn btn-deny"><i class="fas fa-ban"></i> [% l('Cancel') %]</a>
- <br/>
- </div>
- </td>
- </tr>
-
- </tbody>
- </table>
- [% INCLUDE "opac/parts/myopac/main_refund_policy.tt2" %]
-
[% END %]
- </form>
</div></div>
[% END %]
--- /dev/null
+<noscript>
+ [% l("Your browser does not have Javascript enabled, and we cannot " _
+ "process credit card payments without it. Please adjust your " _
+ "browser settings and try again.") %]
+</noscript>
+<script type="text/javascript">
+function build_stripe_form() {
+ var elements = stripe.elements();
+
+ var style = {
+ base: {
+ color: '#32325d',
+ fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
+ fontSmoothing: 'antialiased',
+ fontSize: '16px',
+ '::placeholder': {
+ color: '#aab7c4'
+ }
+ },
+ invalid: {
+ color: '#fa755a',
+ iconColor: '#fa755a'
+ }
+ };
+
+ var card = elements.create('card', {style: style});
+ card.mount('#card-element');
+
+ // real-time validation
+ card.on('change', function(event) {
+ var displayError = document.getElementById('card-errors');
+ if (event.error) {
+ displayError.textContent = event.error.message;
+ } else {
+ displayError.textContent = '';
+ }
+ });
+
+ // let's try some auto-focus
+ card.on('ready', function(event) {
+ try { card.focus(); } catch(E) { console.log('failed to focus card element',E); }
+ });
+
+ var form = document.getElementById('payment_form');
+ form.addEventListener('submit', function(event) {
+ event.preventDefault();
+
+ stripe.createToken(card).then(function(result) {
+ if (result.error) {
+ // Inform the user if there was an error.
+ var errorElement = document.getElementById('card-errors');
+ errorElement.textContent = result.error.message;
+ } else {
+ // Send the token to your server.
+ stripeTokenHandler(result.token);
+ }
+ });
+ });
+
+ function stripeTokenHandler(token) {
+ var form = document.getElementById('payment_form');
+ var hiddenInput = document.createElement('input');
+ hiddenInput.setAttribute('type', 'hidden');
+ hiddenInput.setAttribute('name', 'stripe_token');
+ hiddenInput.setAttribute('value', token.id);
+ form.appendChild(hiddenInput);
+
+ form.submit();
+ }
+}
+ $(document).ready(build_stripe_form);
+</script>
+<form action="#payment" method="post" id="payment_form">
+ <input type="hidden" name="last_chance" value="1" />
+ [% FOR xact IN CGI.param('xact') %]
+ <input type="hidden" name="xact" value="[% xact | html %]" />
+ [% END %]
+ [% FOR xact IN CGI.param('xact_misc') %]
+ <input type="hidden" name="xact_misc" value="[% xact | html %]" />
+ [% END %]
+ <div>
+ <label for="card-element">
+ <h3>[% l('Credit Card Information') %]</h3>
+ </label>
+ <div id="card-element">
+ <!-- A Stripe Element will be inserted here. -->
+ </div>
+
+ <!-- Used to display form errors. -->
+ <div id="card-errors" role="alert"></div>
+ </div>
+ <div id="payment_actions">
+ <button type="submit" id="payment_submit" class="btn btn-confirm"><i class="fas fa-arrow-circle-right"></i> [% l('Next') %]</button>
+ <a href="[% mkurl(ctx.opac_root _ '/myopac/main', {}, 1) %]" class="btn btn-deny"><i class="fas fa-ban"></i> [% l('Cancel') %]</a>
+ </div>
+
+ [% INCLUDE "opac/parts/myopac/main_refund_policy.tt2" %]
+
+</form>
[%- PROCESS "opac/parts/header.tt2" %]
[% IF ctx.use_stripe %]
- <script type="text/javascript" src="https://js.stripe.com/v2/"></script> <!-- use an ou setting for this url? -->
+ <script type="text/javascript" src="https://js.stripe.com/v3/"></script> <!-- use an ou setting for this url? -->
<script type="text/javascript">
// This script is only displayed when logged in, so ctx.user.home_ou is always available
- Stripe.setPublishableKey('[% ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.stripe.pubkey') %]');
+ var stripe = Stripe('[% ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.stripe.pubkey') %]');
- function stripe_onsubmit() {
- var form = document.getElementById("payment_form");
- var button = document.getElementById("payment_submit");
-
- button.disabled = true;
-
- Stripe.card.createToken(form, stripe_callback);
-
- return false;
- }
-
- function stripe_callback(status, response) {
- var form = document.getElementById("payment_form");
- var button = document.getElementById("payment_submit");
- var stripe_token = document.getElementById("stripe_token");
-
- if(response.error) {
- alert(response.error.message);
- button.disabled = false;
- return;
- }
-
- stripe_token.value = response.id; // response.id is the token id, though there are more fields available if needed.
- form.setAttribute("onsubmit","");
- form.submit();
- }
</script>
[%- END %]