paypal-ipn 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/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2010 David Wilkie
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.markdown ADDED
@@ -0,0 +1,113 @@
1
+ # paypal
2
+ A simple ruby wrapper for paypal.
3
+
4
+ ## Features
5
+ Currently paypal supports the following:
6
+
7
+ * Verifying Paypal IPN's
8
+ * MassPay Requests
9
+
10
+ ## Configuration
11
+ Paypal.setup do |config|
12
+ config.environment = "sandbox" # replace with "live" in production
13
+ config.api_username = "Replace me with your api username"
14
+ config.api_password = "Replace me with your api password"
15
+ config.api_signature = "Replace me with your api signature"
16
+ end
17
+
18
+ ## Usage
19
+ ### IPN Modules
20
+ #### Paypal::Ipn
21
+ class PaypalIpn
22
+ include Paypal::Ipn
23
+ attr_accessor :params
24
+ end
25
+ Note: Your class must respond to `params` and return a hash of paypal ipn parameters
26
+
27
+ ##### Public methods
28
+ * `payment_completed?`
29
+ * `payment_status`
30
+ * `txn_id`
31
+
32
+ ##### Private methods
33
+ * `verify` Verifies the IPN with paypal and returns true or false
34
+ * `receiver_email`
35
+ * `self.txn_type(params)`
36
+ * `self.masspay_transaction?(params)`
37
+
38
+ #### Paypal::Ipn::Buyer
39
+ class BuyerPaypalIpn
40
+ include Paypal::Ipn::Buyer
41
+ attr_accessor :params
42
+ end
43
+
44
+ ##### Public methods
45
+ * `customer_address` Convienence method. e.g.
46
+ John Smith,
47
+ 5 Some Street,
48
+ Some City,
49
+ Some State,
50
+ Australia 1234
51
+ * `customer_address_name`
52
+ * `customer_address_street`
53
+ * `customer_address_city`
54
+ * `customer_address_state`
55
+ * `customer_address_zip`
56
+ * `customer_address_country`
57
+
58
+ #### Paypal::Ipn::Item
59
+ class ItemPaypalIpn
60
+ include Paypal::Ipn::Item
61
+ attr_accessor :params
62
+ end
63
+
64
+ ##### Public methods
65
+ * `item_name(index = nil)` If index is supplied it will return item_name#index otherwise simply item_name
66
+ * `item_number(index = nil)`
67
+ * `item_quantity(index = nil)`
68
+ * `number_of_cart_items`
69
+
70
+ #### Paypal::Ipn::Masspay
71
+ class MasspayPaypalIpn
72
+ include Paypal::Ipn::Masspay
73
+ attr_accessor :params
74
+ end
75
+ Note: Currently Masspay IPN's only support a single transaction
76
+
77
+ ##### Public methods
78
+ * `payment_status` Returns the payment status for the 1st transaction
79
+ * `txn_id` Returns the transaction id for the 1st transaction
80
+ * `payment_unclaimed?` Returns whether the payment status for the 1st transaction was unclaimed or not
81
+
82
+ ##### Private methods
83
+ * `unique_id` Returns the unique_id for the 1st transaction
84
+
85
+ ### Masspay
86
+ class Masspay
87
+ include Paypal::Masspay
88
+ attr_accessor :payment_response
89
+ end
90
+ Note: Your class must respond to `payment_response` and return the payment response as a hash
91
+
92
+ ##### Public methods
93
+ * `successful_payment?` Returns whether the masspay request was successful or not. Note: This only tells you if the request was successful or not. You should wait for an IPN to verify the receiver has been paid.
94
+
95
+ ##### Private methods
96
+ * `masspay(payer_email, receiver_email, amount, currency, note, unique_id)` Sends a mass pay request from *payer_email* to *receiver_email* for *amount* in *currency*. The *note* will appear on the receivers paypal account and the *unique_id* will be passed back in the Paypal IPN. Returns the response from paypal.
97
+
98
+ * `payment_error_type` Returns *:unauthorized* or *:insufficient_funds* for these types of errors otherwise returns *:unknown*
99
+
100
+ * `payment_error_message` Returns the paypal long error message
101
+
102
+ Note: Currently Masspay payments only support a single recipient
103
+
104
+ ## Rails
105
+ `rails g paypal:initializer`
106
+ Generates a stub initializer under config/initializers
107
+
108
+ ## Installation
109
+
110
+ gem install paypal
111
+
112
+ Copyright (c) 2010 David Wilkie, released under the MIT license
113
+
data/Rakefile ADDED
@@ -0,0 +1,39 @@
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
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,6 @@
1
+ Description:
2
+ Creates an initializer under config/initializers
3
+
4
+ Example:
5
+ rails g paypal:initializer
6
+
@@ -0,0 +1,14 @@
1
+ require 'rails/generators'
2
+ module Paypal
3
+ class InitializerGenerator < Rails::Generators::Base
4
+
5
+ def self.source_root
6
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
7
+ end
8
+
9
+ def copy_conversation_file
10
+ copy_file "paypal.rb", "config/initializers/paypal.rb"
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,7 @@
1
+ Paypal.setup do |config|
2
+ config.environment = Rails.env.production? ? "live" : "sandbox"
3
+ config.api_username = "Replace me with your api username"
4
+ config.api_password = "Replace me with your api password"
5
+ config.api_signature = "Replace me with your api signature"
6
+ end
7
+
@@ -0,0 +1,61 @@
1
+ module Paypal
2
+ module Ipn
3
+ include HTTParty
4
+
5
+ LIVE_POSTBACK_URI = "https://www.paypal.com/cgi-bin/webscr"
6
+ SANDBOX_POSTBACK_URI = "https://www.sandbox.paypal.com/cgi-bin/webscr"
7
+
8
+ def self.included(base)
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ def self.postback_uri
13
+ Paypal.environment == "live" ?
14
+ LIVE_POSTBACK_URI :
15
+ SANDBOX_POSTBACK_URI
16
+ end
17
+
18
+ def self.verify(params)
19
+ request_uri = URI.parse(postback_uri)
20
+ request_uri.scheme = "https" # force https
21
+ self.post(
22
+ request_uri.to_s,
23
+ :body => params.merge("cmd"=>"_notify-validate")
24
+ ).body == "VERIFIED"
25
+ end
26
+
27
+ def payment_status
28
+ params["payment_status"] if params
29
+ end
30
+
31
+ def payment_completed?
32
+ payment_status == "Completed"
33
+ end
34
+
35
+ def txn_id
36
+ params["txn_id"] if params
37
+ end
38
+ alias_method :transaction_id, :txn_id
39
+
40
+ private
41
+ def verify
42
+ Paypal::Ipn.verify(params)
43
+ end
44
+
45
+ def receiver_email
46
+ params["receiver_email"]
47
+ end
48
+
49
+ module ClassMethods
50
+ private
51
+ def txn_type(params)
52
+ params["txn_type"]
53
+ end
54
+
55
+ def masspay_transaction?(params)
56
+ txn_type(params) == "masspay"
57
+ end
58
+ end
59
+ end
60
+ end
61
+
@@ -0,0 +1,24 @@
1
+ module Paypal
2
+ module Ipn
3
+ module Masspay
4
+ def payment_status
5
+ params["status_1"] if params
6
+ end
7
+
8
+ def payment_unclaimed?
9
+ payment_status == "Unclaimed"
10
+ end
11
+
12
+ def txn_id
13
+ params["masspay_txn_id_1"] if params
14
+ end
15
+ alias_method :transaction_id, :txn_id
16
+
17
+ private
18
+ def unique_id
19
+ params["unique_id_1"]
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,40 @@
1
+ module Paypal
2
+ module Ipn
3
+ module Buyer
4
+ def customer_address(delimeter = ",\n")
5
+ [
6
+ customer_address_name,
7
+ customer_address_street,
8
+ customer_address_city,
9
+ customer_address_state,
10
+ customer_address_country + " " + customer_address_zip,
11
+ ].join(delimeter)
12
+ end
13
+
14
+ def customer_address_name
15
+ self.params["address_name"].to_s
16
+ end
17
+
18
+ def customer_address_street
19
+ self.params["address_street"].to_s
20
+ end
21
+
22
+ def customer_address_city
23
+ self.params["address_city"].to_s
24
+ end
25
+
26
+ def customer_address_state
27
+ self.params["address_state"].to_s
28
+ end
29
+
30
+ def customer_address_zip
31
+ self.params["address_zip"].to_s
32
+ end
33
+
34
+ def customer_address_country
35
+ self.params["address_country"].to_s
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,31 @@
1
+ module Paypal
2
+ module Ipn
3
+ module Item
4
+ def item_name(index = nil)
5
+ item_attribute_value("item_name", index)
6
+ end
7
+
8
+ def item_quantity(index = nil)
9
+ item_attribute_value("quantity", index).to_i
10
+ end
11
+
12
+ def item_number(index = nil)
13
+ item_attribute_value("item_number", index).to_s
14
+ end
15
+
16
+ def number_of_cart_items
17
+ num_cart_items = params["num_cart_items"] || 1
18
+ num_cart_items.to_i
19
+ end
20
+
21
+ private
22
+ def item_attribute_value(key, index = nil)
23
+ non_indexed_value = params[key]
24
+ index && params["num_cart_items"] ?
25
+ params["#{key}#{index + 1}"]
26
+ : non_indexed_value
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,58 @@
1
+ module Paypal
2
+ module Masspay
3
+ include HTTParty
4
+
5
+ def self.masspay(payer_email, receiver_email, amount, currency, note, unique_id)
6
+ request_uri = URI.parse(Paypal.nvp_uri)
7
+ request_uri.scheme = "https" # force https
8
+
9
+ body = {
10
+ "METHOD" => "MassPay",
11
+ "VERSION" => "2.3",
12
+ "CURRENCYCODE" => currency,
13
+ "SUBJECT" => payer_email,
14
+ "USER" => Paypal.api_username,
15
+ "PWD" => Paypal.api_password,
16
+ "SIGNATURE" => Paypal.api_signature,
17
+ "RECEIVERTYPE" => "EmailAddress",
18
+ "L_EMAIL0" => receiver_email,
19
+ "L_AMT0" => amount,
20
+ "L_UNIQUEID0" => unique_id,
21
+ "L_NOTE0" => note
22
+ }
23
+ self.post(request_uri.to_s, :body => body).body
24
+ end
25
+
26
+ def successful_payment?
27
+ payment_response["ACK"] == "Success"
28
+ end
29
+
30
+ private
31
+ def masspay(payer_email, receiver_email, amount, currency, note, unique_id)
32
+ Paypal::Masspay.masspay(
33
+ payer_email,
34
+ receiver_email,
35
+ amount,
36
+ currency,
37
+ note,
38
+ unique_id
39
+ )
40
+ end
41
+
42
+ def payment_error_type
43
+ case payment_response["L_ERRORCODE0"]
44
+ when "10002" || "10007"
45
+ :unauthorized
46
+ when "10321"
47
+ :insufficient_funds
48
+ else
49
+ :unknown
50
+ end
51
+ end
52
+
53
+ def payment_error_message
54
+ payment_response["L_LONGMESSAGE0"]
55
+ end
56
+ end
57
+ end
58
+
data/lib/paypal.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'paypal/ipn/ipn'
2
+ require 'paypal/ipn/types/masspay'
3
+ require 'paypal/ipn/variables/buyer'
4
+ require 'paypal/ipn/variables/item'
5
+ require 'paypal/masspay'
6
+
7
+ module Paypal
8
+
9
+ LIVE_NVP_URI = "https://api-3t.paypal.com/nvp"
10
+ SANDBOX_NVP_URI = "https://api-3t.sandbox.paypal.com/nvp"
11
+
12
+ mattr_accessor :environment,
13
+ :api_username,
14
+ :api_password,
15
+ :api_signature
16
+
17
+ # Default way to setup Paypal. Run rails generate paypal_install to create
18
+ # a fresh initializer with all configuration values.
19
+ def self.setup
20
+ yield self
21
+ end
22
+
23
+ def self.nvp_uri
24
+ environment == "live" ?
25
+ LIVE_NVP_URI :
26
+ SANDBOX_NVP_URI
27
+ end
28
+ end
29
+
data/paypal.gemspec ADDED
@@ -0,0 +1,52 @@
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
+
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paypal-ipn
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - David Wilkie
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-09-24 00:00:00 +07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: httparty
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 6
31
+ - 1
32
+ version: 0.6.1
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description:
36
+ email: dwilkie@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.markdown
43
+ files:
44
+ - MIT-LICENSE
45
+ - README.markdown
46
+ - Rakefile
47
+ - VERSION
48
+ - lib/generators/paypal/initializer/USAGE
49
+ - lib/generators/paypal/initializer/initializer_generator.rb
50
+ - lib/generators/paypal/initializer/templates/paypal.rb
51
+ - lib/paypal.rb
52
+ - lib/paypal/ipn/ipn.rb
53
+ - lib/paypal/ipn/types/masspay.rb
54
+ - lib/paypal/ipn/variables/buyer.rb
55
+ - lib/paypal/ipn/variables/item.rb
56
+ - lib/paypal/masspay.rb
57
+ - paypal.gemspec
58
+ has_rdoc: true
59
+ homepage: http://github.com/dwilkie/paypal
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --charset=UTF-8
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.7
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Another ruby wrapper for Paypal
90
+ test_files: []
91
+