didil-paypal-recurring 1.1.1

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 (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