paypal_permissions 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
6
+ *~
7
+ .emacs.desktop
8
+ tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in paypal_permissions.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/autospec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'autospec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('paypal_permissions', 'autospec')
data/bin/erubis ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'erubis' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('erubis', 'erubis')
data/bin/htmldiff ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'htmldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('paypal_permissions', 'htmldiff')
data/bin/ldiff ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'ldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('paypal_permissions', 'ldiff')
data/bin/rackup ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rackup' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rack', 'rackup')
data/bin/rails ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rails' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('railties', 'rails')
data/bin/rake ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('paypal_permissions', 'rake')
data/bin/rake2thor ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake2thor' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('thor', 'rake2thor')
data/bin/rdoc ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rdoc' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rdoc', 'rdoc')
data/bin/ri ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'ri' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rdoc', 'ri')
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('paypal_permissions', 'rspec')
data/bin/thor ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'thor' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('thor', 'thor')
data/bin/tilt ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'tilt' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('tilt', 'tilt')
data/bin/tt ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'tt' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('treetop', 'tt')
@@ -0,0 +1,13 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ not_found: "not found"
5
+ already_confirmed: "was already confirmed, please try signing in"
6
+ not_locked: "was not locked"
7
+ not_saved:
8
+ one: "1 error prohibited this %{resource} from being saved:"
9
+ other: "%{count} errors prohibited this %{resource} from being saved:"
10
+
11
+ paypal_permissions:
12
+ success: 'That was a fantastic success.'
13
+ failure: 'That failed miserably.'
@@ -0,0 +1,17 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/string/inflections'
3
+ require 'active_support/core_ext/hash/indifferent_access'
4
+ require 'active_support/core_ext/hash/conversions'
5
+ require 'active_support/core_ext/class/attribute'
6
+ require 'active_support/core_ext/class/attribute_accessors'
7
+ require 'active_support/core_ext/class/delegating_attributes'
8
+ require 'active_support/core_ext/module/attribute_accessors'
9
+ require 'active_support/base64'
10
+
11
+ require 'securerandom'
12
+ require 'builder'
13
+ require 'cgi'
14
+ require 'rexml/document'
15
+
16
+ require 'active_utils'
17
+ require 'active_merchant/billing'
@@ -0,0 +1 @@
1
+ require 'active_merchant/billing/gateways'
@@ -0,0 +1,17 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ autoload :Gateway, 'active_merchant/billing/gateway'
4
+
5
+ Dir[File.dirname(__FILE__) + '/gateways/**/*.rb'].each do |f|
6
+ # Get camelized class name
7
+ filename = File.basename(f, '.rb')
8
+ # Add _gateway suffix
9
+ gateway_name = filename + '_gateway'
10
+ # Camelize the string to get the class name
11
+ gateway_class = gateway_name.camelize
12
+
13
+ # Register for autoloading
14
+ autoload gateway_class, f
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,246 @@
1
+ require 'active_merchant'
2
+ require 'uri'
3
+ require 'cgi'
4
+ require 'openssl'
5
+ require 'base64'
6
+
7
+
8
+ module ActiveMerchant #:nodoc:
9
+ module Billing #:nodoc:
10
+ class PaypalPermissionsGateway < Gateway # :nodoc
11
+ public
12
+ def self.setup
13
+ yield self
14
+ end
15
+
16
+ public
17
+ def initialize(options = {})
18
+ requires!(options, :login, :password, :signature, :app_id)
19
+ request_permissions_headers = {
20
+ 'X-PAYPAL-SECURITY-USERID' => options.delete(:login),
21
+ 'X-PAYPAL-SECURITY-PASSWORD' => options.delete(:password),
22
+ 'X-PAYPAL-SECURITY-SIGNATURE' => options.delete(:signature),
23
+ 'X-PAYPAL-APPLICATION-ID' => options.delete(:app_id),
24
+ 'X-PAYPAL-REQUEST-DATA-FORMAT' => 'NV',
25
+ 'X-PAYPAL-RESPONSE-DATA-FORMAT' => 'NV',
26
+ }
27
+ request_permissions_headers = {
28
+ 'X-PAYPAL-SECURITY-USERID' => options.delete(:login),
29
+ 'X-PAYPAL-SECURITY-PASSWORD' => options.delete(:password),
30
+ 'X-PAYPAL-SECURITY-SIGNATURE' => options.delete(:signature),
31
+ 'X-PAYPAL-APPLICATION-ID' => options.delete(:app_id),
32
+ 'X-PAYPAL-REQUEST-DATA-FORMAT' => 'NV',
33
+ 'X-PAYPAL-RESPONSE-DATA-FORMAT' => 'NV',
34
+ }
35
+ @options = {
36
+ :request_permissions_headers => request_permissions_headers,
37
+ }.update(options)
38
+ super
39
+ end
40
+
41
+ public
42
+ def request_permissions(callback_url, scope)
43
+ query_string = build_request_permissions_query_string callback_url, scope
44
+ nvp_response = ssl_get "#{request_permissions_url}?#{query_string}", @options[:request_permissions_headers]
45
+ if nvp_response =~ /error\(\d+\)/
46
+ puts "request: #{request_permissions_url}?#{query_string}\n"
47
+ puts "nvp_response: #{nvp_response}\n"
48
+ end
49
+ response = parse_request_permissions_nvp(nvp_response)
50
+ end
51
+
52
+ public
53
+ def request_permissions_url
54
+ test? ? URLS[:test][:request_permissions] : URLS[:live][:request_permissions]
55
+ end
56
+
57
+ public
58
+ def get_access_token_url
59
+ test? ? URLS[:test][:get_access_token] : URLS[:live][:get_access_token]
60
+ end
61
+
62
+ public
63
+ def get_permissions_url
64
+ test? ? URLS[:test][:get_permissions] : URLS[:live][:get_permissions]
65
+ end
66
+
67
+ private
68
+ URLS = {
69
+ :test => {
70
+ :request_permissions => 'https://svcs.sandbox.paypal.com/Permissions/RequestPermissions',
71
+ :get_access_token => 'https://svcs.sandbox.paypal.com/Permissions/GetAccessToken',
72
+ :get_permissions => 'https://svcs.sandbox.paypal.com/Permissions/GetPermissions',
73
+ },
74
+ :live => {
75
+ :request_permissions => 'https://svcs.paypal.com/Permissions/RequestPermissions',
76
+ :get_access_token => 'https://svcs.paypal.com/Permissions/GetAccessToken',
77
+ :get_permissions => 'https://svcs.sandbox.paypal.com/Permissions/GetPermissions',
78
+ }
79
+ }
80
+
81
+ private
82
+ def build_request_permissions_query_string(callback_url, scope)
83
+ scopes_query = build_scopes_query_string(scope)
84
+ "requestEnvelope.errorLanguage=en_US&#{scopes_query}&callback=#{URI.encode(callback_url)}"
85
+ end
86
+
87
+ private
88
+ def build_scopes_query_string(scope)
89
+ if scope.is_a? String
90
+ scopes = scope.split(',')
91
+ elsif scope.is_a? Array
92
+ scopes = scope
93
+ else
94
+ scopes = []
95
+ end
96
+ scopes.collect{ |s| "scope=#{URI.encode(s.to_s.strip.upcase)}" }.join("&")
97
+ end
98
+
99
+ private
100
+ def setup_request_permission
101
+ callback
102
+ scope
103
+ end
104
+
105
+ private
106
+ def parse_request_permissions_nvp(nvp)
107
+ response = {
108
+ :errors => [
109
+ ],
110
+ }
111
+ pairs = nvp.split "&"
112
+ pairs.each do |pair|
113
+ n,v = pair.split "="
114
+ n = CGI.unescape n
115
+ v = CGI.unescape v
116
+ case n
117
+ when "responseEnvelope.timestamp"
118
+ response[:timestamp] = v
119
+ when "responseEnvelope.ack"
120
+ response[:ack] = v
121
+ =begin
122
+ # Client should implement these with logging...
123
+ case v
124
+ when "Success"
125
+ when "Failure"
126
+ when "Warning"
127
+ when "SuccessWithWarning"
128
+ when "FailureWithWarning"
129
+ end
130
+ =end
131
+ when "responseEnvelope.correlationId"
132
+ response[:correlation_id] = v
133
+ when "responseEnvelope.build"
134
+ # do nothing
135
+ when "token"
136
+ response[:token] = v
137
+ when /^error\((?<error_idx>\d+)\)/
138
+ error_idx = error_idx.to_i
139
+ if response[:errors].length <= error_idx
140
+ response[:errors] << { :parameters => [] }
141
+ raise if response[:errors].length <= error_idx
142
+ end
143
+ case n
144
+ when /^error\(\d+\)\.errorId$/
145
+ response[:errors][error_idx][:error_id] = v
146
+ =begin
147
+ # Client should implement these with logging. PayPal doesn't distinguish
148
+ # between errors which can be corrected by the user and errors which need
149
+ # to be corrected by a developer or merchant, say, in configuration.
150
+ # case v
151
+ # when "520002"
152
+ # when
153
+ =end
154
+ when /^error\(\d+\)\.domain$/
155
+ response[:errors][error_idx][:domain] = v
156
+ when /^error\(\d+\)\.subdomain$/
157
+ response[:errors][error_idx][:subdomain] = v
158
+ when /^error\(\d+\)\.severity$/
159
+ response[:errors][error_idx][:severity] = v
160
+ when /^error\(\d+\)\.category$/
161
+ response[:errors][error_idx][:category] = v
162
+ when /^error\(\d+\)\.message$/
163
+ response[:errors][error_idx][:message] = v
164
+ when /^error\(\d+\)\.parameter\((?<parameter_idx>\d+)\)$/
165
+ parameter_idx = parameter_idx.to_i
166
+ if response[:errors][error_idx][:parameters].length <= parameter_idx
167
+ response[:errors][error_idx][:parameters] << {}
168
+ raise if response[:errors][error_idx][:parameters].length <= parameter_idx
169
+ end
170
+ response[:errors][error_idx][:parameters][parameter_idx] = v
171
+ end
172
+ end
173
+ end
174
+ response
175
+ end
176
+
177
+ private
178
+ def authentication_header url
179
+ timestamp = Time.now.to_i
180
+ signature = authentication_signature url, timestamp
181
+ { 'X-PAYPAL-AUTHORIZATION' => "token=#{access_token}, signature=#{signature}, timeStamp=#{timestamp}" }
182
+ end
183
+
184
+ private
185
+ def authentication_signature url, timestamp
186
+ # no query params, but if there were, this is where they'd go
187
+ query_params = {}
188
+ key = [ password, verifier ].join("&")
189
+ params = query_params.dup.merge({
190
+ "oauth_consumer_key" => @options[:request_permissions_headers]['X-PAYPAL-SECURITY-USERID'],
191
+ "oauth_version" => "1.0",
192
+ "oauth_signature_method" => "HMAC-SHA1",
193
+ "oauth_token" => access_token,
194
+ "oauth_timestamp" => timestamp,
195
+ })
196
+ sorted_params = Hash[params.sort]
197
+ sorted_query_string = sorted_params.to_query
198
+ data = [ "POST", url, sorted_query_string ].join("&") # ? "https://api.sandbox.paypal.com/nvp"
199
+ digest = OpenSSL::Digest::Digest.new('sha1')
200
+ OpenSSL::HMAC.digest(digest, key, data)
201
+ enc = Base64.encode64('Send reinforcements') # encode per RFC 2045 (not 4648
202
+ end
203
+
204
+
205
+ =begin
206
+ public static Map getAuthHeader(String apiUserName, String apiPassword,
207
+ String accessToken, String tokenSecret, HTTPMethod httpMethod,
208
+ String scriptURI,Map queryParams) throws OAuthException {
209
+
210
+ Map headers=new HashMap();
211
+ String consumerKey = apiUserName;
212
+ String consumerSecretStr = apiPassword;
213
+ String time = String.valueOf(System.currentTimeMillis()/1000);
214
+
215
+ OAuthSignature oauth = new OAuthSignature(consumerKey,consumerSecretStr);
216
+ if(HTTPMethod.GET.equals(httpMethod) && queryParams != null){
217
+ Iterator itr = queryParams.entrySet().iterator();
218
+ while (itr.hasNext()) {
219
+ Map.Entry param = (Map.Entry)itr.next();
220
+ String key=(String)param.getKey();
221
+ String value=(String)param.getValue();
222
+ oauth.addParameter(key,value);
223
+ }
224
+ }
225
+ oauth.setToken(accessToken);
226
+ oauth.setTokenSecret(tokenSecret);
227
+ oauth.setHTTPMethod(httpMethod);
228
+ oauth.setTokenTimestamp(time);
229
+ oauth.setRequestURI(scriptURI);
230
+ //Compute Signature
231
+ String sig = oauth.computeV1Signature();
232
+
233
+ headers.put("Signature", sig);
234
+ headers.put("TimeStamp", time);
235
+ return headers;
236
+
237
+ }
238
+ =end
239
+
240
+ private
241
+ def setup_purchase(options)
242
+ commit('Pay', build_adaptive_payment_pay_request(options))
243
+ end
244
+ end
245
+ end
246
+ end