koffsite_payments 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a47eca431ff30d1838ef27788826acb5f3fa5845
4
+ data.tar.gz: 3804a8a36af987ce7d295e9c73802cbc039570e5
5
+ SHA512:
6
+ metadata.gz: c91bb53776a3478a191b8863628469aadea9e0b251dc679147f8df356f1b3adbcb67695f0582ff0f417f1df530985a604ed06fad98caf8884f5dcba87b97be3f
7
+ data.tar.gz: 4a2a5293fe520508f837795820f18dfd309e31fb8a458257b3430f21cca1e38b460e006995ba0ec1178e15da44ce6be85ca9eb597fef83efbfbd4fe1258a2ddf
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005-2014 Tobias Luetke
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.
@@ -0,0 +1,13 @@
1
+ # Offsite Payments
2
+
3
+ Kill Bill fork of https://github.com/Shopify/offsite_payments, with support for new gateways and integrations.
4
+
5
+ All changes are reported upstream - we'll be able to get rid of this repo once the open pull requests have been merged upstream.
6
+
7
+ ## Pull requests
8
+
9
+ * :x: [Альфа-Банк] https://github.com/Shopify/active_merchant/pull/1163 / https://github.com/Shopify/offsite_payments/issues/35
10
+ * :x: https://github.com/Shopify/active_merchant/pull/1187
11
+ * :x: https://github.com/Shopify/active_merchant/pull/1188
12
+ * :x: [QIWI] https://github.com/Shopify/active_merchant/pull/1164 / https://github.com/Shopify/offsite_payments/issues/33
13
+ * :x: [Яндекс] https://github.com/Shopify/active_merchant/pull/1165 / https://github.com/Shopify/offsite_payments/issues/34
@@ -0,0 +1,48 @@
1
+ require 'securerandom'
2
+ require 'cgi'
3
+ require "timeout"
4
+ require "socket"
5
+
6
+ require 'active_support/core_ext/class/delegating_attributes'
7
+
8
+ require 'active_utils/common/network_connection_retries'
9
+ require 'active_utils/common/connection'
10
+ require 'active_utils/common/requires_parameters'
11
+ require 'active_utils/common/country'
12
+ require 'active_utils/common/error'
13
+ require 'active_utils/common/post_data'
14
+ require 'active_utils/common/posts_data'
15
+ require 'active_utils/common/currency_code'
16
+
17
+ require "offsite_payments/helper"
18
+ require "offsite_payments/notification"
19
+ require "offsite_payments/return"
20
+ require "offsite_payments/integrations"
21
+ require "offsite_payments/action_view_helper"
22
+
23
+ I18n.enforce_available_locales = false
24
+
25
+ module OffsitePayments
26
+ # Return the matching integration module
27
+ # You can then get the notification from the module
28
+ # * <tt>bogus</tt>: Bogus - Does nothing (for testing)
29
+ # * <tt>chronopay</tt>: Chronopay
30
+ # * <tt>paypal</tt>: Paypal
31
+ #
32
+ # chronopay = OffsitePayments.integration('chronopay')
33
+ # notification = chronopay.notification(raw_post)
34
+ #
35
+ def self.integration(name)
36
+ Integrations.const_get("#{name.to_s.downcase}".camelize)
37
+ end
38
+
39
+ mattr_accessor :mode
40
+ self.mode = :production
41
+
42
+ # A check to see if we're in test mode
43
+ def self.test?
44
+ self.mode == :test
45
+ end
46
+
47
+ CURRENCIES_WITHOUT_FRACTIONS = [ 'BIF', 'BYR', 'CLP', 'CVE', 'DJF', 'GNF', 'HUF', 'ISK', 'JPY', 'KMF', 'KRW', 'PYG', 'RWF', 'TWD', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF' ]
48
+ end
@@ -0,0 +1,72 @@
1
+ require 'action_pack'
2
+
3
+ module OffsitePayments #:nodoc:
4
+ ActionViewHelperError = Class.new(StandardError)
5
+
6
+ module ActionViewHelper
7
+ # This helper allows the usage of different payment integrations
8
+ # through a single form helper. Payment integrations are the
9
+ # type of service where the user is redirected to the secure
10
+ # site of the service, like Paypal or Chronopay.
11
+ #
12
+ # The helper creates a scope around a payment service helper
13
+ # which provides the specific mapping for that service.
14
+ #
15
+ # <% payment_service_for 1000, 'paypalemail@mystore.com',
16
+ # :amount => 50.00,
17
+ # :currency => 'CAD',
18
+ # :service => :paypal,
19
+ # :html => { :id => 'payment-form' } do |service| %>
20
+ #
21
+ # <% service.customer :first_name => 'Cody',
22
+ # :last_name => 'Fauser',
23
+ # :phone => '(555)555-5555',
24
+ # :email => 'cody@example.com' %>
25
+ #
26
+ # <% service.billing_address :city => 'Ottawa',
27
+ # :address1 => '21 Snowy Brook Lane',
28
+ # :address2 => 'Apt. 36',
29
+ # :state => 'ON',
30
+ # :country => 'CA',
31
+ # :zip => 'K1J1E5' %>
32
+ #
33
+ # <% service.invoice '#1000' %>
34
+ # <% service.shipping '0.00' %>
35
+ # <% service.tax '0.00' %>
36
+ #
37
+ # <% service.notify_url url_for(:only_path => false, :action => 'notify') %>
38
+ # <% service.return_url url_for(:only_path => false, :action => 'done') %>
39
+ # <% service.cancel_return_url 'http://mystore.com' %>
40
+ # <% end %>
41
+ #
42
+ def payment_service_for(order, account, options = {}, &proc)
43
+ raise ArgumentError, "Missing block" unless block_given?
44
+
45
+ integration_module = OffsitePayments::integration(options.delete(:service).to_s)
46
+ service_class = integration_module.const_get('Helper')
47
+
48
+ form_options = options.delete(:html) || {}
49
+ service = service_class.new(order, account, options)
50
+ form_options[:method] = service.form_method
51
+ result = []
52
+ service_url = service.respond_to?(:credential_based_url) ? service.credential_based_url : integration_module.service_url
53
+ result << form_tag(service_url, form_options)
54
+
55
+ result << capture(service, &proc)
56
+
57
+ service.form_fields.each do |field, value|
58
+ result << hidden_field_tag(field, value)
59
+ end
60
+
61
+ service.raw_html_fields.each do |field, value|
62
+ result << "<input id=\"#{field}\" name=\"#{field}\" type=\"hidden\" value=\"#{value}\" />\n"
63
+ end
64
+
65
+ result << '</form>'
66
+ result= result.join("\n")
67
+
68
+ concat(result.respond_to?(:html_safe) ? result.html_safe : result)
69
+ nil
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,119 @@
1
+ module OffsitePayments #:nodoc:
2
+ class Helper #:nodoc:
3
+ attr_reader :fields
4
+ class_attribute :service_url
5
+ class_attribute :mappings
6
+ class_attribute :country_format
7
+ self.country_format = :alpha2
8
+
9
+ # The application making the calls to the gateway
10
+ # Useful for things like the PayPal build notation (BN) id fields
11
+ class_attribute :application_id
12
+ self.application_id = 'ActiveMerchant'
13
+
14
+ def self.inherited(subclass)
15
+ subclass.mappings ||= {}
16
+ end
17
+
18
+ def initialize(order, account, options = {})
19
+ options.assert_valid_keys([:amount, :currency, :test, :credential2, :credential3, :credential4, :country, :account_name, :description, :transaction_type, :authcode, :notify_url, :return_url, :redirect_param, :forward_url])
20
+ @fields = {}
21
+ @raw_html_fields = []
22
+ @test = options[:test]
23
+ self.order = order
24
+ self.account = account
25
+ self.amount = options[:amount]
26
+ self.currency = options[:currency]
27
+ self.credential2 = options[:credential2]
28
+ self.credential3 = options[:credential3]
29
+ self.credential4 = options[:credential4]
30
+ self.notify_url = options[:notify_url]
31
+ self.return_url = options[:return_url]
32
+ self.redirect_param = options[:redirect_param]
33
+ end
34
+
35
+ def self.mapping(attribute, options = {})
36
+ self.mappings[attribute] = options
37
+ end
38
+
39
+ def add_field(name, value)
40
+ return if name.blank? || value.blank?
41
+ @fields[name.to_s] = value.to_s
42
+ end
43
+
44
+ def add_fields(subkey, params = {})
45
+ params.each do |k, v|
46
+ field = mappings[subkey][k]
47
+ add_field(field, v) unless field.blank?
48
+ end
49
+ end
50
+
51
+ # Add a field that has characters that CGI::escape would mangle. Allows
52
+ # for multiple fields with the same name (e.g., to support line items).
53
+ def add_raw_html_field(name, value)
54
+ return if name.blank? || value.blank?
55
+ @raw_html_fields << [name, value]
56
+ end
57
+
58
+ def raw_html_fields
59
+ @raw_html_fields
60
+ end
61
+
62
+ def billing_address(params = {})
63
+ add_address(:billing_address, params)
64
+ end
65
+
66
+ def shipping_address(params = {})
67
+ add_address(:shipping_address, params)
68
+ end
69
+
70
+ def form_fields
71
+ @fields
72
+ end
73
+
74
+ def test?
75
+ @test_mode ||= OffsitePayments.mode == :test || !!@test
76
+ end
77
+
78
+ def form_method
79
+ "POST"
80
+ end
81
+
82
+ private
83
+
84
+ def add_address(key, params)
85
+ return if mappings[key].nil?
86
+
87
+ code = lookup_country_code(params.delete(:country))
88
+ add_field(mappings[key][:country], code)
89
+ add_fields(key, params)
90
+ end
91
+
92
+ def lookup_country_code(name_or_code, format = country_format)
93
+ country = ActiveMerchant::Country.find(name_or_code)
94
+ country.code(format).to_s
95
+ rescue ActiveMerchant::InvalidCountryCodeError
96
+ name_or_code
97
+ end
98
+
99
+ def method_missing(method_id, *args)
100
+ method_id = method_id.to_s.gsub(/=$/, '').to_sym
101
+ # Return and do nothing if the mapping was not found. This allows
102
+ # for easy substitution of the different integrations
103
+ return if mappings[method_id].nil?
104
+
105
+ mapping = mappings[method_id]
106
+
107
+ case mapping
108
+ when Array
109
+ mapping.each{ |field| add_field(field, args.last) }
110
+ when Hash
111
+ options = args.last.is_a?(Hash) ? args.pop : {}
112
+
113
+ mapping.each{ |key, field| add_field(field, options[key]) }
114
+ else
115
+ add_field(mapping, args.last)
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,14 @@
1
+ module OffsitePayments
2
+ module Integrations
3
+ Dir[File.dirname(__FILE__) + '/integrations/*.rb'].each do |f|
4
+ # Get camelized class name
5
+ filename = File.basename(f, '.rb')
6
+
7
+ # Camelize the string to get the class name
8
+ integration_class = filename.camelize.to_sym
9
+
10
+ # Register for autoloading
11
+ autoload integration_class, f
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,245 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module A1agregator
4
+ mattr_accessor :service_url
5
+ self.service_url = 'https://partner.a1agregator.ru/a1lite/input/'
6
+
7
+ mattr_accessor :signature_parameter_name
8
+ self.signature_parameter_name = 'check'
9
+
10
+ def self.notification(*args)
11
+ Notification.new(*args)
12
+ end
13
+
14
+ def self.status(login, password)
15
+ Status.new(login, password)
16
+ end
17
+
18
+ class Helper < OffsitePayments::Helper
19
+ # public key
20
+ mapping :account, 'key'
21
+
22
+ mapping :amount, 'cost'
23
+
24
+ mapping :order, 'order_id'
25
+
26
+ mapping :customer, :email => 'email',
27
+ :phone => 'phone_number'
28
+
29
+ # payment description
30
+ mapping :credential2, 'name'
31
+
32
+ mapping :credential3, 'comment'
33
+
34
+ # on error
35
+ # 1 - raise error
36
+ # 0 - redirect
37
+ mapping :credential4, 'verbose'
38
+ end
39
+
40
+ class Notification < OffsitePayments::Notification
41
+ self.production_ips = [
42
+ '78.108.178.206',
43
+ '79.137.235.129',
44
+ '95.163.96.79',
45
+ '212.24.38.100'
46
+ ]
47
+
48
+ def initialize(*args)
49
+ super
50
+ guess_notification_type
51
+ end
52
+
53
+ # Simple notification request params:
54
+ # tid
55
+ # name
56
+ # comment
57
+ # partner_id
58
+ # service_id
59
+ # order_id
60
+ # type
61
+ # partner_income
62
+ # system_income
63
+
64
+ def complete?
65
+ true
66
+ end
67
+
68
+ def transaction_id
69
+ params['tid']
70
+ end
71
+
72
+ def title
73
+ params['name']
74
+ end
75
+
76
+ def comment
77
+ params['comment']
78
+ end
79
+
80
+ def partner_id
81
+ params['partner_id']
82
+ end
83
+
84
+ def service_id
85
+ params['service_id']
86
+ end
87
+
88
+ def item_id
89
+ params['order_id']
90
+ end
91
+
92
+ def type
93
+ params['type']
94
+ end
95
+
96
+ def partner_income
97
+ params['partner_income']
98
+ end
99
+
100
+ def system_income
101
+ params['system_income']
102
+ end
103
+
104
+ # Additional notification request params:
105
+ # tid
106
+ # name
107
+ # comment
108
+ # partner_id
109
+ # service_id
110
+ # order_id
111
+ # type
112
+ # cost
113
+ # income_total
114
+ # income
115
+ # partner_income
116
+ # system_income
117
+ # command
118
+ # phone_number
119
+ # email
120
+ # resultStr
121
+ # date_created
122
+ # version
123
+ # check
124
+
125
+ def inclome_total
126
+ params['income_total']
127
+ end
128
+
129
+ def income
130
+ params['income']
131
+ end
132
+
133
+ def partner_income
134
+ params['partner_income']
135
+ end
136
+
137
+ def system_income
138
+ params['system_income']
139
+ end
140
+
141
+ def command
142
+ params['command']
143
+ end
144
+
145
+ def phone_number
146
+ params['phone_number']
147
+ end
148
+
149
+ def payer_email
150
+ params['email']
151
+ end
152
+
153
+ def result_string
154
+ params['resultStr']
155
+ end
156
+
157
+ def received_at
158
+ params['date_created']
159
+ end
160
+
161
+ def version
162
+ params['version']
163
+ end
164
+
165
+ def security_key
166
+ params[A1agregator.signature_parameter_name].to_s.downcase
167
+ end
168
+
169
+ # the money amount we received in X.2 decimal.
170
+ alias_method :gross, :system_income
171
+
172
+ def currency
173
+ 'RUB'
174
+ end
175
+
176
+ # Was this a test transaction?
177
+ def test?
178
+ params['test'] == '1'
179
+ end
180
+
181
+ def simple_notification?
182
+ @notification_type == :simple
183
+ end
184
+
185
+ def additional_notification?
186
+ @notification_type == :additional
187
+ end
188
+
189
+ def acknowledge(authcode = nil)
190
+ security_key == signature
191
+ end
192
+
193
+ private
194
+
195
+ def signature
196
+ data = "#{params['tid']}\
197
+ #{params['name']}\
198
+ #{params['comment']}\
199
+ #{params['partner_id']}\
200
+ #{params['service_id']}\
201
+ #{params['order_id']}\
202
+ #{params['type']}\
203
+ #{params['partner_income']}\
204
+ #{params['system_income']}\
205
+ #{params['test']}\
206
+ #{@options[:secret]}"
207
+ Digest::MD5.hexdigest(data)
208
+ end
209
+
210
+ def guess_notification_type
211
+ @notification_type = params['version'] ? :additional : :simple
212
+ end
213
+ end
214
+
215
+ class Status
216
+ include ActiveMerchant::PostsData
217
+
218
+ STATUS_TEST_URL = 'https://partner.a1pay.ru/a1lite/info/'
219
+
220
+ attr_accessor :login, :password
221
+
222
+ def initialize(login, password)
223
+ @login, @password = login, password
224
+ end
225
+
226
+ # agregator provides two methods:
227
+ # by tid - transaction id
228
+ # by order_id & service_id
229
+ def update(options = {})
230
+ data = PostData.new
231
+ data[:user] = @login
232
+ data[:pass] = @password
233
+ if options[:tid]
234
+ data[:tid] = options[:tid]
235
+ else
236
+ data[:ord_id] = options[:ord_id]
237
+ data[:service_id] = options[:service_id]
238
+ end
239
+
240
+ ssl_post(STATUS_TEST_URL, data.to_post_data)
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end