nimbleshop_splitable 0.0.1.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -0
- data/app/assets/images/splitable.png +0 -0
- data/app/assets/images/splitable_big.png +0 -0
- data/app/assets/images/splitable_small.png +0 -0
- data/app/controllers/nimbleshop_splitable/payments_controller.rb +17 -0
- data/app/controllers/nimbleshop_splitable/splitables_controller.rb +60 -0
- data/app/helpers/nimbleshop_splitable/exposed_helper.rb +36 -0
- data/app/models/nimbleshop_splitable/splitable.rb +16 -0
- data/app/views/nimbleshop_splitable/payments/_new.html.erb +23 -0
- data/app/views/nimbleshop_splitable/splitables/_edit.html.erb +36 -0
- data/app/views/nimbleshop_splitable/splitables/_form.html.erb +47 -0
- data/config/routes.rb +8 -0
- data/lib/nimbleshop_splitable/engine.rb +17 -0
- data/lib/nimbleshop_splitable/gateway.rb +74 -0
- data/lib/nimbleshop_splitable/processor.rb +96 -0
- data/lib/nimbleshop_splitable/version.rb +3 -0
- data/lib/nimbleshop_splitable.rb +6 -0
- data/lib/tasks/mock_callback.rake +29 -0
- data/lib/tasks/nimbleshop_splitable_tasks.rake +32 -0
- metadata +80 -0
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# nimbleshop_splitable extension
|
2
|
+
|
3
|
+
This is Splitable extension for [nimbleShop](http://nimbleShop.org) .
|
4
|
+
|
5
|
+
# Documentation
|
6
|
+
|
7
|
+
Documentation is available at [http://nimbleshop.org/](http://nimbleshop.org) .
|
8
|
+
|
9
|
+
# License
|
10
|
+
|
11
|
+
nimbleshop_splitable uses [MIT license](http://www.opensource.org/licenses/mit-license.php) .
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module NimbleshopSplitable
|
2
|
+
class PaymentsController < ::ActionController::Base
|
3
|
+
|
4
|
+
def create
|
5
|
+
order = Order.find_by_id(session[:order_id])
|
6
|
+
processor = NimbleshopSplitable::Processor.new(order: order)
|
7
|
+
error, url = processor.create_split(request: request)
|
8
|
+
|
9
|
+
respond_to do |format|
|
10
|
+
format.html do
|
11
|
+
error ? render(text: error) : redirect_to(url)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module NimbleshopSplitable
|
2
|
+
class SplitablesController < ::Admin::PaymentMethodsController
|
3
|
+
|
4
|
+
protect_from_forgery except: [:notify]
|
5
|
+
|
6
|
+
before_filter :load_payment_method
|
7
|
+
|
8
|
+
def notify
|
9
|
+
Rails.logger.info "splitable callback received: #{params.to_yaml}"
|
10
|
+
|
11
|
+
processor = NimbleshopSplitable::Processor.new(invoice: params[:invoice])
|
12
|
+
|
13
|
+
if processor.acknowledge(params)
|
14
|
+
render nothing: true
|
15
|
+
else
|
16
|
+
Rails.logger.info "webhook with data #{params.to_yaml} was rejected. error: #{processor.errors.join(',')}"
|
17
|
+
render "error: #{error}", status: 403
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
respond_to do |format|
|
23
|
+
if @payment_method.update_attributes(post_params[:splitable])
|
24
|
+
format.js {
|
25
|
+
flash[:notice] = "Splitable record was successfully updated"
|
26
|
+
render js: "window.location = '/admin/payment_methods'"
|
27
|
+
}
|
28
|
+
else
|
29
|
+
msg = @payment_method.errors.full_messages.first
|
30
|
+
error = %Q[alert("#{msg}")]
|
31
|
+
format.js { render js: error }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy
|
37
|
+
respond_to do |format|
|
38
|
+
if @payment_method.destroy
|
39
|
+
format.js {
|
40
|
+
flash[:notice] = "Splitable record was successfully deleted"
|
41
|
+
render js: "window.location = '/admin/payment_methods'" #TODO hardcoded url
|
42
|
+
}
|
43
|
+
else
|
44
|
+
format.js { render js: 'Splitable record could not be deleted. Please try again later.' }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def post_params
|
52
|
+
params.permit(splitable: [ :api_key, :api_secret, :expires_in, :mode] )
|
53
|
+
end
|
54
|
+
|
55
|
+
def load_payment_method
|
56
|
+
@payment_method = NimbleshopSplitable::Splitable.first
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module NimbleshopSplitable
|
2
|
+
module ExposedHelper
|
3
|
+
|
4
|
+
def nimbleshop_splitable_small_image( options = {} )
|
5
|
+
image_tag "engines/nimbleshop_splitable/splitable_small.png", {alt: 'splitable icon'}.merge(options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def nimbleshop_splitable_big_image(options = {})
|
9
|
+
image_tag "engines/nimbleshop_splitable/splitable_big.png", { alt: 'splitable logo' }.merge(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def nimbleshop_splitable_image()
|
13
|
+
image_tag "engines/nimbleshop_splitable/splitable.png", alt: 'splitable logo'
|
14
|
+
end
|
15
|
+
|
16
|
+
def nimbleshop_splitable_available_payment_options_icons
|
17
|
+
return unless NimbleshopSplitable::Splitable.first
|
18
|
+
nimbleshop_splitable_small_image
|
19
|
+
end
|
20
|
+
|
21
|
+
def nimbleshop_splitable_payment_form(order)
|
22
|
+
return unless NimbleshopSplitable::Splitable.first
|
23
|
+
render partial: '/nimbleshop_splitable/payments/new', locals: {order: order}
|
24
|
+
end
|
25
|
+
|
26
|
+
def nimbleshop_splitable_crud_form
|
27
|
+
return unless NimbleshopSplitable::Splitable.first
|
28
|
+
render partial: '/nimbleshop_splitable/splitables/edit'
|
29
|
+
end
|
30
|
+
|
31
|
+
def nimbleshop_splitable_icon_for_order_payment(order)
|
32
|
+
nimbleshop_splitable_small_image height: '10px'
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module NimbleshopSplitable
|
2
|
+
class Splitable < PaymentMethod
|
3
|
+
|
4
|
+
store_accessor :metadata, :api_key, :api_secret, :expires_in, :mode
|
5
|
+
|
6
|
+
validates_presence_of :api_key
|
7
|
+
|
8
|
+
before_save :set_mode
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def set_mode
|
13
|
+
self.mode ||= 'test'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<label class='radio'>
|
2
|
+
<%= radio_button_tag 'payment_choice', 'splitable' %>
|
3
|
+
<%= nimbleshop_splitable_image() %>
|
4
|
+
</label>
|
5
|
+
|
6
|
+
<%= form_for NimbleshopSplitable::Splitable.new, url: nimbleshop_splitable.payment_path, html: { id: 'splitable-payment-form',
|
7
|
+
class: 'form-horizontal' } do |f| %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= javascript_tag do %>
|
11
|
+
$(function() {
|
12
|
+
$("input#payment_choice_splitable:radio").change(function() {
|
13
|
+
var $this, val;
|
14
|
+
$this = $(this);
|
15
|
+
val = $this.val();
|
16
|
+
|
17
|
+
if (val === "splitable") {
|
18
|
+
$("form#splitable-payment-form").submit();
|
19
|
+
}
|
20
|
+
|
21
|
+
});
|
22
|
+
});
|
23
|
+
<% end %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<div class='payment-method-engine-well'>
|
2
|
+
|
3
|
+
<div>
|
4
|
+
<h2> Splitable </h2>
|
5
|
+
|
6
|
+
<div class="edit_link">
|
7
|
+
<%= link_to 'Edit', '#', class: "nimbleshop-payment-method-edit", id: "nimbleshop-splitable-payment-method-edit" %>
|
8
|
+
<%= link_to nimbleshop_splitable.splitable_path, confirm: 'Do you really want to delete Authorize.net payment method',
|
9
|
+
class: 'nimbleshop-payment-method-delete',
|
10
|
+
method: :delete,
|
11
|
+
remote: true do %>
|
12
|
+
<i class='icon-remove icon-white'></i>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<%= nimbleshop_splitable_big_image %>
|
17
|
+
|
18
|
+
<div class='clear'></div>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
|
22
|
+
<%= render partial: '/nimbleshop_splitable/splitables/form' %>
|
23
|
+
|
24
|
+
</div>
|
25
|
+
|
26
|
+
<script>
|
27
|
+
$(function(){
|
28
|
+
|
29
|
+
$('#nimbleshop-splitable-payment-method-edit').toggle(function(){
|
30
|
+
$('#nimbleshop-splitable-form-well').show();
|
31
|
+
}, function(){
|
32
|
+
$('#nimbleshop-splitable-form-well').hide();
|
33
|
+
});
|
34
|
+
|
35
|
+
})
|
36
|
+
</script>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<div class='well nimbleshop-payment-method-form-well' id='nimbleshop-splitable-form-well' style='display:none;'>
|
2
|
+
|
3
|
+
<%= form_for NimbleshopSplitable::Splitable.first, url: '/nimbleshop_splitable/splitable',
|
4
|
+
remote: true,
|
5
|
+
html: { method: 'put',
|
6
|
+
id: 'nimbleshop-splitable-form',
|
7
|
+
class: 'nimbleshop-payment-method-form form-horizontal'} do |f| %>
|
8
|
+
|
9
|
+
<fieldset>
|
10
|
+
<div class="control-group">
|
11
|
+
<%= f.label :api_key, nil, class: 'control-label' %>
|
12
|
+
<div class="controls">
|
13
|
+
<%= f.text_field :api_key, class: 'span6' %>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div class="control-group">
|
18
|
+
<%= f.label :api_secret, nil, class: 'control-label' %>
|
19
|
+
<div class="controls">
|
20
|
+
<%= f.text_field :api_secret, class: 'span6' %>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="control-group">
|
25
|
+
<%= f.label :expires_in, nil, class: 'control-label' %>
|
26
|
+
<div class="controls">
|
27
|
+
<%= f.text_field :expires_in, class: 'span6' %>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<div class="control-group">
|
32
|
+
<div class="controls">
|
33
|
+
<label class='checkbox'>
|
34
|
+
<%= f.check_box :mode, {}, 'test', 'production' %> Enable test mode
|
35
|
+
</label>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
</fieldset>
|
40
|
+
|
41
|
+
<div class="form-actions">
|
42
|
+
<%= f.submit('Submit', class: 'btn btn-primary') %>
|
43
|
+
|
44
|
+
<%= link_to t(:cancel), nimbleshop_splitable.splitable_path, class: 'cancel btn' %>
|
45
|
+
</div>
|
46
|
+
<% end %>
|
47
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module NimbleshopSplitable
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
|
4
|
+
isolate_namespace NimbleshopSplitable
|
5
|
+
|
6
|
+
config.to_prepare do
|
7
|
+
::NimbleshopSplitable::Splitable
|
8
|
+
end
|
9
|
+
|
10
|
+
initializer 'nimbleshop_splitable_engine.action_controller' do |app|
|
11
|
+
ActiveSupport.on_load :action_controller do
|
12
|
+
helper NimbleshopSplitable::ExposedHelper
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module NimbleshopSplitable
|
2
|
+
class Gateway
|
3
|
+
include ActiveMerchant::PostsData
|
4
|
+
|
5
|
+
class_attribute :live_url, :test_url
|
6
|
+
self.live_url = 'https://www.splitable.com/api/splits'
|
7
|
+
self.test_url = 'https://www.splitable-draft.com/api/splits'
|
8
|
+
|
9
|
+
def initialize(splitable)
|
10
|
+
@api_key = splitable.api_key
|
11
|
+
@expires_in = splitable.expires_in
|
12
|
+
@mode = splitable.mode
|
13
|
+
end
|
14
|
+
|
15
|
+
def api_notify_url(request)
|
16
|
+
Util.localhost2public_url( '/nimbleshop_splitable/splitable/notify', 'http' )
|
17
|
+
end
|
18
|
+
|
19
|
+
def create(order, request)
|
20
|
+
params = build_params(order, request)
|
21
|
+
|
22
|
+
params[:api_key] = @api_key
|
23
|
+
params[:api_notify_url] = api_notify_url(request)
|
24
|
+
params[:expires_in] = @expires_in
|
25
|
+
|
26
|
+
unless Rails.env.production?
|
27
|
+
Rails.logger.info "params to be posted: #{params.inspect}"
|
28
|
+
end
|
29
|
+
|
30
|
+
url = test? ? self.test_url : self.live_url
|
31
|
+
params = params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
32
|
+
|
33
|
+
ssl_post(url, params)
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_params(order, request)
|
37
|
+
params = {}
|
38
|
+
add_order_data(params, order)
|
39
|
+
add_product_data(params, order.line_items, request)
|
40
|
+
params
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_order_data(params, order)
|
44
|
+
params[:total_amount] = order.total_amount_in_cents
|
45
|
+
params[:invoice] = order.number
|
46
|
+
params[:shipping] = Util.in_cents(ShippingCostCalculator.new(order).shipping_cost)
|
47
|
+
params[:tax] = Util.in_cents(TaxCalculator.new(order).tax)
|
48
|
+
params[:description] = 'See Splitable integrates nicely with nimbleShop'
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_product_data(params, products, request)
|
52
|
+
products.each.with_index(1) do | item, index |
|
53
|
+
params.update(to_param(item, index, request))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def product_url(item, request)
|
58
|
+
request.protocol + request.host_with_port + "/products/#{item.product_permalink}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_param(item, index, request)
|
62
|
+
{
|
63
|
+
"amount_#{index}" => (item.price * 100).to_i,
|
64
|
+
"item_name_#{index}" => item.product_name,
|
65
|
+
"quantity_#{index}" => item.quantity,
|
66
|
+
"url_#{index}" => product_url(item, request)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def test?
|
71
|
+
@mode == 'test'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module NimbleshopSplitable
|
2
|
+
class Processor < ::Processor::Base
|
3
|
+
|
4
|
+
attr_reader :errors, :order, :payment_method
|
5
|
+
|
6
|
+
def gateway
|
7
|
+
::NimbleshopSplitable::Gateway.new(NimbleshopSplitable::Splitable.first)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
|
12
|
+
unless @order = options[:order]
|
13
|
+
invoice = options[:invoice].try(:to_s)
|
14
|
+
@order = Order.find_by_number(invoice)
|
15
|
+
end
|
16
|
+
|
17
|
+
@errors = []
|
18
|
+
@payment_method = NimbleshopSplitable::Splitable.first
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_split(options = {})
|
22
|
+
options.symbolize_keys!
|
23
|
+
options.assert_valid_keys(:request)
|
24
|
+
|
25
|
+
response = gateway.create(order, options[:request])
|
26
|
+
json = ActiveSupport::JSON.decode(response)
|
27
|
+
result = json.values_at('error','split_url')
|
28
|
+
if result.last
|
29
|
+
order.update_attributes(payment_method: payment_method)
|
30
|
+
order.pending
|
31
|
+
end
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
def acknowledge(params = {})
|
36
|
+
if valid?(params)
|
37
|
+
send(resolve_payment_kind(params[:payment_status]), params)
|
38
|
+
else
|
39
|
+
false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def resolve_payment_kind(payment_status)
|
46
|
+
payment_status == 'paid' ? 'purchase' : 'void'
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid?(params)
|
50
|
+
@errors.clear
|
51
|
+
validate_order
|
52
|
+
validate_params(params)
|
53
|
+
@errors.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate_order
|
57
|
+
unless order
|
58
|
+
@errors << "Unknown invoice number"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def validate_params(params = {})
|
63
|
+
|
64
|
+
unless params[:transaction_id]
|
65
|
+
@errors << "transaction_id is blank"
|
66
|
+
end
|
67
|
+
|
68
|
+
unless params[:payment_status]
|
69
|
+
@errors << "Parameter payment_status is blank"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def do_purchase(options = {})
|
74
|
+
add_to_order(options, 'purchased')
|
75
|
+
order.update_attributes(payment_method: payment_method)
|
76
|
+
order.purchase!
|
77
|
+
|
78
|
+
true
|
79
|
+
end
|
80
|
+
|
81
|
+
def do_void(options = {})
|
82
|
+
add_to_order(options, 'voided')
|
83
|
+
order.update_attributes(payment_method: payment_method)
|
84
|
+
order.void!
|
85
|
+
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_to_order(params, operation)
|
90
|
+
order.payment_transactions.create(operation: operation,
|
91
|
+
success: true,
|
92
|
+
transaction_gid: params[:transaction_id],
|
93
|
+
params: params)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# This is a rake task that simulates what splitable will POST as callback.
|
2
|
+
#
|
3
|
+
|
4
|
+
desc "sends callback"
|
5
|
+
|
6
|
+
namespace :nimbleshop_splitable do
|
7
|
+
task :mock_callback => :environment do
|
8
|
+
|
9
|
+
unless order_number = ENV['order_number']
|
10
|
+
puts "Usage: rake mock_callcak order_number=xxxxxxx"
|
11
|
+
abort
|
12
|
+
end
|
13
|
+
|
14
|
+
base_url = 'http://localhost:3000'
|
15
|
+
endpoint = base_url + '/nimbleshop_splitable/splitable/notify'
|
16
|
+
|
17
|
+
|
18
|
+
params = { invoice: order_number,
|
19
|
+
payment_status: "cancelled",
|
20
|
+
api_secret: "540f0849518d83d6",
|
21
|
+
transaction_id: "49c380175f3c5603287698a4" }
|
22
|
+
|
23
|
+
require "net/http"
|
24
|
+
require "uri"
|
25
|
+
uri = URI.parse(endpoint)
|
26
|
+
response = Net::HTTP.post_form(uri, params)
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
namespace :nimbleshop_splitable do
|
2
|
+
|
3
|
+
desc 'load splitable record'
|
4
|
+
task :load_record => :environment do
|
5
|
+
if NimbleshopSplitable::Splitable.find_by_permalink('splitable')
|
6
|
+
puts "Splitable record already exists"
|
7
|
+
else
|
8
|
+
NimbleshopSplitable::Splitable.create!(
|
9
|
+
{
|
10
|
+
api_secret: '92746e4d66cb8993',
|
11
|
+
expires_in: 24,
|
12
|
+
api_key: '92746e4d66cb8993',
|
13
|
+
name: 'Splitable',
|
14
|
+
permalink: 'splitable',
|
15
|
+
description: %Q[<p> Splitable helps split the cost of product with friends and family. </p> <p> <a href="http://splitable.com"> more information </a> </p>]
|
16
|
+
})
|
17
|
+
puts "Splitable record was successfuly created"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'copies images from engine to main rails application'
|
22
|
+
task :copy_images do
|
23
|
+
engine_name = 'nimbleshop_splitable'
|
24
|
+
origin = File.expand_path('../../app/assets/images', File.dirname(__FILE__))
|
25
|
+
destination = Rails.root.join('app', 'assets', 'images', 'engines', engine_name)
|
26
|
+
FileUtils.mkdir_p(destination) if !File.exist?(destination)
|
27
|
+
Dir[File.join(origin, '**/*')].each { |file| FileUtils.cp(file, File.join(destination) ) unless File.directory?(file) }
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nimbleshop_splitable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.rc1
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Neeraj Singh
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activemerchant
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Provides Splitable functionality to nimbleShop
|
31
|
+
email:
|
32
|
+
- neeraj@BigBinary.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- app/assets/images/splitable.png
|
38
|
+
- app/assets/images/splitable_big.png
|
39
|
+
- app/assets/images/splitable_small.png
|
40
|
+
- app/controllers/nimbleshop_splitable/payments_controller.rb
|
41
|
+
- app/controllers/nimbleshop_splitable/splitables_controller.rb
|
42
|
+
- app/helpers/nimbleshop_splitable/exposed_helper.rb
|
43
|
+
- app/models/nimbleshop_splitable/splitable.rb
|
44
|
+
- app/views/nimbleshop_splitable/payments/_new.html.erb
|
45
|
+
- app/views/nimbleshop_splitable/splitables/_edit.html.erb
|
46
|
+
- app/views/nimbleshop_splitable/splitables/_form.html.erb
|
47
|
+
- config/routes.rb
|
48
|
+
- lib/nimbleshop_splitable/engine.rb
|
49
|
+
- lib/nimbleshop_splitable/gateway.rb
|
50
|
+
- lib/nimbleshop_splitable/processor.rb
|
51
|
+
- lib/nimbleshop_splitable/version.rb
|
52
|
+
- lib/nimbleshop_splitable.rb
|
53
|
+
- lib/tasks/mock_callback.rake
|
54
|
+
- lib/tasks/nimbleshop_splitable_tasks.rake
|
55
|
+
- README.md
|
56
|
+
homepage: http://nimbleShop.org
|
57
|
+
licenses: []
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>'
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 1.3.1
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.8.23
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Splitable extension for Nimbleshop
|
80
|
+
test_files: []
|