paypal_permissions 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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