activemerchant 1.0.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/CHANGELOG +40 -0
- data/MIT-LICENSE +20 -0
- data/README +93 -0
- data/lib/active_merchant.rb +59 -0
- data/lib/active_merchant/billing/base.rb +52 -0
- data/lib/active_merchant/billing/credit_card.rb +217 -0
- data/lib/active_merchant/billing/gateway.rb +100 -0
- data/lib/active_merchant/billing/gateways.rb +15 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +236 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +92 -0
- data/lib/active_merchant/billing/gateways/eway.rb +235 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +445 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +84 -0
- data/lib/active_merchant/billing/gateways/payflow/f73e89fd.0 +17 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +190 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +30 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +123 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +9 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +17 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +90 -0
- data/lib/active_merchant/billing/gateways/paypal/api_cert_chain.crt +35 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +208 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +30 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +115 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +265 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +330 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +189 -0
- data/lib/active_merchant/billing/integrations.rb +12 -0
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +65 -0
- data/lib/active_merchant/billing/integrations/bogus.rb +17 -0
- data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
- data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
- data/lib/active_merchant/billing/integrations/chronopay.rb +17 -0
- data/lib/active_merchant/billing/integrations/chronopay/helper.rb +81 -0
- data/lib/active_merchant/billing/integrations/chronopay/notification.rb +156 -0
- data/lib/active_merchant/billing/integrations/gestpay.rb +21 -0
- data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +72 -0
- data/lib/active_merchant/billing/integrations/gestpay/notification.rb +83 -0
- data/lib/active_merchant/billing/integrations/helper.rb +79 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +21 -0
- data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +101 -0
- data/lib/active_merchant/billing/integrations/notification.rb +52 -0
- data/lib/active_merchant/billing/integrations/paypal.rb +35 -0
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +103 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +187 -0
- data/lib/active_merchant/billing/response.rb +28 -0
- data/lib/active_merchant/lib/country.rb +297 -0
- data/lib/active_merchant/lib/posts_data.rb +21 -0
- data/lib/active_merchant/lib/requires_parameters.rb +17 -0
- data/lib/active_merchant/lib/validateable.rb +76 -0
- data/lib/tasks/cia.rb +90 -0
- metadata +129 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/payflow/payflow_common_api'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class PayflowGateway < Gateway
|
6
|
+
include PayflowCommonAPI
|
7
|
+
|
8
|
+
def authorize(money, credit_card, options = {})
|
9
|
+
if result = test_result_from_cc_number(credit_card.number)
|
10
|
+
return result
|
11
|
+
end
|
12
|
+
|
13
|
+
request = build_sale_or_authorization_request('Authorization', money, credit_card, options)
|
14
|
+
commit(request)
|
15
|
+
end
|
16
|
+
|
17
|
+
def purchase(money, credit_card, options = {})
|
18
|
+
if result = test_result_from_cc_number(credit_card.number)
|
19
|
+
return result
|
20
|
+
end
|
21
|
+
|
22
|
+
request = build_sale_or_authorization_request('Sale', money, credit_card, options)
|
23
|
+
commit(request)
|
24
|
+
end
|
25
|
+
|
26
|
+
def express
|
27
|
+
@express ||= PayflowExpressGateway.new(@options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.supported_cardtypes
|
31
|
+
[:visa, :master, :american_express, :jcb, :discover, :diners_club]
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def build_sale_or_authorization_request(action, money, credit_card, options)
|
36
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
37
|
+
xml.tag! action do
|
38
|
+
xml.tag! 'PayData' do
|
39
|
+
xml.tag! 'Invoice' do
|
40
|
+
xml.tag! 'CustIP', options[:ip] unless options[:ip].blank?
|
41
|
+
xml.tag! 'InvNum', options[:order_id] unless options[:order_id].blank?
|
42
|
+
xml.tag! 'Description', options[:description] unless options[:description].blank?
|
43
|
+
|
44
|
+
billing_address = options[:billing_address] || options[:address]
|
45
|
+
shipping_address = options[:shipping_address] || billing_address
|
46
|
+
|
47
|
+
add_address(xml, 'BillTo', billing_address, options)
|
48
|
+
add_address(xml, 'ShipTo', shipping_address, options)
|
49
|
+
|
50
|
+
xml.tag! 'TotalAmt', amount(money), 'Currency' => currency(money)
|
51
|
+
end
|
52
|
+
|
53
|
+
xml.tag! 'Tender' do
|
54
|
+
add_credit_card(xml, credit_card)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
xml.target!
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_credit_card(xml, credit_card)
|
62
|
+
xml.tag! 'Card' do
|
63
|
+
xml.tag! 'CardType', CARD_MAPPING[credit_card.type.to_sym]
|
64
|
+
xml.tag! 'CardNum', credit_card.number
|
65
|
+
xml.tag! 'ExpDate', expdate(credit_card)
|
66
|
+
xml.tag! 'NameOnCard', credit_card.name
|
67
|
+
xml.tag! 'CVNum', credit_card.verification_value if credit_card.verification_value?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def expdate(creditcard)
|
72
|
+
year = sprintf("%.4i", creditcard.year)
|
73
|
+
month = sprintf("%.2i", creditcard.month)
|
74
|
+
|
75
|
+
"#{year}#{month}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_response(success, message, response, options = {})
|
79
|
+
Response.new(success, message, response, options)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
subject=/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
|
2
|
+
notBefore=Nov 9 00:00:00 1994 GMT
|
3
|
+
notAfter=Jan 7 23:59:59 2010 GMT
|
4
|
+
-----BEGIN CERTIFICATE-----
|
5
|
+
MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG
|
6
|
+
A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
|
7
|
+
VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0
|
8
|
+
MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV
|
9
|
+
BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy
|
10
|
+
dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ
|
11
|
+
ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII
|
12
|
+
0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI
|
13
|
+
uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI
|
14
|
+
hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3
|
15
|
+
YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc
|
16
|
+
1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
|
17
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
module PayflowCommonAPI
|
6
|
+
def self.included(base)
|
7
|
+
base.class_inheritable_accessor :default_currency
|
8
|
+
base.default_currency = 'USD'
|
9
|
+
|
10
|
+
# The certification_id is required by PayPal to make direct HTTPS posts to their servers.
|
11
|
+
# You can obtain a certification id by emailing: payflowintegrator@paypal.com
|
12
|
+
base.class_inheritable_accessor :certification_id
|
13
|
+
base.class_inheritable_accessor :partner
|
14
|
+
|
15
|
+
# Set the default partner to PayPal
|
16
|
+
base.partner = 'PayPal'
|
17
|
+
end
|
18
|
+
|
19
|
+
XMLNS = 'http://www.paypal.com/XMLPay'
|
20
|
+
TEST_URL = 'https://pilot-payflowpro.verisign.com/transaction'
|
21
|
+
LIVE_URL = 'https://payflowpro.verisign.com/transaction'
|
22
|
+
|
23
|
+
CARD_MAPPING = {
|
24
|
+
:visa => 'Visa',
|
25
|
+
:master => 'MasterCard',
|
26
|
+
:discover => 'Discover',
|
27
|
+
:american_express => 'Amex',
|
28
|
+
:jcb => 'JCB',
|
29
|
+
:diners_club => 'DinersClub',
|
30
|
+
:switch => 'Switch',
|
31
|
+
:solo => 'Solo'
|
32
|
+
}
|
33
|
+
|
34
|
+
def initialize(options = {})
|
35
|
+
requires!(options, :login, :password)
|
36
|
+
@options = {
|
37
|
+
:certification_id => self.class.certification_id,
|
38
|
+
:partner => self.class.partner
|
39
|
+
}.update(options)
|
40
|
+
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
def test?
|
45
|
+
@options[:test] || Base.gateway_mode == :test
|
46
|
+
end
|
47
|
+
|
48
|
+
def capture(money, authorization, options = {})
|
49
|
+
request = build_void_or_capture_request('Capture', authorization)
|
50
|
+
commit(request)
|
51
|
+
end
|
52
|
+
|
53
|
+
def void(authorization, options = {})
|
54
|
+
request = build_void_or_capture_request('Void', authorization)
|
55
|
+
commit(request)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def build_request(body)
|
60
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
61
|
+
xml.instruct!
|
62
|
+
xml.tag! 'XMLPayRequest', 'Timeout' => 30, 'version' => "2.1", "xmlns" => XMLNS do
|
63
|
+
xml.tag! 'RequestData' do
|
64
|
+
xml.tag! 'Vendor', @options[:login]
|
65
|
+
xml.tag! 'Partner', @options[:partner]
|
66
|
+
xml.tag! 'Transactions' do
|
67
|
+
xml.tag! 'Transaction' do
|
68
|
+
xml.tag! 'Verbosity', 'MEDIUM'
|
69
|
+
xml << body
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
xml.tag! 'RequestAuth' do
|
74
|
+
xml.tag! 'UserPass' do
|
75
|
+
xml.tag! 'User', @options[:login]
|
76
|
+
xml.tag! 'Password', @options[:password]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
xml.target!
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_void_or_capture_request(action, authorization)
|
84
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
85
|
+
xml.tag! action do
|
86
|
+
xml.tag! 'PNRef', authorization
|
87
|
+
end
|
88
|
+
xml.target!
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_paypal_details(xml, options)
|
92
|
+
xml.tag! 'PayPal' do
|
93
|
+
xml.tag! 'EMail', options[:email]
|
94
|
+
xml.tag! 'ReturnURL', options[:return_url]
|
95
|
+
xml.tag! 'CancelURL', options[:cancel_return_url]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def add_address(xml, tag, address, options)
|
100
|
+
return if address.nil?
|
101
|
+
xml.tag! tag do
|
102
|
+
xml.tag! 'Name', address[:name] unless options[:name].blank?
|
103
|
+
xml.tag! 'Email', options[:email] unless options[:email].blank?
|
104
|
+
xml.tag! 'Phone', address[:phone] unless address[:phone].blank?
|
105
|
+
xml.tag! 'Address' do
|
106
|
+
xml.tag! 'Street', address[:address1] unless address[:address1].blank?
|
107
|
+
xml.tag! 'City', address[:city] unless address[:city].blank?
|
108
|
+
xml.tag! 'State', address[:state] unless address[:state].blank?
|
109
|
+
xml.tag! 'Country', address[:country] unless address[:country].blank?
|
110
|
+
xml.tag! 'Zip', address[:zip] unless address[:zip].blank?
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def ssl_post(url, data, headers)
|
116
|
+
uri = URI.parse(url)
|
117
|
+
|
118
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
119
|
+
|
120
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
121
|
+
http.verify_depth = 5
|
122
|
+
http.use_ssl = true
|
123
|
+
http.ca_file = File.dirname(__FILE__) + '/f73e89fd.0'
|
124
|
+
|
125
|
+
http.post(uri.path, data, headers).body
|
126
|
+
end
|
127
|
+
|
128
|
+
def parse(data)
|
129
|
+
response = {}
|
130
|
+
xml = REXML::Document.new(data)
|
131
|
+
root = REXML::XPath.first(xml, "//ResponseData")
|
132
|
+
|
133
|
+
if REXML::XPath.first(root, "//TransactionResult/attribute::Duplicate")
|
134
|
+
response[:duplicate] = true
|
135
|
+
end
|
136
|
+
|
137
|
+
root.elements.to_a.each do |node|
|
138
|
+
parse_element(response, node)
|
139
|
+
end
|
140
|
+
|
141
|
+
response
|
142
|
+
end
|
143
|
+
|
144
|
+
def parse_element(response, node)
|
145
|
+
if node.has_elements?
|
146
|
+
node.elements.each{|e| parse_element(response, e) }
|
147
|
+
else
|
148
|
+
response[node.name.underscore.to_sym] = node.text
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def generate_request_token
|
153
|
+
Digest::SHA1.hexdigest(rand.to_s).slice(0,32)
|
154
|
+
end
|
155
|
+
|
156
|
+
def currency(money)
|
157
|
+
money.respond_to?(:currency) ? money.currency : self.default_currency
|
158
|
+
end
|
159
|
+
|
160
|
+
def build_headers(content_length)
|
161
|
+
{
|
162
|
+
"Content-Type" => "text/xml",
|
163
|
+
"Content-Length" => content_length.to_s,
|
164
|
+
"X-VPS-Timeout" => "30",
|
165
|
+
"X-VPS-VIT-Client-Certification-Id" => @options[:certification_id].to_s,
|
166
|
+
"X-VPS-VIT-Integration-Product" => "ActiveMerchant",
|
167
|
+
"X-VPS-VIT-Runtime-Version" => RUBY_VERSION,
|
168
|
+
"X-VPS-Request-ID" => generate_request_token
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
def commit(request_body)
|
173
|
+
request = build_request(request_body)
|
174
|
+
headers = build_headers(request_body.size)
|
175
|
+
|
176
|
+
url = test? ? TEST_URL : LIVE_URL
|
177
|
+
data = ssl_post(url, request, headers)
|
178
|
+
@response = parse(data)
|
179
|
+
|
180
|
+
success = @response[:result] == "0"
|
181
|
+
message = @response[:message]
|
182
|
+
|
183
|
+
build_response(success, message, @response,
|
184
|
+
:test => test?,
|
185
|
+
:authorization => @response[:pn_ref]
|
186
|
+
)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PayflowExpressResponse < Response
|
4
|
+
def email
|
5
|
+
@params['e_mail']
|
6
|
+
end
|
7
|
+
|
8
|
+
def token
|
9
|
+
@params['token']
|
10
|
+
end
|
11
|
+
|
12
|
+
def payer_id
|
13
|
+
@params['payer_id']
|
14
|
+
end
|
15
|
+
|
16
|
+
def address
|
17
|
+
{ 'name' => @params['name'],
|
18
|
+
'company' => nil,
|
19
|
+
'address1' => @params['street'],
|
20
|
+
'address2' => nil,
|
21
|
+
'city' => @params['city'],
|
22
|
+
'state' => @params['state'],
|
23
|
+
'country' => @params['country'],
|
24
|
+
'zip' => @params['zip'],
|
25
|
+
'phone' => nil
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/payflow/payflow_common_api'
|
2
|
+
require File.dirname(__FILE__) + '/payflow/payflow_express_response'
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
class PayflowExpressGateway < Gateway
|
7
|
+
include PayflowCommonAPI
|
8
|
+
|
9
|
+
LIVE_REDIRECT_URL = 'https://www.paypal.com/cgibin/webscr?cmd=_express-checkout&token='
|
10
|
+
TEST_REDIRECT_URL = 'https://test-expresscheckout.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='
|
11
|
+
|
12
|
+
def redirect_url
|
13
|
+
test? ? TEST_REDIRECT_URL : LIVE_REDIRECT_URL
|
14
|
+
end
|
15
|
+
|
16
|
+
def redirect_url_for(token)
|
17
|
+
"#{redirect_url}#{token}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def authorize(money, options = {})
|
21
|
+
requires!(options, :token, :payer_id)
|
22
|
+
request = build_sale_or_authorization_request('Authorization', money, options)
|
23
|
+
commit(request)
|
24
|
+
end
|
25
|
+
|
26
|
+
def purchase(money, options = {})
|
27
|
+
requires!(options, :token, :payer_id)
|
28
|
+
request = build_sale_or_authorization_request('Sale', money, options)
|
29
|
+
commit(request)
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_authorization(money, options = {})
|
33
|
+
requires!(options, :return_url, :cancel_return_url)
|
34
|
+
|
35
|
+
request = build_setup_express_sale_or_authorization_request('Authorization', money, options)
|
36
|
+
commit(request)
|
37
|
+
end
|
38
|
+
|
39
|
+
def setup_purchase(money, options = {})
|
40
|
+
requires!(options, :return_url, :cancel_return_url)
|
41
|
+
|
42
|
+
request = build_setup_express_sale_or_authorization_request('Sale', money, options)
|
43
|
+
commit(request)
|
44
|
+
end
|
45
|
+
|
46
|
+
def details_for(token)
|
47
|
+
request = build_get_express_details_request(token)
|
48
|
+
commit(request)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def build_get_express_details_request(token)
|
53
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
54
|
+
xml.tag! 'GetExpressCheckout' do
|
55
|
+
xml.tag! 'Authorization' do
|
56
|
+
xml.tag! 'PayData' do
|
57
|
+
xml.tag! 'Tender' do
|
58
|
+
xml.tag! 'PayPal' do
|
59
|
+
xml.tag! 'Token', token
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
xml.target!
|
66
|
+
end
|
67
|
+
|
68
|
+
def build_setup_express_sale_or_authorization_request(action, money, options = {})
|
69
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
70
|
+
xml.tag! 'SetExpressCheckout' do
|
71
|
+
xml.tag! action do
|
72
|
+
xml.tag! 'PayData' do
|
73
|
+
xml.tag! 'Invoice' do
|
74
|
+
xml.tag! 'CustIP', options[:ip] unless options[:ip].blank?
|
75
|
+
xml.tag! 'InvNum', options[:order_id] unless options[:order_id].blank?
|
76
|
+
xml.tag! 'Description', options[:description] unless options[:description].blank?
|
77
|
+
|
78
|
+
billing_address = options[:billing_address] || options[:address]
|
79
|
+
shipping_address = options[:shipping_address] || billing_address
|
80
|
+
|
81
|
+
add_address(xml, 'BillTo', billing_address, options)
|
82
|
+
add_address(xml, 'ShipTo', shipping_address, options)
|
83
|
+
|
84
|
+
xml.tag! 'TotalAmt', amount(money), 'Currency' => currency(money)
|
85
|
+
end
|
86
|
+
|
87
|
+
xml.tag! 'Tender' do
|
88
|
+
add_paypal_details(xml, options)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
xml.target!
|
94
|
+
end
|
95
|
+
|
96
|
+
def build_sale_or_authorization_request(action, money, options)
|
97
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
98
|
+
xml.tag! 'DoExpressCheckout' do
|
99
|
+
xml.tag! action do
|
100
|
+
xml.tag! 'PayData' do
|
101
|
+
xml.tag! 'Invoice' do
|
102
|
+
xml.tag! 'TotalAmt', amount(money), 'Currency' => currency(money)
|
103
|
+
end
|
104
|
+
xml.tag! 'Tender' do
|
105
|
+
xml.tag! 'PayPal' do
|
106
|
+
xml.tag! 'Token', options[:token]
|
107
|
+
xml.tag! 'PayerID', options[:payer_id]
|
108
|
+
xml.tag! 'NotifyURL', options[:notify_url]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
xml.target!
|
115
|
+
end
|
116
|
+
|
117
|
+
def build_response(success, message, response, options = {})
|
118
|
+
PayflowExpressResponse.new(success, message, response, options)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|