paypal-sdk-core 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/{spec/config/cacert.pem → data/paypal.crt} +0 -0
- data/lib/generators/paypal/sdk/templates/paypal.yml +16 -19
- data/lib/paypal-sdk-core.rb +7 -4
- data/lib/paypal-sdk/core/api/base.rb +71 -87
- data/lib/paypal-sdk/core/api/data_types/base.rb +18 -6
- data/lib/paypal-sdk/core/api/ipn.rb +8 -18
- data/lib/paypal-sdk/core/api/merchant.rb +36 -16
- data/lib/paypal-sdk/core/api/platform.rb +21 -14
- data/lib/paypal-sdk/core/api/rest.rb +139 -0
- data/lib/paypal-sdk/core/authentication.rb +6 -19
- data/lib/paypal-sdk/core/config.rb +77 -7
- data/lib/paypal-sdk/core/exceptions.rb +87 -0
- data/lib/paypal-sdk/core/logging.rb +2 -2
- data/lib/paypal-sdk/core/util/http_helper.rb +146 -0
- data/lib/paypal-sdk/core/version.rb +1 -1
- data/spec/config/paypal.yml +5 -3
- data/spec/core/api/data_type_spec.rb +12 -0
- data/spec/core/api/ipn_spec.rb +11 -4
- data/spec/core/api/merchant_spec.rb +58 -20
- data/spec/core/api/platform_spec.rb +58 -7
- data/spec/core/api/rest_spec.rb +141 -0
- data/spec/core/config_spec.rb +76 -2
- data/spec/log/rest_http.log +104 -0
- data/spec/log/test.log +69 -1381
- data/spec/spec_helper.rb +3 -0
- metadata +13 -19
@@ -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(
|
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
|
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
|
data/spec/config/paypal.yml
CHANGED
@@ -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
|
data/spec/core/api/ipn_spec.rb
CHANGED
@@ -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
|
9
|
-
|
10
|
-
message
|
11
|
-
message.
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
55
|
-
|
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
|
-
|
60
|
-
:list => { :amount => [ { "@currencyID" => "USD", :value => "50" }, { "@currencyID" => "USD", :value => "25" } ] }
|
61
|
-
|
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
|
-
|
66
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
17
|
-
client
|
18
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
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
|