spree_bitpay 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.rspec +1 -0
- data/.travis.yml +18 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +79 -0
- data/Rakefile +21 -0
- data/app/assets/images/BC_nBG_64px.png +0 -0
- data/app/assets/images/bitcoin.png +0 -0
- data/app/assets/javascripts/easyModal.js-master/.gitignore +1 -0
- data/app/assets/javascripts/easyModal.js-master/README.md +3 -0
- data/app/assets/javascripts/easyModal.js-master/bower.json +20 -0
- data/app/assets/javascripts/easyModal.js-master/jquery.easyModal.js +161 -0
- data/app/assets/javascripts/spree/backend/spree_bitpay.js +3 -0
- data/app/assets/javascripts/spree/frontend/spree_bitpay.js +86 -0
- data/app/assets/stylesheets/spree/backend/spree_bitpay.css +3 -0
- data/app/assets/stylesheets/spree/frontend/spree_bitpay.css +58 -0
- data/app/controllers/spree/bitpay_controller.rb +248 -0
- data/app/models/spree/bitpay_invoice.rb +23 -0
- data/app/models/spree/payment_method/bitpay.rb +64 -0
- data/app/overrides/spree/payments/_payment/bitpay_payment_params.html.erb.deface +55 -0
- data/app/views/spree/admin/payments/source_views/_bitpay.html.erb +23 -0
- data/app/views/spree/checkout/payment/_bitpay.html.erb +4 -0
- data/bin/rails +7 -0
- data/config/locales/en.yml +16 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20140720052959_create_spree_bitpay_invoices.rb +8 -0
- data/db/migrate/20140725200946_add_fields_to_spree_bitpay_invoice.rb +14 -0
- data/db/migrate/20140729192827_add_index_to_spree_payments.rb +5 -0
- data/lib/generators/spree_bitpay/install/install_generator.rb +32 -0
- data/lib/spree_bitpay/engine.rb +28 -0
- data/lib/spree_bitpay/factories.rb +6 -0
- data/lib/spree_bitpay/version.rb +3 -0
- data/lib/spree_bitpay.rb +3 -0
- data/script/rails +7 -0
- data/spec/factories/bitpay_test_factories.rb +54 -0
- data/spec/features/bitpay_plugin_spec.rb +75 -0
- data/spec/fixtures/valid_confirmed_callback.json +27 -0
- data/spec/fixtures/valid_confirmed_invoice.json +15 -0
- data/spec/fixtures/valid_expired_invoice.json +16 -0
- data/spec/fixtures/valid_invalid_callback.json +27 -0
- data/spec/fixtures/valid_invalid_invoice.json +15 -0
- data/spec/fixtures/valid_new_invoice.json +15 -0
- data/spec/fixtures/valid_overpaid_callback.json +27 -0
- data/spec/fixtures/valid_overpaid_invoice.json +15 -0
- data/spec/fixtures/valid_paid_callback.json +27 -0
- data/spec/fixtures/valid_paid_invoice.json +15 -0
- data/spec/models/spree/payment_method/bitpay.rb +27 -0
- data/spec/requests/notifications_spec.rb +218 -0
- data/spec/spec_helper.rb +131 -0
- data/spree_bitpay.gemspec +41 -0
- data/testapp.sh +16 -0
- metadata +375 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0c95a10c599f7d3d9cb8f35919131b3c1865aa7e
|
4
|
+
data.tar.gz: 98c339b5f729ae19f3e431a9acecf56fa61edaed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 01cac797c6e62c22a2725215c23a0022e551cbbb6e9234b7e2592a64f1dce07a4429d7cbf731b6bba9891965b694eaf164f239d2c173d83f28abcc70049a8116
|
7
|
+
data.tar.gz: b8a1026b7a5d5f40d8c9192f6f7f3d02c62a87a7bc8fa582a5048d8c1113abffa854862fa97d399400feed70b3bcf8bfbb7f7f9d7fc8d9a98f6ab4f9ce5b8993
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
.DS_Store
|
24
|
+
spec/dummy
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 2.1.2
|
5
|
+
before_install:
|
6
|
+
- gem install bundler --pre
|
7
|
+
before_script:
|
8
|
+
- bundle exec rake test_app
|
9
|
+
script: DISPLAY=:99.0 bundle exec rspec spec
|
10
|
+
notifications:
|
11
|
+
email:
|
12
|
+
recipients:
|
13
|
+
- none@example.com
|
14
|
+
on_failure: change
|
15
|
+
on_success: never
|
16
|
+
env:
|
17
|
+
global:
|
18
|
+
secure: rK79pr+jpARJRPG79WD76v1GMWUm6XnTMr4dUWJk6QgFHB1AMYc3UURccWvlPmVKG3iSJ1rd4SWoajNosYXbL1CMP6LvNNCIeOa+QoLxBu2npXP5fUIt7HmD4b17mcT9sShjU8YValwbHGhfUnEmpP5AGjQSF21dsDDOANWlRKA=
|
data/Gemfile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'spree', '~> 2.2.2'
|
4
|
+
gem 'spree_auth_devise', :git => 'https://github.com/spree/spree_auth_devise.git', :branch => '2-2-stable'
|
5
|
+
gem 'bitpay-client', '>=0.1.3'
|
6
|
+
# Specify your gem's dependencies in spree_bitpay.gemspec
|
7
|
+
gemspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# BitPay plugin for Spree Commerce
|
2
|
+
[![Build Status](https://travis-ci.org/bitpay/spree-bitpay.svg?branch=master)](https://travis-ci.org/bitpay/spree_bitpay)
|
3
|
+
|
4
|
+
BitPay Payments connector for SpreeCommerce RoR storefront. Accept bitcoin payments with ZERO fees. Choose remittance in your local currency or take a percentage in BTC.
|
5
|
+
|
6
|
+
Sign up for your account at https://bitpay.com.
|
7
|
+
For development and testing against the bitcoin testnet, sign up at https://test.bitpay.com.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'spree-bitpay'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install spree-bitpay
|
22
|
+
|
23
|
+
Then run
|
24
|
+
|
25
|
+
$ rails generate spree-bitpay:install
|
26
|
+
|
27
|
+
The BitPay Spree connector receives RESTful confirmation callbacks at the `bitpay_notification_url` (typically `http://<host>/spree_bitpay/notification`). **This route must be available to receive messages from https://bitpay.com for proper operation**. This may require changes to your network configuration if your server is behind a firewall. The connector has been implemented to verify any callbacks received at this route, to prevent fraudulent/spoof messages.
|
28
|
+
|
29
|
+
## Application Configuration
|
30
|
+
|
31
|
+
Once installed, configure the BitPay payment method by logging into the Admin console by browsing to Configuration > Payment Methods.
|
32
|
+
|
33
|
+
Click the "+ New Payment Method" button and choose the provider titled `Spree::PaymentMethod::Bitpay`. Type a unique name that will be displayed to users when selecting a payment method.
|
34
|
+
|
35
|
+
Once you click the "Create" button there will be two additional parameters that should be completed. Input your API Key from your Bitpay dashboard, and specify an API endpoint. For production you should use `https://bitpay.com/api`, while for testing purposes you can use `https://test.bitpay.com/api` which will monitor for payments on the bitcoin testnet. Note that you must have a separate account and API Key for test.bitpay.com.
|
36
|
+
|
37
|
+
## User Experience
|
38
|
+
|
39
|
+
Once installed and configured, users will be able to select Bitcoin on the Payment step of the Checkout process.
|
40
|
+
|
41
|
+
![BTC Invoice](http://heisler3030.github.io/PaymentType.png)
|
42
|
+
|
43
|
+
After confirming their order details, users are presented with a modal Bitcoin invoice for payment.
|
44
|
+
|
45
|
+
![BTC Invoice](http://heisler3030.github.io/BTCInvoice.png)
|
46
|
+
|
47
|
+
When the payment is detected on the Bitcoin network, the modal will update and allow them to continue to the confirmation page.
|
48
|
+
|
49
|
+
![BTC Invoice Confirmed](http://heisler3030.github.io/BTCInvoiceConfirmed.png)
|
50
|
+
|
51
|
+
## Backend Processing
|
52
|
+
|
53
|
+
When a user selects Bitcoin as a payment method, a new `Payment` is created, in `checkout` state, along with a new `BitpayInvoice`, which links to the invoiceID created at BitPay.com.
|
54
|
+
|
55
|
+
In the event Bitcoin checkout is abandoned or the invoice expires, the `Payment` is marked `invalid`.
|
56
|
+
|
57
|
+
When a payment is detected on the Bitcoin network, the `Payment` is marked `pending`, and the `Order` is set `complete`. The user is presented with a confirmation screen.
|
58
|
+
|
59
|
+
When the Bitcoin transaction is fully confirmed according to your BitPay [transaction speed settings](https://bitpay.com/order-settings), a callback is delivered to the `bitpay_notification_url`, and verified with the BitPay server. At this stage the payment will be marked `complete`, and the fullfillment can proceed.
|
60
|
+
|
61
|
+
At any point, the details and current status of a BitPay payment can be viewed by clicking on the payment in the order detail screen
|
62
|
+
|
63
|
+
![BTC Invoice Confirmed](http://heisler3030.github.io/InvoiceDetails.png)
|
64
|
+
|
65
|
+
|
66
|
+
## Plugin Testing
|
67
|
+
|
68
|
+
The BitPay Spree connector uses RSpec, Capybara, and Poltergeist to perform integration testing. To set up and run the tests, you must install PhantomJS, as described [here](https://github.com/teampoltergeist/poltergeist#installing-phantomjs). Then execute the following steps:
|
69
|
+
|
70
|
+
export BITPAYKEY=<your test.bitpay.com api key here>
|
71
|
+
bundle install
|
72
|
+
./testapp.sh
|
73
|
+
rake
|
74
|
+
|
75
|
+
## Support
|
76
|
+
|
77
|
+
Questions? Comments? Suggestions?
|
78
|
+
|
79
|
+
Contact us at support@bitpay.com
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'spree/testing_support/extension_rake'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
|
+
task :default do
|
10
|
+
if Dir["spec/dummy"].empty?
|
11
|
+
Rake::Task[:test_app].invoke
|
12
|
+
Dir.chdir("../../")
|
13
|
+
end
|
14
|
+
Rake::Task[:spec].invoke
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generates a dummy app for testing'
|
18
|
+
task :test_app do
|
19
|
+
ENV['LIB_NAME'] = 'spree_bitpay'
|
20
|
+
Rake::Task['extension:test_app'].invoke
|
21
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
.idea/*
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"name": "easyModal.js",
|
3
|
+
"version": "1.3.1",
|
4
|
+
"homepage": "http://flaviusmatis.github.io/easyModal.js/",
|
5
|
+
"authors": [
|
6
|
+
"Flavius Matis"
|
7
|
+
],
|
8
|
+
"description": "A minimal jQuery modal that works with your CSS.",
|
9
|
+
"main": "jquery.easyModal.js",
|
10
|
+
"ignore": [
|
11
|
+
"**/.*",
|
12
|
+
"node_modules",
|
13
|
+
"bower_components",
|
14
|
+
"test",
|
15
|
+
"tests"
|
16
|
+
],
|
17
|
+
"dependencies": {
|
18
|
+
"jQuery": ">=1.7.0"
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,161 @@
|
|
1
|
+
/**
|
2
|
+
* easyModal.js v1.3.1
|
3
|
+
* A minimal jQuery modal that works with your CSS.
|
4
|
+
* Author: Flavius Matis - http://flaviusmatis.github.com/
|
5
|
+
* URL: https://github.com/flaviusmatis/easyModal.js
|
6
|
+
*/
|
7
|
+
|
8
|
+
/*jslint browser: true*/
|
9
|
+
/*global jQuery*/
|
10
|
+
|
11
|
+
(function ($) {
|
12
|
+
"use strict";
|
13
|
+
var methods = {
|
14
|
+
init: function (options) {
|
15
|
+
|
16
|
+
var defaults = {
|
17
|
+
top: 'auto',
|
18
|
+
autoOpen: false,
|
19
|
+
overlayOpacity: 0.5,
|
20
|
+
overlayColor: '#000',
|
21
|
+
overlayClose: true,
|
22
|
+
overlayParent: 'body',
|
23
|
+
closeOnEscape: true,
|
24
|
+
closeButtonClass: '.close',
|
25
|
+
transitionIn: '',
|
26
|
+
transitionOut: '',
|
27
|
+
onOpen: false,
|
28
|
+
onClose: false,
|
29
|
+
zIndex: function () {
|
30
|
+
return (function (value) {
|
31
|
+
return value === -Infinity ? 0 : value + 1;
|
32
|
+
}(Math.max.apply(Math, $.makeArray($('*').map(function () {
|
33
|
+
return $(this).css('z-index');
|
34
|
+
}).filter(function () {
|
35
|
+
return $.isNumeric(this);
|
36
|
+
}).map(function () {
|
37
|
+
return parseInt(this, 10);
|
38
|
+
})))));
|
39
|
+
},
|
40
|
+
updateZIndexOnOpen: true
|
41
|
+
};
|
42
|
+
|
43
|
+
options = $.extend(defaults, options);
|
44
|
+
|
45
|
+
return this.each(function () {
|
46
|
+
|
47
|
+
var o = options,
|
48
|
+
$overlay = $('<div class="lean-overlay"></div>'),
|
49
|
+
$modal = $(this);
|
50
|
+
|
51
|
+
$overlay.css({
|
52
|
+
'display': 'none',
|
53
|
+
'position': 'fixed',
|
54
|
+
// When updateZIndexOnOpen is set to true, we avoid computing the z-index on initialization,
|
55
|
+
// because the value would be replaced when opening the modal.
|
56
|
+
'z-index': (o.updateZIndexOnOpen ? 0 : o.zIndex()),
|
57
|
+
'top': 0,
|
58
|
+
'left': 0,
|
59
|
+
'height': '100%',
|
60
|
+
'width': '100%',
|
61
|
+
'background': o.overlayColor,
|
62
|
+
'opacity': o.overlayOpacity,
|
63
|
+
'overflow': 'auto'
|
64
|
+
}).appendTo(o.overlayParent);
|
65
|
+
|
66
|
+
$modal.css({
|
67
|
+
'display': 'none',
|
68
|
+
'position' : 'fixed',
|
69
|
+
// When updateZIndexOnOpen is set to true, we avoid computing the z-index on initialization,
|
70
|
+
// because the value would be replaced when opening the modal.
|
71
|
+
'z-index': (o.updateZIndexOnOpen ? 0 : o.zIndex() + 1),
|
72
|
+
'left' : 50 + '%',
|
73
|
+
'top' : parseInt(o.top, 10) > -1 ? o.top + 'px' : 50 + '%'
|
74
|
+
});
|
75
|
+
|
76
|
+
$modal.bind('openModal', function () {
|
77
|
+
var overlayZ = o.updateZIndexOnOpen ? o.zIndex() : parseInt($overlay.css('z-index'), 10),
|
78
|
+
modalZ = overlayZ + 1;
|
79
|
+
|
80
|
+
if(o.transitionIn !== '' && o.transitionOut !== ''){
|
81
|
+
$modal.removeClass(o.transitionOut).addClass(o.transitionIn);
|
82
|
+
}
|
83
|
+
$modal.css({
|
84
|
+
'display' : 'block',
|
85
|
+
'margin-left' : -($modal.outerWidth() / 2) + 'px',
|
86
|
+
'margin-top' : (parseInt(o.top, 10) > -1 ? 0 : -($modal.outerHeight() / 2)) + 'px',
|
87
|
+
'z-index': modalZ
|
88
|
+
});
|
89
|
+
|
90
|
+
$overlay.css({'z-index': overlayZ, 'display': 'block'});
|
91
|
+
|
92
|
+
if (o.onOpen && typeof o.onOpen === 'function') {
|
93
|
+
// onOpen callback receives as argument the modal window
|
94
|
+
o.onOpen($modal[0]);
|
95
|
+
}
|
96
|
+
});
|
97
|
+
|
98
|
+
$modal.bind('closeModal', function () {
|
99
|
+
if(o.transitionIn !== '' && o.transitionOut !== ''){
|
100
|
+
$modal.removeClass(o.transitionIn).addClass(o.transitionOut);
|
101
|
+
$modal.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
|
102
|
+
$modal.css('display', 'none');
|
103
|
+
$overlay.css('display', 'none');
|
104
|
+
});
|
105
|
+
}
|
106
|
+
else {
|
107
|
+
$modal.css('display', 'none');
|
108
|
+
$overlay.css('display', 'none');
|
109
|
+
}
|
110
|
+
if (o.onClose && typeof o.onClose === 'function') {
|
111
|
+
// onClose callback receives as argument the modal window
|
112
|
+
o.onClose($modal[0]);
|
113
|
+
}
|
114
|
+
});
|
115
|
+
|
116
|
+
// Close on overlay click
|
117
|
+
$overlay.click(function () {
|
118
|
+
if (o.overlayClose) {
|
119
|
+
$modal.trigger('closeModal');
|
120
|
+
}
|
121
|
+
});
|
122
|
+
|
123
|
+
$(document).keydown(function (e) {
|
124
|
+
// ESCAPE key pressed
|
125
|
+
if (o.closeOnEscape && e.keyCode === 27) {
|
126
|
+
$modal.trigger('closeModal');
|
127
|
+
}
|
128
|
+
});
|
129
|
+
|
130
|
+
// Close when button pressed
|
131
|
+
$modal.on('click', o.closeButtonClass, function (e) {
|
132
|
+
$modal.trigger('closeModal');
|
133
|
+
e.preventDefault();
|
134
|
+
});
|
135
|
+
|
136
|
+
// Automatically open modal if option set
|
137
|
+
if (o.autoOpen) {
|
138
|
+
$modal.trigger('openModal');
|
139
|
+
}
|
140
|
+
|
141
|
+
});
|
142
|
+
|
143
|
+
}
|
144
|
+
};
|
145
|
+
|
146
|
+
$.fn.easyModal = function (method) {
|
147
|
+
|
148
|
+
// Method calling logic
|
149
|
+
if (methods[method]) {
|
150
|
+
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
151
|
+
}
|
152
|
+
|
153
|
+
if (typeof method === 'object' || !method) {
|
154
|
+
return methods.init.apply(this, arguments);
|
155
|
+
}
|
156
|
+
|
157
|
+
$.error('Method ' + method + ' does not exist on jQuery.easyModal');
|
158
|
+
|
159
|
+
};
|
160
|
+
|
161
|
+
}(jQuery));
|
@@ -0,0 +1,86 @@
|
|
1
|
+
// BitPay Payment Methods
|
2
|
+
//= require spree/frontend
|
3
|
+
|
4
|
+
var Bitpay = {
|
5
|
+
|
6
|
+
reasonableInterval: 2000,
|
7
|
+
|
8
|
+
checkout: function(e) {
|
9
|
+
e.preventDefault();
|
10
|
+
Bitpay.iframeUrl = $.ajax({url: Bitpay.invoiceUrl, async: false}).responseText
|
11
|
+
$('#bitpay_invoice_iframe').attr("src", Bitpay.iframeUrl);
|
12
|
+
$('#bitpay_checkout_modal').trigger('openModal');
|
13
|
+
setTimeout(function(){ Bitpay.checkForUpdates()}, Bitpay.reasonableInterval);
|
14
|
+
return false;
|
15
|
+
},
|
16
|
+
|
17
|
+
checkForUpdates: function() {
|
18
|
+
invId = Bitpay._retrieveInvoiceIdFromURI();
|
19
|
+
url = Bitpay.checkUrl;
|
20
|
+
$.ajax({
|
21
|
+
url: url,
|
22
|
+
data: {invoice_id: invId},
|
23
|
+
dataType: "json",
|
24
|
+
complete: function(json) { Bitpay.getInvoiceState(json.responseText) }
|
25
|
+
});
|
26
|
+
return false
|
27
|
+
},
|
28
|
+
|
29
|
+
continueToConfirmation: function() {
|
30
|
+
// Backend will validate actual invoice payment
|
31
|
+
$('#continue_to_invoice').removeAttr("disabled");
|
32
|
+
$('#continue_to_invoice').attr("class", "continue button primary");
|
33
|
+
$('#choose_another_method').attr("class", "button disabled");
|
34
|
+
$('#choose_another_method').attr("disabled", "disabled");
|
35
|
+
$('#instructions').hide();
|
36
|
+
$('#completed').show();
|
37
|
+
},
|
38
|
+
|
39
|
+
finishCheckout: function(message) {
|
40
|
+
// Limit to messages from apiEndpoint
|
41
|
+
if (Bitpay.apiEndpoint && Bitpay.apiEndpoint.lastIndexOf(message.origin, 0) == 0) {
|
42
|
+
switch(message.data.status) {
|
43
|
+
case "new":
|
44
|
+
break;
|
45
|
+
case "paid":
|
46
|
+
case "confirmed":
|
47
|
+
Bitpay.continueToConfirmation();
|
48
|
+
break;
|
49
|
+
case "expired":
|
50
|
+
Bitpay.showExpiredMessage();
|
51
|
+
break;
|
52
|
+
default:
|
53
|
+
console.log("Unexpected message type: " + message.data.status)
|
54
|
+
}
|
55
|
+
}
|
56
|
+
return false;
|
57
|
+
},
|
58
|
+
|
59
|
+
getInvoiceState: function(invoiceState) {
|
60
|
+
if(invoiceState == "new"){
|
61
|
+
var timeout = setTimeout(function(){ Bitpay.checkForUpdates() }, Bitpay.reasonableInterval);
|
62
|
+
} else {
|
63
|
+
Bitpay.refreshCheckout();
|
64
|
+
}
|
65
|
+
},
|
66
|
+
|
67
|
+
refreshCheckout: function() {
|
68
|
+
$('#bitpay_invoice_iframe').attr("src", Bitpay.iframeUrl);
|
69
|
+
return false;
|
70
|
+
},
|
71
|
+
|
72
|
+
showExpiredMessage: function() {
|
73
|
+
$('#instructions').hide();
|
74
|
+
$('#expired').show();
|
75
|
+
},
|
76
|
+
|
77
|
+
_retrieveInvoiceIdFromURI: function() {
|
78
|
+
var parser = document.createElement('a');
|
79
|
+
parser.href = Bitpay.iframeUrl;
|
80
|
+
var search = parser.search;
|
81
|
+
Bitpay.invoiceId = search.replace(/^\?/,'').split('&')[0].split('=')[1];
|
82
|
+
return Bitpay.invoiceId;
|
83
|
+
}
|
84
|
+
|
85
|
+
}
|
86
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/*
|
2
|
+
*= require spree/frontend
|
3
|
+
*/
|
4
|
+
// Bitpay Payment Method styling
|
5
|
+
|
6
|
+
// No idea why this element is needed but it seems the first entry is ignored??
|
7
|
+
// TODO: Is this really needed?
|
8
|
+
|
9
|
+
#throwaway {
|
10
|
+
width: 20px;
|
11
|
+
}
|
12
|
+
|
13
|
+
#bitpay_modal_content {
|
14
|
+
padding:40px;
|
15
|
+
background-color: #FFF;
|
16
|
+
}
|
17
|
+
|
18
|
+
#bitpay_invoice_iframe {
|
19
|
+
width: 500px;
|
20
|
+
//height: 150px;
|
21
|
+
border: 1px solid #d9d9db;
|
22
|
+
overflow: hidden;
|
23
|
+
padding:20px;
|
24
|
+
max-width: 100%;
|
25
|
+
}
|
26
|
+
|
27
|
+
|
28
|
+
#bitpay_view_invoice_iframe {
|
29
|
+
width: 542px;
|
30
|
+
//height: 150px;
|
31
|
+
border: 1px solid #d9d9db;
|
32
|
+
overflow: hidden;
|
33
|
+
padding:20px;
|
34
|
+
max-width: 100%;
|
35
|
+
}
|
36
|
+
|
37
|
+
#bitpay_checkout_guidance {
|
38
|
+
text-align: center;
|
39
|
+
margin: auto;
|
40
|
+
}
|
41
|
+
|
42
|
+
#bitpay_payment_buttons {
|
43
|
+
padding-top: 10px;
|
44
|
+
text-align: center;
|
45
|
+
}
|
46
|
+
|
47
|
+
a.button.disabled {
|
48
|
+
background-color: #727276;
|
49
|
+
border-color: #59595c;
|
50
|
+
color: #CCC;
|
51
|
+
opacity: .65;
|
52
|
+
pointer-events: none;
|
53
|
+
}
|
54
|
+
|
55
|
+
.bitpay_invoice_details {
|
56
|
+
padding-top: 20px;
|
57
|
+
padding-bottom: 20px;
|
58
|
+
}
|