paypal-recurring 0.1.0

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.
Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +45 -0
  5. data/README.rdoc +128 -0
  6. data/Rakefile +5 -0
  7. data/docs/PP_NVPAPI_DeveloperGuide.pdf +0 -0
  8. data/docs/PP_WPP_IntegrationGuide.pdf +0 -0
  9. data/lib/paypal-recurring.rb +1 -0
  10. data/lib/paypal/recurring.rb +106 -0
  11. data/lib/paypal/recurring/base.rb +149 -0
  12. data/lib/paypal/recurring/cacert.pem +3987 -0
  13. data/lib/paypal/recurring/request.rb +143 -0
  14. data/lib/paypal/recurring/response.rb +26 -0
  15. data/lib/paypal/recurring/response/base.rb +74 -0
  16. data/lib/paypal/recurring/response/checkout.rb +11 -0
  17. data/lib/paypal/recurring/response/details.rb +26 -0
  18. data/lib/paypal/recurring/response/manage_profile.rb +12 -0
  19. data/lib/paypal/recurring/response/payment.rb +22 -0
  20. data/lib/paypal/recurring/response/profile.rb +69 -0
  21. data/lib/paypal/recurring/version.rb +10 -0
  22. data/paypal-recurring.gemspec +25 -0
  23. data/spec/fixtures/checkout/failure.yml +26 -0
  24. data/spec/fixtures/checkout/success.yml +26 -0
  25. data/spec/fixtures/create_profile/failure.yml +26 -0
  26. data/spec/fixtures/create_profile/success.yml +26 -0
  27. data/spec/fixtures/details/cancelled.yml +26 -0
  28. data/spec/fixtures/details/failure.yml +26 -0
  29. data/spec/fixtures/details/success.yml +26 -0
  30. data/spec/fixtures/payment/failure.yml +26 -0
  31. data/spec/fixtures/payment/success.yml +26 -0
  32. data/spec/fixtures/profile/cancel/failure.yml +26 -0
  33. data/spec/fixtures/profile/cancel/success.yml +26 -0
  34. data/spec/fixtures/profile/failure.yml +26 -0
  35. data/spec/fixtures/profile/reactivate/failure.yml +26 -0
  36. data/spec/fixtures/profile/reactivate/success.yml +26 -0
  37. data/spec/fixtures/profile/success.yml +26 -0
  38. data/spec/fixtures/profile/suspend/failure.yml +26 -0
  39. data/spec/fixtures/profile/suspend/success.yml +26 -0
  40. data/spec/paypal/recurring_spec.rb +87 -0
  41. data/spec/paypal/request_spec.rb +102 -0
  42. data/spec/paypal/response/checkout_details_spec.rb +51 -0
  43. data/spec/paypal/response/checkout_spec.rb +32 -0
  44. data/spec/paypal/response/create_recurring_profile_spec.rb +39 -0
  45. data/spec/paypal/response/manage_profile_spec.rb +62 -0
  46. data/spec/paypal/response/profile_spec.rb +41 -0
  47. data/spec/paypal/response/request_payment_spec.rb +35 -0
  48. data/spec/spec_helper.rb +24 -0
  49. metadata +187 -0
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring do
4
+ describe ".logger" do
5
+ it "has a default logging" do
6
+ PayPal::Recurring.logger.should be_a(Logger)
7
+ end
8
+ end
9
+
10
+ describe ".new" do
11
+ it "instantiates PayPal::Recurring::Base" do
12
+ PayPal::Recurring.new.should be_a(PayPal::Recurring::Base)
13
+ end
14
+ end
15
+
16
+ describe ".version" do
17
+ it "returns PayPal's API version" do
18
+ PayPal::Recurring.api_version.should eq("72.0")
19
+ end
20
+ end
21
+
22
+ describe ".configure" do
23
+ it "yields PayPal::Recurring" do
24
+ PayPal::Recurring.configure do |config|
25
+ config.should be(PayPal::Recurring)
26
+ end
27
+ end
28
+
29
+ it "sets attributes" do
30
+ PayPal::Recurring.configure do |config|
31
+ config.sandbox = false
32
+ end
33
+
34
+ PayPal::Recurring.sandbox.should be_false
35
+ end
36
+ end
37
+
38
+ describe ".sandbox?" do
39
+ it "detects sandbox" do
40
+ PayPal::Recurring.sandbox = true
41
+ PayPal::Recurring.should be_sandbox
42
+ end
43
+
44
+ it "ignores sandbox" do
45
+ PayPal::Recurring.sandbox = false
46
+ PayPal::Recurring.should_not be_sandbox
47
+ end
48
+ end
49
+
50
+ describe ".environment" do
51
+ it "returns production" do
52
+ PayPal::Recurring.sandbox = false
53
+ PayPal::Recurring.environment.should eq(:production)
54
+ end
55
+
56
+ it "returns sandbox" do
57
+ PayPal::Recurring.sandbox = true
58
+ PayPal::Recurring.environment.should eq(:sandbox)
59
+ end
60
+ end
61
+
62
+ describe ".api_endpoint" do
63
+ it "returns url" do
64
+ PayPal::Recurring.api_endpoint.should_not be_nil
65
+ PayPal::Recurring.api_endpoint.should == PayPal::Recurring.endpoints[:api]
66
+ end
67
+ end
68
+
69
+ describe ".site_endpoint" do
70
+ it "returns url" do
71
+ PayPal::Recurring.site_endpoint.should_not be_nil
72
+ PayPal::Recurring.site_endpoint.should == PayPal::Recurring.endpoints[:site]
73
+ end
74
+ end
75
+
76
+ describe ".endpoints" do
77
+ it "returns production's" do
78
+ PayPal::Recurring.sandbox = false
79
+ PayPal::Recurring.endpoints.should eq(PayPal::Recurring::ENDPOINTS[:production])
80
+ end
81
+
82
+ it "returns sandbox's" do
83
+ PayPal::Recurring.sandbox = true
84
+ PayPal::Recurring.endpoints.should eq(PayPal::Recurring::ENDPOINTS[:sandbox])
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,102 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Request do
4
+ describe "#client" do
5
+ it "uses SSL" do
6
+ subject.client.use_ssl?.should be_true
7
+ end
8
+
9
+ it "verifies certificate" do
10
+ subject.client.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
11
+ end
12
+
13
+ it "sets CA file to bundled file" do
14
+ subject.client.ca_file.should == File.expand_path("../../../lib/paypal/recurring/cacert.pem", __FILE__)
15
+ File.should be_file(subject.client.ca_file)
16
+ end
17
+ end
18
+
19
+ describe "#post" do
20
+ let(:request) {
21
+ FakeWeb.register_uri :post, "https://api-3t.sandbox.paypal.com/nvp", :status => 200
22
+ subject.post(:checkout)
23
+ CGI.parse(FakeWeb.last_request.body)
24
+ }
25
+
26
+ it "sets action" do
27
+ request["METHOD"].first.should == "SetExpressCheckout"
28
+ end
29
+
30
+ it "sets username" do
31
+ request["USER"].first.should == PayPal::Recurring.username
32
+ end
33
+
34
+ it "sets password" do
35
+ request["PWD"].first.should == PayPal::Recurring.password
36
+ end
37
+
38
+ it "sets signature" do
39
+ request["SIGNATURE"].first.should == PayPal::Recurring.signature
40
+ end
41
+
42
+ it "sets API version" do
43
+ request["VERSION"].first.should == PayPal::Recurring.api_version
44
+ end
45
+
46
+ it "sets user agent" do
47
+ FakeWeb.last_request["User-Agent"].should == "PayPal::Recurring/#{PayPal::Recurring::Version::STRING}"
48
+ end
49
+ end
50
+
51
+ describe "#normalize_params" do
52
+ it "normalizes method" do
53
+ subject.normalize_params(:method => "some method").should == {:METHOD => "some method"}
54
+ end
55
+
56
+ it "normalizes return_url" do
57
+ subject.normalize_params(:return_url => "http://example.com").should == {:RETURNURL => "http://example.com"}
58
+ end
59
+
60
+ it "normalizes cancel_url" do
61
+ subject.normalize_params(:cancel_url => "http://example.com").should == {:CANCELURL => "http://example.com"}
62
+ end
63
+
64
+ it "normalizes amount" do
65
+ subject.normalize_params(:amount => "9.00").should == {:PAYMENTREQUEST_0_AMT => "9.00", :AMT => "9.00"}
66
+ end
67
+
68
+ it "normalizes currency" do
69
+ subject.normalize_params(:currency => "USD").should == {:CURRENCYCODE => "USD", :PAYMENTREQUEST_0_CURRENCYCODE => "USD"}
70
+ end
71
+
72
+ it "normalizes description" do
73
+ subject.normalize_params(:description => "Awesome").should == {:DESC => "Awesome", :PAYMENTREQUEST_0_DESC => "Awesome", :L_BILLINGAGREEMENTDESCRIPTION0 => "Awesome"}
74
+ end
75
+
76
+ it "normalizes ipn url" do
77
+ subject.normalize_params(:ipn_url => "http://example.com").should == {:PAYMENTREQUEST_0_NOTIFYURL => "http://example.com", :NOTIFYURL => "http://example.com"}
78
+ end
79
+
80
+ it "normalizes period" do
81
+ subject.normalize_params(:period => :monthly).should == {:BILLINGPERIOD => "Month"}
82
+ subject.normalize_params(:period => :daily).should == {:BILLINGPERIOD => "Day"}
83
+ subject.normalize_params(:period => :yearly).should == {:BILLINGPERIOD => "Year"}
84
+ end
85
+
86
+ it "normalizes start at" do
87
+ date = Time.parse("2011-06-26 15:13:00")
88
+ subject.normalize_params(:start_at => date).should == {:PROFILESTARTDATE => "2011-06-26T15:13:00Z"}
89
+ end
90
+
91
+ it "normalizes outstanding" do
92
+ subject.normalize_params(:outstanding => :next_billing).should == {:AUTOBILLOUTAMT => "AddToNextBilling"}
93
+ subject.normalize_params(:outstanding => :no_auto).should == {:AUTOBILLOUTAMT => "NoAutoBill"}
94
+ end
95
+
96
+ it "normalizes action" do
97
+ subject.normalize_params(:action => :cancel).should == {:ACTION => "Cancel"}
98
+ subject.normalize_params(:action => :suspend).should == {:ACTION => "Suspend"}
99
+ subject.normalize_params(:action => :reactivate).should == {:ACTION => "Reactivate"}
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Response::Details do
4
+ context "when successful" do
5
+ use_vcr_cassette "details/success"
6
+
7
+ subject {
8
+ ppr = PayPal::Recurring.new(:token => "EC-7B902269MT603740W")
9
+ ppr.checkout_details
10
+ }
11
+
12
+ it { should be_valid }
13
+ it { should be_success }
14
+
15
+ its(:errors) { should be_empty }
16
+ its(:status) { should == "PaymentActionNotInitiated" }
17
+ its(:email) { should == "buyer_1308979708_per@simplesideias.com.br" }
18
+ its(:requested_at) { should be_a(Time) }
19
+ its(:email) { should == "buyer_1308979708_per@simplesideias.com.br" }
20
+ its(:payer_id) { should == "WTTS5KC2T46YU" }
21
+ its(:payer_status) { should == "verified" }
22
+ its(:country) { should == "US" }
23
+ its(:currency) { should == "USD" }
24
+ its(:description) { should == "Awesome - Monthly Subscription" }
25
+ its(:ipn_url) { should == "http://example.com/paypal/ipn" }
26
+ its(:agreed?) { should be_true }
27
+ end
28
+
29
+ context "when cancelled" do
30
+ use_vcr_cassette "details/cancelled"
31
+ subject {
32
+ ppr = PayPal::Recurring.new(:token => "EC-365619347A138351P")
33
+ ppr.checkout_details
34
+ }
35
+
36
+ it { should be_valid }
37
+ it { should be_success }
38
+
39
+ its(:agreed?) { should be_false }
40
+ end
41
+
42
+ context "when failure" do
43
+ use_vcr_cassette("details/failure")
44
+ subject { PayPal::Recurring.new.checkout_details }
45
+
46
+ it { should_not be_valid }
47
+ it { should_not be_success }
48
+
49
+ its(:errors) { should have(1).item }
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Response::Checkout do
4
+ context "when successful" do
5
+ use_vcr_cassette "checkout/success"
6
+
7
+ subject {
8
+ ppr = PayPal::Recurring.new({
9
+ :return_url => "http://example.com/thank_you",
10
+ :cancel_url => "http://example.com/canceled",
11
+ :ipn_url => "http://example.com/paypal/ipn",
12
+ :description => "Awesome - Monthly Subscription",
13
+ :amount => "9.00",
14
+ :currency => "USD"
15
+ })
16
+
17
+ ppr.checkout
18
+ }
19
+
20
+ its(:valid?) { should be_true }
21
+ its(:errors) { should be_empty }
22
+ its(:checkout_url) { should == "#{PayPal::Recurring.site_endpoint}?cmd=_express-checkout&token=EC-7B902269MT603740W" }
23
+ end
24
+
25
+ context "when failure" do
26
+ use_vcr_cassette("checkout/failure")
27
+ subject { PayPal::Recurring.new.checkout }
28
+
29
+ its(:valid?) { should be_false }
30
+ its(:errors) { should have(3).items }
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Response::Profile do
4
+ context "when successful" do
5
+ use_vcr_cassette "create_profile/success"
6
+
7
+ subject {
8
+ ppr = PayPal::Recurring.new({
9
+ :amount => "9.00",
10
+ :currency => "USD",
11
+ :description => "Awesome - Monthly Subscription",
12
+ :ipn_url => "http://example.com/paypal/ipn",
13
+ :frequency => 1,
14
+ :token => "EC-2UK36172XH723314S",
15
+ :period => :monthly,
16
+ :reference => "1234",
17
+ :payer_id => "WTTS5KC2T46YU",
18
+ :start_at => Time.now,
19
+ :failed => 1,
20
+ :outstanding => :next_billing
21
+ })
22
+ ppr.create_recurring_profile
23
+ }
24
+
25
+ it { should be_valid }
26
+
27
+ its(:profile_id) { should == "I-89LD5VEHEVK4" }
28
+ its(:status) { should == "ActiveProfile" }
29
+ its(:errors) { should be_empty }
30
+ end
31
+
32
+ context "when failure" do
33
+ use_vcr_cassette("create_profile/failure")
34
+ subject { PayPal::Recurring.new.create_recurring_profile }
35
+
36
+ it { should_not be_valid }
37
+ its(:errors) { should have(5).items }
38
+ end
39
+ end
@@ -0,0 +1,62 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Response::ManageProfile do
4
+ let(:paypal) { PayPal::Recurring.new(:profile_id => "I-89LD5VEHEVK4") }
5
+
6
+ context "canceling" do
7
+ context "when successful" do
8
+ use_vcr_cassette "profile/cancel/success"
9
+ subject { paypal.cancel }
10
+
11
+ it { should be_success }
12
+ it { should be_valid }
13
+ end
14
+
15
+ context "when failure" do
16
+ use_vcr_cassette "profile/cancel/failure"
17
+ subject { paypal.cancel }
18
+
19
+ it { should_not be_success }
20
+ it { should_not be_valid }
21
+ its(:errors) { should have(1).item }
22
+ end
23
+ end
24
+
25
+ context "reactivating" do
26
+ context "when successful" do
27
+ use_vcr_cassette "profile/reactivate/success"
28
+ subject { paypal.reactivate }
29
+
30
+ it { should be_success }
31
+ it { should be_valid }
32
+ end
33
+
34
+ context "when failure" do
35
+ use_vcr_cassette "profile/reactivate/failure"
36
+ subject { paypal.reactivate }
37
+
38
+ it { should_not be_success }
39
+ it { should_not be_valid }
40
+ its(:errors) { should have(1).item }
41
+ end
42
+ end
43
+
44
+ context "suspending" do
45
+ context "when successful" do
46
+ use_vcr_cassette "profile/suspend/success"
47
+ subject { paypal.suspend }
48
+
49
+ it { should be_success }
50
+ it { should be_valid }
51
+ end
52
+
53
+ context "when failure" do
54
+ use_vcr_cassette "profile/suspend/failure"
55
+ subject { paypal.suspend }
56
+
57
+ it { should_not be_success }
58
+ it { should_not be_valid }
59
+ its(:errors) { should have(1).item }
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Response::Profile do
4
+ let(:paypal) { PayPal::Recurring.new(:profile_id => "I-89LD5VEHEVK4") }
5
+
6
+ context "when successful" do
7
+ use_vcr_cassette "profile/success"
8
+ subject { paypal.profile }
9
+
10
+ it { should_not be_active }
11
+
12
+ its(:status) { should == :canceled }
13
+ its(:profile_id) { should == "I-89LD5VEHEVK4" }
14
+ its(:outstanding) { should == :next_billing }
15
+ its(:description) { should == "Awesome - Monthly Subscription" }
16
+ its(:payer_name) { should == "Test User" }
17
+ its(:reference) { should == "1234" }
18
+ its(:failed) { should == "1" }
19
+ its(:start_at) { should be_a(Time) }
20
+ its(:completed) { should == "1" }
21
+ its(:remaining) { should == "18446744073709551615" }
22
+ its(:outstanding_balance) { should == "0.00" }
23
+ its(:failed_count) { should == "0" }
24
+ its(:last_payment_date) { should be_a(Time) }
25
+ its(:last_payment_amount) { should == "9.00" }
26
+ its(:period) { should == :monthly }
27
+ its(:frequency) { should == "1" }
28
+ its(:currency) { should == "USD" }
29
+ its(:amount) { should == "9.00" }
30
+ end
31
+
32
+ context "when failure" do
33
+ use_vcr_cassette "profile/failure"
34
+ subject { paypal.profile }
35
+
36
+ it { should_not be_valid }
37
+ it { should_not be_success }
38
+
39
+ its(:errors) { should have(1).item }
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Response::Payment do
4
+ context "when successful" do
5
+ use_vcr_cassette "payment/success"
6
+
7
+ subject {
8
+ ppr = PayPal::Recurring.new({
9
+ :description => "Awesome - Monthly Subscription",
10
+ :amount => "9.00",
11
+ :currency => "USD",
12
+ :payer_id => "WTTS5KC2T46YU",
13
+ :token => "EC-7A593227AC789800N",
14
+ })
15
+ ppr.request_payment
16
+ }
17
+
18
+ it { should be_valid }
19
+ it { should be_completed }
20
+ it { should be_approved }
21
+
22
+ its(:errors) { should be_empty }
23
+ end
24
+
25
+ context "when failure" do
26
+ use_vcr_cassette("payment/failure")
27
+ subject { PayPal::Recurring.new.request_payment }
28
+
29
+ it { should_not be_valid }
30
+ it { should_not be_completed }
31
+ it { should_not be_approved }
32
+
33
+ its(:errors) { should have(1).items }
34
+ end
35
+ end