activemerchant 1.28.0 → 1.29.1
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/CHANGELOG +41 -0
- data/CONTRIBUTORS +12 -0
- data/README.md +6 -0
- data/lib/active_merchant/billing/gateway.rb +2 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -2
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +77 -78
- data/lib/active_merchant/billing/gateways/balanced.rb +0 -1
- data/lib/active_merchant/billing/gateways/banwire.rb +1 -2
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +19 -20
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +35 -36
- data/lib/active_merchant/billing/gateways/blue_pay.rb +135 -140
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +12 -4
- data/lib/active_merchant/billing/gateways/card_stream.rb +54 -59
- data/lib/active_merchant/billing/gateways/certo_direct.rb +0 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +19 -14
- data/lib/active_merchant/billing/gateways/data_cash.rb +106 -112
- data/lib/active_merchant/billing/gateways/efsnet.rb +29 -34
- data/lib/active_merchant/billing/gateways/elavon.rb +7 -1
- data/lib/active_merchant/billing/gateways/epay.rb +0 -1
- data/lib/active_merchant/billing/gateways/eway.rb +88 -93
- data/lib/active_merchant/billing/gateways/eway_managed.rb +47 -51
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +300 -0
- data/lib/active_merchant/billing/gateways/exact.rb +45 -54
- data/lib/active_merchant/billing/gateways/federated_canada.rb +3 -4
- data/lib/active_merchant/billing/gateways/first_pay.rb +37 -38
- data/lib/active_merchant/billing/gateways/garanti.rb +1 -2
- data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +5 -8
- data/lib/active_merchant/billing/gateways/inspire.rb +52 -52
- data/lib/active_merchant/billing/gateways/instapay.rb +10 -11
- data/lib/active_merchant/billing/gateways/iridium.rb +38 -39
- data/lib/active_merchant/billing/gateways/itransact.rb +7 -9
- data/lib/active_merchant/billing/gateways/jetpay.rb +45 -46
- data/lib/active_merchant/billing/gateways/linkpoint.rb +104 -108
- data/lib/active_merchant/billing/gateways/litle.rb +1 -5
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +153 -155
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +49 -50
- data/lib/active_merchant/billing/gateways/mercury.rb +272 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +9 -10
- data/lib/active_merchant/billing/gateways/migs.rb +5 -3
- data/lib/active_merchant/billing/gateways/modern_payments.rb +6 -7
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +40 -41
- data/lib/active_merchant/billing/gateways/moneris.rb +46 -50
- data/lib/active_merchant/billing/gateways/moneris_us.rb +52 -55
- data/lib/active_merchant/billing/gateways/nab_transact.rb +0 -5
- data/lib/active_merchant/billing/gateways/net_registry.rb +20 -21
- data/lib/active_merchant/billing/gateways/netaxept.rb +30 -36
- data/lib/active_merchant/billing/gateways/netbilling.rb +2 -2
- data/lib/active_merchant/billing/gateways/ogone.rb +0 -5
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +1 -6
- data/lib/active_merchant/billing/gateways/orbital/avs_result.rb +93 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +25 -21
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +1 -6
- data/lib/active_merchant/billing/gateways/pay_junction.rb +62 -63
- data/lib/active_merchant/billing/gateways/pay_secure.rb +29 -30
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +0 -5
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +33 -38
- data/lib/active_merchant/billing/gateways/payment_express.rb +48 -51
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +7 -11
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +7 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +3 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +62 -64
- data/lib/active_merchant/billing/gateways/payway.rb +2 -9
- data/lib/active_merchant/billing/gateways/plugnpay.rb +0 -1
- data/lib/active_merchant/billing/gateways/psigate.rb +102 -94
- data/lib/active_merchant/billing/gateways/psl_card.rb +66 -67
- data/lib/active_merchant/billing/gateways/qbms.rb +0 -6
- data/lib/active_merchant/billing/gateways/quantum.rb +2 -8
- data/lib/active_merchant/billing/gateways/quickpay.rb +2 -3
- data/lib/active_merchant/billing/gateways/realex.rb +6 -16
- data/lib/active_merchant/billing/gateways/redsys.rb +394 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +25 -26
- data/lib/active_merchant/billing/gateways/sage.rb +15 -16
- data/lib/active_merchant/billing/gateways/sage_pay.rb +51 -56
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +1 -2
- data/lib/active_merchant/billing/gateways/samurai.rb +1 -4
- data/lib/active_merchant/billing/gateways/secure_net.rb +0 -1
- data/lib/active_merchant/billing/gateways/secure_pay.rb +5 -8
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +0 -5
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +17 -18
- data/lib/active_merchant/billing/gateways/skip_jack.rb +29 -34
- data/lib/active_merchant/billing/gateways/smart_ps.rb +55 -56
- data/lib/active_merchant/billing/gateways/stripe.rb +8 -3
- data/lib/active_merchant/billing/gateways/trans_first.rb +28 -29
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +85 -87
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +27 -28
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +0 -5
- data/lib/active_merchant/billing/gateways/verifi.rb +86 -87
- data/lib/active_merchant/billing/gateways/viaklix.rb +42 -47
- data/lib/active_merchant/billing/gateways/vindicia.rb +30 -28
- data/lib/active_merchant/billing/gateways/webpay.rb +45 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +0 -6
- data/lib/active_merchant/billing/gateways/worldpay.rb +4 -9
- data/lib/active_merchant/billing/gateways.rb +6 -7
- data/lib/active_merchant/billing/integrations/a1agregator/helper.rb +31 -0
- data/lib/active_merchant/billing/integrations/a1agregator/notification.rb +186 -0
- data/lib/active_merchant/billing/integrations/a1agregator/status.rb +38 -0
- data/lib/active_merchant/billing/integrations/a1agregator.rb +26 -0
- data/lib/active_merchant/billing/integrations/liqpay/helper.rb +43 -0
- data/lib/active_merchant/billing/integrations/liqpay/notification.rb +89 -0
- data/lib/active_merchant/billing/integrations/liqpay/return.rb +83 -0
- data/lib/active_merchant/billing/integrations/liqpay.rb +30 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +17 -1
- data/lib/active_merchant/billing/integrations/notification.rb +4 -0
- data/lib/active_merchant/billing/integrations/pay_fast/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/pay_fast/helper.rb +50 -0
- data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +134 -0
- data/lib/active_merchant/billing/integrations/pay_fast/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/pay_fast.rb +70 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +64 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +10 -7
- data/lib/active_merchant/billing/integrations/webmoney/notification.rb +12 -0
- data/lib/active_merchant/billing/response.rb +17 -4
- data/lib/active_merchant/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +46 -27
- metadata.gz.sig +0 -0
|
@@ -1,140 +1,138 @@
|
|
|
1
|
-
# This class implements the Psigate gateway for the ActiveMerchant module.
|
|
2
|
-
# Psigate = http://www.psigate.com/ The class is currently set up to use
|
|
3
|
-
# the psigate test server while rails is in testing or developement mode.
|
|
4
|
-
# The real server will be used while in production mode.
|
|
5
|
-
#
|
|
6
|
-
# Modifications by Sean O'Hara ( sohara at sohara dot com )
|
|
7
|
-
#
|
|
8
|
-
# Usage for a PreAuth (authorize) is as follows:
|
|
9
|
-
#
|
|
10
|
-
# twenty = 2000
|
|
11
|
-
# gateway = PsigateGateway.new(
|
|
12
|
-
# :login => 'teststore',
|
|
13
|
-
# :password => 'psigate1234'
|
|
14
|
-
# )
|
|
15
|
-
#
|
|
16
|
-
# creditcard = CreditCard.new(
|
|
17
|
-
# :number => '4242424242424242',
|
|
18
|
-
# :month => 8,
|
|
19
|
-
# :year => 2006,
|
|
20
|
-
# :first_name => 'Longbob',
|
|
21
|
-
# :last_name => 'Longsen'
|
|
22
|
-
# )
|
|
23
|
-
# response = @gateway.authorize(twenty, creditcard,
|
|
24
|
-
# :order_id => 1234,
|
|
25
|
-
# :billing_address => {
|
|
26
|
-
# :address1 => '123 fairweather Lane',
|
|
27
|
-
# :address2 => 'Apt B',
|
|
28
|
-
# :city => 'New York',
|
|
29
|
-
# :state => 'NY',
|
|
30
|
-
# :country => 'U.S.A.',
|
|
31
|
-
# :zip => '10010'
|
|
32
|
-
# },
|
|
33
|
-
# :email => 'jack@yahoo.com'
|
|
34
|
-
# )
|
|
35
|
-
|
|
36
1
|
require 'rexml/document'
|
|
37
2
|
|
|
38
3
|
module ActiveMerchant #:nodoc:
|
|
39
4
|
module Billing #:nodoc:
|
|
40
|
-
|
|
5
|
+
# This class implements the Psigate gateway for the ActiveMerchant module.
|
|
6
|
+
#
|
|
7
|
+
# Modifications by Sean O'Hara ( sohara at sohara dot com )
|
|
8
|
+
#
|
|
9
|
+
# Usage for a PreAuth (authorize) is as follows:
|
|
10
|
+
#
|
|
11
|
+
# gateway = PsigateGateway.new(
|
|
12
|
+
# :login => 'teststore',
|
|
13
|
+
# :password => 'psigate1234'
|
|
14
|
+
# )
|
|
15
|
+
#
|
|
16
|
+
# creditcard = CreditCard.new(
|
|
17
|
+
# :number => '4242424242424242',
|
|
18
|
+
# :month => 8,
|
|
19
|
+
# :year => 2006,
|
|
20
|
+
# :first_name => 'Longbob',
|
|
21
|
+
# :last_name => 'Longsen'
|
|
22
|
+
# )
|
|
23
|
+
#
|
|
24
|
+
# twenty = 2000
|
|
25
|
+
# response = @gateway.authorize(twenty, creditcard,
|
|
26
|
+
# :order_id => 1234,
|
|
27
|
+
# :billing_address => {
|
|
28
|
+
# :address1 => '123 fairweather Lane',
|
|
29
|
+
# :address2 => 'Apt B',
|
|
30
|
+
# :city => 'New York',
|
|
31
|
+
# :state => 'NY',
|
|
32
|
+
# :country => 'U.S.A.',
|
|
33
|
+
# :zip => '10010'
|
|
34
|
+
# },
|
|
35
|
+
# :email => 'jack@yahoo.com'
|
|
36
|
+
# )
|
|
41
37
|
class PsigateGateway < Gateway
|
|
42
38
|
self.test_url = 'https://dev.psigate.com:7989/Messenger/XMLMessenger'
|
|
43
39
|
self.live_url = 'https://secure.psigate.com:7934/Messenger/XMLMessenger'
|
|
44
|
-
|
|
40
|
+
|
|
45
41
|
self.supported_cardtypes = [:visa, :master, :american_express]
|
|
46
42
|
self.supported_countries = ['CA']
|
|
47
43
|
self.homepage_url = 'http://www.psigate.com/'
|
|
48
44
|
self.display_name = 'Psigate'
|
|
49
|
-
|
|
45
|
+
|
|
50
46
|
SUCCESS_MESSAGE = 'Success'
|
|
51
47
|
FAILURE_MESSAGE = 'The transaction was declined'
|
|
52
|
-
|
|
48
|
+
|
|
53
49
|
def initialize(options = {})
|
|
54
50
|
requires!(options, :login, :password)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# Psigate PreAuth
|
|
51
|
+
super
|
|
52
|
+
end
|
|
53
|
+
|
|
60
54
|
def authorize(money, creditcard, options = {})
|
|
61
|
-
requires!(options, :order_id)
|
|
62
|
-
options
|
|
63
|
-
commit(money, creditcard, options)
|
|
55
|
+
requires!(options, :order_id)
|
|
56
|
+
options[:CardAction] = "1"
|
|
57
|
+
commit(money, creditcard, options)
|
|
64
58
|
end
|
|
65
|
-
|
|
66
|
-
# Psigate Sale
|
|
59
|
+
|
|
67
60
|
def purchase(money, creditcard, options = {})
|
|
68
|
-
requires!(options, :order_id)
|
|
69
|
-
options
|
|
70
|
-
commit(money, creditcard, options)
|
|
61
|
+
requires!(options, :order_id)
|
|
62
|
+
options[:CardAction] = "0"
|
|
63
|
+
commit(money, creditcard, options)
|
|
71
64
|
end
|
|
72
|
-
|
|
73
|
-
# Psigate PostAuth
|
|
65
|
+
|
|
74
66
|
def capture(money, authorization, options = {})
|
|
75
|
-
options
|
|
67
|
+
options[:CardAction] = "2"
|
|
68
|
+
options[:order_id], options[:trans_ref_number] = split_authorization(authorization)
|
|
76
69
|
commit(money, nil, options)
|
|
77
70
|
end
|
|
78
|
-
|
|
79
71
|
|
|
80
|
-
# Psigate Credit
|
|
81
72
|
def credit(money, authorization, options = {})
|
|
82
73
|
deprecated CREDIT_DEPRECATION_MESSAGE
|
|
83
74
|
refund(money, authorization, options)
|
|
84
75
|
end
|
|
85
76
|
|
|
86
77
|
def refund(money, authorization, options = {})
|
|
87
|
-
options
|
|
78
|
+
options[:CardAction] = "3"
|
|
79
|
+
options[:order_id], options[:trans_ref_number] = split_authorization(authorization)
|
|
88
80
|
commit(money, nil, options)
|
|
89
81
|
end
|
|
90
82
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
def void(authorization, options = {})
|
|
84
|
+
options[:CardAction] = "9"
|
|
85
|
+
options[:order_id], options[:trans_ref_number] = split_authorization(authorization)
|
|
86
|
+
commit(nil, nil, options)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def commit(money, creditcard, options = {})
|
|
92
|
+
response = parse(ssl_post(url, post_data(money, creditcard, options)))
|
|
95
93
|
|
|
96
|
-
Response.new(successful?(response), message_from(response), response,
|
|
97
|
-
:test => test?,
|
|
98
|
-
:authorization => response
|
|
94
|
+
Response.new(successful?(response), message_from(response), response,
|
|
95
|
+
:test => test?,
|
|
96
|
+
:authorization => build_authorization(response) ,
|
|
99
97
|
:avs_result => { :code => response[:avsresult] },
|
|
100
98
|
:cvv_result => response[:cardidresult]
|
|
101
99
|
)
|
|
102
100
|
end
|
|
103
|
-
|
|
101
|
+
|
|
102
|
+
def url
|
|
103
|
+
(test? ? self.test_url : self.live_url)
|
|
104
|
+
end
|
|
105
|
+
|
|
104
106
|
def successful?(response)
|
|
105
107
|
response[:approved] == "APPROVED"
|
|
106
108
|
end
|
|
107
|
-
|
|
109
|
+
|
|
108
110
|
def parse(xml)
|
|
109
111
|
response = {:message => "Global Error Receipt", :complete => false}
|
|
110
112
|
|
|
111
|
-
xml = REXML::Document.new(xml)
|
|
113
|
+
xml = REXML::Document.new(xml)
|
|
112
114
|
xml.elements.each('//Result/*') do |node|
|
|
113
|
-
|
|
114
115
|
response[node.name.downcase.to_sym] = normalize(node.text)
|
|
115
|
-
|
|
116
116
|
end unless xml.root.nil?
|
|
117
117
|
|
|
118
118
|
response
|
|
119
|
-
end
|
|
119
|
+
end
|
|
120
120
|
|
|
121
121
|
def post_data(money, creditcard, options)
|
|
122
122
|
xml = REXML::Document.new
|
|
123
123
|
xml << REXML::XMLDecl.new
|
|
124
|
-
root
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
root = xml.add_element("Order")
|
|
125
|
+
|
|
126
|
+
parameters(money, creditcard, options).each do |key, value|
|
|
127
127
|
root.add_element(key.to_s).text = value if value
|
|
128
|
-
end
|
|
128
|
+
end
|
|
129
129
|
|
|
130
130
|
xml.to_s
|
|
131
131
|
end
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
# for every action.
|
|
135
|
-
def parameters(money, creditcard, options = {})
|
|
132
|
+
|
|
133
|
+
def parameters(money, creditcard, options = {})
|
|
136
134
|
params = {
|
|
137
|
-
# General order
|
|
135
|
+
# General order parameters
|
|
138
136
|
:StoreID => @options[:login],
|
|
139
137
|
:Passphrase => @options[:password],
|
|
140
138
|
:TestResult => options[:test_result],
|
|
@@ -143,12 +141,13 @@ module ActiveMerchant #:nodoc:
|
|
|
143
141
|
:Phone => options[:phone],
|
|
144
142
|
:Fax => options[:fax],
|
|
145
143
|
:Email => options[:email],
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
:TransRefNumber => options[:trans_ref_number],
|
|
145
|
+
|
|
146
|
+
# Credit Card parameters
|
|
148
147
|
:PaymentType => "CC",
|
|
149
148
|
:CardAction => options[:CardAction],
|
|
150
|
-
|
|
151
|
-
# Financial
|
|
149
|
+
|
|
150
|
+
# Financial parameters
|
|
152
151
|
:CustomerIP => options[:ip],
|
|
153
152
|
:SubTotal => amount(money),
|
|
154
153
|
:Tax1 => options[:tax1],
|
|
@@ -159,9 +158,9 @@ module ActiveMerchant #:nodoc:
|
|
|
159
158
|
if creditcard
|
|
160
159
|
exp_month = sprintf("%.2i", creditcard.month) unless creditcard.month.blank?
|
|
161
160
|
exp_year = creditcard.year.to_s[2,2] unless creditcard.year.blank?
|
|
162
|
-
card_id_code = creditcard.verification_value.blank? ? nil : "1"
|
|
161
|
+
card_id_code = (creditcard.verification_value.blank? ? nil : "1")
|
|
163
162
|
|
|
164
|
-
params.update(
|
|
163
|
+
params.update(
|
|
165
164
|
:CardNumber => creditcard.number,
|
|
166
165
|
:CardExpMonth => exp_month,
|
|
167
166
|
:CardExpYear => exp_year,
|
|
@@ -169,9 +168,9 @@ module ActiveMerchant #:nodoc:
|
|
|
169
168
|
:CardIDNumber => creditcard.verification_value
|
|
170
169
|
)
|
|
171
170
|
end
|
|
172
|
-
|
|
173
|
-
if
|
|
174
|
-
params[:Bname] = address[:name] || creditcard.name
|
|
171
|
+
|
|
172
|
+
if(address = (options[:billing_address] || options[:address]))
|
|
173
|
+
params[:Bname] = address[:name] || creditcard.name
|
|
175
174
|
params[:Baddress1] = address[:address1] unless address[:address1].blank?
|
|
176
175
|
params[:Baddress2] = address[:address2] unless address[:address2].blank?
|
|
177
176
|
params[:Bcity] = address[:city] unless address[:city].blank?
|
|
@@ -180,9 +179,9 @@ module ActiveMerchant #:nodoc:
|
|
|
180
179
|
params[:Bcountry] = address[:country] unless address[:country].blank?
|
|
181
180
|
params[:Bcompany] = address[:company] unless address[:company].blank?
|
|
182
181
|
end
|
|
183
|
-
|
|
182
|
+
|
|
184
183
|
if address = options[:shipping_address]
|
|
185
|
-
params[:Sname] = address[:name] || creditcard.name
|
|
184
|
+
params[:Sname] = address[:name] || creditcard.name
|
|
186
185
|
params[:Saddress1] = address[:address1] unless address[:address1].blank?
|
|
187
186
|
params[:Saddress2] = address[:address2] unless address[:address2].blank?
|
|
188
187
|
params[:Scity] = address[:city] unless address[:city].blank?
|
|
@@ -191,10 +190,10 @@ module ActiveMerchant #:nodoc:
|
|
|
191
190
|
params[:Scountry] = address[:country] unless address[:country].blank?
|
|
192
191
|
params[:Scompany] = address[:company] unless address[:company].blank?
|
|
193
192
|
end
|
|
194
|
-
|
|
195
|
-
|
|
193
|
+
|
|
194
|
+
params
|
|
196
195
|
end
|
|
197
|
-
|
|
196
|
+
|
|
198
197
|
def message_from(response)
|
|
199
198
|
if response[:approved] == "APPROVED"
|
|
200
199
|
return SUCCESS_MESSAGE
|
|
@@ -214,6 +213,15 @@ module ActiveMerchant #:nodoc:
|
|
|
214
213
|
else field
|
|
215
214
|
end
|
|
216
215
|
end
|
|
216
|
+
|
|
217
|
+
def split_authorization(authorization)
|
|
218
|
+
order_id, trans_ref_number = authorization.split(';')
|
|
219
|
+
[order_id, trans_ref_number]
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def build_authorization(response)
|
|
223
|
+
[response[:orderid], response[:transrefnumber]].join(";")
|
|
224
|
+
end
|
|
217
225
|
end
|
|
218
226
|
end
|
|
219
227
|
end
|
|
@@ -2,66 +2,66 @@ module ActiveMerchant
|
|
|
2
2
|
module Billing
|
|
3
3
|
#
|
|
4
4
|
# ActiveMerchant PSL Card Gateway
|
|
5
|
-
#
|
|
5
|
+
#
|
|
6
6
|
# Notes:
|
|
7
7
|
# -To be able to use the capture function, the IP address of the machine must be
|
|
8
8
|
# registered with PSL
|
|
9
|
-
# -ESALE_KEYED should only be used in situations where the cardholder perceives the
|
|
10
|
-
# transaction to be Internet-based, such as purchasing from a web site/on-line store.
|
|
11
|
-
# If the Internet is used purely for the transport of information from the merchant
|
|
12
|
-
# directly to the gateway then the appropriate cardholder present or not present message
|
|
9
|
+
# -ESALE_KEYED should only be used in situations where the cardholder perceives the
|
|
10
|
+
# transaction to be Internet-based, such as purchasing from a web site/on-line store.
|
|
11
|
+
# If the Internet is used purely for the transport of information from the merchant
|
|
12
|
+
# directly to the gateway then the appropriate cardholder present or not present message
|
|
13
13
|
# type should be used rather than the ‘E’ equivalent.
|
|
14
14
|
# -The CV2 / AVS policies are set up with the account settings when signing up for an account
|
|
15
15
|
class PslCardGateway < Gateway
|
|
16
16
|
self.money_format = :cents
|
|
17
17
|
self.default_currency = 'GBP'
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
self.supported_countries = ['GB']
|
|
20
20
|
# Visa Credit, Visa Debit, Mastercard, Maestro, Solo, Electron,
|
|
21
21
|
# American Express, Diners Club, JCB, International Maestro,
|
|
22
22
|
# Style, Clydesdale Financial Services, Other
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :jcb, :switch, :solo, :maestro ]
|
|
25
25
|
self.homepage_url = 'http://www.paymentsolutionsltd.com/'
|
|
26
26
|
self.display_name = 'PSL Payment Solutions'
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
# Default ISO 3166 country code (GB)
|
|
29
29
|
cattr_accessor :location
|
|
30
30
|
self.location = 826
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
# PslCard server self.live_url - The url is the same whether testing or live - use
|
|
33
33
|
# the test account when testing...
|
|
34
34
|
self.live_url = self.test_url = 'https://pslcard3.paymentsolutionsltd.com/secure/transact.asp?'
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
# eCommerce sale transaction, details keyed by merchant or cardholder
|
|
37
|
-
MESSAGE_TYPE = 'ESALE_KEYED'
|
|
38
|
-
|
|
37
|
+
MESSAGE_TYPE = 'ESALE_KEYED'
|
|
38
|
+
|
|
39
39
|
# The type of response that we want to get from PSL, options are HTML, XML or REDIRECT
|
|
40
40
|
RESPONSE_ACTION = 'HTML'
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
# Currency Codes
|
|
43
43
|
CURRENCY_CODES = {
|
|
44
44
|
'AUD' => 036,
|
|
45
45
|
'GBP' => 826,
|
|
46
46
|
'USD' => 840
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
#The terminal used - only for swipe transactions, so hard coded to 32 for online
|
|
50
50
|
EMV_TERMINAL_TYPE = 32
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
#Different Dispatch types
|
|
53
53
|
DISPATCH_LATER = 'LATER'
|
|
54
54
|
DISPATCH_NOW = 'NOW'
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
# Return codes
|
|
57
57
|
APPROVED = '00'
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
#Nominal amount to authorize for a 'dispatch later' type
|
|
60
60
|
#The nominal amount is held straight away, when the goods are ready
|
|
61
61
|
#to be dispatched, PSL is informed and the full amount is the
|
|
62
62
|
#taken.
|
|
63
63
|
NOMINAL_AMOUNT = 101
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
AVS_CODE = {
|
|
66
66
|
"ALL MATCH" => 'Y',
|
|
67
67
|
"SECURITY CODE MATCH ONLY" => 'N',
|
|
@@ -70,7 +70,7 @@ module ActiveMerchant
|
|
|
70
70
|
"DATA NOT CHECKED" => 'R',
|
|
71
71
|
"SECURITY CHECKS NOT SUPPORTED" => 'X'
|
|
72
72
|
}
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
CVV_CODE = {
|
|
75
75
|
"ALL MATCH" => 'M',
|
|
76
76
|
"SECURITY CODE MATCH ONLY" => 'M',
|
|
@@ -79,23 +79,22 @@ module ActiveMerchant
|
|
|
79
79
|
"DATA NOT CHECKED" => 'P',
|
|
80
80
|
"SECURITY CHECKS NOT SUPPORTED" => 'X'
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
# Create a new PslCardGateway
|
|
84
|
-
#
|
|
84
|
+
#
|
|
85
85
|
# The gateway requires that a valid :login be passed in the options hash
|
|
86
|
-
#
|
|
86
|
+
#
|
|
87
87
|
# Paramaters:
|
|
88
88
|
# -options:
|
|
89
89
|
# :login - the PslCard account login (required)
|
|
90
90
|
def initialize(options = {})
|
|
91
91
|
requires!(options, :login)
|
|
92
|
-
|
|
93
|
-
@options = options
|
|
92
|
+
|
|
94
93
|
super
|
|
95
94
|
end
|
|
96
95
|
|
|
97
96
|
# Purchase the item straight away
|
|
98
|
-
#
|
|
97
|
+
#
|
|
99
98
|
# Parameters:
|
|
100
99
|
# -money: Amount to be charged as an Integer value in cents
|
|
101
100
|
# -authorization: the PSL cross reference from the previous authorization
|
|
@@ -103,27 +102,27 @@ module ActiveMerchant
|
|
|
103
102
|
#
|
|
104
103
|
# Returns:
|
|
105
104
|
# -ActiveRecord::Billing::Response object
|
|
106
|
-
#
|
|
105
|
+
#
|
|
107
106
|
def purchase(money, credit_card, options = {})
|
|
108
107
|
post = {}
|
|
109
|
-
|
|
108
|
+
|
|
110
109
|
add_amount(post, money, DISPATCH_NOW, options)
|
|
111
110
|
add_credit_card(post, credit_card)
|
|
112
111
|
add_address(post, options)
|
|
113
112
|
add_invoice(post, options)
|
|
114
113
|
add_purchase_details(post)
|
|
115
|
-
|
|
114
|
+
|
|
116
115
|
commit(post)
|
|
117
116
|
end
|
|
118
|
-
|
|
117
|
+
|
|
119
118
|
# Authorize the transaction
|
|
120
|
-
#
|
|
121
|
-
# Reserves the funds on the customer's credit card, but does not
|
|
119
|
+
#
|
|
120
|
+
# Reserves the funds on the customer's credit card, but does not
|
|
122
121
|
# charge the card.
|
|
123
122
|
#
|
|
124
123
|
# This implementation does not authorize the full amount, rather it checks that the full amount
|
|
125
124
|
# is available and only 'reserves' the nominal amount (currently a pound and a penny)
|
|
126
|
-
#
|
|
125
|
+
#
|
|
127
126
|
# Parameters:
|
|
128
127
|
# -money: Amount to be charged as an Integer value in cents
|
|
129
128
|
# -authorization: the PSL cross reference from the previous authorization
|
|
@@ -131,23 +130,23 @@ module ActiveMerchant
|
|
|
131
130
|
#
|
|
132
131
|
# Returns:
|
|
133
132
|
# -ActiveRecord::Billing::Response object
|
|
134
|
-
#
|
|
133
|
+
#
|
|
135
134
|
def authorize(money, credit_card, options = {})
|
|
136
135
|
post = {}
|
|
137
|
-
|
|
136
|
+
|
|
138
137
|
add_amount(post, money, DISPATCH_LATER, options)
|
|
139
138
|
add_credit_card(post, credit_card)
|
|
140
139
|
add_address(post, options)
|
|
141
140
|
add_invoice(post, options)
|
|
142
141
|
add_purchase_details(post)
|
|
143
|
-
|
|
142
|
+
|
|
144
143
|
commit(post)
|
|
145
144
|
end
|
|
146
|
-
|
|
147
|
-
# Post an authorization.
|
|
145
|
+
|
|
146
|
+
# Post an authorization.
|
|
147
|
+
#
|
|
148
|
+
# Captures the funds from an authorized transaction.
|
|
148
149
|
#
|
|
149
|
-
# Captures the funds from an authorized transaction.
|
|
150
|
-
#
|
|
151
150
|
# Parameters:
|
|
152
151
|
# -money: Amount to be charged as an Integer value in cents
|
|
153
152
|
# -authorization: The PSL Cross Reference
|
|
@@ -158,7 +157,7 @@ module ActiveMerchant
|
|
|
158
157
|
#
|
|
159
158
|
def capture(money, authorization, options = {})
|
|
160
159
|
post = {}
|
|
161
|
-
|
|
160
|
+
|
|
162
161
|
add_amount(post, money, DISPATCH_NOW, options)
|
|
163
162
|
add_reference(post, authorization)
|
|
164
163
|
add_purchase_details(post)
|
|
@@ -167,82 +166,82 @@ module ActiveMerchant
|
|
|
167
166
|
end
|
|
168
167
|
|
|
169
168
|
private
|
|
170
|
-
|
|
169
|
+
|
|
171
170
|
def add_credit_card(post, credit_card)
|
|
172
171
|
post[:QAName] = credit_card.name
|
|
173
172
|
post[:CardNumber] = credit_card.number
|
|
174
173
|
post[:EMVTerminalType] = EMV_TERMINAL_TYPE
|
|
175
174
|
post[:ExpMonth] = credit_card.month
|
|
176
175
|
post[:ExpYear] = credit_card.year
|
|
177
|
-
|
|
178
|
-
if requires_start_date_or_issue_number?(credit_card)
|
|
176
|
+
|
|
177
|
+
if requires_start_date_or_issue_number?(credit_card)
|
|
179
178
|
post[:IssueNumber] = credit_card.issue_number unless credit_card.issue_number.blank?
|
|
180
179
|
post[:StartMonth] = credit_card.start_month unless credit_card.start_month.blank?
|
|
181
180
|
post[:StartYear] = credit_card.start_year unless credit_card.start_year.blank?
|
|
182
181
|
end
|
|
183
|
-
|
|
182
|
+
|
|
184
183
|
# CV2 check
|
|
185
184
|
post[:AVSCV2Check] = credit_card.verification_value? ? 'YES' : 'NO'
|
|
186
185
|
post[:CV2] = credit_card.verification_value if credit_card.verification_value?
|
|
187
186
|
end
|
|
188
|
-
|
|
187
|
+
|
|
189
188
|
def add_address(post, options)
|
|
190
189
|
address = options[:billing_address] || options[:address]
|
|
191
190
|
return if address.nil?
|
|
192
|
-
|
|
191
|
+
|
|
193
192
|
post[:QAAddress] = [:address1, :address2, :city, :state].collect{|a| address[a]}.reject{|a| a.blank?}.join(' ')
|
|
194
193
|
post[:QAPostcode] = address[:zip]
|
|
195
194
|
end
|
|
196
|
-
|
|
195
|
+
|
|
197
196
|
def add_invoice(post, options)
|
|
198
197
|
post[:MerchantName] = options[:merchant] || 'Merchant Name' # May use this as the order_id field
|
|
199
198
|
post[:OrderID] = options[:order_id] unless options[:order_id].blank?
|
|
200
199
|
end
|
|
201
|
-
|
|
200
|
+
|
|
202
201
|
def add_reference(post, authorization)
|
|
203
202
|
post[:CrossReference] = authorization
|
|
204
203
|
end
|
|
205
|
-
|
|
204
|
+
|
|
206
205
|
def add_amount(post, money, dispatch_type, options)
|
|
207
206
|
post[:CurrencyCode] = currency_code(options[:currency] || currency(money))
|
|
208
|
-
|
|
207
|
+
|
|
209
208
|
if dispatch_type == DISPATCH_LATER
|
|
210
209
|
post[:amount] = amount(NOMINAL_AMOUNT)
|
|
211
210
|
post[:DispatchLaterAmount] = amount(money)
|
|
212
211
|
else
|
|
213
212
|
post[:amount] = amount(money)
|
|
214
213
|
end
|
|
215
|
-
|
|
214
|
+
|
|
216
215
|
post[:Dispatch] = dispatch_type
|
|
217
216
|
end
|
|
218
|
-
|
|
217
|
+
|
|
219
218
|
def add_purchase_details(post)
|
|
220
219
|
post[:EchoAmount] = 'YES'
|
|
221
220
|
post[:SCBI] = 'YES' # Return information about the transaction
|
|
222
221
|
post[:MessageType] = MESSAGE_TYPE
|
|
223
222
|
end
|
|
224
|
-
|
|
223
|
+
|
|
225
224
|
# Get the currency code for the passed money object
|
|
226
|
-
#
|
|
225
|
+
#
|
|
227
226
|
# The money class stores the currency as an ISO 4217:2001 Alphanumeric,
|
|
228
227
|
# however PSL requires the ISO 4217:2001 Numeric code.
|
|
229
|
-
#
|
|
228
|
+
#
|
|
230
229
|
# Parameters:
|
|
231
230
|
# -money: Integer value in cents
|
|
232
|
-
#
|
|
231
|
+
#
|
|
233
232
|
# Returns:
|
|
234
233
|
# -the ISO 4217:2001 Numberic currency code
|
|
235
|
-
#
|
|
234
|
+
#
|
|
236
235
|
def currency_code(currency)
|
|
237
236
|
CURRENCY_CODES[currency]
|
|
238
237
|
end
|
|
239
|
-
|
|
238
|
+
|
|
240
239
|
# Parse the PSL response and create a Response object
|
|
241
240
|
#
|
|
242
241
|
# Parameters:
|
|
243
242
|
# -body: The response string returned from PSL, Formatted:
|
|
244
243
|
# Key=value&key=value...
|
|
245
|
-
#
|
|
244
|
+
#
|
|
246
245
|
# Returns:
|
|
247
246
|
# -a hash with all of the values returned in the PSL response
|
|
248
247
|
#
|
|
@@ -255,7 +254,7 @@ module ActiveMerchant
|
|
|
255
254
|
end
|
|
256
255
|
fields.symbolize_keys
|
|
257
256
|
end
|
|
258
|
-
|
|
257
|
+
|
|
259
258
|
# Send the passed data to PSL for processing
|
|
260
259
|
#
|
|
261
260
|
# Parameters:
|
|
@@ -266,23 +265,23 @@ module ActiveMerchant
|
|
|
266
265
|
#
|
|
267
266
|
def commit(request)
|
|
268
267
|
response = parse( ssl_post(self.live_url, post_data(request)) )
|
|
269
|
-
|
|
270
|
-
Response.new(response[:ResponseCode] == APPROVED, response[:Message], response,
|
|
271
|
-
:test => test?,
|
|
268
|
+
|
|
269
|
+
Response.new(response[:ResponseCode] == APPROVED, response[:Message], response,
|
|
270
|
+
:test => test?,
|
|
272
271
|
:authorization => response[:CrossReference],
|
|
273
272
|
:cvv_result => CVV_CODE[response[:AVSCV2Check]],
|
|
274
273
|
:avs_result => { :code => AVS_CODE[response[:AVSCV2Check]] }
|
|
275
274
|
)
|
|
276
275
|
end
|
|
277
|
-
|
|
276
|
+
|
|
278
277
|
# Put the passed data into a format that can be submitted to PSL
|
|
279
278
|
# Key=Value&Key=Value...
|
|
280
279
|
#
|
|
281
280
|
# Any ampersands and equal signs are removed from the data being posted
|
|
282
|
-
# as PSL puts them back into the response string which then cannot be parsed.
|
|
281
|
+
# as PSL puts them back into the response string which then cannot be parsed.
|
|
283
282
|
# This is after escaping before sending the request to PSL - this is a work
|
|
284
283
|
# around for the time being
|
|
285
|
-
#
|
|
284
|
+
#
|
|
286
285
|
# Parameters:
|
|
287
286
|
# -post: Hash of all the data to be sent
|
|
288
287
|
#
|
|
@@ -294,7 +293,7 @@ module ActiveMerchant
|
|
|
294
293
|
post[:MerchantID] = @options[:login]
|
|
295
294
|
post[:ValidityID] = @options[:password]
|
|
296
295
|
post[:ResponseAction] = RESPONSE_ACTION
|
|
297
|
-
|
|
296
|
+
|
|
298
297
|
post.collect { |key, value|
|
|
299
298
|
"#{key}=#{CGI.escape(value.to_s.tr('&=', ' '))}"
|
|
300
299
|
}.join("&")
|
|
@@ -38,8 +38,6 @@ module ActiveMerchant #:nodoc:
|
|
|
38
38
|
#
|
|
39
39
|
def initialize(options = {})
|
|
40
40
|
requires!(options, :login, :ticket)
|
|
41
|
-
test_mode = options[:test] || false
|
|
42
|
-
@options = options
|
|
43
41
|
super
|
|
44
42
|
end
|
|
45
43
|
|
|
@@ -115,10 +113,6 @@ module ActiveMerchant #:nodoc:
|
|
|
115
113
|
commit(:query, nil, {})
|
|
116
114
|
end
|
|
117
115
|
|
|
118
|
-
def test?
|
|
119
|
-
@options[:test] || super
|
|
120
|
-
end
|
|
121
|
-
|
|
122
116
|
private
|
|
123
117
|
|
|
124
118
|
def hosted?
|