activemerchant 1.42.2 → 1.42.3
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.
- checksums.yaml +8 -8
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG +32 -0
- data/CONTRIBUTORS +12 -0
- data/README.md +3 -0
- data/lib/active_merchant/billing/base.rb +9 -2
- data/lib/active_merchant/billing/credit_card_methods.rb +1 -1
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -2
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +8 -8
- data/lib/active_merchant/billing/gateways/balanced.rb +7 -2
- data/lib/active_merchant/billing/gateways/beanstream.rb +1 -1
- data/lib/active_merchant/billing/gateways/bogus.rb +32 -22
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +124 -39
- data/lib/active_merchant/billing/gateways/cyber_source.rb +2 -2
- data/lib/active_merchant/billing/gateways/litle.rb +1 -1
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -2
- data/lib/active_merchant/billing/gateways/moneris.rb +1 -1
- data/lib/active_merchant/billing/gateways/moneris_us.rb +1 -1
- data/lib/active_merchant/billing/gateways/nab_transact.rb +3 -1
- data/lib/active_merchant/billing/gateways/netpay.rb +1 -1
- data/lib/active_merchant/billing/gateways/pay_junction.rb +7 -7
- data/lib/active_merchant/billing/gateways/payex.rb +402 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +41 -11
- data/lib/active_merchant/billing/gateways/payment_express.rb +1 -1
- data/lib/active_merchant/billing/gateways/paymill.rb +55 -3
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/payscout.rb +171 -0
- data/lib/active_merchant/billing/gateways/pin.rb +1 -1
- data/lib/active_merchant/billing/gateways/realex.rb +1 -1
- data/lib/active_merchant/billing/gateways/redsys.rb +1 -1
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +23 -25
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +26 -15
- data/lib/active_merchant/billing/gateways/webpay.rb +27 -11
- data/lib/active_merchant/billing/gateways/wirecard.rb +1 -1
- data/lib/active_merchant/billing/integrations/bit_pay/helper.rb +1 -1
- data/lib/active_merchant/billing/integrations/ipay88.rb +4 -0
- data/lib/active_merchant/billing/integrations/ipay88/helper.rb +1 -1
- data/lib/active_merchant/billing/integrations/ipay88/notification.rb +103 -0
- data/lib/active_merchant/billing/integrations/ipay88/return.rb +8 -74
- data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +1 -1
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +1 -1
- data/lib/active_merchant/billing/integrations/payu_in.rb +2 -9
- data/lib/active_merchant/billing/integrations/payu_in/helper.rb +15 -13
- data/lib/active_merchant/billing/integrations/payu_in/notification.rb +9 -20
- data/lib/active_merchant/billing/integrations/payu_in_paisa/helper.rb +1 -1
- data/lib/active_merchant/billing/integrations/payu_in_paisa/notification.rb +0 -10
- data/lib/active_merchant/billing/integrations/payu_in_paisa/return.rb +1 -1
- data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +1 -1
- data/lib/active_merchant/billing/integrations/valitor/helper.rb +3 -3
- data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +2 -2
- data/lib/active_merchant/billing/integrations/verkkomaksut/notification.rb +1 -1
- data/lib/active_merchant/billing/integrations/wirecard_checkout_page.rb +1 -1
- data/lib/active_merchant/billing/integrations/world_pay/helper.rb +2 -2
- data/lib/active_merchant/version.rb +1 -1
- metadata +7 -3
- metadata.gz.sig +0 -0
@@ -24,7 +24,7 @@ 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
|
27
|
+
# * To process pinless debit cards through the pinless debit card
|
28
28
|
# network, your Cybersource merchant account must accept pinless
|
29
29
|
# debit card payments.
|
30
30
|
class CyberSourceGateway < Gateway
|
@@ -102,7 +102,7 @@ module ActiveMerchant #:nodoc:
|
|
102
102
|
# :vat_reg_number => your VAT registration number
|
103
103
|
#
|
104
104
|
# :nexus => "WI CA QC" sets the states/provinces where you have a physical
|
105
|
-
#
|
105
|
+
# presence for tax purposes
|
106
106
|
#
|
107
107
|
# :ignore_avs => true don't want to use AVS so continue processing even
|
108
108
|
# if AVS would have failed
|
@@ -75,7 +75,7 @@ module ActiveMerchant #:nodoc:
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def add_address(post, options)
|
78
|
-
return unless(address = options[:address])
|
78
|
+
return unless(address = (options[:billing_address] || options[:address]))
|
79
79
|
|
80
80
|
post['customerName'] = address[:name]
|
81
81
|
post['customerCountry'] = address[:country]
|
@@ -86,7 +86,7 @@ module ActiveMerchant #:nodoc:
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def add_product(post, options)
|
89
|
-
post['transactionProduct'] = options[:
|
89
|
+
post['transactionProduct'] = options[:description]
|
90
90
|
end
|
91
91
|
|
92
92
|
def add_payment_method(post, payment_method)
|
@@ -167,7 +167,7 @@ module ActiveMerchant #:nodoc:
|
|
167
167
|
}.merge(options)
|
168
168
|
end
|
169
169
|
|
170
|
-
# Splits an +authorization+ param and
|
170
|
+
# Splits an +authorization+ param and retrieves the order id and
|
171
171
|
# transaction number in that order.
|
172
172
|
def split_authorization(authorization)
|
173
173
|
if authorization.nil? || authorization.empty? || authorization !~ /;/
|
@@ -111,7 +111,7 @@ module ActiveMerchant #:nodoc:
|
|
111
111
|
}.merge(options)
|
112
112
|
end
|
113
113
|
|
114
|
-
# Splits an +authorization+ param and
|
114
|
+
# Splits an +authorization+ param and retrieves the order id and
|
115
115
|
# transaction number in that order.
|
116
116
|
def split_authorization(authorization)
|
117
117
|
if authorization.nil? || authorization.empty? || authorization !~ /;/
|
@@ -127,11 +127,13 @@ module ActiveMerchant #:nodoc:
|
|
127
127
|
xml.tag! 'purchaseOrderNo', order_id
|
128
128
|
xml.tag! 'preauthID', preauth_id
|
129
129
|
|
130
|
+
add_metadata(xml, options)
|
131
|
+
|
130
132
|
xml.target!
|
131
133
|
end
|
132
134
|
|
133
135
|
#Generate payment request XML
|
134
|
-
# - API is set to allow multiple Txn's but
|
136
|
+
# - API is set to allow multiple Txn's but currently only allows one
|
135
137
|
# - txnSource = 23 - (XML)
|
136
138
|
def build_request(action, body)
|
137
139
|
xml = Builder::XmlMarkup.new
|
@@ -18,7 +18,7 @@ module ActiveMerchant #:nodoc:
|
|
18
18
|
# transaction. After this, a refund should be performed instead.
|
19
19
|
#
|
20
20
|
# In addition to the regular ActiveMerchant transaction options, NETPAY
|
21
|
-
# also supports a `:mode` parameter. This allows testing to be
|
21
|
+
# also supports a `:mode` parameter. This allows testing to be performed
|
22
22
|
# in production and force specific results.
|
23
23
|
#
|
24
24
|
# * 'P' - Production
|
@@ -73,16 +73,16 @@ module ActiveMerchant #:nodoc:
|
|
73
73
|
#
|
74
74
|
# PayJunction Field ActiveMerchant Use
|
75
75
|
#
|
76
|
-
# dc_logon provide as :login value to gateway
|
76
|
+
# dc_logon provide as :login value to gateway instantiation
|
77
77
|
# dc_password provide as :password value to gateway instantiation
|
78
78
|
#
|
79
79
|
# dc_name will be retrieved from credit_card.name
|
80
|
-
# dc_first_name :first_name on CreditCard object
|
81
|
-
# dc_last_name :last_name on CreditCard object
|
82
|
-
# dc_number :number on CreditCard object
|
83
|
-
# dc_expiration_month :month on CreditCard object
|
84
|
-
# dc_expiration_year :year on CreditCard object
|
85
|
-
# dc_verification_number :verification_value on CC object
|
80
|
+
# dc_first_name :first_name on CreditCard object instantiation
|
81
|
+
# dc_last_name :last_name on CreditCard object instantiation
|
82
|
+
# dc_number :number on CreditCard object instantiation
|
83
|
+
# dc_expiration_month :month on CreditCard object instantiation
|
84
|
+
# dc_expiration_year :year on CreditCard object instantiation
|
85
|
+
# dc_verification_number :verification_value on CC object instantiation
|
86
86
|
#
|
87
87
|
# dc_transaction_amount include as argument to method for your transaction type
|
88
88
|
# dc_transaction_type do nothing, set by your transaction type
|
@@ -0,0 +1,402 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
module ActiveMerchant #:nodoc:
|
3
|
+
module Billing #:nodoc:
|
4
|
+
class PayexGateway < Gateway
|
5
|
+
self.live_url = 'https://external.payex.com/'
|
6
|
+
self.test_url = 'https://test-external.payex.com/'
|
7
|
+
|
8
|
+
self.money_format = :cents
|
9
|
+
self.supported_countries = ['SE', 'NO', 'DK']
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
11
|
+
self.homepage_url = 'http://payex.com/'
|
12
|
+
self.display_name = 'Payex'
|
13
|
+
self.default_currency = "EUR"
|
14
|
+
|
15
|
+
# NOTE: the PurchaseCC uses a different url for test transactions
|
16
|
+
TEST_CONFINED_URL = 'https://test-confined.payex.com/'
|
17
|
+
|
18
|
+
TRANSACTION_STATUS = {
|
19
|
+
sale: '0',
|
20
|
+
initialize: '1',
|
21
|
+
credit: '2',
|
22
|
+
authorize: '3',
|
23
|
+
cancel: '4',
|
24
|
+
failure: '5',
|
25
|
+
capture: '6',
|
26
|
+
}
|
27
|
+
|
28
|
+
SOAP_ACTIONS = {
|
29
|
+
initialize: { name: 'Initialize8', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
30
|
+
purchasecc: { name: 'PurchaseCC', url: 'pxconfined/pxorder.asmx', xmlns: 'http://confined.payex.com/PxOrder/', confined: true},
|
31
|
+
cancel: { name: 'Cancel2', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
32
|
+
capture: { name: 'Capture5', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
33
|
+
credit: { name: 'Credit5', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
34
|
+
create_agreement: { name: 'CreateAgreement3', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' },
|
35
|
+
delete_agreement: { name: 'DeleteAgreement', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' },
|
36
|
+
autopay: { name: 'AutoPay3', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' },
|
37
|
+
}
|
38
|
+
|
39
|
+
def initialize(options = {})
|
40
|
+
requires!(options, :account, :encryption_key)
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
# Public: Send an authorize Payex request
|
45
|
+
#
|
46
|
+
# amount - The monetary amount of the transaction in cents.
|
47
|
+
# payment_method - The Active Merchant payment method or the +store+ authorization for stored transactions.
|
48
|
+
# options - A standard ActiveMerchant options hash:
|
49
|
+
# :currency - Three letter currency code for the transaction (default: "EUR")
|
50
|
+
# :order_id - The unique order ID for this transaction (required).
|
51
|
+
# :product_number - The merchant product number (default: '1').
|
52
|
+
# :description - The merchant description for this product (default: The :order_id).
|
53
|
+
# :ip - The client IP address (default: '127.0.0.1').
|
54
|
+
# :vat - The vat amount (optional).
|
55
|
+
#
|
56
|
+
# Returns an ActiveMerchant::Billing::Response object
|
57
|
+
def authorize(amount, payment_method, options = {})
|
58
|
+
requires!(options, :order_id)
|
59
|
+
amount = amount(amount)
|
60
|
+
if payment_method.respond_to?(:number)
|
61
|
+
# credit card authorization
|
62
|
+
MultiResponse.new.tap do |r|
|
63
|
+
r.process {send_initialize(amount, true, options)}
|
64
|
+
r.process {send_purchasecc(payment_method, r.params['orderref'])}
|
65
|
+
end
|
66
|
+
else
|
67
|
+
# stored authorization
|
68
|
+
send_autopay(amount, payment_method, true, options)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# Public: Send a purchase Payex request
|
74
|
+
#
|
75
|
+
# amount - The monetary amount of the transaction in cents.
|
76
|
+
# payment_method - The Active Merchant payment method or the +store+ authorization for stored transactions.
|
77
|
+
# options - A standard ActiveMerchant options hash:
|
78
|
+
# :currency - Three letter currency code for the transaction (default: "EUR")
|
79
|
+
# :order_id - The unique order ID for this transaction (required).
|
80
|
+
# :product_number - The merchant product number (default: '1').
|
81
|
+
# :description - The merchant description for this product (default: The :order_id).
|
82
|
+
# :ip - The client IP address (default: '127.0.0.1').
|
83
|
+
# :vat - The vat amount (optional).
|
84
|
+
#
|
85
|
+
# Returns an ActiveMerchant::Billing::Response object
|
86
|
+
def purchase(amount, payment_method, options = {})
|
87
|
+
requires!(options, :order_id)
|
88
|
+
amount = amount(amount)
|
89
|
+
if payment_method.respond_to?(:number)
|
90
|
+
# credit card purchase
|
91
|
+
MultiResponse.new.tap do |r|
|
92
|
+
r.process {send_initialize(amount, false, options)}
|
93
|
+
r.process {send_purchasecc(payment_method, r.params['orderref'])}
|
94
|
+
end
|
95
|
+
else
|
96
|
+
# stored purchase
|
97
|
+
send_autopay(amount, payment_method, false, options)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Public: Capture money from a previously authorized transaction
|
102
|
+
#
|
103
|
+
# money - The amount to capture
|
104
|
+
# authorization - The authorization token from the authorization request
|
105
|
+
#
|
106
|
+
# Returns an ActiveMerchant::Billing::Response object
|
107
|
+
def capture(money, authorization, options = {})
|
108
|
+
amount = amount(money)
|
109
|
+
send_capture(amount, authorization)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Public: Voids an authorize transaction
|
113
|
+
#
|
114
|
+
# authorization - The authorization returned from the successful authorize transaction.
|
115
|
+
# options - A standard ActiveMerchant options hash
|
116
|
+
#
|
117
|
+
# Returns an ActiveMerchant::Billing::Response object
|
118
|
+
def void(authorization, options={})
|
119
|
+
send_cancel(authorization)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Public: Refunds a purchase transaction
|
123
|
+
#
|
124
|
+
# money - The amount to refund
|
125
|
+
# authorization - The authorization token from the purchase request.
|
126
|
+
# options - A standard ActiveMerchant options hash:
|
127
|
+
# :order_id - The unique order ID for this transaction (required).
|
128
|
+
# :vat_amount - The vat amount (optional).
|
129
|
+
#
|
130
|
+
# Returns an ActiveMerchant::Billing::Response object
|
131
|
+
def refund(money, authorization, options = {})
|
132
|
+
requires!(options, :order_id)
|
133
|
+
amount = amount(money)
|
134
|
+
send_credit(authorization, amount, options)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Public: Stores a credit card and creates a Payex agreement with a customer
|
138
|
+
#
|
139
|
+
# creditcard - The credit card to store.
|
140
|
+
# options - A standard ActiveMerchant options hash:
|
141
|
+
# :order_id - The unique order ID for this transaction (required).
|
142
|
+
# :merchant_ref - A reference that links this agreement to something the merchant takes money for (default: '1')
|
143
|
+
# :currency - Three letter currency code for the transaction (default: "EUR")
|
144
|
+
# :product_number - The merchant product number (default: '1').
|
145
|
+
# :description - The merchant description for this product (default: The :order_id).
|
146
|
+
# :ip - The client IP address (default: '127.0.0.1').
|
147
|
+
# :max_amount - The maximum amount to allow to be charged (default: 100000).
|
148
|
+
# :vat - The vat amount (optional).
|
149
|
+
#
|
150
|
+
# Returns an ActiveMerchant::Billing::Response object where the authorization is set to the agreement_ref which is used for stored payments.
|
151
|
+
def store(creditcard, options = {})
|
152
|
+
requires!(options, :order_id)
|
153
|
+
amount = amount(1) # 1 cent for authorization
|
154
|
+
MultiResponse.run(:first) do |r|
|
155
|
+
r.process {send_create_agreement(options)}
|
156
|
+
r.process {send_initialize(amount, true, options.merge({agreement_ref: r.authorization}))}
|
157
|
+
order_ref = r.params['orderref']
|
158
|
+
r.process {send_purchasecc(creditcard, order_ref)}
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Public: Unstores a customer's credit card and deletes their Payex agreement.
|
163
|
+
#
|
164
|
+
# authorization - The authorization token from the store request.
|
165
|
+
#
|
166
|
+
# Returns an ActiveMerchant::Billing::Response object
|
167
|
+
def unstore(authorization, options = {})
|
168
|
+
send_delete_agreement(authorization)
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def send_initialize(amount, is_auth, options = {})
|
174
|
+
properties = {
|
175
|
+
accountNumber: @options[:account],
|
176
|
+
purchaseOperation: is_auth ? 'AUTHORIZATION' : 'SALE',
|
177
|
+
price: amount,
|
178
|
+
priceArgList: nil,
|
179
|
+
currency: (options[:currency] || default_currency),
|
180
|
+
vat: options[:vat] || 0,
|
181
|
+
orderID: options[:order_id],
|
182
|
+
productNumber: options[:product_number] || '1',
|
183
|
+
description: options[:description] || options[:order_id],
|
184
|
+
clientIPAddress: options[:client_ip_address] || '127.0.0.1',
|
185
|
+
clientIdentifier: nil,
|
186
|
+
additionalValues: nil,
|
187
|
+
externalID: nil,
|
188
|
+
returnUrl: 'http://example.net', # set to dummy value since this is not used but is required
|
189
|
+
view: 'CREDITCARD',
|
190
|
+
agreementRef: options[:agreement_ref], # this is used to attach a stored agreement to a transaction as part of the store card
|
191
|
+
cancelUrl: nil,
|
192
|
+
clientLanguage: nil
|
193
|
+
}
|
194
|
+
hash_fields = [:accountNumber, :purchaseOperation, :price, :priceArgList, :currency, :vat, :orderID,
|
195
|
+
:productNumber, :description, :clientIPAddress, :clientIdentifier, :additionalValues,
|
196
|
+
:externalID, :returnUrl, :view, :agreementRef, :cancelUrl, :clientLanguage]
|
197
|
+
add_request_hash(properties, hash_fields)
|
198
|
+
soap_action = SOAP_ACTIONS[:initialize]
|
199
|
+
request = build_xml_request(soap_action, properties)
|
200
|
+
commit(soap_action, request)
|
201
|
+
end
|
202
|
+
|
203
|
+
def send_purchasecc(payment_method, order_ref)
|
204
|
+
properties = {
|
205
|
+
accountNumber: @options[:account],
|
206
|
+
orderRef: order_ref,
|
207
|
+
transactionType: 1, # online payment
|
208
|
+
cardNumber: payment_method.number,
|
209
|
+
cardNumberExpireMonth: "%02d" % payment_method.month,
|
210
|
+
cardNumberExpireYear: "%02d" % payment_method.year,
|
211
|
+
cardHolderName: payment_method.name,
|
212
|
+
cardNumberCVC: payment_method.verification_value
|
213
|
+
}
|
214
|
+
hash_fields = [:accountNumber, :orderRef, :transactionType, :cardNumber, :cardNumberExpireMonth,
|
215
|
+
:cardNumberExpireYear, :cardNumberCVC, :cardHolderName]
|
216
|
+
add_request_hash(properties, hash_fields)
|
217
|
+
|
218
|
+
soap_action = SOAP_ACTIONS[:purchasecc]
|
219
|
+
request = build_xml_request(soap_action, properties)
|
220
|
+
commit(soap_action, request)
|
221
|
+
end
|
222
|
+
|
223
|
+
def send_autopay(amount, authorization, is_auth, options = {})
|
224
|
+
properties = {
|
225
|
+
accountNumber: @options[:account],
|
226
|
+
agreementRef: authorization,
|
227
|
+
price: amount,
|
228
|
+
productNumber: options[:product_number] || '1',
|
229
|
+
description: options[:description] || options[:order_id],
|
230
|
+
orderId: options[:order_id],
|
231
|
+
purchaseOperation: is_auth ? 'AUTHORIZATION' : 'SALE',
|
232
|
+
currency: (options[:currency] || default_currency),
|
233
|
+
}
|
234
|
+
hash_fields = [:accountNumber, :agreementRef, :price, :productNumber, :description, :orderId, :purchaseOperation, :currency]
|
235
|
+
add_request_hash(properties, hash_fields)
|
236
|
+
|
237
|
+
soap_action = SOAP_ACTIONS[:autopay]
|
238
|
+
request = build_xml_request(soap_action, properties)
|
239
|
+
commit(soap_action, request)
|
240
|
+
end
|
241
|
+
|
242
|
+
def send_capture(amount, transaction_number, options = {})
|
243
|
+
properties = {
|
244
|
+
accountNumber: @options[:account],
|
245
|
+
transactionNumber: transaction_number,
|
246
|
+
amount: amount,
|
247
|
+
orderId: options[:order_id] || '',
|
248
|
+
vatAmount: options[:vat_amount] || 0,
|
249
|
+
additionalValues: ''
|
250
|
+
}
|
251
|
+
hash_fields = [:accountNumber, :transactionNumber, :amount, :orderId, :vatAmount, :additionalValues]
|
252
|
+
add_request_hash(properties, hash_fields)
|
253
|
+
|
254
|
+
soap_action = SOAP_ACTIONS[:capture]
|
255
|
+
request = build_xml_request(soap_action, properties)
|
256
|
+
commit(soap_action, request)
|
257
|
+
end
|
258
|
+
|
259
|
+
def send_credit(transaction_number, amount, options = {})
|
260
|
+
properties = {
|
261
|
+
accountNumber: @options[:account],
|
262
|
+
transactionNumber: transaction_number,
|
263
|
+
amount: amount,
|
264
|
+
orderId: options[:order_id],
|
265
|
+
vatAmount: options[:vat_amount] || 0,
|
266
|
+
additionalValues: ''
|
267
|
+
}
|
268
|
+
hash_fields = [:accountNumber, :transactionNumber, :amount, :orderId, :vatAmount, :additionalValues]
|
269
|
+
add_request_hash(properties, hash_fields)
|
270
|
+
|
271
|
+
soap_action = SOAP_ACTIONS[:credit]
|
272
|
+
request = build_xml_request(soap_action, properties)
|
273
|
+
commit(soap_action, request)
|
274
|
+
end
|
275
|
+
|
276
|
+
def send_cancel(transaction_number)
|
277
|
+
properties = {
|
278
|
+
accountNumber: @options[:account],
|
279
|
+
transactionNumber: transaction_number,
|
280
|
+
}
|
281
|
+
hash_fields = [:accountNumber, :transactionNumber]
|
282
|
+
add_request_hash(properties, hash_fields)
|
283
|
+
|
284
|
+
soap_action = SOAP_ACTIONS[:cancel]
|
285
|
+
request = build_xml_request(soap_action, properties)
|
286
|
+
commit(soap_action, request)
|
287
|
+
end
|
288
|
+
|
289
|
+
def send_create_agreement(options)
|
290
|
+
properties = {
|
291
|
+
accountNumber: @options[:account],
|
292
|
+
merchantRef: options[:merchant_ref] || '1',
|
293
|
+
description: options[:description] || options[:order_id],
|
294
|
+
purchaseOperation: 'SALE',
|
295
|
+
maxAmount: options[:max_amount] || 100000, # default to 1,000
|
296
|
+
notifyUrl: '',
|
297
|
+
startDate: options[:startDate] || '',
|
298
|
+
stopDate: options[:stopDate] || ''
|
299
|
+
}
|
300
|
+
hash_fields = [:accountNumber, :merchantRef, :description, :purchaseOperation, :maxAmount, :notifyUrl, :startDate, :stopDate]
|
301
|
+
add_request_hash(properties, hash_fields)
|
302
|
+
|
303
|
+
soap_action = SOAP_ACTIONS[:create_agreement]
|
304
|
+
request = build_xml_request(soap_action, properties)
|
305
|
+
commit(soap_action, request)
|
306
|
+
end
|
307
|
+
|
308
|
+
def send_delete_agreement(authorization)
|
309
|
+
properties = {
|
310
|
+
accountNumber: @options[:account],
|
311
|
+
agreementRef: authorization,
|
312
|
+
}
|
313
|
+
hash_fields = [:accountNumber, :agreementRef]
|
314
|
+
add_request_hash(properties, hash_fields)
|
315
|
+
|
316
|
+
soap_action = SOAP_ACTIONS[:delete_agreement]
|
317
|
+
request = build_xml_request(soap_action, properties)
|
318
|
+
commit(soap_action, request)
|
319
|
+
end
|
320
|
+
|
321
|
+
def url_for(soap_action)
|
322
|
+
base_url = test? ? (soap_action[:confined] ? TEST_CONFINED_URL : test_url) : live_url
|
323
|
+
File.join(base_url, soap_action[:url])
|
324
|
+
end
|
325
|
+
|
326
|
+
# this will add a hash to the passed in properties as required by Payex requests
|
327
|
+
def add_request_hash(properties, fields)
|
328
|
+
data = fields.map { |e| properties[e] }
|
329
|
+
data << @options[:encryption_key]
|
330
|
+
properties['hash_'] = Digest::MD5.hexdigest(data.join(''))
|
331
|
+
end
|
332
|
+
|
333
|
+
def build_xml_request(soap_action, properties)
|
334
|
+
builder = Nokogiri::XML::Builder.new
|
335
|
+
builder.__send__('soap12:Envelope', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
336
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
337
|
+
'xmlns:soap12' => 'http://www.w3.org/2003/05/soap-envelope'}) do |root|
|
338
|
+
root.__send__('soap12:Body') do |body|
|
339
|
+
body.__send__(soap_action[:name], xmlns: soap_action[:xmlns]) do |doc|
|
340
|
+
properties.each do |key, val|
|
341
|
+
doc.send(key, val)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
builder.to_xml
|
347
|
+
end
|
348
|
+
|
349
|
+
def parse(xml)
|
350
|
+
response = {}
|
351
|
+
|
352
|
+
xmldoc = Nokogiri::XML(xml)
|
353
|
+
body = xmldoc.xpath("//soap:Body/*[1]")[0].inner_text
|
354
|
+
|
355
|
+
doc = Nokogiri::XML(body)
|
356
|
+
|
357
|
+
doc.root.xpath("*").each do |node|
|
358
|
+
if (node.elements.size == 0)
|
359
|
+
response[node.name.downcase.to_sym] = node.text
|
360
|
+
else
|
361
|
+
node.elements.each do |childnode|
|
362
|
+
name = "#{node.name.downcase}_#{childnode.name.downcase}"
|
363
|
+
response[name.to_sym] = childnode.text
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end unless doc.root.nil?
|
367
|
+
|
368
|
+
response
|
369
|
+
end
|
370
|
+
|
371
|
+
# Commits all requests to the Payex soap endpoint
|
372
|
+
def commit(soap_action, request)
|
373
|
+
url = url_for(soap_action)
|
374
|
+
headers = {
|
375
|
+
'Content-Type' => 'application/soap+xml; charset=utf-8',
|
376
|
+
'Content-Length' => request.size.to_s
|
377
|
+
}
|
378
|
+
response = parse(ssl_post(url, request, headers))
|
379
|
+
Response.new(success?(response),
|
380
|
+
message_from(response),
|
381
|
+
response,
|
382
|
+
test: test?,
|
383
|
+
authorization: build_authorization(response)
|
384
|
+
)
|
385
|
+
end
|
386
|
+
|
387
|
+
def build_authorization(response)
|
388
|
+
# agreementref is for the store transaction, everything else gets transactionnumber
|
389
|
+
response[:transactionnumber] || response[:agreementref]
|
390
|
+
end
|
391
|
+
|
392
|
+
def success?(response)
|
393
|
+
response[:status_errorcode] == 'OK' && response[:transactionstatus] != TRANSACTION_STATUS[:failure]
|
394
|
+
end
|
395
|
+
|
396
|
+
def message_from(response)
|
397
|
+
response[:status_description]
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|