didil-paypal-recurring 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +46 -0
  6. data/README.rdoc +144 -0
  7. data/Rakefile +5 -0
  8. data/docs/PP_NVPAPI_DeveloperGuide.pdf +0 -0
  9. data/docs/PP_WPP_IntegrationGuide.pdf +0 -0
  10. data/lib/paypal-recurring.rb +1 -0
  11. data/lib/paypal/recurring.rb +110 -0
  12. data/lib/paypal/recurring/base.rb +286 -0
  13. data/lib/paypal/recurring/cacert.pem +3987 -0
  14. data/lib/paypal/recurring/notification.rb +84 -0
  15. data/lib/paypal/recurring/request.rb +211 -0
  16. data/lib/paypal/recurring/response.rb +29 -0
  17. data/lib/paypal/recurring/response/base.rb +62 -0
  18. data/lib/paypal/recurring/response/checkout.rb +11 -0
  19. data/lib/paypal/recurring/response/details.rb +26 -0
  20. data/lib/paypal/recurring/response/manage_profile.rb +12 -0
  21. data/lib/paypal/recurring/response/payment.rb +24 -0
  22. data/lib/paypal/recurring/response/profile.rb +71 -0
  23. data/lib/paypal/recurring/response/refund.rb +23 -0
  24. data/lib/paypal/recurring/utils.rb +26 -0
  25. data/lib/paypal/recurring/version.rb +10 -0
  26. data/paypal-recurring.gemspec +27 -0
  27. data/spec/fixtures/checkout/failure.yml +38 -0
  28. data/spec/fixtures/checkout/success.yml +38 -0
  29. data/spec/fixtures/create_profile/failure.yml +38 -0
  30. data/spec/fixtures/create_profile/success.yml +38 -0
  31. data/spec/fixtures/details/cancelled.yml +38 -0
  32. data/spec/fixtures/details/failure.yml +38 -0
  33. data/spec/fixtures/details/success.yml +38 -0
  34. data/spec/fixtures/ipn/express_checkout.json +35 -0
  35. data/spec/fixtures/ipn/recurring_payment.json +44 -0
  36. data/spec/fixtures/ipn/recurring_payment_profile_created.json +31 -0
  37. data/spec/fixtures/ipn/recurring_payment_profile_created_with_initial_amount.json +33 -0
  38. data/spec/fixtures/ipn/recurring_payment_skipped.json +30 -0
  39. data/spec/fixtures/ipn/recurring_payment_with_initial_amount.json +44 -0
  40. data/spec/fixtures/notification/failure.yml +50 -0
  41. data/spec/fixtures/notification/success.yml +50 -0
  42. data/spec/fixtures/payment/failure.yml +38 -0
  43. data/spec/fixtures/payment/success.yml +38 -0
  44. data/spec/fixtures/profile/cancel/failure.yml +38 -0
  45. data/spec/fixtures/profile/cancel/success.yml +38 -0
  46. data/spec/fixtures/profile/failure.yml +38 -0
  47. data/spec/fixtures/profile/reactivate/failure.yml +38 -0
  48. data/spec/fixtures/profile/reactivate/success.yml +38 -0
  49. data/spec/fixtures/profile/success.yml +38 -0
  50. data/spec/fixtures/profile/suspend/failure.yml +38 -0
  51. data/spec/fixtures/profile/suspend/success.yml +38 -0
  52. data/spec/fixtures/refund/failure.yml +38 -0
  53. data/spec/fixtures/refund/success.yml +38 -0
  54. data/spec/fixtures/update_profile/failure.yml +38 -0
  55. data/spec/fixtures/update_profile/profile.yml +38 -0
  56. data/spec/fixtures/update_profile/success.yml +38 -0
  57. data/spec/paypal/notification_spec.rb +106 -0
  58. data/spec/paypal/recurring_spec.rb +81 -0
  59. data/spec/paypal/request_spec.rb +136 -0
  60. data/spec/paypal/response/base_spec.rb +19 -0
  61. data/spec/paypal/response/checkout_details_spec.rb +50 -0
  62. data/spec/paypal/response/checkout_spec.rb +32 -0
  63. data/spec/paypal/response/create_recurring_profile_spec.rb +41 -0
  64. data/spec/paypal/response/manage_profile_spec.rb +62 -0
  65. data/spec/paypal/response/profile_spec.rb +43 -0
  66. data/spec/paypal/response/refund_spec.rb +33 -0
  67. data/spec/paypal/response/request_payment_spec.rb +35 -0
  68. data/spec/paypal/response/update_recurring_profile_spec.rb +48 -0
  69. data/spec/spec_helper.rb +27 -0
  70. metadata +209 -0
@@ -0,0 +1,81 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring do
4
+ describe ".new" do
5
+ it "instantiates PayPal::Recurring::Base" do
6
+ PayPal::Recurring.new.should be_a(PayPal::Recurring::Base)
7
+ end
8
+ end
9
+
10
+ describe ".version" do
11
+ it "returns PayPal's API version" do
12
+ PayPal::Recurring.api_version.should eq("72.0")
13
+ end
14
+ end
15
+
16
+ describe ".configure" do
17
+ it "yields PayPal::Recurring" do
18
+ PayPal::Recurring.configure do |config|
19
+ config.should be(PayPal::Recurring)
20
+ end
21
+ end
22
+
23
+ it "sets attributes" do
24
+ PayPal::Recurring.configure do |config|
25
+ config.sandbox = false
26
+ end
27
+
28
+ PayPal::Recurring.sandbox.should be_false
29
+ end
30
+ end
31
+
32
+ describe ".sandbox?" do
33
+ it "detects sandbox" do
34
+ PayPal::Recurring.sandbox = true
35
+ PayPal::Recurring.should be_sandbox
36
+ end
37
+
38
+ it "ignores sandbox" do
39
+ PayPal::Recurring.sandbox = false
40
+ PayPal::Recurring.should_not be_sandbox
41
+ end
42
+ end
43
+
44
+ describe ".environment" do
45
+ it "returns production" do
46
+ PayPal::Recurring.sandbox = false
47
+ PayPal::Recurring.environment.should eq(:production)
48
+ end
49
+
50
+ it "returns sandbox" do
51
+ PayPal::Recurring.sandbox = true
52
+ PayPal::Recurring.environment.should eq(:sandbox)
53
+ end
54
+ end
55
+
56
+ describe ".api_endpoint" do
57
+ it "returns url" do
58
+ PayPal::Recurring.api_endpoint.should_not be_nil
59
+ PayPal::Recurring.api_endpoint.should == PayPal::Recurring.endpoints[:api]
60
+ end
61
+ end
62
+
63
+ describe ".site_endpoint" do
64
+ it "returns url" do
65
+ PayPal::Recurring.site_endpoint.should_not be_nil
66
+ PayPal::Recurring.site_endpoint.should == PayPal::Recurring.endpoints[:site]
67
+ end
68
+ end
69
+
70
+ describe ".endpoints" do
71
+ it "returns production's" do
72
+ PayPal::Recurring.sandbox = false
73
+ PayPal::Recurring.endpoints.should eq(PayPal::Recurring::ENDPOINTS[:production])
74
+ end
75
+
76
+ it "returns sandbox's" do
77
+ PayPal::Recurring.sandbox = true
78
+ PayPal::Recurring.endpoints.should eq(PayPal::Recurring::ENDPOINTS[:sandbox])
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,136 @@
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
+ before :all do
21
+ VCR.eject_cassette
22
+ VCR.turn_off!
23
+ end
24
+
25
+ after :all do
26
+ VCR.turn_on!
27
+ end
28
+
29
+ let(:request) {
30
+ FakeWeb.register_uri :post, "https://api-3t.sandbox.paypal.com/nvp", :status => 200
31
+ subject.run(:checkout)
32
+ CGI.parse(FakeWeb.last_request.body)
33
+ }
34
+
35
+ it "sets action" do
36
+ request["METHOD"].first.should == "SetExpressCheckout"
37
+ end
38
+
39
+ it "sets username" do
40
+ request["USER"].first.should == PayPal::Recurring.username
41
+ end
42
+
43
+ it "sets password" do
44
+ request["PWD"].first.should == PayPal::Recurring.password
45
+ end
46
+
47
+ it "sets signature" do
48
+ request["SIGNATURE"].first.should == PayPal::Recurring.signature
49
+ end
50
+
51
+ it "sets API version" do
52
+ request["VERSION"].first.should == PayPal::Recurring.api_version
53
+ end
54
+
55
+ it "sets user agent" do
56
+ FakeWeb.last_request["User-Agent"].should == "PayPal::Recurring/#{PayPal::Recurring::Version::STRING}"
57
+ end
58
+ end
59
+
60
+ describe "#normalize_params" do
61
+ it "normalizes method" do
62
+ subject.normalize_params(:method => "some method").should == {:METHOD => "some method"}
63
+ end
64
+
65
+ it "normalizes return_url" do
66
+ subject.normalize_params(:return_url => "http://example.com").should == {:RETURNURL => "http://example.com"}
67
+ end
68
+
69
+ it "normalizes cancel_url" do
70
+ subject.normalize_params(:cancel_url => "http://example.com").should == {:CANCELURL => "http://example.com"}
71
+ end
72
+
73
+ it "normalizes amount" do
74
+ subject.normalize_params(:amount => "9.00").should == {:PAYMENTREQUEST_0_AMT => "9.00", :AMT => "9.00"}
75
+ end
76
+
77
+ it "normalizes currency" do
78
+ subject.normalize_params(:currency => "USD").should == {:CURRENCYCODE => "USD", :PAYMENTREQUEST_0_CURRENCYCODE => "USD"}
79
+ end
80
+
81
+ it "normalizes description" do
82
+ subject.normalize_params(:description => "Awesome").should == {:DESC => "Awesome", :PAYMENTREQUEST_0_DESC => "Awesome", :L_BILLINGAGREEMENTDESCRIPTION0 => "Awesome"}
83
+ end
84
+
85
+ it "normalizes ipn url" do
86
+ subject.normalize_params(:ipn_url => "http://example.com").should == {:PAYMENTREQUEST_0_NOTIFYURL => "http://example.com", :NOTIFYURL => "http://example.com"}
87
+ end
88
+
89
+ it "normalizes period" do
90
+ subject.normalize_params(:period => :monthly).should == {:BILLINGPERIOD => "Month"}
91
+ subject.normalize_params(:period => :weekly).should == {:BILLINGPERIOD => "Weekly"}
92
+ subject.normalize_params(:period => :daily).should == {:BILLINGPERIOD => "Day"}
93
+ subject.normalize_params(:period => :yearly).should == {:BILLINGPERIOD => "Year"}
94
+ end
95
+
96
+ it "normalizes trial period" do
97
+ subject.normalize_params(:trial_period => :monthly).should == {:TRIALBILLINGPERIOD => "Month"}
98
+ subject.normalize_params(:trial_period => :weekly).should == {:TRIALBILLINGPERIOD => "Weekly"}
99
+ subject.normalize_params(:trial_period => :daily).should == {:TRIALBILLINGPERIOD => "Day"}
100
+ subject.normalize_params(:trial_period => :yearly).should == {:TRIALBILLINGPERIOD => "Year"}
101
+ end
102
+
103
+ it "normalizes start at" do
104
+ date = Time.parse("2011-06-26 15:13:00")
105
+ subject.normalize_params(:start_at => date).should == {:PROFILESTARTDATE => "2011-06-26T15:13:00Z"}
106
+ end
107
+
108
+ it "normalizes outstanding" do
109
+ subject.normalize_params(:outstanding => :next_billing).should == {:AUTOBILLOUTAMT => "AddToNextBilling"}
110
+ subject.normalize_params(:outstanding => :no_auto).should == {:AUTOBILLOUTAMT => "NoAutoBill"}
111
+ end
112
+
113
+ it "normalizes action" do
114
+ subject.normalize_params(:action => :cancel).should == {:ACTION => "Cancel"}
115
+ subject.normalize_params(:action => :suspend).should == {:ACTION => "Suspend"}
116
+ subject.normalize_params(:action => :reactivate).should == {:ACTION => "Reactivate"}
117
+ end
118
+
119
+ it "normalizes initial amount" do
120
+ subject.normalize_params(:initial_amount => "9.00").should == {:INITAMT => "9.00"}
121
+ end
122
+
123
+ it "normalizes initial amount action" do
124
+ subject.normalize_params(:initial_amount_action => :cancel).should == {:FAILEDINITAMTACTION => "CancelOnFailure"}
125
+ subject.normalize_params(:initial_amount_action => :continue).should == {:FAILEDINITAMTACTION => "ContinueOnFailure"}
126
+ end
127
+
128
+ it "normalizes reference" do
129
+ subject.normalize_params(:reference => "abc").should == {:PROFILEREFERENCE => "abc", :PAYMENTREQUEST_0_CUSTOM => "abc", :PAYMENTREQUEST_0_INVNUM => "abc"}
130
+ end
131
+
132
+ it "normalizes locale" do
133
+ subject.normalize_params(:locale => :us).should == {:LOCALECODE => "US"}
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+
3
+ describe PayPal::Recurring::Response do
4
+ let(:response_class) { Class.new(PayPal::Recurring::Response::Base) }
5
+
6
+ describe ".mapping" do
7
+ it "returns single item mapping" do
8
+ response_class.mapping :foo => :bar
9
+ response = response_class.new(stub(:body => "bar=foo"))
10
+ response.foo.should == "foo"
11
+ end
12
+
13
+ it "returns item from array mapping" do
14
+ response_class.mapping :foo => [:bar, :zaz]
15
+ response = response_class.new(stub(:body => "zaz=foo"))
16
+ response.foo.should == "foo"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,50 @@
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-08C2125544495393T")
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 == "fnando.vieira+br@gmail.com" }
18
+ its(:requested_at) { should be_a(Time) }
19
+ its(:payer_id) { should == "D2U7M6PTMJBML" }
20
+ its(:payer_status) { should == "unverified" }
21
+ its(:country) { should == "BR" }
22
+ its(:currency) { should == "BRL" }
23
+ its(:description) { should == "Awesome - Monthly Subscription" }
24
+ its(:ipn_url) { should == "http://example.com/paypal/ipn" }
25
+ its(:agreed?) { should be_true }
26
+ end
27
+
28
+ context "when cancelled" do
29
+ use_vcr_cassette "details/cancelled"
30
+ subject {
31
+ ppr = PayPal::Recurring.new(:token => "EC-8J298813NS092694P")
32
+ ppr.checkout_details
33
+ }
34
+
35
+ it { should be_valid }
36
+ it { should be_success }
37
+
38
+ its(:agreed?) { should be_false }
39
+ end
40
+
41
+ context "when failure" do
42
+ use_vcr_cassette("details/failure")
43
+ subject { PayPal::Recurring.new.checkout_details }
44
+
45
+ it { should_not be_valid }
46
+ it { should_not be_success }
47
+
48
+ its(:errors) { should have(1).item }
49
+ end
50
+ 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-6K296451S2213041J&useraction=commit" }
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,41 @@
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
+ :initial_amount => "9.00",
11
+ :initial_amount_action => :cancel,
12
+ :currency => "BRL",
13
+ :description => "Awesome - Monthly Subscription",
14
+ :ipn_url => "http://example.com/paypal/ipn",
15
+ :frequency => 1,
16
+ :token => "EC-47J551124P900104V",
17
+ :period => :monthly,
18
+ :reference => "1234",
19
+ :payer_id => "D2U7M6PTMJBML",
20
+ :start_at => Time.now,
21
+ :failed => 1,
22
+ :outstanding => :next_billing
23
+ })
24
+ ppr.create_recurring_profile
25
+ }
26
+
27
+ it { should be_valid }
28
+
29
+ its(:profile_id) { should == "I-W4FNTE6EXJ2W" }
30
+ its(:status) { should == "ActiveProfile" }
31
+ its(:errors) { should be_empty }
32
+ end
33
+
34
+ context "when failure" do
35
+ use_vcr_cassette("create_profile/failure")
36
+ subject { PayPal::Recurring.new.create_recurring_profile }
37
+
38
+ it { should_not be_valid }
39
+ its(:errors) { should have(5).items }
40
+ end
41
+ 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-W4FNTE6EXJ2W") }
5
+
6
+ context "suspending" do
7
+ context "when successful" do
8
+ use_vcr_cassette "profile/suspend/success"
9
+ subject { paypal.suspend }
10
+
11
+ it { should be_success }
12
+ it { should be_valid }
13
+ end
14
+
15
+ context "when failure" do
16
+ use_vcr_cassette "profile/suspend/failure"
17
+ subject { paypal.suspend }
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 "cancelling" do
45
+ context "when successful" do
46
+ use_vcr_cassette "profile/cancel/success"
47
+ subject { paypal.cancel }
48
+
49
+ it { should be_success }
50
+ it { should be_valid }
51
+ end
52
+
53
+ context "when failure" do
54
+ use_vcr_cassette "profile/cancel/failure"
55
+ subject { paypal.cancel }
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,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "spec_helper"
3
+
4
+ describe PayPal::Recurring::Response::Profile do
5
+ context "when successful" do
6
+ use_vcr_cassette "profile/success"
7
+ let(:paypal) { PayPal::Recurring.new(:profile_id => "I-W4FNTE6EXJ2W") }
8
+ subject { paypal.profile }
9
+
10
+ it { should_not be_active }
11
+
12
+ its(:status) { should == :canceled }
13
+ its(:profile_id) { should == "I-W4FNTE6EXJ2W" }
14
+ its(:outstanding) { should == :next_billing }
15
+ its(:description) { should == "Awesome - Monthly Subscription" }
16
+ its(:payer_name) { should == "José da Silva" }
17
+ its(:reference) { should == "1234" }
18
+ its(:failed) { should == "1" }
19
+ its(:start_at) { should be_a(Time) }
20
+ its(:completed) { should == "0" }
21
+ its(:remaining) { should == "0" }
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 == "BRL" }
29
+ its(:amount) { should == "9.00" }
30
+ its(:initial_amount) { should == "9.00" }
31
+ end
32
+
33
+ context "when failure" do
34
+ use_vcr_cassette "profile/failure"
35
+ let(:paypal) { PayPal::Recurring.new(:profile_id => "invalid") }
36
+ subject { paypal.profile }
37
+
38
+ it { should_not be_valid }
39
+ it { should_not be_success }
40
+
41
+ its(:errors) { should have(1).item }
42
+ end
43
+ end