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