activemerchant 1.29.3 → 1.30.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 +0 -0
- data/CHANGELOG +39 -0
- data/CONTRIBUTORS +19 -0
- data/README.md +43 -41
- data/lib/active_merchant/billing/check.rb +15 -11
- data/lib/active_merchant/billing/credit_card.rb +5 -1
- data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +15 -4
- data/lib/active_merchant/billing/gateways/balanced.rb +9 -3
- data/lib/active_merchant/billing/gateways/banwire.rb +15 -1
- data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +6 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +5 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
- data/lib/active_merchant/billing/gateways/eway.rb +114 -171
- data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +222 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
- data/lib/active_merchant/billing/gateways/litle.rb +50 -19
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +2 -4
- data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
- data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +18 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +9 -5
- data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/paypal_express.rb +2 -0
- data/lib/active_merchant/billing/gateways/pin.rb +157 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +3 -2
- data/lib/active_merchant/billing/gateways/quickpay.rb +66 -28
- data/lib/active_merchant/billing/gateways/sage_pay.rb +6 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +235 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +1 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +4 -1
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +14 -14
- data/lib/active_merchant/version.rb +1 -1
- metadata +109 -49
- metadata.gz.sig +0 -0
@@ -65,6 +65,7 @@ module ActiveMerchant #:nodoc:
|
|
65
65
|
add_credit_card(post, credit_card)
|
66
66
|
add_address(post, options)
|
67
67
|
add_customer_data(post, options)
|
68
|
+
add_optional_data(post, options)
|
68
69
|
|
69
70
|
commit(:purchase, post)
|
70
71
|
end
|
@@ -79,6 +80,7 @@ module ActiveMerchant #:nodoc:
|
|
79
80
|
add_credit_card(post, credit_card)
|
80
81
|
add_address(post, options)
|
81
82
|
add_customer_data(post, options)
|
83
|
+
add_optional_data(post, options)
|
82
84
|
|
83
85
|
commit(:authorization, post)
|
84
86
|
end
|
@@ -156,6 +158,10 @@ module ActiveMerchant #:nodoc:
|
|
156
158
|
add_pair(post, :ClientIPAddress, options[:ip])
|
157
159
|
end
|
158
160
|
|
161
|
+
def add_optional_data(post, options)
|
162
|
+
add_pair(post, :GiftAidPayment, options[:gift_aid_payment]) unless options[:gift_aid_payment].blank?
|
163
|
+
end
|
164
|
+
|
159
165
|
def add_address(post, options)
|
160
166
|
if billing_address = options[:billing_address] || options[:address]
|
161
167
|
first_name, last_name = parse_first_and_last_name(billing_address[:name])
|
@@ -221,7 +221,7 @@ module ActiveMerchant #:nodoc:
|
|
221
221
|
parameters[:amount] = amount(money) if money
|
222
222
|
response = parse( ssl_post(self.live_url, post_data(action,parameters)) )
|
223
223
|
Response.new(response["response"] == "1", message_from(response), response,
|
224
|
-
:authorization => response["transactionid"],
|
224
|
+
:authorization => (response["transactionid"] || response["customer_vault_id"]),
|
225
225
|
:test => test?,
|
226
226
|
:cvv_result => response["cvvresponse"],
|
227
227
|
:avs_result => { :code => response["avsresponse"] }
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# Public: This gateway allows you to interact with any gateway you've
|
6
|
+
# created in Spreedly Core (https://spreedlycore.com). It's an adapter
|
7
|
+
# which can be particularly useful if you already have code interacting with
|
8
|
+
# ActiveMerchant and want to easily take advantage of Core's vault.
|
9
|
+
class SpreedlyCoreGateway < Gateway
|
10
|
+
self.live_url = 'https://spreedlycore.com/v1'
|
11
|
+
|
12
|
+
self.supported_countries = %w(AD AE AT AU BD BE BG BN CA CH CY CZ DE DK EE EG ES FI FR GB
|
13
|
+
GI GR HK HU ID IE IL IM IN IS IT JO KW LB LI LK LT LU LV MC
|
14
|
+
MT MU MV MX MY NL NO NZ OM PH PL PT QA RO SA SE SG SI SK SM
|
15
|
+
TR TT UM US VA VN ZA)
|
16
|
+
|
17
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
18
|
+
self.homepage_url = 'https://spreedlycore.com'
|
19
|
+
self.display_name = 'Spreedly Core'
|
20
|
+
self.money_format = :cents
|
21
|
+
self.default_currency = 'USD'
|
22
|
+
|
23
|
+
# Public: Create a new Spreedly Core Gateway.
|
24
|
+
#
|
25
|
+
# options - A hash of options:
|
26
|
+
# :login - Your Spreedly Core API login.
|
27
|
+
# :password - Your Spreedly Core API secret.
|
28
|
+
# :gateway_token - The token of the gateway you've created in
|
29
|
+
# Spreedly Core.
|
30
|
+
def initialize(options = {})
|
31
|
+
requires!(options, :login, :password, :gateway_token)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
# Public: Run a purchase transaction.
|
36
|
+
#
|
37
|
+
# money - The monetary amount of the transaction in cents.
|
38
|
+
# payment_method - The CreditCard or the Spreedly Core payment method
|
39
|
+
# token.
|
40
|
+
# options - A standard ActiveMerchant options hash
|
41
|
+
def purchase(money, payment_method, options = {})
|
42
|
+
if payment_method.is_a?(String)
|
43
|
+
purchase_with_token(money, payment_method, options)
|
44
|
+
else
|
45
|
+
MultiResponse.run do |r|
|
46
|
+
r.process { save_card(false, payment_method, options) }
|
47
|
+
r.process { purchase_with_token(money, r.authorization, options) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Public: Run an authorize transaction.
|
53
|
+
#
|
54
|
+
# money - The monetary amount of the transaction in cents.
|
55
|
+
# payment_method - The CreditCard or the Spreedly Core payment method
|
56
|
+
# token.
|
57
|
+
# options - A standard ActiveMerchant options hash
|
58
|
+
def authorize(money, payment_method, options = {})
|
59
|
+
if payment_method.is_a?(String)
|
60
|
+
authorize_with_token(money, payment_method, options)
|
61
|
+
else
|
62
|
+
MultiResponse.run do |r|
|
63
|
+
r.process { save_card(false, payment_method, options) }
|
64
|
+
r.process { authorize_with_token(money, r.authorization, options) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def capture(money, authorization, options={})
|
70
|
+
request = build_xml_request('transaction') do |doc|
|
71
|
+
add_invoice(doc, money, options)
|
72
|
+
end
|
73
|
+
|
74
|
+
commit("transactions/#{authorization}/capture.xml", request)
|
75
|
+
end
|
76
|
+
|
77
|
+
def refund(money, authorization, options={})
|
78
|
+
request = build_xml_request('transaction') do |doc|
|
79
|
+
add_invoice(doc, money, options)
|
80
|
+
end
|
81
|
+
|
82
|
+
commit("transactions/#{authorization}/credit.xml", request)
|
83
|
+
end
|
84
|
+
|
85
|
+
def void(authorization, options={})
|
86
|
+
commit("transactions/#{authorization}/void.xml", '')
|
87
|
+
end
|
88
|
+
|
89
|
+
# Public: Store a credit card in the Spreedly Core vault and retain it.
|
90
|
+
#
|
91
|
+
# credit_card - The CreditCard to store
|
92
|
+
# options - A standard ActiveMerchant options hash
|
93
|
+
def store(credit_card, options={})
|
94
|
+
save_card(true, credit_card, options)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Public: Redact the CreditCard in Spreedly Core. This wipes the
|
98
|
+
# sensitive payment information from the card.
|
99
|
+
#
|
100
|
+
# credit_card - The CreditCard to store
|
101
|
+
# options - A standard ActiveMerchant options hash
|
102
|
+
def unstore(authorization, options={})
|
103
|
+
commit("payment_methods/#{authorization}/redact.xml", '', :put)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
def save_card(retain, credit_card, options)
|
108
|
+
request = build_xml_request('payment_method') do |doc|
|
109
|
+
add_credit_card(doc, credit_card, options)
|
110
|
+
add_data(doc, options)
|
111
|
+
doc.retained(true) if retain
|
112
|
+
end
|
113
|
+
|
114
|
+
commit("payment_methods.xml", request, :post, :payment_method_token)
|
115
|
+
end
|
116
|
+
|
117
|
+
def purchase_with_token(money, payment_method_token, options)
|
118
|
+
request = auth_purchase_request(money, payment_method_token, options)
|
119
|
+
commit("gateways/#{@options[:gateway_token]}/purchase.xml", request)
|
120
|
+
end
|
121
|
+
|
122
|
+
def authorize_with_token(money, payment_method_token, options)
|
123
|
+
request = auth_purchase_request(money, payment_method_token, options)
|
124
|
+
commit("gateways/#{@options[:gateway_token]}/authorize.xml", request)
|
125
|
+
end
|
126
|
+
|
127
|
+
def auth_purchase_request(money, payment_method_token, options)
|
128
|
+
build_xml_request('transaction') do |doc|
|
129
|
+
add_invoice(doc, money, options)
|
130
|
+
doc.payment_method_token(payment_method_token)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_invoice(doc, money, options)
|
135
|
+
doc.amount amount(money)
|
136
|
+
doc.currency_code(options[:currency] || currency(money) || default_currency)
|
137
|
+
end
|
138
|
+
|
139
|
+
def add_credit_card(doc, credit_card, options)
|
140
|
+
doc.credit_card do
|
141
|
+
doc.number(credit_card.number)
|
142
|
+
doc.first_name(credit_card.first_name)
|
143
|
+
doc.last_name(credit_card.last_name)
|
144
|
+
doc.month(credit_card.month)
|
145
|
+
doc.year(credit_card.year)
|
146
|
+
doc.email(options[:email])
|
147
|
+
doc.address1(options[:billing_address].try(:[], :address1))
|
148
|
+
doc.address2(options[:billing_address].try(:[], :address2))
|
149
|
+
doc.city(options[:billing_address].try(:[], :city))
|
150
|
+
doc.state(options[:billing_address].try(:[], :state))
|
151
|
+
doc.zip(options[:billing_address].try(:[], :zip))
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def add_data(doc, options)
|
156
|
+
doc.data do
|
157
|
+
data_to_doc(doc, options[:data])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def data_to_doc(doc, value)
|
162
|
+
return doc.text value unless value.kind_of? Hash
|
163
|
+
value.each do |k, v|
|
164
|
+
doc.send(k) do
|
165
|
+
data_to_doc(doc, v)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def parse(xml)
|
171
|
+
response = {}
|
172
|
+
|
173
|
+
doc = Nokogiri::XML(xml)
|
174
|
+
doc.root.xpath('*').each do |node|
|
175
|
+
if (node.elements.empty?)
|
176
|
+
response[node.name.downcase.to_sym] = node.text
|
177
|
+
else
|
178
|
+
node.elements.each do |childnode|
|
179
|
+
childnode_to_response(response, node, childnode)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
response
|
185
|
+
end
|
186
|
+
|
187
|
+
def childnode_to_response(response, node, childnode)
|
188
|
+
name = "#{node.name.downcase}_#{childnode.name.downcase}"
|
189
|
+
if name == 'payment_method_data' && !childnode.elements.empty?
|
190
|
+
response[name.to_sym] = Hash.from_xml(childnode.to_s).values.first
|
191
|
+
else
|
192
|
+
response[name.to_sym] = childnode.text
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def build_xml_request(root)
|
197
|
+
builder = Nokogiri::XML::Builder.new
|
198
|
+
builder.__send__(root) do |doc|
|
199
|
+
yield(doc)
|
200
|
+
end
|
201
|
+
builder.to_xml
|
202
|
+
end
|
203
|
+
|
204
|
+
def commit(relative_url, request, method = :post, authorization_field = :token)
|
205
|
+
begin
|
206
|
+
raw_response = ssl_request(method, "#{live_url}/#{relative_url}", request, headers)
|
207
|
+
rescue ResponseError => e
|
208
|
+
raw_response = e.response.body
|
209
|
+
end
|
210
|
+
|
211
|
+
response_from(raw_response, authorization_field)
|
212
|
+
end
|
213
|
+
|
214
|
+
def response_from(raw_response, authorization_field)
|
215
|
+
parsed = parse(raw_response)
|
216
|
+
options = {
|
217
|
+
:authorization => parsed[authorization_field],
|
218
|
+
:test => (parsed[:on_test_gateway] == 'true'),
|
219
|
+
:avs_result => { :code => parsed[:response_avs_code] },
|
220
|
+
:cvv_result => parsed[:response_cvv_code]
|
221
|
+
}
|
222
|
+
|
223
|
+
Response.new(parsed[:succeeded] == 'true', parsed[:message] || parsed[:error], parsed, options)
|
224
|
+
end
|
225
|
+
|
226
|
+
def headers
|
227
|
+
{
|
228
|
+
'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:login]}:#{@options[:password]}").chomp),
|
229
|
+
'Content-Type' => 'text/xml'
|
230
|
+
}
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
@@ -50,6 +50,7 @@ module ActiveMerchant #:nodoc:
|
|
50
50
|
add_customer(post, options)
|
51
51
|
add_customer_data(post,options)
|
52
52
|
post[:description] = options[:description] || options[:email]
|
53
|
+
post[:application_fee] = options[:application_fee] if options[:application_fee]
|
53
54
|
add_flags(post, options)
|
54
55
|
|
55
56
|
meta = generate_meta(options)
|
@@ -16,7 +16,7 @@ module ActiveMerchant #:nodoc:
|
|
16
16
|
'xsi:noNamespaceSchemaLocation' => 'wirecard.xsd'
|
17
17
|
}
|
18
18
|
|
19
|
-
PERMITTED_TRANSACTIONS = %w[
|
19
|
+
PERMITTED_TRANSACTIONS = %w[ PREAUTHORIZATION CAPTURE PURCHASE ]
|
20
20
|
|
21
21
|
RETURN_CODES = %w[ ACK NOK ]
|
22
22
|
|
@@ -63,13 +63,13 @@ module ActiveMerchant #:nodoc:
|
|
63
63
|
# Authorization
|
64
64
|
def authorize(money, creditcard, options = {})
|
65
65
|
options[:credit_card] = creditcard
|
66
|
-
commit(:
|
66
|
+
commit(:preauthorization, money, options)
|
67
67
|
end
|
68
68
|
|
69
69
|
# Capture Authorization
|
70
70
|
def capture(money, authorization, options = {})
|
71
|
-
options[:
|
72
|
-
commit(:
|
71
|
+
options[:preauthorization] = authorization
|
72
|
+
commit(:capture, money, options)
|
73
73
|
end
|
74
74
|
|
75
75
|
# Purchase
|
@@ -148,16 +148,17 @@ module ActiveMerchant #:nodoc:
|
|
148
148
|
options[:order_id] ||= generate_unique_id
|
149
149
|
|
150
150
|
xml.tag! "FNC_CC_#{options[:action].to_s.upcase}" do
|
151
|
-
xml.tag! 'FunctionID', options[:description]
|
151
|
+
xml.tag! 'FunctionID', options[:description].to_s.slice(0,32)
|
152
152
|
xml.tag! 'CC_TRANSACTION' do
|
153
153
|
xml.tag! 'TransactionID', options[:order_id]
|
154
154
|
case options[:action]
|
155
|
-
when :
|
155
|
+
when :preauthorization, :purchase
|
156
156
|
add_invoice(xml, money, options)
|
157
157
|
add_creditcard(xml, options[:credit_card])
|
158
158
|
add_address(xml, options[:billing_address])
|
159
|
-
when :
|
160
|
-
xml.tag! 'GuWID', options[:
|
159
|
+
when :capture
|
160
|
+
xml.tag! 'GuWID', options[:preauthorization]
|
161
|
+
add_amount(xml, money)
|
161
162
|
end
|
162
163
|
end
|
163
164
|
end
|
@@ -165,7 +166,7 @@ module ActiveMerchant #:nodoc:
|
|
165
166
|
|
166
167
|
# Includes the payment (amount, currency, country) to the transaction-xml
|
167
168
|
def add_invoice(xml, money, options)
|
168
|
-
xml
|
169
|
+
add_amount(xml, money)
|
169
170
|
xml.tag! 'Currency', options[:currency] || currency(money)
|
170
171
|
xml.tag! 'CountryCode', options[:billing_address][:country]
|
171
172
|
xml.tag! 'RECURRING_TRANSACTION' do
|
@@ -173,6 +174,11 @@ module ActiveMerchant #:nodoc:
|
|
173
174
|
end
|
174
175
|
end
|
175
176
|
|
177
|
+
# Include the amount in the transaction-xml
|
178
|
+
def add_amount(xml, money)
|
179
|
+
xml.tag! 'Amount', amount(money)
|
180
|
+
end
|
181
|
+
|
176
182
|
# Includes the credit-card data to the transaction-xml
|
177
183
|
def add_creditcard(xml, creditcard)
|
178
184
|
raise "Creditcard must be supplied!" if creditcard.nil?
|
@@ -20,7 +20,6 @@ module ActiveMerchant #:nodoc:
|
|
20
20
|
mapping :credential2, 'pwd'
|
21
21
|
mapping :credential3, 'partner'
|
22
22
|
mapping :order, 'user1'
|
23
|
-
mapping :description, 'description'
|
24
23
|
|
25
24
|
mapping :amount, 'amt'
|
26
25
|
|
@@ -35,6 +34,10 @@ module ActiveMerchant #:nodoc:
|
|
35
34
|
|
36
35
|
mapping :customer, :name => 'name'
|
37
36
|
|
37
|
+
def description(value)
|
38
|
+
add_field('description', "#{value}".delete("#"))
|
39
|
+
end
|
40
|
+
|
38
41
|
def customer(params = {})
|
39
42
|
add_field(mappings[:customer][:name], [params.delete(:first_name), params.delete(:last_name)].compact.join(' '))
|
40
43
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
require 'net/http'
|
2
|
+
require 'time'
|
2
3
|
|
3
4
|
module ActiveMerchant #:nodoc:
|
4
5
|
module Billing #:nodoc:
|
5
6
|
module Integrations #:nodoc:
|
6
7
|
module Paypal
|
7
|
-
# Parser and handler for incoming Instant payment notifications from paypal.
|
8
|
+
# Parser and handler for incoming Instant payment notifications from paypal.
|
8
9
|
# The Example shows a typical handler in a rails application. Note that this
|
9
10
|
# is an example, please read the Paypal API documentation for all the details
|
10
11
|
# on creating a safe payment controller.
|
11
12
|
#
|
12
13
|
# Example
|
13
|
-
#
|
14
|
+
#
|
14
15
|
# class BackendController < ApplicationController
|
15
16
|
# include ActiveMerchant::Billing::Integrations
|
16
17
|
#
|
@@ -20,28 +21,28 @@ module ActiveMerchant #:nodoc:
|
|
20
21
|
# if notify.masspay?
|
21
22
|
# masspay_items = notify.items
|
22
23
|
# end
|
23
|
-
#
|
24
|
+
#
|
24
25
|
# order = Order.find(notify.item_id)
|
25
|
-
#
|
26
|
-
# if notify.acknowledge
|
26
|
+
#
|
27
|
+
# if notify.acknowledge
|
27
28
|
# begin
|
28
|
-
#
|
29
|
+
#
|
29
30
|
# if notify.complete? and order.total == notify.amount
|
30
|
-
# order.status = 'success'
|
31
|
-
#
|
31
|
+
# order.status = 'success'
|
32
|
+
#
|
32
33
|
# shop.ship(order)
|
33
34
|
# else
|
34
35
|
# logger.error("Failed to verify Paypal's notification, please investigate")
|
35
36
|
# end
|
36
|
-
#
|
37
|
+
#
|
37
38
|
# rescue => e
|
38
|
-
# order.status = 'failed'
|
39
|
+
# order.status = 'failed'
|
39
40
|
# raise
|
40
41
|
# ensure
|
41
42
|
# order.save
|
42
43
|
# end
|
43
44
|
# end
|
44
|
-
#
|
45
|
+
#
|
45
46
|
# render :nothing
|
46
47
|
# end
|
47
48
|
# end
|
@@ -52,7 +53,7 @@ module ActiveMerchant #:nodoc:
|
|
52
53
|
super
|
53
54
|
extend MassPayNotification if masspay?
|
54
55
|
end
|
55
|
-
|
56
|
+
|
56
57
|
# Was the transaction complete?
|
57
58
|
def complete?
|
58
59
|
status == "Completed"
|
@@ -63,13 +64,20 @@ module ActiveMerchant #:nodoc:
|
|
63
64
|
type == "masspay"
|
64
65
|
end
|
65
66
|
|
66
|
-
# When was this payment received by the client.
|
67
|
-
# sometimes it can happen that we get the notification much later.
|
68
|
-
# One possible scenario is that our web application was down. In this case paypal tries several
|
67
|
+
# When was this payment received by the client.
|
68
|
+
# sometimes it can happen that we get the notification much later.
|
69
|
+
# One possible scenario is that our web application was down. In this case paypal tries several
|
69
70
|
# times an hour to inform us about the notification
|
70
71
|
def received_at
|
71
|
-
parsed_time_fields = DateTime._strptime(params['payment_date'], "%H:%M:%S %b %d, %Y %
|
72
|
-
Time.
|
72
|
+
parsed_time_fields = DateTime._strptime(params['payment_date'], "%H:%M:%S %b %d, %Y %Z")
|
73
|
+
Time.gm(
|
74
|
+
parsed_time_fields[:year],
|
75
|
+
parsed_time_fields[:mon],
|
76
|
+
parsed_time_fields[:mday],
|
77
|
+
parsed_time_fields[:hour],
|
78
|
+
parsed_time_fields[:min],
|
79
|
+
parsed_time_fields[:sec]
|
80
|
+
) + Time.zone_offset(parsed_time_fields[:zone])
|
73
81
|
end
|
74
82
|
|
75
83
|
# Status of transaction. List of possible values:
|
@@ -94,8 +102,8 @@ module ActiveMerchant #:nodoc:
|
|
94
102
|
params['txn_id']
|
95
103
|
end
|
96
104
|
|
97
|
-
# What type of transaction are we dealing with?
|
98
|
-
# "cart" "send_money" "web_accept" are possible here.
|
105
|
+
# What type of transaction are we dealing with?
|
106
|
+
# "cart" "send_money" "web_accept" are possible here.
|
99
107
|
def type
|
100
108
|
params['txn_type']
|
101
109
|
end
|
@@ -115,37 +123,37 @@ module ActiveMerchant #:nodoc:
|
|
115
123
|
params['mc_currency']
|
116
124
|
end
|
117
125
|
|
118
|
-
# This is the item number which we submitted to paypal
|
126
|
+
# This is the item number which we submitted to paypal
|
119
127
|
# The custom field is also mapped to item_id because PayPal
|
120
128
|
# doesn't return item_number in dispute notifications
|
121
129
|
def item_id
|
122
130
|
params['item_number'] || params['custom']
|
123
131
|
end
|
124
132
|
|
125
|
-
# This is the invoice which you passed to paypal
|
133
|
+
# This is the invoice which you passed to paypal
|
126
134
|
def invoice
|
127
135
|
params['invoice']
|
128
|
-
end
|
136
|
+
end
|
129
137
|
|
130
138
|
# Was this a test transaction?
|
131
139
|
def test?
|
132
140
|
params['test_ipn'] == '1'
|
133
141
|
end
|
134
|
-
|
142
|
+
|
135
143
|
def account
|
136
144
|
params['business'] || params['receiver_email']
|
137
145
|
end
|
138
146
|
|
139
|
-
# Acknowledge the transaction to paypal. This method has to be called after a new
|
140
|
-
# ipn arrives. Paypal will verify that all the information we received are correct and will return a
|
141
|
-
# ok or a fail.
|
142
|
-
#
|
147
|
+
# Acknowledge the transaction to paypal. This method has to be called after a new
|
148
|
+
# ipn arrives. Paypal will verify that all the information we received are correct and will return a
|
149
|
+
# ok or a fail.
|
150
|
+
#
|
143
151
|
# Example:
|
144
|
-
#
|
152
|
+
#
|
145
153
|
# def paypal_ipn
|
146
154
|
# notify = PaypalNotification.new(request.raw_post)
|
147
155
|
#
|
148
|
-
# if notify.acknowledge
|
156
|
+
# if notify.acknowledge
|
149
157
|
# ... process order ... if notify.complete?
|
150
158
|
# else
|
151
159
|
# ... log possible hacking attempt ...
|
@@ -153,11 +161,11 @@ module ActiveMerchant #:nodoc:
|
|
153
161
|
def acknowledge
|
154
162
|
payload = raw
|
155
163
|
|
156
|
-
response = ssl_post(Paypal.service_url + '?cmd=_notify-validate', payload,
|
164
|
+
response = ssl_post(Paypal.service_url + '?cmd=_notify-validate', payload,
|
157
165
|
'Content-Length' => "#{payload.size}",
|
158
166
|
'User-Agent' => "Active Merchant -- http://activemerchant.org"
|
159
167
|
)
|
160
|
-
|
168
|
+
|
161
169
|
raise StandardError.new("Faulty paypal result: #{response}") unless ["VERIFIED", "INVALID"].include?(response)
|
162
170
|
|
163
171
|
response == "VERIFIED"
|