activemerchant 1.28.0 → 1.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data.tar.gz.sig +3 -3
  2. data/CHANGELOG +36 -0
  3. data/CONTRIBUTORS +8 -0
  4. data/README.md +5 -0
  5. data/lib/active_merchant/billing/gateway.rb +2 -1
  6. data/lib/active_merchant/billing/gateways.rb +6 -7
  7. data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -2
  8. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +77 -78
  9. data/lib/active_merchant/billing/gateways/balanced.rb +0 -1
  10. data/lib/active_merchant/billing/gateways/banwire.rb +1 -2
  11. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +19 -20
  12. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +35 -36
  13. data/lib/active_merchant/billing/gateways/blue_pay.rb +135 -140
  14. data/lib/active_merchant/billing/gateways/braintree_blue.rb +12 -4
  15. data/lib/active_merchant/billing/gateways/card_stream.rb +54 -59
  16. data/lib/active_merchant/billing/gateways/certo_direct.rb +0 -1
  17. data/lib/active_merchant/billing/gateways/cyber_source.rb +19 -14
  18. data/lib/active_merchant/billing/gateways/data_cash.rb +106 -112
  19. data/lib/active_merchant/billing/gateways/efsnet.rb +29 -34
  20. data/lib/active_merchant/billing/gateways/elavon.rb +7 -1
  21. data/lib/active_merchant/billing/gateways/epay.rb +0 -1
  22. data/lib/active_merchant/billing/gateways/eway.rb +88 -93
  23. data/lib/active_merchant/billing/gateways/eway_managed.rb +47 -51
  24. data/lib/active_merchant/billing/gateways/exact.rb +45 -54
  25. data/lib/active_merchant/billing/gateways/federated_canada.rb +3 -4
  26. data/lib/active_merchant/billing/gateways/first_pay.rb +37 -38
  27. data/lib/active_merchant/billing/gateways/garanti.rb +1 -2
  28. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  29. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +5 -8
  30. data/lib/active_merchant/billing/gateways/inspire.rb +52 -52
  31. data/lib/active_merchant/billing/gateways/instapay.rb +10 -11
  32. data/lib/active_merchant/billing/gateways/iridium.rb +38 -39
  33. data/lib/active_merchant/billing/gateways/itransact.rb +7 -9
  34. data/lib/active_merchant/billing/gateways/jetpay.rb +45 -46
  35. data/lib/active_merchant/billing/gateways/linkpoint.rb +104 -108
  36. data/lib/active_merchant/billing/gateways/litle.rb +1 -5
  37. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +153 -155
  38. data/lib/active_merchant/billing/gateways/merchant_ware.rb +49 -50
  39. data/lib/active_merchant/billing/gateways/mercury.rb +272 -0
  40. data/lib/active_merchant/billing/gateways/metrics_global.rb +9 -10
  41. data/lib/active_merchant/billing/gateways/migs.rb +5 -3
  42. data/lib/active_merchant/billing/gateways/modern_payments.rb +6 -7
  43. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +40 -41
  44. data/lib/active_merchant/billing/gateways/moneris.rb +46 -50
  45. data/lib/active_merchant/billing/gateways/moneris_us.rb +52 -55
  46. data/lib/active_merchant/billing/gateways/nab_transact.rb +0 -5
  47. data/lib/active_merchant/billing/gateways/net_registry.rb +20 -21
  48. data/lib/active_merchant/billing/gateways/netaxept.rb +30 -36
  49. data/lib/active_merchant/billing/gateways/netbilling.rb +2 -2
  50. data/lib/active_merchant/billing/gateways/ogone.rb +0 -5
  51. data/lib/active_merchant/billing/gateways/optimal_payment.rb +1 -6
  52. data/lib/active_merchant/billing/gateways/orbital.rb +25 -21
  53. data/lib/active_merchant/billing/gateways/orbital/avs_result.rb +93 -0
  54. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +1 -6
  55. data/lib/active_merchant/billing/gateways/pay_junction.rb +62 -63
  56. data/lib/active_merchant/billing/gateways/pay_secure.rb +29 -30
  57. data/lib/active_merchant/billing/gateways/paybox_direct.rb +0 -5
  58. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +33 -38
  59. data/lib/active_merchant/billing/gateways/payment_express.rb +48 -51
  60. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +7 -11
  61. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +7 -0
  62. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +3 -0
  63. data/lib/active_merchant/billing/gateways/paystation.rb +62 -64
  64. data/lib/active_merchant/billing/gateways/payway.rb +2 -9
  65. data/lib/active_merchant/billing/gateways/plugnpay.rb +0 -1
  66. data/lib/active_merchant/billing/gateways/psigate.rb +102 -94
  67. data/lib/active_merchant/billing/gateways/psl_card.rb +66 -67
  68. data/lib/active_merchant/billing/gateways/qbms.rb +0 -6
  69. data/lib/active_merchant/billing/gateways/quantum.rb +2 -8
  70. data/lib/active_merchant/billing/gateways/quickpay.rb +2 -3
  71. data/lib/active_merchant/billing/gateways/realex.rb +6 -16
  72. data/lib/active_merchant/billing/gateways/redsys.rb +394 -0
  73. data/lib/active_merchant/billing/gateways/sage.rb +15 -16
  74. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +25 -26
  75. data/lib/active_merchant/billing/gateways/sage_pay.rb +51 -56
  76. data/lib/active_merchant/billing/gateways/sallie_mae.rb +1 -2
  77. data/lib/active_merchant/billing/gateways/samurai.rb +1 -4
  78. data/lib/active_merchant/billing/gateways/secure_net.rb +0 -1
  79. data/lib/active_merchant/billing/gateways/secure_pay.rb +5 -8
  80. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +0 -5
  81. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +17 -18
  82. data/lib/active_merchant/billing/gateways/skip_jack.rb +29 -34
  83. data/lib/active_merchant/billing/gateways/smart_ps.rb +55 -56
  84. data/lib/active_merchant/billing/gateways/stripe.rb +8 -3
  85. data/lib/active_merchant/billing/gateways/trans_first.rb +28 -29
  86. data/lib/active_merchant/billing/gateways/trust_commerce.rb +85 -87
  87. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +27 -28
  88. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +0 -5
  89. data/lib/active_merchant/billing/gateways/verifi.rb +86 -87
  90. data/lib/active_merchant/billing/gateways/viaklix.rb +42 -47
  91. data/lib/active_merchant/billing/gateways/vindicia.rb +30 -28
  92. data/lib/active_merchant/billing/gateways/webpay.rb +45 -0
  93. data/lib/active_merchant/billing/gateways/wirecard.rb +0 -6
  94. data/lib/active_merchant/billing/gateways/worldpay.rb +4 -9
  95. data/lib/active_merchant/billing/integrations/a1agregator.rb +26 -0
  96. data/lib/active_merchant/billing/integrations/a1agregator/helper.rb +31 -0
  97. data/lib/active_merchant/billing/integrations/a1agregator/notification.rb +186 -0
  98. data/lib/active_merchant/billing/integrations/a1agregator/status.rb +38 -0
  99. data/lib/active_merchant/billing/integrations/liqpay.rb +30 -0
  100. data/lib/active_merchant/billing/integrations/liqpay/helper.rb +43 -0
  101. data/lib/active_merchant/billing/integrations/liqpay/notification.rb +89 -0
  102. data/lib/active_merchant/billing/integrations/liqpay/return.rb +83 -0
  103. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +17 -1
  104. data/lib/active_merchant/billing/integrations/notification.rb +4 -0
  105. data/lib/active_merchant/billing/integrations/pay_fast.rb +70 -0
  106. data/lib/active_merchant/billing/integrations/pay_fast/common.rb +42 -0
  107. data/lib/active_merchant/billing/integrations/pay_fast/helper.rb +50 -0
  108. data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +134 -0
  109. data/lib/active_merchant/billing/integrations/pay_fast/return.rb +10 -0
  110. data/lib/active_merchant/billing/integrations/paypal/notification.rb +64 -0
  111. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +10 -7
  112. data/lib/active_merchant/billing/integrations/webmoney/notification.rb +12 -0
  113. data/lib/active_merchant/billing/response.rb +19 -4
  114. data/lib/active_merchant/version.rb +1 -1
  115. metadata +45 -27
  116. metadata.gz.sig +0 -0
@@ -21,7 +21,7 @@ module ActiveMerchant #:nodoc:
21
21
  'unchecked' => 'P'
22
22
  }
23
23
 
24
- self.supported_countries = ['US']
24
+ self.supported_countries = ['US', 'CA']
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]
@@ -48,6 +48,7 @@ module ActiveMerchant #:nodoc:
48
48
  add_amount(post, money, options)
49
49
  add_creditcard(post, creditcard, options)
50
50
  add_customer(post, options)
51
+ add_customer_data(post,options)
51
52
  post[:description] = options[:description] || options[:email]
52
53
  add_flags(post, options)
53
54
 
@@ -105,8 +106,11 @@ module ActiveMerchant #:nodoc:
105
106
  end
106
107
 
107
108
  def add_customer_data(post, options)
108
- post[:description] = options[:description]
109
- post[:email] = options[:email]
109
+ metadata_options = [:description,:browser_ip,:user_agent,:referrer]
110
+ post.update(options.slice(*metadata_options))
111
+
112
+ post[:external_id] = options[:order_id]
113
+ post[:payment_user_agent] = "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}"
110
114
  end
111
115
 
112
116
  def add_address(post, options)
@@ -117,6 +121,7 @@ module ActiveMerchant #:nodoc:
117
121
  post[:card][:address_country] = address[:country] if address[:country]
118
122
  post[:card][:address_zip] = address[:zip] if address[:zip]
119
123
  post[:card][:address_state] = address[:state] if address[:state]
124
+ post[:card][:address_city] = address[:city] if address[:city]
120
125
  end
121
126
  end
122
127
 
@@ -7,36 +7,35 @@ module ActiveMerchant #:nodoc:
7
7
  self.supported_cardtypes = [:visa, :master, :american_express, :discover]
8
8
  self.homepage_url = 'http://www.transfirst.com/'
9
9
  self.display_name = 'TransFirst'
10
-
10
+
11
11
  UNUSED_FIELDS = %w(ECIValue UserId CAVVData TrackData POSInd EComInd MerchZIP MerchCustPNum MCC InstallmentNum InstallmentOf POSEntryMode POSConditionCode AuthCharInd CardCertData)
12
12
 
13
13
  DECLINED = 'The transaction was declined'
14
14
 
15
15
  def initialize(options = {})
16
16
  requires!(options, :login, :password)
17
- @options = options
18
17
  super
19
- end
20
-
18
+ end
19
+
21
20
  def purchase(money, credit_card, options = {})
22
21
  post = {}
23
-
22
+
24
23
  add_amount(post, money)
25
24
  add_invoice(post, options)
26
- add_credit_card(post, credit_card)
27
- add_address(post, options)
28
-
25
+ add_credit_card(post, credit_card)
26
+ add_address(post, options)
27
+
29
28
  commit(post)
30
- end
31
-
32
- private
29
+ end
30
+
31
+ private
33
32
  def add_amount(post, money)
34
33
  add_pair(post, :Amount, amount(money), :required => true)
35
34
  end
36
-
35
+
37
36
  def add_address(post, options)
38
37
  address = options[:billing_address] || options[:address]
39
-
38
+
40
39
  if address
41
40
  add_pair(post, :Address, address[:address1])
42
41
  add_pair(post, :ZipCode, address[:zip])
@@ -50,34 +49,34 @@ module ActiveMerchant #:nodoc:
50
49
  add_pair(post, :PaymentDesc, options[:description], :required => true)
51
50
  add_pair(post, :TaxIndicator, 0)
52
51
  end
53
-
52
+
54
53
  def add_credit_card(post, credit_card)
55
54
  add_pair(post, :CardHolderName, credit_card.name, :required => true)
56
55
  add_pair(post, :CardNumber, credit_card.number, :required => true)
57
-
56
+
58
57
  add_pair(post, :Expiration, expdate(credit_card), :required => true)
59
58
  add_pair(post, :CVV2, credit_card.verification_value)
60
59
  end
61
-
60
+
62
61
  def add_unused_fields(post)
63
62
  UNUSED_FIELDS.each do |f|
64
63
  post[f] = ""
65
64
  end
66
65
  end
67
-
66
+
68
67
  def expdate(credit_card)
69
68
  year = format(credit_card.year, :two_digits)
70
69
  month = format(credit_card.month, :two_digits)
71
70
 
72
71
  "#{month}#{year}"
73
72
  end
74
-
73
+
75
74
  def parse(data)
76
75
  response = {}
77
-
76
+
78
77
  xml = REXML::Document.new(data)
79
78
  root = REXML::XPath.first(xml, "//CCSaleDebitResponse")
80
-
79
+
81
80
  if root.nil?
82
81
  response[:message] = data.to_s.strip
83
82
  else
@@ -85,21 +84,21 @@ module ActiveMerchant #:nodoc:
85
84
  response[node.name.underscore.to_sym] = node.text
86
85
  end
87
86
  end
88
-
87
+
89
88
  response
90
89
  end
91
-
92
- def commit(params)
90
+
91
+ def commit(params)
93
92
  response = parse( ssl_post(self.live_url, post_data(params)) )
94
93
 
95
- Response.new(response[:status] == "Authorized", message_from(response), response,
96
- :test => test?,
94
+ Response.new(response[:status] == "Authorized", message_from(response), response,
95
+ :test => test?,
97
96
  :authorization => response[:trans_id],
98
97
  :avs_result => { :code => response[:avs_code] },
99
98
  :cvv_result => response[:cvv2_code]
100
99
  )
101
100
  end
102
-
101
+
103
102
  def message_from(response)
104
103
  case response[:message]
105
104
  when 'Call Voice Center'
@@ -108,16 +107,16 @@ module ActiveMerchant #:nodoc:
108
107
  response[:message]
109
108
  end
110
109
  end
111
-
110
+
112
111
  def post_data(params = {})
113
112
  add_unused_fields(params)
114
113
  params[:MerchantID] = @options[:login]
115
114
  params[:RegKey] = @options[:password]
116
-
115
+
117
116
  request = params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
118
117
  request
119
118
  end
120
-
119
+
121
120
  def add_pair(post, key, value, options = {})
122
121
  post[key] = value if !value.blank? || options[:required]
123
122
  end
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
8
8
  module Billing #:nodoc:
9
9
  # TO USE:
10
10
  # First, make sure you have everything setup correctly and all of your dependencies in place with:
11
- #
11
+ #
12
12
  # require 'rubygems'
13
13
  # require 'active_merchant'
14
14
  #
@@ -63,12 +63,12 @@ module ActiveMerchant #:nodoc:
63
63
  #
64
64
  # This should be enough to get you started with Trust Commerce and active_merchant. For further information, review the methods
65
65
  # below and the rest of active_merchant's documentation, as well as Trust Commerce's user and developer documentation.
66
-
66
+
67
67
  class TrustCommerceGateway < Gateway
68
68
  self.live_url = self.test_url = 'https://vault.trustcommerce.com/trans/'
69
-
69
+
70
70
  SUCCESS_TYPES = ["approved", "accepted"]
71
-
71
+
72
72
  DECLINE_CODES = {
73
73
  "decline" => "The credit card was declined",
74
74
  "avs" => "AVS failed; the address entered does not match the billing address on file at the bank",
@@ -78,13 +78,13 @@ module ActiveMerchant #:nodoc:
78
78
  "carderror" => "Card number is invalid",
79
79
  "authexpired" => "Attempt to postauth an expired (more than 14 days old) preauth",
80
80
  "fraud" => "CrediGuard fraud score was below requested threshold",
81
- "blacklist" => "CrediGuard blacklist value was triggered",
81
+ "blacklist" => "CrediGuard blacklist value was triggered",
82
82
  "velocity" => "CrediGuard velocity control value was triggered",
83
83
  "dailylimit" => "Daily limit in transaction count or amount as been reached",
84
84
  "weeklylimit" => "Weekly limit in transaction count or amount as been reached",
85
85
  "monthlylimit" => "Monthly limit in transaction count or amount as been reached"
86
86
  }
87
-
87
+
88
88
  BADDATA_CODES = {
89
89
  "missingfields" => "One or more parameters required for this transaction type were not sent",
90
90
  "extrafields" => "Parameters not allowed for this transaction type were sent",
@@ -93,32 +93,32 @@ module ActiveMerchant #:nodoc:
93
93
  "merchantcantaccept" => "The merchant can't accept data passed in this field",
94
94
  "mismatch" => "Data in one of the offending fields did not cross-check with the other offending field"
95
95
  }
96
-
96
+
97
97
  ERROR_CODES = {
98
98
  "cantconnect" => "Couldn't connect to the TrustCommerce gateway",
99
99
  "dnsfailure" => "The TCLink software was unable to resolve DNS hostnames",
100
100
  "linkfailure" => "The connection was established, but was severed before the transaction could complete",
101
101
  "failtoprocess" => "The bank servers are offline and unable to authorize transactions"
102
102
  }
103
-
103
+
104
104
  TEST_LOGIN = 'TestMerchant'
105
105
  TEST_PASSWORD = 'password'
106
-
106
+
107
107
  self.money_format = :cents
108
108
  self.supported_cardtypes = [:visa, :master, :discover, :american_express, :diners_club, :jcb]
109
109
  self.supported_countries = ['US']
110
110
  self.homepage_url = 'http://www.trustcommerce.com/'
111
111
  self.display_name = 'TrustCommerce'
112
-
112
+
113
113
  def self.tclink?
114
114
  defined?(TCLink)
115
115
  end
116
-
116
+
117
117
  # Creates a new TrustCommerceGateway
118
- #
118
+ #
119
119
  # The gateway requires that a valid login and password be passed
120
120
  # in the +options+ hash.
121
- #
121
+ #
122
122
  # ==== Options
123
123
  #
124
124
  # * <tt>:login</tt> -- The TrustCommerce account login.
@@ -130,44 +130,42 @@ module ActiveMerchant #:nodoc:
130
130
  # * <tt>:password</tt> -- password
131
131
  def initialize(options = {})
132
132
  requires!(options, :login, :password)
133
-
134
- @options = options
133
+
135
134
  super
136
135
  end
137
-
136
+
138
137
  def tclink?
139
138
  self.class.tclink?
140
139
  end
141
-
140
+
142
141
  def test?
143
- @options[:login] == TEST_LOGIN &&
144
- @options[:password] == TEST_PASSWORD || @options[:test] || super
142
+ ((@options[:login] == TEST_LOGIN && @options[:password] == TEST_PASSWORD) || super)
145
143
  end
146
-
144
+
147
145
  # authorize() is the first half of the preauth(authorize)/postauth(capture) model. The TC API docs call this
148
146
  # preauth, we preserve active_merchant's nomenclature of authorize() for consistency with the rest of the library. This
149
147
  # method simply checks to make sure funds are available for a transaction, and returns a transid that can be used later to
150
148
  # postauthorize (capture) the funds.
151
-
149
+
152
150
  def authorize(money, creditcard_or_billing_id, options = {})
153
151
  parameters = {
154
152
  :amount => amount(money),
155
- }
156
-
153
+ }
154
+
157
155
  add_order_id(parameters, options)
158
156
  add_customer_data(parameters, options)
159
157
  add_payment_source(parameters, creditcard_or_billing_id)
160
158
  add_addresses(parameters, options)
161
159
  commit('preauth', parameters)
162
160
  end
163
-
161
+
164
162
  # purchase() is a simple sale. This is one of the most common types of transactions, and is extremely simple. All that you need
165
163
  # to process a purchase are an amount in cents or a money object and a creditcard object or billingid string.
166
- def purchase(money, creditcard_or_billing_id, options = {})
164
+ def purchase(money, creditcard_or_billing_id, options = {})
167
165
  parameters = {
168
166
  :amount => amount(money),
169
- }
170
-
167
+ }
168
+
171
169
  add_order_id(parameters, options)
172
170
  add_customer_data(parameters, options)
173
171
  add_payment_source(parameters, creditcard_or_billing_id)
@@ -183,62 +181,62 @@ module ActiveMerchant #:nodoc:
183
181
  :amount => amount(money),
184
182
  :transid => authorization,
185
183
  }
186
-
184
+
187
185
  commit('postauth', parameters)
188
186
  end
189
-
187
+
190
188
  # refund() allows you to return money to a card that was previously billed. You need to supply the amount, in cents or a money object,
191
189
  # that you want to refund, and a TC transid for the transaction that you are refunding.
192
- def refund(money, identification, options = {})
190
+ def refund(money, identification, options = {})
193
191
  parameters = {
194
192
  :amount => amount(money),
195
193
  :transid => identification
196
194
  }
197
-
195
+
198
196
  commit('credit', parameters)
199
197
  end
200
198
 
201
- def credit(money, identification, options = {})
199
+ def credit(money, identification, options = {})
202
200
  deprecated CREDIT_DEPRECATION_MESSAGE
203
201
  refund(money, identification, options)
204
202
  end
205
-
203
+
206
204
  # void() clears an existing authorization and releases the reserved fund
207
- # s back to the cardholder. The TC API refers to this transaction as a
208
- # reversal. After voiding, you will no longer be able to capture funds
209
- # from this authorization. TrustCommerce seems to always return a status
210
- # of "accepted" even if the transid you are trying to deauthorize has
211
- # already been captured. Note: Your account needs to be configured by
212
- # TrustCommerce to allow for reversal transactions before you can use this
213
- # method.
214
- #
215
- # NOTE: AMEX preauth's cannot be reversed. If you want to clear it more
216
- # quickly than the automatic expiration (7-10 days), you will have to
217
- # capture it and then immediately issue a credit for the same amount
205
+ # s back to the cardholder. The TC API refers to this transaction as a
206
+ # reversal. After voiding, you will no longer be able to capture funds
207
+ # from this authorization. TrustCommerce seems to always return a status
208
+ # of "accepted" even if the transid you are trying to deauthorize has
209
+ # already been captured. Note: Your account needs to be configured by
210
+ # TrustCommerce to allow for reversal transactions before you can use this
211
+ # method.
212
+ #
213
+ # NOTE: AMEX preauth's cannot be reversed. If you want to clear it more
214
+ # quickly than the automatic expiration (7-10 days), you will have to
215
+ # capture it and then immediately issue a credit for the same amount
218
216
  # which should clear the customers credit card with 48 hours according to
219
217
  # TC.
220
218
  def void(authorization, options = {})
221
219
  parameters = {
222
220
  :transid => authorization,
223
221
  }
224
-
222
+
225
223
  commit('reversal', parameters)
226
224
  end
227
-
225
+
228
226
  # recurring() a TrustCommerce account that is activated for Citatdel, TrustCommerce's
229
227
  # hosted customer billing info database.
230
228
  #
231
229
  # Recurring billing uses the same TC action as a plain-vanilla 'store', but we have a separate method for clarity. It can be called
232
230
  # like store, with the addition of a required 'periodicity' parameter:
233
- #
231
+ #
234
232
  # The parameter :periodicity should be specified as either :bimonthly, :monthly, :biweekly, :weekly, :yearly or :daily
235
233
  #
236
234
  # gateway.recurring(tendollar, creditcard, :periodicity => :weekly)
237
235
  #
238
236
  # You can optionally specify how long you want payments to continue using 'payments'
239
- def recurring(money, creditcard, options = {})
237
+ def recurring(money, creditcard, options = {})
240
238
  requires!(options, [:periodicity, :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily] )
241
-
239
+
242
240
  cycle = case options[:periodicity]
243
241
  when :monthly
244
242
  '1m'
@@ -253,7 +251,7 @@ module ActiveMerchant #:nodoc:
253
251
  when :daily
254
252
  '1d'
255
253
  end
256
-
254
+
257
255
  parameters = {
258
256
  :amount => amount(money),
259
257
  :cycle => cycle,
@@ -261,37 +259,37 @@ module ActiveMerchant #:nodoc:
261
259
  :billingid => options[:billingid] || nil,
262
260
  :payments => options[:payments] || nil,
263
261
  }
264
-
262
+
265
263
  add_creditcard(parameters, creditcard)
266
-
264
+
267
265
  commit('store', parameters)
268
- end
269
-
266
+ end
267
+
270
268
  # store() requires a TrustCommerce account that is activated for Citatdel. You can call it with a credit card and a billing ID
271
269
  # you would like to use to reference the stored credit card info for future captures. Use 'verify' to specify whether you want
272
270
  # to simply store the card in the DB, or you want TC to verify the data first.
273
-
274
- def store(creditcard, options = {})
271
+
272
+ def store(creditcard, options = {})
275
273
  parameters = {
276
274
  :verify => options[:verify] || 'y',
277
275
  :billingid => options[:billingid] || options[:billing_id] || nil,
278
276
  }
279
-
277
+
280
278
  add_creditcard(parameters, creditcard)
281
- add_addresses(parameters, options)
279
+ add_addresses(parameters, options)
282
280
  commit('store', parameters)
283
281
  end
284
-
282
+
285
283
  # To unstore a creditcard stored in Citadel using store() or recurring(), all that is required is the billing id. When you run
286
284
  # unstore() the information will be removed and a Response object will be returned indicating the success of the action.
287
285
  def unstore(identification, options = {})
288
286
  parameters = {
289
287
  :billingid => identification,
290
288
  }
291
-
289
+
292
290
  commit('unstore', parameters)
293
- end
294
-
291
+ end
292
+
295
293
  private
296
294
  def add_payment_source(params, source)
297
295
  if source.is_a?(String)
@@ -300,39 +298,39 @@ module ActiveMerchant #:nodoc:
300
298
  add_creditcard(params, source)
301
299
  end
302
300
  end
303
-
301
+
304
302
  def expdate(creditcard)
305
303
  year = sprintf("%.4i", creditcard.year)
306
304
  month = sprintf("%.2i", creditcard.month)
307
305
 
308
306
  "#{month}#{year[-2..-1]}"
309
307
  end
310
-
308
+
311
309
  def add_creditcard(params, creditcard)
312
310
  params[:media] = "cc"
313
311
  params[:name] = creditcard.name
314
- params[:cc] = creditcard.number
312
+ params[:cc] = creditcard.number
315
313
  params[:exp] = expdate(creditcard)
316
314
  params[:cvv] = creditcard.verification_value if creditcard.verification_value?
317
315
  end
318
-
316
+
319
317
  def add_order_id(params, options)
320
318
  params[:ticket] = options[:order_id] unless options[:order_id].blank?
321
319
  end
322
-
320
+
323
321
  def add_billing_id(params, billingid)
324
322
  params[:billingid] = billingid
325
323
  end
326
-
324
+
327
325
  def add_customer_data(params, options)
328
326
  params[:email] = options[:email] unless options[:email].blank?
329
327
  params[:ip] = options[:ip] unless options[:ip].blank?
330
328
  end
331
-
329
+
332
330
  def add_addresses(params, options)
333
331
  address = options[:billing_address] || options[:address]
334
-
335
- if address
332
+
333
+ if address
336
334
  params[:address1] = address[:address1] unless address[:address1].blank?
337
335
  params[:address2] = address[:address2] unless address[:address2].blank?
338
336
  params[:city] = address[:city] unless address[:city].blank?
@@ -341,7 +339,7 @@ module ActiveMerchant #:nodoc:
341
339
  params[:country] = address[:country] unless address[:country].blank?
342
340
  params[:avs] = 'n'
343
341
  end
344
-
342
+
345
343
  if shipping_address = options[:shipping_address]
346
344
  params[:shipto_name] = shipping_address[:name] unless shipping_address[:name].blank?
347
345
  params[:shipto_address1] = shipping_address[:address1] unless shipping_address[:address1].blank?
@@ -352,7 +350,7 @@ module ActiveMerchant #:nodoc:
352
350
  params[:shipto_country] = shipping_address[:country] unless shipping_address[:country].blank?
353
351
  end
354
352
  end
355
-
353
+
356
354
  def clean_and_stringify_params(parameters)
357
355
  # TCLink wants us to send a hash with string keys, and activemerchant pushes everything around with
358
356
  # symbol keys. Before sending our input to TCLink, we convert all our keys to strings and dump the symbol keys.
@@ -364,50 +362,50 @@ module ActiveMerchant #:nodoc:
364
362
  parameters.delete(key)
365
363
  end
366
364
  end
367
-
365
+
368
366
  def post_data(parameters)
369
367
  parameters.collect { |key, value| "#{key}=#{ CGI.escape(value.to_s)}" }.join("&")
370
368
  end
371
-
369
+
372
370
  def commit(action, parameters)
373
371
  parameters[:custid] = @options[:login]
374
372
  parameters[:password] = @options[:password]
375
373
  parameters[:demo] = test? ? 'y' : 'n'
376
374
  parameters[:action] = action
377
-
375
+
378
376
  clean_and_stringify_params(parameters)
379
-
377
+
380
378
  data = if tclink?
381
379
  TCLink.send(parameters)
382
380
  else
383
381
  parse( ssl_post(self.live_url, post_data(parameters)) )
384
382
  end
385
-
383
+
386
384
  # to be considered successful, transaction status must be either "approved" or "accepted"
387
385
  success = SUCCESS_TYPES.include?(data["status"])
388
386
  message = message_from(data)
389
- Response.new(success, message, data,
390
- :test => test?,
387
+ Response.new(success, message, data,
388
+ :test => test?,
391
389
  :authorization => data["transid"],
392
390
  :cvv_result => data["cvv"],
393
391
  :avs_result => { :code => data["avs"] }
394
392
  )
395
393
  end
396
-
394
+
397
395
  def parse(body)
398
396
  results = {}
399
-
397
+
400
398
  body.split(/\n/).each do |pair|
401
399
  key,val = pair.split(/=/)
402
400
  results[key] = val
403
401
  end
404
-
402
+
405
403
  results
406
404
  end
407
-
408
- def message_from(data)
405
+
406
+ def message_from(data)
409
407
  status = case data["status"]
410
- when "decline"
408
+ when "decline"
411
409
  return DECLINE_CODES[data["declinetype"]]
412
410
  when "baddata"
413
411
  return BADDATA_CODES[data["error"]]
@@ -417,7 +415,7 @@ module ActiveMerchant #:nodoc:
417
415
  return "The transaction was successful"
418
416
  end
419
417
  end
420
-
418
+
421
419
  end
422
420
  end
423
421
  end