activemerchant 1.34.1 → 1.35.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,5 +1,21 @@
1
1
  = ActiveMerchant CHANGELOG
2
2
 
3
+ == Version 1.35.0 (July 17, 2013)
4
+
5
+ * Add Barclays ePDQ Extra Plus gateway [ntalbott]
6
+ * PayPal: Add MassPay payment to recipients by UserID [damonmorgan]
7
+ * Authorize.Net: Add authorization_code to response params [noahlh]
8
+ * Make Rails 4 a supported version [sanemat]
9
+ * CyberSource: Add pinless debit card support [JoshMcKin]
10
+ * Verkkomaksut: Add item title field [kaapa]
11
+ * Add MerchantWare V4 gateway [hron]
12
+ * Eway Rapid: Add #store method [adrianmacneil]
13
+ * Barclays ePDQ Extra Plus: Use correct PROD url [ntalbott]
14
+ * Hitrust: update test & live urls [melari]
15
+ * NAB Transact: Add auth & capture support [nagash]
16
+ * Mercury: Support card-less capture and refund [ntalbott]
17
+ * Mercury: Support void [ntalbott]
18
+
3
19
  == Version 1.34.1 (June 28, 2013)
4
20
 
5
21
  * WorldPay: Add dynamic return URL [jordanwheeler]
@@ -400,3 +400,11 @@ Cardstream Modern (March 2013)
400
400
  Transnational (May 2013)
401
401
 
402
402
  * Ben VandenBos (bvandenbos)
403
+
404
+ Barclays ePDQ Extra Plus (June 2013)
405
+
406
+ * Nathaniel Talbott (ntalbott)
407
+
408
+ MerchantWare V4 (July 2013)
409
+
410
+ * Aleksei Gusev (hron)
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
1
  # Active Merchant
2
+ [![Build Status](https://secure.travis-ci.org/Shopify/active_merchant.png)](http://travis-ci.org/Shopify/active_merchant)
3
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/Shopify/active_merchant)
2
4
 
3
5
  Active Merchant is an extraction from the e-commerce system [Shopify](http://www.shopify.com).
4
6
  Shopify's requirements for a simple and unified API to access dozens of different payment
@@ -83,7 +85,8 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
83
85
  * [Authorize.Net CIM](http://www.authorize.net/) - US
84
86
  * [Balanced](https://www.balancedpayments.com/) - US
85
87
  * [Banwire](https://www.banwire.com/) - MX
86
- * [Barclays ePDQ](http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/) - UK
88
+ * [Barclays ePDQ MPI](http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/) - UK
89
+ * [Barclays ePDQ Extra Plus](http://www.barclaycard.co.uk/business/accepting-payments/epdq-ecomm/) - UK
87
90
  * [Beanstream.com](http://www.beanstream.com/) - CA
88
91
  * [BluePay](http://www.bluepay.com/) - US
89
92
  * [Braintree](http://www.braintreepaymentsolutions.com) - US
@@ -215,7 +218,3 @@ information on adding a new gateway to ActiveMerchant.
215
218
 
216
219
  Please don't touch the CHANGELOG in your pull requests, we'll add the appropriate CHANGELOG entries
217
220
  at release time.
218
-
219
- [![Build Status](https://secure.travis-ci.org/Shopify/active_merchant.png)](http://travis-ci.org/Shopify/active_merchant)
220
-
221
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/Shopify/active_merchant)
@@ -38,7 +38,7 @@ module ActiveMerchant #:nodoc:
38
38
 
39
39
  APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
40
40
 
41
- RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3
41
+ RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT, AUTHORIZATION_CODE = 0, 2, 3, 4
42
42
  AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE = 5, 6, 38
43
43
 
44
44
  self.default_currency = 'USD'
@@ -310,7 +310,8 @@ module ActiveMerchant #:nodoc:
310
310
  :response_reason_text => fields[RESPONSE_REASON_TEXT],
311
311
  :avs_result_code => fields[AVS_RESULT_CODE],
312
312
  :transaction_id => fields[TRANSACTION_ID],
313
- :card_code => fields[CARD_CODE_RESPONSE_CODE]
313
+ :card_code => fields[CARD_CODE_RESPONSE_CODE],
314
+ :authorization_code => fields[AUTHORIZATION_CODE]
314
315
  }
315
316
  results
316
317
  end
@@ -9,7 +9,7 @@ module ActiveMerchant #:nodoc:
9
9
  self.supported_cardtypes = [:visa, :master, :american_express, :maestro, :switch ]
10
10
  self.money_format = :cents
11
11
  self.homepage_url = 'http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/'
12
- self.display_name = 'Barclays ePDQ'
12
+ self.display_name = 'Barclays ePDQ MPI'
13
13
 
14
14
  def initialize(options = {})
15
15
  requires!(options, :login, :password, :client_id)
@@ -0,0 +1,15 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class BarclaysEpdqExtraPlusGateway < OgoneGateway
4
+ self.test_url = "https://mdepayments.epdq.co.uk/ncol/test/"
5
+ self.live_url = "https://payments.epdq.co.uk/ncol/prod/"
6
+
7
+ self.display_name = "Barclays ePDQ Extra Plus"
8
+ self.homepage_url = "http://www.barclaycard.co.uk/business/accepting-payments/epdq-ecomm/"
9
+
10
+ self.supported_countries = ["GB"]
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro]
12
+ self.default_currency = "GBP"
13
+ end
14
+ end
15
+ end
@@ -24,6 +24,9 @@ module ActiveMerchant #:nodoc:
24
24
  # CyberSource what kind of item you are selling. It is used when
25
25
  # calculating tax/VAT.
26
26
  # * All transactions use dollar values.
27
+ # * To process pinless debit cards throught the pinless debit card
28
+ # network, your Cybersource merchant account must accept pinless
29
+ # debit card payments.
27
30
  class CyberSourceGateway < Gateway
28
31
  self.test_url = 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor'
29
32
  self.live_url = 'https://ics2ws.ic3.com/commerce/1.x/transactionProcessor'
@@ -132,6 +135,7 @@ module ActiveMerchant #:nodoc:
132
135
 
133
136
  # Purchase is an auth followed by a capture
134
137
  # You must supply an order_id in the options hash
138
+ # options[:pinless_debit_card] => true # attempts to process as pinless debit card
135
139
  def purchase(money, payment_method_or_reference, options = {})
136
140
  requires!(options, :order_id)
137
141
  setup_address_hash(options)
@@ -212,6 +216,12 @@ module ActiveMerchant #:nodoc:
212
216
  commit(build_tax_calculation_request(creditcard, options), options)
213
217
  end
214
218
 
219
+ # Determines if a card can be used for Pinless Debit Card transactions
220
+ def validate_pinless_debit_card(creditcard, options = {})
221
+ requires!(options, :order_id)
222
+ commit(build_validate_pinless_debit_request(creditcard,options), options)
223
+ end
224
+
215
225
  private
216
226
 
217
227
  # Create all address hash key value pairs so that we still function if we
@@ -258,7 +268,7 @@ module ActiveMerchant #:nodoc:
258
268
  add_check_service(xml)
259
269
  else
260
270
  add_purchase_service(xml, options)
261
- add_business_rules_data(xml)
271
+ add_business_rules_data(xml) unless options[:pinless_debit_card]
262
272
  end
263
273
  xml.target!
264
274
  end
@@ -349,6 +359,13 @@ module ActiveMerchant #:nodoc:
349
359
  xml.target!
350
360
  end
351
361
 
362
+ def build_validate_pinless_debit_request(creditcard,options)
363
+ xml = Builder::XmlMarkup.new :indent => 2
364
+ add_creditcard(xml, creditcard)
365
+ add_validate_pinless_debit_service(xml)
366
+ xml.target!
367
+ end
368
+
352
369
  def add_business_rules_data(xml)
353
370
  xml.tag! 'businessRules' do
354
371
  xml.tag!('ignoreAVSResult', 'true') if @options[:ignore_avs]
@@ -441,8 +458,12 @@ module ActiveMerchant #:nodoc:
441
458
  end
442
459
 
443
460
  def add_purchase_service(xml, options)
444
- xml.tag! 'ccAuthService', {'run' => 'true'}
445
- xml.tag! 'ccCaptureService', {'run' => 'true'}
461
+ if options[:pinless_debit_card]
462
+ xml.tag! 'pinlessDebitService', {'run' => 'true'}
463
+ else
464
+ xml.tag! 'ccAuthService', {'run' => 'true'}
465
+ xml.tag! 'ccCaptureService', {'run' => 'true'}
466
+ end
446
467
  end
447
468
 
448
469
  def add_void_service(xml, request_id, request_token)
@@ -535,6 +556,10 @@ module ActiveMerchant #:nodoc:
535
556
  end
536
557
  end
537
558
 
559
+ def add_validate_pinless_debit_service(xml)
560
+ xml.tag!'pinlessDebitValidateService', {'run' => 'true'}
561
+ end
562
+
538
563
  # Where we actually build the full SOAP request using builder
539
564
  def build_request(body, options)
540
565
  xml = Builder::XmlMarkup.new :indent => 2
@@ -104,6 +104,23 @@ module ActiveMerchant #:nodoc:
104
104
  commit(url_for("GetAccessCodeResult"), request)
105
105
  end
106
106
 
107
+ # Public: Store card details and return a valid token
108
+ #
109
+ # options - A supplemented ActiveMerchant options hash:
110
+ # :order_id - A merchant-supplied identifier for the
111
+ # transaction (optional).
112
+ # :billing_address - Standard ActiveMerchant address hash
113
+ # (required).
114
+ # :ip - The ip of the consumer initiating the
115
+ # transaction (optional).
116
+ # :application_id - A string identifying the application
117
+ # submitting the transaction
118
+ # (default: "https://github.com/Shopify/active_merchant")
119
+ def store(payment_method, options = {})
120
+ requires!(options, :billing_address)
121
+ purchase(0, payment_method, options.merge(:request_method => "CreateTokenCustomer"))
122
+ end
123
+
107
124
  private
108
125
 
109
126
  def run_purchase(identification, payment_method, endpoint)
@@ -118,7 +135,7 @@ module ActiveMerchant #:nodoc:
118
135
  def add_metadata(doc, options)
119
136
  doc.RedirectUrl(options[:redirect_url])
120
137
  doc.CustomerIP options[:ip] if options[:ip]
121
- doc.Method "ProcessPayment"
138
+ doc.Method options[:request_method] || "ProcessPayment"
122
139
  doc.DeviceID(options[:application_id] || application_id)
123
140
  end
124
141
 
@@ -148,13 +165,14 @@ module ActiveMerchant #:nodoc:
148
165
  doc.FirstName parts.shift if parts.size > 1
149
166
  doc.LastName parts.join(" ")
150
167
  end
168
+ doc.Title address[:title]
151
169
  doc.CompanyName address[:company] unless options[:skip_company]
152
170
  doc.Street1 address[:address1]
153
171
  doc.Street2 address[:address2]
154
172
  doc.City address[:city]
155
173
  doc.State address[:state]
156
174
  doc.PostalCode address[:zip]
157
- doc.Country address[:country]
175
+ doc.Country address[:country].to_s.downcase
158
176
  doc.Phone address[:phone]
159
177
  doc.Fax address[:fax]
160
178
  doc.Email options[:email]
@@ -242,6 +260,8 @@ module ActiveMerchant #:nodoc:
242
260
  def success?(response)
243
261
  if response[:errors]
244
262
  false
263
+ elsif response[:responsecode] == "00"
264
+ true
245
265
  elsif response[:transactionstatus]
246
266
  (response[:transactionstatus] == "true")
247
267
  else
@@ -320,4 +320,3 @@ module ActiveMerchant #:nodoc:
320
320
  end
321
321
  end
322
322
  end
323
-
@@ -0,0 +1,275 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class MerchantWareVersionFourGateway < Gateway
4
+ self.live_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
5
+ self.test_url = 'https://staging.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
6
+
7
+ self.supported_countries = ['US']
8
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
9
+ self.homepage_url = 'http://merchantwarehouse.com/merchantware'
10
+ self.display_name = 'MerchantWARE'
11
+
12
+ ENV_NAMESPACES = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
13
+ "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
14
+ "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/" }
15
+
16
+ TX_NAMESPACE = "http://schemas.merchantwarehouse.com/merchantware/40/Credit/"
17
+
18
+ ACTIONS = {
19
+ :purchase => "SaleKeyed",
20
+ :reference_purchase => 'RepeatSale',
21
+ :authorize => "PreAuthorizationKeyed",
22
+ :capture => "PostAuthorization",
23
+ :void => "VoidPreAuthorization",
24
+ :refund => "Refund"
25
+ }
26
+
27
+ # Creates a new MerchantWareVersionFourGateway
28
+ #
29
+ # The gateway requires that a valid login, password, and name be passed
30
+ # in the +options+ hash.
31
+ #
32
+ # ==== Options
33
+ #
34
+ # * <tt>:login</tt> - The MerchantWARE SiteID.
35
+ # * <tt>:password</tt> - The MerchantWARE Key.
36
+ # * <tt>:name</tt> - The MerchantWARE Name.
37
+ def initialize(options = {})
38
+ requires!(options, :login, :password, :name)
39
+ super
40
+ end
41
+
42
+ # Authorize a credit card for a given amount.
43
+ #
44
+ # ==== Parameters
45
+ # * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
46
+ # * <tt>credit_card</tt> - The CreditCard details for the transaction.
47
+ # * <tt>options</tt>
48
+ # * <tt>:order_id</tt> - A unique reference for this order (required).
49
+ # * <tt>:billing_address</tt> - The billing address for the cardholder.
50
+ def authorize(money, credit_card, options = {})
51
+ request = build_purchase_request(:authorize, money, credit_card, options)
52
+ commit(:authorize, request)
53
+ end
54
+
55
+ # Authorize and immediately capture funds from a credit card.
56
+ #
57
+ # ==== Parameters
58
+ # * <tt>money</tt> - The amount to be authorized as anInteger value in cents.
59
+ # * <tt>payment_source</tt> - The CreditCard details or 'token' from prior transaction
60
+ # * <tt>options</tt>
61
+ # * <tt>:order_id</tt> - A unique reference for this order (required).
62
+ # * <tt>:billing_address</tt> - The billing address for the cardholder.
63
+ def purchase(money, payment_source, options = {})
64
+ action = payment_source.is_a?(String) ? :reference_purchase : :purchase
65
+ request = build_purchase_request(action, money, payment_source, options)
66
+ commit(action, request)
67
+ end
68
+
69
+ # Capture authorized funds from a credit card.
70
+ #
71
+ # ==== Parameters
72
+ # * <tt>money</tt> - The amount to be captured as anInteger value in cents.
73
+ # * <tt>authorization</tt> - The authorization string returned from the initial authorization.
74
+ def capture(money, authorization, options = {})
75
+ request = build_capture_request(:capture, money, authorization, options)
76
+ commit(:capture, request)
77
+ end
78
+
79
+ # Void a transaction.
80
+ #
81
+ # ==== Parameters
82
+ # * <tt>authorization</tt> - The authorization string returned from the initial authorization or purchase.
83
+ def void(authorization, options = {})
84
+ reference, options[:order_id] = split_reference(authorization)
85
+ request = soap_request(:void) do |xml|
86
+ add_reference_token(xml, reference)
87
+ end
88
+ commit(:void, request)
89
+ end
90
+
91
+ # Refund an amount back a cardholder
92
+ #
93
+ # ==== Parameters
94
+ #
95
+ # * <tt>money</tt> - The amount to be refunded as an Integer value in cents.
96
+ # * <tt>identification</tt> - The credit card you want to refund or the authorization for the existing transaction you are refunding.
97
+ # * <tt>options</tt>
98
+ # * <tt>:order_id</tt> - A unique reference for this order (required when performing a non-referenced credit)
99
+ def refund(money, identification, options = {})
100
+ reference, options[:order_id] = split_reference(identification)
101
+
102
+ request = soap_request(:refund) do |xml|
103
+ add_reference_token(xml, reference)
104
+ add_invoice(xml, options)
105
+ add_amount(xml, money, "overrideAmount")
106
+ end
107
+
108
+ commit(:refund, request)
109
+ end
110
+
111
+ private
112
+
113
+ def soap_request(action)
114
+ xml = Builder::XmlMarkup.new :indent => 2
115
+ xml.instruct!
116
+ xml.tag! "soap:Envelope", ENV_NAMESPACES do
117
+ xml.tag! "soap:Body" do
118
+ xml.tag! ACTIONS[action], "xmlns" => TX_NAMESPACE do
119
+ xml.tag! "merchantName", @options[:name]
120
+ xml.tag! "merchantSiteId", @options[:login]
121
+ xml.tag! "merchantKey", @options[:password]
122
+ yield xml
123
+ end
124
+ end
125
+ end
126
+ xml.target!
127
+ end
128
+
129
+ def build_purchase_request(action, money, payment_source, options)
130
+ requires!(options, :order_id)
131
+
132
+ request = soap_request(action) do |xml|
133
+ add_invoice(xml, options)
134
+ add_amount(xml, money)
135
+ add_payment_source(xml, payment_source)
136
+ add_address(xml, options)
137
+ end
138
+ end
139
+
140
+ def build_capture_request(action, money, identification, options)
141
+ reference, options[:order_id] = split_reference(identification)
142
+
143
+ request = soap_request(action) do |xml|
144
+ add_reference_token(xml, reference)
145
+ add_invoice(xml, options)
146
+ add_amount(xml, money)
147
+ end
148
+ end
149
+
150
+ def expdate(credit_card)
151
+ year = sprintf("%.4i", credit_card.year)
152
+ month = sprintf("%.2i", credit_card.month)
153
+
154
+ "#{month}#{year[-2..-1]}"
155
+ end
156
+
157
+ def add_invoice(xml, options)
158
+ xml.tag! "invoiceNumber", options[:order_id].to_s.gsub(/[^\w]/, '').slice(0, 25)
159
+ end
160
+
161
+ def add_amount(xml, money, tag = "amount")
162
+ xml.tag! tag, amount(money)
163
+ end
164
+
165
+ def add_reference_token(xml, reference)
166
+ xml.tag! "token", reference
167
+ end
168
+
169
+ def add_address(xml, options)
170
+ address = options[:billing_address] || options[:address] || {}
171
+ xml.tag! "avsStreetAddress", address[:address1]
172
+ xml.tag! "avsStreetZipCode", address[:zip]
173
+ end
174
+
175
+ def add_payment_source(xml, source)
176
+ if source.is_a?(String)
177
+ add_reference_token(xml, source)
178
+ else
179
+ add_credit_card(xml, source)
180
+ end
181
+ end
182
+
183
+ def add_credit_card(xml, credit_card)
184
+ xml.tag! "cardNumber", credit_card.number
185
+ xml.tag! "expirationDate", expdate(credit_card)
186
+ xml.tag! "cardholder", credit_card.name
187
+ xml.tag! "cardSecurityCode", credit_card.verification_value if credit_card.verification_value?
188
+ end
189
+
190
+ def split_reference(reference)
191
+ reference.to_s.split(";")
192
+ end
193
+
194
+ def parse(action, data)
195
+ response = {}
196
+ xml = REXML::Document.new(data)
197
+
198
+ root = REXML::XPath.first(xml, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
199
+
200
+ root.elements.each do |element|
201
+ response[element.name] = element.text
202
+ end
203
+
204
+ if response["ErrorMessage"].present?
205
+ response[:message] = response["ErrorMessage"]
206
+ response[:success] = false
207
+ else
208
+ status, code, message = response["ApprovalStatus"].split(";")
209
+ response[:status] = status
210
+
211
+ if response[:success] = status == "APPROVED"
212
+ response[:message] = status
213
+ else
214
+ response[:message] = message
215
+ response[:failure_code] = code
216
+ end
217
+ end
218
+
219
+ response
220
+ end
221
+
222
+ def parse_error(http_response, action)
223
+ response = {}
224
+ response[:http_code] = http_response.code
225
+ response[:http_message] = http_response.message
226
+ response[:success] = false
227
+
228
+ document = REXML::Document.new(http_response.body)
229
+ node = REXML::XPath.first(document, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
230
+
231
+ node.elements.each do |element|
232
+ response[element.name] = element.text
233
+ end
234
+
235
+ response[:message] = response["ErrorMessage"].to_s.gsub("\n", " ")
236
+ response
237
+ rescue REXML::ParseException => e
238
+ response[:http_body] = http_response.body
239
+ response[:message] = "Failed to parse the failed response"
240
+ response
241
+ end
242
+
243
+ def soap_action(action)
244
+ "#{TX_NAMESPACE}#{ACTIONS[action]}"
245
+ end
246
+
247
+ def url
248
+ test? ? test_url : live_url
249
+ end
250
+
251
+ def commit(action, request)
252
+ begin
253
+ data = ssl_post(url, request,
254
+ "Content-Type" => 'text/xml; charset=utf-8',
255
+ "SOAPAction" => soap_action(action)
256
+ )
257
+ response = parse(action, data)
258
+ rescue ActiveMerchant::ResponseError => e
259
+ response = parse_error(e.response, action)
260
+ end
261
+
262
+ Response.new(response[:success], response[:message], response,
263
+ :test => test?,
264
+ :authorization => authorization_from(response),
265
+ :avs_result => { :code => response["AvsResponse"] },
266
+ :cvv_result => response["CvResponse"]
267
+ )
268
+ end
269
+
270
+ def authorization_from(response)
271
+ response['Token']
272
+ end
273
+ end
274
+ end
275
+ end
@@ -1,5 +1,15 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
+ # The Mercury gateway integration by default requires that the Mercury
4
+ # account being used has tokenization turned. This enables the use of
5
+ # capture/refund/void without having to pass the credit card back in each
6
+ # time. Only the "OneTime" tokenization is used; there is no use of
7
+ # "Recurring" tokenization.
8
+ #
9
+ # If you don't wish to enable Mercury tokenization, you can pass
10
+ # <code>:tokenization => false</code> as an option when creating the
11
+ # gateway. If you do so, then passing a +:credit_card+ option to +capture+
12
+ # and +refund+ will become mandatory.
3
13
  class MercuryGateway < Gateway
4
14
  URLS = {
5
15
  :test => 'https://w1.mercurydev.net/ws/ws.asmx',
@@ -14,6 +24,7 @@ module ActiveMerchant #:nodoc:
14
24
 
15
25
  def initialize(options = {})
16
26
  requires!(options, :login, :password)
27
+ @use_tokenization = (!options.has_key?(:tokenization) || options[:tokenization])
17
28
  super
18
29
  end
19
30
 
@@ -34,25 +45,28 @@ module ActiveMerchant #:nodoc:
34
45
  def authorize(money, credit_card, options = {})
35
46
  requires!(options, :order_id)
36
47
 
37
- options[:authorized] ||= money
38
- request = build_non_authorized_request('PreAuth', money, credit_card, options)
48
+ request = build_non_authorized_request('PreAuth', money, credit_card, options.merge(:authorized => money))
39
49
  commit('PreAuth', request)
40
50
  end
41
51
 
42
52
  def capture(money, authorization, options = {})
43
- requires!(options, :credit_card)
44
- options[:authorized] ||= money
45
- request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options)
53
+ requires!(options, :credit_card) unless @use_tokenization
54
+
55
+ request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options.merge(:authorized => money))
46
56
  commit('PreAuthCapture', request)
47
57
  end
48
58
 
49
59
  def refund(money, authorization, options = {})
50
- requires!(options, :credit_card)
60
+ requires!(options, :credit_card) unless @use_tokenization
51
61
 
52
62
  request = build_authorized_request('VoidSale', money, authorization, options[:credit_card], options)
53
63
  commit(options[:void], request)
54
64
  end
55
65
 
66
+ def void(authorization, options={})
67
+ refund(nil, authorization, options.merge(:void => true))
68
+ end
69
+
56
70
  private
57
71
 
58
72
  def build_non_authorized_request(action, money, credit_card, options)
@@ -78,19 +92,21 @@ module ActiveMerchant #:nodoc:
78
92
  def build_authorized_request(action, money, authorization, credit_card, options)
79
93
  xml = Builder::XmlMarkup.new
80
94
 
81
- invoice_no, ref_no, auth_code, acq_ref_data, process_data = split_authorization(authorization)
95
+ invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount = split_authorization(authorization)
96
+ ref_no = invoice_no if options[:void]
82
97
 
83
98
  xml.tag! "TStream" do
84
99
  xml.tag! "Transaction" do
85
100
  xml.tag! 'TranType', 'Credit'
86
- xml.tag! 'TranCode', action
101
+ xml.tag! 'TranCode', (@use_tokenization ? (action + "ByRecordNo") : action)
87
102
  if action == 'PreAuthCapture'
88
103
  xml.tag! "PartialAuth", "Allow"
89
104
  end
90
105
  add_invoice(xml, invoice_no, ref_no, options)
106
+ add_reference(xml, record_no) if @use_tokenization
91
107
  add_customer_data(xml, options)
92
- add_amount(xml, money, options)
93
- add_credit_card(xml, credit_card, action)
108
+ add_amount(xml, (money || amount.to_i), options)
109
+ add_credit_card(xml, credit_card, action) if credit_card
94
110
  add_address(xml, options)
95
111
  xml.tag! 'TranInfo' do
96
112
  xml.tag! "AuthCode", auth_code
@@ -108,9 +124,18 @@ module ActiveMerchant #:nodoc:
108
124
  end
109
125
 
110
126
  xml.tag! 'InvoiceNo', invoice_no
111
- xml.tag! 'RefNo', ref_no || invoice_no
127
+ xml.tag! 'RefNo', (ref_no || invoice_no)
112
128
  xml.tag! 'OperatorID', options[:merchant] if options[:merchant]
113
129
  xml.tag! 'Memo', options[:description] if options[:description]
130
+ if @use_tokenization
131
+ xml.tag! 'Frequency', "OneTime"
132
+ xml.tag! 'RecordNo', "RecordNumberRequested"
133
+ end
134
+ end
135
+
136
+ def add_reference(xml, record_no)
137
+ xml.tag! "Frequency", "OneTime"
138
+ xml.tag! "RecordNo", record_no
114
139
  end
115
140
 
116
141
  def add_customer_data(xml, options)
@@ -240,18 +265,23 @@ module ActiveMerchant #:nodoc:
240
265
  end
241
266
 
242
267
  def authorization_from(response)
268
+ dollars, cents = (response[:purchase] || "").split(".").collect{|e| e.to_i}
269
+ dollars ||= 0
270
+ cents ||= 0
243
271
  [
244
272
  response[:invoice_no],
245
273
  response[:ref_no],
246
274
  response[:auth_code],
247
275
  response[:acq_ref_data],
248
- response[:process_data]
276
+ response[:process_data],
277
+ response[:record_no],
278
+ ((dollars * 100) + cents).to_s
249
279
  ].join(";")
250
280
  end
251
281
 
252
282
  def split_authorization(authorization)
253
- invoice_no, ref_no, auth_code, acq_ref_data, process_data = authorization.split(";")
254
- [invoice_no, ref_no, auth_code, acq_ref_data, process_data]
283
+ invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount = authorization.split(";")
284
+ [invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount]
255
285
  end
256
286
 
257
287
  ENVELOPE_NAMESPACES = {
@@ -70,6 +70,14 @@ module ActiveMerchant #:nodoc:
70
70
  commit :refund, build_reference_request(money, authorization)
71
71
  end
72
72
 
73
+ def authorize(money, credit_card, options = {})
74
+ commit :authorization, build_purchase_request(money, credit_card, options)
75
+ end
76
+
77
+ def capture(money, authorization)
78
+ commit :capture, build_reference_request(money, authorization)
79
+ end
80
+
73
81
  def store(creditcard, options = {})
74
82
  requires!(options, :billing_id, :amount)
75
83
  commit_periodic(build_periodic_item(:addcrn, options[:amount], creditcard, options))
@@ -99,12 +99,6 @@ module ActiveMerchant #:nodoc:
99
99
  # :language => Customer's language, for example: "en_EN"
100
100
  #
101
101
  class OgoneGateway < Gateway
102
-
103
- URLS = {
104
- :order => 'https://secure.ogone.com/ncol/%s/orderdirect.asp',
105
- :maintenance => 'https://secure.ogone.com/ncol/%s/maintenancedirect.asp'
106
- }
107
-
108
102
  CVV_MAPPING = { 'OK' => 'M',
109
103
  'KO' => 'N',
110
104
  'NO' => 'P' }
@@ -125,8 +119,8 @@ module ActiveMerchant #:nodoc:
125
119
  OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE = "Signature usage will be the default for a future release of ActiveMerchant. You should either begin using it, or update your configuration to explicitly disable it (signature_encryptor: none)"
126
120
  OGONE_STORE_OPTION_DEPRECATION_MESSAGE = "The 'store' option has been renamed to 'billing_id', and its usage is deprecated."
127
121
 
128
- self.test_url = URLS[:order] % "test"
129
- self.live_url = URLS[:order] % "prod"
122
+ self.test_url = "https://secure.ogone.com/ncol/test/"
123
+ self.live_url = "https://secure.ogone.com/ncol/prod/"
130
124
 
131
125
  self.supported_countries = ['BE', 'DE', 'FR', 'NL', 'AT', 'CH']
132
126
  # also supports Airplus and UATP
@@ -331,8 +325,7 @@ module ActiveMerchant #:nodoc:
331
325
  add_pair parameters, 'USERID', @options[:user]
332
326
  add_pair parameters, 'PSWD', @options[:password]
333
327
 
334
- url = URLS[parameters['PAYID'] ? :maintenance : :order] % [test? ? "test" : "prod"]
335
- response = parse(ssl_post(url, post_data(action, parameters)))
328
+ response = parse(ssl_post(url(parameters['PAYID']), post_data(action, parameters)))
336
329
 
337
330
  options = {
338
331
  :authorization => [response["PAYID"], action].join(";"),
@@ -343,6 +336,10 @@ module ActiveMerchant #:nodoc:
343
336
  OgoneResponse.new(successful?(response), message_from(response), response, options)
344
337
  end
345
338
 
339
+ def url(payid)
340
+ (test? ? test_url : live_url) + (payid ? "maintenancedirect.asp" : "orderdirect.asp")
341
+ end
342
+
346
343
  def successful?(response)
347
344
  response["NCERROR"] == "0"
348
345
  end
@@ -342,6 +342,7 @@ module ActiveMerchant #:nodoc:
342
342
  def build_mass_pay_request(*args)
343
343
  default_options = args.last.is_a?(Hash) ? args.pop : {}
344
344
  recipients = args.first.is_a?(Array) ? args : [args]
345
+ receiver_type = default_options[:receiver_type]
345
346
 
346
347
  xml = Builder::XmlMarkup.new
347
348
 
@@ -349,11 +350,18 @@ module ActiveMerchant #:nodoc:
349
350
  xml.tag! 'MassPayRequest', 'xmlns:n2' => EBAY_NAMESPACE do
350
351
  xml.tag! 'n2:Version', API_VERSION
351
352
  xml.tag! 'EmailSubject', default_options[:subject] if default_options[:subject]
353
+ xml.tag! 'ReceiverType', receiver_type if receiver_type
352
354
  recipients.each do |money, recipient, options|
353
355
  options ||= default_options
354
356
  xml.tag! 'MassPayItem' do
355
- xml.tag! 'ReceiverEmail', recipient
356
- xml.tag! 'Amount', amount(money), 'currencyID' => options[:currency] || currency(money)
357
+ if(!receiver_type || receiver_type == 'EmailAddress')
358
+ xml.tag! 'ReceiverEmail', recipient
359
+ elsif receiver_type == 'UserID'
360
+ xml.tag! 'ReceiverID', recipient
361
+ else
362
+ raise ArgumentError.new("Unknown receiver_type: #{receiver_type}")
363
+ end
364
+ xml.tag! 'Amount', amount(money), 'currencyID' => (options[:currency] || currency(money))
357
365
  xml.tag! 'Note', options[:note] if options[:note]
358
366
  xml.tag! 'UniqueId', options[:unique_id] if options[:unique_id]
359
367
  end
@@ -394,7 +394,7 @@ module ActiveMerchant #:nodoc:
394
394
  post[:StreetAddress] = address[:address1]
395
395
  post[:StreetAddress2] = address[:address2]
396
396
  post[:City] = address[:city]
397
- post[:State] = address[:state]
397
+ post[:State] = address[:state] || 'XX'
398
398
  post[:ZipCode] = address[:zip]
399
399
  post[:Country] = address[:country]
400
400
  post[:Phone] = address[:phone]
@@ -406,7 +406,7 @@ module ActiveMerchant #:nodoc:
406
406
  post[:ShipToStreetAddress] = address[:address1]
407
407
  post[:ShipToStreetAddress2] = address[:address2]
408
408
  post[:ShipToCity] = address[:city]
409
- post[:ShipToState] = address[:state]
409
+ post[:ShipToState] = address[:state] || 'XX'
410
410
  post[:ShipToZipCode] = address[:zip]
411
411
  post[:ShipToCountry] = address[:country]
412
412
  post[:ShipToPhone] = address[:phone]
@@ -1,4 +1,5 @@
1
- require 'active_support/core_ext/float/rounding.rb' # Float#round(precision)
1
+ require 'active_support/version' # for ActiveSupport2.3
2
+ require 'active_support/core_ext/float/rounding.rb' unless ActiveSupport::VERSION::MAJOR > 3 # Float#round(precision)
2
3
 
3
4
  module ActiveMerchant #:nodoc:
4
5
  module Billing #:nodoc:
@@ -9,11 +10,11 @@ module ActiveMerchant #:nodoc:
9
10
  # so preferably pass in X.2 decimal so that no rounding occurs. It is
10
11
  # rounded because if it looks like 00.000 Authorize.Net fails the
11
12
  # transaction as incorrectly formatted.
12
- #
13
+ #
13
14
  # payment_service_for('order_id', 'authorize_net_account', :service => :authorize_net_sim, :amount => 157.0) do |service|
14
- #
15
+ #
15
16
  # # You must call setup_hash and invoice
16
- #
17
+ #
17
18
  # service.setup_hash :transaction_key => '8CP6zJ7uD875J6tY',
18
19
  # :order_timestamp => 1206836763
19
20
  # service.customer_id 8
@@ -24,7 +25,7 @@ module ActiveMerchant #:nodoc:
24
25
  # service.billing_address :zip => 'g',
25
26
  # :country => 'United States of America',
26
27
  # :address => 'g'
27
- #
28
+ #
28
29
  # service.ship_to_address :first_name => 'g',
29
30
  # :last_name => 'g',
30
31
  # :city => '',
@@ -33,7 +34,7 @@ module ActiveMerchant #:nodoc:
33
34
  # :state => address.state,
34
35
  # :country => 'United States of America',
35
36
  # :zip => 'g'
36
- #
37
+ #
37
38
  # service.invoice "516428355" # your invoice number
38
39
  # # The end-user is presented with the HTML produced by the notify_url.
39
40
  # service.notify_url "http://t/authorize_net_sim/payment_received_notification_sub_step"
@@ -48,20 +49,20 @@ module ActiveMerchant #:nodoc:
48
49
  # server.add_tax_as_line_item # same with tax
49
50
  # # See the helper.rb file for various custom fields
50
51
  # end
51
-
52
- class Helper < ActiveMerchant::Billing::Integrations::Helper
52
+
53
+ class Helper < ActiveMerchant::Billing::Integrations::Helper
53
54
  mapping :order, 'x_fp_sequence'
54
55
  mapping :account, 'x_login'
55
-
56
+
56
57
  mapping :customer, :first_name => 'x_first_name',
57
58
  :last_name => 'x_last_name',
58
59
  :email => 'x_email',
59
60
  :phone => 'x_phone'
60
-
61
+
61
62
  mapping :notify_url, 'x_relay_url'
62
63
  mapping :return_url, '' # unused
63
64
  mapping :cancel_return_url, '' # unused
64
-
65
+
65
66
  # Custom fields for Authorize.net SIM.
66
67
  # See http://www.Authorize.Net/support/SIM_guide.pdf for more descriptions.
67
68
  mapping :fax, 'x_fax'
@@ -69,18 +70,18 @@ module ActiveMerchant #:nodoc:
69
70
  mapping :description, 'x_description'
70
71
  mapping :tax, 'x_tax'
71
72
  mapping :shipping, 'x_freight'
72
-
73
+
73
74
  # True or false, or 0 or 1 same effect [not required to send one,
74
75
  # defaults to false].
75
76
  mapping :test_request, 'x_test_request'
76
-
77
+
77
78
  # This one is necessary for the notify url to be able to parse its
78
79
  # information later! They also pass back customer id, if that's
79
80
  # useful.
80
81
  def invoice(number)
81
82
  add_field 'x_invoice_num', number
82
83
  end
83
-
84
+
84
85
  # Set the billing address. Call like service.billing_address {:city =>
85
86
  # 'provo, :state => 'UT'}...
86
87
  def billing_address(options)
@@ -90,29 +91,29 @@ module ActiveMerchant #:nodoc:
90
91
  raise 'must use address1 and address2' if options[:address]
91
92
  add_field 'x_address', (options[:address1].to_s + ' ' + options[:address2].to_s).strip
92
93
  end
93
-
94
+
94
95
  # Adds a custom field which you submit to Authorize.Net. These fields
95
96
  # are all passed back to you verbatim when it does its relay
96
97
  # (callback) to you note that if you call it twice with the same name,
97
- # this function only uses keeps the second value you called it with.
98
+ # this function only uses keeps the second value you called it with.
98
99
  def add_custom_field(name, value)
99
100
  add_field name, value
100
101
  end
101
-
102
+
102
103
  # Displays tax as a line item, so they can see it. Otherwise it isn't
103
104
  # displayed.
104
105
  def add_tax_as_line_item
105
106
  raise unless @fields['x_tax']
106
107
  add_line_item :name => 'Total Tax', :quantity => 1, :unit_price => @fields['x_tax'], :tax => 0, :line_title => 'Tax'
107
108
  end
108
-
109
+
109
110
  # Displays shipping as a line item, so they can see it. Otherwise it
110
111
  # isn't displayed.
111
112
  def add_shipping_as_line_item(extra_options = {})
112
113
  raise 'must set shipping/freight before calling this' unless @fields['x_freight']
113
114
  add_line_item extra_options.merge({:name => 'Shipping and Handling Cost', :quantity => 1, :unit_price => @fields['x_freight'], :line_title => 'Shipping'})
114
115
  end
115
-
116
+
116
117
  # Add ship_to_address in the same format as the normal address is
117
118
  # added.
118
119
  def ship_to_address(options)
@@ -124,7 +125,7 @@ module ActiveMerchant #:nodoc:
124
125
  raise 'must use :address1 and/or :address2' if options[:address]
125
126
  add_field 'x_ship_to_address', (options[:address1].to_s + ' ' + options[:address2].to_s).strip
126
127
  end
127
-
128
+
128
129
  # These control the look of the SIM payment page. Note that you can
129
130
  # include a CSS header in descriptors, etc.
130
131
  mapping :color_link, 'x_color_link'
@@ -133,7 +134,7 @@ module ActiveMerchant #:nodoc:
133
134
  mapping :background_url, 'x_background_url' # background image url for the page
134
135
  mapping :payment_header, 'x_header_html_payment_form'
135
136
  mapping :payment_footer, 'x_footer_html_payment_form'
136
-
137
+
137
138
  # For this to work you must have also passed in an email for the
138
139
  # purchaser.
139
140
  def yes_email_customer_from_authorizes_side
@@ -149,7 +150,7 @@ module ActiveMerchant #:nodoc:
149
150
  # You can use the :line_title for the product name and then :name for description, if desired
150
151
  def add_line_item(options)
151
152
  raise 'needs name' unless options[:name]
152
-
153
+
153
154
  if @line_item_count == 30
154
155
  # Add a note that we are not showing at least one -- AN doesn't
155
156
  # display more than 30 or so.
@@ -159,18 +160,18 @@ module ActiveMerchant #:nodoc:
159
160
  # Create a new description, which can't be too big, so truncate here.
160
161
  @raw_html_fields[-1][1] = description_of_last.gsub($1, $1[0..200] + ' + more unshown items after this one.')
161
162
  end
162
-
163
+
163
164
  name = options[:name]
164
165
  quantity = options[:quantity] || 1
165
166
  line_title = options[:line_title] || ('Item ' + (@line_item_count + 1).to_s) # left most field
166
167
  unit_price = options[:unit_price] || 0
167
168
  unit_price = unit_price.to_f.round(2)
168
169
  tax_value = options[:tax_value] || 'N'
169
-
170
+
170
171
  # Sanitization, in case they include a reserved word here, following
171
172
  # their guidelines; unfortunately, they require 'raw' fields here,
172
173
  # not CGI escaped, using their own delimiters.
173
- #
174
+ #
174
175
  # Authorize.net ignores the second field (sanitized_short_name)
175
176
  raise 'illegal char for line item <|>' if name.include? '<|>'
176
177
  raise 'illegal char for line item "' if name.include? '"'
@@ -180,19 +181,19 @@ module ActiveMerchant #:nodoc:
180
181
  # the HTML presented to the end-user's browser (e.g., spaces turn
181
182
  # into +'s).
182
183
  sanitized_short_name = name[0..30]
183
- name = name[0..255]
184
+ name = name[0..255]
184
185
 
185
186
  add_raw_html_field "x_line_item", "#{line_title}<|>#{sanitized_short_name}<|>#{name}<|>#{quantity}<|>#{unit_price}<|>#{tax_value}"
186
187
 
187
188
  @line_item_count += 1
188
189
  end
189
-
190
+
190
191
  # If you call this it will e-mail to this address a copy of a receipt
191
192
  # after successful, from Authorize.Net.
192
193
  def email_merchant_from_authorizes_side(to_this_email)
193
194
  add_field 'x_email_merchant', to_this_email
194
195
  end
195
-
196
+
196
197
  # You MUST call this at some point for it to actually work. Options
197
198
  # must include :transaction_key and :order_timestamp
198
199
  def setup_hash(options)
@@ -204,7 +205,7 @@ module ActiveMerchant #:nodoc:
204
205
  add_field 'x_fp_hash', hmac
205
206
  add_field 'x_fp_timestamp', options[:order_timestamp].to_i
206
207
  end
207
-
208
+
208
209
  # Note that you should call #invoice and #setup_hash as well, for the
209
210
  # response_url to actually work.
210
211
  def initialize(order, account, options = {})
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/float/rounding.rb' # Float#round(precision)
2
-
3
1
  module ActiveMerchant #:nodoc:
4
2
  module Billing #:nodoc:
5
3
  module Integrations #:nodoc:
@@ -7,8 +7,8 @@ module ActiveMerchant #:nodoc:
7
7
  autoload :Return, File.dirname(__FILE__) + '/hi_trust/return.rb'
8
8
  autoload :Notification, File.dirname(__FILE__) + '/hi_trust/notification.rb'
9
9
 
10
- TEST_URL = 'https://testtrustlink.hitrust.com.tw/TrustLink/TrxReq'
11
- LIVE_URL = 'https://trustlink.hitrust.com.tw/TrustLink/TrxReq'
10
+ TEST_URL = 'https://testtrustlink.hitrust.com.tw/TrustLink/TrxReqForJava'
11
+ LIVE_URL = 'https://trustlink.hitrust.com.tw/TrustLink/TrxReqForJava'
12
12
 
13
13
  def self.service_url
14
14
  ActiveMerchant::Billing::Base.integration_mode == :test ? TEST_URL : LIVE_URL
@@ -1,4 +1,5 @@
1
- require 'active_support/core_ext/float/rounding.rb' # Float#round(precision)
1
+ require 'active_support/version' # for ActiveSupport2.3
2
+ require 'active_support/core_ext/float/rounding.rb' unless ActiveSupport::VERSION::MAJOR > 3 # Float#round(precision)
2
3
 
3
4
  module ActiveMerchant #:nodoc:
4
5
  module Billing #:nodoc:
@@ -13,7 +14,7 @@ module ActiveMerchant #:nodoc:
13
14
  # in addition to the user being redirected to your return_url, the return_url will
14
15
  # be accessed by the PxPay servers directly, immediately after transaction success.
15
16
  #
16
- # payment_service_for('order_id', 'pxpay_user_ID', :service => :pxpay,
17
+ # payment_service_for('order_id', 'pxpay_user_ID', :service => :pxpay,
17
18
  # :amount => 157.0, :currency => 'USD', :credential2 => 'pxpay_key') do |service|
18
19
  #
19
20
  # service.customer :email => 'customer@email.com'
@@ -3,40 +3,40 @@ module ActiveMerchant #:nodoc:
3
3
  module Integrations #:nodoc:
4
4
  module Verkkomaksut
5
5
  class Helper < ActiveMerchant::Billing::Integrations::Helper
6
-
6
+
7
7
  # Fetches the md5secret and adds MERCHANT_ID and API TYPE to the form
8
8
  def initialize(order, account, options = {})
9
9
  md5secret options.delete(:credential2)
10
10
  super
11
11
  add_field("MERCHANT_ID", account)
12
12
  add_field("TYPE", "E1")
13
- end
14
-
13
+ end
14
+
15
15
  def md5secret(value)
16
16
  @md5secret = value
17
17
  end
18
-
18
+
19
19
  # Adds the AUTHCODE to the form
20
20
  def form_fields
21
21
  @fields.merge("AUTHCODE" => generate_md5string)
22
22
  end
23
-
23
+
24
24
  # Calculates the AUTHCODE
25
25
  def generate_md5string
26
26
  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"],
27
27
  @fields["NOTIFY_ADDRESS"], @fields["TYPE"], @fields["CULTURE"], @fields["PRESELECTED_METHOD"], @fields["MODE"], @fields["VISIBLE_METHODS"], @fields["GROUP"], @fields["CONTACT_TELNO"], @fields["CONTACT_CELLNO"],
28
28
  @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"],
29
29
  @fields["ITEMS"]]
30
-
30
+
31
31
  (0..@fields["ITEMS"].to_i-1).each do |i|
32
32
  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}]"]]
33
33
  end
34
-
34
+
35
35
  fields = fields.join("|")
36
-
36
+
37
37
  return Digest::MD5.hexdigest(fields).upcase
38
38
  end
39
-
39
+
40
40
  # Mappings
41
41
  mapping :merchant_id, "MERCHANT_ID"
42
42
  mapping :order, "ORDER_NUMBER"
@@ -47,8 +47,8 @@ module ActiveMerchant #:nodoc:
47
47
  :phone => "CONTACT_CELLNO",
48
48
  :tellno => "CONTACT_TELLNO",
49
49
  :company => "CONTACT_COMPANY"
50
-
51
-
50
+
51
+
52
52
  mapping :billing_address, :city => "CONTACT_ADDR_CITY",
53
53
  :address1 => "CONTACT_ADDR_STREET",
54
54
  :address2 => "",
@@ -71,8 +71,9 @@ module ActiveMerchant #:nodoc:
71
71
  mapping :mode, "MODE"
72
72
  mapping :visible_methods, "VISIBLE_METHODS"
73
73
  mapping :group, "GROUP"
74
-
74
+
75
75
  (0..499.to_i).each do |i|
76
+ mapping "item_title_#{i}".to_sym, "ITEM_TITLE[#{i}]"
76
77
  mapping "item_no_#{i}".to_sym, "ITEM_NO[#{i}]"
77
78
  mapping "item_amount_#{i}".to_sym, "ITEM_AMOUNT[#{i}]"
78
79
  mapping "item_price_#{i}".to_sym, "ITEM_PRICE[#{i}]"
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = "1.34.1"
2
+ VERSION = "1.35.0"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: activemerchant
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.34.1
5
+ version: 1.35.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Tobias Luetke
@@ -37,7 +37,7 @@ cert_chain:
37
37
  Z1BvU1BxN25rK3MyRlFVQko5VVpGSzFsZ016aG8vNGZaZ3pKd2J1K2NPOFNO
38
38
  dWFMUy9iagpoUGFTVHlWVTB5Q1Nudz09Ci0tLS0tRU5EIENFUlRJRklDQVRF
39
39
  LS0tLS0K
40
- date: 2013-06-28 00:00:00.000000000 Z
40
+ date: 2013-07-25 00:00:00.000000000 Z
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
43
  version_requirements: !ruby/object:Gem::Requirement
@@ -244,6 +244,7 @@ files:
244
244
  - lib/active_merchant/billing/gateways/balanced.rb
245
245
  - lib/active_merchant/billing/gateways/banwire.rb
246
246
  - lib/active_merchant/billing/gateways/barclays_epdq.rb
247
+ - lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb
247
248
  - lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb
248
249
  - lib/active_merchant/billing/gateways/beanstream.rb
249
250
  - lib/active_merchant/billing/gateways/beanstream_interac.rb
@@ -289,6 +290,7 @@ files:
289
290
  - lib/active_merchant/billing/gateways/merchant_e_solutions.rb
290
291
  - lib/active_merchant/billing/gateways/merchant_one.rb
291
292
  - lib/active_merchant/billing/gateways/merchant_ware.rb
293
+ - lib/active_merchant/billing/gateways/merchant_ware_version_four.rb
292
294
  - lib/active_merchant/billing/gateways/merchant_warrior.rb
293
295
  - lib/active_merchant/billing/gateways/mercury.rb
294
296
  - lib/active_merchant/billing/gateways/metrics_global.rb
metadata.gz.sig CHANGED
Binary file