paypal-sdk-core 0.1.5 → 0.2.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.
@@ -26,7 +26,7 @@ module PayPal::SDK::Core
26
26
 
27
27
  # Get or Create configured logger based on the default environment configuration
28
28
  def logger
29
- @logger ||= Logger.new(Config.config.logfile || STDERR)
29
+ @logger ||= Logger.new(STDERR)
30
30
  end
31
31
 
32
32
  # Set logger directly and clear the loggers cache.
@@ -35,7 +35,7 @@ module PayPal::SDK::Core
35
35
  # === Example
36
36
  # Logging.logger = Logger.new(STDERR)
37
37
  def logger=(logger)
38
- @logger = logger
38
+ @logger = logger
39
39
  end
40
40
 
41
41
  end
@@ -0,0 +1,146 @@
1
+ require 'net/https'
2
+ require 'uri'
3
+ require 'cgi'
4
+
5
+ module PayPal::SDK::Core
6
+ module Util
7
+ module HTTPHelper
8
+
9
+ include Configuration
10
+ include Logging
11
+ include Authentication
12
+ include Exceptions
13
+
14
+ # Create HTTP connection based on given service name or configured end point
15
+ def create_http_connection(uri)
16
+ new_http(uri).tap do |http|
17
+ if config.http_timeout
18
+ http.open_timeout = config.http_timeout
19
+ http.read_timeout = config.http_timeout
20
+ end
21
+ configure_ssl(http) if uri.scheme == "https"
22
+ end
23
+ end
24
+
25
+ # New raw HTTP object
26
+ def new_http(uri)
27
+ if config.http_proxy
28
+ proxy = URI.parse(config.http_proxy)
29
+ Net::HTTP.new(uri.host, uri.port, proxy.host, proxy.port, proxy.user, proxy.password)
30
+ else
31
+ Net::HTTP.new(uri.host, uri.port)
32
+ end
33
+ end
34
+
35
+ # Default ca file
36
+ def default_ca_file
37
+ File.expand_path("../../../../../data/paypal.crt", __FILE__)
38
+ end
39
+
40
+ # Apply ssl configuration to http object
41
+ def configure_ssl(http)
42
+ http.tap do |https|
43
+ https.use_ssl = true
44
+ https.ca_file = default_ca_file
45
+ https.verify_mode = OpenSSL::SSL::VERIFY_PEER
46
+ config.ssl_options.each do |key, value|
47
+ http.send("#{key}=", value)
48
+ end
49
+ add_certificate(https)
50
+ end
51
+ end
52
+
53
+ # Join url
54
+ def url_join(path, action)
55
+ path.sub(/\/?$/, "/#{action}")
56
+ end
57
+
58
+ # Make Http call
59
+ # * payload - Hash(:http, :method, :uri, :body, :header)
60
+ def http_call(payload)
61
+ response =
62
+ log_http_call(payload) do
63
+ http = payload[:http] || create_http_connection(payload[:uri])
64
+ http.start do |session|
65
+ if payload[:method] == :get
66
+ session.get(payload[:uri].request_uri, payload[:header])
67
+ else
68
+ session.send(payload[:method], payload[:uri].request_uri, payload[:body], payload[:header])
69
+ end
70
+ end
71
+ end
72
+ handle_response(response)
73
+ end
74
+
75
+ # Log Http call
76
+ # * payload - Hash(:http, :method, :uri, :body, :header)
77
+ def log_http_call(payload)
78
+ logger.info "Request[#{payload[:method]}]: #{payload[:uri].to_s}"
79
+ start_time = Time.now
80
+ response = yield
81
+ logger.info sprintf("Response[%s]: %s, Duration: %.3fs", response.code,
82
+ response.message, Time.now - start_time)
83
+ response
84
+ end
85
+
86
+ # Generate header based on given header keys and properties
87
+ # === Arguments
88
+ # * <tt>header_keys</tt> -- List of Header keys for the properties
89
+ # * <tt>properties</tt> -- properties
90
+ # === Return
91
+ # Hash with header as key property as value
92
+ # === Example
93
+ # map_header_value( { :username => "X-PAYPAL-USERNAME"}, { :username => "guest" })
94
+ # # Return: { "X-PAYPAL-USERNAME" => "guest" }
95
+ def map_header_value(header_keys, properties)
96
+ header = {}
97
+ properties.each do |key, value|
98
+ key = header_keys[key]
99
+ header[key] = value.to_s if key and value
100
+ end
101
+ header
102
+ end
103
+
104
+ def encode_www_form(hash)
105
+ if defined? URI.encode_www_form
106
+ URI.encode_www_form(hash)
107
+ else
108
+ hash.map{|key, value| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}" }.join("&")
109
+ end
110
+ end
111
+
112
+ # Handles response and error codes from the remote service.
113
+ def handle_response(response)
114
+ case response.code.to_i
115
+ when 301, 302, 303, 307
116
+ raise(Redirection.new(response))
117
+ when 200...400
118
+ response
119
+ when 400
120
+ raise(BadRequest.new(response))
121
+ when 401
122
+ raise(UnauthorizedAccess.new(response))
123
+ when 403
124
+ raise(ForbiddenAccess.new(response))
125
+ when 404
126
+ raise(ResourceNotFound.new(response))
127
+ when 405
128
+ raise(MethodNotAllowed.new(response))
129
+ when 409
130
+ raise(ResourceConflict.new(response))
131
+ when 410
132
+ raise(ResourceGone.new(response))
133
+ when 422
134
+ raise(ResourceInvalid.new(response))
135
+ when 401...500
136
+ raise(ClientError.new(response))
137
+ when 500...600
138
+ raise(ServerError.new(response))
139
+ else
140
+ raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
141
+ end
142
+ end
143
+
144
+ end
145
+ end
146
+ end
@@ -1,7 +1,7 @@
1
1
  module PayPal
2
2
  module SDK
3
3
  module Core
4
- VERSION = "0.1.5"
4
+ VERSION = "0.2.0"
5
5
  end
6
6
  end
7
7
  end
@@ -6,13 +6,15 @@ test: &default
6
6
  http_timeout: 30
7
7
  mode: sandbox
8
8
  sandbox_email_address: Platform.sdk.seller@gmail.com
9
- logfile: spec/log/test.log
10
- ca_file: <%= File.expand_path("../cacert.pem", __FILE__) %>
11
- ipn_end_point: https://www.sandbox.paypal.com/cgi-bin/webscr
12
9
 
13
10
  development:
14
11
  <<: *default
15
12
 
13
+ with_authentication:
14
+ <<: *default
15
+ client_id: EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM
16
+ client_secret: EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM
17
+
16
18
  with_certificate:
17
19
  <<: *default
18
20
  username: platfo_1255170694_biz_api1.gmail.com
@@ -25,6 +25,18 @@ describe PayPal::SDK::Core::API::DataTypes::Base do
25
25
  object_of :created_at, DateTime
26
26
  end
27
27
 
28
+ class Message < DataType
29
+ object_of :value, String
30
+ end
31
+
32
+ it "should allow content key" do
33
+ message = Message.new("Testing message")
34
+ message.value.should eql "Testing message"
35
+
36
+ message = Message.new(:value => "Testing message")
37
+ message.value.should eql "Testing message"
38
+ end
39
+
28
40
  it "should create member object automatically" do
29
41
  test_type = TestType.new
30
42
  test_type.fromCurrency.should be_a TestCurrency
@@ -5,10 +5,17 @@ describe PayPal::SDK::Core::API::IPN do
5
5
  IPN = PayPal::SDK::Core::API::IPN
6
6
 
7
7
  describe "Configuration" do
8
- it "set IPN end_point" do
9
- ipn_validate_url = "https://www.sandbox.paypal.com/cgi-bin/webscr"
10
- message = IPN::Message.new(samples["ipn"]["valid_message"], :ipn_end_point => ipn_validate_url )
11
- message.config.ipn_end_point.should eql ipn_validate_url
8
+ it "set IPN endpoint" do
9
+ message = IPN::Message.new("")
10
+ message.ipn_endpoint.should eql "https://www.sandbox.paypal.com/cgi-bin/webscr"
11
+ message = IPN::Message.new("", :mode => :sandbox)
12
+ message.ipn_endpoint.should eql "https://www.sandbox.paypal.com/cgi-bin/webscr"
13
+
14
+ message = IPN::Message.new("", :mode => :live)
15
+ message.ipn_endpoint.should eql "https://ipnpb.paypal.com/cgi-bin/webscr"
16
+
17
+ message = IPN::Message.new("", :ipn_endpoint => "http://example.com")
18
+ message.ipn_endpoint.should eql "http://example.com"
12
19
  end
13
20
  end
14
21
 
@@ -5,9 +5,46 @@ describe PayPal::SDK::Core::API::Merchant do
5
5
  Merchant = PayPal::SDK::Core::API::Merchant
6
6
 
7
7
  TransactionSearchParams = { "StartDate" => "2012-09-30T00:00:00+0530", "EndDate" => "2012-09-30T00:01:00+0530"}
8
- MassPayParams = { "ReceiverType" => "EmailAddress", "MassPayItem" => [{
8
+ MassPayParams = { "ReceiverType" => "EmailAddress", "MassPayItem" => [{
9
9
  "ReceiverEmail" => "enduser_biz@gmail.com", "Amount" => { "@currencyID" => "USD", "value" => "3.00" } }] }
10
10
 
11
+ describe "Configuration" do
12
+ it "service endpoint for sandbox" do
13
+ client = Merchant.new
14
+ client.service_endpoint.should eql "https://api-3t.sandbox.paypal.com/2.0/"
15
+ client = Merchant.new( :mode => "sandbox" )
16
+ client.service_endpoint.should eql "https://api-3t.sandbox.paypal.com/2.0/"
17
+ client = Merchant.new( :mode => :sandbox )
18
+ client.service_endpoint.should eql "https://api-3t.sandbox.paypal.com/2.0/"
19
+ client = Merchant.new( :mode => "invalid" )
20
+ client.service_endpoint.should eql "https://api-3t.sandbox.paypal.com/2.0/"
21
+ client = Merchant.new( :mode => nil )
22
+ client.service_endpoint.should eql "https://api-3t.sandbox.paypal.com/2.0/"
23
+
24
+ client = Merchant.new(:with_certificate)
25
+ client.service_endpoint.should eql "https://api.sandbox.paypal.com/2.0/"
26
+ end
27
+
28
+ it "service_endpoint for live" do
29
+ client = Merchant.new( :mode => "live" )
30
+ client.service_endpoint.should eql "https://api-3t.paypal.com/2.0/"
31
+ client = Merchant.new( :mode => :live )
32
+ client.service_endpoint.should eql "https://api-3t.paypal.com/2.0/"
33
+
34
+ client = Merchant.new( :with_certificate, :mode => "live" )
35
+ client.service_endpoint.should eql "https://api.paypal.com/2.0/"
36
+ end
37
+
38
+ it "override service endpoint" do
39
+ client = Merchant.new( :merchant_endpoint => "http://example.com" )
40
+ client.service_endpoint.should eql "http://example.com"
41
+ client = Merchant.new( :merchant_endpoint => "http://example.com", :mode => :live )
42
+ client.service_endpoint.should eql "http://example.com"
43
+ client = Merchant.new( :endpoint => "http://example.com" )
44
+ client.service_endpoint.should eql "http://example.com"
45
+ end
46
+ end
47
+
11
48
  describe "Success request" do
12
49
  it "with default configuration" do
13
50
  client = Merchant.new
@@ -37,33 +74,33 @@ describe PayPal::SDK::Core::API::Merchant do
37
74
  end
38
75
 
39
76
  it "should handle :value member" do
40
- uri, request, http_header = @client.format_request("Action", :amount => { :value => "50" } )
41
- request.should match '<amount>50</amount>'
42
- uri, request, http_header = @client.format_request("Action", "amount" => { "value" => "50" } )
43
- request.should match '<amount>50</amount>'
77
+ payload = @client.format_request(:action => "Action", :params => { :amount => { :value => "50" } } )
78
+ payload[:body].should match '<amount>50</amount>'
79
+ payload = @client.format_request(:action => "Action", :params => { "amount" => { "value" => "50" } } )
80
+ payload[:body].should match '<amount>50</amount>'
44
81
  end
45
82
 
46
83
  it "should handle attribute" do
47
- uri, request, http_header = @client.format_request("Action", :amount => { "@currencyID" => "USD", :value => "50" } )
48
- request.should match '<amount currencyID="USD">50</amount>'
49
- uri, request, http_header = @client.format_request("Action", "amount" => { "@currencyID" => "USD", "value" => "50" } )
50
- request.should match '<amount currencyID="USD">50</amount>'
84
+ payload = @client.format_request(:action => "Action", :params => { :amount => { "@currencyID" => "USD", :value => "50" } } )
85
+ payload[:body].should match '<amount currencyID="USD">50</amount>'
86
+ payload = @client.format_request(:amount => "Action", :params => { "amount" => { "@currencyID" => "USD", "value" => "50" } } )
87
+ payload[:body].should match '<amount currencyID="USD">50</amount>'
51
88
  end
52
89
 
53
90
  it "should handle members" do
54
- uri, request, http_header = @client.format_request("Action", :list => { :amount => { "@currencyID" => "USD", :value => "50" } } )
55
- request.should match '<list><amount currencyID="USD">50</amount></list>'
91
+ payload = @client.format_request(:action => "Action", :params => { :list => { :amount => { "@currencyID" => "USD", :value => "50" } } })
92
+ payload[:body].should match '<list><amount currencyID="USD">50</amount></list>'
56
93
  end
57
94
 
58
95
  it "should handle array of members" do
59
- uri, request, http_header = @client.format_request("Action",
60
- :list => { :amount => [ { "@currencyID" => "USD", :value => "50" }, { "@currencyID" => "USD", :value => "25" } ] } )
61
- request.should match '<list><amount currencyID="USD">50</amount><amount currencyID="USD">25</amount></list>'
96
+ payload = @client.format_request(:action => "Action", :params => {
97
+ :list => { :amount => [ { "@currencyID" => "USD", :value => "50" }, { "@currencyID" => "USD", :value => "25" } ] } })
98
+ payload[:body].should match '<list><amount currencyID="USD">50</amount><amount currencyID="USD">25</amount></list>'
62
99
  end
63
100
 
64
101
  it "should handle namespace" do
65
- uri, request, http_header = @client.format_request("Action", :"ebl:amount" => { "@cc:currencyID" => "USD", :value => "50" } )
66
- request.should match '<ebl:amount cc:currencyID="USD">50</ebl:amount>'
102
+ payload = @client.format_request(:action => "Action", :params => { :"ebl:amount" => { "@cc:currencyID" => "USD", :value => "50" } } )
103
+ payload[:body].should match '<ebl:amount cc:currencyID="USD">50</ebl:amount>'
67
104
  end
68
105
  end
69
106
 
@@ -78,7 +115,7 @@ describe PayPal::SDK::Core::API::Merchant do
78
115
  end
79
116
 
80
117
  it "invalid 3 token authentication" do
81
- client = Merchant.new(:username => "invalid")
118
+ client = Merchant.new(:username => "invalid", :password => 1234 )
82
119
  response = client.request("TransactionSearch", TransactionSearchParams )
83
120
  should_be_failure(response, "Security error")
84
121
  end
@@ -90,9 +127,10 @@ describe PayPal::SDK::Core::API::Merchant do
90
127
  end
91
128
 
92
129
  it "invalid action" do
93
- client = Merchant.new
94
- response = client.request("InvalidAction", TransactionSearchParams )
95
- should_be_failure(response, "Internal Server Error")
130
+ lambda {
131
+ client = Merchant.new
132
+ response = client.request("InvalidAction", TransactionSearchParams )
133
+ }.should raise_error PayPal::SDK::Core::Exceptions::ServerError
96
134
  end
97
135
 
98
136
  it "invalid params" do
@@ -13,9 +13,45 @@ describe PayPal::SDK::Core::API::Platform do
13
13
  { "name"=>"item2", "quantity"=>"2", "unitPrice"=>"2.00" } ] },
14
14
  "currencyCode" => "USD", "paymentTerms" => "DueOnReceipt" } }
15
15
 
16
- it "create client with Service name" do
17
- client = Platform.new("AdaptivePayments")
18
- client.uri.path.should match "AdaptivePayments$"
16
+ describe "Configuration" do
17
+ it "create client with Service name" do
18
+ client = Platform.new("AdaptivePayments")
19
+ client.uri.path.should match "AdaptivePayments$"
20
+ client.service_name.should eql "AdaptivePayments"
21
+ end
22
+
23
+ it "service endpoint for sandbox" do
24
+ sandbox_endpoint = "https://svcs.sandbox.paypal.com/"
25
+ client = Platform.new("AdaptivePayments")
26
+ client.service_endpoint.should eql sandbox_endpoint
27
+ client = Platform.new("AdaptivePayments", :with_certificate)
28
+ client.service_endpoint.should eql sandbox_endpoint
29
+ client = Platform.new("AdaptivePayments", :mode => "sandbox")
30
+ client.service_endpoint.should eql sandbox_endpoint
31
+ client = Platform.new("AdaptivePayments", :mode => :sandbox)
32
+ client.service_endpoint.should eql sandbox_endpoint
33
+ client = Platform.new("AdaptivePayments", :mode => "invalid")
34
+ client.service_endpoint.should eql sandbox_endpoint
35
+ client = Platform.new("AdaptivePayments", :mode => nil)
36
+ client.service_endpoint.should eql sandbox_endpoint
37
+ end
38
+
39
+ it "service endpoint for live" do
40
+ live_endpoint = "https://svcs.paypal.com/"
41
+ client = Platform.new("AdaptivePayments", :mode => "live")
42
+ client.service_endpoint.should eql live_endpoint
43
+ client = Platform.new("AdaptivePayments", :with_certificate, :mode => :live)
44
+ client.service_endpoint.should eql live_endpoint
45
+ end
46
+
47
+ it "override service endpoint" do
48
+ client = Platform.new("AdaptivePayments", :platform_endpoint => "http://example.com" )
49
+ client.service_endpoint.should eql "http://example.com"
50
+ client = Platform.new("AdaptivePayments", :platform_endpoint => "http://example.com", :mode => :live )
51
+ client.service_endpoint.should eql "http://example.com"
52
+ client = Platform.new("AdaptivePayments", :endpoint => "http://example.com" )
53
+ client.service_endpoint.should eql "http://example.com"
54
+ end
19
55
  end
20
56
 
21
57
  describe "Success request" do
@@ -58,8 +94,22 @@ describe PayPal::SDK::Core::API::Platform do
58
94
  should_be_success(response)
59
95
  end
60
96
  end
97
+
98
+ describe "Override Configuration" do
99
+ it "Set verify_mode" do
100
+ api = Platform.new("AdaptivePayments", :ssl_options => { :verify_mode => 0 } )
101
+ api.http.verify_mode.should eql 0
102
+ end
103
+
104
+ it "Set ca_file" do
105
+ api = Platform.new("AdaptivePayments", :ssl_options => { :ca_file => "ca_file_path" } )
106
+ api.http.ca_file.should eql "ca_file_path"
107
+ end
108
+ end
109
+
61
110
  end
62
111
 
112
+
63
113
  describe "Failure request" do
64
114
  def should_be_failure(response, message = nil)
65
115
  response.should_not be_nil
@@ -69,7 +119,7 @@ describe PayPal::SDK::Core::API::Platform do
69
119
  end
70
120
 
71
121
  it "invalid 3 token authentication" do
72
- client = Platform.new("AdaptivePayments", :password => "invalid")
122
+ client = Platform.new("AdaptivePayments", :username => 1234, :password => "invalid")
73
123
  response = client.request("ConvertCurrency", ConvertCurrencyParams )
74
124
  should_be_failure(response, "Authentication failed")
75
125
  end
@@ -81,9 +131,10 @@ describe PayPal::SDK::Core::API::Platform do
81
131
  end
82
132
 
83
133
  it "invalid action" do
84
- client = Platform.new("AdaptivePayments")
85
- response = client.request("InvalidAction", ConvertCurrencyParams)
86
- should_be_failure(response, "Internal Server Error")
134
+ lambda {
135
+ client = Platform.new("AdaptivePayments")
136
+ response = client.request("InvalidAction", ConvertCurrencyParams)
137
+ }.should raise_error PayPal::SDK::Core::Exceptions::ServerError
87
138
  end
88
139
 
89
140
  it "invalid params" do