paypal-express 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,9 +1,19 @@
1
1
  = paypal-express
2
2
 
3
- Description goes here.
3
+ Handle PayPal Express Checkout.
4
+ Both instance payment and recurring payment are supported.
5
+
6
+ == Installation
7
+
8
+ gem install paypal-express
9
+
10
+ == Usage
11
+
12
+ See Wiki on Github
13
+ https://github.com/nov/paypal-express/wiki
4
14
 
5
15
  == Note on Patches/Pull Requests
6
-
16
+
7
17
  * Fork the project.
8
18
  * Make your feature addition or bug fix.
9
19
  * Add tests for it. This is important so I don't break it in a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
data/lib/paypal.rb CHANGED
@@ -12,6 +12,14 @@ module Paypal
12
12
  :sandbox => 'https://www.sandbox.paypal.com/cgi-bin/webscr'
13
13
  }
14
14
 
15
+ def self.endpoint
16
+ if sandbox?
17
+ Paypal::ENDPOINT[:sandbox]
18
+ else
19
+ Paypal::ENDPOINT[:production]
20
+ end
21
+ end
22
+
15
23
  def self.log(message, mode = :info)
16
24
  self.logger.send mode, message
17
25
  end
@@ -40,6 +48,7 @@ end
40
48
  require 'paypal/util'
41
49
  require 'paypal/exceptions'
42
50
  require 'paypal/base'
51
+ require 'paypal/ipn'
43
52
  require 'paypal/nvp/request'
44
53
  require 'paypal/nvp/response'
45
54
  require 'paypal/express/request'
@@ -2,12 +2,7 @@ module Paypal
2
2
  module Express
3
3
  class Response < NVP::Response
4
4
  def redirect_uri
5
- endpoint = if Paypal.sandbox?
6
- Paypal::ENDPOINT[:sandbox]
7
- else
8
- Paypal::ENDPOINT[:production]
9
- end
10
- endpoint = URI.parse endpoint
5
+ endpoint = URI.parse Paypal.endpoint
11
6
  endpoint.query = {
12
7
  :cmd => '_express-checkout',
13
8
  :token => self.token
data/lib/paypal/ipn.rb ADDED
@@ -0,0 +1,23 @@
1
+ module Paypal
2
+ module IPN
3
+ def self.endpoint
4
+ _endpoint_ = URI.parse Paypal.endpoint
5
+ _endpoint_.query = {
6
+ :cmd => '_notify-validate'
7
+ }.to_query
8
+ _endpoint_.to_s
9
+ end
10
+
11
+ def self.verify!(raw_post)
12
+ response = RestClient.post(
13
+ endpoint, raw_post
14
+ )
15
+ case response.body
16
+ when 'VERIFIED'
17
+ true
18
+ else
19
+ raise APIError.new(response.body)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,20 +2,23 @@ module Paypal
2
2
  module NVP
3
3
  class Request < Base
4
4
  attr_required :username, :password, :signature
5
- attr_accessor :version, :endpoint
5
+ attr_accessor :version
6
6
 
7
7
  ENDPOINT = {
8
8
  :production => 'https://api-3t.paypal.com/nvp',
9
9
  :sandbox => 'https://api-3t.sandbox.paypal.com/nvp'
10
10
  }
11
11
 
12
- def initialize(attributes = {})
13
- @version = API_VERSION
14
- @endpoint = if Paypal.sandbox?
12
+ def self.endpoint
13
+ if Paypal.sandbox?
15
14
  ENDPOINT[:sandbox]
16
15
  else
17
16
  ENDPOINT[:production]
18
17
  end
18
+ end
19
+
20
+ def initialize(attributes = {})
21
+ @version = API_VERSION
19
22
  super
20
23
  end
21
24
 
@@ -37,7 +40,7 @@ module Paypal
37
40
  private
38
41
 
39
42
  def post(method, params)
40
- RestClient.post(self.endpoint, common_params.merge(params).merge(:METHOD => method))
43
+ RestClient.post(self.class.endpoint, common_params.merge(params).merge(:METHOD => method))
41
44
  end
42
45
 
43
46
  def handle_response
@@ -0,0 +1 @@
1
+ INVALID
@@ -0,0 +1 @@
1
+ VERIFIED
@@ -2,16 +2,22 @@ require 'fakeweb'
2
2
 
3
3
  module FakeResponseHelper
4
4
 
5
- def fake_response(file_path, options = {})
6
- Paypal::NVP::Request::ENDPOINT.each do |env, endpoint|
7
- FakeWeb.register_uri(
8
- :post,
9
- endpoint,
10
- options.merge(
11
- :body => File.read(File.join(File.dirname(__FILE__), '../fake_response', "#{file_path}.txt"))
12
- )
13
- )
5
+ def fake_response(file_path, api = :NVP, options = {})
6
+ endpoint = case api
7
+ when :NVP
8
+ Paypal::NVP::Request.endpoint
9
+ when :IPN
10
+ Paypal::IPN.endpoint
11
+ else
12
+ raise "Non-supported API: #{api}"
14
13
  end
14
+ FakeWeb.register_uri(
15
+ :post,
16
+ endpoint,
17
+ options.merge(
18
+ :body => File.read(File.join(File.dirname(__FILE__), '../fake_response', "#{file_path}.txt"))
19
+ )
20
+ )
15
21
  end
16
22
 
17
23
  def request_to(endpoint, method = :get)
@@ -53,7 +53,7 @@ describe Paypal::Express::Request do
53
53
 
54
54
  describe '.new' do
55
55
  context 'when any required parameters are missing' do
56
- it 'should raise AttrMissing exception' do
56
+ it 'should raise AttrRequired::AttrMissing' do
57
57
  attributes.keys.each do |missing_key|
58
58
  insufficient_attributes = attributes.reject do |key, value|
59
59
  key == missing_key
@@ -1,10 +1,6 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe Paypal::Express::Response do
4
- before do
5
- fake_response 'SetExpressCheckout/success'
6
- end
7
-
8
4
  let :instance do
9
5
  request = Paypal::Express::Request.new(
10
6
  :username => 'nov',
@@ -21,11 +17,13 @@ describe Paypal::Express::Response do
21
17
 
22
18
  describe '#redirect_uri' do
23
19
  it 'should return express-checkout redirect endpoint with token' do
20
+ fake_response 'SetExpressCheckout/success'
24
21
  instance.redirect_uri.should == 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-5YJ90598G69065317'
25
22
  end
26
23
 
27
24
  it 'should support sandbox mode' do
28
25
  sandbox_mode do
26
+ fake_response 'SetExpressCheckout/success'
29
27
  instance.redirect_uri.should == 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-5YJ90598G69065317'
30
28
  end
31
29
  end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paypal::IPN do
4
+ describe '.verify!' do
5
+ context 'when valid' do
6
+ before do
7
+ fake_response 'IPN/valid', :IPN
8
+ end
9
+
10
+ it 'should return true' do
11
+ Paypal::IPN.verify!("raw-post-body").should be_true
12
+ end
13
+ end
14
+
15
+ context 'when invalid' do
16
+ before do
17
+ fake_response 'IPN/invalid', :IPN
18
+ end
19
+
20
+ it 'should raise Paypal::APIError' do
21
+ lambda do
22
+ Paypal::IPN.verify!("raw-post-body")
23
+ end.should raise_error(Paypal::APIError)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -15,7 +15,7 @@ describe Paypal::NVP::Request do
15
15
 
16
16
  describe '.new' do
17
17
  context 'when any required parameters are missing' do
18
- it 'should raise AttrMissing exception' do
18
+ it 'should raise AttrRequired::AttrMissing' do
19
19
  attributes.keys.each do |missing_key|
20
20
  insufficient_attributes = attributes.reject do |key, value|
21
21
  key == missing_key
@@ -37,13 +37,13 @@ describe Paypal::NVP::Request do
37
37
  it 'should setup endpoint and version' do
38
38
  client = Paypal::NVP::Request.new attributes
39
39
  client.version.should == Paypal::API_VERSION
40
- client.endpoint.should == Paypal::NVP::Request::ENDPOINT[:production]
40
+ client.class.endpoint.should == Paypal::NVP::Request::ENDPOINT[:production]
41
41
  end
42
42
 
43
43
  it 'should support sandbox mode' do
44
44
  sandbox_mode do
45
45
  client = Paypal::NVP::Request.new attributes
46
- client.endpoint.should == Paypal::NVP::Request::ENDPOINT[:sandbox]
46
+ client.class.endpoint.should == Paypal::NVP::Request::ENDPOINT[:sandbox]
47
47
  end
48
48
  end
49
49
  end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Paypal::NVP::Response do
4
+ let :request do
5
+ Paypal::Express::Request.new(
6
+ :username => 'nov',
7
+ :password => 'password',
8
+ :signature => 'sig',
9
+ :return_url => 'http://example.com/success',
10
+ :cancel_url => 'http://example.com/cancel'
11
+ )
12
+ end
13
+
14
+ let :payment_request do
15
+ Paypal::Payment::Request.new(
16
+ :amount => 1000,
17
+ :description => 'Instant Payment Request'
18
+ )
19
+ end
20
+
21
+ let :recurring_profile do
22
+ Paypal::Payment::Recurring.new(
23
+ :start_date => Time.utc(2011, 2, 8, 9, 0, 0),
24
+ :description => 'Recurring Profile',
25
+ :billing => {
26
+ :period => :Month,
27
+ :frequency => 1,
28
+ :amount => 1000
29
+ }
30
+ )
31
+ end
32
+
33
+ describe '.new' do
34
+ context 'when non-supported attributes are given' do
35
+ it 'should ignore them and warn' do
36
+ Paypal.logger.should_receive(:warn).with(
37
+ "Ignored Parameter (Paypal::NVP::Response): ignored=Ignore me!"
38
+ )
39
+ Paypal::NVP::Response.new(
40
+ :ignored => 'Ignore me!'
41
+ )
42
+ end
43
+ end
44
+
45
+ context 'when SetExpressCheckout response given' do
46
+ before do
47
+ fake_response 'SetExpressCheckout/success'
48
+ end
49
+
50
+ it 'should handle all attributes' do
51
+ Paypal.logger.should_not_receive(:warn)
52
+ response = request.setup payment_request
53
+ response.token.should == 'EC-5YJ90598G69065317'
54
+ end
55
+ end
56
+
57
+ context 'when GetExpressCheckoutDetails response given' do
58
+ before do
59
+ fake_response 'GetExpressCheckoutDetails/success'
60
+ end
61
+
62
+ it 'should handle all attributes' do
63
+ Paypal.logger.should_not_receive(:warn)
64
+ response = request.details 'token'
65
+ response.payer.identifier.should == 'PRT3TZ6MCBCNC'
66
+ response.payment_responses.size.should == 1
67
+ response.payment_info.size.should == 0
68
+ response.payment_responses.first.should be_instance_of(Paypal::Payment::Response)
69
+ end
70
+ end
71
+
72
+ context 'when DoExpressCheckoutPayment response given' do
73
+ before do
74
+ fake_response 'DoExpressCheckoutPayment/success'
75
+ end
76
+
77
+ it 'should handle all attributes' do
78
+ Paypal.logger.should_not_receive(:warn)
79
+ response = request.checkout! 'token', 'payer_id', payment_request
80
+ response.payment_responses.size.should == 0
81
+ response.payment_info.size.should == 1
82
+ response.payment_info.first.should be_instance_of(Paypal::Payment::Response::Info)
83
+ end
84
+ end
85
+
86
+ context 'when CreateRecurringPaymentsProfile response given' do
87
+ before do
88
+ fake_response 'CreateRecurringPaymentsProfile/success'
89
+ end
90
+
91
+ it 'should handle all attributes' do
92
+ Paypal.logger.should_not_receive(:warn)
93
+ response = request.subscribe! 'token', recurring_profile
94
+ response.recurring.identifier.should == 'I-L8N58XFUCET3'
95
+ end
96
+ end
97
+
98
+ context 'when GetRecurringPaymentsProfileDetails response given' do
99
+ before do
100
+ fake_response 'GetRecurringPaymentsProfileDetails/success'
101
+ end
102
+
103
+ it 'should handle all attributes' do
104
+ Paypal.logger.should_not_receive(:warn)
105
+ response = request.subscription 'profile_id'
106
+ response.recurring.billing.amount.total.should == 1000
107
+ response.recurring.regular_billing.paid.should == 1000
108
+ response.recurring.summary.next_billing_date.should == '2011-03-04T10:00:00Z'
109
+ end
110
+ end
111
+
112
+ context 'when ManageRecurringPaymentsProfileStatus response given' do
113
+ before do
114
+ fake_response 'ManageRecurringPaymentsProfileStatus/success'
115
+ end
116
+
117
+ it 'should handle all attributes' do
118
+ Paypal.logger.should_not_receive(:warn)
119
+ request.renew! 'profile_id', :Cancel
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paypal::Payment::Recurring::Activation do
4
+ let :instance do
5
+ Paypal::Payment::Recurring::Activation.new(
6
+ :initial_amount => 100,
7
+ :failed_action => 'ContinueOnFailure'
8
+ )
9
+ end
10
+
11
+ describe '#to_params' do
12
+ it 'should handle Recurring Profile activation parameters' do
13
+ instance.to_params.should == {
14
+ :INITAMT => '100.00',
15
+ :FAILEDINITAMTACTION => 'ContinueOnFailure'
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Paypal::Payment::Response do
4
+ describe '.new' do
5
+ context 'when non-supported attributes are given' do
6
+ it 'should ignore them and warn' do
7
+ Paypal.logger.should_receive(:warn).with(
8
+ "Ignored Parameter (Paypal::Payment::Response): ignored=Ignore me!"
9
+ )
10
+ response = Paypal::Payment::Response.new(
11
+ :ignored => 'Ignore me!'
12
+ )
13
+ end
14
+ end
15
+ end
16
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paypal-express
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease:
4
+ hash: 27
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - nov matake
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-08 00:00:00 +09:00
18
+ date: 2011-02-09 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -163,6 +163,7 @@ files:
163
163
  - lib/paypal/express.rb
164
164
  - lib/paypal/express/request.rb
165
165
  - lib/paypal/express/response.rb
166
+ - lib/paypal/ipn.rb
166
167
  - lib/paypal/nvp/request.rb
167
168
  - lib/paypal/nvp/response.rb
168
169
  - lib/paypal/payment/recurring.rb
@@ -186,6 +187,8 @@ files:
186
187
  - spec/fake_response/GetExpressCheckoutDetails/success.txt
187
188
  - spec/fake_response/GetRecurringPaymentsProfileDetails/failure.txt
188
189
  - spec/fake_response/GetRecurringPaymentsProfileDetails/success.txt
190
+ - spec/fake_response/IPN/invalid.txt
191
+ - spec/fake_response/IPN/valid.txt
189
192
  - spec/fake_response/ManageRecurringPaymentsProfileStatus/failure.txt
190
193
  - spec/fake_response/ManageRecurringPaymentsProfileStatus/success.txt
191
194
  - spec/fake_response/SetExpressCheckout/failure.txt
@@ -194,13 +197,17 @@ files:
194
197
  - spec/paypal/exception_spec.rb
195
198
  - spec/paypal/express/request_spec.rb
196
199
  - spec/paypal/express/response_spec.rb
200
+ - spec/paypal/ipn_spec.rb
197
201
  - spec/paypal/nvp/request_spec.rb
202
+ - spec/paypal/nvp/response_spec.rb
203
+ - spec/paypal/payment/recurring/activation_spec.rb
198
204
  - spec/paypal/payment/recurring_spec.rb
199
205
  - spec/paypal/payment/request_spec.rb
200
206
  - spec/paypal/payment/response/amount_spec.rb
201
207
  - spec/paypal/payment/response/info_spec.rb
202
208
  - spec/paypal/payment/response/payer_spec.rb
203
209
  - spec/paypal/payment/response/ship_to_spec.rb
210
+ - spec/paypal/payment/response_spec.rb
204
211
  - spec/paypal/util_spec.rb
205
212
  - spec/spec_helper.rb
206
213
  has_rdoc: true
@@ -235,7 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
242
  requirements: []
236
243
 
237
244
  rubyforge_project:
238
- rubygems_version: 1.5.0
245
+ rubygems_version: 1.3.7
239
246
  signing_key:
240
247
  specification_version: 3
241
248
  summary: PayPal Express Checkout API Client Supporting Both Instant and Recurring Payment
@@ -248,6 +255,8 @@ test_files:
248
255
  - spec/fake_response/GetExpressCheckoutDetails/success.txt
249
256
  - spec/fake_response/GetRecurringPaymentsProfileDetails/failure.txt
250
257
  - spec/fake_response/GetRecurringPaymentsProfileDetails/success.txt
258
+ - spec/fake_response/IPN/invalid.txt
259
+ - spec/fake_response/IPN/valid.txt
251
260
  - spec/fake_response/ManageRecurringPaymentsProfileStatus/failure.txt
252
261
  - spec/fake_response/ManageRecurringPaymentsProfileStatus/success.txt
253
262
  - spec/fake_response/SetExpressCheckout/failure.txt
@@ -256,12 +265,16 @@ test_files:
256
265
  - spec/paypal/exception_spec.rb
257
266
  - spec/paypal/express/request_spec.rb
258
267
  - spec/paypal/express/response_spec.rb
268
+ - spec/paypal/ipn_spec.rb
259
269
  - spec/paypal/nvp/request_spec.rb
270
+ - spec/paypal/nvp/response_spec.rb
271
+ - spec/paypal/payment/recurring/activation_spec.rb
260
272
  - spec/paypal/payment/recurring_spec.rb
261
273
  - spec/paypal/payment/request_spec.rb
262
274
  - spec/paypal/payment/response/amount_spec.rb
263
275
  - spec/paypal/payment/response/info_spec.rb
264
276
  - spec/paypal/payment/response/payer_spec.rb
265
277
  - spec/paypal/payment/response/ship_to_spec.rb
278
+ - spec/paypal/payment/response_spec.rb
266
279
  - spec/paypal/util_spec.rb
267
280
  - spec/spec_helper.rb