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.
Files changed (55) hide show
  1. data/CHANGELOG +40 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +93 -0
  4. data/lib/active_merchant.rb +59 -0
  5. data/lib/active_merchant/billing/base.rb +52 -0
  6. data/lib/active_merchant/billing/credit_card.rb +217 -0
  7. data/lib/active_merchant/billing/gateway.rb +100 -0
  8. data/lib/active_merchant/billing/gateways.rb +15 -0
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +236 -0
  10. data/lib/active_merchant/billing/gateways/bogus.rb +92 -0
  11. data/lib/active_merchant/billing/gateways/eway.rb +235 -0
  12. data/lib/active_merchant/billing/gateways/linkpoint.rb +445 -0
  13. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  14. data/lib/active_merchant/billing/gateways/payflow.rb +84 -0
  15. data/lib/active_merchant/billing/gateways/payflow/f73e89fd.0 +17 -0
  16. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +190 -0
  17. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +30 -0
  18. data/lib/active_merchant/billing/gateways/payflow_express.rb +123 -0
  19. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +9 -0
  20. data/lib/active_merchant/billing/gateways/payflow_uk.rb +17 -0
  21. data/lib/active_merchant/billing/gateways/paypal.rb +90 -0
  22. data/lib/active_merchant/billing/gateways/paypal/api_cert_chain.crt +35 -0
  23. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +208 -0
  24. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +30 -0
  25. data/lib/active_merchant/billing/gateways/paypal_express.rb +115 -0
  26. data/lib/active_merchant/billing/gateways/psigate.rb +265 -0
  27. data/lib/active_merchant/billing/gateways/trust_commerce.rb +330 -0
  28. data/lib/active_merchant/billing/gateways/usa_epay.rb +189 -0
  29. data/lib/active_merchant/billing/integrations.rb +12 -0
  30. data/lib/active_merchant/billing/integrations/action_view_helper.rb +65 -0
  31. data/lib/active_merchant/billing/integrations/bogus.rb +17 -0
  32. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  33. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  34. data/lib/active_merchant/billing/integrations/chronopay.rb +17 -0
  35. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +81 -0
  36. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +156 -0
  37. data/lib/active_merchant/billing/integrations/gestpay.rb +21 -0
  38. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  39. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +72 -0
  40. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +83 -0
  41. data/lib/active_merchant/billing/integrations/helper.rb +79 -0
  42. data/lib/active_merchant/billing/integrations/nochex.rb +21 -0
  43. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  44. data/lib/active_merchant/billing/integrations/nochex/notification.rb +101 -0
  45. data/lib/active_merchant/billing/integrations/notification.rb +52 -0
  46. data/lib/active_merchant/billing/integrations/paypal.rb +35 -0
  47. data/lib/active_merchant/billing/integrations/paypal/helper.rb +103 -0
  48. data/lib/active_merchant/billing/integrations/paypal/notification.rb +187 -0
  49. data/lib/active_merchant/billing/response.rb +28 -0
  50. data/lib/active_merchant/lib/country.rb +297 -0
  51. data/lib/active_merchant/lib/posts_data.rb +21 -0
  52. data/lib/active_merchant/lib/requires_parameters.rb +17 -0
  53. data/lib/active_merchant/lib/validateable.rb +76 -0
  54. data/lib/tasks/cia.rb +90 -0
  55. metadata +129 -0
@@ -0,0 +1,17 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PayflowUkGateway < PayflowGateway
4
+ self.default_currency = 'GBP'
5
+ self.partner = 'PayPalUk'
6
+
7
+ def express
8
+ @express ||= PayflowExpressUkGateway.new(@options)
9
+ end
10
+
11
+ def self.supported_cardtypes
12
+ [:visa, :master, :american_express, :discover, :solo, :switch]
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,90 @@
1
+ require File.dirname(__FILE__) + '/paypal/paypal_common_api'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class PaypalGateway < Gateway
6
+ include PaypalCommonAPI
7
+
8
+ def self.supported_cardtypes
9
+ [:visa, :master, :american_express, :discover]
10
+ end
11
+
12
+ def authorize(money, credit_card, options = {})
13
+ requires!(options, :ip)
14
+
15
+ if result = test_result_from_cc_number(credit_card.number)
16
+ return result
17
+ end
18
+
19
+ commit 'DoDirectPayment', build_sale_or_authorization_request('Authorization', money, credit_card, options)
20
+ end
21
+
22
+ def purchase(money, credit_card, options = {})
23
+ requires!(options, :ip)
24
+
25
+ if result = test_result_from_cc_number(credit_card.number)
26
+ return result
27
+ end
28
+
29
+ commit 'DoDirectPayment', build_sale_or_authorization_request('Sale', money, credit_card, options)
30
+ end
31
+
32
+ def express
33
+ @express ||= PaypalExpressGateway.new(@options)
34
+ end
35
+
36
+ private
37
+ def build_sale_or_authorization_request(action, money, credit_card, options)
38
+ xml = Builder::XmlMarkup.new :indent => 2
39
+
40
+ xml.tag! 'DoDirectPaymentReq', 'xmlns' => 'urn:ebay:api:PayPalAPI' do
41
+ xml.tag! 'DoDirectPaymentRequest', 'xmlns:n2' => 'urn:ebay:apis:eBLBaseComponents' do
42
+ xml.tag! 'n2:Version', '2.0'
43
+ xml.tag! 'n2:DoDirectPaymentRequestDetails' do
44
+ xml.tag! 'n2:PaymentAction', action
45
+ xml.tag! 'n2:PaymentDetails' do
46
+ xml.tag! 'n2:OrderTotal', amount(money), 'currencyID' => currency(money)
47
+ xml.tag! 'n2:NotifyURL', options[:notify_url]
48
+ end
49
+ add_credit_card(xml, credit_card, options[:billing_address] || options[:address])
50
+ xml.tag! 'n2:IPAddress', options[:ip]
51
+ end
52
+ end
53
+ end
54
+
55
+ xml.target!
56
+ end
57
+
58
+ def add_credit_card(xml, credit_card, address)
59
+ xml.tag! 'n2:CreditCard' do
60
+ xml.tag! 'n2:CreditCardType', credit_card_type(credit_card.type)
61
+ xml.tag! 'n2:CreditCardNumber', credit_card.number
62
+ xml.tag! 'n2:ExpMonth', sprintf("%.2i", credit_card.month)
63
+ xml.tag! 'n2:ExpYear', sprintf("%.4i", credit_card.year)
64
+ xml.tag! 'n2:CVV2', credit_card.verification_value
65
+
66
+ xml.tag! 'n2:CardOwner' do
67
+ xml.tag! 'n2:PayerName' do
68
+ xml.tag! 'n2:FirstName', credit_card.first_name
69
+ xml.tag! 'n2:LastName', credit_card.last_name
70
+ end
71
+ add_address(xml, address)
72
+ end
73
+ end
74
+ end
75
+
76
+ def credit_card_type(type)
77
+ case type
78
+ when 'visa' then 'Visa'
79
+ when 'master' then 'MasterCard'
80
+ when 'discover' then 'Discover'
81
+ when 'american_express' then 'Amex'
82
+ end
83
+ end
84
+
85
+ def build_response(success, message, response, options = {})
86
+ Response.new(success, message, response, options)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,35 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDgzCCAuygAwIBAgIQJUuKhThCzONY+MXdriJupDANBgkqhkiG9w0BAQUFADBf
3
+ MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT
4
+ LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
5
+ HhcNOTcwNDE3MDAwMDAwWhcNMTExMDI0MjM1OTU5WjCBujEfMB0GA1UEChMWVmVy
6
+ aVNpZ24gVHJ1c3QgTmV0d29yazEXMBUGA1UECxMOVmVyaVNpZ24sIEluYy4xMzAx
7
+ BgNVBAsTKlZlcmlTaWduIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gQ2xhc3Mg
8
+ MzFJMEcGA1UECxNAd3d3LnZlcmlzaWduLmNvbS9DUFMgSW5jb3JwLmJ5IFJlZi4g
9
+ TElBQklMSVRZIExURC4oYyk5NyBWZXJpU2lnbjCBnzANBgkqhkiG9w0BAQEFAAOB
10
+ jQAwgYkCgYEA2IKA6NYZAn0fhRg5JaJlK+G/1AXTvOY2O6rwTGxbtueqPHNFVbLx
11
+ veqXQu2aNAoV1Klc9UAl3dkHwTKydWzEyruj/lYncUOqY/UwPpMo5frxCTvzt01O
12
+ OfdcSVq4wR3Tsor+cDCVQsv+K1GLWjw6+SJPkLICp1OcTzTnqwSye28CAwEAAaOB
13
+ 4zCB4DAPBgNVHRMECDAGAQH/AgEAMEQGA1UdIAQ9MDswOQYLYIZIAYb4RQEHAQEw
14
+ KjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL0NQUzA0BgNV
15
+ HSUELTArBggrBgEFBQcDAQYIKwYBBQUHAwIGCWCGSAGG+EIEAQYKYIZIAYb4RQEI
16
+ ATALBgNVHQ8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgEGMDEGA1UdHwQqMCgwJqAk
17
+ oCKGIGh0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA0GCSqGSIb3DQEB
18
+ BQUAA4GBAAgB7ORolANC8XPxI6I63unx2sZUxCM+hurPajozq+qcBBQHNgYL+Yhv
19
+ 1RPuKSvD5HKNRO3RrCAJLeH24RkFOLA9D59/+J4C3IYChmFOJl9en5IeDCSk9dBw
20
+ E88mw0M9SR2egi5SX7w+xmYpAY5Okiy8RnUDgqxz6dl+C2fvVFIa
21
+ -----END CERTIFICATE-----
22
+ -----BEGIN CERTIFICATE-----
23
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
24
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
25
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
26
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
27
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
28
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
29
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
30
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
31
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
32
+ CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
33
+ lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
34
+ AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
35
+ -----END CERTIFICATE-----
@@ -0,0 +1,208 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ # This class is an abstract base class for both PaypalGateway and
4
+ # PaypalExpressGateway
5
+ module PaypalCommonAPI
6
+ def self.included(base)
7
+ base.cattr_accessor :pem_file
8
+ end
9
+
10
+ TEST_URL = 'https://api.sandbox.paypal.com/2.0/'
11
+ LIVE_URL = 'https://api-aa.paypal.com/2.0/'
12
+
13
+ ENVELOPE_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
14
+ 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
15
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
16
+ }
17
+ CREDENTIALS_NAMESPACES = { 'xmlns' => 'urn:ebay:api:PayPalAPI',
18
+ 'xmlns:n1' => 'urn:ebay:apis:eBLBaseComponents',
19
+ 'env:mustUnderstand' => '0'
20
+ }
21
+
22
+ # <tt>:pem</tt> The text of your PayPal PEM file. Note
23
+ # this is not the path to file, but its
24
+ # contents. If you are only using one PEM
25
+ # file on your site you can declare it
26
+ # globally and then you won't need to
27
+ # include this option
28
+ def initialize(options = {})
29
+ requires!(options, :login, :password)
30
+
31
+ @options = {
32
+ :pem => self.class.pem_file
33
+ }.update(options)
34
+
35
+ super
36
+ end
37
+
38
+ def test?
39
+ @options[:test] || Base.gateway_mode == :test
40
+ end
41
+
42
+ def capture(money, authorization, options = {})
43
+ commit 'DoCapture', build_capture_request(money, authorization, options)
44
+ end
45
+
46
+ def void(authorization, options = {})
47
+ commit 'DoVoid', build_void_request(authorization, options)
48
+ end
49
+
50
+ private
51
+
52
+ def build_capture_request(money, authorization, options)
53
+ xml = Builder::XmlMarkup.new :indent => 2
54
+
55
+ xml.tag! 'DoCaptureReq', 'xmlns' => 'urn:ebay:api:PayPalAPI' do
56
+ xml.tag! 'DoCaptureRequest', 'xmlns:n2' => 'urn:ebay:apis:eBLBaseComponents' do
57
+ xml.tag! 'n2:Version', '2.0'
58
+ xml.tag! 'AuthorizationID', authorization
59
+ xml.tag! 'Amount', amount(money), 'currencyID' => currency(money)
60
+ xml.tag! 'CompleteType', 'Complete'
61
+ xml.tag! 'Note', options[:description]
62
+ end
63
+ end
64
+
65
+ xml.target!
66
+ end
67
+
68
+ def build_void_request(authorization, options)
69
+ xml = Builder::XmlMarkup.new :indent => 2
70
+
71
+ xml.tag! 'DoVoidReq', 'xmlns' => 'urn:ebay:api:PayPalAPI' do
72
+ xml.tag! 'DoVoidRequest', 'xmlns:n2' => 'urn:ebay:apis:eBLBaseComponents' do
73
+ xml.tag! 'n2:Version', '2.0'
74
+ xml.tag! 'AuthorizationID', authorization
75
+ xml.tag! 'Note', options[:description]
76
+ end
77
+ end
78
+
79
+ xml.target!
80
+ end
81
+
82
+ def ssl_post(data)
83
+ uri = URI.parse(test? ? TEST_URL : LIVE_URL)
84
+
85
+ http = Net::HTTP.new(uri.host, uri.port)
86
+
87
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
88
+ http.use_ssl = true
89
+ http.cert = OpenSSL::X509::Certificate.new(@options[:pem])
90
+ http.key = OpenSSL::PKey::RSA.new(@options[:pem])
91
+ http.ca_file = File.dirname(__FILE__) + '/api_cert_chain.crt'
92
+
93
+ http.post(uri.path, data).body
94
+ end
95
+
96
+ def parse(action, xml)
97
+ response = {}
98
+ xml = REXML::Document.new(xml)
99
+ if root = REXML::XPath.first(xml, "//#{action}Response")
100
+ root.elements.to_a.each do |node|
101
+ case node.name
102
+ when 'Errors'
103
+ response[:message] = node.elements.to_a('//LongMessage').collect{|error| error.text}.join('.')
104
+ else
105
+ parse_element(response, node)
106
+ end
107
+ end
108
+ elsif root = REXML::XPath.first(xml, "//SOAP-ENV:Fault")
109
+ parse_element(response, root)
110
+ response[:message] = "#{response[:faultcode]}: #{response[:faultstring]} - #{response[:detail]}"
111
+ end
112
+
113
+ response
114
+ end
115
+
116
+ def parse_element(response, node)
117
+ if node.has_elements?
118
+ node.elements.each{|e| parse_element(response, e) }
119
+ else
120
+ response[node.name.underscore.to_sym] = node.text
121
+ node.attributes.each do |k, v|
122
+ response["#{node.name.underscore}_#{k.underscore}".to_sym] = v if k == 'currencyID'
123
+ end
124
+ end
125
+ end
126
+
127
+ def response_type_for(action)
128
+ case action
129
+ when 'Authorization', 'Purchase'
130
+ 'DoDirectPaymentResponse'
131
+ when 'Void'
132
+ 'DoVoidResponse'
133
+ when 'Capture'
134
+ 'DoCaptureResponse'
135
+ end
136
+ end
137
+
138
+ def build_request(body)
139
+ xml = Builder::XmlMarkup.new :indent => 2
140
+
141
+ xml.instruct!
142
+ xml.tag! 'env:Envelope', ENVELOPE_NAMESPACES do
143
+ xml.tag! 'env:Header' do
144
+ add_credentials(xml)
145
+ end
146
+
147
+ xml.tag! 'env:Body' do
148
+ xml << body
149
+ end
150
+ end
151
+ xml.target!
152
+ end
153
+
154
+ def add_credentials(xml)
155
+ xml.tag! 'RequesterCredentials', CREDENTIALS_NAMESPACES do
156
+ xml.tag! 'n1:Credentials' do
157
+ xml.tag! 'Username', @options[:login]
158
+ xml.tag! 'Password', @options[:password]
159
+ xml.tag! 'Subject', @options[:subject]
160
+ end
161
+ end
162
+ end
163
+
164
+ def response_type_for(action)
165
+ case action
166
+ when 'Authorization', 'Purchase'
167
+ 'DoDirectPaymentResponse'
168
+ when 'Void'
169
+ 'DoVoidResponse'
170
+ when 'Capture'
171
+ 'DoCaptureResponse'
172
+ end
173
+ end
174
+
175
+ def add_address(xml, address)
176
+ return if address.nil?
177
+ xml.tag! 'n2:Address' do
178
+ xml.tag! 'n2:Name', address[:name]
179
+ xml.tag! 'n2:Street1', address[:address1]
180
+ xml.tag! 'n2:Street2', address[:address2]
181
+ xml.tag! 'n2:CityName', address[:city]
182
+ xml.tag! 'n2:StateOrProvince', address[:state]
183
+ xml.tag! 'n2:Country', address[:country]
184
+ xml.tag! 'n2:PostalCode', address[:zip]
185
+ xml.tag! 'n2:Phone', address[:phone]
186
+ end
187
+ end
188
+
189
+ def currency(money)
190
+ money.respond_to?(:currency) ? money.currency : 'USD'
191
+ end
192
+
193
+ def commit(action, request)
194
+ data = ssl_post build_request(request)
195
+
196
+ @response = parse(action, data)
197
+
198
+ success = @response[:ack] == "Success"
199
+ message = @response[:message] || @response[:ack]
200
+
201
+ build_response(success, message, @response,
202
+ :test => test?,
203
+ :authorization => @response[:transaction_id]
204
+ )
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,30 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PaypalExpressResponse < Response
4
+ def email
5
+ @params['payer']
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' => @params['payer_business'],
19
+ 'address1' => @params['street1'],
20
+ 'address2' => @params['street2'],
21
+ 'city' => @params['city_name'],
22
+ 'state' => @params['state_or_province'],
23
+ 'country' => @params['country'],
24
+ 'zip' => @params['postal_code'],
25
+ 'phone' => nil
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,115 @@
1
+ require File.dirname(__FILE__) + '/paypal/paypal_common_api'
2
+ require File.dirname(__FILE__) + '/paypal/paypal_express_response'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ class PaypalExpressGateway < Gateway
7
+ include PaypalCommonAPI
8
+
9
+ LIVE_REDIRECT_URL = 'https://www.paypal.com/cgibin/webscr?cmd=_express-checkout&token='
10
+ TEST_REDIRECT_URL = 'https://www.sandbox.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 setup_authorization(money, options = {})
21
+ requires!(options, :return_url, :cancel_return_url)
22
+
23
+ commit 'SetExpressCheckout', build_setup_request('Authorization', money, options)
24
+ end
25
+
26
+ def setup_purchase(money, options = {})
27
+ requires!(options, :return_url, :cancel_return_url)
28
+
29
+ commit 'SetExpressCheckout', build_setup_request('Sale', money, options)
30
+ end
31
+
32
+ def details_for(token)
33
+ commit 'GetExpressCheckoutDetails', build_get_details_request(token)
34
+ end
35
+
36
+ def authorize(money, options = {})
37
+ requires!(options, :token, :payer_id)
38
+
39
+ commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Authorization', money, options)
40
+ end
41
+
42
+ def purchase(money, token, payer_id, options = {})
43
+ requires!(options, :token, :payer_id)
44
+
45
+ commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Sale', money, options)
46
+ end
47
+
48
+ private
49
+ def build_get_details_request(token)
50
+ xml = Builder::XmlMarkup.new :indent => 2
51
+ xml.tag! 'GetExpressCheckoutDetailsReq', 'xmlns' => 'urn:ebay:api:PayPalAPI' do
52
+ xml.tag! 'GetExpressCheckoutDetailsRequest', 'xmlns:n2' => 'urn:ebay:apis:eBLBaseComponents' do
53
+ xml.tag! 'n2:Version', '2.0'
54
+ xml.tag! 'Token', token
55
+ end
56
+ end
57
+
58
+ xml.target!
59
+ end
60
+
61
+ def build_sale_or_authorization_request(action, money, options)
62
+ xml = Builder::XmlMarkup.new :indent => 2
63
+ xml.tag! 'DoExpressCheckoutPaymentReq', 'xmlns' => 'urn:ebay:api:PayPalAPI' do
64
+ xml.tag! 'DoExpressCheckoutPaymentRequest', 'xmlns:n2' => 'urn:ebay:apis:eBLBaseComponents' do
65
+ xml.tag! 'n2:Version', '2.0'
66
+ xml.tag! 'n2:DoExpressCheckoutPaymentRequestDetails' do
67
+ xml.tag! 'n2:PaymentAction', action
68
+ xml.tag! 'n2:Token', options[:token]
69
+ xml.tag! 'n2:PayerID', options[:payer_id]
70
+ xml.tag! 'n2:PaymentDetails' do
71
+ xml.tag! 'n2:OrderTotal', amount(money), 'currencyID' => currency(money)
72
+ xml.tag! 'n2:NotifyURL', options[:notify_url]
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ xml.target!
79
+ end
80
+
81
+ def build_setup_request(action, money, options)
82
+ xml = Builder::XmlMarkup.new :indent => 2
83
+ xml.tag! 'SetExpressCheckoutReq', 'xmlns' => 'urn:ebay:api:PayPalAPI' do
84
+ xml.tag! 'SetExpressCheckoutRequest', 'xmlns:n2' => 'urn:ebay:apis:eBLBaseComponents' do
85
+ xml.tag! 'n2:Version', '2.0'
86
+ xml.tag! 'n2:SetExpressCheckoutRequestDetails' do
87
+ xml.tag! 'n2:PaymentAction', action
88
+ xml.tag! 'n2:OrderTotal', amount(money), 'currencyID' => currency(money)
89
+ xml.tag! 'n2:MaxAmount', amount(options[:max_amount]), 'currencyID' => currency(options[:max_amount]) if options[:max_amount]
90
+ add_address(xml, options[:billing_address] || options[:address])
91
+ #xml.tag! 'n2:AddressOverride', 1
92
+ #xml.tag! 'n2:NoShipping', 1
93
+ xml.tag! 'n2:PageStyle', options[:page_style] unless options[:page_style].blank?
94
+ xml.tag! 'n2:ReturnURL', options[:return_url]
95
+ xml.tag! 'n2:CancelURL', options[:cancel_return_url]
96
+ xml.tag! 'n2:IPAddress', options[:ip]
97
+ xml.tag! 'n2:OrderDescription', options[:description]
98
+ xml.tag! 'n2:BuyerEmail', options[:email] unless options[:email].blank?
99
+ xml.tag! 'n2:InvoiceID', options[:order_id]
100
+
101
+ # This should be set to the same locale as the shop
102
+ # localeCode - String
103
+ end
104
+ end
105
+ end
106
+
107
+ xml.target!
108
+ end
109
+
110
+ def build_response(success, message, response, options = {})
111
+ PaypalExpressResponse.new(success, message, response, options)
112
+ end
113
+ end
114
+ end
115
+ end