offsite_payments 2.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 (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,237 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Directebanking
4
+ # Supported countries:
5
+ # Germany - DE
6
+ # Austria - AT
7
+ # Belgium - BE
8
+ # Netherlands - NL
9
+ # Switzerland - CH
10
+ # Great Britain - GB
11
+
12
+ # Overwrite this if you want to change the directebanking test url
13
+ mattr_accessor :test_url
14
+ self.test_url = 'https://www.directebanking.com/payment/start'
15
+
16
+ # Overwrite this if you want to change the directebanking production url
17
+ mattr_accessor :production_url
18
+ self.production_url = 'https://www.directebanking.com/payment/start'
19
+
20
+ def self.service_url
21
+ mode = OffsitePayments.mode
22
+ case mode
23
+ when :production
24
+ self.production_url
25
+ when :test
26
+ self.test_url
27
+ else
28
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
29
+ end
30
+ end
31
+
32
+ def self.notification(post, options = {})
33
+ Notification.new(post, options)
34
+ end
35
+
36
+ def self.return(post, options = {})
37
+ Return.new(post, options)
38
+ end
39
+
40
+ class Helper < OffsitePayments::Helper
41
+ # All credentials are mandatory and need to be set
42
+ #
43
+ # credential1: User ID
44
+ # credential2: Project ID
45
+ # credential3: Project Password (Algorithm: SH1)
46
+ # credential4: Notification Password (Algorithm: SH1)
47
+ def initialize(order, account, options = {})
48
+ super
49
+ add_field('user_variable_0', order)
50
+ add_field('project_id', options[:credential2])
51
+ @project_password = options[:credential3]
52
+ end
53
+
54
+ SIGNATURE_FIELDS = [
55
+ :user_id,
56
+ :project_id,
57
+ :sender_holder,
58
+ :sender_account_number,
59
+ :sender_bank_code,
60
+ :sender_country_id,
61
+ :amount,
62
+ :currency_id,
63
+ :reason_1,
64
+ :reason_2,
65
+ :user_variable_0,
66
+ :user_variable_1,
67
+ :user_variable_2,
68
+ :user_variable_3,
69
+ :user_variable_4,
70
+ :user_variable_5
71
+ ]
72
+
73
+ SIGNATURE_IGNORE_AT_METHOD_CREATION_FIELDS = [
74
+ :user_id,
75
+ :amount,
76
+ :project_id,
77
+ :currency_id,
78
+ :user_variable_0,
79
+ :user_variable_1,
80
+ :user_variable_2,
81
+ :user_variable_3
82
+ ]
83
+
84
+ SIGNATURE_FIELDS.each do |key|
85
+ if !SIGNATURE_IGNORE_AT_METHOD_CREATION_FIELDS.include?(key)
86
+ mapping "#{key}".to_sym, "#{key.to_s}"
87
+ end
88
+ end
89
+
90
+ # Need to format the amount to have 2 decimal places
91
+ def amount=(money)
92
+ cents = money.respond_to?(:cents) ? money.cents : money
93
+ raise ArgumentError, "amount must be a Money object or an integer" if money.is_a?(String)
94
+ raise ActionViewHelperError, "amount must be greater than $0.00" if cents.to_i <= 0
95
+
96
+ add_field mappings[:amount], sprintf("%.2f", cents.to_f/100)
97
+ end
98
+
99
+ def generate_signature_string
100
+ # format of signature: user_id|project_id|sender_holder|sender_account_number|sender_bank_code| sender_country_id|amount|currency_id|reason_1|reason_2|user_variable_0|user_variable_1|user_variable_2|user_variable_3|user_variable_4|user_variable_5|project_password
101
+ SIGNATURE_FIELDS.map {|key| @fields[key.to_s]} * "|" + "|#{@project_password}"
102
+ end
103
+
104
+ def generate_signature
105
+ Digest::SHA1.hexdigest(generate_signature_string)
106
+ end
107
+
108
+ def form_fields
109
+ @fields.merge('hash' => generate_signature)
110
+ end
111
+
112
+ mapping :account, 'user_id'
113
+ mapping :amount, 'amount'
114
+ mapping :currency, 'currency_id'
115
+ mapping :description, 'reason_1'
116
+
117
+ mapping :return_url, 'user_variable_1'
118
+ mapping :cancel_return_url, 'user_variable_2'
119
+ mapping :notify_url, 'user_variable_3'
120
+ end
121
+
122
+ class Notification < OffsitePayments::Notification
123
+ def initialize(data, options)
124
+ if options[:credential4].nil?
125
+ raise ArgumentError, "You need to provide the notification password (SH1) as the option :credential4 to verify that the notification originated from Directebanking (Payment Networks AG)"
126
+ end
127
+ super
128
+ end
129
+
130
+ def complete?
131
+ status == 'Completed'
132
+ end
133
+
134
+ def item_id
135
+ params['user_variable_0']
136
+ end
137
+
138
+ def transaction_id
139
+ params['transaction']
140
+ end
141
+
142
+ # When was this payment received by the client.
143
+ def received_at
144
+ Time.parse(params['created']) if params['created']
145
+ end
146
+
147
+ # the money amount we received in X.2 decimal.
148
+ def gross
149
+ "%.2f" % params['amount'].to_f
150
+ end
151
+
152
+ def status
153
+ 'Completed'
154
+ end
155
+
156
+ def currency
157
+ params['currency_id']
158
+ end
159
+
160
+ def test?
161
+ params['sender_bank_name'] == 'Testbank'
162
+ end
163
+
164
+ # for verifying the signature of the URL parameters
165
+ PAYMENT_HOOK_SIGNATURE_FIELDS = [
166
+ :transaction,
167
+ :user_id,
168
+ :project_id,
169
+ :sender_holder,
170
+ :sender_account_number,
171
+ :sender_bank_code,
172
+ :sender_bank_name,
173
+ :sender_bank_bic,
174
+ :sender_iban,
175
+ :sender_country_id,
176
+ :recipient_holder,
177
+ :recipient_account_number,
178
+ :recipient_bank_code,
179
+ :recipient_bank_name,
180
+ :recipient_bank_bic,
181
+ :recipient_iban,
182
+ :recipient_country_id,
183
+ :international_transaction,
184
+ :amount,
185
+ :currency_id,
186
+ :reason_1,
187
+ :reason_2,
188
+ :security_criteria,
189
+ :user_variable_0,
190
+ :user_variable_1,
191
+ :user_variable_2,
192
+ :user_variable_3,
193
+ :user_variable_4,
194
+ :user_variable_5,
195
+ :created
196
+ ]
197
+
198
+ PAYMENT_HOOK_IGNORE_AT_METHOD_CREATION_FIELDS = [
199
+ :transaction,
200
+ :amount,
201
+ :currency_id,
202
+ :user_variable_0,
203
+ :user_variable_1,
204
+ :user_variable_2,
205
+ :user_variable_3,
206
+ :created
207
+ ]
208
+
209
+ # Provide access to raw fields
210
+ PAYMENT_HOOK_SIGNATURE_FIELDS.each do |key|
211
+ if !PAYMENT_HOOK_IGNORE_AT_METHOD_CREATION_FIELDS.include?(key)
212
+ define_method(key.to_s) do
213
+ params[key.to_s]
214
+ end
215
+ end
216
+ end
217
+
218
+ def generate_signature_string
219
+ #format is: transaction|user_id|project_id|sender_holder|sender_account_number|sender_bank_code|sender_bank_name|sender_bank_bic|sender_iban|sender_country_id|recipient_holder|recipient_account_number|recipient_bank_code|recipient_bank_name|recipient_bank_bic|recipient_iban|recipient_country_id|international_transaction|amount|currency_id|reason_1|reason_2|security_criteria|user_variable_0|user_variable_1|user_variable_2|user_variable_3|user_variable_4|user_variable_5|created|notification_password
220
+ PAYMENT_HOOK_SIGNATURE_FIELDS.map {|key| params[key.to_s]} * "|" + "|#{@options[:credential4]}"
221
+ end
222
+
223
+ def generate_signature
224
+ Digest::SHA1.hexdigest(generate_signature_string)
225
+ end
226
+
227
+ def acknowledge(authcode = nil)
228
+ # signature_is_valid?
229
+ generate_signature.to_s == params['hash'].to_s
230
+ end
231
+ end
232
+
233
+ class Return < OffsitePayments::Return
234
+ end
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,171 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Doku
4
+ def self.service_url
5
+ 'https://apps.myshortcart.com/payment/request-payment/'
6
+ end
7
+
8
+ def self.notification(post, options = {})
9
+ Notification.new(post, options)
10
+ end
11
+
12
+ def self.return(post, options = {})
13
+ Return.new(post, options)
14
+ end
15
+
16
+ # # Example.
17
+ #
18
+ # payment_service_for('ORDER_ID', 'DOKU_STORE_ID', :service => :doku, :amount => 155_000, :shared_key => 'DOKU_SHARED_KEY') do |service|
19
+ #
20
+ # service.customer :name => 'Ismail Danuarta',
21
+ # :email => 'ismail.danuarta@gmail.com',
22
+ # :mobile_phone => '085779280093',
23
+ # :working_phone => '0215150555',
24
+ # :home_phone => '0215150555',
25
+ # :birth_date => '1991-09-11'
26
+ #
27
+ # service.billing_address :city => 'Jakarta Selatan',
28
+ # :address => 'Jl. Jendral Sudirman kav 59, Plaza Asia Office Park Unit 3',
29
+ # :state => 'DKI Jakarta',
30
+ # :zip => '12190',
31
+ # :country => 'ID'
32
+
33
+ # service.shipping_address :city => 'Jakarta',
34
+ # :address => 'Jl. Jendral Sudirman kav 59, Plaza Asia Office Park Unit 3',
35
+ # :state => 'DKI Jakarta',
36
+ # :zip => '12190',
37
+ # :country => 'ID'
38
+ #
39
+ # service.url 'http://yourstore.com'
40
+ #
41
+ # end
42
+ #
43
+ class Helper < OffsitePayments::Helper
44
+ def initialize(order, account, options = {})
45
+ @shared_key = options.delete(:credential2)
46
+ @transidmerchant = order
47
+ super
48
+ end
49
+
50
+ def form_fields
51
+ add_field 'WORDS', words
52
+ add_field 'BASKET', basket
53
+ add_field 'TRANSIDMERCHANT', @transidmerchant
54
+ @fields
55
+ end
56
+
57
+ def customer(params = {})
58
+ add_field mappings[:customer][:name], "#{params[:first_name]} #{params[:last_name]}"
59
+ add_field mappings[:customer][:email], params[:email]
60
+ add_field mappings[:customer][:phone], params[:phone]
61
+ add_field mappings[:customer][:mobile_phone], params[:mobile_phone]
62
+ add_field mappings[:customer][:working_phone], params[:working_phone]
63
+ add_field mappings[:customer][:birth_date], params[:birth_date]
64
+ end
65
+
66
+ mapping :account, 'STOREID'
67
+ mapping :amount, 'AMOUNT'
68
+ mapping :cancel_return_url, 'URL'
69
+
70
+
71
+ mapping :customer, :name => 'CNAME',
72
+ :email => 'CEMAIL',
73
+ :phone => 'CHPHONE',
74
+ :mobile_phone => 'CMPHONE',
75
+ :working_phone => 'CWPHONE',
76
+ :birth_date => 'BIRTHDATE'
77
+
78
+ mapping :billing_address, :city => 'CCITY',
79
+ :address1 => 'CADDRESS',
80
+ :state => 'CSTATE',
81
+ :zip => 'CZIPCODE',
82
+ :country => 'CCOUNTRY'
83
+
84
+ mapping :shipping_address, :city => 'SCITY',
85
+ :address1 => 'SADDRESS',
86
+ :state => 'SSTATE',
87
+ :zip => 'SZIPCODE',
88
+ :country => 'SCOUNTRY'
89
+
90
+ private
91
+
92
+ def basket
93
+ "Checkout #{@transidmerchant},#{@fields['AMOUNT']},1,#{@fields['AMOUNT']}"
94
+ end
95
+
96
+ def words
97
+ @words ||= Digest::SHA1.hexdigest("#{ @fields['AMOUNT'] }#{ @shared_key }#{ @transidmerchant }")
98
+ end
99
+
100
+ def add_address(key, params)
101
+ return if mappings[key].nil?
102
+
103
+ code = lookup_country_code(params.delete(:country), :numeric)
104
+ add_field(mappings[key][:country], code)
105
+ add_fields(key, params)
106
+ end
107
+ end
108
+
109
+ class Notification < OffsitePayments::Notification
110
+ self.production_ips = ['103.10.128.11', '103.10.128.14']
111
+
112
+ def complete?
113
+ status.present?
114
+ end
115
+
116
+ def item_id
117
+ params['TRANSIDMERCHANT']
118
+ end
119
+
120
+ def gross
121
+ params['AMOUNT']
122
+ end
123
+
124
+ def status
125
+ case params['RESULT']
126
+ when 'Success'
127
+ 'Completed'
128
+ when 'Fail'
129
+ 'Failed'
130
+ end
131
+ end
132
+
133
+ def currency
134
+ 'IDR'
135
+ end
136
+
137
+ def words
138
+ params['WORDS']
139
+ end
140
+
141
+ def type
142
+ if words && params['STOREID']
143
+ 'verify'
144
+ elsif status
145
+ 'notify'
146
+ end
147
+ end
148
+
149
+ # no unique ID is generated by Doku at any point in the process,
150
+ # so use the same as the original order number.
151
+ def transaction_id
152
+ params['TRANSIDMERCHANT']
153
+ end
154
+
155
+ def acknowledge(authcode = nil)
156
+ case type
157
+ when 'verify'
158
+ words == Digest::SHA1.hexdigest("#{gross}#{@options[:credential2]}#{item_id}")
159
+ when 'notify'
160
+ true
161
+ else
162
+ false
163
+ end
164
+ end
165
+ end
166
+
167
+ class Return < OffsitePayments::Return
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,166 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Dotpay
4
+ mattr_accessor :service_url
5
+ self.service_url = 'https://ssl.dotpay.pl'
6
+
7
+ def self.notification(post, options = {})
8
+ Notification.new(post, options)
9
+ end
10
+
11
+ def self.return(post, options = {})
12
+ Return.new(post, options)
13
+ end
14
+
15
+ class Helper < OffsitePayments::Helper
16
+ def initialize(order, account, options = {})
17
+ options = {:currency => 'PLN'}.merge options
18
+
19
+ super
20
+
21
+ add_field('channel', '0')
22
+ add_field('ch_lock', '0')
23
+ add_field('lang', 'PL')
24
+ add_field('onlinetransfer', '0')
25
+ add_field('tax', '0')
26
+ add_field('type', '2')
27
+ end
28
+
29
+ mapping :account, 'id'
30
+ mapping :amount, 'amount'
31
+
32
+ mapping :billing_address, :street => 'street',
33
+ :street_n1 => 'street_n1',
34
+ :street_n2 => 'street_n2',
35
+ :addr2 => 'addr2',
36
+ :addr3 => 'addr3',
37
+ :city => 'city',
38
+ :postcode => 'postcode',
39
+ :phone => 'phone',
40
+ :country => 'country'
41
+
42
+ mapping :buttontext, 'buttontext'
43
+ mapping :channel, 'channel'
44
+ mapping :ch_lock, 'ch_lock'
45
+ mapping :code, 'code'
46
+ mapping :control, 'control'
47
+ mapping :currency, 'currency'
48
+
49
+ mapping :customer, :firstname => 'firstname',
50
+ :lastname => 'lastname',
51
+ :email => 'email'
52
+
53
+ mapping :description, 'description'
54
+ mapping :lang, 'lang'
55
+ mapping :onlinetransfer, 'onlinetransfer'
56
+ mapping :order, 'description'
57
+ mapping :p_email, 'p_email'
58
+ mapping :p_info, 'p_info'
59
+ mapping :tax, 'tax'
60
+ mapping :type, 'type'
61
+ mapping :url, 'url'
62
+ mapping :urlc, 'urlc'
63
+
64
+ def billing_address(params = {})
65
+ country = lookup_country_code(params.delete(:country) { 'POL' }, :alpha3)
66
+ add_field(mappings[:billing_address][:country], country)
67
+
68
+ # Everything else
69
+ params.each do |k, v|
70
+ field = mappings[:billing_address][k]
71
+ add_field(field, v) unless field.nil?
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def lookup_country_code(name_or_code, format = country_format)
78
+ country = ActiveMerchant::Country.find(name_or_code)
79
+ country.code(format).to_s
80
+ rescue ActiveMerchant::InvalidCountryCodeError
81
+ name_or_code
82
+ end
83
+ end
84
+
85
+ class Notification < OffsitePayments::Notification
86
+ def complete?
87
+ status == 'OK' && %w(2 4 5).include?(t_status)
88
+ end
89
+
90
+ def currency
91
+ orginal_amount.split(' ')[1]
92
+ end
93
+
94
+ # the money amount we received in X.2 decimal.
95
+ def gross
96
+ params['amount']
97
+ end
98
+
99
+ def pin=(value)
100
+ @options[:pin] = value
101
+ end
102
+
103
+ def status
104
+ params['status']
105
+ end
106
+
107
+ def test?
108
+ params['t_id'].match('.*-TST\d+') ? true : false
109
+ end
110
+
111
+ PAYMENT_HOOK_FIELDS = [
112
+ :id,
113
+ :control,
114
+ :t_id,
115
+ :orginal_amount,
116
+ :email,
117
+ :service,
118
+ :code,
119
+ :username,
120
+ :password,
121
+ :t_status,
122
+ :description,
123
+ :md5,
124
+ :p_info,
125
+ :p_email,
126
+ :t_date
127
+ ]
128
+
129
+ PAYMENT_HOOK_SIGNATURE_FIELDS = [
130
+ :id,
131
+ :control,
132
+ :t_id,
133
+ :amount,
134
+ :email,
135
+ :service,
136
+ :code,
137
+ :username,
138
+ :password,
139
+ :t_status
140
+ ]
141
+
142
+ # Provide access to raw fields
143
+ PAYMENT_HOOK_FIELDS.each do |key|
144
+ define_method(key.to_s) do
145
+ params[key.to_s]
146
+ end
147
+ end
148
+
149
+ def generate_signature_string
150
+ "#{@options[:pin]}:" + PAYMENT_HOOK_SIGNATURE_FIELDS.map {|key| params[key.to_s]} * ":"
151
+ end
152
+
153
+ def generate_signature
154
+ Digest::MD5.hexdigest(generate_signature_string)
155
+ end
156
+
157
+ def acknowledge(authcode = nil)
158
+ generate_signature.to_s == md5.to_s
159
+ end
160
+ end
161
+
162
+ class Return < OffsitePayments::Return
163
+ end
164
+ end
165
+ end
166
+ end