offsite_payments 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +70 -0
  4. data/lib/offsite_payments.rb +46 -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/direc_pay.rb +339 -0
  15. data/lib/offsite_payments/integrations/directebanking.rb +237 -0
  16. data/lib/offsite_payments/integrations/doku.rb +171 -0
  17. data/lib/offsite_payments/integrations/dotpay.rb +166 -0
  18. data/lib/offsite_payments/integrations/dwolla.rb +160 -0
  19. data/lib/offsite_payments/integrations/e_payment_plans.rb +146 -0
  20. data/lib/offsite_payments/integrations/easy_pay.rb +137 -0
  21. data/lib/offsite_payments/integrations/epay.rb +161 -0
  22. data/lib/offsite_payments/integrations/first_data.rb +133 -0
  23. data/lib/offsite_payments/integrations/gestpay.rb +201 -0
  24. data/lib/offsite_payments/integrations/hi_trust.rb +179 -0
  25. data/lib/offsite_payments/integrations/ipay88.rb +240 -0
  26. data/lib/offsite_payments/integrations/klarna.rb +291 -0
  27. data/lib/offsite_payments/integrations/liqpay.rb +216 -0
  28. data/lib/offsite_payments/integrations/maksuturva.rb +231 -0
  29. data/lib/offsite_payments/integrations/mollie_ideal.rb +213 -0
  30. data/lib/offsite_payments/integrations/moneybookers.rb +199 -0
  31. data/lib/offsite_payments/integrations/nochex.rb +228 -0
  32. data/lib/offsite_payments/integrations/pag_seguro.rb +255 -0
  33. data/lib/offsite_payments/integrations/paxum.rb +114 -0
  34. data/lib/offsite_payments/integrations/pay_fast.rb +269 -0
  35. data/lib/offsite_payments/integrations/paydollar.rb +142 -0
  36. data/lib/offsite_payments/integrations/payflow_link.rb +194 -0
  37. data/lib/offsite_payments/integrations/paypal.rb +362 -0
  38. data/lib/offsite_payments/integrations/paypal_payments_advanced.rb +23 -0
  39. data/lib/offsite_payments/integrations/paysbuy.rb +71 -0
  40. data/lib/offsite_payments/integrations/payu_in.rb +266 -0
  41. data/lib/offsite_payments/integrations/payu_in_paisa.rb +46 -0
  42. data/lib/offsite_payments/integrations/platron.rb +153 -0
  43. data/lib/offsite_payments/integrations/pxpay.rb +271 -0
  44. data/lib/offsite_payments/integrations/quickpay.rb +232 -0
  45. data/lib/offsite_payments/integrations/rbkmoney.rb +110 -0
  46. data/lib/offsite_payments/integrations/robokassa.rb +154 -0
  47. data/lib/offsite_payments/integrations/sage_pay_form.rb +425 -0
  48. data/lib/offsite_payments/integrations/two_checkout.rb +332 -0
  49. data/lib/offsite_payments/integrations/universal.rb +180 -0
  50. data/lib/offsite_payments/integrations/valitor.rb +200 -0
  51. data/lib/offsite_payments/integrations/verkkomaksut.rb +143 -0
  52. data/lib/offsite_payments/integrations/web_pay.rb +186 -0
  53. data/lib/offsite_payments/integrations/webmoney.rb +119 -0
  54. data/lib/offsite_payments/integrations/wirecard_checkout_page.rb +359 -0
  55. data/lib/offsite_payments/integrations/world_pay.rb +273 -0
  56. data/lib/offsite_payments/notification.rb +71 -0
  57. data/lib/offsite_payments/return.rb +37 -0
  58. data/lib/offsite_payments/version.rb +3 -0
  59. metadata +270 -0
@@ -0,0 +1,119 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # Documentation:
4
+ # http://wiki.webmoney.ru/projects/webmoney/wiki/Web_Merchant_Interface
5
+ module Webmoney
6
+ mattr_accessor :test_url
7
+ self.test_url = "https://merchant.webmoney.ru/lmi/payment.asp"
8
+
9
+ mattr_accessor :production_url
10
+ self.production_url = "https://merchant.webmoney.ru/lmi/payment.asp"
11
+
12
+ mattr_accessor :signature_parameter_name
13
+ self.signature_parameter_name = 'LMI_HASH'
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
+ "#{params['LMI_PAYEE_PURSE']}#{params['LMI_PAYMENT_AMOUNT']}#{params['LMI_PAYMENT_NO']}#{params['LMI_MODE']}#{params['LMI_SYS_INVS_NO']}#{params['LMI_SYS_TRANS_NO']}#{params['LMI_SYS_TRANS_DATE']}#{secret}#{params['LMI_PAYER_PURSE']}#{params['LMI_PAYER_WM']}"
38
+ end
39
+
40
+ def generate_signature
41
+ Digest::MD5.hexdigest(generate_signature_string).upcase
42
+ end
43
+ end
44
+
45
+ class Helper < OffsitePayments::Helper
46
+ include Common
47
+
48
+ def initialize(order, account, options = {})
49
+ @webmoney_options = options.dup
50
+ options.delete(:description)
51
+ options.delete(:fail_url)
52
+ options.delete(:success_url)
53
+ options.delete(:result_url)
54
+ super
55
+ @webmoney_options.each do |key, value|
56
+ add_field mappings[key], value
57
+ end
58
+ end
59
+
60
+ def form_fields
61
+ @fields
62
+ end
63
+
64
+ def params
65
+ @fields
66
+ end
67
+
68
+ mapping :account, 'LMI_PAYEE_PURSE'
69
+ mapping :amount, 'LMI_PAYMENT_AMOUNT'
70
+ mapping :order, 'LMI_PAYMENT_NO'
71
+ mapping :description, 'LMI_PAYMENT_DESC'
72
+ mapping :fail_url, 'LMI_FAIL_URL'
73
+ mapping :success_url, 'LMI_SUCCESS_URL'
74
+ mapping :result_url, 'LMI_RESULT_URL'
75
+ mapping :debug, 'LMI_SIM_MODE'
76
+ end
77
+
78
+ class Notification < OffsitePayments::Notification
79
+ include Common
80
+
81
+ def recognizes?
82
+ (params.has_key?('LMI_PAYMENT_NO') && params.has_key?('LMI_PAYMENT_AMOUNT'))
83
+ end
84
+
85
+ def amount
86
+ BigDecimal.new(gross)
87
+ end
88
+
89
+ def key_present?
90
+ params["LMI_HASH"].present?
91
+ end
92
+
93
+ def item_id
94
+ params['LMI_PAYMENT_NO']
95
+ end
96
+
97
+ def gross
98
+ params['LMI_PAYMENT_AMOUNT']
99
+ end
100
+
101
+ def security_key
102
+ params["LMI_HASH"]
103
+ end
104
+
105
+ def secret
106
+ @options[:secret]
107
+ end
108
+
109
+ def acknowledge(authcode = nil)
110
+ (security_key == generate_signature)
111
+ end
112
+
113
+ def success_response(*args)
114
+ {:nothing => true}
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,359 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # Shop System Plugins - Terms of use
4
+ #
5
+ # This terms of use regulates warranty and liability between Wirecard Central Eastern Europe (subsequently referred to as WDCEE) and it's
6
+ # contractual partners (subsequently referred to as customer or customers) which are related to the use of plugins provided by WDCEE.
7
+ #
8
+ # The Plugin is provided by WDCEE free of charge for it's customers and must be used for the purpose of WDCEE's payment platform
9
+ # integration only. It explicitly is not part of the general contract between WDCEE and it's customer. The plugin has successfully been tested
10
+ # under specific circumstances which are defined as the shopsystem's standard configuration (vendor's delivery state). The Customer is
11
+ # responsible for testing the plugin's functionality before putting it into production environment.
12
+ # The customer uses the plugin at own risk. WDCEE does not guarantee it's full functionality neither does WDCEE assume liability for any
13
+ # disadvantage related to the use of this plugin. By installing the plugin into the shopsystem the customer agrees to the terms of use.
14
+ # Please do not use this plugin if you do not agree to the terms of use!
15
+ module WirecardCheckoutPage
16
+ mattr_accessor :service_url
17
+ self.service_url = 'https://checkout.wirecard.com/page/init.php'
18
+
19
+ def self.notification(post, options)
20
+ Notification.new(post, options)
21
+ end
22
+
23
+ def self.return(postdata, options)
24
+ Return.new(postdata, options)
25
+ end
26
+
27
+ module Common
28
+ mattr_accessor :paymenttypes
29
+ self.paymenttypes = %w(
30
+ SELECT
31
+ CCARD
32
+ BANCONTACT_MISTERCASH
33
+ C2P
34
+ CCARD-MOTO
35
+ EKONTO
36
+ ELV
37
+ EPS
38
+ GIROPAY
39
+ IDL
40
+ INSTALLMENT
41
+ INSTANTBANK
42
+ INVOICE
43
+ MAESTRO
44
+ MONETA
45
+ MPASS
46
+ PRZELEWY24
47
+ PAYPAL
48
+ PBX
49
+ POLI
50
+ PSC
51
+ QUICK
52
+ SKRILLDIRECT
53
+ SKRILLWALLET
54
+ SOFORTUEBERWEISUNG)
55
+
56
+ def message
57
+ @message
58
+ end
59
+
60
+ def verify_response(params, secret)
61
+ logstr = ''
62
+ params.each { |key, value|
63
+ logstr += "#{key} #{value}\n"
64
+ }
65
+
66
+ @paymentstate = 'FAILURE'
67
+
68
+ unless params.has_key?('paymentState')
69
+ @message = "paymentState is missing"
70
+ return false
71
+ end
72
+
73
+ if params['paymentState'] == 'SUCCESS' || params['paymentState'] == 'PENDING'
74
+ unless params.has_key?('responseFingerprint')
75
+ @message = "responseFingerprint is missing"
76
+ return false
77
+ end
78
+
79
+ unless params.has_key?('responseFingerprintOrder')
80
+ @message = "responseFingerprintOrder is missing"
81
+ return false
82
+ end
83
+
84
+ end
85
+
86
+ if params['paymentState'] == 'SUCCESS' || params['paymentState'] == 'PENDING'
87
+ fields = params['responseFingerprintOrder'].split(",")
88
+ values = ''
89
+ fields.each { |f|
90
+ values += f == 'secret' ? secret : params[f]
91
+ }
92
+
93
+
94
+ if Digest::MD5.hexdigest(values) != params['responseFingerprint']
95
+ @message = "responseFingerprint verification failed"
96
+ return false
97
+ end
98
+ end
99
+
100
+ @paymentstate = params['paymentState']
101
+ true
102
+ end
103
+ end
104
+
105
+ class Helper < OffsitePayments::Helper
106
+ include Common
107
+
108
+ PLUGIN_NAME = 'ActiveMerchant_WirecardCheckoutPage'
109
+ PLUGIN_VERSION = '1.0.0'
110
+
111
+ # Replace with the real mapping
112
+ mapping :account, 'customerId'
113
+ mapping :amount, 'amount'
114
+
115
+ mapping :order, 'xActiveMerchantOrderId'
116
+
117
+ mapping :customer, :first_name => 'consumerBillingFirstName',
118
+ :last_name => 'consumerBillingLastName',
119
+ :email => 'consumerEmail',
120
+ :phone => 'consumerBillingPhone',
121
+ :ipaddress => 'consumerIpAddress',
122
+ :user_agent => 'consumerUserAgent',
123
+ :fax => 'consumerBillingFax',
124
+ :birthdate => 'consumerBirthDate' # mandatory for INVOICE and INSTALLMENT
125
+
126
+ mapping :billing_address, :city => 'consumerBillingCity',
127
+ :address1 => 'consumerBillingAddress1',
128
+ :address2 => 'consumerBillingAddress2',
129
+ :state => 'consumerBillingState',
130
+ :zip => 'consumerBillingZipCode',
131
+ :country => 'consumerBillingCountry'
132
+
133
+ mapping :shipping_address, :first_name => 'consumerShippingFirstName',
134
+ :last_name => 'consumerShippingLastName',
135
+ :address1 => 'consumerShippingAddress1',
136
+ :address2 => 'consumerShippingAddress2',
137
+ :city => 'consumerShippingCity',
138
+ :state => 'consumerShippingState',
139
+ :country => 'consumerShippingCountry',
140
+ :zip => 'consumerShippingZipCode',
141
+ :phone => 'consumerShippingPhone',
142
+ :fax => 'consumerShippingFax'
143
+
144
+ mapping :currency, 'currency'
145
+ mapping :language, 'language' # language for displayed texts on payment page
146
+
147
+ mapping :description, 'orderDescription' # unique description of the consumer's order in a human readable form
148
+
149
+ mapping :shop_service_url, 'serviceUrl' # URL of your service page containing contact information
150
+
151
+ mapping :notify_url, 'confirmUrl'
152
+ mapping :return_url, 'successUrl'
153
+
154
+ # defaulting to return_url
155
+ mapping :cancel_return_url, 'cancelUrl'
156
+ mapping :pending_url, 'pendingUrl'
157
+ mapping :failure_url, 'failureUrl'
158
+
159
+ # optional parameters
160
+ mapping :window_name, 'windowName' # window.name of browser window where payment page is opened
161
+ mapping :duplicate_request_check, 'duplicateRequestCheck' # check for duplicate requests done by your consumer
162
+ mapping :customer_statement, 'customerStatement' # text displayed on invoice of financial institution of your consumer
163
+ mapping :order_reference, 'orderReference' # unique order reference id sent from merchant to financial institution
164
+ mapping :display_text, 'displayText' # text displayed to your consumer within the payment page
165
+ mapping :image_url, 'imageUrl' # URL of your web shop where your web shop logo is located
166
+ mapping :max_retries, 'maxRetries' # maximum number of attempted payments for the same order
167
+ mapping :auto_deposit, 'autoDeposit' # enable automated debiting of payments
168
+ mapping :financial_institution, 'financialInstitution' # based on pre-selected payment type a sub-selection of financial institutions regarding to pre-selected payment type
169
+
170
+ # not used
171
+ mapping :tax, ''
172
+ mapping :shipping, ''
173
+
174
+ def initialize(order, customer_id, options = {})
175
+ @paymenttype = options.delete(:paymenttype)
176
+
177
+ raise "Unknown Paymenttype: " + @paymenttype if paymenttypes.find_index(@paymenttype) == nil
178
+
179
+ @secret = options.delete(:secret)
180
+ @customer_id = customer_id
181
+ @shop_id = options.delete(:shop_id)
182
+ super
183
+ end
184
+
185
+ def add_version(shop_name, shop_version)
186
+ add_field('pluginVersion', Base64.encode64(shop_name + ';' + shop_version + ';ActiveMerchant;' + PLUGIN_NAME + ';' + PLUGIN_VERSION))
187
+ end
188
+
189
+ def add_standard_fields
190
+ addfields = {}
191
+ addfields['shopId'] = @shop_id if !@shop_id.blank?
192
+ addfields['paymentType'] = @paymenttype
193
+
194
+ addfields[mappings[:pending_url]] = @fields[mappings[:return_url]] unless @fields.has_key?(mappings[:pending_url])
195
+ addfields[mappings[:cancel_return_url]] = @fields[mappings[:return_url]] unless @fields.has_key?(mappings[:cancel_return_url])
196
+ addfields[mappings[:failure_url]] = @fields[mappings[:return_url]] unless @fields.has_key?(mappings[:failure_url])
197
+
198
+ addfields
199
+ end
200
+
201
+ def add_request_fingerprint(fpfields)
202
+ addfields = {}
203
+ fingerprint_order = %w(secret)
204
+ fingerprint_values = @secret.to_s
205
+ fpfields.each { |key, value|
206
+ next if key == 'pluginVersion'
207
+ fingerprint_order.append key
208
+ fingerprint_values += value.to_s
209
+ }
210
+
211
+ fingerprint_order.append 'requestFingerprintOrder'
212
+ fingerprint_values += fingerprint_order.join(',')
213
+
214
+ addfields['requestFingerprintOrder'] = fingerprint_order.join(',')
215
+ addfields['requestFingerprint'] = Digest::MD5.hexdigest(fingerprint_values)
216
+
217
+ addfields
218
+ end
219
+
220
+ def form_fields
221
+ result = {}
222
+ result.merge!(@fields)
223
+ result.merge!(add_standard_fields)
224
+ result.merge!(add_request_fingerprint(result))
225
+ result
226
+ end
227
+
228
+ def secret
229
+ @secret
230
+ end
231
+
232
+ def customer_id
233
+ @customer_id
234
+ end
235
+
236
+ def shop_id
237
+ @shop_id
238
+ end
239
+ end
240
+
241
+ class Notification < OffsitePayments::Notification
242
+ include Common
243
+
244
+ def complete?
245
+ @paymentstate == 'SUCCESS'
246
+ end
247
+
248
+ def item_id
249
+ params['xActiveMerchantOrderId']
250
+ end
251
+
252
+ def transaction_id
253
+ params['orderNumber']
254
+ end
255
+
256
+ # When was this payment received by the client.
257
+ def received_at
258
+ nil
259
+ end
260
+
261
+ # the money amount we received in X.2 decimal.
262
+ def gross
263
+ params['amount']
264
+ end
265
+
266
+ # Was this a test transaction?
267
+ def test?
268
+ false
269
+ end
270
+
271
+ def status
272
+ case @paymentstate
273
+ when 'SUCCESS'
274
+ 'Completed'
275
+ when 'PENDING'
276
+ 'Pending'
277
+ when 'CANCEL'
278
+ 'Cancelled'
279
+ when 'FAILURE'
280
+ 'Failed'
281
+ else
282
+ 'Error'
283
+ end
284
+ end
285
+
286
+ def status_code
287
+ @paymentstate
288
+ end
289
+
290
+ # Acknowledge the transaction to WirecardCheckoutPage. This method has to be called after a new
291
+ # apc arrives. WirecardCheckoutPage will verify that all the information we received are correct and will return a
292
+ # ok or a fail.
293
+ #
294
+ # Example:
295
+ #
296
+ # def ipn
297
+ # notify = WirecardCheckoutPageNotification.new(request.raw_post, options)
298
+ #
299
+ # if notify.acknowledge
300
+ # ... process order ... if notify.complete?
301
+ # else
302
+ # ... log possible hacking attempt ...
303
+ # end
304
+ def acknowledge
305
+ verify_response(params, @options[:secret])
306
+ end
307
+
308
+ def response(umessage = nil)
309
+ if @message || umessage
310
+ '<QPAY-CONFIRMATION-RESPONSE result="NOK" message="' + CGI.escapeHTML(umessage ? umessage : @message) + '"/>'
311
+ else
312
+ '<QPAY-CONFIRMATION-RESPONSE result="OK"/>'
313
+ end
314
+ end
315
+
316
+ def method_missing(method_id, *args)
317
+ return params[method_id.to_s] if params.has_key?(method_id.to_s)
318
+ end
319
+
320
+ private
321
+
322
+ # Take the posted data and move the relevant data into a hash
323
+ def parse(post)
324
+ @raw = post.to_s
325
+ for line in @raw.split('&')
326
+ key, value = *line.scan( %r{^([A-Za-z0-9_.]+)\=(.*)$} ).flatten
327
+ params[key] = CGI.unescape(value)
328
+ end
329
+ end
330
+ end
331
+
332
+ class Return < OffsitePayments::Return
333
+ include Common
334
+
335
+ def initialize(postdata, options = {})
336
+ @params = parse(postdata)
337
+ @options = options
338
+ verify_response(@params, options[:secret])
339
+ end
340
+
341
+ def success?
342
+ @paymentstate == 'SUCCESS'
343
+ end
344
+
345
+ def cancelled?
346
+ @paymentstate == 'CANCEL'
347
+ end
348
+
349
+ def pending?
350
+ @paymentstate == 'PENDING'
351
+ end
352
+
353
+ def method_missing(method_id, *args)
354
+ return params[method_id.to_s] if params.has_key?(method_id.to_s)
355
+ end
356
+ end
357
+ end
358
+ end
359
+ end