koffsite_payments 3.0.0

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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +13 -0
  4. data/lib/offsite_payments.rb +48 -0
  5. data/lib/offsite_payments/action_view_helper.rb +72 -0
  6. data/lib/offsite_payments/helper.rb +119 -0
  7. data/lib/offsite_payments/integrations.rb +14 -0
  8. data/lib/offsite_payments/integrations/a1agregator.rb +245 -0
  9. data/lib/offsite_payments/integrations/authorize_net_sim.rb +580 -0
  10. data/lib/offsite_payments/integrations/bit_pay.rb +150 -0
  11. data/lib/offsite_payments/integrations/bogus.rb +32 -0
  12. data/lib/offsite_payments/integrations/chronopay.rb +283 -0
  13. data/lib/offsite_payments/integrations/citrus.rb +227 -0
  14. data/lib/offsite_payments/integrations/coinbase.rb +166 -0
  15. data/lib/offsite_payments/integrations/direc_pay.rb +339 -0
  16. data/lib/offsite_payments/integrations/directebanking.rb +237 -0
  17. data/lib/offsite_payments/integrations/doku.rb +171 -0
  18. data/lib/offsite_payments/integrations/dotpay.rb +166 -0
  19. data/lib/offsite_payments/integrations/dwolla.rb +160 -0
  20. data/lib/offsite_payments/integrations/e_payment_plans.rb +146 -0
  21. data/lib/offsite_payments/integrations/easy_pay.rb +137 -0
  22. data/lib/offsite_payments/integrations/epay.rb +161 -0
  23. data/lib/offsite_payments/integrations/first_data.rb +133 -0
  24. data/lib/offsite_payments/integrations/gestpay.rb +203 -0
  25. data/lib/offsite_payments/integrations/hi_trust.rb +179 -0
  26. data/lib/offsite_payments/integrations/ipay88.rb +251 -0
  27. data/lib/offsite_payments/integrations/klarna.rb +291 -0
  28. data/lib/offsite_payments/integrations/liqpay.rb +216 -0
  29. data/lib/offsite_payments/integrations/maksuturva.rb +231 -0
  30. data/lib/offsite_payments/integrations/mollie_ideal.rb +216 -0
  31. data/lib/offsite_payments/integrations/moneybookers.rb +199 -0
  32. data/lib/offsite_payments/integrations/nochex.rb +228 -0
  33. data/lib/offsite_payments/integrations/pag_seguro.rb +268 -0
  34. data/lib/offsite_payments/integrations/paxum.rb +114 -0
  35. data/lib/offsite_payments/integrations/pay_fast.rb +269 -0
  36. data/lib/offsite_payments/integrations/pay_u_latam.rb +246 -0
  37. data/lib/offsite_payments/integrations/paydollar.rb +142 -0
  38. data/lib/offsite_payments/integrations/payflow_link.rb +194 -0
  39. data/lib/offsite_payments/integrations/paypal.rb +362 -0
  40. data/lib/offsite_payments/integrations/paypal_payments_advanced.rb +23 -0
  41. data/lib/offsite_payments/integrations/paysbuy.rb +71 -0
  42. data/lib/offsite_payments/integrations/payu_in.rb +266 -0
  43. data/lib/offsite_payments/integrations/payu_in_paisa.rb +46 -0
  44. data/lib/offsite_payments/integrations/platron.rb +153 -0
  45. data/lib/offsite_payments/integrations/pxpay.rb +273 -0
  46. data/lib/offsite_payments/integrations/quickpay.rb +232 -0
  47. data/lib/offsite_payments/integrations/rbkmoney.rb +110 -0
  48. data/lib/offsite_payments/integrations/robokassa.rb +154 -0
  49. data/lib/offsite_payments/integrations/sage_pay_form.rb +425 -0
  50. data/lib/offsite_payments/integrations/two_checkout.rb +329 -0
  51. data/lib/offsite_payments/integrations/universal.rb +181 -0
  52. data/lib/offsite_payments/integrations/valitor.rb +200 -0
  53. data/lib/offsite_payments/integrations/verkkomaksut.rb +143 -0
  54. data/lib/offsite_payments/integrations/web_pay.rb +186 -0
  55. data/lib/offsite_payments/integrations/webmoney.rb +119 -0
  56. data/lib/offsite_payments/integrations/wirecard_checkout_page.rb +359 -0
  57. data/lib/offsite_payments/integrations/world_pay.rb +273 -0
  58. data/lib/offsite_payments/notification.rb +71 -0
  59. data/lib/offsite_payments/return.rb +37 -0
  60. data/lib/offsite_payments/version.rb +3 -0
  61. metadata +268 -0
@@ -0,0 +1,114 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # Documentation:
4
+ # https://www.paxum.com/payment_docs/page.php?name=apiIntroduction
5
+ module Paxum
6
+ mattr_accessor :test_url
7
+ self.test_url = 'https://paxum.com/payment/phrame.php?action=displayProcessPaymentLogin'
8
+
9
+ mattr_accessor :production_url
10
+ self.production_url = 'https://paxum.com/payment/phrame.php?action=displayProcessPaymentLogin'
11
+
12
+ mattr_accessor :signature_parameter_name
13
+ self.signature_parameter_name = 'key'
14
+
15
+ def self.service_url
16
+ mode = OffsitePayments.mode
17
+ case mode
18
+ when :production
19
+ self.production_url
20
+ when :test
21
+ self.test_url
22
+ else
23
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
24
+ end
25
+ end
26
+
27
+ def self.helper(order, account, options = {})
28
+ Helper.new(order, account, options)
29
+ end
30
+
31
+ def self.notification(query_string, options = {})
32
+ Notification.new(query_string, options)
33
+ end
34
+
35
+ module Common
36
+ def generate_signature_string
37
+ @raw_post.slice!(0) if @raw_post.starts_with?("&")
38
+ @raw_post = CGI.unescape(@raw_post)
39
+ @raw_post = "&#{@raw_post}" unless @raw_post.starts_with?("&")
40
+ arr = @raw_post.split('&')
41
+ arr.delete(arr.last)
42
+ data = arr.join('&')
43
+
44
+ (data + secret)
45
+ end
46
+
47
+ def generate_signature
48
+ Digest::MD5.hexdigest(generate_signature_string)
49
+ end
50
+ end
51
+
52
+ class Helper < OffsitePayments::Helper
53
+ include Common
54
+
55
+ def initialize(order, account, options = {})
56
+ @paxum_options = options.dup
57
+ options.delete(:description)
58
+ options.delete(:fail_url)
59
+ options.delete(:success_url)
60
+ options.delete(:result_url)
61
+ super
62
+ add_field "button_type_id", "1"
63
+ add_field "variables", "notify_url=#{@paxum_options[:result_url]}"
64
+ @paxum_options.each do |key, value|
65
+ add_field mappings[key], value
66
+ end
67
+ end
68
+
69
+ def form_fields
70
+ @fields
71
+ end
72
+
73
+ def params
74
+ @fields
75
+ end
76
+
77
+ mapping :account, 'business_email'
78
+ mapping :amount, 'amount'
79
+ mapping :currency, 'currency'
80
+ mapping :order, 'item_id'
81
+ mapping :description, 'item_name'
82
+ mapping :fail_url, 'cancel_url'
83
+ mapping :success_url, 'finish_url'
84
+ mapping :result_url, 'notify_url'
85
+ end
86
+
87
+ class Notification < OffsitePayments::Notification
88
+ include Common
89
+
90
+ def initialize(post, options = {})
91
+ @raw_post = post.dup
92
+ post.slice!(0)
93
+ super
94
+ end
95
+
96
+ def self.recognizes?(params)
97
+ (params.has_key?('transaction_item_id') && params.has_key?('transaction_amount'))
98
+ end
99
+
100
+ def security_key
101
+ params["key"]
102
+ end
103
+
104
+ def secret
105
+ @options[:secret]
106
+ end
107
+
108
+ def acknowledge(authcode = nil)
109
+ (security_key == generate_signature)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,269 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # Documentation:
4
+ # https://www.payfast.co.za/s/std/integration-guide
5
+ module PayFast
6
+ # Overwrite this if you want to change the PayFast sandbox url
7
+ mattr_accessor :process_test_url
8
+ self.process_test_url = 'https://sandbox.payfast.co.za/eng/process'
9
+
10
+ # Overwrite this if you want to change the PayFast production url
11
+ mattr_accessor :process_production_url
12
+ self.process_production_url = 'https://www.payfast.co.za/eng/process'
13
+
14
+ # Overwrite this if you want to change the PayFast sandbox url
15
+ mattr_accessor :validate_test_url
16
+ self.validate_test_url = 'https://sandbox.payfast.co.za/eng/query/validate'
17
+
18
+ # Overwrite this if you want to change the PayFast production url
19
+ mattr_accessor :validate_production_url
20
+ self.validate_production_url = 'https://www.payfast.co.za/eng/query/validate'
21
+
22
+ mattr_accessor :signature_parameter_name
23
+ self.signature_parameter_name = 'signature'
24
+
25
+ def self.service_url
26
+ mode = OffsitePayments.mode
27
+ case mode
28
+ when :production
29
+ self.process_production_url
30
+ when :test
31
+ self.process_test_url
32
+ else
33
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
34
+ end
35
+ end
36
+
37
+ def self.validate_service_url
38
+ mode = OffsitePayments.mode
39
+ case mode
40
+ when :production
41
+ self.validate_production_url
42
+ when :test
43
+ self.validate_test_url
44
+ else
45
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
46
+ end
47
+ end
48
+
49
+ def self.helper(order, account, options = {})
50
+ Helper.new(order, account, options)
51
+ end
52
+
53
+ def self.notification(query_string, options = {})
54
+ Notification.new(query_string, options)
55
+ end
56
+
57
+ def self.return(post, options = {})
58
+ Return.new(post, options)
59
+ end
60
+
61
+ module Common
62
+ def generate_signature(type)
63
+ string = case type
64
+ when :request
65
+ request_signature_string
66
+ when :notify
67
+ notify_signature_string
68
+ end
69
+
70
+ Digest::MD5.hexdigest(string)
71
+ end
72
+
73
+ def request_attributes
74
+ [:merchant_id, :merchant_key, :return_url, :cancel_url,
75
+ :notify_url, :name_first, :name_last, :email_address,
76
+ :payment_id, :amount, :item_name, :item_description,
77
+ :custom_str1, :custom_str2, :custom_str3, :custom_str4,
78
+ :custom_str5, :custom_int1, :custom_int2, :custom_int3,
79
+ :custom_int4, :custom_int5, :email_confirmation,
80
+ :confirmation_address]
81
+ end
82
+
83
+ def request_signature_string
84
+ request_attributes.map do |attr|
85
+ "#{mappings[attr]}=#{CGI.escape(@fields[mappings[attr]])}" if @fields[mappings[attr]].present?
86
+ end.compact.join('&')
87
+ end
88
+
89
+ def notify_signature_string
90
+ params.map do |key, value|
91
+ "#{key}=#{CGI.escape(value)}" unless key == PayFast.signature_parameter_name
92
+ end.compact.join('&')
93
+ end
94
+ end
95
+
96
+ class Helper < OffsitePayments::Helper
97
+ include Common
98
+
99
+ def initialize(order, account, options = {})
100
+ super
101
+ add_field('merchant_id', account)
102
+ add_field('merchant_key', options.delete(:credential2))
103
+ add_field('m_payment_id', order)
104
+ end
105
+
106
+ def form_fields
107
+ @fields
108
+ end
109
+
110
+ def params
111
+ @fields
112
+ end
113
+
114
+ mapping :merchant_id, 'merchant_id'
115
+ mapping :merchant_key, 'merchant_key'
116
+ mapping :return_url, 'return_url'
117
+ mapping :cancel_return_url, 'cancel_url'
118
+ mapping :notify_url, 'notify_url'
119
+ mapping :name_first, 'name_first'
120
+ mapping :name_last, 'name_last'
121
+ mapping :email_address, 'email_address'
122
+ mapping :payment_id, 'm_payment_id'
123
+ mapping :amount, 'amount'
124
+ mapping :item_name, 'item_name'
125
+ mapping :description, 'item_name'
126
+
127
+ mapping :customer, :first_name => 'name_first',
128
+ :last_name => 'name_last',
129
+ :email => 'email_address',
130
+ :phone => 'phone'
131
+
132
+ 5.times { |i| mapping :"custom_str#{i}", "custom_str#{i}" }
133
+ 5.times { |i| mapping :"custom_int#{i}", "custom_int#{i}" }
134
+
135
+ mapping :email_confirmation, 'email_confirmation'
136
+ mapping :confirmation_address, 'confirmation_address'
137
+ end
138
+
139
+ # Parser and handler for incoming ITN from PayFast.
140
+ # The Example shows a typical handler in a rails application.
141
+ #
142
+ # Example
143
+ #
144
+ # class BackendController < ApplicationController
145
+ # include OffsitePayments::Integrations
146
+ #
147
+ # def pay_fast_itn
148
+ # notify = PayFast::Notification.new(request.raw_post)
149
+ #
150
+ # order = Order.find(notify.item_id)
151
+ #
152
+ # if notify.acknowledge
153
+ # begin
154
+ #
155
+ # if notify.complete? and order.total == notify.amount
156
+ # order.status = 'success'
157
+ #
158
+ # shop.ship(order)
159
+ # else
160
+ # logger.error("Failed to verify Paypal's notification, please investigate")
161
+ # end
162
+ #
163
+ # rescue => e
164
+ # order.status = 'failed'
165
+ # raise
166
+ # ensure
167
+ # order.save
168
+ # end
169
+ # end
170
+ #
171
+ # render :nothing
172
+ # end
173
+ # end
174
+ class Notification < OffsitePayments::Notification
175
+ include ActiveMerchant::PostsData
176
+ include Common
177
+
178
+ # Was the transaction complete?
179
+ def complete?
180
+ status == "Completed"
181
+ end
182
+
183
+ # Status of transaction. List of possible values:
184
+ # <tt>COMPLETE</tt>::
185
+ def status
186
+ if params['payment_status'] == "COMPLETE"
187
+ "Completed"
188
+ else
189
+ "Failed"
190
+ end
191
+ end
192
+
193
+ # Id of this transaction (uniq PayFast transaction id)
194
+ def transaction_id
195
+ params['pf_payment_id']
196
+ end
197
+
198
+ # Id of this transaction (uniq Shopify transaction id)
199
+ def item_id
200
+ params['m_payment_id']
201
+ end
202
+
203
+ # The total amount which the payer paid.
204
+ def gross
205
+ params['amount_gross']
206
+ end
207
+
208
+ # The total in fees which was deducted from the amount.
209
+ def fee
210
+ params['amount_fee']
211
+ end
212
+
213
+ # The net amount credited to the receiver's account.
214
+ def amount
215
+ params['amount_net']
216
+ end
217
+
218
+ # The name of the item being charged for.
219
+ def item_name
220
+ params['item_name']
221
+ end
222
+
223
+ # The Merchant ID as given by the PayFast system. Used to uniquely identify the receiver's account.
224
+ def merchant_id
225
+ params['merchant_id']
226
+ end
227
+
228
+ def currency
229
+ nil
230
+ end
231
+
232
+ # Generated hash depends on params order so use OrderedHash instead of Hash
233
+ def empty!
234
+ super
235
+ @params = ActiveSupport::OrderedHash.new
236
+ end
237
+
238
+ # Acknowledge the transaction to PayFast. This method has to be called after a new
239
+ # ITN arrives. PayFast will verify that all the information we received are correct and will return a
240
+ # VERIFIED or INVALID status.
241
+ #
242
+ # Example:
243
+ #
244
+ # def pay_fast_itn
245
+ # notify = PayFastNotification.new(request.raw_post)
246
+ #
247
+ # if notify.acknowledge
248
+ # ... process order ... if notify.complete?
249
+ # else
250
+ # ... log possible hacking attempt ...
251
+ # end
252
+ def acknowledge(authcode = nil)
253
+ if params[PayFast.signature_parameter_name] == generate_signature(:notify)
254
+ response = ssl_post(PayFast.validate_service_url, notify_signature_string,
255
+ 'Content-Type' => "application/x-www-form-urlencoded",
256
+ 'Content-Length' => "#{notify_signature_string.size}"
257
+ )
258
+ raise StandardError.new("Faulty PayFast result: #{response}") unless ['VALID', 'INVALID'].include?(response)
259
+
260
+ response == "VALID"
261
+ end
262
+ end
263
+ end
264
+
265
+ class Return < OffsitePayments::Return
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,246 @@
1
+ require 'builder'
2
+
3
+ module OffsitePayments #:nodoc:
4
+ module Integrations #:nodoc:
5
+ module PayULatam
6
+
7
+ mattr_accessor :test_url
8
+ self.test_url = 'https://stg.api.payulatam.com/payments-api/4.0/service.cgi'
9
+
10
+ mattr_accessor :production_url
11
+ self.production_url = 'https://api.payulatam.com/payments-api/4.0/service.cgi'
12
+
13
+ QUERIES_API_TEST_URL = 'https://stg.api.payulatam.com/reports-api/4.0/service.cgi'
14
+ QUERIES_API_LIVE_URL = 'https://api.payulatam.com/reports-api/4.0/service.cgi'
15
+
16
+ QUERY_COMMANDS = {
17
+ :orderId => 'ORDER_DETAIL',
18
+ :referenceCode => 'ORDER_DETAIL_BY_REFERENCE_CODE',
19
+ :transactionId => 'TRANSACTION_RESPONSE_DETAIL',
20
+ }
21
+
22
+ def self.service_url
23
+ mode = OffsitePayments.mode
24
+ case mode
25
+ when :production
26
+ self.production_url
27
+ when :test
28
+ self.test_url
29
+ else
30
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
31
+ end
32
+ end
33
+
34
+ def self.queries_url
35
+ mode = OffsitePayments.mode
36
+ case mode
37
+ when :production
38
+ QUERIES_API_LIVE_URL
39
+ when :test
40
+ QUERIES_API_TEST_URL
41
+ else
42
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
43
+ end
44
+ end
45
+
46
+ def self.helper(order, account, options = {})
47
+ Helper.new(order, account, options)
48
+ end
49
+
50
+ class Helper < OffsitePayments::Helper
51
+
52
+ mapping :customer,
53
+ :name => 'name',
54
+ :email => 'email',
55
+ :phone => 'phone',
56
+ :dni_number => 'dniNumber'
57
+
58
+ mapping :billing_address,
59
+ :address1 => 'address1',
60
+ :city => 'city',
61
+ :state => 'state',
62
+ :country => 'country'
63
+
64
+ mapping :amount, 'amount'
65
+ mapping :currency, 'currency'
66
+ mapping :order, 'order'
67
+ mapping :description, 'description'
68
+
69
+ mapping :language, 'language'
70
+ mapping :payment_method, 'paymentMethod'
71
+ mapping :expiration_date, 'expirationDate'
72
+
73
+ # These credentials are mandatory:
74
+ #
75
+ # credential2: api_login
76
+ # credential3: api_key
77
+ # credential4: account_id
78
+ def initialize(order, merchant_id, options = {})
79
+ super
80
+ @merchant_id = merchant_id
81
+ @options = options
82
+
83
+ add_field 'language', 'en'
84
+ end
85
+
86
+ def api_login
87
+ @options[:credential2]
88
+ end
89
+
90
+ def api_key
91
+ @options[:credential3]
92
+ end
93
+
94
+ def account_id
95
+ @options[:credential4]
96
+ end
97
+
98
+ def merchant_id
99
+ @merchant_id
100
+ end
101
+
102
+ def form_method
103
+ 'GET'
104
+ end
105
+
106
+ def form_fields
107
+ cash_request = send_request(PayULatam.service_url, build_cash_request)
108
+
109
+ raise ActionViewHelperError, "Invalid response: #{cash_request}" unless success_cash_request_response?(cash_request)
110
+
111
+ {
112
+ :order_id => cash_request['transactionResponse']['orderId'],
113
+ :transaction_id => cash_request['transactionResponse']['transactionId'],
114
+ :url => cash_request['transactionResponse']['extraParameters']['URL_PAYMENT_RECEIPT_HTML'],
115
+ :expiration_date => cash_request['transactionResponse']['extraParameters']['EXPIRATION_DATE'],
116
+ }
117
+ end
118
+
119
+ def order_status(order_id)
120
+ request_status = send_request(PayULatam.queries_url, build_query_request(:orderId, order_id))
121
+
122
+ raise ActionViewHelperError, "Invalid response: #{request_status}" unless success_response?(request_status)
123
+ # Not found?
124
+ return nil if request_status['result'].nil? or request_status['result']['payload'].nil?
125
+
126
+ {
127
+ :order_id => request_status['result']['payload']['id'],
128
+ :status => request_status['result']['payload']['status'],
129
+ :reference_code => request_status['result']['payload']['referenceCode'],
130
+ :description => request_status['result']['payload']['description']
131
+ }
132
+ end
133
+
134
+ def transaction_status(transaction_id)
135
+ request_status = send_request(PayULatam.queries_url, build_query_request(:transactionId, transaction_id))
136
+
137
+ raise ActionViewHelperError, "Invalid response: #{request_status}" unless success_response?(request_status)
138
+ # Not found?
139
+ return nil if request_status['result'].nil? or request_status['result']['payload'].nil?
140
+
141
+ {
142
+ :status => request_status['result']['payload']['state'],
143
+ :traceability_code => request_status['result']['payload']['trazabilityCode'],
144
+ :authorization => request_status['result']['payload']['authorizationCode']
145
+ }
146
+ end
147
+
148
+ def orders_statuses(reference_code)
149
+ request_status = send_request(PayULatam.queries_url, build_query_request(:referenceCode, reference_code))
150
+
151
+ raise ActionViewHelperError, "Invalid response: #{request_status}" unless success_response?(request_status)
152
+ # Not found?
153
+ return nil if request_status['result'].nil?
154
+
155
+ request_status['result']['payload']
156
+ end
157
+
158
+ private
159
+
160
+ def send_request(url, request_body)
161
+ uri = URI.parse(url)
162
+ http = Net::HTTP.new(uri.host, uri.port)
163
+ http.use_ssl = true
164
+ # PayULatam's test server has an improperly installed cert
165
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if test?
166
+
167
+ request = Net::HTTP::Post.new(uri.request_uri)
168
+ request['Accept'] = 'application/json'
169
+ request.content_type = 'application/json'
170
+ request.body = request_body
171
+
172
+ response = http.request(request)
173
+ JSON.parse(response.body)
174
+ rescue JSON::ParserError
175
+ response.body
176
+ end
177
+
178
+ def build_cash_request
179
+ shipping_address = {}
180
+ shipping_address[:street1] = @fields['address1'] unless @fields['address1'].nil?
181
+ shipping_address[:city] = @fields['city'] unless @fields['city'].nil?
182
+ shipping_address[:state] = @fields['state'] unless @fields['state'].nil?
183
+ shipping_address[:country] = @fields['country'] unless @fields['country'].nil?
184
+ shipping_address[:phone] = @fields['phone'] unless @fields['phone'].nil?
185
+
186
+ buyer = {}
187
+ buyer[:fullName] = @fields['name'] unless @fields['name'].nil?
188
+ buyer[:emailAddress] = @fields['email'] unless @fields['email'].nil?
189
+ buyer[:dniNumber] = @fields['dniNumber'] unless @fields['dniNumber'].nil?
190
+ buyer[:shippingAddress] = shipping_address
191
+
192
+ order = {}
193
+ order[:accountId] = account_id
194
+ order[:referenceCode] = @fields['order']
195
+ order[:description] = @fields['description']
196
+ order[:language] = @fields['language']
197
+ order[:signature] = signature
198
+ order[:shippingAddress] = {:country => @fields['country']} unless @fields['country'].nil?
199
+ order[:buyer] = buyer
200
+ order[:additionalValues] = {:TX_VALUE => {:value => @fields['amount'].to_i, :currency => @fields['currency']}}
201
+
202
+ transaction = {}
203
+ transaction[:order] = order
204
+ transaction[:type] = 'AUTHORIZATION_AND_CAPTURE'
205
+ transaction[:paymentMethod] = @fields['paymentMethod']
206
+ transaction[:expirationDate] = @fields['expirationDate'] unless @fields['expirationDate'].nil?
207
+
208
+ request = build_base_request('SUBMIT_TRANSACTION')
209
+ request[:transaction] = transaction
210
+
211
+ request.to_json
212
+ end
213
+
214
+ def build_query_request(key, value)
215
+ request = build_base_request(QUERY_COMMANDS[key])
216
+ request[:details] = {key => value}
217
+
218
+ request.to_json
219
+ end
220
+
221
+ def build_base_request(command)
222
+ request = {}
223
+ request[:language] = @fields['language']
224
+ request[:command] = command
225
+ # Should always be false, even in test mode
226
+ request[:test] = 'false'
227
+ request[:merchant] = {:apiLogin => api_login, :apiKey => api_key}
228
+ request
229
+ end
230
+
231
+ def signature
232
+ raw = "#{api_key}~#{merchant_id}~#{@fields['order']}~#{@fields['amount']}~#{@fields['currency']}"
233
+ Digest::MD5.hexdigest(raw)
234
+ end
235
+
236
+ def success_cash_request_response?(cash_request_response)
237
+ success_response?(cash_request_response) and cash_request_response['transactionResponse'].is_a?(Hash) and cash_request_response['transactionResponse']['errorCode'].nil?
238
+ end
239
+
240
+ def success_response?(response)
241
+ response.is_a?(Hash) and response['code'] == 'SUCCESS' and response['error'].nil?
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end