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.
- checksums.yaml +4 -4
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.travis.yml +26 -0
- data/Appraisals +29 -0
- data/Gemfile +9 -0
- data/LICENSE +30 -0
- data/README.md +50 -0
- data/Rakefile +21 -0
- data/app/assets/javascripts/spree/backend/spree_instamojo.js +2 -0
- data/app/assets/javascripts/spree/frontend/spree_instamojo.js +2 -0
- data/app/assets/stylesheets/spree/backend/spree_instamojo.css +4 -0
- data/app/assets/stylesheets/spree/frontend/spree_instamojo.css +4 -0
- data/app/controllers/spree/instamojo_controller.rb +106 -0
- data/app/controllers/spree/paytm_controller.rb +71 -0
- data/app/models/spree/gateway/instamojo.rb +45 -0
- data/app/models/spree/gateway/paytm.rb +259 -0
- data/app/models/spree/payment_checkout.rb +4 -0
- data/app/views/spree/admin/payments/source_views/_instamojo.html.erb +0 -0
- data/app/views/spree/admin/payments/source_views/_paytm.html.erb +0 -0
- data/app/views/spree/checkout/payment/_instamojo.html.erb +4 -0
- data/app/views/spree/checkout/payment/_paytm.html.erb +4 -0
- data/app/views/spree/instamojo/confirm.html.erb +17 -0
- data/app/views/spree/instamojo/index.html.erb +11 -0
- data/app/views/spree/paytm/confirm.html.erb +17 -0
- data/app/views/spree/paytm/index.html.erb +13 -0
- data/bin/rails +7 -0
- data/config/locales/en.yml +7 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20180308104631_create_spree_instamojo_checkout.rb +13 -0
- data/lib/generators/spree_instamojo/install/install_generator.rb +31 -0
- data/lib/spree_instamojo.rb +5 -0
- data/lib/spree_instamojo/engine.rb +27 -0
- data/lib/spree_instamojo/factories.rb +6 -0
- data/lib/spree_instamojo/version.rb +17 -0
- data/spec/spec_helper.rb +99 -0
- data/spree_instamojo.gemspec +28 -0
- 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
|
File without changes
|
File without changes
|
@@ -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,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
|