spree_ignitor_ipay88 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 (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: []