paypal-express 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.
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