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,200 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ module Valitor
4
+ mattr_accessor :test_url
5
+ self.test_url = 'https://testvefverslun.valitor.is/1_1/'
6
+
7
+ mattr_accessor :production_url
8
+ self.production_url = 'https://vefverslun.valitor.is/1_1/'
9
+
10
+ def self.test?
11
+ (OffsitePayments.mode == :test)
12
+ end
13
+
14
+ def self.service_url
15
+ (test? ? test_url : production_url)
16
+ end
17
+
18
+ def self.notification(params, options={})
19
+ Notification.new(params, options.merge(:test => test?))
20
+ end
21
+
22
+ def self.return(query_string, options={})
23
+ Return.new(query_string, options.merge(:test => test?))
24
+ end
25
+
26
+ class Helper < OffsitePayments::Helper
27
+ include ActiveMerchant::RequiresParameters
28
+
29
+ DEFAULT_SUCCESS_TEXT = "The transaction has been completed."
30
+
31
+ def initialize(order, account, options={})
32
+ options[:currency] ||= 'ISK'
33
+ super
34
+ add_field 'Adeinsheimild', '0'
35
+ add_field 'KaupandaUpplysingar', '0'
36
+ add_field 'SlokkvaHaus', '0'
37
+ @security_number = options[:credential2]
38
+ @amount = options[:amount]
39
+ @order = order
40
+ end
41
+
42
+ mapping :account, 'VefverslunID'
43
+ mapping :currency, 'Gjaldmidill'
44
+
45
+ mapping :order, 'Tilvisunarnumer'
46
+
47
+ mapping :notify_url, 'SlodTokstAdGjaldfaeraServerSide'
48
+ mapping :return_url, 'SlodTokstAdGjaldfaera'
49
+ mapping :cancel_return_url, 'SlodNotandiHaettirVid'
50
+
51
+ mapping :success_text, 'SlodTokstAdGjaldfaeraTexti'
52
+
53
+ mapping :language, 'Lang'
54
+
55
+ def authorize_only
56
+ add_field 'Adeinsheimild', '1'
57
+ end
58
+
59
+ def collect_customer_info
60
+ add_field 'KaupandaUpplysingar', '1'
61
+ end
62
+
63
+ def hide_header
64
+ add_field 'SlokkvaHaus', '1'
65
+ end
66
+
67
+ def product(id, options={})
68
+ raise ArgumentError, "Product id #{id} is not an integer between 1 and 500" unless id.to_i > 0 && id.to_i <= 500
69
+ requires!(options, :amount, :description)
70
+ options.assert_valid_keys([:description, :quantity, :amount, :discount])
71
+
72
+ add_field("Vara_#{id}_Verd", format_amount(options[:amount], @fields[mappings[:currency]]))
73
+ add_field("Vara_#{id}_Fjoldi", options[:quantity] || "1")
74
+
75
+ add_field("Vara_#{id}_Lysing", options[:description]) if options[:description]
76
+ add_field("Vara_#{id}_Afslattur", options[:discount] || '0')
77
+
78
+ @products ||= []
79
+ @products << id.to_i
80
+ end
81
+
82
+ def signature
83
+ raise ArgumentError, "Security number not set" unless @security_number
84
+ parts = [@security_number, @fields['Adeinsheimild']]
85
+ @products.sort.uniq.each do |id|
86
+ parts.concat(["Vara_#{id}_Fjoldi", "Vara_#{id}_Verd", "Vara_#{id}_Afslattur"].collect{|e| @fields[e]})
87
+ end if @products
88
+ parts.concat(%w(VefverslunID Tilvisunarnumer SlodTokstAdGjaldfaera SlodTokstAdGjaldfaeraServerSide Gjaldmidill).collect{|e| @fields[e]})
89
+ Digest::MD5.hexdigest(parts.compact.join(''))
90
+ end
91
+
92
+ def form_fields
93
+ product(1, :amount => @amount, :description => @order) if Array(@products).empty?
94
+ @fields[mappings[:success_text]] ||= DEFAULT_SUCCESS_TEXT
95
+ @fields.merge('RafraenUndirskrift' => signature)
96
+ end
97
+
98
+ def format_amount(amount, currency)
99
+ OffsitePayments::CURRENCIES_WITHOUT_FRACTIONS.include?(currency) ? amount.to_f.round : sprintf("%.2f", amount)
100
+ end
101
+ end
102
+
103
+ module ResponseFields
104
+ def success?
105
+ status == 'Completed'
106
+ end
107
+ alias :complete? :success?
108
+
109
+ def test?
110
+ @options[:test]
111
+ end
112
+
113
+ def item_id
114
+ params['Tilvisunarnumer']
115
+ end
116
+ alias :order :item_id
117
+
118
+ def transaction_id
119
+ params['VefverslunSalaID']
120
+ end
121
+
122
+ def currency
123
+ nil
124
+ end
125
+
126
+ def status
127
+ "Completed" if acknowledge
128
+ end
129
+
130
+ def received_at
131
+ Time.parse(params['Dagsetning'].to_s)
132
+ end
133
+
134
+ def gross
135
+ "%0.2f" % params['Upphaed'].to_s.sub(',', '.')
136
+ end
137
+
138
+ def card_type
139
+ params['Kortategund']
140
+ end
141
+
142
+ def card_last_four
143
+ params['KortnumerSidustu']
144
+ end
145
+
146
+ def authorization_number
147
+ params['Heimildarnumer']
148
+ end
149
+
150
+ def transaction_number
151
+ params['Faerslunumer']
152
+ end
153
+
154
+ def customer_name
155
+ params['Nafn']
156
+ end
157
+
158
+ def customer_address
159
+ params['Heimilisfang']
160
+ end
161
+
162
+ def customer_zip
163
+ params['Postnumer']
164
+ end
165
+
166
+ def customer_city
167
+ params['Stadur']
168
+ end
169
+
170
+ def customer_country
171
+ params['Land']
172
+ end
173
+
174
+ def customer_email
175
+ params['Tolvupostfang']
176
+ end
177
+
178
+ def customer_comment
179
+ params['Athugasemdir']
180
+ end
181
+
182
+ def password
183
+ @options[:credential2]
184
+ end
185
+
186
+ def acknowledge(authcode = nil)
187
+ password ? Digest::MD5.hexdigest("#{password}#{order}") == params['RafraenUndirskriftSvar'] : true
188
+ end
189
+ end
190
+
191
+ class Notification < OffsitePayments::Notification
192
+ include ResponseFields
193
+ end
194
+
195
+ class Return < OffsitePayments::Return
196
+ include ResponseFields
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,143 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # Usage, see the blog post here: http://blog.kiskolabs.com/post/22374612968/understanding-active-merchant-integrations and E1 API documentation here: http://docs.verkkomaksut.fi/
4
+ module Verkkomaksut
5
+ mattr_accessor :service_url
6
+ self.service_url = 'https://payment.verkkomaksut.fi/'
7
+
8
+ def self.notification(post)
9
+ Notification.new(post)
10
+ end
11
+
12
+ class Helper < OffsitePayments::Helper
13
+ # Fetches the md5secret and adds MERCHANT_ID and API TYPE to the form
14
+ def initialize(order, account, options = {})
15
+ md5secret options.delete(:credential2)
16
+ super
17
+ add_field("MERCHANT_ID", account)
18
+ add_field("TYPE", "E1")
19
+ end
20
+
21
+ def md5secret(value)
22
+ @md5secret = value
23
+ end
24
+
25
+ # Adds the AUTHCODE to the form
26
+ def form_fields
27
+ @fields.merge("AUTHCODE" => generate_md5string)
28
+ end
29
+
30
+ # Calculates the AUTHCODE
31
+ def generate_md5string
32
+ fields = [@md5secret, @fields["MERCHANT_ID"], @fields["ORDER_NUMBER"], @fields["REFERENCE_NUMBER"], @fields["ORDER_DESCRIPTION"], @fields["CURRENCY"], @fields["RETURN_ADDRESS"], @fields["CANCEL_ADDRESS"], @fields["PENDING_ADDRESS"],
33
+ @fields["NOTIFY_ADDRESS"], @fields["TYPE"], @fields["CULTURE"], @fields["PRESELECTED_METHOD"], @fields["MODE"], @fields["VISIBLE_METHODS"], @fields["GROUP"], @fields["CONTACT_TELNO"], @fields["CONTACT_CELLNO"],
34
+ @fields["CONTACT_EMAIL"], @fields["CONTACT_FIRSTNAME"], @fields["CONTACT_LASTNAME"], @fields["CONTACT_COMPANY"], @fields["CONTACT_ADDR_STREET"], @fields["CONTACT_ADDR_ZIP"], @fields["CONTACT_ADDR_CITY"], @fields["CONTACT_ADDR_COUNTRY"], @fields["INCLUDE_VAT"],
35
+ @fields["ITEMS"]]
36
+
37
+ (0..@fields["ITEMS"].to_i-1).each do |i|
38
+ fields += [@fields["ITEM_TITLE[#{i}]"], @fields["ITEM_NO[#{i}]"], @fields["ITEM_AMOUNT[#{i}]"], @fields["ITEM_PRICE[#{i}]"], @fields["ITEM_TAX[#{i}]"], @fields["ITEM_DISCOUNT[#{i}]"], @fields["ITEM_TYPE[#{i}]"]]
39
+ end
40
+
41
+ fields = fields.join("|")
42
+
43
+ return Digest::MD5.hexdigest(fields).upcase
44
+ end
45
+
46
+ # Mappings
47
+ mapping :merchant_id, "MERCHANT_ID"
48
+ mapping :order, "ORDER_NUMBER"
49
+ mapping :reference_number, "REFERENCE_NUMBER"
50
+ mapping :customer, :first_name => "CONTACT_FIRSTNAME",
51
+ :last_name => "CONTACT_LASTNAME",
52
+ :email => "CONTACT_EMAIL",
53
+ :phone => "CONTACT_CELLNO",
54
+ :tellno => "CONTACT_TELLNO",
55
+ :company => "CONTACT_COMPANY"
56
+
57
+
58
+ mapping :billing_address, :city => "CONTACT_ADDR_CITY",
59
+ :address1 => "CONTACT_ADDR_STREET",
60
+ :address2 => "",
61
+ :state => "",
62
+ :zip => "CONTACT_ADDR_ZIP",
63
+ :country => "CONTACT_ADDR_COUNTRY"
64
+
65
+ mapping :notify_url, "NOTIFY_ADDRESS"
66
+ mapping :currency, "CURRENCY"
67
+ mapping :return_url, "RETURN_ADDRESS"
68
+ mapping :cancel_return_url, "CANCEL_ADDRESS"
69
+ mapping :description, "ORDER_DESCRIPTION"
70
+ mapping :tax, ""
71
+ mapping :shipping, ""
72
+ mapping :include_vat, "INCLUDE_VAT"
73
+ mapping :pending_address, "PENDING_ADDRESS"
74
+ mapping :culture, "CULTURE"
75
+ mapping :items, "ITEMS"
76
+ mapping :preselected_method, "PRESELECTED_METHOD"
77
+ mapping :mode, "MODE"
78
+ mapping :visible_methods, "VISIBLE_METHODS"
79
+ mapping :group, "GROUP"
80
+
81
+ (0..499.to_i).each do |i|
82
+ mapping "item_title_#{i}".to_sym, "ITEM_TITLE[#{i}]"
83
+ mapping "item_no_#{i}".to_sym, "ITEM_NO[#{i}]"
84
+ mapping "item_amount_#{i}".to_sym, "ITEM_AMOUNT[#{i}]"
85
+ mapping "item_price_#{i}".to_sym, "ITEM_PRICE[#{i}]"
86
+ mapping "item_tax_#{i}".to_sym, "ITEM_TAX[#{i}]"
87
+ mapping "item_discount_#{i}".to_sym, "ITEM_DISCOUNT[#{i}]"
88
+ mapping "item_type_#{i}".to_sym, "ITEM_TYPE[#{i}]"
89
+ end
90
+ end
91
+
92
+ class Notification < OffsitePayments::Notification
93
+ # Is the payment complete or not. Verkkomaksut only has two statuses: random string or 0000000000 which means pending
94
+ def complete?
95
+ params['PAID'] != "0000000000"
96
+ end
97
+
98
+ # Order id
99
+ def order_id
100
+ params['ORDER_NUMBER']
101
+ end
102
+
103
+ # Payment method used
104
+ def method
105
+ params['METHOD']
106
+ end
107
+
108
+ # When was this payment received by the client.
109
+ def received_at
110
+ params['TIMESTAMP']
111
+ end
112
+
113
+ # Security key got from Verkkomaksut
114
+ def security_key
115
+ params['RETURN_AUTHCODE']
116
+ end
117
+
118
+ # Another way of asking the payment status
119
+ def status
120
+ if complete?
121
+ "PAID"
122
+ else
123
+ "PENDING"
124
+ end
125
+ end
126
+
127
+ # Acknowledges the payment. If the authcodes match, returns true.
128
+ def acknowledge(authcode = nil)
129
+ return_authcode = [params["ORDER_NUMBER"], params["TIMESTAMP"], params["PAID"], params["METHOD"], authcode].join("|")
130
+ Digest::MD5.hexdigest(return_authcode).upcase == params["RETURN_AUTHCODE"]
131
+ end
132
+
133
+ private
134
+
135
+ def parse(post)
136
+ post.each do |key, value|
137
+ params[key] = value
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,186 @@
1
+ module OffsitePayments #:nodoc:
2
+ module Integrations #:nodoc:
3
+ # Documentation: You will get it after registration steps here:
4
+ # http://reg.webpay.by/registration-form.php
5
+ module WebPay
6
+ # Overwrite this if you want to change the WebPay sandbox url
7
+ mattr_accessor :test_url
8
+ self.test_url = 'https://secure.sandbox.webpay.by:8843'
9
+
10
+ # Overwrite this if you want to change the WebPay production url
11
+ mattr_accessor :production_url
12
+ self.production_url = 'https://secure.webpay.by'
13
+
14
+ mattr_accessor :signature_parameter_name
15
+ self.signature_parameter_name = 'wsb_signature'
16
+
17
+ def self.service_url
18
+ mode = OffsitePayments.mode
19
+ case mode
20
+ when :production
21
+ self.production_url
22
+ when :test
23
+ self.test_url
24
+ else
25
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
26
+ end
27
+ end
28
+
29
+ def self.helper(order, account, options = {})
30
+ Helper.new(order, account, options)
31
+ end
32
+
33
+ def self.notification(query_string, options = {})
34
+ Notification.new(query_string, options)
35
+ end
36
+
37
+ module Common
38
+ def generate_signature(type)
39
+ string = case type
40
+ when :request
41
+ request_signature_string
42
+ when :notify
43
+ notify_signature_string
44
+ end
45
+ if type != :notify && @fields[mappings[:version]] == '2'
46
+ Digest::SHA1.hexdigest(string)
47
+ else
48
+ Digest::MD5.hexdigest(string)
49
+ end
50
+ end
51
+
52
+ def request_signature_string
53
+ [
54
+ @fields[mappings[:seed]],
55
+ @fields[mappings[:account]],
56
+ @fields[mappings[:order]],
57
+ @fields[mappings[:test]],
58
+ @fields[mappings[:currency]],
59
+ @fields[mappings[:amount]],
60
+ secret
61
+ ].join
62
+ end
63
+
64
+ def notify_signature_string
65
+ [
66
+ params['batch_timestamp'],
67
+ params['currency_id'],
68
+ params['amount'],
69
+ params['payment_method'],
70
+ params['order_id'],
71
+ params['site_order_id'],
72
+ params['transaction_id'],
73
+ params['payment_type'],
74
+ params['rrn'],
75
+ secret
76
+ ].join
77
+ end
78
+ end
79
+
80
+ class Helper < OffsitePayments::Helper
81
+ include Common
82
+
83
+ def initialize(order, account, options = {})
84
+ @md5secret = options.delete(:secret)
85
+ @line_item_count = 0
86
+ super
87
+ end
88
+
89
+ def form_fields
90
+ @fields.merge(OffsitePayments::Integrations::WebPay.signature_parameter_name => generate_signature(:request))
91
+ end
92
+
93
+ def params
94
+ @fields
95
+ end
96
+
97
+ def secret
98
+ @md5secret
99
+ end
100
+
101
+ def add_line_item(options)
102
+ options.each do |key, value|
103
+ add_field("wsb_invoice_item_#{key}[#{@line_item_count}]", value)
104
+ end
105
+
106
+ @line_item_count += 1
107
+ end
108
+
109
+ def calculate_total
110
+ sum = 0
111
+
112
+ @line_item_count.times do |i|
113
+ sum += @fields["wsb_invoice_item_quantity[#{i}]"].to_i * @fields["wsb_invoice_item_price[#{i}]"].to_i
114
+ end
115
+
116
+ sum + @fields[mappings[:tax]].to_i + @fields[mappings[:shipping_price]].to_i - @fields[mappings[:discount_price]].to_i
117
+ end
118
+
119
+ mapping :scart, '*scart'
120
+ mapping :account, 'wsb_storeid'
121
+ mapping :store, 'wsb_store'
122
+ mapping :order, 'wsb_order_num'
123
+ mapping :currency, 'wsb_currency_id'
124
+ mapping :version, 'wsb_version'
125
+ mapping :language, 'wsb_language_id'
126
+ mapping :seed, 'wsb_seed'
127
+ mapping :success_url, 'wsb_return_url'
128
+ mapping :cancel_url, 'wsb_cancel_return_url'
129
+ mapping :notify_url, 'wsb_notify_url'
130
+ mapping :test, 'wsb_test'
131
+ mapping :tax, 'wsb_tax'
132
+ mapping :shipping_name, 'wsb_shipping_name'
133
+ mapping :shipping_price, 'wsb_shipping_price'
134
+ mapping :discount_name, 'wsb_discount_name'
135
+ mapping :discount_price, 'wsb_discount_price'
136
+ mapping :amount, 'wsb_total'
137
+ mapping :email, 'wsb_email'
138
+ mapping :phone, 'wsb_phone'
139
+ end
140
+
141
+ class Notification < OffsitePayments::Notification
142
+ include Common
143
+
144
+ def self.recognizes?(params)
145
+ params.has_key?('site_order_id') && params.has_key?('amount')
146
+ end
147
+
148
+ def complete?
149
+ true
150
+ end
151
+
152
+ def amount
153
+ BigDecimal.new(gross)
154
+ end
155
+
156
+ def item_id
157
+ params['site_order_id']
158
+ end
159
+
160
+ def security_key
161
+ params[OffsitePayments::Integrations::WebPay.signature_parameter_name]
162
+ end
163
+
164
+ def gross
165
+ params['amount']
166
+ end
167
+
168
+ def status
169
+ 'success'
170
+ end
171
+
172
+ def secret
173
+ @options[:secret]
174
+ end
175
+
176
+ def acknowledge(authcode = nil)
177
+ (security_key == generate_signature(:notify))
178
+ end
179
+
180
+ def success_response(*args)
181
+ {:nothing => true}
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end