spree_instamojo 0.0.1.alpha → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +21 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +26 -0
  5. data/Appraisals +29 -0
  6. data/Gemfile +9 -0
  7. data/LICENSE +30 -0
  8. data/README.md +50 -0
  9. data/Rakefile +21 -0
  10. data/app/assets/javascripts/spree/backend/spree_instamojo.js +2 -0
  11. data/app/assets/javascripts/spree/frontend/spree_instamojo.js +2 -0
  12. data/app/assets/stylesheets/spree/backend/spree_instamojo.css +4 -0
  13. data/app/assets/stylesheets/spree/frontend/spree_instamojo.css +4 -0
  14. data/app/controllers/spree/instamojo_controller.rb +106 -0
  15. data/app/controllers/spree/paytm_controller.rb +71 -0
  16. data/app/models/spree/gateway/instamojo.rb +45 -0
  17. data/app/models/spree/gateway/paytm.rb +259 -0
  18. data/app/models/spree/payment_checkout.rb +4 -0
  19. data/app/views/spree/admin/payments/source_views/_instamojo.html.erb +0 -0
  20. data/app/views/spree/admin/payments/source_views/_paytm.html.erb +0 -0
  21. data/app/views/spree/checkout/payment/_instamojo.html.erb +4 -0
  22. data/app/views/spree/checkout/payment/_paytm.html.erb +4 -0
  23. data/app/views/spree/instamojo/confirm.html.erb +17 -0
  24. data/app/views/spree/instamojo/index.html.erb +11 -0
  25. data/app/views/spree/paytm/confirm.html.erb +17 -0
  26. data/app/views/spree/paytm/index.html.erb +13 -0
  27. data/bin/rails +7 -0
  28. data/config/locales/en.yml +7 -0
  29. data/config/routes.rb +12 -0
  30. data/db/migrate/20180308104631_create_spree_instamojo_checkout.rb +13 -0
  31. data/lib/generators/spree_instamojo/install/install_generator.rb +31 -0
  32. data/lib/spree_instamojo.rb +5 -0
  33. data/lib/spree_instamojo/engine.rb +27 -0
  34. data/lib/spree_instamojo/factories.rb +6 -0
  35. data/lib/spree_instamojo/version.rb +17 -0
  36. data/spec/spec_helper.rb +99 -0
  37. data/spree_instamojo.gemspec +28 -0
  38. metadata +43 -217
@@ -0,0 +1,259 @@
1
+ module Spree
2
+ class Gateway::Paytm < Gateway
3
+ preference :merchant_id, :string
4
+ preference :merchant_key, :string
5
+ preference :website, :string
6
+ preference :industry_type_id, :string
7
+ preference :channel_id, :string
8
+
9
+ def supports?(source)
10
+ true
11
+ end
12
+
13
+ def provider_class
14
+ self
15
+ end
16
+
17
+ def provider
18
+ self
19
+ end
20
+
21
+ def auto_capture?
22
+ true
23
+ end
24
+
25
+ def method_type
26
+ "paytm"
27
+ end
28
+
29
+ def purchase(amount, source, gateway_options={})
30
+ ActiveMerchant::Billing::Response.new(true, "paytm success")
31
+ end
32
+
33
+ def txnid(order)
34
+ "#{order.id.to_s}-#{SecureRandom.random_number(100000)}-#{order.number.to_s}"
35
+ end
36
+
37
+ def refund_url
38
+ 'https://' + domain + '/oltp/HANDLER_INTERNAL/REFUND'
39
+ end
40
+
41
+ def status_query_url
42
+ 'https://' + domain + '/oltp/HANDLER_INTERNAL/TXNSTATUS'
43
+ end
44
+
45
+ def txn_url
46
+ 'https://' + domain + '/oltp-web/processTransaction'
47
+ end
48
+
49
+ def request_type
50
+ 'DEFAULT' #or SUBSCRIBE
51
+ end
52
+
53
+ ### function returns a single encrypted value ###
54
+ ### input data -> value to be encrypted ###
55
+ ### key -> key to use for encryption ###
56
+ def new_pg_encrypt_variable(data, key)
57
+ ##aes = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
58
+ aes = OpenSSL::Cipher::AES.new('128-CBC')
59
+ aes.encrypt
60
+ aes.key = key
61
+ aes.iv = '@@@@&&&&####$$$$'
62
+ encrypted_data = nil
63
+ begin
64
+ encrypted_data = aes.update(data.to_s) + aes.final
65
+ encrypted_data = Base64.encode64(encrypted_data)
66
+ rescue Exception => e
67
+ return false
68
+ end
69
+ return encrypted_data
70
+ end
71
+
72
+
73
+ ### function returns dictionary of decrypted data ###
74
+ ### accepts a dictionary with data and key to decrypt with ###
75
+ ### can accept multiple key value pairs in the dictionary ###
76
+ def new_pg_decrypt(paytmparams)
77
+ if (paytmparams.class != Hash) || (paytmparams.keys == [])
78
+ return false
79
+ end
80
+ if !paytmparams.has_key?(:key)
81
+ return false
82
+ end
83
+ decrypted_data = Hash[]
84
+ key = paytmparams.delete(:key)
85
+ keys = paytmparams.keys
86
+ ##aes = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
87
+ aes = OpenSSL::Cipher::AES.new('128-CBC')
88
+ begin
89
+ keys.each do |k|
90
+ data = paytmparams[k]
91
+ aes.decrypt
92
+ aes.key = key
93
+ aes.iv = '@@@@&&&&####$$$$'
94
+ decrypted_k = Base64.decode64(k.to_s)
95
+ decrypted_k = aes.update(decrypted_k.to_s) + aes.final
96
+ if data.empty?
97
+ decrypted_data[decrypted_k] = ""
98
+ next
99
+ end
100
+ aes.decrypt
101
+ aes.key = key
102
+ aes.iv = '@@@@&&&&####$$$$'
103
+ data = Base64.decode64(data)
104
+ decrypted_data[decrypted_k] = aes.update(data) + aes.final
105
+ end
106
+ rescue Exception => e
107
+ return false
108
+ end
109
+ return decrypted_data
110
+ end
111
+
112
+ ### function returns a single decrypted value ###
113
+ ### input data -> value to be decrypted ###
114
+ ### key -> key to use for decryption ###
115
+ def new_pg_decrypt_variable(data, key)
116
+ ##aes = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
117
+ aes = OpenSSL::Cipher::AES.new('128-CBC')
118
+ aes.decrypt
119
+ aes.key = key
120
+ aes.iv = '@@@@&&&&####$$$$'
121
+ decrypted_data = nil
122
+ begin
123
+ decrypted_data = Base64.decode64(data.to_s)
124
+ decrypted_data = aes.update(decrypted_data) + aes.final
125
+ rescue Exception => e
126
+ return false
127
+ end
128
+ return decrypted_data
129
+ end
130
+ def new_pg_generate_salt(length)
131
+ salt = SecureRandom.urlsafe_base64(length*(3.0/4.0))
132
+ return salt.to_s
133
+ end
134
+
135
+ ### function returns checksum of given key value pairs ###
136
+ ### accepts a hash with key value pairs ###
137
+ ### calculates sha256 checksum of given values ###
138
+ def new_pg_checksum(paytmparams, key = preferred_merchant_key, salt_length = 4)
139
+ if paytmparams.class != Hash
140
+ return false
141
+ end
142
+ if key.empty?
143
+ return false
144
+ end
145
+ salt = new_pg_generate_salt(salt_length)
146
+ keys = paytmparams.keys
147
+ str = nil
148
+ keys = keys.sort
149
+ keys.each do |k|
150
+ if str.nil?
151
+ str = paytmparams[k].to_s
152
+ next
153
+ end
154
+ str = str + '|' + paytmparams[k].to_s
155
+ end
156
+ str = str + '|' + salt
157
+ check_sum = Digest::SHA256.hexdigest(str)
158
+ check_sum = check_sum + salt
159
+ ### encrypting checksum ###
160
+ check_sum = new_pg_encrypt_variable(check_sum, key)
161
+ return check_sum
162
+ end
163
+
164
+ ### function returns checksum of given key value pairs ###
165
+ ### accepts a hash with key value pairs ###
166
+ ### calculates sha256 checksum of given values ###
167
+ def new_pg_refund_checksum(paytmparams, key = preferred_merchant_key, salt_length = 4)
168
+ keys = paytmparams.keys
169
+ keys.each do |k|
170
+ if ! paytmparams[k].empty?
171
+ #if params[k].to_s.include? "REFUND"
172
+ unless paytmparams[k].to_s.include? "|"
173
+ next
174
+ end
175
+ paytmparams[k] = paytmparams[k]
176
+ end
177
+ end
178
+ if paytmparams.class != Hash
179
+ return false
180
+ end
181
+ if key.empty?
182
+ return false
183
+ end
184
+ salt = new_pg_generate_salt(salt_length)
185
+ keys = paytmparams.keys
186
+ str = nil
187
+ keys = keys.sort
188
+ keys.each do |k|
189
+ if str.nil?
190
+ str = paytmparams[k].to_s
191
+ next
192
+ end
193
+ str = str + '|' + paytmparams[k].to_s
194
+ end
195
+ str = str + '|' + salt
196
+ check_sum = Digest::SHA256.hexdigest(str)
197
+ check_sum = check_sum + salt
198
+ ### encrypting checksum ###
199
+ check_sum = new_pg_encrypt_variable(check_sum, key)
200
+ return check_sum
201
+ end
202
+
203
+ ### function returns checksum of given key value pairs (must contain the :checksum key) ###
204
+ ### accepts a hash with key value pairs ###
205
+ ### calculates sha256 checksum of given values ###
206
+ ### returns true if checksum is consistent ###
207
+ ### returns false in case of inconsistency ###
208
+ def new_pg_verify_checksum(paytmparams, check_sum, key = preferred_merchant_key, salt_length = 4)
209
+ if paytmparams.class != Hash
210
+ return false
211
+ end
212
+ if key.empty?
213
+ return false
214
+ end
215
+ if check_sum.nil? || check_sum.empty?
216
+ return false
217
+ end
218
+ generated_check_sum = nil
219
+
220
+ check_sum = new_pg_decrypt_variable(check_sum, key)
221
+ if check_sum == false
222
+ return false
223
+ end
224
+ begin
225
+ salt = check_sum[(check_sum.length-salt_length), (check_sum.length)]
226
+ keys = paytmparams.keys
227
+ str = nil
228
+ keys = keys.sort
229
+ keys.each do |k|
230
+ if str.nil?
231
+ str = paytmparams[k].to_s
232
+ next
233
+ end
234
+ str = str + '|' + paytmparams[k].to_s
235
+ end
236
+ str = str + '|' + salt
237
+ generated_check_sum = Digest::SHA256.hexdigest(str)
238
+ generated_check_sum = generated_check_sum + salt
239
+ rescue Exception => e
240
+ return false
241
+ end
242
+
243
+ if check_sum == generated_check_sum
244
+ return true
245
+ else
246
+ return false
247
+ end
248
+ end
249
+
250
+ private
251
+ def domain
252
+ domain = 'secure.paytm.in'
253
+ if (preferred_test_mode == true)
254
+ domain = 'pguat.paytm.com'
255
+ end
256
+ domain
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,4 @@
1
+ module Spree
2
+ class PaymentCheckout < ActiveRecord::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+
2
+ <%= link_to("Pay with Instamojo", instamj_proceed_url(:payment_method_id => payment_method.id), :method => :post, :id => "instamj_button", class: "btn btn-md btn-primary pull-right") %>
3
+
4
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
@@ -0,0 +1,4 @@
1
+
2
+ <%= link_to("Pay with Paytm", paytm_proceed_url(:payment_method_id => payment_method.id), :method => :post, :id => "paytm_button", class: "btn btn-md btn-primary pull-right") %>
3
+
4
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
@@ -0,0 +1,17 @@
1
+ <h1>
2
+ <b>HOLDON!</b>
3
+ While we connect you back to merchant's site
4
+ </h1>
5
+ <% if @error.present? %>
6
+ <p class="error">
7
+ <%= @message %>
8
+ </p>
9
+ <% end %>
10
+
11
+ <script>
12
+ $(document).ready(function(){
13
+ setTimeout(function(){
14
+ window.location.replace("<%= @redirect_path %>");
15
+ }, 3000);
16
+ })
17
+ </script>
@@ -0,0 +1,11 @@
1
+ <h4>Processing ...</h4>
2
+ <form id="checkout_form" name="checkout_form" action="<%= @instamj_txn_url %>">
3
+
4
+ </form>
5
+ <script type="text/javascript">
6
+ // self executing function
7
+ (function () {
8
+ // auto submit form
9
+ document.getElementById("checkout_form").submit();
10
+ })();
11
+ </script>
@@ -0,0 +1,17 @@
1
+ <h1>
2
+ <b>HOLDON!</b>
3
+ While we connect you back to merchant's site
4
+ </h1>
5
+ <% if @error.present? %>
6
+ <p class="error">
7
+ <%= @message %>
8
+ </p>
9
+ <% end %>
10
+
11
+ <script>
12
+ $(document).ready(function(){
13
+ setTimeout(function(){
14
+ window.location.replace("<%= @redirect_path %>");
15
+ }, 5000);
16
+ })
17
+ </script>
@@ -0,0 +1,13 @@
1
+ <h4>Processing ...</h4>
2
+ <form id="checkout_form" name="checkout_form" method="post" action="<%= @paytm_txn_url %>">
3
+ <% @param_list.each do |name, value| %>
4
+ <input type="hidden" name="<%= name %>" value="<%= value %>" >
5
+ <% end %>
6
+ </form>
7
+ <script type="text/javascript">
8
+ // self executing function
9
+ (function () {
10
+ // auto submit form
11
+ document.getElementById("checkout_form").submit();
12
+ })();
13
+ </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_instamojo/engine', __FILE__)
5
+
6
+ require 'rails/all'
7
+ require 'rails/engine/commands'
@@ -0,0 +1,7 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ spree:
6
+ paytm:
7
+ paytm_payment_failed: "Paytm failed. Security header is not valid"
data/config/routes.rb ADDED
@@ -0,0 +1,12 @@
1
+ Spree::Core::Engine.add_routes do
2
+ # Add your extension routes here
3
+
4
+ Spree::Core::Engine.add_routes do
5
+ post '/instamojo', :to => "instamojo#index", :as => :instamj_proceed
6
+ get '/instamojo/confirm', :to => "instamojo#confirm", :as => :instamj_confirm
7
+ post '/instamojo/cancel', :to => "instamojo#cancel", :as => :instamj_cancel
8
+ post '/paytm', :to => "paytm#index", :as => :paytm_proceed
9
+ post '/paytm/confirm', :to => "paytm#confirm", :as => :paytm_confirm
10
+ post '/paytm/cancel', :to => "paytm#cancel", :as => :paytm_cancel
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ class CreateSpreeInstamojoCheckout < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :spree_payment_checkouts do |t|
4
+ t.string :payment_request_id
5
+ t.string :payment_id
6
+ t.string :order_id
7
+ t.string :amount
8
+ t.string :status
9
+ t.text :checksum
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ module SpreeInstamojo
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_instamojo\n"
9
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/spree_instamojo\n"
10
+ end
11
+
12
+ def add_stylesheets
13
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/spree_instamojo\n", before: /\*\//, verbose: true
14
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/spree_instamojo\n", before: /\*\//, verbose: true
15
+ end
16
+
17
+ def add_migrations
18
+ run 'bundle exec rake railties:install:migrations FROM=spree_instamojo'
19
+ end
20
+
21
+ def run_migrations
22
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
23
+ if run_migrations
24
+ run 'bundle exec rake db:migrate'
25
+ else
26
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ require 'spree_core'
2
+ require 'spree_extension'
3
+ require 'spree_instamojo/engine'
4
+ require 'spree_instamojo/version'
5
+ require 'typhoeus'
@@ -0,0 +1,27 @@
1
+ module SpreeInstamojo
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_instamojo'
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ def self.activate
13
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
14
+ Rails.configuration.cache_classes ? require(c) : load(c)
15
+ end
16
+ end
17
+
18
+ config.to_prepare &method(:activate).to_proc
19
+
20
+ initializer "spree.gateway",
21
+ after: "spree.register.payment_methods" do |app|
22
+ app.config.spree.payment_methods << Spree::Gateway::Instamojo
23
+ app.config.spree.payment_methods << Spree::Gateway::Paytm
24
+ end
25
+
26
+ end
27
+ end