paypal-ipn 0.0.1 → 0.0.2

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.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in paypal.gemspec
4
+ gemspec
@@ -6,6 +6,8 @@ Currently paypal supports the following:
6
6
 
7
7
  * Verifying Paypal IPN's
8
8
  * MassPay Requests
9
+ * Permissions Service
10
+ * Authentication Service
9
11
 
10
12
  ## Configuration
11
13
  Paypal.setup do |config|
@@ -101,13 +103,56 @@ Note: Your class must respond to `payment_response` and return the payment respo
101
103
 
102
104
  Note: Currently Masspay payments only support a single recipient
103
105
 
104
- ## Rails
105
- `rails g paypal:initializer`
106
- Generates a stub initializer under config/initializers
106
+ ### Permissions Service
107
+ class Permissions
108
+ include Paypal::Permissions
109
+ end
110
+
111
+ #### Usage
112
+ 1. Make a call to `set_paypal_permissions_url` setting the *return_url* to your application's callback url and with your *required_permissions*
113
+
114
+ 2. Redirect the user to that url
115
+
116
+ 3. When Paypal redirects the user back to your application at *return_url* make a call to `get_paypal_permissions` with the token parameter
117
+
118
+ See below for further details:
119
+
120
+ ##### Private methods
121
+ `set_paypal_permissions_url(return_url, required_permissions = {})`
122
+ Returns a url where the user can sign in to Paypal and authorize the requested permissions. Paypal will then redirect the user to the *return_url*. Specify *required_permissions* by supplying a hash in the following format:
123
+ {
124
+ :mass_pay => true,
125
+ :refund_transaction => true,
126
+ :get_transaction_details => true
127
+ }
128
+ First name, Last name and email are always required permissions so you never have to specify these manually.
129
+
130
+ `get_paypal_permissions(token)`
131
+ Returns a hash of user information and permission details for the given *token* in the following format:
132
+ {
133
+ :email => "joe@example.com",
134
+ :first_name => "Joe",
135
+ :last_name => "Bloggs",
136
+ :payer_id => "VK7XZU4BDY79",
137
+ :permissions => {
138
+ :mass_pay => true,
139
+ :refund_transaction => true,
140
+ :get_transaction_details => true
141
+ }
142
+ }
107
143
 
108
144
  ## Installation
109
145
 
110
- gem install paypal
146
+ gem install paypal-ipn
147
+
148
+ ## Rails
149
+
150
+ Place the following in your Gemfile:
151
+ `gem 'paypal-ipn', :require => 'paypal'`
152
+
153
+ To generate a stub initializer under config/initializers run:
154
+ `rails g paypal:initializer`
155
+
111
156
 
112
157
  Copyright (c) 2010 David Wilkie, released under the MIT license
113
158
 
data/Rakefile CHANGED
@@ -1,39 +1,2 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
4
-
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
-
8
- desc 'Test the Paypal plugin.'
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.libs << 'spec'
12
- t.libs << 'features'
13
- t.pattern = 'spec/**/*_spec.rb'
14
- t.verbose = true
15
- end
16
-
17
- begin
18
- require 'jeweler'
19
- Jeweler::Tasks.new do |gemspec|
20
- gemspec.name = "paypal-ipn"
21
- gemspec.summary = "Another ruby wrapper for Paypal"
22
- gemspec.email = "dwilkie@gmail.com"
23
- gemspec.homepage = "http://github.com/dwilkie/paypal"
24
- gemspec.authors = ["David Wilkie"]
25
- gemspec.add_runtime_dependency "httparty", ">=0.6.1"
26
- end
27
- rescue LoadError
28
- puts "Jeweler not available. Install it with: gem install jeweler"
29
- end
30
-
31
- desc 'Generate documentation for the Paypal plugin.'
32
- Rake::RDocTask.new(:rdoc) do |rdoc|
33
- rdoc.rdoc_dir = 'rdoc'
34
- rdoc.title = 'Paypal'
35
- rdoc.options << '--line-numbers' << '--inline-source'
36
- rdoc.rdoc_files.include('README')
37
- rdoc.rdoc_files.include('lib/**/*.rb')
38
- end
39
-
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -1,14 +1,20 @@
1
+ require 'httparty'
1
2
  require 'paypal/ipn/ipn'
2
3
  require 'paypal/ipn/types/masspay'
3
4
  require 'paypal/ipn/variables/buyer'
4
5
  require 'paypal/ipn/variables/item'
5
6
  require 'paypal/masspay'
7
+ require 'paypal/permissions'
8
+ require 'paypal/authentication'
6
9
 
7
10
  module Paypal
8
11
 
9
12
  LIVE_NVP_URI = "https://api-3t.paypal.com/nvp"
10
13
  SANDBOX_NVP_URI = "https://api-3t.sandbox.paypal.com/nvp"
11
14
 
15
+ LIVE_URI = "https://www.paypal.com"
16
+ SANDBOX_URI = "https://www.sandbox.paypal.com"
17
+
12
18
  mattr_accessor :environment,
13
19
  :api_username,
14
20
  :api_password,
@@ -20,10 +26,16 @@ module Paypal
20
26
  yield self
21
27
  end
22
28
 
23
- def self.nvp_uri
29
+ def self.nvp_uri(force_https = true)
24
30
  environment == "live" ?
25
31
  LIVE_NVP_URI :
26
32
  SANDBOX_NVP_URI
27
33
  end
34
+
35
+ def self.uri
36
+ environment == "live" ?
37
+ LIVE_URI :
38
+ SANDBOX_URI
39
+ end
28
40
  end
29
41
 
@@ -0,0 +1,67 @@
1
+ module Paypal
2
+ module Authentication
3
+ require 'rack'
4
+ include HTTParty
5
+ private
6
+ def authenticate_with_paypal_url(return_url)
7
+ body = {
8
+ "METHOD" => "SetAuthFlowParam",
9
+ "VERSION" => "2.3",
10
+ "USER" => Paypal.api_username,
11
+ "PWD" => Paypal.api_password,
12
+ "SIGNATURE" => Paypal.api_signature,
13
+ "SERVICENAME1" => "Name",
14
+ "SERVICEDEFREQ1" => "Required",
15
+ "SERVICENAME2" => "Email",
16
+ "SERVICEDEFREQ2" => "Required",
17
+ "RETURNURL" => return_url,
18
+ "CANCELURL" => return_url,
19
+ "LOGOUTURL"=> return_url
20
+ }
21
+ request_uri = URI.parse(Paypal.nvp_uri)
22
+ request_uri.scheme = "https" # force https
23
+ response = Paypal::Authentication.send_request(body)
24
+ url = Paypal::Authentication.build_uri_from_set_auth_flow_param_response(response)
25
+ url ? url : return_url
26
+ end
27
+
28
+ def get_auth_details(token)
29
+ body = {
30
+ "METHOD" => "GetAuthDetails",
31
+ "VERSION" => "2.3",
32
+ "USER" => Paypal.api_username,
33
+ "PWD" => Paypal.api_password,
34
+ "SIGNATURE" => Paypal.api_signature,
35
+ "TOKEN" => token
36
+ }
37
+ Paypal::Authentication.normalize_paypal_response(
38
+ Paypal::Authentication.send_request(body)
39
+ )
40
+ end
41
+
42
+ def self.normalize_paypal_response(raw_response)
43
+ raw_response_hash = Rack::Utils.parse_nested_query(raw_response)
44
+ {
45
+ :payer_id => raw_response_hash["PAYERID"],
46
+ :first_name => raw_response_hash["FIRSTNAME"],
47
+ :last_name => raw_response_hash["LASTNAME"],
48
+ :email => raw_response_hash["EMAIL"]
49
+ } if raw_response_hash["ACK"] == "Success"
50
+ end
51
+
52
+ def self.send_request(body)
53
+ self.post(Paypal.nvp_uri, :body => body).body
54
+ end
55
+
56
+ def self.build_uri_from_set_auth_flow_param_response(response)
57
+ if token = Rack::Utils.parse_nested_query(response)["TOKEN"]
58
+ uri = URI.parse(Paypal.uri)
59
+ uri.query = Rack::Utils.build_nested_query(
60
+ "token" => token, "cmd" => "_account-authenticate-login"
61
+ )
62
+ uri.to_s
63
+ end
64
+ end
65
+ end
66
+ end
67
+
@@ -0,0 +1,126 @@
1
+ module Paypal
2
+ module Permissions
3
+ require 'rack'
4
+ include HTTParty
5
+ private
6
+ def set_paypal_permissions_url(return_url, required_permissions = {})
7
+ required_permissions.merge!(:name => true, :email => true)
8
+ paypal_required_permissions = {}
9
+ index = 0
10
+ required_permissions.each do |k,v|
11
+ if v
12
+ paypal_required_permissions["L_REQUIREDACCESSPERMISSIONS#{index}"] = Paypal::Permissions.paypal_permission_name(k)
13
+ index += 1
14
+ end
15
+ end
16
+ body = {
17
+ "METHOD" => "SetAccessPermissions",
18
+ "VERSION" => "2.3",
19
+ "USER" => Paypal.api_username,
20
+ "PWD" => Paypal.api_password,
21
+ "SIGNATURE" => Paypal.api_signature,
22
+ "RETURNURL" => return_url,
23
+ "CANCELURL" => return_url,
24
+ "LOGOUTURL"=> return_url
25
+ }.merge(paypal_required_permissions)
26
+ response = Paypal::Permissions.send_request(body)
27
+ url = Paypal::Permissions.build_uri_from_set_access_permissions_response(response)
28
+ url ? url : return_url
29
+ end
30
+
31
+ def get_paypal_permissions(token)
32
+ body = {
33
+ "METHOD" => "GetAccessPermissionDetails",
34
+ "VERSION" => "2.3",
35
+ "USER" => Paypal.api_username,
36
+ "PWD" => Paypal.api_password,
37
+ "SIGNATURE" => Paypal.api_signature,
38
+ "TOKEN" => token
39
+ }
40
+ Paypal::Permissions.normalize_paypal_response(
41
+ Paypal::Permissions.send_request(body)
42
+ )
43
+ end
44
+
45
+ def self.send_request(body)
46
+ self.post(Paypal.nvp_uri, :body => body).body
47
+ end
48
+
49
+ def self.paypal_permission_name(key)
50
+ case key.to_s
51
+
52
+ when "express_checkout"
53
+ "Express_Checkout"
54
+
55
+ when "admin_api"
56
+ "Admin_API"
57
+
58
+ when "auth_settle"
59
+ "Auth_Settle"
60
+
61
+ when "transaction_history"
62
+ "Transaction_History"
63
+
64
+ when "do_uatp_authorization"
65
+ "DoUATPAuthorization"
66
+
67
+ when "do_uatp_express_checkout_payment"
68
+ "DoUATPExpressCheckoutPayment"
69
+
70
+ else
71
+ camelize(key)
72
+ end
73
+ end
74
+
75
+ def self.build_uri_from_set_access_permissions_response(response)
76
+ if token = Rack::Utils.parse_nested_query(response)["TOKEN"]
77
+ uri = URI.parse(Paypal.uri)
78
+ uri.query = Rack::Utils.build_nested_query(
79
+ "token" => token, "cmd" => "_access-permission-login"
80
+ )
81
+ uri.to_s
82
+ end
83
+ end
84
+
85
+ def self.normalize_paypal_response(raw_response)
86
+ raw_response_hash = Rack::Utils.parse_nested_query(raw_response)
87
+ if raw_response_hash["ACK"] == "Success"
88
+ normalized_response = {
89
+ :payer_id => raw_response_hash["PAYERID"],
90
+ :first_name => raw_response_hash["FIRSTNAME"],
91
+ :last_name => raw_response_hash["LASTNAME"],
92
+ :email => raw_response_hash["EMAIL"],
93
+ :permissions => normalize_permissions(raw_response_hash)
94
+ }
95
+ end
96
+ end
97
+
98
+ def self.normalize_permissions(raw_response_hash)
99
+ normalized_permissions = {}
100
+ permission_name_key = "L_ACCESSPERMISSIONNAME"
101
+ permission_status_key = "L_ACCESSPERMISSIONSTATUS"
102
+ i = 0
103
+ begin
104
+ permission = raw_response_hash[permission_name_key + i.to_s]
105
+ permission_status = raw_response_hash[permission_status_key + i.to_s]
106
+ normalized_permissions[underscore(permission).to_sym] = (permission_status == "Accepted") if permission && permission_status
107
+ i += 1
108
+ end until permission.nil? || permission_status.nil?
109
+ normalized_permissions
110
+ end
111
+
112
+ def self.camelize(lower_case_and_underscored_word)
113
+ lower_case_and_underscored_word.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
114
+ end
115
+
116
+ def self.underscore(camel_cased_word)
117
+ word = camel_cased_word.to_s.dup
118
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
119
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
120
+ word.tr!("-", "_")
121
+ word.downcase!
122
+ word
123
+ end
124
+ end
125
+ end
126
+
@@ -0,0 +1,3 @@
1
+ module Paypal
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "paypal/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "paypal-ipn"
7
+ s.version = Paypal::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["David Wilkie"]
10
+ s.email = ["dwilkie@gmail.com"]
11
+ s.homepage = "https://github.com/dwilkie/paypal"
12
+ s.summary = %q{More than just IPNs}
13
+ s.description = %q{A ruby library for handling paypal api's including IPNs}
14
+ s.add_runtime_dependency("httparty")
15
+
16
+ s.rubyforge_project = "paypal"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+ end
23
+
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Wilkie
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-24 00:00:00 +07:00
17
+ date: 2010-11-16 00:00:00 +07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,41 +27,44 @@ dependencies:
27
27
  - !ruby/object:Gem::Version
28
28
  segments:
29
29
  - 0
30
- - 6
31
- - 1
32
- version: 0.6.1
30
+ version: "0"
33
31
  type: :runtime
34
32
  version_requirements: *id001
35
- description:
36
- email: dwilkie@gmail.com
33
+ description: A ruby library for handling paypal api's including IPNs
34
+ email:
35
+ - dwilkie@gmail.com
37
36
  executables: []
38
37
 
39
38
  extensions: []
40
39
 
41
- extra_rdoc_files:
42
- - README.markdown
40
+ extra_rdoc_files: []
41
+
43
42
  files:
43
+ - .gitignore
44
+ - Gemfile
44
45
  - MIT-LICENSE
45
46
  - README.markdown
46
47
  - Rakefile
47
- - VERSION
48
48
  - lib/generators/paypal/initializer/USAGE
49
49
  - lib/generators/paypal/initializer/initializer_generator.rb
50
50
  - lib/generators/paypal/initializer/templates/paypal.rb
51
51
  - lib/paypal.rb
52
+ - lib/paypal/authentication.rb
52
53
  - lib/paypal/ipn/ipn.rb
53
54
  - lib/paypal/ipn/types/masspay.rb
54
55
  - lib/paypal/ipn/variables/buyer.rb
55
56
  - lib/paypal/ipn/variables/item.rb
56
57
  - lib/paypal/masspay.rb
57
- - paypal.gemspec
58
+ - lib/paypal/permissions.rb
59
+ - lib/paypal/version.rb
60
+ - paypal-ipn.gemspec
58
61
  has_rdoc: true
59
- homepage: http://github.com/dwilkie/paypal
62
+ homepage: https://github.com/dwilkie/paypal
60
63
  licenses: []
61
64
 
62
65
  post_install_message:
63
- rdoc_options:
64
- - --charset=UTF-8
66
+ rdoc_options: []
67
+
65
68
  require_paths:
66
69
  - lib
67
70
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -82,10 +85,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
85
  version: "0"
83
86
  requirements: []
84
87
 
85
- rubyforge_project:
88
+ rubyforge_project: paypal
86
89
  rubygems_version: 1.3.7
87
90
  signing_key:
88
91
  specification_version: 3
89
- summary: Another ruby wrapper for Paypal
92
+ summary: More than just IPNs
90
93
  test_files: []
91
94
 
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.1
@@ -1,52 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{paypal}
8
- s.version = "0.0.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["David Wilkie"]
12
- s.date = %q{2010-09-24}
13
- s.email = %q{dwilkie@gmail.com}
14
- s.extra_rdoc_files = [
15
- "README.markdown"
16
- ]
17
- s.files = [
18
- "MIT-LICENSE",
19
- "README.markdown",
20
- "Rakefile",
21
- "VERSION",
22
- "lib/generators/paypal/initializer/USAGE",
23
- "lib/generators/paypal/initializer/initializer_generator.rb",
24
- "lib/generators/paypal/initializer/templates/paypal.rb",
25
- "lib/paypal.rb",
26
- "lib/paypal/ipn/ipn.rb",
27
- "lib/paypal/ipn/types/masspay.rb",
28
- "lib/paypal/ipn/variables/buyer.rb",
29
- "lib/paypal/ipn/variables/item.rb",
30
- "lib/paypal/masspay.rb",
31
- "paypal.gemspec"
32
- ]
33
- s.homepage = %q{http://github.com/dwilkie/paypal}
34
- s.rdoc_options = ["--charset=UTF-8"]
35
- s.require_paths = ["lib"]
36
- s.rubygems_version = %q{1.3.7}
37
- s.summary = %q{Another ruby wrapper for Paypal}
38
-
39
- if s.respond_to? :specification_version then
40
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
- s.specification_version = 3
42
-
43
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
- s.add_runtime_dependency(%q<httparty>, [">= 0.6.1"])
45
- else
46
- s.add_dependency(%q<httparty>, [">= 0.6.1"])
47
- end
48
- else
49
- s.add_dependency(%q<httparty>, [">= 0.6.1"])
50
- end
51
- end
52
-