lottay-paypal_adaptive 0.0.5

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,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ config
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Tommy Chheng
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.
@@ -0,0 +1,90 @@
1
+ # paypal_adaptive
2
+ This gem is a lightweight wrapper for the paypal adaptive payments API.
3
+
4
+ This is very much a work in progress! Use at your own risk or submit bug fixes :)
5
+
6
+ Before you need start, read the API manual https://www.x.com/docs/DOC-1531 and check out the forums on http://x.com
7
+ It'll be invaluable for parameters and error messages. The gem keeps the request/response as hashes so you will have to
8
+ read the manual to make the proper calls. I made a few test cases for further examples at http://github.com/tc/paypal_adaptive/tree/master/test/
9
+
10
+
11
+ ## HOWTO
12
+ Create paypal_adaptive.yml to your config folder:
13
+ development:
14
+ environment: "sandbox"
15
+ username: "sandbox_username"
16
+ password: "sandbox_password"
17
+ signature: "sandbox_signature"
18
+ application_id: "sandbox_app_id"
19
+
20
+ test:
21
+ environment: "sandbox"
22
+ username: "sandbox_username"
23
+ password: "sandbox_password"
24
+ signature: "sandbox_signature"
25
+ application_id: "sandbox_app_id"
26
+
27
+ production:
28
+ environment: "production"
29
+ username: "my_production_username"
30
+ password: "my_production_password"
31
+ signature: "my_production_signature"
32
+ application_id: "my_production_app_id"
33
+
34
+ Make the payment request:
35
+
36
+ pay_request = PaypalAdaptive::Request.new
37
+
38
+ data = {
39
+ "returnUrl" => "http://testserver.com/payments/completed_payment_request",
40
+ "requestEnvelope" => {"errorLanguage" => "en_US"},
41
+ "currencyCode"=>"USD",
42
+ "receiverList"=>{"receiver"=>[{"email"=>"testpp_1261697850_per@nextsprocket.com", "amount"=>"10.00"}]},
43
+ "cancelUrl"=>"http://testserver.com/payments/canceled_payment_request",
44
+ "actionType"=>"PAY",
45
+ "ipnNotificationUrl"=>"http://testserver.com/payments/ipn_notification"
46
+ }
47
+
48
+ pay_response = pay_request.pay(data)
49
+
50
+ if pay_response.success?
51
+ redirect_to pp_response.approve_paypal_payment_url
52
+ else
53
+ puts pay_response.errors.first['message']
54
+ redirect_to failed_payment_url
55
+ end
56
+
57
+ ---
58
+ Once the user goes to pp_response.approve_paypal_payment_url, they will be prompted to login to Paypal for payment.
59
+
60
+ Upon payment completion page, they will be redirected to http://testserver.com/payments/completed_payment_request.
61
+
62
+ They can also click cancel to go to http://testserver.com/payments/canceled_payment_request
63
+
64
+ The actual payment details will be sent to your server via "ipnNotificationUrl"
65
+ You have to create a listener to receive POST messages from paypal. I added a Rails metal template in the templates folder which handles the callback.
66
+
67
+ Additionally, you can make calls to Paypal Adaptive's other APIs:
68
+ payment_details, preapproval, preapproval_details, cancel_preapproval, convert_currency, refund
69
+
70
+ Input is just a Hash just like the pay method. Refer to the Paypal manual for more details.
71
+
72
+ ## Changelog
73
+ 0.0.5
74
+ Added Preapproval preapproval_paypal_payment_url along with test case.
75
+
76
+ 0.0.4
77
+ Preapproval now returns a PaypalAdaptive::Response class. Added preapproval test cases.
78
+
79
+ 0.0.3
80
+ Renamed PayRequest, PayResponse into Request, Response since other api calls use the class as well.
81
+
82
+ 0.0.2
83
+ Fixed initialized constant warning.
84
+
85
+ 0.0.1
86
+ First release.
87
+
88
+ ## Copyright
89
+
90
+ Copyright (c) 2009 Tommy Chheng. See LICENSE for details.
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "lottay-paypal_adaptive"
9
+ gem.summary = %Q{initial import}
10
+ gem.description = %Q{Lightweight wrapper for Paypal's Adaptive Payments API.}
11
+ gem.email = "rosshale@gmail.com"
12
+ gem.homepage = "http://github.com/lottay/paypal_adaptive"
13
+ gem.authors = ["Tommy Chheng", "Ross Hale"]
14
+ gem.add_development_dependency "json", ">= 0"
15
+ gem.add_development_dependency "jsonschema", ">= 0"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rake/testtask'
24
+ Rake::TestTask.new(:test) do |test|
25
+ test.libs << 'lib' << 'test'
26
+ test.pattern = 'test/**/test_*.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |test|
33
+ test.libs << 'test'
34
+ test.pattern = 'test/**/test_*.rb'
35
+ test.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :test => :check_dependencies
44
+
45
+ task :default => :test
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "lottay-paypal_adaptive #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.5
@@ -0,0 +1,59 @@
1
+ module PaypalAdaptive
2
+ class Config
3
+ PAYPAL_BASE_URL_MAPPING = {
4
+ :production => "https://www.paypal.com",
5
+ :sandbox => "https://www.sandbox.paypal.com",
6
+ :beta_sandbox => "https://www.beta-sandbox.paypal.com"
7
+ } unless defined? PAYPAL_BASE_URL_MAPPING
8
+
9
+ API_BASE_URL_MAPPING = {
10
+ :production => "https://svcs.paypal.com",
11
+ :sandbox => "https://svcs.sandbox.paypal.com",
12
+ :beta_sandbox => "https://svcs.beta-sandbox.paypal.com"
13
+ } unless defined? API_BASE_URL_MAPPING
14
+
15
+ attr_accessor :config_filepath, :paypal_base_url, :api_base_url, :headers
16
+
17
+ def initialize(env=nil)
18
+ if env
19
+ #non-rails env
20
+ @config_filepath = "../config/paypal_adaptive.yml"
21
+ load(env)
22
+ else
23
+ @config_filepath = File.join(Rails.root, "config/paypal_adaptive.yml")
24
+ load(Rails.env)
25
+ end
26
+ end
27
+
28
+ def load(rails_env)
29
+ config= YAML.load_file(@config_filepath)[rails_env]
30
+
31
+ if config["retain_requests_for_test"] == true
32
+ @retain_requests_for_test = true
33
+ else
34
+ pp_env = config['environment'].to_sym
35
+
36
+ @paypal_base_url = PAYPAL_BASE_URL_MAPPING[pp_env]
37
+ @api_base_url = API_BASE_URL_MAPPING[pp_env]
38
+ @headers = {
39
+ "X-PAYPAL-SECURITY-USERID" => config['username'],
40
+ "X-PAYPAL-SECURITY-PASSWORD" => config['password'],
41
+ "X-PAYPAL-SECURITY-SIGNATURE" => config['signature'],
42
+ "X-PAYPAL-APPLICATION-ID" => config['application_id'],
43
+ "X-PAYPAL-REQUEST-DATA-FORMAT" => "JSON",
44
+ "X-PAYPAL-RESPONSE-DATA-FORMAT" => "JSON",
45
+ "X-PAYPAL-DEVICE-IPADDRESS" => "0.0.0.0"
46
+ }
47
+
48
+ if config['environment'] == 'sandbox'
49
+ @headers.merge!("X-PAYPAL-SANDBOX-EMAIL-ADDRESS" => "andy@lottay.com")
50
+ end
51
+ end
52
+ end
53
+
54
+ def retain_requests_for_test?
55
+ !!@retain_requests_for_test
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,32 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'json'
4
+ require 'config'
5
+
6
+ module PaypalAdaptive
7
+ class IpnNotification
8
+
9
+ def initialize(env=nil)
10
+ @env = env
11
+ @@config ||= PaypalAdaptive::Config.new(@env)
12
+ @@paypal_base_url ||= @@config.paypal_base_url
13
+ end
14
+
15
+ def send_back(data)
16
+ data = "cmd=_notify-validate&#{data}"
17
+ url = URI.parse @@paypal_base_url
18
+ http = Net::HTTP.new(url.host, 443)
19
+ http.use_ssl = (url.scheme == 'https')
20
+
21
+ path = "#{@@paypal_base_url}/cgi-bin/webscr"
22
+ resp, response_data = http.post(path, data)
23
+
24
+ @verified = response_data == "VERIFIED"
25
+ end
26
+
27
+ def verified?
28
+ @verified
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ {"description":"Paypal PayRequest API",
2
+ "type":"object",
3
+ "properties":
4
+ {
5
+ "actionType": {"type":"string", "options":[{"value":"PAY", "label":"PAY"}]},
6
+ "cancelUrl": {"type":"string"},
7
+ "clientDetails": {"type":"object", "optional": true},
8
+ "currencyCode": {"type":"string"},
9
+ "feesPayer": {"type":"string", "optional":true,
10
+ "options":[
11
+ {"value":"SENDER", "label":"SENDER"},
12
+ {"value":"PRIMARYRECEIVER", "label":"PRIMARYRECEIVER"},
13
+ {"value":"EACHRECEIVER", "label":"EACHRECEIVER"},
14
+ {"value":"SECONDARYONLY", "label":"SECONDARYONLY"}
15
+ ]},
16
+ "fundingConstraint": {"type":"object", "optional": true},
17
+ "ipnNotificationUrl": {"type":"string", "optional": true},
18
+ "memo": {"type":"string", "optional": true},
19
+ "pin": {"type":"string", "optional": true},
20
+ "preapprovalKey": {"type":"string", "optional": true},
21
+ "receiverList": {
22
+ "type":"object", "properties":{
23
+ "receiver":{
24
+ "type":"array",
25
+ "items":{
26
+ "email":{"type":"string"},
27
+ "amount":{"type":"string"},
28
+ "primary":{"type":"string","optional": true}}
29
+ }
30
+ }
31
+ },
32
+
33
+ "requestEnvelope": {"type":"object", "properties":{"errorLanguage":{"type":"string"}}},
34
+ "returnUrl": {"type":"string"},
35
+ "reverseAllParallelPaymentsOnError": {"type":"boolean", "optional": true},
36
+ "senderEmail": {"type":"string", "optional": true},
37
+ "trackingId": {"type":"string", "optional": true}
38
+ }
39
+ }
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "config"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "request"))
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "response"))
4
+ require File.expand_path(File.join(File.dirname(__FILE__), "ipn_notification"))
@@ -0,0 +1,92 @@
1
+ require 'json'
2
+ require 'config'
3
+ require 'net/http'
4
+ require 'net/https'
5
+ require 'response'
6
+
7
+ module PaypalAdaptive
8
+ class NoDataError < Exception
9
+ end
10
+
11
+ class Request
12
+ def initialize(env = nil)
13
+ @env = env
14
+ @@config ||= PaypalAdaptive::Config.new(@env)
15
+ @@api_base_url ||= @@config.api_base_url
16
+ @@headers ||= @@config.headers
17
+ end
18
+
19
+ def validate
20
+ #TODO the receiverList field not validating properly
21
+
22
+ # @@schema_filepath = "../lib/pay_request_schema.json"
23
+ # @@schema = File.open(@@schema_filepath, "rb"){|f| JSON.parse(f.read)}
24
+ # see page 42 of PP Adaptive Payments PDF for explanation of all fields.
25
+ #JSON::Schema.validate(@data, @@schema)
26
+ end
27
+
28
+ def pay(data)
29
+ raise NoDataError unless data
30
+
31
+ response_data = call_api(data, "/AdaptivePayments/Pay")
32
+ PaypalAdaptive::Response.new(response_data, @env)
33
+ end
34
+
35
+ def payment_details(data)
36
+ raise NoDataError unless data
37
+
38
+ call_api(data, "/AdaptivePayments/PaymentDetails")
39
+ end
40
+
41
+ def preapproval(data)
42
+ raise NoDataError unless data
43
+
44
+ response_data = call_api(data, "/AdaptivePayments/Preapproval")
45
+ PaypalAdaptive::Response.new(response_data, @env)
46
+ end
47
+
48
+ def preapproval_details(data)
49
+ raise NoDataError unless data
50
+
51
+ call_api(data, "/AdaptivePayments/PreapprovalDetails")
52
+ end
53
+
54
+ def cancel_preapproval(data)
55
+ raise NoDataError unless data
56
+
57
+ call_api(data, "/AdaptivePayments/CancelPreapproval")
58
+ end
59
+
60
+ def convert_currency(data)
61
+ raise NoDataError unless data
62
+
63
+ call_api(data, "/AdaptivePayments/ConvertCurrency")
64
+ end
65
+
66
+ def refund(data)
67
+ raise NoDataError unless data
68
+
69
+ call_api(data, "/AdaptivePayments/Refund")
70
+ end
71
+
72
+ def create_account(data)
73
+ raise NoDataError unless data
74
+
75
+ response_data = call_api(data, "/AdaptiveAccounts/CreateAccount")
76
+ PaypalAdaptive::Response.new(response_data, @env)
77
+ end
78
+
79
+ def call_api(data, path)
80
+ #hack fix: JSON.unparse doesn't work in Rails 2.3.5; only {}.to_json does..
81
+ api_request_data = JSON.unparse(data) rescue data.to_json
82
+ url = URI.parse @@api_base_url
83
+ http = Net::HTTP.new(url.host, 443)
84
+ http.use_ssl = (url.scheme == 'https')
85
+
86
+ resp, response_data = http.post(path, api_request_data, @@headers)
87
+
88
+ JSON.parse(response_data)
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,38 @@
1
+ module PaypalAdaptive
2
+ class Response < Hash
3
+ def initialize(response, env=nil)
4
+ @@config ||= PaypalAdaptive::Config.new(env)
5
+ @@paypal_base_url ||= @@config.paypal_base_url
6
+
7
+ self.merge!(response)
8
+ end
9
+
10
+ def success?
11
+ self['responseEnvelope']['ack'] == 'Success'
12
+ end
13
+
14
+ def errors
15
+ if success?
16
+ return []
17
+ else
18
+ self['error']
19
+ end
20
+ end
21
+
22
+ def error_message
23
+ if success?
24
+ return nil
25
+ else
26
+ self['error'].first['message'] rescue nil
27
+ end
28
+ end
29
+
30
+ def approve_paypal_payment_url
31
+ self['payKey'].nil? ? nil : "#{@@paypal_base_url}/webscr?cmd=_ap-payment&paykey=#{self['payKey']}"
32
+ end
33
+
34
+ def preapproval_paypal_payment_url
35
+ self['preapprovalKey'].nil? ? nil : "#{@@paypal_base_url}/webscr?cmd=_ap-preapproval&preapprovalkey=#{self['preapprovalKey']}"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,77 @@
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_adaptive}
8
+ s.version = "0.0.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tommy Chheng"]
12
+ s.date = %q{2009-12-29}
13
+ s.description = %q{Lightweight wrapper for Paypal's Adaptive Payments API.}
14
+ s.email = %q{tommy.chheng@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.markdown",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "config/paypal_adaptive.yml",
26
+ "lib/config.rb",
27
+ "lib/ipn_notification.rb",
28
+ "lib/pay_request_schema.json",
29
+ "lib/paypal_adaptive.rb",
30
+ "lib/request.rb",
31
+ "lib/response.rb",
32
+ "paypal_adaptive.gemspec",
33
+ "templates/paypal_ipn.rb",
34
+ "test/data/invalid_chain_pay_request.json",
35
+ "test/data/invalid_parallel_pay_request.json",
36
+ "test/data/invalid_preapproval.json",
37
+ "test/data/invalid_simple_pay_request_1.json",
38
+ "test/data/valid_chain_pay_request.json",
39
+ "test/data/valid_parallel_pay_request.json",
40
+ "test/data/valid_preapproval.json",
41
+ "test/data/valid_simple_pay_request_1.json",
42
+ "test/helper.rb",
43
+ "test/pay_request_schema_test.rb",
44
+ "test/pay_request_test.rb",
45
+ "test/payment_details_test.rb",
46
+ "test/preapproval_test.rb"
47
+ ]
48
+ s.homepage = %q{http://github.com/tc/paypal_adaptive}
49
+ s.rdoc_options = ["--charset=UTF-8"]
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = %q{1.3.5}
52
+ s.summary = %q{initial import}
53
+ s.test_files = [
54
+ "test/helper.rb",
55
+ "test/pay_request_schema_test.rb",
56
+ "test/pay_request_test.rb",
57
+ "test/payment_details_test.rb",
58
+ "test/preapproval_test.rb"
59
+ ]
60
+
61
+ if s.respond_to? :specification_version then
62
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
63
+ s.specification_version = 3
64
+
65
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
66
+ s.add_development_dependency(%q<json>, [">= 0"])
67
+ s.add_development_dependency(%q<jsonschema>, [">= 0"])
68
+ else
69
+ s.add_dependency(%q<json>, [">= 0"])
70
+ s.add_dependency(%q<jsonschema>, [">= 0"])
71
+ end
72
+ else
73
+ s.add_dependency(%q<json>, [">= 0"])
74
+ s.add_dependency(%q<jsonschema>, [">= 0"])
75
+ end
76
+ end
77
+
@@ -0,0 +1,25 @@
1
+ # Allow the metal piece to run in isolation
2
+ require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
3
+
4
+ class PaypalIpn
5
+ def self.call(env)
6
+ if env["PATH_INFO"] =~ /^\/paypal_ipn/
7
+ request = Rack::Request.new(env)
8
+ params = request.params
9
+
10
+ ipn = PaypalAdaptive::IpnNotification.new
11
+ ipn.send_back(env['QUERY_STRING'])
12
+ if ipn.verified?
13
+ #mark transaction as completed in your DB
14
+ output = "Verified."
15
+ else
16
+ output = "Not Verified."
17
+ end
18
+
19
+ [200, {"Content-Type" => "text/html"}, [output]]
20
+ else
21
+ [404, {"Content-Type" => "text/html"}, ["Not Found"]]
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,34 @@
1
+ require 'helper'
2
+ require '../lib/request'
3
+
4
+ class CreateAccountTest < Test::Unit::TestCase
5
+ def setup
6
+ @account_request = PaypalAdaptive::Request.new("test")
7
+ end
8
+
9
+ def test_valid_create_account
10
+ data_filepath = "../test/data/valid_create_account_request.json"
11
+
12
+ data = read_json_file(data_filepath)
13
+
14
+ data["emailAddress"] = "joetester_#{Time.now.to_i}@example.com"
15
+
16
+ pp_response = @account_request.create_account(data)
17
+
18
+ assert pp_response.success?
19
+ assert pp_response["redirectURL"]
20
+ end
21
+
22
+ def test_create_account_email_address_already_an_account
23
+ data_filepath = "../test/data/valid_create_account_request.json"
24
+
25
+ data = read_json_file(data_filepath)
26
+
27
+ data["emailAddress"] = "joetester@example.com"
28
+ pp_response = @account_request.create_account(data)
29
+
30
+ assert !pp_response.success?
31
+ assert_equal "An account already exists for the specified email address", pp_response["error"].first["message"]
32
+ end
33
+
34
+ end
@@ -0,0 +1,13 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "receiverList":{"receiver":[
6
+ {"email":"testpp_1261697850_per@nextsprocket.com", "amount":"50.00", "primary": "true"},
7
+ {"email":"sender_1261713739_per@nextsprocket.com", "amount":"100.00", "primary": "false"},
8
+ {"email":"ppsell_1261697921_biz@nextsprocket.com", "amount":"100.00", "primary": "false"}
9
+ ]},
10
+ "cancelUrl":"http://127.0.0.1:3000/payments/cancelled_payment",
11
+ "actionType":"PAY"
12
+ }
13
+
@@ -0,0 +1,13 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "receiverList":{"receiver":[
6
+ {"email":"dummy@account.com", "amount":"100.00"},
7
+ {"email":"dummy@account.com", "amount":"50.00"},
8
+ {"email":"dummy@account.com", "amount":"50.00"}
9
+ ]},
10
+ "cancelUrl":"http://127.0.0.1:3000/payments/cancelled_payment",
11
+ "actionType":"PAY"
12
+ }
13
+
@@ -0,0 +1,12 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment_request",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "cancelUrl":"http://127.0.0.1:3000/payments/canceled_payment_request",
6
+ "actionType":"PAY",
7
+ "maxTotalAmountOfAllPayments": "1500.00",
8
+ "maxNumberOfPayments":"30",
9
+ "startingDate":"2010-07-13T07sdf00.000Z",
10
+ "endingDate":"2010-12-13T07dfg0000.000Z"
11
+ }
12
+
@@ -0,0 +1,8 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "receiverList":{"receiver":[{"email":"testpp_1261697850_per@nextsprocket.com", "amount":"10.0"}]},
6
+ "cancelUrl":"http://127.0.0.1:3000/payments/canceled_payment",
7
+ "actionType":1
8
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment_request",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "receiverList":{"receiver":[
6
+ {"email":"testpp_1261697850_per@nextsprocket.com", "amount":"100.00", "primary": "true"},
7
+ {"email":"ppsell_1261697921_biz@nextsprocket.com", "amount":"90.00", "primary": "false"}
8
+ ]},
9
+ "cancelUrl":"http://127.0.0.1:3000/payments/canceled_payment_request",
10
+ "actionType":"PAY"
11
+ }
12
+
@@ -0,0 +1,23 @@
1
+ {
2
+ "name":{"firstName":"Joe", "lastName":"Tester"},
3
+ "preferredLanguageCode":"en_US",
4
+ "address": {
5
+ "line1":"1234 Imaginary Ln",
6
+ "line2":"",
7
+ "city":"Ventura",
8
+ "state":"CA",
9
+ "postalCode":"93001",
10
+ "countryCode":"US"
11
+ },
12
+ "accountType":"Personal",
13
+ "citizenshipCountryCode":"US",
14
+ "contactPhoneNumber":"805-555-5555",
15
+ "createAccountWebOptions":{"returnUrl":"http://127.0.0.1:3000/payments/completed_payment_request"},
16
+ "emailAddress":"joetester@example.com",
17
+ "requestEnvelope":{"errorLanguage":"en_US"},
18
+ "currencyCode":"USD",
19
+ "registrationType":"WEB",
20
+ "receiverList":{"receiver":[{"email":"testpp_1261697850_per@nextsprocket.com", "amount":"10.00"}]},
21
+ "cancelUrl":"http://127.0.0.1:3000/payments/canceled_payment_request",
22
+ "notificationURL":"http://127.0.0.1:3000/payments/ipn_notification"
23
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment_request",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "receiverList":{"receiver":[
6
+ {"email":"testpp_1261697850_per@nextsprocket.com", "amount":"100.00"},
7
+ {"email":"sender_1261713739_per@nextsprocket.com", "amount":"50.00"},
8
+ {"email":"ppsell_1261697921_biz@nextsprocket.com", "amount":"50.00"}
9
+ ]},
10
+ "cancelUrl":"http://127.0.0.1:3000/payments/canceled_payment_request",
11
+ "actionType":"PAY",
12
+ "senderEmail": "a@a.com"
13
+ }
14
+
@@ -0,0 +1,11 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment_request",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "cancelUrl":"http://127.0.0.1:3000/payments/canceled_payment_request",
6
+ "maxTotalAmountOfAllPayments": "1500.00",
7
+ "maxNumberOfPayments":"30",
8
+ "startingDate":"2010-07-13T07:00:00.000Z",
9
+ "endingDate":"2010-12-13T07:00:00.000Z"
10
+ }
11
+
@@ -0,0 +1,9 @@
1
+ {
2
+ "returnUrl":"http://127.0.0.1:3000/payments/completed_payment_request",
3
+ "requestEnvelope":{"errorLanguage":"en_US"},
4
+ "currencyCode":"USD",
5
+ "receiverList":{"receiver":[{"email":"testpp_1261697850_per@nextsprocket.com", "amount":"10.00"}]},
6
+ "cancelUrl":"http://127.0.0.1:3000/payments/canceled_payment_request",
7
+ "actionType":"PAY",
8
+ "ipnNotificationUrl":"http://127.0.0.1:3000/payments/ipn_notification"
9
+ }
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'JSON'
3
+ require 'test/unit'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+
8
+ class Test::Unit::TestCase
9
+
10
+ def read_json_file(filepath)
11
+ File.open(filepath, "rb"){|f| JSON.parse(f.read)}
12
+ end
13
+
14
+ end
@@ -0,0 +1,46 @@
1
+ require 'helper'
2
+ require 'json'
3
+ require 'jsonschema'
4
+
5
+ class PayRequestSchemaTest < Test::Unit::TestCase
6
+ def setup
7
+ @schema_filepath = "../lib/pay_request_schema.json"
8
+ @schema = File.open(@schema_filepath, "rb"){|f| JSON.parse(f.read)}
9
+ end
10
+
11
+ def xtest_valid_simple_pay
12
+ data_filepath = "data/valid_simple_pay_request_1.json"
13
+ data = read_json_file(data_filepath)
14
+
15
+ #receiverList not validating correctly, is it due to the schema or jsonschema parsing?
16
+ assert_nothing_raised do
17
+ JSON::Schema.validate(data, @schema)
18
+ end
19
+ end
20
+
21
+ def test_invalid_simple_pay
22
+ data_filepath = "data/invalid_simple_pay_request_1.json"
23
+ data = read_json_file(data_filepath)
24
+
25
+ assert_raise JSON::Schema::ValueError do
26
+ JSON::Schema.validate(data, @schema)
27
+ end
28
+ end
29
+
30
+ def test_valid_chain_pay
31
+ #TODO
32
+ end
33
+
34
+ def test_invalid_chain_pay
35
+ #TODO
36
+ end
37
+
38
+ def test_valid_parallel_pay
39
+ #TODO
40
+ end
41
+
42
+ def test_invalid_parallel_pay
43
+ #TODO
44
+ end
45
+
46
+ end
@@ -0,0 +1,98 @@
1
+ require 'helper'
2
+ require '../lib/request'
3
+
4
+ class PayRequestTest < Test::Unit::TestCase
5
+ def setup
6
+ @pay_request = PaypalAdaptive::Request.new("test")
7
+ end
8
+
9
+ def test_valid_simple_pay
10
+ puts "-------"
11
+ puts "simple"
12
+
13
+ data_filepath = "../test/data/valid_simple_pay_request_1.json"
14
+
15
+ data = read_json_file(data_filepath)
16
+ pp_response = @pay_request.pay(data)
17
+
18
+ puts "redirect url to\n #{pp_response.approve_paypal_payment_url}"
19
+ assert pp_response.success?
20
+ end
21
+
22
+ def test_invalid_simple_pay
23
+ data_filepath = "../test/data/invalid_simple_pay_request_1.json"
24
+
25
+ data = read_json_file(data_filepath)
26
+ pp_response = @pay_request.pay(data)
27
+ puts pp_response.errors
28
+ assert pp_response.success? == false
29
+ end
30
+
31
+ def test_valid_chain_pay
32
+ puts "-------"
33
+ puts "chain"
34
+ data_filepath = "../test/data/valid_chain_pay_request.json"
35
+
36
+ data = read_json_file(data_filepath)
37
+ pp_response = @pay_request.pay(data)
38
+ puts "redirect url to\n #{pp_response.approve_paypal_payment_url}"
39
+
40
+ unless pp_response.success?
41
+ puts pp_response.errors
42
+ end
43
+
44
+ assert pp_response.success?
45
+ end
46
+
47
+ def test_invalid_chain_pay
48
+ data_filepath = "../test/data/invalid_chain_pay_request.json"
49
+
50
+ data = read_json_file(data_filepath)
51
+ pp_response = @pay_request.pay(data)
52
+ puts pp_response.errors
53
+ assert pp_response.success? == false
54
+ end
55
+
56
+ def test_valid_parallel_pay
57
+ puts "-------"
58
+ puts "parallel"
59
+
60
+ data_filepath = "../test/data/valid_chain_pay_request.json"
61
+
62
+ data = read_json_file(data_filepath)
63
+ pp_response = @pay_request.pay(data)
64
+ puts "redirect url to\n #{pp_response.approve_paypal_payment_url}"
65
+ assert pp_response.success?
66
+ end
67
+
68
+ def test_invalid_parallel_pay
69
+ data_filepath = "../test/data/invalid_parallel_pay_request.json"
70
+
71
+ data = read_json_file(data_filepath)
72
+ pp_response = @pay_request.pay(data)
73
+ puts pp_response.errors
74
+ assert pp_response.success? == false
75
+ end
76
+
77
+
78
+ def test_preapproval
79
+ #TODO
80
+ end
81
+
82
+ def test_preapproval_details
83
+ #TODO
84
+ end
85
+
86
+ def test_cancel_preapproval
87
+ #TODO
88
+ end
89
+
90
+ def test_convert_currency
91
+ #TODO
92
+ end
93
+
94
+ def test_refund
95
+ #TODO
96
+ end
97
+
98
+ end
@@ -0,0 +1,31 @@
1
+ require 'helper'
2
+ require '../lib/request'
3
+
4
+ class PaymentDetailsTest < Test::Unit::TestCase
5
+ def setup
6
+ @pay_request = PaypalAdaptive::Request.new("test")
7
+ @payment_details_request = PaypalAdaptive::Request.new("test")
8
+ end
9
+
10
+ def test_payment_details
11
+ puts "-------"
12
+ puts "payment details"
13
+ data_filepath = "../test/data/valid_chain_pay_request.json"
14
+
15
+ data = read_json_file(data_filepath)
16
+ pp_response = @pay_request.pay(data)
17
+ puts "redirect url to\n #{pp_response.approve_paypal_payment_url}"
18
+
19
+ unless pp_response.success?
20
+ puts pp_response.errors
21
+ end
22
+
23
+ assert pp_response.success?
24
+
25
+ data = {"requestEnvelope"=>{"errorLanguage"=>"en_US"}, "payKey" => pp_response['payKey']}
26
+
27
+ response = @payment_details_request.payment_details(data)
28
+ assert_equal 'CREATED', response['status']
29
+ end
30
+
31
+ end
@@ -0,0 +1,38 @@
1
+ require 'helper'
2
+ require '../lib/request'
3
+
4
+ class PreapprovalTest < Test::Unit::TestCase
5
+ def setup
6
+ @preapproval_request = PaypalAdaptive::Request.new("test")
7
+ end
8
+
9
+ def test_preapproval
10
+ puts "-------"
11
+ puts "valid test"
12
+ data_filepath = "../test/data/valid_preapproval.json"
13
+
14
+ data = read_json_file(data_filepath)
15
+ pp_response = @preapproval_request.preapproval(data)
16
+ puts "preapproval code is #{pp_response['preapprovalKey']}"
17
+
18
+ assert pp_response.success?
19
+ assert_not_nil pp_response.preapproval_paypal_payment_url
20
+ assert_not_nil pp_response['preapprovalKey']
21
+ end
22
+
23
+
24
+ def test_invalid_preapproval
25
+ puts "-------"
26
+ puts "invalid"
27
+ data_filepath = "../test/data/invalid_preapproval.json"
28
+
29
+ data = read_json_file(data_filepath)
30
+ pp_response = @preapproval_request.preapproval(data)
31
+ puts "error message is #{pp_response.error_message}"
32
+
33
+ assert pp_response.success? == false
34
+ assert_nil pp_response.preapproval_paypal_payment_url
35
+ assert_nil pp_response['preapprovalKey']
36
+ end
37
+
38
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lottay-paypal_adaptive
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 5
9
+ version: 0.0.5
10
+ platform: ruby
11
+ authors:
12
+ - Tommy Chheng
13
+ - Ross Hale
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-03-08 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: jsonschema
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ type: :development
44
+ version_requirements: *id002
45
+ description: Lightweight wrapper for Paypal's Adaptive Payments API.
46
+ email: rosshale@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - LICENSE
53
+ - README.markdown
54
+ files:
55
+ - .gitignore
56
+ - LICENSE
57
+ - README.markdown
58
+ - Rakefile
59
+ - VERSION
60
+ - config/paypal_adaptive.yml
61
+ - lib/config.rb
62
+ - lib/ipn_notification.rb
63
+ - lib/pay_request_schema.json
64
+ - lib/paypal_adaptive.rb
65
+ - lib/request.rb
66
+ - lib/response.rb
67
+ - paypal_adaptive.gemspec
68
+ - templates/paypal_ipn.rb
69
+ - test/create_account_test.rb
70
+ - test/data/invalid_chain_pay_request.json
71
+ - test/data/invalid_parallel_pay_request.json
72
+ - test/data/invalid_preapproval.json
73
+ - test/data/invalid_simple_pay_request_1.json
74
+ - test/data/valid_chain_pay_request.json
75
+ - test/data/valid_create_account_request.json
76
+ - test/data/valid_parallel_pay_request.json
77
+ - test/data/valid_preapproval.json
78
+ - test/data/valid_simple_pay_request_1.json
79
+ - test/helper.rb
80
+ - test/pay_request_schema_test.rb
81
+ - test/pay_request_test.rb
82
+ - test/payment_details_test.rb
83
+ - test/preapproval_test.rb
84
+ has_rdoc: true
85
+ homepage: http://github.com/lottay/paypal_adaptive
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options:
90
+ - --charset=UTF-8
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ requirements: []
108
+
109
+ rubyforge_project:
110
+ rubygems_version: 1.3.6
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: initial import
114
+ test_files:
115
+ - test/create_account_test.rb
116
+ - test/helper.rb
117
+ - test/pay_request_schema_test.rb
118
+ - test/pay_request_test.rb
119
+ - test/payment_details_test.rb
120
+ - test/preapproval_test.rb