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.
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,7 @@
1
+ PaymentMethod.class_eval do
2
+
3
+ def self.providers
4
+ Rails.application.config.spree.payment_methods + [Gateway::PayuIn]
5
+ end
6
+
7
+ 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
+ &nbsp;
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,8 @@
1
+ Rails.application.routes.draw do
2
+ match '/payment_confirmed' => 'checkout#gateway_callback', :via => [:get, :post], :as => :payment_callback
3
+
4
+ namespace :gateway do
5
+ match '/:gateway_id/payu_in/:order_id' => 'payu_in#show', :as => :payu_in
6
+ end
7
+
8
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module SpreePayuin
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,5 @@
1
+ require 'spree_payuin'
2
+
3
+ describe SpreePayuin do
4
+ it "should behave"
5
+ end
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.1
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-20 00:00:00.000000000 Z
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