spree_payuin 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/images/store/loading.gif +0 -0
- data/app/controllers/checkout_controller_decorator.rb +60 -0
- data/app/controllers/gateway/payu_in_controller.rb +13 -0
- data/app/models/gateway/payu_in.rb +20 -0
- data/app/models/payment_method_decorator.rb +7 -0
- data/app/models/payu_in_gateway.rb +55 -0
- data/app/models/payu_payment.rb +41 -0
- data/app/views/checkout/gateway_callback.html.erb +30 -0
- data/app/views/checkout/payment/_gateway.html.erb +39 -0
- data/app/views/gateway/.DS_Store +0 -0
- data/app/views/gateway/payu_in/.DS_Store +0 -0
- data/app/views/gateway/payu_in/_payu_form.html.erb +35 -0
- data/app/views/gateway/payu_in/show.html.erb +10 -0
- data/config/routes.rb +8 -0
- data/lib/generators/spree_payuin/install/install_generator.rb +24 -0
- data/lib/generators/spree_payuin/install/templates/create_payu_payments.rb +16 -0
- data/lib/spree_payuin/version.rb +1 -1
- data/spec/spree_payuin_spec.rb +5 -0
- metadata +21 -3
Binary file
|
@@ -0,0 +1,60 @@
|
|
1
|
+
CheckoutController.class_eval do
|
2
|
+
skip_before_filter :verify_authenticity_token, :only => [:gateway_callback]
|
3
|
+
skip_before_filter :load_order, :only => [:gateway_callback]
|
4
|
+
skip_before_filter :check_authorization, :only => [:gateway_callback]
|
5
|
+
|
6
|
+
before_filter :build_payment_method, :only => [:update]
|
7
|
+
|
8
|
+
before_filter :only => :update do
|
9
|
+
redirect_for_payu
|
10
|
+
end
|
11
|
+
|
12
|
+
def gateway_callback
|
13
|
+
return unless request.post?
|
14
|
+
@order = Order.find(params[:txnid])
|
15
|
+
if params[:status] == 'failed'
|
16
|
+
#TODO: PaymentError.new_from(params)
|
17
|
+
#flash[:notice] = "Payment processing failed. Please choose a different payment option, or try again."
|
18
|
+
|
19
|
+
elsif params[:status] == 'canceled'
|
20
|
+
@order.cancel!
|
21
|
+
session[:order_id] = nil
|
22
|
+
redirect_to(payment_callback_url(:status=> 'canceled'))
|
23
|
+
else
|
24
|
+
payment = @order.payments.first
|
25
|
+
p_id = get_payment_method(params["mode"], params['udf1'])
|
26
|
+
payment.update_attributes(:amount => BigDecimal.new(params["amount"]),
|
27
|
+
:source => PayuPayment.new_from(params),
|
28
|
+
:payment_method_id => p_id, :bank_code => params["bankcode"])
|
29
|
+
session[:order_id] = nil if @order.next
|
30
|
+
|
31
|
+
if @order.state == "complete" || @order.completed?
|
32
|
+
redirect_to(payment_callback_url)
|
33
|
+
else
|
34
|
+
respond_with(@order, :location => checkout_state_path(@order.state))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
private
|
41
|
+
def build_payment_method
|
42
|
+
@payment_method = PaymentMethod.find(params[:order][:payments_attributes].first[:payment_method_id])
|
43
|
+
end
|
44
|
+
|
45
|
+
def redirect_for_payu
|
46
|
+
return unless params[:state] == "payment"
|
47
|
+
if @payment_method && @payment_method.kind_of?(Gateway::PayuIn)
|
48
|
+
params[:order][:payments_attributes].first[:bank_code] = nil unless @payment_method.name == "Netbanking"
|
49
|
+
@order.update_attributes(object_params)
|
50
|
+
redirect_to gateway_payu_in_path(:gateway_id => @payment_method.id, :order_id => @order.id, :pg => PayuPayment::PAYU_TYPE[@payment_method.name], :bankcode => params[:order][:payments_attributes].first[:bank_code])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_payment_method(mode, payment_method_id)
|
55
|
+
keys = PayuPayment::PAYU_TYPE.select{|k,v| v == mode}.keys
|
56
|
+
return PaymentMethod.find(:first, :conditions => ["type=? AND name=? AND environment=?", "Gateway::PayuIn", keys.first, Rails.env]).id if keys.present?
|
57
|
+
payment_method_id
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
class Gateway::PayuInController < Spree::BaseController
|
3
|
+
ssl_required :show
|
4
|
+
include ERB::Util
|
5
|
+
|
6
|
+
respond_to :html, :js
|
7
|
+
|
8
|
+
def show
|
9
|
+
@order = Order.find(params[:order_id])
|
10
|
+
@gateway = PaymentMethod.find(params[:gateway_id])
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Gateway::PayuIn < Gateway
|
2
|
+
preference :merchant_id, :string
|
3
|
+
preference :salt, :string
|
4
|
+
#preference :url, :string
|
5
|
+
|
6
|
+
def provider_class
|
7
|
+
ActiveMerchant::Billing::PayuInGateway
|
8
|
+
end
|
9
|
+
|
10
|
+
def external_payment_url
|
11
|
+
#self.url
|
12
|
+
case Rails.env
|
13
|
+
when "production", "staging"
|
14
|
+
'https://secure.payu.in/_payment.php'
|
15
|
+
else
|
16
|
+
'https://test.payu.in/_payment.php'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'digest/sha2'
|
2
|
+
require 'bigdecimal'
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
class PayuInGateway < Gateway
|
7
|
+
def initialize(options = {})
|
8
|
+
requires!(options, :merchant_id, :salt)
|
9
|
+
@options = options
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def merchant_id
|
14
|
+
@options[:merchant_id]
|
15
|
+
end
|
16
|
+
|
17
|
+
def salt
|
18
|
+
@options[:salt]
|
19
|
+
end
|
20
|
+
|
21
|
+
def hash(order, payment_method_id)
|
22
|
+
if Rails.env.production? || Rails.env.staging?
|
23
|
+
Digest::SHA512.hexdigest("#{self.merchant_id}|#{order.id}|#{order.total.to_f}|#{order.number}|#{order.bill_address.firstname}|#{order.user.email}|#{payment_method_id}||||||||||#{self.salt}")
|
24
|
+
else
|
25
|
+
Digest::SHA512.hexdigest("#{self.merchant_id}|#{order.id}|#{order.total.to_i}|#{order.number}|#{order.bill_address.firstname}|#{order.user.email}|#{payment_method_id}||||||||||#{self.salt}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Methods suggested to be supported by active_merchant
|
31
|
+
# https://github.com/Shopify/active_merchant/blob/master/lib/active_merchant/billing/gateway.rb
|
32
|
+
#
|
33
|
+
# purchase(money, creditcard, options = {})
|
34
|
+
# authorize(money, creditcard, options = {})
|
35
|
+
# capture(money, authorization, options = {})
|
36
|
+
# void(identification, options = {})
|
37
|
+
# credit(money, identification, options = {})
|
38
|
+
def purchase(money, creditcard, options = {})
|
39
|
+
end
|
40
|
+
|
41
|
+
def authorize(money, creditcard, options = {})
|
42
|
+
end
|
43
|
+
|
44
|
+
def capture(money, authorization, options= {})
|
45
|
+
end
|
46
|
+
|
47
|
+
def void(identification, options= {})
|
48
|
+
end
|
49
|
+
|
50
|
+
def credit(money, identification, options = {})
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class PayuPayment < ActiveRecord::Base
|
2
|
+
serialize :json
|
3
|
+
|
4
|
+
has_many :payments, :as => :source
|
5
|
+
belongs_to :order, :foreign_key => "transaction_id"
|
6
|
+
|
7
|
+
BANK_CODES = {
|
8
|
+
"AXIS Bank NetBanking" => "AXIB",
|
9
|
+
"Citibank Netbanking" => "CITNB",
|
10
|
+
"Corporation Bank" => "CRPB",
|
11
|
+
"Deutsche Bank" => "DSHB",
|
12
|
+
"HDFC Bank" => "HDFB",
|
13
|
+
"ICICI NetBanking" => "ICIB",
|
14
|
+
"Industrial Development Bank of India" => "IDBB",
|
15
|
+
"State Bank of India" => "SBIB",
|
16
|
+
"Union Bank of India" => "UBIB",
|
17
|
+
"Yes Bank" => "YESB"
|
18
|
+
}
|
19
|
+
|
20
|
+
PAYU_TYPE = {
|
21
|
+
"Netbanking" => "NB",
|
22
|
+
"Credit Card" => "CC",
|
23
|
+
"Debit Card" => "DC"
|
24
|
+
}
|
25
|
+
|
26
|
+
def self.new_from(params)
|
27
|
+
PayuPayment.new(
|
28
|
+
:payment_id=> params['mihpayid'],
|
29
|
+
:mode => params['mode'],
|
30
|
+
:status => params['status'],
|
31
|
+
:key => params['key'],
|
32
|
+
:transaction_id=> params['txnid'],
|
33
|
+
:amount => BigDecimal.new(params['amount']).to_f,
|
34
|
+
:discount=> params['discount'],
|
35
|
+
:json=> params)
|
36
|
+
end
|
37
|
+
|
38
|
+
def process!(payment)
|
39
|
+
payment.complete
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<div style="padding-left: 5px;">
|
2
|
+
<% if params[:status] == 'failed' %>
|
3
|
+
<h3>Oops... Something went wrong...</h3>
|
4
|
+
<div>
|
5
|
+
<p>Something went wrong with the payment. No money has been deducted from your account. Your order is still in draft, please try again at a later point of time.</p>
|
6
|
+
|
7
|
+
<p>Please feel free to contact us if you have any queries</p>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<% elsif params[:status] == 'canceled' %>
|
11
|
+
<h3>Transaction Cancelled</h3>
|
12
|
+
<div>
|
13
|
+
<p>You have cancelled the transaction and payment. The order is still visible to you in your order history, where you can conveniently place a similar order again.</p>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<% elsif params[:status] == 'COD' %>
|
17
|
+
<h3>Thank you for your Order!</h3>
|
18
|
+
<div>
|
19
|
+
<p>Your order will be delivered as soon as possible, as per the delivery times indicated in the respective products.</p>
|
20
|
+
<p>Please check your email inbox for other status notifications, and keep the cheque ready once we inform you about the dispatch of your order.</p>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<% else %>
|
24
|
+
<h3>Thank you for your Order!</h3>
|
25
|
+
<div>
|
26
|
+
<p>Your order will be delivered as soon as possible, as per the delivery times indicated in the respective products.</p>
|
27
|
+
<p>Please check your email inbox for other status notifications.</p>
|
28
|
+
</div>
|
29
|
+
<% end %>
|
30
|
+
</div>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<% if payment_method.type == "Gateway::PayuIn" %>
|
2
|
+
<% if payment_method.name == "Netbanking" %>
|
3
|
+
<%= select_tag "order[payments_attributes][][bank_code]", options_for_select(PayuPayment::BANK_CODES), :class => "netbanking_select_tag" %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
|
7
|
+
<% else %> <!-- unless Gateway::PayuIn -->
|
8
|
+
<%= image_tag 'creditcards/creditcard.gif', :id => 'creditcard-image' %>
|
9
|
+
<% param_prefix = "payment_source[#{payment_method.id}]" %>
|
10
|
+
|
11
|
+
<p class="field" data-hook="card_number">
|
12
|
+
<%= label_tag nil, t(:card_number) %><br />
|
13
|
+
<% options_hash = Rails.env.production? ? {:autocomplete => 'off'} : {} %>
|
14
|
+
<%= text_field_tag "#{param_prefix}[number]", '', options_hash.merge(:id => 'card_number', :class => 'required', :size => 19, :maxlength => 19) %>
|
15
|
+
<span class="req">*</span>
|
16
|
+
|
17
|
+
<span id="card_type" style="display:none;">
|
18
|
+
( <span id="looks_like" ><%= t(:card_type_is) %> <span id="type"></span></span>
|
19
|
+
<span id="unrecognized"><%= t(:unrecognized_card_type) %></span>
|
20
|
+
)
|
21
|
+
</span>
|
22
|
+
</p>
|
23
|
+
<p class="field" data-hook="card_expiration">
|
24
|
+
<%= label_tag nil, t(:expiration) %><br />
|
25
|
+
<%= select_month(Date.today, :prefix => param_prefix, :field_name => 'month', :use_month_numbers => true, :class => 'required') %>
|
26
|
+
<%= select_year(Date.today, :prefix => param_prefix, :field_name => 'year', :start_year => Date.today.year, :end_year => Date.today.year + 15, :class => 'required') %>
|
27
|
+
<span class="req">*</span>
|
28
|
+
</p>
|
29
|
+
<p class="field" data-hook="cart_code">
|
30
|
+
<%= label_tag nil, t(:card_code) %><br />
|
31
|
+
<%= text_field_tag "#{param_prefix}[verification_value]", '', options_hash.merge(:id => 'card_code', :class => 'required', :size => 5) %>
|
32
|
+
<span class="req">*</span>
|
33
|
+
<a href="/content/cvv" target="_blank" onclick="window.open(this.href,'cvv_info','left=20,top=20,width=500,height=500,toolbar=0,resizable=0,scrollbars=1');return false" data-hook="ccv_link">
|
34
|
+
(<%= t(:whats_this) %>)
|
35
|
+
</a>
|
36
|
+
</p>
|
37
|
+
<%= hidden_field param_prefix, 'first_name', :value => @order.billing_firstname %>
|
38
|
+
<%= hidden_field param_prefix, 'last_name', :value => @order.billing_lastname %>
|
39
|
+
<% end %>
|
Binary file
|
Binary file
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<%= form_tag(@gateway.external_payment_url, :method=>:post, :id => "payu_form") do %>
|
2
|
+
<% provider = @gateway.provider %>
|
3
|
+
<%= hidden_field_tag 'key', provider.merchant_id %>
|
4
|
+
<%= hidden_field_tag 'txnid', "#{@order.id}" %>
|
5
|
+
|
6
|
+
<% if Rails.env.production? || Rails.env.staging? %>
|
7
|
+
<%= hidden_field_tag 'amount', @order.total.to_f %>
|
8
|
+
<% else %>
|
9
|
+
<%= hidden_field_tag 'amount', @order.total.to_i %>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<%= hidden_field_tag 'productinfo', @order.number %>
|
13
|
+
<%= hidden_field_tag 'Firstname', @order.bill_address.firstname %>
|
14
|
+
<%= hidden_field_tag 'Lastname', @order.bill_address.lastname %>
|
15
|
+
<%= hidden_field_tag 'address1', @order.bill_address.address1 %>
|
16
|
+
<%= hidden_field_tag 'address2', @order.bill_address.address2 %>
|
17
|
+
<%= hidden_field_tag 'City', @order.bill_address.city %>
|
18
|
+
<%= hidden_field_tag 'State', @order.bill_address.state.name %>
|
19
|
+
<%= hidden_field_tag 'Country', @order.bill_address.country.name %>
|
20
|
+
<%= hidden_field_tag 'Zipcode', @order.bill_address.zipcode %>
|
21
|
+
<%= hidden_field_tag 'Email', @order.user.email %>
|
22
|
+
<%= hidden_field_tag 'phone', @order.bill_address.phone %>
|
23
|
+
<%= hidden_field_tag 'surl', payment_callback_url %>
|
24
|
+
<%= hidden_field_tag 'furl', payment_callback_url(:status=>'failed') %>
|
25
|
+
<%= hidden_field_tag 'curl', payment_callback_url(:status=> 'canceled') %>
|
26
|
+
<%= hidden_field_tag 'udf1', params[:gateway_id] %>
|
27
|
+
<%= hidden_field_tag 'Pg', params[:pg] %>
|
28
|
+
<%= hidden_field_tag 'Bankcode', params[:bankcode] if params[:bankcode].present? %>
|
29
|
+
<%= hidden_field_tag 'Hash', provider.hash(@order, params[:gateway_id]) %>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<script>
|
33
|
+
setTimeout("document.forms['payu_form'].submit()", 500);
|
34
|
+
</script>
|
35
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<h3 align="center">You will now be redirected to PayU's payment gateway page.</h3>
|
2
|
+
|
3
|
+
<div data-hook="outside_cart_form" style="width: 800px;">
|
4
|
+
<div id="fb_loader">
|
5
|
+
<p><%= image_tag "store/loading.gif" %></p>
|
6
|
+
<p><strong>Redirecting...</strong></p>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<%= render :partial => 'gateway/payu_in/payu_form' %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
|
3
|
+
module SpreePayuin
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
8
|
+
desc "add the migrations"
|
9
|
+
|
10
|
+
def self.next_migration_number(path)
|
11
|
+
unless @prev_migration_nr
|
12
|
+
@prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
|
13
|
+
else
|
14
|
+
@prev_migration_nr += 1
|
15
|
+
end
|
16
|
+
@prev_migration_nr.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def copy_migrations
|
20
|
+
migration_template "create_payu_payments.rb", "db/migrate/create_payu_payments.rb"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreatePayuPayments < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :payu_payments do |t|
|
4
|
+
t.string :payment_id
|
5
|
+
t.string :mode
|
6
|
+
t.string :status
|
7
|
+
t.string :key
|
8
|
+
t.string :transaction_id
|
9
|
+
t.float :amount
|
10
|
+
t.string :discount
|
11
|
+
t.text :json
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/spree_payuin/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_payuin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: spree_core
|
@@ -39,8 +39,25 @@ files:
|
|
39
39
|
- LICENSE
|
40
40
|
- README.md
|
41
41
|
- Rakefile
|
42
|
+
- app/assets/images/store/loading.gif
|
43
|
+
- app/controllers/checkout_controller_decorator.rb
|
44
|
+
- app/controllers/gateway/payu_in_controller.rb
|
45
|
+
- app/models/gateway/payu_in.rb
|
46
|
+
- app/models/payment_method_decorator.rb
|
47
|
+
- app/models/payu_in_gateway.rb
|
48
|
+
- app/models/payu_payment.rb
|
49
|
+
- app/views/checkout/gateway_callback.html.erb
|
50
|
+
- app/views/checkout/payment/_gateway.html.erb
|
51
|
+
- app/views/gateway/.DS_Store
|
52
|
+
- app/views/gateway/payu_in/.DS_Store
|
53
|
+
- app/views/gateway/payu_in/_payu_form.html.erb
|
54
|
+
- app/views/gateway/payu_in/show.html.erb
|
55
|
+
- config/routes.rb
|
56
|
+
- lib/generators/spree_payuin/install/install_generator.rb
|
57
|
+
- lib/generators/spree_payuin/install/templates/create_payu_payments.rb
|
42
58
|
- lib/spree_payuin.rb
|
43
59
|
- lib/spree_payuin/version.rb
|
60
|
+
- spec/spree_payuin_spec.rb
|
44
61
|
- spree_payuin.gemspec
|
45
62
|
homepage: http://www.payu.in
|
46
63
|
licenses: []
|
@@ -66,4 +83,5 @@ rubygems_version: 1.8.21
|
|
66
83
|
signing_key:
|
67
84
|
specification_version: 3
|
68
85
|
summary: PayU.in payment gateway integration for Spree
|
69
|
-
test_files:
|
86
|
+
test_files:
|
87
|
+
- spec/spree_payuin_spec.rb
|