spree_zaez_komerci 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +9 -0
- data/Guardfile +90 -0
- data/LICENSE +26 -0
- data/README.md +52 -0
- data/Rakefile +21 -0
- data/app/assets/images/rede-credit-cards/rede-dinersclub.png +0 -0
- data/app/assets/images/rede-credit-cards/rede-hipercard.png +0 -0
- data/app/assets/images/rede-credit-cards/rede-jcb.png +0 -0
- data/app/assets/images/rede-credit-cards/rede-mastercard.png +0 -0
- data/app/assets/images/rede-credit-cards/rede-visa.png +0 -0
- data/app/assets/javascripts/spree/backend/spree_zaez_komerci.js +1 -0
- data/app/assets/javascripts/spree/frontend/app/komerci_credit_card.js.coffee +26 -0
- data/app/assets/javascripts/spree/frontend/spree_zaez_komerci.js +1 -0
- data/app/assets/stylesheets/spree/frontend/spree_zaez_komerci.css +7 -0
- data/app/controllers/spree/admin/komerci_settings_controller.rb +20 -0
- data/app/models/spree/credit_card_decorator.rb +7 -0
- data/app/models/spree/komerci_transaction.rb +8 -0
- data/app/models/spree/payment/gateway_options_decorator.rb +14 -0
- data/app/models/spree/payment_method/komerci.rb +250 -0
- data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_komerci_settings_to_configuration_tab.html.erb.deface +2 -0
- data/app/views/spree/admin/komerci_settings/edit.html.erb +67 -0
- data/app/views/spree/admin/payments/source_forms/_komerci.html.erb +62 -0
- data/app/views/spree/admin/payments/source_views/_komerci.html.erb +33 -0
- data/app/views/spree/checkout/payment/_komerci.html.erb +62 -0
- data/bin/rails +7 -0
- data/config/locales/en.yml +31 -0
- data/config/locales/pt-br.yml +32 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20160630132716_add_portions_to_spree_payments.rb +5 -0
- data/db/migrate/20160630161016_create_spree_komerci_transaction.rb +14 -0
- data/db/migrate/20160701184408_add_payment_id_to_spree_komerci_transactions.rb +5 -0
- data/db/migrate/20160704120859_add_total_to_spree_komerci_transactions.rb +5 -0
- data/lib/generators/spree_zaez_komerci/install/install_generator.rb +30 -0
- data/lib/spree/komerci_configuration.rb +190 -0
- data/lib/spree_zaez_komerci/engine.rb +30 -0
- data/lib/spree_zaez_komerci/factories.rb +30 -0
- data/lib/spree_zaez_komerci.rb +5 -0
- data/spec/features/admin/komerci_actions_spec.rb +80 -0
- data/spec/features/admin/komerci_settings_spec.rb +77 -0
- data/spec/features/checkout_with_komerci_spec.rb +75 -0
- data/spec/fixtures/authorize_error.txt +14 -0
- data/spec/fixtures/authorize_success.txt +14 -0
- data/spec/fixtures/conf_authorize_error.txt +7 -0
- data/spec/fixtures/conf_authorize_success.txt +7 -0
- data/spec/fixtures/error.txt +1 -0
- data/spec/fixtures/void_error.txt +7 -0
- data/spec/fixtures/void_success.txt +7 -0
- data/spec/lib/spree/komerci_configuration_spec.rb +82 -0
- data/spec/models/spree/payment_method/komerci_spec.rb +206 -0
- data/spec/spec_helper.rb +99 -0
- data/spec/support/capybara_login.rb +11 -0
- data/spec/support/shared_contexts/checkout_setup.rb +9 -0
- data/spree_zaez_komerci.gemspec +42 -0
- data/vendor/assets/javascripts/jquery.payment.js +612 -0
- metadata +423 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
<div class="well clearfix">
|
2
|
+
<% param_prefix = "payment_source[#{payment_method.id}]" %>
|
3
|
+
|
4
|
+
<div class="row">
|
5
|
+
<div class="col-md-12 field">
|
6
|
+
<%= label_tag "name_on_card_#{payment_method.id}", Spree.t(:name_on_card) %><span class="required">*</span><br />
|
7
|
+
<%= text_field_tag "#{param_prefix}[name]", "#{@order.billing_firstname} #{@order.billing_lastname}",
|
8
|
+
{ id: "name_on_card_#{payment_method.id}", class: 'form-control required'} %>
|
9
|
+
</div>
|
10
|
+
<div class="col-md-12 field">
|
11
|
+
<%= label_tag 'card_number', Spree.t(:card_number) %><span class="required">*</span><br />
|
12
|
+
<% options_hash = Rails.env.production? ? {:autocomplete => 'off'} : {} %>
|
13
|
+
<%= text_field_tag "#{param_prefix}[number]", '', options_hash.merge(id: 'cielo_card_number',
|
14
|
+
class: 'form-control required cardNumber komerci-cc',
|
15
|
+
size: 19,
|
16
|
+
maxlength: 19,
|
17
|
+
autocomplete: 'off') %>
|
18
|
+
<span id="komerci_unrecognized" style="display:none;" class="error"><%= Spree.t(:unrecognized_card_type) %></span>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<div class="row">
|
22
|
+
<div class="col-md-8 field" data-hook="card_expiration">
|
23
|
+
<%= label_tag 'card_expiry', Spree.t(:expiration) %><span class="required">*</span><br />
|
24
|
+
<%= text_field_tag "#{param_prefix}[expiry]", '', id: 'card_expiry',
|
25
|
+
class: 'form-control required cardExpiry', placeholder: 'MM / YY' %>
|
26
|
+
</div>
|
27
|
+
<div class="col-md-4 field" data-hook="card_code">
|
28
|
+
<%= label_tag 'card_code', Spree.t(:card_code) %><span class="required">*</span><br />
|
29
|
+
<%= text_field_tag "#{param_prefix}[verification_value]", '', options_hash.merge(id: 'card_code',
|
30
|
+
class: 'form-control required cardCode',
|
31
|
+
size: 5) %>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
<div class="row komerci-info">
|
35
|
+
<% portions = Spree::KomerciConfig.calculate_portions @order %>
|
36
|
+
<div class="col-sm-10">
|
37
|
+
<% portions.each do |item| %>
|
38
|
+
<%
|
39
|
+
total = Spree::Money.new(item[:total], {currency: @order.currency}).to_html
|
40
|
+
value = Spree::Money.new(item[:value], {currency: @order.currency}).to_html
|
41
|
+
%>
|
42
|
+
<%= radio_button_tag 'order[payments_attributes][][portions]', item[:portion], item[:portion] == 1 %>
|
43
|
+
<%= Spree.t(:komerci_portions, times: item[:portion], value: value,
|
44
|
+
tax: Spree.t(item[:tax_message]), total: total) %><br />
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
<div class="col-sm-2" id="komerci_cc_type"></div>
|
48
|
+
</div>
|
49
|
+
|
50
|
+
<%= hidden_field_tag "#{param_prefix}[cc_type]", '', id: 'cc_type' %>
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<script type="text/javascript">
|
54
|
+
available_cc = {
|
55
|
+
visa: '<%= asset_url 'rede-credit-cards/rede-visa.png' %>',
|
56
|
+
mastercard: '<%= asset_url 'rede-credit-cards/rede-mastercard.png' %>',
|
57
|
+
dinersclub: '<%= asset_url 'rede-credit-cards/rede-dinersclub.png' %>',
|
58
|
+
hipercard: '<%= asset_url 'rede-credit-cards/rede-hipercard.png' %>',
|
59
|
+
jcb: '<%= asset_url 'rede-credit-cards/rede-jcb.png' %>'
|
60
|
+
};
|
61
|
+
new window.KomerciCreditCard(available_cc);
|
62
|
+
</script>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<fieldset data-hook="credit_card">
|
2
|
+
<legend><%= Spree.t(:credit_card) %></legend>
|
3
|
+
<table class="table table-condensed table-bordered">
|
4
|
+
<tr>
|
5
|
+
<th width="20%"><%= Spree.t(:name_on_card) %>:</th>
|
6
|
+
<td><%= payment.source.name %></td>
|
7
|
+
</tr>
|
8
|
+
<tr>
|
9
|
+
<th><%= Spree.t(:card_type) %>:</th>
|
10
|
+
<td><%= payment.source.cc_type %></td>
|
11
|
+
</tr>
|
12
|
+
<tr>
|
13
|
+
<th><%= Spree.t(:card_number) %>:</th>
|
14
|
+
<td><%= payment.source.display_number %></td>
|
15
|
+
</tr>
|
16
|
+
<tr>
|
17
|
+
<th><%= Spree.t(:expiration) %>:</th>
|
18
|
+
<td><%= payment.source.month %>/<%= payment.source.year %></td>
|
19
|
+
</tr>
|
20
|
+
<tr>
|
21
|
+
<th><%= Spree.t(:portions) %>:</th>
|
22
|
+
<td><%= "#{payment.portions}x" %></td>
|
23
|
+
</tr>
|
24
|
+
<tr>
|
25
|
+
<th><%= Spree.t(:transaction_id) %>:</th>
|
26
|
+
<td><%= payment.transaction_id %></td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<th><%= Spree.t(:number) %>:</th>
|
30
|
+
<td><%= "#{payment.order.number}-#{payment.id}" %></td>
|
31
|
+
</tr>
|
32
|
+
</table>
|
33
|
+
</fieldset>
|
@@ -0,0 +1,62 @@
|
|
1
|
+
<div class="well clearfix">
|
2
|
+
<% param_prefix = "payment_source[#{payment_method.id}]" %>
|
3
|
+
|
4
|
+
<div class="row">
|
5
|
+
<div class="col-md-12 field">
|
6
|
+
<%= label_tag "name_on_card_#{payment_method.id}", Spree.t(:name_on_card) %><span class="required">*</span><br />
|
7
|
+
<%= text_field_tag "#{param_prefix}[name]", "#{@order.billing_firstname} #{@order.billing_lastname}",
|
8
|
+
{ id: "name_on_card_#{payment_method.id}", class: 'form-control required'} %>
|
9
|
+
</div>
|
10
|
+
<div class="col-md-12 field">
|
11
|
+
<%= label_tag 'card_number', Spree.t(:card_number) %><span class="required">*</span><br />
|
12
|
+
<% options_hash = Rails.env.production? ? {:autocomplete => 'off'} : {} %>
|
13
|
+
<%= text_field_tag "#{param_prefix}[number]", '', options_hash.merge(id: 'cielo_card_number',
|
14
|
+
class: 'form-control required cardNumber komerci-cc',
|
15
|
+
size: 19,
|
16
|
+
maxlength: 19,
|
17
|
+
autocomplete: 'off') %>
|
18
|
+
<span id="komerci_unrecognized" style="display:none;" class="error"><%= Spree.t(:unrecognized_card_type) %></span>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<div class="row">
|
22
|
+
<div class="col-md-8 field" data-hook="card_expiration">
|
23
|
+
<%= label_tag 'card_expiry', Spree.t(:expiration) %><span class="required">*</span><br />
|
24
|
+
<%= text_field_tag "#{param_prefix}[expiry]", '', id: 'card_expiry',
|
25
|
+
class: 'form-control required cardExpiry', placeholder: 'MM / YY' %>
|
26
|
+
</div>
|
27
|
+
<div class="col-md-4 field" data-hook="card_code">
|
28
|
+
<%= label_tag 'card_code', Spree.t(:card_code) %><span class="required">*</span><br />
|
29
|
+
<%= text_field_tag "#{param_prefix}[verification_value]", '', options_hash.merge(id: 'card_code',
|
30
|
+
class: 'form-control required cardCode',
|
31
|
+
size: 5) %>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
<div class="row komerci-info">
|
35
|
+
<% portions = Spree::KomerciConfig.calculate_portions @order %>
|
36
|
+
<div class="col-sm-10">
|
37
|
+
<% portions.each do |item| %>
|
38
|
+
<%
|
39
|
+
total = Spree::Money.new(item[:total], {currency: @order.currency}).to_html
|
40
|
+
value = Spree::Money.new(item[:value], {currency: @order.currency}).to_html
|
41
|
+
%>
|
42
|
+
<%= radio_button_tag 'order[payments_attributes][][portions]', item[:portion], item[:portion] == 1 %>
|
43
|
+
<%= Spree.t(:komerci_portions, times: item[:portion], value: value,
|
44
|
+
tax: Spree.t(item[:tax_message]), total: total) %><br />
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
<div class="col-sm-2" id="komerci_cc_type"></div>
|
48
|
+
</div>
|
49
|
+
|
50
|
+
<%= hidden_field_tag "#{param_prefix}[cc_type]", '', id: 'cc_type' %>
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<script type="text/javascript">
|
54
|
+
available_cc = {
|
55
|
+
visa: '<%= asset_url 'rede-credit-cards/rede-visa.png' %>',
|
56
|
+
mastercard: '<%= asset_url 'rede-credit-cards/rede-mastercard.png' %>',
|
57
|
+
dinersclub: '<%= asset_url 'rede-credit-cards/rede-dinersclub.png' %>',
|
58
|
+
hipercard: '<%= asset_url 'rede-credit-cards/rede-hipercard.png' %>',
|
59
|
+
jcb: '<%= asset_url 'rede-credit-cards/rede-jcb.png' %>'
|
60
|
+
};
|
61
|
+
new window.KomerciCreditCard(available_cc);
|
62
|
+
</script>
|
data/bin/rails
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
2
|
+
|
3
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
4
|
+
ENGINE_PATH = File.expand_path('../../lib/spree_zaez_komerci/engine', __FILE__)
|
5
|
+
|
6
|
+
require 'rails/all'
|
7
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
en:
|
2
|
+
spree:
|
3
|
+
komerci_settings: Komerci Settings
|
4
|
+
settings: Settings
|
5
|
+
affiltion_key: Affilition Key
|
6
|
+
komerci_user: Komerci User
|
7
|
+
komerci_password: Password of Komerci User
|
8
|
+
test_mode: Enable Test Mode
|
9
|
+
minimum_value: Minimum Value
|
10
|
+
portion_without_tax: Portions Without Tax
|
11
|
+
max_portion: Quantity of Portions Supported
|
12
|
+
tax_value: Tax Value
|
13
|
+
portions_type: Portions Type
|
14
|
+
portions_type_06: Portions by Issuing
|
15
|
+
portions_type_08: Portions by Store
|
16
|
+
komerci_without_tax: without tax.
|
17
|
+
komerci_with_tax: with tax.
|
18
|
+
komerci_adjustment_tax: Credit Card Tax
|
19
|
+
komerci_portions: "%{times}x of %{value} %{tax} (total: %{total})"
|
20
|
+
komerci:
|
21
|
+
messages:
|
22
|
+
purchase_success: "Komerci: transaction purchased successfully"
|
23
|
+
authorize_success: "Komerci: transaction authorized successfully"
|
24
|
+
capture_success: "Komerci: captured successfully"
|
25
|
+
void_success: "Komerci: Voided successfully"
|
26
|
+
cancel_success: "Komerci: Canceled successfully"
|
27
|
+
invalid_portions: "Komerci: The number of portions is required"
|
28
|
+
activerecord:
|
29
|
+
attributes:
|
30
|
+
spree/payment:
|
31
|
+
portions: Portions
|
@@ -0,0 +1,32 @@
|
|
1
|
+
pt-BR:
|
2
|
+
spree:
|
3
|
+
komerci_settings: Configurações Komerci
|
4
|
+
settings: Configuraçcões
|
5
|
+
affiltion_key: Número de Filiação
|
6
|
+
komerci_user: Usuário Komerci
|
7
|
+
komerci_password: Senha
|
8
|
+
test_mode: Habilitar ambiente de teste
|
9
|
+
minimum_value: Valor mínimo da parcela
|
10
|
+
portion_without_tax: Parcelas sem juros
|
11
|
+
max_portion: Quantidade máxima de parcelas
|
12
|
+
tax_value: Valor do juros
|
13
|
+
portions_type: Tipo de parcelamento
|
14
|
+
portions_type_06: Parcelado pelo emissor
|
15
|
+
portions_type_08: Parcelado pelo estabelecimento
|
16
|
+
komerci_without_tax: sem juros.
|
17
|
+
komerci_with_tax: com juros.
|
18
|
+
komerci_adjustment_tax: Juros do Cartão de Crédito
|
19
|
+
komerci_portions: "%{times}x de %{value} %{tax} (total: %{total})"
|
20
|
+
komerci:
|
21
|
+
messages:
|
22
|
+
purchase_success: "Komerci: transação processada com sucesso"
|
23
|
+
authorize_success: "Komerci: transação autorizada com sucesso"
|
24
|
+
capture_success: "Komerci: Capturado com sucesso"
|
25
|
+
void_success: "Komerci: Estornado com sucesso"
|
26
|
+
cancel_success: "Komerci: Cancelado com sucesso"
|
27
|
+
cancel_error_date: "Komerci: O cancelamento deve ser realizado no Portal pois o período para cancelar pelo e-commerce se encerrou."
|
28
|
+
invalid_portions: "Komerci: O número de parcelas é requerido"
|
29
|
+
activerecord:
|
30
|
+
attributes:
|
31
|
+
spree/payment:
|
32
|
+
portions: Parcelas
|
data/config/routes.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateSpreeKomerciTransaction < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :spree_komerci_transactions do |t|
|
4
|
+
t.string :authorization_number
|
5
|
+
t.string :order_number
|
6
|
+
t.string :authentication_number
|
7
|
+
t.string :sequencial_number
|
8
|
+
t.string :bin
|
9
|
+
t.belongs_to :credit_card
|
10
|
+
|
11
|
+
t.timestamps null: false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SpreeZaezKomerci
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
class_option :auto_run_migrations, :type => :boolean, :default => false
|
6
|
+
|
7
|
+
def add_javascripts
|
8
|
+
append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/spree_zaez_komerci\n"
|
9
|
+
append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/spree_zaez_komerci\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_stylesheets
|
13
|
+
inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/spree_zaez_komerci\n", :before => /\*\//, :verbose => true
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_migrations
|
17
|
+
run 'bundle exec rake railties:install:migrations FROM=spree_zaez_komerci'
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_migrations
|
21
|
+
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
|
22
|
+
if run_migrations
|
23
|
+
run 'bundle exec rake db:migrate'
|
24
|
+
else
|
25
|
+
puts 'Skipping rake db:migrate, don\'t forget to run it!'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
class Spree::KomerciConfiguration < Spree::Preferences::Configuration
|
2
|
+
|
3
|
+
preference :afiliation_key, :string, default: '' # afiliation key
|
4
|
+
preference :komerci_user, :string, default: '' # Komerci user
|
5
|
+
preference :komerci_password, :string, default: '' # Password of Komerci user
|
6
|
+
preference :test_mode, :boolean, default: false # enable test mode
|
7
|
+
preference :minimum_value, :float, default: 5.0 # minimum value per portion (minimum is 5.00)
|
8
|
+
preference :tax_value, :float, default: 0.0 # tax value per month
|
9
|
+
preference :max_portion, :integer, default: 10 # quantity of portions supported
|
10
|
+
preference :portion_without_tax, :integer, default: 1 # number of portions without tax
|
11
|
+
preference :portions_type, :string, default: '06' # (04 = a vista, 06 = parcelado emissor, 08 = parcelado estabelecimento )
|
12
|
+
|
13
|
+
def authorize_uri
|
14
|
+
if preferred_test_mode
|
15
|
+
'https://ecommerce.userede.com.br/pos_virtual/wskomerci/cap_teste.asmx/GetAuthorizedTst'
|
16
|
+
else
|
17
|
+
'https://ecommerce.redecard.com.br/pos_virtual/wskomerci/cap.asmx/GetAuthorized'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def conf_authorization_uri
|
22
|
+
if preferred_test_mode
|
23
|
+
'https://ecommerce.userede.com.br/pos_virtual/wskomerci/cap_teste.asmx/ConfPreAuthorizationTst'
|
24
|
+
else
|
25
|
+
'https://ecommerce.redecard.com.br/pos_virtual/wskomerci/cap.asmx/ConfPreAuthorization'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def void_transaction_uri
|
30
|
+
if preferred_test_mode
|
31
|
+
'https://ecommerce.userede.com.br/pos_virtual/wskomerci/cap_teste.asmx/VoidTransactionTst'
|
32
|
+
else
|
33
|
+
'https://ecommerce.redecard.com.br/pos_virtual/wskomerci/cap.asmx/VoidTransaction'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def authorize(params)
|
38
|
+
response_xml = HTTParty.post(authorize_uri, body: params)
|
39
|
+
response = Hash.from_xml response_xml.body.gsub("\r\n ", '')
|
40
|
+
response = format_keys(response)
|
41
|
+
authorization = response[:authorization]
|
42
|
+
|
43
|
+
if authorization[:codret] == '0' and authorization[:numcv]
|
44
|
+
return {
|
45
|
+
success: true,
|
46
|
+
data: {
|
47
|
+
authorization_number: authorization[:numautor],
|
48
|
+
order_number: authorization[:numcv],
|
49
|
+
authentication_number: authorization[:numautent],
|
50
|
+
sequencial_number: authorization[:numsqn],
|
51
|
+
bin: authorization[:origem_bin]
|
52
|
+
}
|
53
|
+
}
|
54
|
+
else
|
55
|
+
return {
|
56
|
+
success: false,
|
57
|
+
data: {
|
58
|
+
error_number: authorization[:codret],
|
59
|
+
error_message: authorization[:msgret]
|
60
|
+
}
|
61
|
+
}
|
62
|
+
end
|
63
|
+
rescue REXML::ParseException
|
64
|
+
{
|
65
|
+
success: false,
|
66
|
+
data: {
|
67
|
+
error_message: response_xml.body.gsub("\r\n", '')
|
68
|
+
}
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def conf_authorize(params)
|
73
|
+
response_xml = HTTParty.post(conf_authorization_uri, body: params)
|
74
|
+
response = Hash.from_xml response_xml.body.gsub("\r\n ", '')
|
75
|
+
response = format_keys(response)
|
76
|
+
confirmation = response[:confirmation][:root]
|
77
|
+
|
78
|
+
if confirmation[:codret] == '0'
|
79
|
+
return { success: true }
|
80
|
+
else
|
81
|
+
return {
|
82
|
+
success: false,
|
83
|
+
data: {
|
84
|
+
error_number: confirmation[:codret],
|
85
|
+
error_message: confirmation[:msgret]
|
86
|
+
}
|
87
|
+
}
|
88
|
+
end
|
89
|
+
rescue REXML::ParseException
|
90
|
+
{
|
91
|
+
success: false,
|
92
|
+
data: {
|
93
|
+
error_message: response_xml.body.gsub("\r\n", '')
|
94
|
+
}
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def void_transaction params
|
99
|
+
response_xml = HTTParty.post(void_transaction_uri, body: params)
|
100
|
+
response = Hash.from_xml response_xml.body.gsub("\r\n ", '')
|
101
|
+
response = format_keys response
|
102
|
+
confirmation = response[:confirmation][:root]
|
103
|
+
|
104
|
+
if confirmation[:codret] == '0'
|
105
|
+
return { success: true }
|
106
|
+
else
|
107
|
+
return {
|
108
|
+
success: false,
|
109
|
+
data: {
|
110
|
+
error_number: confirmation[:codret],
|
111
|
+
error_message: confirmation[:msgret]
|
112
|
+
}
|
113
|
+
}
|
114
|
+
end
|
115
|
+
rescue REXML::ParseException
|
116
|
+
{
|
117
|
+
success: false,
|
118
|
+
data: {
|
119
|
+
error_message: response_xml.body.gsub("\r\n", '')
|
120
|
+
}
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
# Calculates the portions of credit card type
|
125
|
+
# based on Komerci configuration
|
126
|
+
#
|
127
|
+
# @param order [Spree::Order]
|
128
|
+
#
|
129
|
+
# @return [Array]
|
130
|
+
#
|
131
|
+
def calculate_portions(order)
|
132
|
+
amount = order.total.to_f
|
133
|
+
ret = []
|
134
|
+
|
135
|
+
portions_number = preferred_max_portion
|
136
|
+
minimum_value = preferred_minimum_value.to_f
|
137
|
+
tax = preferred_tax_value.to_f
|
138
|
+
|
139
|
+
ret.push({portion: 1, value: amount, total: amount, tax_message: :komerci_without_tax})
|
140
|
+
|
141
|
+
(2..portions_number).each do |number|
|
142
|
+
if tax <= 0 or number <= preferred_portion_without_tax
|
143
|
+
value = amount / number
|
144
|
+
tax_message = :komerci_without_tax
|
145
|
+
else
|
146
|
+
value = (amount * ((1 + tax / 100) ** number)) / number
|
147
|
+
tax_message = :komerci_with_tax
|
148
|
+
end
|
149
|
+
|
150
|
+
if value >= minimum_value
|
151
|
+
value_total = value * number
|
152
|
+
ret.push({portion: number, value: value, total: value_total, tax_message: tax_message})
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
ret
|
157
|
+
end
|
158
|
+
|
159
|
+
# Calculate the value of the portion based on Komerci configuration
|
160
|
+
# (verify if the portion has tax)
|
161
|
+
#
|
162
|
+
# @param order [Spree::Order]
|
163
|
+
# @param portion [Integer]
|
164
|
+
#
|
165
|
+
# @return [Float]
|
166
|
+
#
|
167
|
+
def calculate_portion_value(order, portion)
|
168
|
+
amount = order.total.to_f
|
169
|
+
amount = amount / 100 if amount.is_a? Integer
|
170
|
+
tax = preferred_tax_value.to_f
|
171
|
+
|
172
|
+
if tax <= 0 or portion <= preferred_portion_without_tax
|
173
|
+
value = amount / portion
|
174
|
+
else
|
175
|
+
value = (amount * ((1 + tax / 100) ** portion)) / portion
|
176
|
+
end
|
177
|
+
value
|
178
|
+
end
|
179
|
+
|
180
|
+
private
|
181
|
+
|
182
|
+
def format_keys hash
|
183
|
+
hash.inject({}) { |result, (key, value)|
|
184
|
+
value = format_keys(value) if value.is_a?(Hash)
|
185
|
+
result[(key.downcase.to_sym rescue key) || key] = value
|
186
|
+
result
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SpreeZaezKomerci
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
require 'spree/core'
|
4
|
+
isolate_namespace Spree
|
5
|
+
engine_name 'spree_zaez_komerci'
|
6
|
+
|
7
|
+
# use rspec for tests
|
8
|
+
config.generators do |g|
|
9
|
+
g.test_framework :rspec
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer 'spree.zaez_komerci.preferences', after: :load_config_initializers do |app|
|
13
|
+
# require file with the preferences of the Billet
|
14
|
+
require 'spree/komerci_configuration'
|
15
|
+
Spree::KomerciConfig = Spree::KomerciConfiguration.new
|
16
|
+
end
|
17
|
+
|
18
|
+
initializer 'spree.zaez_komerci.payment_methods', after: 'spree.register.payment_methods' do |app|
|
19
|
+
app.config.spree.payment_methods << Spree::PaymentMethod::Komerci
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.activate
|
23
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
|
24
|
+
Rails.configuration.cache_classes ? require(c) : load(c)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
config.to_prepare &method(:activate).to_proc
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :komerci_payment_method, class: Spree::PaymentMethod::Komerci do
|
3
|
+
name 'Komerci'
|
4
|
+
created_at Date.today
|
5
|
+
end
|
6
|
+
|
7
|
+
factory :komerci_payment, class: Spree::Payment do
|
8
|
+
amount 15.00
|
9
|
+
order
|
10
|
+
state 'checkout'
|
11
|
+
portions 2
|
12
|
+
association(:payment_method, factory: :komerci_payment_method)
|
13
|
+
association(:source, factory: :credit_card_komerci)
|
14
|
+
end
|
15
|
+
|
16
|
+
factory :credit_card_komerci, class: Spree::CreditCard do
|
17
|
+
verification_value 123
|
18
|
+
month 12
|
19
|
+
year { 1.year.from_now.year }
|
20
|
+
number '4111111111111111'
|
21
|
+
name 'Spree Commerce'
|
22
|
+
cc_type 'visa'
|
23
|
+
association(:payment_method, factory: :komerci_payment_method)
|
24
|
+
end
|
25
|
+
|
26
|
+
factory :komerci_transaction, class: Spree::KomerciTransaction do
|
27
|
+
association(:credit_card, factory: :credit_card_komerci)
|
28
|
+
association(:payment, factory: :komerci_payment)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Admin Komerci Payment', { type: :feature, js: true } do
|
4
|
+
|
5
|
+
let(:payment) { create(:komerci_payment, response_code: 'ABC1234') }
|
6
|
+
let!(:komerci_transaction) { create(:komerci_transaction, order_number: 'ABC1234', payment: payment) }
|
7
|
+
|
8
|
+
before(:all) { Spree::KomerciConfig[:test_mode] = true }
|
9
|
+
before { create_admin_and_sign_in }
|
10
|
+
|
11
|
+
context 'executing the actions' do
|
12
|
+
|
13
|
+
context 'capture the payment' do
|
14
|
+
|
15
|
+
let(:request_url) { Spree::KomerciConfig.conf_authorization_uri }
|
16
|
+
|
17
|
+
it 'should capture the payment' do
|
18
|
+
stub_request(:post, request_url).
|
19
|
+
with(body: hash_including({ 'filiacao' => Spree::KomerciConfig[:afiliation_key] })).
|
20
|
+
to_return(:body => File.read('spec/fixtures/conf_authorize_success.txt'), :status => 200)
|
21
|
+
|
22
|
+
visit spree.admin_order_payments_path payment.order
|
23
|
+
find('.action-capture').click
|
24
|
+
|
25
|
+
expect(page).to have_text 'Payment Updated'
|
26
|
+
within_row(1) do
|
27
|
+
expect(column_text(6)).to eq 'completed'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should show an error message when try capture and fail' do
|
32
|
+
stub_request(:post, request_url).
|
33
|
+
with(body: hash_including({ 'filiacao' => Spree::KomerciConfig[:afiliation_key] })).
|
34
|
+
to_return(:body => File.read('spec/fixtures/conf_authorize_error.txt'), :status => 200)
|
35
|
+
|
36
|
+
visit spree.admin_order_payments_path payment.order
|
37
|
+
find('.action-capture').click
|
38
|
+
|
39
|
+
expect(page).to have_text '98: Cartão inválido'
|
40
|
+
within_row(1) do
|
41
|
+
expect(column_text(6)).to eq 'failed'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'void the payment' do
|
47
|
+
|
48
|
+
let(:request_url) { Spree::KomerciConfig.void_transaction_uri }
|
49
|
+
|
50
|
+
it 'should void the payment' do
|
51
|
+
stub_request(:post, request_url).
|
52
|
+
with(body: hash_including({ 'filiacao' => Spree::KomerciConfig[:afiliation_key] })).
|
53
|
+
to_return(:body => File.read('spec/fixtures/void_success.txt'), :status => 200)
|
54
|
+
|
55
|
+
visit spree.admin_order_payments_path payment.order
|
56
|
+
find('.action-void').click
|
57
|
+
|
58
|
+
expect(page).to have_text 'Payment Updated'
|
59
|
+
within_row(1) do
|
60
|
+
expect(column_text(6)).to eq 'void'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should show an error message when try void and fail' do
|
65
|
+
stub_request(:post, request_url).
|
66
|
+
with(body: hash_including({ 'filiacao' => Spree::KomerciConfig[:afiliation_key] })).
|
67
|
+
to_return(:body => File.read('spec/fixtures/void_error.txt'), :status => 200)
|
68
|
+
|
69
|
+
visit spree.admin_order_payments_path payment.order
|
70
|
+
find('.action-void').click
|
71
|
+
|
72
|
+
expect(page).to have_text '97: Data de estorno expirou'
|
73
|
+
within_row(1) do
|
74
|
+
expect(column_text(6)).to eq 'checkout'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|