ianfleeton-paypal-express 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +22 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +11 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE +20 -0
  8. data/README.rdoc +43 -0
  9. data/Rakefile +19 -0
  10. data/VERSION +1 -0
  11. data/ianfleeton-paypal-express.gemspec +24 -0
  12. data/lib/paypal.rb +86 -0
  13. data/lib/paypal/base.rb +19 -0
  14. data/lib/paypal/exception.rb +4 -0
  15. data/lib/paypal/exception/api_error.rb +94 -0
  16. data/lib/paypal/exception/http_error.rb +12 -0
  17. data/lib/paypal/express.rb +1 -0
  18. data/lib/paypal/express/request.rb +186 -0
  19. data/lib/paypal/express/response.rb +35 -0
  20. data/lib/paypal/ipn.rb +23 -0
  21. data/lib/paypal/nvp/request.rb +66 -0
  22. data/lib/paypal/nvp/response.rb +237 -0
  23. data/lib/paypal/payment/common/amount.rb +13 -0
  24. data/lib/paypal/payment/recurring.rb +43 -0
  25. data/lib/paypal/payment/recurring/activation.rb +14 -0
  26. data/lib/paypal/payment/recurring/billing.rb +39 -0
  27. data/lib/paypal/payment/recurring/summary.rb +11 -0
  28. data/lib/paypal/payment/request.rb +67 -0
  29. data/lib/paypal/payment/request/item.rb +26 -0
  30. data/lib/paypal/payment/response.rb +75 -0
  31. data/lib/paypal/payment/response/address.rb +7 -0
  32. data/lib/paypal/payment/response/info.rb +45 -0
  33. data/lib/paypal/payment/response/item.rb +41 -0
  34. data/lib/paypal/payment/response/payee_info.rb +7 -0
  35. data/lib/paypal/payment/response/payer.rb +7 -0
  36. data/lib/paypal/payment/response/reference.rb +23 -0
  37. data/lib/paypal/payment/response/refund.rb +17 -0
  38. data/lib/paypal/payment/response/refund_info.rb +7 -0
  39. data/lib/paypal/util.rb +27 -0
  40. data/spec/fake_response/BillAgreementUpdate/fetch.txt +1 -0
  41. data/spec/fake_response/BillAgreementUpdate/revoke.txt +1 -0
  42. data/spec/fake_response/CreateBillingAgreement/success.txt +1 -0
  43. data/spec/fake_response/CreateRecurringPaymentsProfile/failure.txt +1 -0
  44. data/spec/fake_response/CreateRecurringPaymentsProfile/success.txt +1 -0
  45. data/spec/fake_response/DoCapture/failure.txt +1 -0
  46. data/spec/fake_response/DoCapture/success.txt +1 -0
  47. data/spec/fake_response/DoExpressCheckoutPayment/failure.txt +1 -0
  48. data/spec/fake_response/DoExpressCheckoutPayment/success.txt +1 -0
  49. data/spec/fake_response/DoExpressCheckoutPayment/success_with_billing_agreement.txt +1 -0
  50. data/spec/fake_response/DoExpressCheckoutPayment/success_with_many_items.txt +1 -0
  51. data/spec/fake_response/DoReferenceTransaction/failure.txt +1 -0
  52. data/spec/fake_response/DoReferenceTransaction/success.txt +1 -0
  53. data/spec/fake_response/DoVoid/success.txt +1 -0
  54. data/spec/fake_response/GetExpressCheckoutDetails/failure.txt +1 -0
  55. data/spec/fake_response/GetExpressCheckoutDetails/success.txt +1 -0
  56. data/spec/fake_response/GetExpressCheckoutDetails/with_billing_accepted_status.txt +1 -0
  57. data/spec/fake_response/GetRecurringPaymentsProfileDetails/failure.txt +1 -0
  58. data/spec/fake_response/GetRecurringPaymentsProfileDetails/success.txt +1 -0
  59. data/spec/fake_response/GetTransactionDetails/failure.txt +1 -0
  60. data/spec/fake_response/GetTransactionDetails/success.txt +1 -0
  61. data/spec/fake_response/IPN/invalid.txt +1 -0
  62. data/spec/fake_response/IPN/valid.txt +1 -0
  63. data/spec/fake_response/ManageRecurringPaymentsProfileStatus/failure.txt +1 -0
  64. data/spec/fake_response/ManageRecurringPaymentsProfileStatus/success.txt +1 -0
  65. data/spec/fake_response/RefundTransaction/full.txt +1 -0
  66. data/spec/fake_response/SetExpressCheckout/failure.txt +1 -0
  67. data/spec/fake_response/SetExpressCheckout/success.txt +1 -0
  68. data/spec/helpers/fake_response_helper.rb +29 -0
  69. data/spec/paypal/exception/api_error_spec.rb +105 -0
  70. data/spec/paypal/exception/http_error_spec.rb +20 -0
  71. data/spec/paypal/express/request_spec.rb +578 -0
  72. data/spec/paypal/express/response_spec.rb +89 -0
  73. data/spec/paypal/ipn_spec.rb +19 -0
  74. data/spec/paypal/nvp/request_spec.rb +113 -0
  75. data/spec/paypal/nvp/response_spec.rb +175 -0
  76. data/spec/paypal/payment/common/amount_spec.rb +36 -0
  77. data/spec/paypal/payment/recurring/activation_spec.rb +19 -0
  78. data/spec/paypal/payment/recurring_spec.rb +170 -0
  79. data/spec/paypal/payment/request/item_spec.rb +27 -0
  80. data/spec/paypal/payment/request_spec.rb +136 -0
  81. data/spec/paypal/payment/response/address_spec.rb +26 -0
  82. data/spec/paypal/payment/response/info_spec.rb +93 -0
  83. data/spec/paypal/payment/response/item_spec.rb +78 -0
  84. data/spec/paypal/payment/response/payee_info_spec.rb +24 -0
  85. data/spec/paypal/payment/response/payer_spec.rb +26 -0
  86. data/spec/paypal/payment/response/reference_info_spec.rb +36 -0
  87. data/spec/paypal/payment/response/refund_info_spec.rb +18 -0
  88. data/spec/paypal/payment/response/refund_spec.rb +28 -0
  89. data/spec/paypal/payment/response_spec.rb +29 -0
  90. data/spec/paypal/util_spec.rb +32 -0
  91. data/spec/spec_helper.rb +25 -0
  92. metadata +319 -0
@@ -0,0 +1,89 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Paypal::Express::Response do
4
+ before { fake_response 'SetExpressCheckout/success' }
5
+
6
+ let(:return_url) { 'http://example.com/success' }
7
+ let(:cancel_url) { 'http://example.com/cancel' }
8
+ let :request do
9
+ Paypal::Express::Request.new(
10
+ :username => 'nov',
11
+ :password => 'password',
12
+ :signature => 'sig'
13
+ )
14
+ end
15
+ let :payment_request do
16
+ Paypal::Payment::Request.new(
17
+ :billing_type => :RecurringPayments,
18
+ :billing_agreement_description => 'Recurring Payment Request'
19
+ )
20
+ end
21
+ let(:response) { request.setup payment_request, return_url, cancel_url }
22
+
23
+ describe '#redirect_uri' do
24
+ subject { response.redirect_uri }
25
+ it { is_expected.to include 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' }
26
+ end
27
+
28
+ describe '#popup_uri' do
29
+ subject { response.popup_uri }
30
+ it { is_expected.to include 'https://www.paypal.com/incontext?token=' }
31
+ end
32
+
33
+ context 'when pay_on_paypal option is given' do
34
+ let(:response) { request.setup payment_request, return_url, cancel_url, :pay_on_paypal => true }
35
+
36
+ subject { response }
37
+
38
+ describe '#pay_on_paypal' do
39
+ subject { super().pay_on_paypal }
40
+ it { is_expected.to be_truthy }
41
+ end
42
+
43
+ describe '#query' do
44
+ # FIXME spec on private method
45
+ subject { super().send(:query) }
46
+ it { is_expected.to include(:useraction => 'commit') }
47
+ end
48
+
49
+ describe '#redirect_uri' do
50
+ subject { response.redirect_uri }
51
+ it { is_expected.to include 'useraction=commit' }
52
+ end
53
+
54
+ describe '#popup_uri' do
55
+ subject { response.popup_uri }
56
+ it { is_expected.to include 'useraction=commit' }
57
+ end
58
+ end
59
+
60
+ context 'when sandbox mode' do
61
+ before do
62
+ Paypal.sandbox!
63
+ fake_response 'SetExpressCheckout/success'
64
+ end
65
+ after { Paypal.sandbox = false }
66
+
67
+ describe '#redirect_uri' do
68
+ subject { response.redirect_uri }
69
+ it { is_expected.to include 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' }
70
+ end
71
+
72
+ describe '#popup_uri' do
73
+ subject { response.popup_uri }
74
+ it { is_expected.to include 'https://www.sandbox.paypal.com/incontext?token=' }
75
+ end
76
+ end
77
+
78
+ context 'when mobile option is given' do
79
+ let(:response) { request.setup payment_request, return_url, cancel_url, :mobile => true }
80
+
81
+ subject { response }
82
+
83
+ describe '#redirect_uri' do
84
+ subject { response.redirect_uri }
85
+ it { is_expected.to include 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout-mobile&token=' }
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Paypal::IPN do
4
+ describe '.verify!' do
5
+ context 'when valid' do
6
+ before { fake_response 'IPN/valid', :IPN }
7
+ subject { Paypal::IPN.verify!('raw-post-body') }
8
+ it { is_expected.to be_truthy }
9
+ end
10
+
11
+ context 'when invalid' do
12
+ before { fake_response 'IPN/invalid', :IPN }
13
+ subject {}
14
+ it do
15
+ expect { Paypal::IPN.verify!('raw-post-body') }.to raise_error(Paypal::Exception::APIError)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Paypal::NVP::Request do
4
+ let :attributes do
5
+ {
6
+ :username => 'nov',
7
+ :password => 'password',
8
+ :signature => 'sig'
9
+ }
10
+ end
11
+
12
+ let :instance do
13
+ Paypal::NVP::Request.new attributes
14
+ end
15
+
16
+ describe '.new' do
17
+ context 'when any required parameters are missing' do
18
+ it 'should raise AttrRequired::AttrMissing' do
19
+ attributes.keys.each do |missing_key|
20
+ insufficient_attributes = attributes.reject do |key, value|
21
+ key == missing_key
22
+ end
23
+ expect do
24
+ Paypal::NVP::Request.new insufficient_attributes
25
+ end.to raise_error AttrRequired::AttrMissing
26
+ end
27
+ end
28
+ end
29
+
30
+ context 'when all required parameters are given' do
31
+ it 'should succeed' do
32
+ expect do
33
+ Paypal::NVP::Request.new attributes
34
+ end.not_to raise_error
35
+ end
36
+
37
+ it 'should setup endpoint and version' do
38
+ client = Paypal::NVP::Request.new attributes
39
+ expect(client.class.endpoint).to eq(Paypal::NVP::Request::ENDPOINT[:production])
40
+ end
41
+
42
+ it 'should support sandbox mode' do
43
+ sandbox_mode do
44
+ client = Paypal::NVP::Request.new attributes
45
+ expect(client.class.endpoint).to eq(Paypal::NVP::Request::ENDPOINT[:sandbox])
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'when optional parameters are given' do
51
+ let(:optional_attributes) do
52
+ { :subject => 'user@example.com' }
53
+ end
54
+
55
+ it 'should setup subject' do
56
+ client = Paypal::NVP::Request.new attributes.merge(optional_attributes)
57
+ expect(client.subject).to eq('user@example.com')
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#common_params' do
63
+ [
64
+ [:username, :USER],
65
+ [:password, :PWD],
66
+ [:signature, :SIGNATURE],
67
+ [:subject, :SUBJECT],
68
+ [:version, :VERSION],
69
+ [:version, :version]
70
+ ].each do |method, param_key|
71
+ it "should include :#{param_key}" do
72
+ expect(instance.common_params).to include(param_key)
73
+ end
74
+
75
+ it "should set :#{param_key} to return of ##{method}" do
76
+ expect(instance.common_params[param_key]).to eq(instance.send(method))
77
+ end
78
+ end
79
+ end
80
+
81
+ describe '#request' do
82
+ it 'should POST to NPV endpoint' do
83
+ expect do
84
+ instance.request :RPCMethod
85
+ end.to request_to Paypal::NVP::Request::ENDPOINT[:production], :post
86
+ end
87
+
88
+ context 'when got API error response' do
89
+ before do
90
+ fake_response 'SetExpressCheckout/failure'
91
+ end
92
+
93
+ it 'should raise Paypal::Exception::APIError' do
94
+ expect do
95
+ instance.request :SetExpressCheckout
96
+ end.to raise_error(Paypal::Exception::APIError)
97
+ end
98
+ end
99
+
100
+ context 'when got HTTP error response' do
101
+ before do
102
+ stub_request(:post, Paypal::NVP::Request::ENDPOINT[:production])
103
+ .to_return(body: 'Invalid Request', status: 400)
104
+ end
105
+
106
+ it 'should raise Paypal::Exception::HttpError' do
107
+ expect do
108
+ instance.request :SetExpressCheckout
109
+ end.to raise_error(Paypal::Exception::HttpError)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,175 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Paypal::NVP::Response do
4
+ let(:return_url) { 'http://example.com/success' }
5
+ let(:cancel_url) { 'http://example.com/cancel' }
6
+ let :request do
7
+ Paypal::Express::Request.new(
8
+ :username => 'nov',
9
+ :password => 'password',
10
+ :signature => 'sig'
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
+ expect(Paypal.logger).to 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
+ expect(Paypal.logger).not_to receive(:warn)
52
+ response = request.setup payment_request, return_url, cancel_url
53
+ expect(response.token).to eq('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
+ expect(Paypal.logger).not_to receive(:warn)
64
+ response = request.details 'token'
65
+ expect(response.payer.identifier).to eq('9RWDTMRKKHQ8S')
66
+ expect(response.payment_info.size).to eq(0)
67
+ end
68
+
69
+ it 'records payment response information' do
70
+ response = request.details 'token'
71
+ expect(response.payment_responses.size).to eq(1)
72
+ payment_response = response.payment_responses.first
73
+ expect(payment_response).to be_instance_of(Paypal::Payment::Response)
74
+ expect(payment_response.custom).to eq 'custom'
75
+ expect(payment_response.bill_to.normalization_status).to eq 'None'
76
+ end
77
+
78
+ context 'when BILLINGAGREEMENTACCEPTEDSTATUS included' do
79
+ before do
80
+ fake_response 'GetExpressCheckoutDetails/with_billing_accepted_status'
81
+ end
82
+
83
+ it 'should handle all attributes' do
84
+ expect(Paypal.logger).not_to receive(:warn)
85
+ response = request.details 'token'
86
+ end
87
+ end
88
+ end
89
+
90
+ context 'when DoExpressCheckoutPayment response given' do
91
+ before do
92
+ fake_response 'DoExpressCheckoutPayment/success'
93
+ end
94
+
95
+ it 'should handle all attributes' do
96
+ expect(Paypal.logger).not_to receive(:warn)
97
+ response = request.checkout! 'token', 'payer_id', payment_request
98
+ expect(response.payment_responses.size).to eq(0)
99
+ expect(response.payment_info.size).to eq(1)
100
+ expect(response.payment_info.first).to be_instance_of(Paypal::Payment::Response::Info)
101
+ end
102
+
103
+ context 'when billing_agreement is included' do
104
+ before do
105
+ fake_response 'DoExpressCheckoutPayment/success_with_billing_agreement'
106
+ end
107
+
108
+ it 'should have billing_agreement' do
109
+ expect(Paypal.logger).not_to receive(:warn)
110
+ response = request.checkout! 'token', 'payer_id', payment_request
111
+ expect(response.billing_agreement.identifier).to eq('B-1XR87946TC504770W')
112
+ end
113
+ end
114
+ end
115
+
116
+ context 'when CreateRecurringPaymentsProfile response given' do
117
+ before do
118
+ fake_response 'CreateRecurringPaymentsProfile/success'
119
+ end
120
+
121
+ it 'should handle all attributes' do
122
+ expect(Paypal.logger).not_to receive(:warn)
123
+ response = request.subscribe! 'token', recurring_profile
124
+ expect(response.recurring.identifier).to eq('I-L8N58XFUCET3')
125
+ end
126
+ end
127
+
128
+ context 'when GetRecurringPaymentsProfileDetails response given' do
129
+ before do
130
+ fake_response 'GetRecurringPaymentsProfileDetails/success'
131
+ end
132
+
133
+ it 'should handle all attributes' do
134
+ expect(Paypal.logger).not_to receive(:warn)
135
+ response = request.subscription 'profile_id'
136
+ expect(response.recurring.billing.amount.total).to eq(1000)
137
+ expect(response.recurring.regular_billing.paid).to eq(1000)
138
+ expect(response.recurring.summary.next_billing_date).to eq('2011-03-04T10:00:00Z')
139
+ end
140
+ end
141
+
142
+ context 'when ManageRecurringPaymentsProfileStatus response given' do
143
+ before do
144
+ fake_response 'ManageRecurringPaymentsProfileStatus/success'
145
+ end
146
+
147
+ it 'should handle all attributes' do
148
+ expect(Paypal.logger).not_to receive(:warn)
149
+ request.renew! 'profile_id', :Cancel
150
+ end
151
+ end
152
+
153
+ context 'when RefundTransaction response given' do
154
+ before do
155
+ fake_response 'RefundTransaction/full'
156
+ end
157
+
158
+ it 'should handle all attributes' do
159
+ expect(Paypal.logger).not_to receive(:warn)
160
+ request.refund! 'transaction-id'
161
+ end
162
+ end
163
+
164
+ context 'when BillAgreementUpdate (BAUpdate) cancellation response given' do
165
+ before do
166
+ fake_response 'BillAgreementUpdate/revoke'
167
+ end
168
+
169
+ it 'should handle all attributes' do
170
+ expect(Paypal.logger).not_to receive(:warn)
171
+ request.revoke! 'transaction-id'
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Paypal::Payment::Common::Amount do
4
+ let :keys do
5
+ Paypal::Payment::Common::Amount.optional_attributes
6
+ end
7
+
8
+ describe '.new' do
9
+ it 'should not allow nil for attributes' do
10
+ amount = Paypal::Payment::Common::Amount.new
11
+ keys.each do |key|
12
+ expect(amount.send(key)).to eq(0)
13
+ end
14
+ end
15
+
16
+ it 'should treat all attributes as Numeric' do
17
+ # Integer
18
+ attributes = keys.inject({}) do |attributes, key|
19
+ attributes.merge!(key => "100")
20
+ end
21
+ amount = Paypal::Payment::Common::Amount.new attributes
22
+ keys.each do |key|
23
+ expect(amount.send(key)).to eq(100)
24
+ end
25
+
26
+ # Float
27
+ attributes = keys.inject({}) do |attributes, key|
28
+ attributes.merge!(key => "10.25")
29
+ end
30
+ amount = Paypal::Payment::Common::Amount.new attributes
31
+ keys.each do |key|
32
+ expect(amount.send(key)).to eq(10.25)
33
+ end
34
+ end
35
+ end
36
+ 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
+ expect(instance.to_params).to eq({
14
+ :INITAMT => '100.00',
15
+ :FAILEDINITAMTACTION => 'ContinueOnFailure'
16
+ })
17
+ end
18
+ end
19
+ end