spree_ignitor_ipay88 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/app/assets/images/ignitor_logo.png +0 -0
  5. data/app/assets/javascripts/spree/backend/spree_ignitor_ipay88.js +0 -0
  6. data/app/assets/javascripts/spree/frontend/spree_ignitor_ipay88.js +0 -0
  7. data/app/assets/stylesheets/spree/backend/spree_ignitor_ipay88.css +0 -0
  8. data/app/assets/stylesheets/spree/frontend/spree_ignitor_ipay88.css +0 -0
  9. data/app/controllers/spree/admin/payment_methods_controller_decorator.rb +3 -0
  10. data/app/controllers/spree/checkout_controller_decorator.rb +21 -0
  11. data/app/controllers/spree/ipay88_controller.rb +97 -0
  12. data/app/helpers/spree/ipay88_helper.rb +38 -0
  13. data/app/models/spree/ipay88/payment_method.rb +43 -0
  14. data/app/models/spree/ipay88/transaction.rb +123 -0
  15. data/app/models/spree/ipay88.rb +5 -0
  16. data/app/models/spree_order_decorator.rb +16 -0
  17. data/app/models/spree_payment_method_decorator.rb +3 -0
  18. data/app/overrides/payment_method_view_override.rb +11 -0
  19. data/app/views/spree/admin/payment_methods/_branding.html.erb +3 -0
  20. data/app/views/spree/checkout/payment/_ipay88.html.erb +0 -0
  21. data/app/views/spree/ipay88/error.html.erb +2 -0
  22. data/app/views/spree/ipay88/show.html.erb +38 -0
  23. data/config/locales/en.yml +5 -0
  24. data/config/routes.rb +5 -0
  25. data/db/migrate/20160726135841_create_spree_ipay88_transactions.rb +28 -0
  26. data/lib/sha1_encryptor.rb +29 -0
  27. data/lib/spree_ignitor_ipay88/engine.rb +20 -0
  28. data/lib/spree_ignitor_ipay88/version.rb +3 -0
  29. data/lib/spree_ignitor_ipay88.rb +6 -0
  30. data/lib/tasks/spree_ignitor_ipay88_tasks.rake +4 -0
  31. metadata +133 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e32f8b521896268e7499c14003d07f72632cbafc
4
+ data.tar.gz: 0dda862451fd477a2a2b36e0aea89dce6e5ba860
5
+ SHA512:
6
+ metadata.gz: f8846fde0336030bca2ba19c6ba064e81427aaf322779ca91047db94c231c1e8511b579c1a66dacb6dd0642f9578f189bb9429b3c3a373fac4d5a7d59cc6ea7a
7
+ data.tar.gz: 0329df80c64d55a06549a2573fe00e8346d10e70dd703af9f0c015f524c884a48371676754e00c5f8fa79956b4825bab97c6a75681875e6dc1bd1faab2e2d46d
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 Edutor Technologies
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+ require 'rake/testtask'
9
+
10
+ RDoc::Task.new(:rdoc) do |rdoc|
11
+ rdoc.rdoc_dir = 'rdoc'
12
+ rdoc.title = 'SpreeIgnitorIpay88'
13
+ rdoc.options << '--line-numbers'
14
+ rdoc.rdoc_files.include('README.rdoc')
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ end
17
+
18
+ Rake::TestTask.new do |t|
19
+ t.libs << 'test'
20
+ t.test_files = FileList['test/**/*test.rb']
21
+ t.verbose = true
22
+ end
23
+
24
+ load 'rails/tasks/statistics.rake'
25
+
26
+ desc "Run tests"
27
+ task :default => :test
28
+
29
+
30
+
31
+ Bundler::GemHelper.install_tasks
32
+
Binary file
@@ -0,0 +1,3 @@
1
+ Spree::Admin::PaymentMethodsController.class_eval do
2
+ # This is a decorator where a url can be notified when some one new adds spree ignitor ipay88 extension
3
+ end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ CheckoutController.class_eval do
3
+
4
+ before_action :push_to_ipay88_show_action, only: :update
5
+
6
+ private
7
+
8
+ # This is the hook which pushes/redirects user to ipay88 show page for the first time
9
+ def push_to_ipay88_show_action
10
+ # Perform this redirect only if the order is in payment state
11
+ return unless (params[:state] == 'payment') && params[:order][:payments_attributes]
12
+ # The user already has picked Ipay88.
13
+ # So we will have the corresponding payment method for Ipay88 in the parameter
14
+ payment_method = PaymentMethod.find(params[:order][:payments_attributes].first[:payment_method_id])
15
+ if payment_method && payment_method.kind_of?(Spree::Ipay88::PaymentMethod)
16
+ redirect_to gateway_ipay88_path(@order.number, payment_method.id)
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,97 @@
1
+ module Spree
2
+ class Ipay88Controller < StoreController
3
+ # Because call back should come from Ipay. They don't have an authenticity token
4
+ skip_before_action :verify_authenticity_token, only: :callback
5
+ # Ensure that the callback is redirected from Ipay88' secure server
6
+ before_action :check_signature, only: :callback
7
+ helper 'spree/orders'
8
+ include Spree::Ipay88Helper
9
+
10
+ # This is the method which renders the form which redirects to Ipay88 upon form submission from user's browser
11
+ def show
12
+ # We initially let the user to pick which payment method he wants to use. Payment method id therefore comes from the user
13
+ @payment_method = Spree::PaymentMethod.find(params[:payment_method_id])
14
+
15
+ if !@payment_method or !@payment_method.kind_of?(Spree::Ipay88::PaymentMethod)
16
+ # if by any chance
17
+ flash[:error] = 'Invalid payment method'
18
+ # Don't render anything just show a flash message in the existing screen (checkout#edit)
19
+ render :error
20
+ return
21
+ end
22
+
23
+ @order = current_order
24
+ if @order.has_authorized_ipay88_transaction?
25
+ # if by any chance, we get to the url by copy pasting the link etc., we flash useful error message
26
+ flash[:error] = 'Order #{@order.number} is already authorized at Ipay88'
27
+ # Don't render anything just show a flash message in the existing screen (checkout#edit)
28
+ render :error
29
+ return
30
+ end
31
+
32
+ # Precautions
33
+ @order.cancel_existing_ipay88_transactions!
34
+ @order.payments.destroy_all
35
+
36
+ # Creates new payment and a corresponding Ipay88 transaction
37
+ @order.payments.build(amount:@order.total,payment_method_id:@payment_method.id)
38
+ @transaction = @order.ipay88_transactions.build( amount:@order.total, currency:@order.currency.to_s, payment_method_id:@payment_method.id )
39
+ @transaction.transact # shifts the transaction state from 'created' to 'sent'. We didn't really send the transaction to ipay88 yet.
40
+ # Now all we have left is to make the user submit the form
41
+
42
+ # We save the order, the corresponding payment and ipay88 transaction in the database
43
+ @order.save!
44
+ # these are needed on the view
45
+ @bill_address, @ship_address = @order.bill_address, (@order.ship_address || @order.bill_address)
46
+ logger.info("Will send order #{@order.number} to Ipay88 with local transaction ID: #{@transaction.id}")
47
+ end
48
+
49
+ # Responds to the Ipay88 initiated redirect. This is the URL which is given to Ipay88 as a redirect/callback url
50
+
51
+ def callback
52
+ @transaction.status = params["Status"]
53
+ @transaction.ipay88_payment_id = params["PaymentId"].to_s
54
+ @transaction.ref_no = params["RefNo"] # Spree's order.number
55
+ @transaction.ipay88_amount = params["Amount"] # Stored seperately, in case
56
+ @transaction.remark = params["Remark"]
57
+ @transaction.trans_id = params["TransId"].to_s
58
+ @transaction.auth_code = params["AuthCode"]
59
+ @transaction.error_description = params["ErrDesc"]
60
+ @transaction.signature = params["Signature"]
61
+
62
+ session[:access_token] = @transaction.order.guest_token if @transaction.order.respond_to?(:guest_token)
63
+ session[:order_id] = @transaction.order.id
64
+
65
+ if @transaction.next
66
+ # Handles transaction states
67
+ if @transaction.authorized? # Success
68
+ session[:order_id] = nil
69
+ flash[:success] = I18n.t(:success)
70
+ # Google analytics part
71
+ # flash[:commerce_tracking] = 'nothing special'
72
+ if session[:access_token].nil?
73
+ redirect_to order_path(@transaction.order, {:order_complete => true})
74
+ else # Enables the url to be reused and copied else where a.k.a the page will still be displayed
75
+ redirect_to order_path(@transaction.order, {:order_complete => true, :token => session[:access_token]})
76
+ end
77
+ else # Failure
78
+ redirect_to edit_order_path(@transaction.order), :error => @transaction.error_description
79
+ end
80
+ else
81
+ render 'error'
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def check_signature
88
+ @transaction = Spree::Ipay88::Transaction.find(params[:id])
89
+ raise "Transaction with id: #{params[:id]} not found!" unless @transaction
90
+ merchant_key = @transaction.payment_method.preferred_merchant_key
91
+ # Produces white screen
92
+ @ipay88_error = params["ErrDesc"]
93
+ render 'error' unless params["Signature"] == get_response_signature(params,merchant_key)
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,38 @@
1
+ require 'sha1_encryptor'
2
+
3
+ module Spree
4
+ module Ipay88Helper
5
+
6
+ # Generates request parameters to be used in form which redirects the user to ipay88
7
+ def request_params(payment_method,order)
8
+ request_params = {"MerchantCode"=>payment_method.preferred_merchant_code,"RefNo"=>order.number,
9
+ "Amount"=>get_amount(order),"Currency"=>order.currency,"ProdDesc"=>order.prod_desc,
10
+ "UserName"=>"","UserEmail"=>"","UserContact"=>"",
11
+ "Remark"=>"","Signature"=>get_request_signature(payment_method,order),"ResponseURL"=>""}
12
+ end
13
+
14
+ def get_amount(order)
15
+ order.total.to_money.format(thousands_separator:',',symbol:false)
16
+ end
17
+
18
+ def get_simplified_amount(order)
19
+ order.total.to_money.format(thousands_separator:false,symbol:false).gsub('.','')
20
+ end
21
+
22
+ # Calculates request signature which is used by Ipay88 to verify if the request is received with right amount from the right merchant
23
+ def get_request_signature(payment_method,order)
24
+ params = {merchant_key:payment_method.preferred_merchant_key,merchant_code:payment_method.preferred_merchant_code,
25
+ ref_no:order.number,simplified_amount:get_simplified_amount(order),currency:order.currency}
26
+ SHA1Encryptor.request_signature(params)
27
+ end
28
+
29
+ # Directly send in response params to generate response signature
30
+ def get_response_signature(params,merchant_key)
31
+ simplified_amount = params["Amount"].gsub(/[\.\,]/,"")
32
+ signature_params = {merchant_key:merchant_key,merchant_code:params["MerchantCode"],payment_id:params["PaymentId"],
33
+ ref_no:params["RefNo"],simplified_amount:simplified_amount,currency:params["Currency"],
34
+ status:params["Status"]}
35
+ SHA1Encryptor.response_signature(signature_params)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ module Spree
2
+ class Ipay88::PaymentMethod < Spree::PaymentMethod
3
+ preference :merchant_code, :string
4
+ preference :merchant_key, :string
5
+
6
+ # This is the url to which we redirect user to pay money through ipay88 gateway
7
+ def url
8
+ "https://www.mobile88.com/epayment/entry.asp"
9
+ end
10
+
11
+ # Auto capture of payments. Leave it true always.
12
+ def auto_capture?
13
+ true
14
+ end
15
+
16
+ # For the sake of Spree you need to add a purchase class with success? and authorization methods,
17
+ # mention the transaction provider class, payment source class and a method type named
18
+ def purchase(amount, source, options = {})
19
+ Class.new do
20
+ def success?;
21
+ true;
22
+ end
23
+
24
+ def authorization;
25
+ nil;
26
+ end
27
+ end.new
28
+ end
29
+
30
+ def provider_class
31
+ Spree::Ipay88::Transaction
32
+ end
33
+
34
+ def payment_source_class
35
+ Spree::Ipay88::Transaction
36
+ end
37
+
38
+ def method_type
39
+ 'ipay88'
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,123 @@
1
+ module Spree
2
+ # Ipay88 transaction class. The model which handles transaction records on the store when done through Ipay88
3
+ class Ipay88::Transaction < ActiveRecord::Base
4
+ belongs_to :order, class_name:"Spree::Order"
5
+ belongs_to :payment_method, class_name:"Spree::Ipay88::PaymentMethod"
6
+ has_many :payments, :as => :source
7
+
8
+ def actions
9
+ ["capture","void"]
10
+ end
11
+
12
+ # Only captures payments that have checkout and pending states
13
+ def can_capture?(payment)
14
+ ['checkout', 'pending'].include?(payment.state)
15
+ end
16
+
17
+ def can_void?(payment)
18
+ payment.state != 'void'
19
+ end
20
+
21
+ # The following methods first update the state from checkout to
22
+ # pending as required by the state machine used by payments class
23
+ # After the transaction, capture payment
24
+
25
+ def capture(payment)
26
+ payment.update_attribute(:state,'pending') if payment.state == 'checkout'
27
+ payment.complete
28
+ true
29
+ end
30
+
31
+ # Method to void payments in case there are issues with transaction
32
+ def void(payment)
33
+ payment.update_attribute(:state,'pending') if payment.state =='checkout'
34
+ payment.complete
35
+ true
36
+ end
37
+
38
+ # Uses state machine provided automatically when you require spree/core
39
+ #TODO update states according to the statuses received after writing controller
40
+
41
+ state_machine :initial=> :created, :use_transactions => false do
42
+
43
+ before_transition :to => :sent, :do => :initialize_state!
44
+
45
+ event :transact do
46
+ transition :created => :sent
47
+ end
48
+
49
+ event :next do
50
+ transition [:sent, :batch] => :authorized, :if => lambda {|txn| txn.status == 1}
51
+ transition [:sent, :batch] => :failed, :if => lambda {|txn| txn.status == 0}
52
+ end
53
+
54
+ after_transition :to => :authorized, :do => :payment_authorized
55
+
56
+ # This is useful when internet failure occurs and
57
+ # after the user retries the payment via a new transaction
58
+ # It is important to note that a new transaction gets created
59
+ # as soon as an old transaction is moved to cancelled state and a user retries the operation.
60
+ # Another way to create a cancelled transaction is
61
+ # when we query the Ipay88 server to know if the transaction is aborted for any reason.
62
+ # In that case since the transaction is already in cancelled state,
63
+ # it won't cause any inconsistency when a new transaction is initiated
64
+
65
+ event :cancel do
66
+ transition all - [:authorized] => :cancelled
67
+ end
68
+ end
69
+
70
+ def payment_authorized
71
+ payment = order.payments.where(:payment_method_id=>self.payment_method.id).first
72
+ payment.update_attributes :source => self, :payment_method_id => self.payment_method.id
73
+ order.next
74
+ order.save
75
+ end
76
+
77
+ def initialize_state!
78
+ if order.confirmation_required? && !order.confirm?
79
+ raise "Order is not in 'confirm' state. Order should be in 'confirm' state before transaction can be sent to CCAvenue"
80
+ end
81
+ this = self
82
+ previous = order.ipay88_transactions.reject {|t| t==this}
83
+ previous.each {|p| p.cancel!}
84
+ # This transaction number is unique only within the scope of order.
85
+ #This is to keep track of succesful and cancelled transactions.
86
+ generate_transaction_number!
87
+ end
88
+
89
+
90
+ def gateway_order_number
91
+ order.number + transaction_number
92
+ end
93
+
94
+ def generate_transaction_number!
95
+ record = true
96
+ # attempts to create a record till you meet an unused transaction number and finaly creates a record
97
+ # whose transaction number is unique
98
+ while record.present?
99
+ random = "#{Array.new(4){rand(4)}.join}"
100
+ record = Spree::Ipay88::Transaction.where(order_id: self.order.id,transaction_number: random)
101
+ end
102
+ self.transaction_number = random
103
+ end
104
+
105
+ def initialize(*args)
106
+ if !args or args.empty?
107
+ super(*args)
108
+ else
109
+ from_admin = args[0].delete('from_admin')
110
+ super(*args)
111
+ if from_admin
112
+ self.amount = self.order.amount
113
+ self.transact
114
+ self.ipay88_amount = self.amount.to_s
115
+ self.next
116
+ end
117
+ end
118
+ end
119
+
120
+
121
+ end
122
+
123
+ end
@@ -0,0 +1,5 @@
1
+ module Spree::Ipay88
2
+ def self.table_name_prefix
3
+ 'spree_ipay88_'
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ Spree::Order.class_eval do
2
+ has_many :ipay88_transactions, :class_name => "Spree::Ipay88::Transaction"
3
+
4
+ def has_authorized_ipay88_transaction?
5
+ ipay88_transactions.select{|txn| txn.authorized?}.present?
6
+ end
7
+
8
+ def cancel_existing_ipay88_transactions!
9
+ ipay88_transactions.each{|t| t.cancel!}
10
+ end
11
+
12
+ def prod_desc
13
+ self.products.map(&:name).join(",")
14
+ end
15
+
16
+ end
@@ -0,0 +1,3 @@
1
+ Spree::PaymentMethod.class_eval do
2
+ has_many :ipay88_transactions, :class_name => "Spree::Ipay88::Transaction"
3
+ end
@@ -0,0 +1,11 @@
1
+ # We want to remove environments select list from payment methods view in admin panel
2
+ Deface::Override.new(:virtual_path => 'spree/admin/payment_methods/_form',
3
+ :name => 'Environment section removal',
4
+ :remove => "[data-hook='environment']"
5
+ )
6
+
7
+ # Ignitor company branding
8
+ Deface::Override.new(:virtual_path => 'spree/admin/payment_methods/_form',
9
+ :insert_before => "[data-hook='name']",
10
+ :text => "<%= render 'branding', payment_method: @payment_method%>",
11
+ :name => 'branding')
@@ -0,0 +1,3 @@
1
+ <% if !payment_method.new_record? && payment_method.provider_class.name.downcase.include?('ipay88') %>
2
+ <%= image_tag 'ignitor_logo.png',alt:'Ignitor Learning' %>
3
+ <% end %>
File without changes
@@ -0,0 +1,2 @@
1
+ <%= @ipay88_error %>
2
+ <%= link_to "Back",edit_order_path(@transaction.order) %>
@@ -0,0 +1,38 @@
1
+ <div id="checkout" data-hook>
2
+ <%= render partial: 'spree/shared/error_messages', locals: { target: @order } %>
3
+ <h3><%= t(:checkout) %></h3>
4
+ <div class="row">
5
+ <div class="">
6
+ <div class="clear"></div>
7
+ <div class="checkout_form">
8
+ <%= form_tag @payment_method.url do %>
9
+ <%
10
+ request_params = request_params(@payment_method,@order)
11
+ redirect_url = gateway_ipay88_callback_url(@transaction, :protocol => 'http')
12
+ %>
13
+
14
+ <div style="padding:10px;background-color:#fcf8e3">
15
+ <p style= "color:red"> * Mandatory Fields</p>
16
+
17
+ <%= hidden_field_tag 'MerchantCode', request_params['MerchantCode'] %>
18
+ <%= hidden_field_tag 'RefNo', request_params['RefNo'] %>
19
+ <%= hidden_field_tag 'Amount', request_params['Amount'] %>
20
+ <%= hidden_field_tag 'Currency', request_params['Currency'] %>
21
+ <%= hidden_field_tag 'ProdDesc', request_params['ProdDesc'] %>
22
+ <%= text_field_tag 'UserName', request_params['UserName'],required:true, placeholder:'Your name' %>
23
+ <%= email_field_tag 'UserEmail', request_params['UserEmail'],required:true, placeholder:'Email' %>
24
+ <%= telephone_field_tag 'UserContact', request_params['UserContact'],required:true,placeholder:"Contact Number" %>
25
+ <%= hidden_field_tag 'Remark', request_params['Remark'] %>
26
+ <%= hidden_field_tag 'Signature', request_params['Signature'] %>
27
+ <%= hidden_field_tag 'ResponseURL', redirect_url %>
28
+
29
+ </div>
30
+
31
+ <%= render :partial => 'spree/checkout/confirm' %>
32
+ <p style="margin: 10px 0;"><%= t(:ipay88_instructional_text) %></p><br/>
33
+ <% end %>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ <div class="clear"></div>
38
+ </div>
@@ -0,0 +1,5 @@
1
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
2
+
3
+ en:
4
+ ipay88_instructional_text: "You will now be redirect to Ipay88's payment gateway"
5
+ success: "Order processed successfully!"
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ match '/gateway/:order_id/ipay88/:payment_method_id' => 'ipay88#show', :as => :gateway_ipay88, via: [:get, :post]
3
+ # Here :id refers to ipay88 transaction ID. The response redirect is dynamically sent to this url
4
+ match '/gateway/ipay88/:id/callback' => 'ipay88#callback', :as => :gateway_ipay88_callback, via: [:get, :post]
5
+ end
@@ -0,0 +1,28 @@
1
+ class CreateSpreeIpay88Transactions < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_ipay88_transactions do |t|
4
+ t.integer :order_id
5
+ t.integer :payment_method_id
6
+ t.string :transaction_number # unique transaction number within the scope of an order
7
+ t.string :ref_no # This will correspond to order.number. It is different from Order#id
8
+ t.decimal :amount, :precision => 8, :scale => 2
9
+ t.string :currency
10
+ t.string :ipay88_amount # For the purpose of cross verifying when needed
11
+ t.string :state # Used by State machine gem to maintain various transaction states
12
+ t.integer :status # Either 0= Failure or 1= Success
13
+ t.string :signature # Correspongs to response signature
14
+ t.string :ipay88_payment_id
15
+ t.string :error_description
16
+ t.string :auth_code # Authorization code from bank as fetched by ipay88
17
+ t.text :remark
18
+ t.string :trans_id # Provided by ipay88
19
+
20
+ t.timestamps
21
+ end
22
+
23
+ add_index :spree_ipay88_transactions, :order_id
24
+ add_index :spree_ipay88_transactions, :trans_id
25
+ add_index :spree_ipay88_transactions, :ref_no
26
+ add_index :spree_ipay88_transactions, :ipay88_payment_id
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ require 'digest/sha1'
2
+ class SHA1Encryptor
3
+
4
+ # Creates signature based on the information needed as per ipay88
5
+ def self.request_signature(params)
6
+ # Ref No. is same as order number
7
+ # amount should be stripped of commas and periods. And it should be only till 2 decimal digits
8
+ cipher = params[:merchant_key]+params[:merchant_code]+
9
+ params[:ref_no]+params[:simplified_amount]+params[:currency]
10
+ self.digest(cipher)
11
+ end
12
+
13
+ # The intended purpose of this method is to verify the signature received from ipay88 for additional security
14
+ def self.response_signature(params)
15
+ # payment id is the one received from ipay88. It is different from spree's payment id
16
+ # status is basically 1 or 0 1= success, 0 = failure. This too, is received from ipay88
17
+ cipher = params[:merchant_key]+params[:merchant_code]+
18
+ params[:payment_id]+params[:ref_no]+params[:simplified_amount]+params[:currency]+params[:status]
19
+ self.digest(cipher)
20
+ end
21
+
22
+
23
+
24
+ def self.digest(target_string)
25
+ digest = Digest::SHA1.digest(target_string)
26
+ # encodes it in base64
27
+ [digest].pack("m").chomp
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ module SpreeIgnitorIpay88
2
+ class Engine < ::Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_ignitor_ipay88'
6
+
7
+ def self.activate
8
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
9
+ Rails.configuration.cache_classes ? require(c) : load(c)
10
+ end
11
+ end
12
+
13
+ config.after_initialize do |app|
14
+ app.config.spree.payment_methods+= [Spree::Ipay88::PaymentMethod]
15
+ end
16
+
17
+ config.to_prepare &method(:activate).to_proc
18
+
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module SpreeIgnitorIpay88
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "spree_ignitor_ipay88/engine"
2
+ require "spree_core"
3
+ require "sha1_encryptor"
4
+
5
+ module SpreeIgnitorIpay88
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :spree_ignitor_ipay88 do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_ignitor_ipay88
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Edutor Technologies
8
+ - Ignitor learning
9
+ - Sriharsha Chintalapati
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2016-08-02 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: spree_core
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '3.0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: sqlite3
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '1.3'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '1.3'
43
+ - !ruby/object:Gem::Dependency
44
+ name: minitest
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '5.9'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '5.9'
57
+ - !ruby/object:Gem::Dependency
58
+ name: gem-release
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '0.7'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '0.7'
71
+ description: Ipay88 is a payment gateway service in South East Asian countries. This
72
+ gem provides integration support for Spree with the gateway
73
+ email:
74
+ - info@ignitorlearning.com
75
+ executables: []
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - MIT-LICENSE
80
+ - Rakefile
81
+ - app/assets/images/ignitor_logo.png
82
+ - app/assets/javascripts/spree/backend/spree_ignitor_ipay88.js
83
+ - app/assets/javascripts/spree/frontend/spree_ignitor_ipay88.js
84
+ - app/assets/stylesheets/spree/backend/spree_ignitor_ipay88.css
85
+ - app/assets/stylesheets/spree/frontend/spree_ignitor_ipay88.css
86
+ - app/controllers/spree/admin/payment_methods_controller_decorator.rb
87
+ - app/controllers/spree/checkout_controller_decorator.rb
88
+ - app/controllers/spree/ipay88_controller.rb
89
+ - app/helpers/spree/ipay88_helper.rb
90
+ - app/models/spree/ipay88.rb
91
+ - app/models/spree/ipay88/payment_method.rb
92
+ - app/models/spree/ipay88/transaction.rb
93
+ - app/models/spree_order_decorator.rb
94
+ - app/models/spree_payment_method_decorator.rb
95
+ - app/overrides/payment_method_view_override.rb
96
+ - app/views/spree/admin/payment_methods/_branding.html.erb
97
+ - app/views/spree/checkout/payment/_ipay88.html.erb
98
+ - app/views/spree/ipay88/error.html.erb
99
+ - app/views/spree/ipay88/show.html.erb
100
+ - config/locales/en.yml
101
+ - config/routes.rb
102
+ - db/migrate/20160726135841_create_spree_ipay88_transactions.rb
103
+ - lib/sha1_encryptor.rb
104
+ - lib/spree_ignitor_ipay88.rb
105
+ - lib/spree_ignitor_ipay88/engine.rb
106
+ - lib/spree_ignitor_ipay88/version.rb
107
+ - lib/tasks/spree_ignitor_ipay88_tasks.rake
108
+ homepage: http://www.ignitorlearning.com
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements:
127
+ - none
128
+ rubyforge_project:
129
+ rubygems_version: 2.4.6
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Ipay88 payment gateway support for Spree commerce engine
133
+ test_files: []