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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZWMwM2MzM2I5ZDkwMDY1ZWE1NDFkODJhMzQxMmEwZDM4NzhlMzk0YQ==
5
+ data.tar.gz: !binary |-
6
+ ZTA1MGNhNjE3MzdmZTBmNjY2M2IxNjU2YzNkM2FlMmVhYmMyNjBjNg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NDFmMzU2ZGNiM2JhOWM0ZDQ5NTI5MTUyNjY1MDU2MzA0ZTlmMDVmNWY2Yzc3
10
+ ZjE4ODBkMWViNjQ4Y2NhNGY4NjIzOThkOTBiMzI4ZDE3NmNkNmYzMzVjYzky
11
+ MjBiYTc0ZWFhZjBiZTliYWUxODM3NWFhZWExZGU2MWYyNDMzMjQ=
12
+ data.tar.gz: !binary |-
13
+ YWE5YjYwNjYzYWIxOGFhMDMzNGIwY2UyODcwZjg4OGIxZjliMzllNTJjOGFi
14
+ Y2MwMWFlZTNlOWEzNGYyZWY1YjA2ZTI5Njc2NjY2YTg2NmE2OTE1Y2ZlM2Qw
15
+ YzdkMzI5MjY0NTY0YjFiNDIwMTJiM2IzYWU4NzlkMWE2MWY5ZDQ=
File without changes
@@ -1,32 +1,29 @@
1
1
  test: &default
2
+
3
+ # Credentials for New APIs
4
+ client_id: EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM
5
+ client_secret: EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM
6
+
7
+ # Mode can be 'live' or 'sandbox'
8
+ mode: sandbox
9
+
10
+ # Credentials for Classic APIs
2
11
  username: jb-us-seller_api1.paypal.com
3
12
  password: WX4WTU3S8MY44S7F
4
13
  signature: AFcWxV21C7fd0v3bYYYRCpSSRl31A7yDhhsPUU2XhtMoZXsWHFxu-RWy
5
14
  app_id: APP-80W284485P519543T
6
- http_timeout: 30
7
- mode: sandbox
15
+ # # With Certificate
16
+ # cert_path: "config/cert_key.pem"
8
17
  sandbox_email_address: Platform.sdk.seller@gmail.com
9
18
 
19
+ # # IP Address
20
+ # ip_address: 127.0.0.1
21
+ # # HTTP Proxy
22
+ # http_proxy: http://proxy-ipaddress:3129/
23
+
10
24
  development:
11
25
  <<: *default
12
26
 
13
27
  production:
14
28
  <<: *default
15
29
  mode: live
16
-
17
- # with_certificate:
18
- # <<: *default
19
- # username: platfo_1255170694_biz_api1.gmail.com
20
- # password: 2DPPKUPKB7DQLXNR
21
- # signature:
22
- # cert_path: "config/cert_key.pem"
23
- # app_id: APP-80W284485P519543T
24
- #
25
- # with_oauth_token:
26
- # <<: *default
27
- # token: ESTy2hio5WJQo1iixkH29I53RJxaS0Gvno1A6.YQXZgktxbY4I2Tdg
28
- # token_secret: ZKPhUYuwJwYsfWdzorozWO2U9pI
29
- #
30
- # with_proxy:
31
- # <<: *default
32
- # http_proxy: http://proxy-ipaddress:3129/
@@ -1,17 +1,19 @@
1
- require "paypal-sdk/core/version"
2
- require "paypal-sdk/core/config"
3
- require "paypal-sdk/core/logging"
4
-
5
1
  module PayPal
6
2
  module SDK
7
3
  module Core
8
4
 
5
+ autoload :VERSION, "paypal-sdk/core/version"
6
+ autoload :Config, "paypal-sdk/core/config"
7
+ autoload :Configuration, "paypal-sdk/core/config"
8
+ autoload :Logging, "paypal-sdk/core/logging"
9
9
  autoload :Authentication, "paypal-sdk/core/authentication"
10
+ autoload :Exceptions, "paypal-sdk/core/exceptions"
10
11
 
11
12
  module API
12
13
  autoload :Base, "paypal-sdk/core/api/base"
13
14
  autoload :Merchant, "paypal-sdk/core/api/merchant"
14
15
  autoload :Platform, "paypal-sdk/core/api/platform"
16
+ autoload :REST, "paypal-sdk/core/api/rest"
15
17
  autoload :IPN, "paypal-sdk/core/api/ipn"
16
18
 
17
19
  module DataTypes
@@ -25,6 +27,7 @@ module PayPal
25
27
  module Util
26
28
  autoload :OauthSignature, "paypal-sdk/core/util/oauth_signature"
27
29
  autoload :OrderedHash, "paypal-sdk/core/util/ordered_hash"
30
+ autoload :HTTPHelper, "paypal-sdk/core/util/http_helper"
28
31
  end
29
32
 
30
33
  module Credential
@@ -1,5 +1,3 @@
1
- require 'net/https'
2
-
3
1
  module PayPal::SDK::Core
4
2
 
5
3
  module API
@@ -9,35 +7,12 @@ module PayPal::SDK::Core
9
7
  # response = api.request("GetPaymentOptions", "")
10
8
  class Base
11
9
 
12
- include Configuration
13
- include Logging
14
- include Authentication
10
+ include Util::HTTPHelper
15
11
 
16
12
  attr_accessor :http, :uri, :service_name
17
13
 
18
- DEFAULT_END_POINTS = {
19
- :sandbox => {
20
- :platform => { # NVP EndPoint
21
- :three_token => "https://svcs.sandbox.paypal.com/",
22
- :certificate => "https://svcs.sandbox.paypal.com/"
23
- },
24
- :merchant => { # SOAP EndPoint
25
- :three_token => "https://api-3t.sandbox.paypal.com/2.0",
26
- :certificate => "https://api.sandbox.paypal.com/2.0"
27
- }
28
- },
29
- :live => {
30
- :platform => { # NVP EndPoint
31
- :three_token => "https://svcs.paypal.com/",
32
- :certificate => "https://svcs.paypal.com/"
33
- },
34
- :merchant => { # SOAP EndPoint
35
- :three_token => "https://api-3t.paypal.com/2.0",
36
- :certificate => "https://api.paypal.com/2.0"
37
- }
38
- }
39
- }
40
- DEFAULT_HTTP_HEADER = {}
14
+ DEFAULT_API_MODE = :sandbox
15
+ API_MODES = [ :live, :sandbox ]
41
16
 
42
17
  # Initialize API object
43
18
  # === Argument
@@ -56,89 +31,89 @@ module PayPal::SDK::Core
56
31
  set_config(environment, options)
57
32
  end
58
33
 
59
- # Override set_config method to create http connection on changing the configuration.
60
- def set_config(*args)
61
- super
62
- create_http_connection
34
+ def uri
35
+ @uri ||=
36
+ begin
37
+ uri = URI.parse("#{service_endpoint}/#{service_name}")
38
+ uri.path = uri.path.gsub(/\/+/, "/")
39
+ uri
40
+ end
63
41
  end
64
42
 
65
- # Create HTTP connection based on given service name or configured end point
66
- def create_http_connection
67
- service_path = "#{service_endpoint}/#{service_name}"
68
- @uri = URI.parse(service_path)
69
- if config.http_proxy
70
- proxy = URI.parse(config.http_proxy)
71
- @http = Net::HTTP.new(@uri.host, @uri.port, proxy.host, proxy.port, proxy.user, proxy.password)
72
- else
73
- @http = Net::HTTP.new(@uri.host, @uri.port)
74
- end
75
- @uri.path = @uri.path.gsub(/\/+/, "/")
76
- configure_http_connection
43
+ def http
44
+ @http ||= create_http_connection(uri)
77
45
  end
78
46
 
79
- # Configure HTTP connection based on configuration.
80
- def configure_http_connection
81
- if @uri.scheme == "https"
82
- http.use_ssl = true
83
- if config.ca_file
84
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
85
- http.ca_file = config.ca_file
86
- end
87
- end
88
- if config.http_timeout
89
- http.open_timeout = config.http_timeout
90
- http.read_timeout = config.http_timeout
91
- end
92
- add_certificate(http)
47
+ # Override set_config method to create http connection on changing the configuration.
48
+ def set_config(*args)
49
+ @http = @uri = nil
50
+ super
93
51
  end
94
52
 
95
53
  # Get configured API mode( sandbox or live)
96
54
  def api_mode
97
- api_modes = DEFAULT_END_POINTS.keys
98
- config_mode = ( config.mode || api_modes.first ).to_sym
99
- api_modes.include?(config_mode) ? config_mode : api_modes.first
100
- end
101
-
102
- # Get default endpoint for the given service name
103
- # === Argument
104
- # * <tt>name</tt> -- Service name ( platform or merchant)
105
- # === Returns
106
- # Return service end point based on the configured API mode.
107
- def default_end_point(name)
108
- default_end_point = DEFAULT_END_POINTS[api_mode][name]
109
- if default_end_point
110
- config.cert_path ? default_end_point[:certificate] : default_end_point[:three_token]
55
+ if config.mode and API_MODES.include? config.mode.to_sym
56
+ config.mode.to_sym
57
+ else
58
+ DEFAULT_API_MODE
111
59
  end
112
60
  end
113
61
 
114
62
  # Get service end point
115
63
  def service_endpoint
116
- config.end_point ? default_end_point(config.end_point.to_sym) : config.end_point
64
+ config.endpoint
117
65
  end
118
66
 
119
67
  # Default Http header
120
68
  def default_http_header
121
- DEFAULT_HTTP_HEADER
69
+ { "User-Agent" => self.class.user_agent }
122
70
  end
123
71
 
124
72
  # Generate HTTP request for given action and parameters
125
73
  # === Arguments
74
+ # * <tt>http_method</tt> -- HTTP method(get/put/post/delete/patch)
126
75
  # * <tt>action</tt> -- Action to perform
127
76
  # * <tt>params</tt> -- (Optional) Parameters for the action
128
77
  # * <tt>initheader</tt> -- (Optional) HTTP header
129
- def request(action, params = {}, initheader = {})
130
- uri, content, header = format_request(action, params)
131
- initheader = default_http_header.merge(header).merge(initheader)
132
- initheader.delete_if{|key, val| val.nil? }
133
- response =
134
- log_event("Request: #{action}") do
135
- @http.post(uri.path, content, initheader)
136
- end
137
- format_response(action, response)
78
+ def api_call(payload)
79
+ payload[:header] = default_http_header.merge(payload[:header])
80
+ payload[:uri] ||= uri.dup
81
+ payload[:http] ||= http.dup
82
+ payload[:uri].query = encode_www_form(payload[:query]) if payload[:query] and payload[:query].any?
83
+ format_request(payload)
84
+ payload[:response] = http_call(payload)
85
+ format_response(payload)
86
+ payload[:data]
138
87
  rescue Net::HTTPBadGateway, Errno::ECONNRESET, Errno::ECONNABORTED, SocketError => error
139
88
  format_error(error, error.message)
140
89
  end
141
90
 
91
+ # Generate HTTP request for given action and parameters
92
+ # === Arguments
93
+ # * <tt>action</tt> -- Action to perform
94
+ # * <tt>params</tt> -- (Optional) Parameters for the action
95
+ # * <tt>initheader</tt> -- (Optional) HTTP header
96
+ def post(action, params = {}, header = {})
97
+ api_call(:method => :post, :action => action, :params => params, :header => header)
98
+ end
99
+ alias_method :request, :post
100
+
101
+ def get(action, params = {}, header = {})
102
+ api_call(:method => :get, :action => action, :query => params, :params => nil, :header => header)
103
+ end
104
+
105
+ def patch(action, params = {}, header = {})
106
+ api_call(:method => :patch, :action => action, :params => params, :header => header)
107
+ end
108
+
109
+ def put(action, params = {}, header = {})
110
+ api_call(:method => :put, :action => action, :params => params, :header => header)
111
+ end
112
+
113
+ def delete(action, params = {}, header = {})
114
+ api_call(:method => :delete, :action => action, :params => params, :header => header)
115
+ end
116
+
142
117
  # Format Request data. It will be override by child class
143
118
  # == Arguments
144
119
  # * <tt>action</tt> -- Request action
@@ -147,16 +122,19 @@ module PayPal::SDK::Core
147
122
  # * <tt>path</tt> -- Formated request uri object
148
123
  # * <tt>params</tt> -- Formated request Parameters
149
124
  # * <tt>header</tt> -- HTTP Header
150
- def format_request(action, params)
151
- [ @uri, params, {} ]
125
+ def format_request(payload)
126
+ payload[:uri].path = url_join(payload[:uri].path, payload[:action])
127
+ payload[:body] = payload[:params].to_s
128
+ payload
152
129
  end
153
130
 
154
131
  # Format Response object. It will be override by child class
155
132
  # == Argument
156
133
  # * <tt>action</tt> -- Request action
157
134
  # * <tt>response</tt> -- HTTP response object
158
- def format_response(action, response)
159
- response
135
+ def format_response(payload)
136
+ payload[:data] = payload[:response].body
137
+ payload
160
138
  end
161
139
 
162
140
  # Format Error object. It will be override by child class.
@@ -166,6 +144,12 @@ module PayPal::SDK::Core
166
144
  def format_error(exception, message)
167
145
  raise exception
168
146
  end
147
+
148
+ class << self
149
+ def user_agent
150
+ @user_agent ||= "paypal-sdk-core/#{VERSION} #{RUBY_DESCRIPTION}"
151
+ end
152
+ end
169
153
  end
170
154
  end
171
155
  end
@@ -110,20 +110,32 @@ module PayPal::SDK::Core
110
110
 
111
111
  # Initialize options.
112
112
  def initialize(options = {}, &block)
113
+ merge!(options, &block)
114
+ end
115
+
116
+ # Merge values
117
+ def merge!(options, &block)
113
118
  if options.is_a? Hash
114
119
  options.each do |key, value|
115
- begin
116
- send("#{key}=", value)
117
- rescue TypeError, ArgumentError => error
118
- raise TypeError, "#{error.message}(#{value.inspect}) for #{self.class.name}.#{key} member"
119
- end
120
+ set(key, value)
120
121
  end
121
122
  elsif members[ContentKey]
122
- self.value = options
123
+ set(ContentKey, options)
123
124
  else
124
125
  raise ArgumentError, "invalid data(#{options.inspect}) for #{self.class.name} class"
125
126
  end
126
127
  self.instance_eval(&block) if block
128
+ self
129
+ end
130
+
131
+ # Set value for given member
132
+ # === Arguments
133
+ # * <tt>key</tt> -- member name
134
+ # * <tt>value</tt> -- value for member
135
+ def set(key, value)
136
+ send("#{key}=", value)
137
+ rescue TypeError, ArgumentError => error
138
+ raise TypeError, "#{error.message}(#{value.inspect}) for #{self.class.name}.#{key} member"
127
139
  end
128
140
 
129
141
  # Create array of objects.
@@ -1,5 +1,3 @@
1
- require 'net/https'
2
-
3
1
  module PayPal
4
2
  module SDK
5
3
  module Core
@@ -14,7 +12,7 @@ module PayPal
14
12
  INVALID = "INVALID"
15
13
 
16
14
  class Message
17
- include PayPal::SDK::Core::Configuration
15
+ include Util::HTTPHelper
18
16
 
19
17
  attr_accessor :message
20
18
 
@@ -24,31 +22,23 @@ module PayPal
24
22
  end
25
23
 
26
24
  # Fetch end point
27
- def ipn_end_point
28
- config.ipn_end_point || default_ipn_end_point
25
+ def ipn_endpoint
26
+ config.ipn_endpoint || default_ipn_endpoint
29
27
  end
30
28
 
31
29
  # Default IPN end point
32
- def default_ipn_end_point
33
- end_point = END_POINTS[(config.mode || :sandbox).to_sym] rescue nil
34
- end_point || END_POINTS[:sandbox]
30
+ def default_ipn_endpoint
31
+ endpoint = END_POINTS[(config.mode || :sandbox).to_sym] rescue nil
32
+ endpoint || END_POINTS[:sandbox]
35
33
  end
36
34
 
37
35
  # Request IPN service for validating the content
38
36
  # === Return
39
37
  # return http response object
40
38
  def request
41
- uri = URI(ipn_end_point)
42
- http = Net::HTTP.new(uri.host, uri.port)
43
- if uri.scheme == "https"
44
- http.use_ssl = true
45
- if config.ca_file
46
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
47
- http.ca_file = config.ca_file
48
- end
49
- end
39
+ uri = URI(ipn_endpoint)
50
40
  query_string = "cmd=_notify-validate&#{message}"
51
- http.post(uri.path, query_string)
41
+ http_call(:method => :post, :uri => uri, :body => query_string)
52
42
  end
53
43
 
54
44
  # Validate the given content
@@ -35,10 +35,20 @@ module PayPal::SDK::Core
35
35
  :signature => "ebl:Signature",
36
36
  :subject => "ebl:Subject"
37
37
  }
38
+ DEFAULT_END_POINTS = {
39
+ :sandbox => {
40
+ :three_token => "https://api-3t.sandbox.paypal.com/2.0/",
41
+ :certificate => "https://api.sandbox.paypal.com/2.0/"
42
+ },
43
+ :live => {
44
+ :three_token => "https://api-3t.paypal.com/2.0/",
45
+ :certificate => "https://api.paypal.com/2.0/"
46
+ }
47
+ }
38
48
 
39
- # Get SOAP or default end point
49
+ # Get services end point
40
50
  def service_endpoint
41
- config.merchant_end_point || super || default_end_point(:merchant)
51
+ config.merchant_endpoint || config.endpoint || DEFAULT_END_POINTS[api_mode][base_credential_type]
42
52
  end
43
53
 
44
54
  # Format the HTTP request content
@@ -48,22 +58,24 @@ module PayPal::SDK::Core
48
58
  # === Return
49
59
  # * <tt>request_path</tt> -- Soap request path. DEFAULT("/")
50
60
  # * <tt>request_content</tt> -- Request content in SOAP format.
51
- def format_request(action, params)
61
+ def format_request(payload)
52
62
  credential_properties = credential(uri.to_s).properties
53
63
  user_auth_header = map_header_value(SOAP_AUTH_HEADER, credential_properties)
54
- content_key = params.keys.first.is_a?(Symbol) ? ContentKey.to_sym : ContentKey.to_s
64
+ content_key = payload[:params].keys.first.is_a?(Symbol) ? ContentKey.to_sym : ContentKey.to_s
55
65
  xml_out_options = XML_OUT_OPTIONS.merge( 'ContentKey' => content_key )
56
66
  request_content = XmlSimple.xml_out({
57
67
  "soapenv:Envelope" => {
58
68
  content_key => (
59
- XmlSimple.xml_out({"soapenv:Header" => { "ns:RequesterCredentials" => {
69
+ XmlSimple.xml_out({"soapenv:Header" => { "ns:RequesterCredentials" => {
60
70
  "ebl:Credentials" => user_auth_header
61
71
  }}}, xml_out_options) +
62
- XmlSimple.xml_out({"soapenv:Body" => body(action, params)}, xml_out_options))
72
+ XmlSimple.xml_out({"soapenv:Body" => request_body(payload[:action], payload[:params])}, xml_out_options))
63
73
  }.merge(Namespaces)
64
74
  }, xml_out_options.merge('noescape' => true))
65
75
  header = map_header_value(SOAP_HTTP_AUTH_HEADER, credential_properties)
66
- [ @uri, request_content, header ]
76
+ payload[:header] = header.merge(header)
77
+ payload[:body] = request_content
78
+ payload
67
79
  end
68
80
 
69
81
  # Format Response object
@@ -72,14 +84,22 @@ module PayPal::SDK::Core
72
84
  # * <tt>response</tt> -- Response object
73
85
  # === Return
74
86
  # Parse the SOAP response content and return Hash object
75
- def format_response(action, response)
76
- if response.code == "200"
77
- hash = XmlSimple.xml_in(response.body, XML_IN_OPTIONS)
78
- hash = skip_attributes(hash)
79
- hash["Body"].find{|key_val| key_val[0] =~ /^[^@]/ }[1] || {}
80
- else
81
- format_error(response, response.message)
82
- end
87
+ def format_response(payload)
88
+ payload[:data] =
89
+ if payload[:response].code == "200"
90
+ hash = XmlSimple.xml_in(payload[:response].body, XML_IN_OPTIONS)
91
+ hash = skip_attributes(hash)
92
+ hash["Body"].find{|key_val| key_val[0] =~ /^[^@]/ }[1] || {}
93
+ else
94
+ format_error(payload[:response], payload[:response].message)
95
+ end
96
+ payload
97
+ end
98
+
99
+ # Log additional information
100
+ def log_http_call(payload)
101
+ logger.info "Action: #{payload[:action]}" if payload[:action]
102
+ super
83
103
  end
84
104
 
85
105
  private
@@ -88,7 +108,7 @@ module PayPal::SDK::Core
88
108
  # == Arguments
89
109
  # * <tt>action</tt> -- Request Action name
90
110
  # * <tt>params</tt> -- Parameters for the action.
91
- def body(action, params = {})
111
+ def request_body(action, params = {})
92
112
  { "ns:#{action}Req" => { "ns:#{action}Request" => DEFAULT_PARAMS.merge(params) } }
93
113
  end
94
114