activemerchant 1.34.1 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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