activemerchant 1.38.1 → 1.39.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/CHANGELOG +23 -0
  2. data/CONTRIBUTORS +8 -0
  3. data/README.md +65 -59
  4. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +6 -2
  5. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  6. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/blue_pay.rb +0 -3
  8. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +2 -2
  9. data/lib/active_merchant/billing/gateways/braintree_blue.rb +70 -67
  10. data/lib/active_merchant/billing/gateways/cyber_source.rb +2 -4
  11. data/lib/active_merchant/billing/gateways/eway_rapid.rb +75 -2
  12. data/lib/active_merchant/billing/gateways/moneris.rb +62 -10
  13. data/lib/active_merchant/billing/gateways/money_movers.rb +160 -0
  14. data/lib/active_merchant/billing/gateways/ogone.rb +21 -8
  15. data/lib/active_merchant/billing/gateways/orbital/avs_result.rb +6 -6
  16. data/lib/active_merchant/billing/gateways/payflow_uk.rb +2 -2
  17. data/lib/active_merchant/billing/gateways/paymill.rb +12 -2
  18. data/lib/active_merchant/billing/gateways/paypal.rb +2 -2
  19. data/lib/active_merchant/billing/gateways/quickpay.rb +32 -2
  20. data/lib/active_merchant/billing/gateways/realex.rb +11 -7
  21. data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -1
  22. data/lib/active_merchant/billing/gateways/secure_net.rb +7 -10
  23. data/lib/active_merchant/billing/gateways/spreedly_core.rb +9 -2
  24. data/lib/active_merchant/billing/gateways/stripe.rb +1 -1
  25. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +4 -2
  26. data/lib/active_merchant/billing/gateways/wirecard.rb +1 -1
  27. data/lib/active_merchant/billing/gateways/worldpay.rb +2 -2
  28. data/lib/active_merchant/billing/integrations/a1agregator/notification.rb +1 -1
  29. data/lib/active_merchant/billing/integrations/action_view_helper.rb +2 -1
  30. data/lib/active_merchant/billing/integrations/bit_pay/helper.rb +41 -0
  31. data/lib/active_merchant/billing/integrations/bit_pay/notification.rb +56 -0
  32. data/lib/active_merchant/billing/integrations/bit_pay.rb +18 -0
  33. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +1 -1
  34. data/lib/active_merchant/billing/integrations/citrus/helper.rb +40 -0
  35. data/lib/active_merchant/billing/integrations/citrus/notification.rb +133 -0
  36. data/lib/active_merchant/billing/integrations/citrus/return.rb +40 -0
  37. data/lib/active_merchant/billing/integrations/citrus.rb +51 -0
  38. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +1 -1
  39. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +1 -1
  40. data/lib/active_merchant/billing/integrations/dotpay/notification.rb +1 -1
  41. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +1 -1
  42. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +1 -1
  43. data/lib/active_merchant/billing/integrations/easy_pay/notification.rb +1 -1
  44. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +1 -1
  45. data/lib/active_merchant/billing/integrations/helper.rb +1 -1
  46. data/lib/active_merchant/billing/integrations/liqpay/notification.rb +1 -1
  47. data/lib/active_merchant/billing/integrations/liqpay/return.rb +1 -1
  48. data/lib/active_merchant/billing/integrations/maksuturva/notification.rb +1 -1
  49. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +1 -1
  50. data/lib/active_merchant/billing/integrations/nochex/notification.rb +1 -1
  51. data/lib/active_merchant/billing/integrations/paxum/notification.rb +1 -1
  52. data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +1 -1
  53. data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +1 -1
  54. data/lib/active_merchant/billing/integrations/paypal/notification.rb +1 -1
  55. data/lib/active_merchant/billing/integrations/paysbuy/notification.rb +13 -2
  56. data/lib/active_merchant/billing/integrations/payu_in/notification.rb +1 -1
  57. data/lib/active_merchant/billing/integrations/payu_in_paisa/helper.rb +19 -0
  58. data/lib/active_merchant/billing/integrations/payu_in_paisa/notification.rb +23 -0
  59. data/lib/active_merchant/billing/integrations/payu_in_paisa/return.rb +16 -0
  60. data/lib/active_merchant/billing/integrations/payu_in_paisa.rb +30 -0
  61. data/lib/active_merchant/billing/integrations/platron/notification.rb +1 -1
  62. data/lib/active_merchant/billing/integrations/pxpay/notification.rb +1 -1
  63. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +28 -6
  64. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +1 -1
  65. data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +1 -1
  66. data/lib/active_merchant/billing/integrations/robokassa/notification.rb +1 -1
  67. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +1 -1
  68. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +1 -1
  69. data/lib/active_merchant/billing/integrations/verkkomaksut/notification.rb +1 -1
  70. data/lib/active_merchant/billing/integrations/web_pay/notification.rb +1 -1
  71. data/lib/active_merchant/billing/integrations/webmoney/notification.rb +1 -1
  72. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +1 -1
  73. data/lib/active_merchant/version.rb +1 -1
  74. data/lib/support/gateway_support.rb +16 -10
  75. data.tar.gz.sig +0 -0
  76. metadata +23 -3
  77. metadata.gz.sig +2 -2
@@ -34,7 +34,7 @@ module ActiveMerchant
34
34
  self.money_format = :cents
35
35
  self.default_currency = 'EUR'
36
36
  self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :switch, :solo, :laser ]
37
- self.supported_countries = [ 'IE', 'GB' ]
37
+ self.supported_countries = %w(IE GB FR BE NL LU IT)
38
38
  self.homepage_url = 'http://www.realexpayments.com/'
39
39
  self.display_name = 'Realex'
40
40
 
@@ -86,8 +86,11 @@ module ActiveMerchant
86
86
  def commit(request)
87
87
  response = parse(ssl_post(self.live_url, request))
88
88
 
89
- Response.new(response[:result] == "00", message_from(response), response,
90
- :test => response[:message] =~ /\[ test system \]/,
89
+ Response.new(
90
+ (response[:result] == "00"),
91
+ message_from(response),
92
+ response,
93
+ :test => (response[:message] =~ %r{\[ test system \]}),
91
94
  :authorization => authorization_from(response),
92
95
  :cvv_result => response[:cvnresult],
93
96
  :avs_result => {
@@ -187,14 +190,14 @@ module ActiveMerchant
187
190
 
188
191
  if billing_address
189
192
  xml.tag! 'address', 'type' => 'billing' do
190
- xml.tag! 'code', format_shipping_zip_code(billing_address[:zip])
193
+ xml.tag! 'code', format_address_code(billing_address)
191
194
  xml.tag! 'country', billing_address[:country]
192
195
  end
193
196
  end
194
197
 
195
198
  if shipping_address
196
199
  xml.tag! 'address', 'type' => 'shipping' do
197
- xml.tag! 'code', format_shipping_zip_code(shipping_address[:zip])
200
+ xml.tag! 'code', format_address_code(shipping_address)
198
201
  xml.tag! 'country', shipping_address[:country]
199
202
  end
200
203
  end
@@ -240,8 +243,9 @@ module ActiveMerchant
240
243
  end
241
244
  end
242
245
 
243
- def format_shipping_zip_code(zip)
244
- zip.to_s.gsub(/\W/, '')
246
+ def format_address_code(address)
247
+ code = [address[:zip].to_s, address[:address1].to_s + address[:address2].to_s]
248
+ code.collect{|e| e.gsub(/\D/, "")}.reject{|e| e.empty?}.join("|")
245
249
  end
246
250
 
247
251
  def new_timestamp
@@ -44,7 +44,7 @@ module ActiveMerchant #:nodoc:
44
44
  }
45
45
 
46
46
  self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :switch, :solo, :maestro, :diners_club]
47
- self.supported_countries = ['GB']
47
+ self.supported_countries = ['GB', 'IE']
48
48
  self.default_currency = 'GBP'
49
49
 
50
50
  self.homepage_url = 'http://www.sagepay.com'
@@ -93,9 +93,8 @@ module ActiveMerchant #:nodoc:
93
93
 
94
94
  xml.tag! 'AMOUNT', amount(money)
95
95
  add_credit_card(xml, creditcard)
96
- add_required_params(xml, action, options)
96
+ add_params_in_required_order(xml, action, options)
97
97
  add_address(xml, creditcard, options)
98
- add_invoice(xml, options)
99
98
  add_more_required_params(xml, options)
100
99
 
101
100
  xml.target!
@@ -111,7 +110,7 @@ module ActiveMerchant #:nodoc:
111
110
  xml.tag! 'CARDNUMBER', last_four
112
111
  end
113
112
 
114
- add_required_params(xml, action, options)
113
+ add_params_in_required_order(xml, action, options)
115
114
  xml.tag! 'REF_TRANSID', transaction_id
116
115
  add_more_required_params(xml, options)
117
116
 
@@ -181,12 +180,6 @@ module ActiveMerchant #:nodoc:
181
180
 
182
181
  end
183
182
 
184
- def add_invoice(xml, options)
185
- xml.tag! 'NOTE', options[:description] if options[:description]
186
- xml.tag! 'INVOICEDESC', options[:invoice_description] if options[:invoice_description]
187
- xml.tag! 'INVOICENUM', options[:invoice_number] if options[:invoice_number]
188
- end
189
-
190
183
  def add_merchant_key(xml, options)
191
184
  xml.tag!("MERCHANT_KEY") do
192
185
  xml.tag! 'GROUPID', 0
@@ -195,13 +188,17 @@ module ActiveMerchant #:nodoc:
195
188
  end
196
189
  end
197
190
 
198
- def add_required_params(xml, action, options)
191
+ # SecureNet requires some of the xml params to be in a certain order. http://cl.ly/image/3K260E0p0a0n/content.png
192
+ def add_params_in_required_order(xml, action, options)
199
193
  xml.tag! 'CODE', TRANSACTIONS[action]
200
194
  add_customer_data(xml, options)
201
195
  xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID
202
196
  xml.tag! 'INSTALLMENT_SEQUENCENUM', 1
197
+ xml.tag! 'INVOICEDESC', options[:invoice_description] if options[:invoice_description]
198
+ xml.tag! 'INVOICENUM', options[:invoice_number] if options[:invoice_number]
203
199
  add_merchant_key(xml, options)
204
200
  xml.tag! 'METHOD', 'CC'
201
+ xml.tag! 'NOTE', options[:description] if options[:description]
205
202
  xml.tag! 'ORDERID', options[:order_id]
206
203
  xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it
207
204
  end
@@ -36,7 +36,9 @@ module ActiveMerchant #:nodoc:
36
36
  #
37
37
  # money - The monetary amount of the transaction in cents.
38
38
  # payment_method - The CreditCard or the Spreedly payment method token.
39
- # options - A standard ActiveMerchant options hash
39
+ # options - A hash of options:
40
+ # :store - Retain the payment method if the purchase
41
+ # succeeds. Defaults to false. (optional)
40
42
  def purchase(money, payment_method, options = {})
41
43
  if payment_method.is_a?(String)
42
44
  purchase_with_token(money, payment_method, options)
@@ -52,7 +54,9 @@ module ActiveMerchant #:nodoc:
52
54
  #
53
55
  # money - The monetary amount of the transaction in cents.
54
56
  # payment_method - The CreditCard or the Spreedly payment method token.
55
- # options - A standard ActiveMerchant options hash
57
+ # options - A hash of options:
58
+ # :store - Retain the payment method if the authorize
59
+ # succeeds. Defaults to false. (optional)
56
60
  def authorize(money, payment_method, options = {})
57
61
  if payment_method.is_a?(String)
58
62
  authorize_with_token(money, payment_method, options)
@@ -126,6 +130,7 @@ module ActiveMerchant #:nodoc:
126
130
  build_xml_request('transaction') do |doc|
127
131
  add_invoice(doc, money, options)
128
132
  doc.payment_method_token(payment_method_token)
133
+ doc.retain_on_success(true) if options[:store]
129
134
  end
130
135
  end
131
136
 
@@ -137,6 +142,7 @@ module ActiveMerchant #:nodoc:
137
142
  def add_credit_card(doc, credit_card, options)
138
143
  doc.credit_card do
139
144
  doc.number(credit_card.number)
145
+ doc.verification_value(credit_card.verification_value)
140
146
  doc.first_name(credit_card.first_name)
141
147
  doc.last_name(credit_card.last_name)
142
148
  doc.month(credit_card.month)
@@ -147,6 +153,7 @@ module ActiveMerchant #:nodoc:
147
153
  doc.city(options[:billing_address].try(:[], :city))
148
154
  doc.state(options[:billing_address].try(:[], :state))
149
155
  doc.zip(options[:billing_address].try(:[], :zip))
156
+ doc.country(options[:billing_address].try(:[], :country))
150
157
  end
151
158
  end
152
159
 
@@ -21,7 +21,7 @@ module ActiveMerchant #:nodoc:
21
21
  'unchecked' => 'P'
22
22
  }
23
23
 
24
- self.supported_countries = ['US', 'CA', 'GB']
24
+ self.supported_countries = %w(US CA GB AU IE FR NL BE DE ES)
25
25
  self.default_currency = 'USD'
26
26
  self.money_format = :cents
27
27
  self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
@@ -2,7 +2,8 @@ module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
 
4
4
  class UsaEpayTransactionGateway < Gateway
5
- self.test_url = self.live_url = 'https://www.usaepay.com/gate.php'
5
+ self.test_url = 'https://sandbox.usaepay.com/gate.php'
6
+ self.live_url = 'https://www.usaepay.com/gate.php'
6
7
 
7
8
  self.supported_cardtypes = [:visa, :master, :american_express]
8
9
  self.supported_countries = ['US']
@@ -168,7 +169,8 @@ module ActiveMerchant #:nodoc:
168
169
  end
169
170
 
170
171
  def commit(action, parameters)
171
- response = parse( ssl_post(self.live_url, post_data(action, parameters)) )
172
+ url = (self.test? ? self.test_url : self.live_url)
173
+ response = parse( ssl_post(url, post_data(action, parameters)) )
172
174
 
173
175
  Response.new(response[:status] == 'Approved', message_from(response), response,
174
176
  :test => test?,
@@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc:
30
30
  VALID_PHONE_FORMAT = /\+\d{1,3}(\(?\d{3}\)?)?\d{3}-\d{4}-\d{3}/
31
31
 
32
32
  # The countries the gateway supports merchants from as 2 digit ISO country codes
33
- self.supported_countries = ['DE']
33
+ self.supported_countries = %w(AD CY GI IM MT RO CH AT DK GR IT MC SM TR BE EE HU LV NL SK GB BG FI IS LI NO SI VA FR IL LT PL ES CZ DE IE LU PT SE)
34
34
 
35
35
  # Wirecard supports all major credit and debit cards:
36
36
  # Visa, Mastercard, American Express, Diners Club,
@@ -6,7 +6,7 @@ module ActiveMerchant #:nodoc:
6
6
 
7
7
  self.default_currency = 'GBP'
8
8
  self.money_format = :cents
9
- self.supported_countries = ['HK', 'US', 'GB', 'AU']
9
+ self.supported_countries = %w(HK US GB AU AD BE CH CY CZ DE DK ES FI FR GI GR HU IE IL IT LI LU MC MT NL NO NZ PL PT SE SG SI SM TR UM VA)
10
10
  self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :maestro, :laser]
11
11
  self.homepage_url = 'http://www.worldpay.com/'
12
12
  self.display_name = 'WorldPay'
@@ -59,7 +59,7 @@ module ActiveMerchant #:nodoc:
59
59
 
60
60
  def refund(money, authorization, options = {})
61
61
  MultiResponse.run do |r|
62
- r.process{inquire_request(authorization, options, "CAPTURED", "SETTLED")}
62
+ r.process{inquire_request(authorization, options, "CAPTURED", "SETTLED", "SETTLED_BY_MERCHANT")}
63
63
  r.process{refund_request(money, authorization, options)}
64
64
  end
65
65
  end
@@ -154,7 +154,7 @@ module ActiveMerchant #:nodoc:
154
154
  @notification_type == :additional
155
155
  end
156
156
 
157
- def acknowledge
157
+ def acknowledge(authcode = nil)
158
158
  security_key == signature
159
159
  end
160
160
 
@@ -49,7 +49,8 @@ module ActiveMerchant #:nodoc:
49
49
  service = service_class.new(order, account, options)
50
50
  form_options[:method] = service.form_method
51
51
  result = []
52
- result << form_tag(integration_module.service_url, form_options)
52
+ service_url = integration_module.respond_to?(:credential_based_url) ? integration_module.credential_based_url(options) : integration_module.service_url
53
+ result << form_tag(service_url, form_options)
53
54
 
54
55
  result << capture(service, &proc)
55
56
 
@@ -0,0 +1,41 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module Integrations #:nodoc:
4
+ module BitPay
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+ def initialize(order_id, account, options)
7
+ super
8
+ add_field('account', account)
9
+ add_field('orderID', order_id)
10
+ add_field('posData', options[:authcode])
11
+ add_field('currency', options[:currency])
12
+ add_field('fullNotifications', 'true')
13
+ add_field('transactionSpeed', options[:transactionSpeed] || "high")
14
+ add_field('address1', options[:address1])
15
+ end
16
+
17
+ # Replace with the real mapping
18
+ mapping :account, 'key'
19
+ mapping :amount, 'price'
20
+
21
+ mapping :order, 'orderID'
22
+ mapping :currency, 'currency'
23
+
24
+ mapping :customer, :first_name => 'buyerName',
25
+ :email => 'buyerEmail',
26
+ :phone => 'buyerPhone'
27
+
28
+ mapping :billing_address, :city => 'buyerCity',
29
+ :address1 => 'buyerAddress1',
30
+ :address2 => 'buyerAddress2',
31
+ :state => 'buyerState',
32
+ :zip => 'buyerZip',
33
+ :country => 'buyerCountry'
34
+
35
+ mapping :notify_url, 'notificationURL'
36
+ mapping :return_url, 'returnURL'
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,56 @@
1
+ require 'net/http'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ module Integrations #:nodoc:
6
+ module BitPay
7
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
8
+ def complete?
9
+ status == "complete"
10
+ end
11
+
12
+ def transaction_id
13
+ params['id']
14
+ end
15
+
16
+ # When was this payment received by the client.
17
+ def received_at
18
+ params['invoiceTime'].to_i
19
+ end
20
+
21
+ def currency
22
+ params['currency']
23
+ end
24
+
25
+ def amount
26
+ params['price']
27
+ end
28
+
29
+ # the money amount we received in X.2 decimal.
30
+ def btcPrice
31
+ params['btcPrice'].to_f
32
+ end
33
+
34
+ def status
35
+ params['status'].downcase
36
+ end
37
+
38
+ def acknowledge(authcode = nil)
39
+ authcode == params['posData']
40
+ end
41
+
42
+ private
43
+
44
+ # Take the posted data and move the relevant data into a hash
45
+ def parse(post)
46
+ @raw = post.to_s
47
+ for line in @raw.split('&')
48
+ key, value = *line.scan( %r{^([A-Za-z0-9_.]+)\=(.*)$} ).flatten
49
+ params[key] = CGI.unescape(value)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/bit_pay/helper.rb'
2
+ require File.dirname(__FILE__) + '/bit_pay/notification.rb'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ module Integrations #:nodoc:
7
+ module BitPay
8
+
9
+ mattr_accessor :service_url
10
+ self.service_url = 'https://www.bitpay.com/api/invoice'
11
+
12
+ def self.notification(post)
13
+ Notification.new(post)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -148,7 +148,7 @@ module ActiveMerchant #:nodoc:
148
148
  date.blank? && time.blank? && transaction_id.blank?
149
149
  end
150
150
 
151
- def acknowledge
151
+ def acknowledge(authcode = nil)
152
152
  true
153
153
  end
154
154
  end
@@ -0,0 +1,40 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ module Integrations
4
+ module Citrus
5
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
6
+
7
+ mapping :order, 'merchantTxnId'
8
+ mapping :amount, 'orderAmount'
9
+ mapping :account, 'merchantAccessKey'
10
+ mapping :credential2, 'secret_key'
11
+ mapping :credential3, 'pmt_url'
12
+ mapping :currency, 'currency'
13
+
14
+ mapping :customer, :first_name => 'firstName',:last_name => 'lastName', :email => 'email', :phone => 'mobileNo'
15
+
16
+ mapping :billing_address, :city => 'addressCity', :address1 => 'addressStreet1', :address2 => 'addressStreet2',:state => 'addressState',:zip => 'addressZip', :country => 'addressCountry'
17
+
18
+ mapping :checksum, 'secSignature'
19
+ mapping :return_url, 'returnUrl'
20
+
21
+
22
+ def initialize(order, account, options = {})
23
+ super
24
+ add_field 'paymentMode', 'NET_BANKING'
25
+ add_field 'reqtime', (Time.now.to_i * 1000).to_s
26
+ end
27
+
28
+ def form_fields
29
+ @fields.merge(mappings[:checksum] => generate_checksum)
30
+ end
31
+
32
+ def generate_checksum
33
+ checksum_fields = @fields["pmt_url"] + @fields["orderAmount"].to_s + @fields["merchantTxnId"] + @fields["currency"]
34
+ Citrus.checksum(@fields["secret_key"], checksum_fields )
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,133 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ module Integrations
4
+ module Citrus
5
+ class Notification < ActiveMerchant::Billing::Integrations::Notification
6
+
7
+ def initialize(post, options = {})
8
+ super(post, options)
9
+ @secret_key = options[:credential2]
10
+ end
11
+
12
+ def complete?
13
+ status == "Completed" || status == 'Canceled'
14
+ end
15
+
16
+ def status
17
+ @status ||= if checksum_ok?
18
+ if transaction_id.blank?
19
+ 'Invalid'
20
+ else
21
+ case transaction_status.downcase
22
+ when 'success' then 'Completed'
23
+ when 'canceled' then 'Canceled'
24
+ end
25
+ end
26
+ else
27
+ 'Tampered'
28
+ end
29
+ end
30
+
31
+ def invoice_ok?( order_id )
32
+ order_id.to_s == invoice.to_s
33
+ end
34
+
35
+ def amount_ok?( order_amount )
36
+ BigDecimal.new( amount ) == order_amount
37
+ end
38
+
39
+ def item_id
40
+ params['TxId']
41
+ end
42
+
43
+ def invoice
44
+ item_id
45
+ end
46
+
47
+ # Status of transaction return from the Citrus. List of possible values:
48
+ # <tt>SUCCESS</tt>::
49
+ # <tt>CANCELED</tt>::
50
+ def transaction_status
51
+ params['TxStatus']
52
+ end
53
+
54
+ def gross
55
+ params['amount']
56
+ end
57
+
58
+ def amount
59
+ gross
60
+ end
61
+
62
+ def transaction_id
63
+ params['pgTxnNo']
64
+ end
65
+
66
+ def issuerrefno
67
+ params['issuerRefNo']
68
+ end
69
+
70
+ def authidcode
71
+ params['authIdCode']
72
+ end
73
+
74
+ def pgrespcode
75
+ params['pgRespCode']
76
+ end
77
+
78
+ def checksum
79
+ params['signature']
80
+ end
81
+
82
+ def paymentmode
83
+ params['paymentMode']
84
+ end
85
+
86
+ def currency
87
+ params['currency']
88
+ end
89
+
90
+ def customer_email
91
+ params['email']
92
+ end
93
+
94
+ def customer_phone
95
+ params['mobileNo']
96
+ end
97
+
98
+ def customer_first_name
99
+ params['firstName']
100
+ end
101
+
102
+ def customer_last_name
103
+ params['lastName']
104
+ end
105
+
106
+ def customer_address
107
+ { :address1 => params['addressStreet1'], :address2 => params['addressStreet2'],
108
+ :city => params['addressCity'], :state => params['addressState'],
109
+ :country => params['addressCountry'], :zip => params['addressZip'] }
110
+ end
111
+
112
+ def message
113
+ @message || params['TxMsg']
114
+ end
115
+
116
+ def acknowledge(authcode = nil)
117
+ checksum_ok?
118
+ end
119
+
120
+ def checksum_ok?
121
+ fields = [invoice, transaction_status, amount.to_s, transaction_id, issuerrefno, authidcode, customer_first_name, customer_last_name, pgrespcode, customer_address[:zip]].join
122
+
123
+ unless Citrus.checksum(@secret_key, fields ) == checksum
124
+ @message = 'checksum mismatch...'
125
+ return false
126
+ end
127
+ true
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,40 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ module Integrations
4
+ module Citrus
5
+ class Return < ActiveMerchant::Billing::Integrations::Return
6
+
7
+ def initialize(query_string, options = {})
8
+ super
9
+ @notification = Notification.new(query_string, options)
10
+ end
11
+
12
+ def transaction_id
13
+ @notification.transaction_id
14
+ end
15
+
16
+ def status( order_id, order_amount )
17
+ if @notification.invoice_ok?( order_id ) && @notification.amount_ok?( BigDecimal.new(order_amount) )
18
+ @notification.status
19
+ else
20
+ 'Mismatch'
21
+ end
22
+ end
23
+
24
+ def success?
25
+ status( @params['TxId'], @params['amount'] ) == 'Completed'
26
+ end
27
+
28
+ def message
29
+ @notification.message
30
+ end
31
+
32
+ def cancelled?
33
+ @notification.status == 'Cancelled'
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,51 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ module Integrations
4
+ module Citrus
5
+ autoload :Helper, File.dirname(__FILE__) + '/citrus/helper.rb'
6
+ autoload :Notification, File.dirname(__FILE__) + '/citrus/notification.rb'
7
+ autoload :Return, File.dirname(__FILE__) + '/citrus/return.rb'
8
+
9
+ mattr_accessor :sandbox_url
10
+ mattr_accessor :staging_url
11
+ mattr_accessor :production_url
12
+
13
+ self.sandbox_url = 'https://sandbox.citruspay.com/'
14
+ self.staging_url = 'https://stg.citruspay.com/'
15
+ self.production_url = 'https://www.citruspay.com/'
16
+
17
+ def self.credential_based_url(options)
18
+ pmt_url = options[:credential3]
19
+
20
+ case ActiveMerchant::Billing::Base.integration_mode
21
+ when :production
22
+ self.production_url + pmt_url
23
+ when :test
24
+ self.sandbox_url + pmt_url
25
+ when :staging
26
+ self.staging_url + pmt_url
27
+ else
28
+ raise StandardError, "Integration mode set to an invalid value: #{mode}"
29
+ end
30
+ end
31
+
32
+ def self.helper(order, account, options = {})
33
+ Helper.new(order, account, options)
34
+ end
35
+
36
+ def self.notification(post, options = {})
37
+ Notification.new(post, options)
38
+ end
39
+
40
+ def self.return(query_string, options = {})
41
+ Return.new(query_string, options)
42
+ end
43
+
44
+ def self.checksum(secret_key, payload_items )
45
+ digest = OpenSSL::Digest::Digest.new('sha1')
46
+ OpenSSL::HMAC.hexdigest(digest, secret_key, payload_items)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
7
7
  class Notification < ActiveMerchant::Billing::Integrations::Notification
8
8
  RESPONSE_PARAMS = ['DirecPay Reference ID', 'Flag', 'Country', 'Currency', 'Other Details', 'Merchant Order No', 'Amount']
9
9
 
10
- def acknowledge
10
+ def acknowledge(authcode = nil)
11
11
  true
12
12
  end
13
13
 
@@ -108,7 +108,7 @@ module ActiveMerchant #:nodoc:
108
108
  Digest::SHA1.hexdigest(generate_signature_string)
109
109
  end
110
110
 
111
- def acknowledge
111
+ def acknowledge(authcode = nil)
112
112
  # signature_is_valid?
113
113
  generate_signature.to_s == params['hash'].to_s
114
114
  end
@@ -76,7 +76,7 @@ module ActiveMerchant #:nodoc:
76
76
  Digest::MD5.hexdigest(generate_signature_string)
77
77
  end
78
78
 
79
- def acknowledge
79
+ def acknowledge(authcode = nil)
80
80
  generate_signature.to_s == md5.to_s
81
81
  end
82
82
  end