activemerchant 1.27.0 → 1.28.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +3 -0
- data/CHANGELOG +13 -0
- data/README.md +4 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +3 -1
- data/lib/active_merchant/billing/gateways/banwire.rb +92 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +35 -35
- data/lib/active_merchant/billing/gateways/elavon.rb +192 -23
- data/lib/active_merchant/billing/gateways/litle.rb +7 -2
- data/lib/active_merchant/billing/gateways/orbital.rb +229 -88
- data/lib/active_merchant/billing/gateways/paypal_express.rb +22 -2
- data/lib/active_merchant/billing/integrations/easy_pay/common.rb +1 -1
- data/lib/active_merchant/billing/integrations/easy_pay/helper.rb +1 -5
- data/lib/active_merchant/billing/integrations/easy_pay/notification.rb +10 -2
- data/lib/active_merchant/billing/integrations/paysbuy.rb +36 -0
- data/lib/active_merchant/billing/integrations/paysbuy/helper.rb +15 -0
- data/lib/active_merchant/billing/integrations/paysbuy/notification.rb +28 -0
- data/lib/active_merchant/billing/integrations/webmoney.rb +43 -0
- data/lib/active_merchant/billing/integrations/webmoney/common.rb +17 -0
- data/lib/active_merchant/billing/integrations/webmoney/helper.rb +39 -0
- data/lib/active_merchant/billing/integrations/webmoney/notification.rb +31 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +60 -25
- metadata.gz.sig +0 -0
data.tar.gz.sig
ADDED
data/CHANGELOG
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.28.0 (August 10, 2012)
|
4
|
+
|
5
|
+
* PayPal Express: support non standard locale codes [Soleone]
|
6
|
+
* Litle: allow setting test mode per transaction [jduff]
|
7
|
+
* Add Banwire gateway [acolin]
|
8
|
+
* Authorize.Net CIM gateway: Move cardCode after order to comply with the XSD [davetron5000]
|
9
|
+
* Add WebMoney integration [Mehonoshin]
|
10
|
+
* EasyPay: Make symmetric with other integrations [nashby]
|
11
|
+
* Add Paysbuy integration [divineforest]
|
12
|
+
* Bogus gateway: Use last digit for pass/fail [mipearson]
|
13
|
+
* Elavon gateway: Separate from Viaklix, implement refund & void [duff]
|
14
|
+
* Orbital gateway: Update to API version 5.6 and add support for profile requests [rbarazi]
|
15
|
+
|
3
16
|
== Version 1.27.0 (August 10, 2012)
|
4
17
|
|
5
18
|
* Add First Data integration [courtland]
|
data/README.md
CHANGED
@@ -87,6 +87,7 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
|
|
87
87
|
* [Authorize.Net](http://www.authorize.net/) - US
|
88
88
|
* [Authorize.Net CIM](http://www.authorize.net/) - US
|
89
89
|
* [Balanced](https://www.balancedpayments.com/) - US
|
90
|
+
* [Banwire](https://www.banwire.com/) - MX
|
90
91
|
* [Barclays ePDQ](http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/) - UK
|
91
92
|
* [Beanstream.com](http://www.beanstream.com/) - CA
|
92
93
|
* [BluePay](http://www.bluepay.com/) - US
|
@@ -125,7 +126,7 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
|
|
125
126
|
* [NMI](http://nmi.com/) - US
|
126
127
|
* [Ogone DirectLink](http://www.ogone.com) - BE, DE, FR, NL, AT, CH
|
127
128
|
* [Optimal Payments](http://www.optimalpayments.com/) - CA, US, UK
|
128
|
-
* [Orbital Paymentech](http://chasepaymentech.com/) - CA, US
|
129
|
+
* [Orbital Paymentech](http://chasepaymentech.com/) - CA, US, UK, GB
|
129
130
|
* [PayBox Direct](http://www.paybox.com) - FR
|
130
131
|
* [PayGate PayXML](http://paygate.co.za/) - US, ZA
|
131
132
|
* [PayJunction](http://www.payjunction.com/) - US
|
@@ -181,11 +182,13 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
|
|
181
182
|
* [Nochex](http://www.nochex.com)
|
182
183
|
* [Paxum](https://www.paxum.com/)
|
183
184
|
* [PayPal Website Payments Standard](https://www.paypal.com/cgi-bin/webscr?cmd#_wp-standard-overview-outside)
|
185
|
+
* [Paysbuy](https://www.paysbuy.com/) - TH
|
184
186
|
* [Robokassa](http://robokassa.ru/)
|
185
187
|
* [SagePay Form](http://www.sagepay.com/products_services/sage_pay_go/integration/form)
|
186
188
|
* [Suomen Maksuturva](https://www.maksuturva.fi/services/vendor_services/integration_guidelines.html)
|
187
189
|
* [Valitor](http://www.valitor.is/) - IS
|
188
190
|
* [Verkkomaksut](http://www.verkkomaksut.fi) - FI
|
191
|
+
* [WebMoney](http://www.webmoney.ru) - RU
|
189
192
|
* [WebPay](http://webpay.by/)
|
190
193
|
* [WorldPay](http://www.worldpay.com)
|
191
194
|
|
@@ -673,9 +673,11 @@ module ActiveMerchant #:nodoc:
|
|
673
673
|
xml.tag!('customerProfileId', transaction[:customer_profile_id])
|
674
674
|
xml.tag!('customerPaymentProfileId', transaction[:customer_payment_profile_id])
|
675
675
|
xml.tag!('approvalCode', transaction[:approval_code]) if transaction[:type] == :capture_only
|
676
|
-
tag_unless_blank(xml, 'cardCode', transaction[:card_code])
|
677
676
|
end
|
678
677
|
add_order(xml, transaction[:order]) if transaction[:order].present?
|
678
|
+
unless [:void,:refund,:prior_auth_capture].include?(transaction[:type])
|
679
|
+
tag_unless_blank(xml, 'cardCode', transaction[:card_code])
|
680
|
+
end
|
679
681
|
end
|
680
682
|
end
|
681
683
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class BanwireGateway < Gateway
|
4
|
+
URL = 'https://banwire.com/api.pago_pro'
|
5
|
+
|
6
|
+
self.supported_countries = ['MX']
|
7
|
+
self.supported_cardtypes = [:visa, :master, :american_express]
|
8
|
+
self.homepage_url = 'http://www.banwire.com/'
|
9
|
+
self.display_name = 'Banwire'
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
requires!(options, :login)
|
13
|
+
@options = options
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def purchase(money, creditcard, options = {})
|
18
|
+
post = {}
|
19
|
+
add_response_type(post)
|
20
|
+
add_customer_data(post, options)
|
21
|
+
add_order_data(post, options)
|
22
|
+
add_creditcard(post, creditcard)
|
23
|
+
add_address(post, creditcard, options)
|
24
|
+
add_customer_data(post, options)
|
25
|
+
add_amount(post, money, options)
|
26
|
+
|
27
|
+
commit(money, post)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def add_response_type(post)
|
33
|
+
post[:response_format] = "JSON"
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_customer_data(post, options)
|
37
|
+
post[:user] = @options[:login]
|
38
|
+
post[:phone] = options[:billing_address][:phone]
|
39
|
+
post[:mail] = options[:email]
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_order_data(post, options)
|
43
|
+
post[:reference] = options[:order_id]
|
44
|
+
post[:concept] = options[:description]
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_address(post, creditcard, options)
|
48
|
+
post[:address] = options[:billing_address][:address1]
|
49
|
+
post[:post_code] = options[:billing_address][:zipcode]
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_creditcard(post, creditcard)
|
53
|
+
post[:card_num] = creditcard.number
|
54
|
+
post[:card_name] = creditcard.name
|
55
|
+
post[:card_type] = card_brand(creditcard)
|
56
|
+
post[:card_exp] = "#{sprintf("%02d", creditcard.month)}/#{"#{creditcard.year}"[-2, 2]}"
|
57
|
+
post[:card_ccv2] = creditcard.verification_value
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_amount(post, money, options)
|
61
|
+
post[:ammount] = amount(money)
|
62
|
+
post[:currency] = options[:currency]
|
63
|
+
end
|
64
|
+
|
65
|
+
def card_brand(card)
|
66
|
+
brand = super
|
67
|
+
({"master" => "mastercard", "american_express" => "amex"}[brand] || brand)
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse(body)
|
71
|
+
JSON.parse(body)
|
72
|
+
end
|
73
|
+
|
74
|
+
def commit(money, parameters)
|
75
|
+
response = parse(ssl_post(URL, post_data(parameters)))
|
76
|
+
Response.new(success?(response),
|
77
|
+
response["message"],
|
78
|
+
response,
|
79
|
+
:test => test?,
|
80
|
+
:authorization => response["code_auth"])
|
81
|
+
end
|
82
|
+
|
83
|
+
def success?(response)
|
84
|
+
(response["response"] == "ok")
|
85
|
+
end
|
86
|
+
|
87
|
+
def post_data(parameters = {})
|
88
|
+
parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -3,57 +3,57 @@ module ActiveMerchant #:nodoc:
|
|
3
3
|
# Bogus Gateway
|
4
4
|
class BogusGateway < Gateway
|
5
5
|
AUTHORIZATION = '53433'
|
6
|
-
|
6
|
+
|
7
7
|
SUCCESS_MESSAGE = "Bogus Gateway: Forced success"
|
8
8
|
FAILURE_MESSAGE = "Bogus Gateway: Forced failure"
|
9
|
-
ERROR_MESSAGE = "Bogus Gateway: Use CreditCard number 1 for success, 2 for exception and anything else for error"
|
10
|
-
CREDIT_ERROR_MESSAGE = "Bogus Gateway: Use CreditCard number 1 for success, 2 for exception and anything else for error"
|
11
|
-
UNSTORE_ERROR_MESSAGE = "Bogus Gateway: Use trans_id 1 for success, 2 for exception and anything else for error"
|
12
|
-
CAPTURE_ERROR_MESSAGE = "Bogus Gateway: Use authorization number 1 for exception, 2 for error and anything else for success"
|
13
|
-
VOID_ERROR_MESSAGE = "Bogus Gateway: Use authorization number 1 for exception, 2 for error and anything else for success"
|
14
|
-
REFUND_ERROR_MESSAGE = "Bogus Gateway: Use trans_id number 1 for exception, 2 for error and anything else for success"
|
15
|
-
|
9
|
+
ERROR_MESSAGE = "Bogus Gateway: Use CreditCard number ending in 1 for success, 2 for exception and anything else for error"
|
10
|
+
CREDIT_ERROR_MESSAGE = "Bogus Gateway: Use CreditCard number ending in 1 for success, 2 for exception and anything else for error"
|
11
|
+
UNSTORE_ERROR_MESSAGE = "Bogus Gateway: Use trans_id ending in 1 for success, 2 for exception and anything else for error"
|
12
|
+
CAPTURE_ERROR_MESSAGE = "Bogus Gateway: Use authorization number ending in 1 for exception, 2 for error and anything else for success"
|
13
|
+
VOID_ERROR_MESSAGE = "Bogus Gateway: Use authorization number ending in 1 for exception, 2 for error and anything else for success"
|
14
|
+
REFUND_ERROR_MESSAGE = "Bogus Gateway: Use trans_id number ending in 1 for exception, 2 for error and anything else for success"
|
15
|
+
|
16
16
|
self.supported_countries = ['US']
|
17
17
|
self.supported_cardtypes = [:bogus]
|
18
18
|
self.homepage_url = 'http://example.com'
|
19
19
|
self.display_name = 'Bogus'
|
20
|
-
|
20
|
+
|
21
21
|
def authorize(money, credit_card_or_reference, options = {})
|
22
22
|
money = amount(money)
|
23
23
|
case normalize(credit_card_or_reference)
|
24
|
-
when
|
24
|
+
when /1$/
|
25
25
|
Response.new(true, SUCCESS_MESSAGE, {:authorized_amount => money}, :test => true, :authorization => AUTHORIZATION )
|
26
|
-
when
|
26
|
+
when /2$/
|
27
27
|
Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money, :error => FAILURE_MESSAGE }, :test => true)
|
28
28
|
else
|
29
29
|
raise Error, ERROR_MESSAGE
|
30
|
-
end
|
30
|
+
end
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def purchase(money, credit_card_or_reference, options = {})
|
34
34
|
money = amount(money)
|
35
35
|
case normalize(credit_card_or_reference)
|
36
|
-
when
|
36
|
+
when /1$/, AUTHORIZATION
|
37
37
|
Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
|
38
|
-
when
|
38
|
+
when /2$/
|
39
39
|
Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE },:test => true)
|
40
40
|
else
|
41
41
|
raise Error, ERROR_MESSAGE
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def recurring(money, credit_card_or_reference, options = {})
|
46
46
|
money = amount(money)
|
47
47
|
case normalize(credit_card_or_reference)
|
48
|
-
when
|
48
|
+
when /1$/
|
49
49
|
Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
|
50
|
-
when
|
50
|
+
when /2$/
|
51
51
|
Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE },:test => true)
|
52
52
|
else
|
53
53
|
raise Error, ERROR_MESSAGE
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def credit(money, credit_card_or_reference, options = {})
|
58
58
|
if credit_card_or_reference.is_a?(String)
|
59
59
|
deprecated CREDIT_DEPRECATION_MESSAGE
|
@@ -62,9 +62,9 @@ module ActiveMerchant #:nodoc:
|
|
62
62
|
|
63
63
|
money = amount(money)
|
64
64
|
case normalize(credit_card_or_reference)
|
65
|
-
when
|
65
|
+
when /1$/
|
66
66
|
Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true )
|
67
|
-
when
|
67
|
+
when /2$/
|
68
68
|
Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true)
|
69
69
|
else
|
70
70
|
raise Error, CREDIT_ERROR_MESSAGE
|
@@ -74,21 +74,21 @@ module ActiveMerchant #:nodoc:
|
|
74
74
|
def refund(money, reference, options = {})
|
75
75
|
money = amount(money)
|
76
76
|
case reference
|
77
|
-
when
|
77
|
+
when /1$/
|
78
78
|
raise Error, REFUND_ERROR_MESSAGE
|
79
|
-
when
|
79
|
+
when /2$/
|
80
80
|
Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true)
|
81
81
|
else
|
82
82
|
Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
def capture(money, reference, options = {})
|
87
87
|
money = amount(money)
|
88
88
|
case reference
|
89
|
-
when
|
89
|
+
when /1$/
|
90
90
|
raise Error, CAPTURE_ERROR_MESSAGE
|
91
|
-
when
|
91
|
+
when /2$/
|
92
92
|
Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true)
|
93
93
|
else
|
94
94
|
Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
|
@@ -97,31 +97,31 @@ module ActiveMerchant #:nodoc:
|
|
97
97
|
|
98
98
|
def void(reference, options = {})
|
99
99
|
case reference
|
100
|
-
when
|
100
|
+
when /1$/
|
101
101
|
raise Error, VOID_ERROR_MESSAGE
|
102
|
-
when
|
102
|
+
when /2$/
|
103
103
|
Response.new(false, FAILURE_MESSAGE, {:authorization => reference, :error => FAILURE_MESSAGE }, :test => true)
|
104
104
|
else
|
105
105
|
Response.new(true, SUCCESS_MESSAGE, {:authorization => reference}, :test => true)
|
106
106
|
end
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def store(credit_card_or_reference, options = {})
|
110
110
|
case normalize(credit_card_or_reference)
|
111
|
-
when
|
111
|
+
when /1$/
|
112
112
|
Response.new(true, SUCCESS_MESSAGE, {:billingid => '1'}, :test => true, :authorization => AUTHORIZATION)
|
113
|
-
when
|
113
|
+
when /2$/
|
114
114
|
Response.new(false, FAILURE_MESSAGE, {:billingid => nil, :error => FAILURE_MESSAGE }, :test => true)
|
115
115
|
else
|
116
116
|
raise Error, ERROR_MESSAGE
|
117
|
-
end
|
117
|
+
end
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
def unstore(reference, options = {})
|
121
121
|
case reference
|
122
|
-
when
|
122
|
+
when /1$/
|
123
123
|
Response.new(true, SUCCESS_MESSAGE, {}, :test => true)
|
124
|
-
when
|
124
|
+
when /2$/
|
125
125
|
Response.new(false, FAILURE_MESSAGE, {:error => FAILURE_MESSAGE },:test => true)
|
126
126
|
else
|
127
127
|
raise Error, UNSTORE_ERROR_MESSAGE
|
@@ -29,7 +29,9 @@ module ActiveMerchant #:nodoc:
|
|
29
29
|
# puts response.message # Retrieve the message returned by Elavon
|
30
30
|
# puts response.authorization # Retrieve the unique transaction ID returned by Elavon
|
31
31
|
#
|
32
|
-
class ElavonGateway <
|
32
|
+
class ElavonGateway < Gateway
|
33
|
+
class_attribute :test_url, :live_url, :delimiter, :actions
|
34
|
+
|
33
35
|
self.test_url = 'https://demo.myvirtualmerchant.com/VirtualMerchantDemo/process.do'
|
34
36
|
self.live_url = 'https://www.myvirtualmerchant.com/VirtualMerchant/process.do'
|
35
37
|
|
@@ -42,29 +44,59 @@ module ActiveMerchant #:nodoc:
|
|
42
44
|
self.actions = {
|
43
45
|
:purchase => 'CCSALE',
|
44
46
|
:credit => 'CCCREDIT',
|
47
|
+
:refund => 'CCRETURN',
|
45
48
|
:authorize => 'CCAUTHONLY',
|
46
|
-
:capture => 'CCFORCE'
|
49
|
+
:capture => 'CCFORCE',
|
50
|
+
:void => 'CCVOID'
|
47
51
|
}
|
48
|
-
|
52
|
+
|
53
|
+
# Initialize the Gateway
|
54
|
+
#
|
55
|
+
# The gateway requires that a valid login and password be passed
|
56
|
+
# in the +options+ hash.
|
57
|
+
#
|
58
|
+
# ==== Options
|
59
|
+
#
|
60
|
+
# * <tt>:login</tt> -- Merchant ID
|
61
|
+
# * <tt>:password</tt> -- PIN
|
62
|
+
# * <tt>:user</tt> -- Specify a subuser of the account (optional)
|
63
|
+
# * <tt>:test => +true+ or +false+</tt> -- Force test transactions
|
64
|
+
def initialize(options = {})
|
65
|
+
requires!(options, :login, :password)
|
66
|
+
@options = options
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
# Make a purchase
|
71
|
+
def purchase(money, creditcard, options = {})
|
72
|
+
form = {}
|
73
|
+
add_invoice(form, options)
|
74
|
+
add_creditcard(form, creditcard)
|
75
|
+
add_address(form, options)
|
76
|
+
add_customer_data(form, options)
|
77
|
+
add_test_mode(form, options)
|
78
|
+
commit(:purchase, money, form)
|
79
|
+
end
|
80
|
+
|
49
81
|
# Authorize a credit card for a given amount.
|
50
|
-
#
|
82
|
+
#
|
51
83
|
# ==== Parameters
|
52
84
|
# * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
|
53
85
|
# * <tt>credit_card</tt> - The CreditCard details for the transaction.
|
54
86
|
# * <tt>options</tt>
|
55
|
-
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
87
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
56
88
|
def authorize(money, creditcard, options = {})
|
57
89
|
form = {}
|
58
90
|
add_invoice(form, options)
|
59
|
-
add_creditcard(form, creditcard)
|
60
|
-
add_address(form, options)
|
91
|
+
add_creditcard(form, creditcard)
|
92
|
+
add_address(form, options)
|
61
93
|
add_customer_data(form, options)
|
62
94
|
add_test_mode(form, options)
|
63
95
|
commit(:authorize, money, form)
|
64
96
|
end
|
65
|
-
|
97
|
+
|
66
98
|
# Capture authorized funds from a credit card.
|
67
|
-
#
|
99
|
+
#
|
68
100
|
# ==== Parameters
|
69
101
|
# * <tt>money</tt> - The amount to be captured as an Integer value in cents.
|
70
102
|
# * <tt>authorization</tt> - The approval code returned from the initial authorization.
|
@@ -72,33 +104,116 @@ module ActiveMerchant #:nodoc:
|
|
72
104
|
# * <tt>:credit_card</tt> - The CreditCard details from the initial transaction (required).
|
73
105
|
def capture(money, authorization, options = {})
|
74
106
|
requires!(options, :credit_card)
|
75
|
-
|
107
|
+
|
76
108
|
form = {}
|
77
|
-
|
109
|
+
add_approval_code(form, authorization)
|
78
110
|
add_invoice(form, options)
|
79
111
|
add_creditcard(form, options[:credit_card])
|
80
112
|
add_customer_data(form, options)
|
81
113
|
add_test_mode(form, options)
|
82
114
|
commit(:capture, money, form)
|
83
115
|
end
|
84
|
-
|
116
|
+
|
117
|
+
# Refund a transaction.
|
118
|
+
#
|
119
|
+
# This transaction indicates to the gateway that
|
120
|
+
# money should flow from the merchant to the customer.
|
121
|
+
#
|
122
|
+
# ==== Parameters
|
123
|
+
#
|
124
|
+
# * <tt>money</tt> -- The amount to be credited to the customer as an Integer value in cents.
|
125
|
+
# * <tt>identification</tt> -- The ID of the original transaction against which the refund is being issued.
|
126
|
+
# * <tt>options</tt> -- A hash of parameters.
|
127
|
+
def refund(money, identification, options = {})
|
128
|
+
form = {}
|
129
|
+
add_txn_id(form, identification)
|
130
|
+
add_test_mode(form, options)
|
131
|
+
commit(:refund, money, form)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Void a previous transaction
|
135
|
+
#
|
136
|
+
# ==== Parameters
|
137
|
+
#
|
138
|
+
# * <tt>authorization</tt> - The authorization returned from the previous request.
|
139
|
+
def void(identification, options = {})
|
140
|
+
form = {}
|
141
|
+
add_txn_id(form, identification)
|
142
|
+
add_test_mode(form, options)
|
143
|
+
commit(:void, nil, form)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Make a credit to a card. Use the refund method if you'd like to credit using
|
147
|
+
# previous transaction
|
148
|
+
#
|
149
|
+
# ==== Parameters
|
150
|
+
# * <tt>money</tt> - The amount to be credited as an Integer value in cents.
|
151
|
+
# * <tt>creditcard</tt> - The credit card to be credited.
|
152
|
+
# * <tt>options</tt>
|
153
|
+
def credit(money, creditcard, options = {})
|
154
|
+
if creditcard.is_a?(String)
|
155
|
+
raise ArgumentError, "Reference credits are not supported. Please supply the original credit card or use the #refund method."
|
156
|
+
end
|
157
|
+
|
158
|
+
form = {}
|
159
|
+
add_invoice(form, options)
|
160
|
+
add_creditcard(form, creditcard)
|
161
|
+
add_address(form, options)
|
162
|
+
add_customer_data(form, options)
|
163
|
+
add_test_mode(form, options)
|
164
|
+
commit(:credit, money, form)
|
165
|
+
end
|
166
|
+
|
167
|
+
|
85
168
|
private
|
86
|
-
def
|
87
|
-
form[:
|
169
|
+
def add_invoice(form,options)
|
170
|
+
form[:invoice_number] = (options[:order_id] || options[:invoice]).to_s.slice(0, 10)
|
171
|
+
form[:description] = options[:description].to_s.slice(0, 255)
|
172
|
+
end
|
173
|
+
|
174
|
+
def add_approval_code(form, authorization)
|
175
|
+
form[:approval_code] = authorization.split(';').first
|
176
|
+
end
|
177
|
+
|
178
|
+
def add_txn_id(form, authorization)
|
179
|
+
form[:txn_id] = authorization.split(';').last
|
88
180
|
end
|
89
|
-
|
181
|
+
|
90
182
|
def authorization_from(response)
|
91
|
-
response['approval_code']
|
183
|
+
[response['approval_code'], response['txn_id']].join(';')
|
184
|
+
end
|
185
|
+
|
186
|
+
def add_creditcard(form, creditcard)
|
187
|
+
form[:card_number] = creditcard.number
|
188
|
+
form[:exp_date] = expdate(creditcard)
|
189
|
+
|
190
|
+
if creditcard.verification_value?
|
191
|
+
add_verification_value(form, creditcard)
|
192
|
+
end
|
193
|
+
|
194
|
+
form[:first_name] = creditcard.first_name.to_s.slice(0, 20)
|
195
|
+
form[:last_name] = creditcard.last_name.to_s.slice(0, 30)
|
92
196
|
end
|
93
|
-
|
197
|
+
|
94
198
|
def add_verification_value(form, creditcard)
|
95
|
-
form[:cvv2cvc2] = creditcard.verification_value
|
199
|
+
form[:cvv2cvc2] = creditcard.verification_value
|
96
200
|
form[:cvv2cvc2_indicator] = '1'
|
97
201
|
end
|
98
202
|
|
203
|
+
def add_customer_data(form, options)
|
204
|
+
form[:email] = options[:email].to_s.slice(0, 100) unless options[:email].blank?
|
205
|
+
form[:customer_code] = options[:customer].to_s.slice(0, 10) unless options[:customer].blank?
|
206
|
+
end
|
207
|
+
|
208
|
+
def expdate(creditcard)
|
209
|
+
year = sprintf("%.4i", creditcard.year)
|
210
|
+
month = sprintf("%.2i", creditcard.month)
|
211
|
+
"#{month}#{year[2..3]}"
|
212
|
+
end
|
213
|
+
|
99
214
|
def add_address(form,options)
|
100
|
-
billing_address = options[:billing_address] || options[:address]
|
101
|
-
|
215
|
+
billing_address = options[:billing_address] || options[:address]
|
216
|
+
|
102
217
|
if billing_address
|
103
218
|
form[:avs_address] = billing_address[:address1].to_s.slice(0, 30)
|
104
219
|
form[:address2] = billing_address[:address2].to_s.slice(0, 30)
|
@@ -109,7 +224,7 @@ module ActiveMerchant #:nodoc:
|
|
109
224
|
form[:phone] = billing_address[:phone].to_s.slice(0, 20)
|
110
225
|
form[:country] = billing_address[:country].to_s.slice(0, 50)
|
111
226
|
end
|
112
|
-
|
227
|
+
|
113
228
|
if shipping_address = options[:shipping_address]
|
114
229
|
first_name, last_name = parse_first_and_last_name(shipping_address[:name])
|
115
230
|
form[:ship_to_first_name] = first_name.to_s.slice(0, 20)
|
@@ -123,14 +238,68 @@ module ActiveMerchant #:nodoc:
|
|
123
238
|
form[:ship_to_zip] = shipping_address[:zip].to_s.slice(0, 10)
|
124
239
|
end
|
125
240
|
end
|
126
|
-
|
241
|
+
|
242
|
+
def parse_first_and_last_name(value)
|
243
|
+
name = value.to_s.split(' ')
|
244
|
+
|
245
|
+
last_name = name.pop || ''
|
246
|
+
first_name = name.join(' ')
|
247
|
+
[ first_name, last_name ]
|
248
|
+
end
|
249
|
+
|
250
|
+
def add_test_mode(form, options)
|
251
|
+
form[:test_mode] = 'TRUE' if options[:test_mode]
|
252
|
+
end
|
253
|
+
|
127
254
|
def message_from(response)
|
128
255
|
success?(response) ? response['result_message'] : response['errorMessage']
|
129
256
|
end
|
130
|
-
|
257
|
+
|
131
258
|
def success?(response)
|
132
259
|
!response.has_key?('errorMessage')
|
133
260
|
end
|
261
|
+
|
262
|
+
def commit(action, money, parameters)
|
263
|
+
parameters[:amount] = amount(money)
|
264
|
+
parameters[:transaction_type] = self.actions[action]
|
265
|
+
|
266
|
+
response = parse( ssl_post(test? ? self.test_url : self.live_url, post_data(parameters)) )
|
267
|
+
|
268
|
+
Response.new(response['result'] == '0', message_from(response), response,
|
269
|
+
:test => @options[:test] || test?,
|
270
|
+
:authorization => authorization_from(response),
|
271
|
+
:avs_result => { :code => response['avs_response'] },
|
272
|
+
:cvv_result => response['cvv2_response']
|
273
|
+
)
|
274
|
+
end
|
275
|
+
|
276
|
+
def post_data(parameters)
|
277
|
+
result = preamble
|
278
|
+
result.merge!(parameters)
|
279
|
+
result.collect { |key, value| "ssl_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
280
|
+
end
|
281
|
+
|
282
|
+
def preamble
|
283
|
+
result = {
|
284
|
+
'merchant_id' => @options[:login],
|
285
|
+
'pin' => @options[:password],
|
286
|
+
'show_form' => 'false',
|
287
|
+
'result_format' => 'ASCII'
|
288
|
+
}
|
289
|
+
|
290
|
+
result['user_id'] = @options[:user] unless @options[:user].blank?
|
291
|
+
result
|
292
|
+
end
|
293
|
+
|
294
|
+
def parse(msg)
|
295
|
+
resp = {}
|
296
|
+
msg.split(self.delimiter).collect{|li|
|
297
|
+
key, value = li.split("=")
|
298
|
+
resp[key.strip.gsub(/^ssl_/, '')] = value.to_s.strip
|
299
|
+
}
|
300
|
+
resp
|
301
|
+
end
|
302
|
+
|
134
303
|
end
|
135
304
|
end
|
136
305
|
end
|