bitfluent-activemerchant 1.5.1.1

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 (138) hide show
  1. data/CHANGELOG +520 -0
  2. data/CONTRIBUTORS +138 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +136 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant/billing/avs_result.rb +98 -0
  7. data/lib/active_merchant/billing/base.rb +57 -0
  8. data/lib/active_merchant/billing/check.rb +68 -0
  9. data/lib/active_merchant/billing/credit_card.rb +159 -0
  10. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  11. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  12. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  13. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  14. data/lib/active_merchant/billing/gateway.rb +163 -0
  15. data/lib/active_merchant/billing/gateways/authorize_net.rb +654 -0
  16. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +736 -0
  17. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +244 -0
  18. data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
  19. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  20. data/lib/active_merchant/billing/gateways/bogus.rb +102 -0
  21. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  22. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  23. data/lib/active_merchant/billing/gateways/cyber_source.rb +406 -0
  24. data/lib/active_merchant/billing/gateways/data_cash.rb +593 -0
  25. data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
  26. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  27. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  28. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  29. data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
  30. data/lib/active_merchant/billing/gateways/garanti.rb +222 -0
  31. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  32. data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
  33. data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
  34. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
  35. data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -0
  36. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  37. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  38. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  39. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  40. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  41. data/lib/active_merchant/billing/gateways/ogone.rb +279 -0
  42. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  43. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  44. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  45. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  46. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  47. data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
  48. data/lib/active_merchant/billing/gateways/payflow_express.rb +138 -0
  49. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  50. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  51. data/lib/active_merchant/billing/gateways/payment_express.rb +230 -0
  52. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
  53. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  54. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  55. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  56. data/lib/active_merchant/billing/gateways/paypal_express.rb +135 -0
  57. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
  58. data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
  59. data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
  60. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  61. data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
  62. data/lib/active_merchant/billing/gateways/realex.rb +200 -0
  63. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  64. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  65. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  66. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  67. data/lib/active_merchant/billing/gateways/sage_pay.rb +309 -0
  68. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  69. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  70. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
  71. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  72. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  73. data/lib/active_merchant/billing/gateways/smart_ps.rb +265 -0
  74. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  75. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  76. data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
  77. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  78. data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
  79. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  80. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  81. data/lib/active_merchant/billing/gateways.rb +18 -0
  82. data/lib/active_merchant/billing/integrations/action_view_helper.rb +79 -0
  83. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  84. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  85. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  86. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  87. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  88. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  89. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  90. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  91. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  92. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  93. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  94. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  95. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  96. data/lib/active_merchant/billing/integrations/helper.rb +93 -0
  97. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  98. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  99. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  100. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  101. data/lib/active_merchant/billing/integrations/ipay88/helper.rb +120 -0
  102. data/lib/active_merchant/billing/integrations/ipay88/return.rb +121 -0
  103. data/lib/active_merchant/billing/integrations/ipay88.rb +40 -0
  104. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  105. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  106. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  107. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  108. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  109. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  110. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  111. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  112. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  113. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  114. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  115. data/lib/active_merchant/billing/integrations/quickpay.rb +17 -0
  116. data/lib/active_merchant/billing/integrations/return.rb +35 -0
  117. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  118. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  119. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  120. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  121. data/lib/active_merchant/billing/integrations.rb +29 -0
  122. data/lib/active_merchant/billing/response.rb +32 -0
  123. data/lib/active_merchant/billing.rb +9 -0
  124. data/lib/active_merchant/common/connection.rb +172 -0
  125. data/lib/active_merchant/common/country.rb +319 -0
  126. data/lib/active_merchant/common/error.rb +26 -0
  127. data/lib/active_merchant/common/post_data.rb +24 -0
  128. data/lib/active_merchant/common/posts_data.rb +47 -0
  129. data/lib/active_merchant/common/requires_parameters.rb +16 -0
  130. data/lib/active_merchant/common/utils.rb +18 -0
  131. data/lib/active_merchant/common/validateable.rb +76 -0
  132. data/lib/active_merchant/common.rb +14 -0
  133. data/lib/active_merchant.rb +38 -0
  134. data/lib/activemerchant.rb +1 -0
  135. data/lib/certs/cacert.pem +7815 -0
  136. data/lib/support/gateway_support.rb +58 -0
  137. data/lib/support/outbound_hosts.rb +25 -0
  138. metadata +235 -0
@@ -0,0 +1,62 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ class Notification
5
+ attr_accessor :params
6
+ attr_accessor :raw
7
+
8
+ # set this to an array in the subclass, to specify which IPs are allowed to send requests
9
+ class_inheritable_accessor :production_ips
10
+
11
+ def initialize(post, options = {})
12
+ @options = options
13
+ empty!
14
+ parse(post)
15
+ end
16
+
17
+ def status
18
+ raise NotImplementedError, "Must implement this method in the subclass"
19
+ end
20
+
21
+ # the money amount we received in X.2 decimal.
22
+ def gross
23
+ raise NotImplementedError, "Must implement this method in the subclass"
24
+ end
25
+
26
+ def gross_cents
27
+ (gross.to_f * 100.0).round
28
+ end
29
+
30
+ # This combines the gross and currency and returns a proper Money object.
31
+ # this requires the money library located at http://dist.leetsoft.com/api/money
32
+ def amount
33
+ return Money.new(gross_cents, currency) rescue ArgumentError
34
+ return Money.new(gross_cents) # maybe you have an own money object which doesn't take a currency?
35
+ end
36
+
37
+ # reset the notification.
38
+ def empty!
39
+ @params = Hash.new
40
+ @raw = ""
41
+ end
42
+
43
+ # Check if the request comes from an official IP
44
+ def valid_sender?(ip)
45
+ return true if ActiveMerchant::Billing::Base.integration_mode == :test || production_ips.blank?
46
+ production_ips.include?(ip)
47
+ end
48
+
49
+ private
50
+
51
+ # Take the posted data and move the relevant data into a hash
52
+ def parse(post)
53
+ @raw = post.to_s
54
+ for line in @raw.split('&')
55
+ key, value = *line.scan( %r{^([A-Za-z0-9_.]+)\=(.*)$} ).flatten
56
+ params[key] = CGI.unescape(value)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,119 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Paypal
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+ CANADIAN_PROVINCES = { 'AB' => 'Alberta',
7
+ 'BC' => 'British Columbia',
8
+ 'MB' => 'Manitoba',
9
+ 'NB' => 'New Brunswick',
10
+ 'NL' => 'Newfoundland',
11
+ 'NS' => 'Nova Scotia',
12
+ 'NU' => 'Nunavut',
13
+ 'NT' => 'Northwest Territories',
14
+ 'ON' => 'Ontario',
15
+ 'PE' => 'Prince Edward Island',
16
+ 'QC' => 'Quebec',
17
+ 'SK' => 'Saskatchewan',
18
+ 'YT' => 'Yukon'
19
+ }
20
+ # See https://www.paypal.com/IntegrationCenter/ic_std-variable-reference.html for details on the following options.
21
+ mapping :order, [ 'item_number', 'custom' ]
22
+
23
+ def initialize(order, account, options = {})
24
+ super
25
+ add_field('cmd', '_ext-enter')
26
+ add_field('redirect_cmd', '_xclick')
27
+ add_field('quantity', 1)
28
+ add_field('item_name', 'Store purchase')
29
+ add_field('no_shipping', '1')
30
+ add_field('no_note', '1')
31
+ add_field('charset', 'utf-8')
32
+ add_field('address_override', '0')
33
+ add_field('bn', application_id.to_s.slice(0,32)) unless application_id.blank?
34
+ end
35
+
36
+ mapping :amount, 'amount'
37
+ mapping :account, 'business'
38
+ mapping :currency, 'currency_code'
39
+ mapping :notify_url, 'notify_url'
40
+ mapping :return_url, 'return'
41
+ mapping :cancel_return_url, 'cancel_return'
42
+ mapping :invoice, 'invoice'
43
+ mapping :item_name, 'item_name'
44
+ mapping :quantity, 'quantity'
45
+ mapping :no_shipping, 'no_shipping'
46
+ mapping :no_note, 'no_note'
47
+ mapping :address_override, 'address_override'
48
+
49
+ mapping :application_id, 'bn'
50
+
51
+ mapping :customer, :first_name => 'first_name',
52
+ :last_name => 'last_name',
53
+ :email => 'email'
54
+
55
+ mapping :shipping_address, :city => 'city',
56
+ :address1 => 'address1',
57
+ :address2 => 'address2',
58
+ :state => 'state',
59
+ :zip => 'zip',
60
+ :country => 'country'
61
+
62
+ def shipping_address(params = {})
63
+
64
+ # Get the country code in the correct format
65
+ # Use what we were given if we can't find anything
66
+ country_code = lookup_country_code(params.delete(:country))
67
+ add_field(mappings[:shipping_address][:country], country_code)
68
+
69
+ if params.has_key?(:phone)
70
+ phone = params.delete(:phone).to_s
71
+
72
+ # Whipe all non digits
73
+ phone.gsub!(/\D+/, '')
74
+
75
+ if ['US', 'CA'].include?(country_code) && phone =~ /(\d{3})(\d{3})(\d{4})$/
76
+ add_field('night_phone_a', $1)
77
+ add_field('night_phone_b', $2)
78
+ add_field('night_phone_c', $3)
79
+ else
80
+ add_field('night_phone_b', phone)
81
+ end
82
+ end
83
+
84
+ province_code = params.delete(:state)
85
+
86
+ case country_code
87
+ when 'CA'
88
+ add_field(mappings[:shipping_address][:state], CANADIAN_PROVINCES[province_code.upcase]) unless province_code.nil?
89
+ when 'US'
90
+ add_field(mappings[:shipping_address][:state], province_code)
91
+ else
92
+ add_field(mappings[:shipping_address][:state], province_code.blank? ? 'N/A' : province_code)
93
+ end
94
+
95
+ # Everything else
96
+ params.each do |k, v|
97
+ field = mappings[:shipping_address][k]
98
+ add_field(field, v) unless field.nil?
99
+ end
100
+ end
101
+
102
+ mapping :tax, 'tax'
103
+ mapping :shipping, 'shipping'
104
+ mapping :cmd, 'cmd'
105
+ mapping :custom, 'custom'
106
+ mapping :src, 'src'
107
+ mapping :sra, 'sra'
108
+ %w(a p t).each do |l|
109
+ (1..3).each do |i|
110
+ mapping "#{l}#{i}".to_sym, "#{l}#{i}"
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+
@@ -0,0 +1,154 @@
1
+ require 'net/http'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module Paypal
7
+ # Parser and handler for incoming Instant payment notifications from paypal.
8
+ # The Example shows a typical handler in a rails application. Note that this
9
+ # is an example, please read the Paypal API documentation for all the details
10
+ # on creating a safe payment controller.
11
+ #
12
+ # Example
13
+ #
14
+ # class BackendController < ApplicationController
15
+ # include ActiveMerchant::Billing::Integrations
16
+ #
17
+ # def paypal_ipn
18
+ # notify = Paypal::Notification.new(request.raw_post)
19
+ #
20
+ # order = Order.find(notify.item_id)
21
+ #
22
+ # if notify.acknowledge
23
+ # begin
24
+ #
25
+ # if notify.complete? and order.total == notify.amount
26
+ # order.status = 'success'
27
+ #
28
+ # shop.ship(order)
29
+ # else
30
+ # logger.error("Failed to verify Paypal's notification, please investigate")
31
+ # end
32
+ #
33
+ # rescue => e
34
+ # order.status = 'failed'
35
+ # raise
36
+ # ensure
37
+ # order.save
38
+ # end
39
+ # end
40
+ #
41
+ # render :nothing
42
+ # end
43
+ # end
44
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
45
+ include PostsData
46
+
47
+ # Was the transaction complete?
48
+ def complete?
49
+ status == "Completed"
50
+ end
51
+
52
+ # When was this payment received by the client.
53
+ # sometimes it can happen that we get the notification much later.
54
+ # One possible scenario is that our web application was down. In this case paypal tries several
55
+ # times an hour to inform us about the notification
56
+ def received_at
57
+ Time.parse params['payment_date']
58
+ end
59
+
60
+ # Status of transaction. List of possible values:
61
+ # <tt>Canceled-Reversal</tt>::
62
+ # <tt>Completed</tt>::
63
+ # <tt>Denied</tt>::
64
+ # <tt>Expired</tt>::
65
+ # <tt>Failed</tt>::
66
+ # <tt>In-Progress</tt>::
67
+ # <tt>Partially-Refunded</tt>::
68
+ # <tt>Pending</tt>::
69
+ # <tt>Processed</tt>::
70
+ # <tt>Refunded</tt>::
71
+ # <tt>Reversed</tt>::
72
+ # <tt>Voided</tt>::
73
+ def status
74
+ params['payment_status']
75
+ end
76
+
77
+ # Id of this transaction (paypal number)
78
+ def transaction_id
79
+ params['txn_id']
80
+ end
81
+
82
+ # What type of transaction are we dealing with?
83
+ # "cart" "send_money" "web_accept" are possible here.
84
+ def type
85
+ params['txn_type']
86
+ end
87
+
88
+ # the money amount we received in X.2 decimal.
89
+ def gross
90
+ params['mc_gross']
91
+ end
92
+
93
+ # the markup paypal charges for the transaction
94
+ def fee
95
+ params['mc_fee']
96
+ end
97
+
98
+ # What currency have we been dealing with
99
+ def currency
100
+ params['mc_currency']
101
+ end
102
+
103
+ # This is the item number which we submitted to paypal
104
+ # The custom field is also mapped to item_id because PayPal
105
+ # doesn't return item_number in dispute notifications
106
+ def item_id
107
+ params['item_number'] || params['custom']
108
+ end
109
+
110
+ # This is the invoice which you passed to paypal
111
+ def invoice
112
+ params['invoice']
113
+ end
114
+
115
+ # Was this a test transaction?
116
+ def test?
117
+ params['test_ipn'] == '1'
118
+ end
119
+
120
+ def account
121
+ params['business'] || params['receiver_email']
122
+ end
123
+
124
+ # Acknowledge the transaction to paypal. This method has to be called after a new
125
+ # ipn arrives. Paypal will verify that all the information we received are correct and will return a
126
+ # ok or a fail.
127
+ #
128
+ # Example:
129
+ #
130
+ # def paypal_ipn
131
+ # notify = PaypalNotification.new(request.raw_post)
132
+ #
133
+ # if notify.acknowledge
134
+ # ... process order ... if notify.complete?
135
+ # else
136
+ # ... log possible hacking attempt ...
137
+ # end
138
+ def acknowledge
139
+ payload = raw
140
+
141
+ response = ssl_post(Paypal.service_url + '?cmd=_notify-validate', payload,
142
+ 'Content-Length' => "#{payload.size}",
143
+ 'User-Agent' => "Active Merchant -- http://activemerchant.org"
144
+ )
145
+
146
+ raise StandardError.new("Faulty paypal result: #{response}") unless ["VERIFIED", "INVALID"].include?(response)
147
+
148
+ response == "VERIFIED"
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,10 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Paypal
5
+ class Return < ActiveMerchant::Billing::Integrations::Return
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,39 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Paypal
5
+ autoload :Return, 'active_merchant/billing/integrations/paypal/return.rb'
6
+ autoload :Helper, 'active_merchant/billing/integrations/paypal/helper.rb'
7
+ autoload :Notification, 'active_merchant/billing/integrations/paypal/notification.rb'
8
+
9
+ # Overwrite this if you want to change the Paypal test url
10
+ mattr_accessor :test_url
11
+ self.test_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'
12
+
13
+ # Overwrite this if you want to change the Paypal production url
14
+ mattr_accessor :production_url
15
+ self.production_url = 'https://www.paypal.com/cgi-bin/webscr'
16
+
17
+ def self.service_url
18
+ mode = ActiveMerchant::Billing::Base.integration_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.notification(post)
30
+ Notification.new(post)
31
+ end
32
+
33
+ def self.return(query_string)
34
+ Return.new(query_string)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,72 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Quickpay
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+
7
+ def initialize(order, account, options = {})
8
+ super
9
+ add_field('protocol', '3')
10
+ add_field('msgtype', 'authorize')
11
+ add_field('language', 'da')
12
+ add_field('autocapture', 0)
13
+ add_field('testmode', 0)
14
+ add_field('ordernumber', format_order_number(order))
15
+ end
16
+
17
+ def md5secret(value)
18
+ @md5secret = value
19
+ end
20
+
21
+ def form_fields
22
+ @fields.merge('md5check' => generate_md5check)
23
+ end
24
+
25
+ def generate_md5string
26
+ MD5_CHECK_FIELDS.map {|key| @fields[key.to_s]} * "" + @md5secret
27
+ end
28
+
29
+ def generate_md5check
30
+ Digest::MD5.hexdigest(generate_md5string)
31
+ end
32
+
33
+ # Limited to 20 digits max
34
+ def format_order_number(number)
35
+ number.to_s.gsub(/[^\w_]/, '').rjust(4, "0")[0...20]
36
+ end
37
+
38
+ MD5_CHECK_FIELDS = [
39
+ :protocol, :msgtype, :merchant, :language, :ordernumber,
40
+ :amount, :currency, :continueurl, :cancelurl, :callbackurl,
41
+ :autocapture, :cardtypelock, :description, :ipaddress, :testmode
42
+ ]
43
+
44
+ mapping :protocol, 'protocol'
45
+ mapping :msgtype, 'msgtype'
46
+ mapping :account, 'merchant'
47
+ mapping :language, 'language'
48
+ mapping :amount, 'amount'
49
+ mapping :currency, 'currency'
50
+
51
+ mapping :return_url, 'continueurl'
52
+ mapping :cancel_return_url, 'cancelurl'
53
+ mapping :notify_url, 'callbackurl'
54
+
55
+ mapping :autocapture, 'autocapture'
56
+ mapping :cardtypelock, 'cardtypelock'
57
+
58
+ mapping :description, 'description'
59
+ mapping :ipaddress, 'ipaddress'
60
+ mapping :testmode, 'testmode'
61
+
62
+ mapping :md5secret, 'md5secret'
63
+
64
+ mapping :customer, ''
65
+ mapping :billing_address, {}
66
+ mapping :tax, ''
67
+ mapping :shipping, ''
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,74 @@
1
+ require 'net/http'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module Quickpay
7
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
8
+ def complete?
9
+ status == '000'
10
+ end
11
+
12
+ def item_id
13
+ params['ordernumber']
14
+ end
15
+
16
+ def transaction_id
17
+ params['transaction']
18
+ end
19
+
20
+ def received_at
21
+ Time.local(*params['time'].scan(/../))
22
+ end
23
+
24
+ def gross
25
+ "%.2f" % (gross_cents / 100.0)
26
+ end
27
+
28
+ def gross_cents
29
+ params['amount'].to_i
30
+ end
31
+
32
+ def test?
33
+ params['testmode'] == 'Yes'
34
+ end
35
+
36
+ def status
37
+ params['qpstat']
38
+ end
39
+
40
+ def currency
41
+ params['currency']
42
+ end
43
+
44
+ # Provide access to raw fields from quickpay
45
+ %w(msgtype ordernumber state chstat chstatmsg qpstat qpstatmsg merchant merchantemail cardtype cardnumber).each do |attr|
46
+ define_method(attr) do
47
+ params[attr]
48
+ end
49
+ end
50
+
51
+ MD5_CHECK_FIELDS = [
52
+ :msgtype, :ordernumber, :amount, :currency, :time, :state,
53
+ :chstat, :chstatmsg, :qpstat, :qpstatmsg, :merchant, :merchantemail,
54
+ :transaction, :cardtype, :cardnumber, :testmode
55
+ ]
56
+
57
+ def generate_md5string
58
+ MD5_CHECK_FIELDS.map { |key| params[key.to_s] } * "" + @options[:md5secret]
59
+ end
60
+
61
+ def generate_md5check
62
+ Digest::MD5.hexdigest(generate_md5string)
63
+ end
64
+
65
+ # Quickpay doesn't do acknowledgements of callback notifications
66
+ # Instead it uses and MD5 hash of all parameters
67
+ def acknowledge
68
+ generate_md5check == params['md5check']
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,17 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module Quickpay
5
+ autoload :Helper, File.dirname(__FILE__) + '/quickpay/helper.rb'
6
+ autoload :Notification, File.dirname(__FILE__) + '/quickpay/notification.rb'
7
+
8
+ mattr_accessor :service_url
9
+ self.service_url = 'https://secure.quickpay.dk/form/'
10
+
11
+ def self.notification(post)
12
+ Notification.new(post)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ class Return
5
+ attr_accessor :params
6
+
7
+ def initialize(query_string)
8
+ @params = parse(query_string)
9
+ end
10
+
11
+ # Successful by default. Overridden in the child class
12
+ def success?
13
+ true
14
+ end
15
+
16
+ def message
17
+
18
+ end
19
+
20
+ def parse(query_string)
21
+ return {} if query_string.blank?
22
+
23
+ query_string.split('&').inject({}) do |memo, chunk|
24
+ next if chunk.empty?
25
+ key, value = chunk.split('=', 2)
26
+ next if key.empty?
27
+ value = value.nil? ? nil : CGI.unescape(value)
28
+ memo[CGI.unescape(key)] = value
29
+ memo
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module TwoCheckout
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+ def initialize(order, account, options = {})
7
+ super
8
+ add_field('fixed', 'Y')
9
+
10
+ if ActiveMerchant::Billing::Base.integration_mode == :test || options[:test]
11
+ add_field('demo', 'Y')
12
+ end
13
+ end
14
+
15
+ # The 2checkout vendor account number
16
+ mapping :account, 'sid'
17
+
18
+ # he total amount to be billed, in decimal form, without a currency symbol. (8 characters, decimal, 2 characters: Example: 99999999.99)
19
+ mapping :amount, 'total'
20
+
21
+ # a unique order id from your program. (128 characters max)
22
+ mapping :order, 'cart_order_id'
23
+
24
+
25
+ mapping :customer, :email => 'email',
26
+ :phone => 'phone'
27
+
28
+ mapping :billing_address, :city => 'city',
29
+ :address1 => 'street_address',
30
+ :address2 => 'street_address2',
31
+ :state => 'state',
32
+ :zip => 'zip',
33
+ :country => 'country'
34
+
35
+ mapping :shipping_address, :city => 'ship_city',
36
+ :address1 => 'ship_street_address',
37
+ :state => 'ship_state',
38
+ :zip => 'ship_zip',
39
+ :country => 'ship_country'
40
+
41
+ mapping :invoice, 'merchant_order_id'
42
+
43
+ # Does nothing, since we've disabled the Continue Shopping button by using the fixed = Y field
44
+ mapping :return_url, 'return_url'
45
+
46
+ #mapping :description, ''
47
+ #mapping :tax, ''
48
+ #mapping :shipping, ''
49
+
50
+ def customer(params = {})
51
+ add_field(mappings[:customer][:email], params[:email])
52
+ add_field(mappings[:customer][:phone], params[:phone])
53
+ add_field('card_holder_name', "#{params[:first_name]} #{params[:last_name]}")
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end