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.
- 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
|