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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fb8b050d216c855ccf68536d06120313331ff5d3
4
+ data.tar.gz: 210a993a47e065ff709785bf0a31921c4b3db024
5
+ SHA512:
6
+ metadata.gz: efbeb055a9260ff379014425e3b0a07c99e198c69963b1389b868a2615770f4834cf432093667ec17ea556400efc7e9f6a6442403ff24a2d9ec43f27119219fa
7
+ data.tar.gz: 4ab800c3df207994194831fd78333799c26f800cc029de773975639a85762cb32ee3fce61093ac8dbd2282d409a6820548198c614bb6e6b634c0f5fff777a038
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ .DS_Store
2
+ pkg
3
+ tmp
4
+ examples
5
+ .bundle
6
+ db/*.sqlite3*
7
+ log/*.log
8
+ *.log
9
+ tmp/**/*
10
+ tmp/*
11
+ doc/api
12
+ doc/app
13
+ *.swp
14
+ *~
15
+ .DS_Store
16
+ .rvmrc
17
+
18
+ .idea/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,46 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ paypal-recurring (1.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activesupport (3.2.3)
10
+ i18n (~> 0.6)
11
+ multi_json (~> 1.0)
12
+ awesome_print (1.0.2)
13
+ coderay (1.0.6)
14
+ diff-lcs (1.1.3)
15
+ fakeweb (1.3.0)
16
+ i18n (0.6.0)
17
+ method_source (0.7.1)
18
+ multi_json (1.3.2)
19
+ pry (0.9.9.3)
20
+ coderay (~> 1.0.5)
21
+ method_source (~> 0.7.1)
22
+ slop (>= 2.4.4, < 3)
23
+ rake (0.9.2.2)
24
+ rspec (2.10.0)
25
+ rspec-core (~> 2.10.0)
26
+ rspec-expectations (~> 2.10.0)
27
+ rspec-mocks (~> 2.10.0)
28
+ rspec-core (2.10.1)
29
+ rspec-expectations (2.10.0)
30
+ diff-lcs (~> 1.1.3)
31
+ rspec-mocks (2.10.1)
32
+ slop (2.4.4)
33
+ vcr (2.1.0)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ activesupport
40
+ awesome_print
41
+ fakeweb
42
+ paypal-recurring!
43
+ pry
44
+ rake
45
+ rspec
46
+ vcr
data/README.rdoc ADDED
@@ -0,0 +1,144 @@
1
+ = PayPal Recurring Billing
2
+
3
+ PayPal Express Checkout API Client for recurring billing.
4
+
5
+ == Installation
6
+
7
+ gem install paypal-recurring
8
+
9
+ == Usage
10
+
11
+ First, you need to set up your credentials:
12
+
13
+ require "paypal/recurring"
14
+
15
+ PayPal::Recurring.configure do |config|
16
+ config.sandbox = true
17
+ config.username = "seller_1308793919_biz_api1.simplesideias.com.br"
18
+ config.password = "1308793931"
19
+ config.signature = "AFcWxV21C7fd0v3bYYYRCpSSRl31AzaB6TzXx5amObyEghjU13.0av2Y"
20
+ end
21
+
22
+ Then, you can request a new payment authorization:
23
+
24
+ ppr = PayPal::Recurring.new({
25
+ :return_url => "http://example.com/paypal/thank_you",
26
+ :cancel_url => "http://example.com/paypal/canceled",
27
+ :ipn_url => "http://example.com/paypal/ipn",
28
+ :description => "Awesome - Monthly Subscription",
29
+ :amount => "9.00",
30
+ :currency => "USD"
31
+ })
32
+
33
+ response = ppr.checkout
34
+ puts response.checkout_url if response.valid?
35
+
36
+ You need to redirect your user to the url returned by <tt>response.checkout_url</tt>.
37
+ After the user accepts or rejects your payment request, he will be redirected to one of those urls you specified.
38
+ The return url will receive two parameters: <tt>PAYERID</tt> and <tt>TOKEN</tt>. You can use the <tt>TOKEN</tt>
39
+ parameter to identify your user on your database.
40
+
41
+ If you need to retrieve information about your buyer, like address or e-mail, you can use the
42
+ <tt>checkout_details()</tt> method.
43
+
44
+ ppr = PayPal::Recurring.new(:token => "EC-05C46042TU8306821")
45
+ response = ppr.checkout_details
46
+
47
+ Now, you need to request payment. The information you provide here should be exactly the same when you started
48
+ the checkout process.
49
+
50
+ ppr = PayPal::Recurring.new({
51
+ :token => "EC-05C46042TU8306821",
52
+ :payer_id => "WTTS5KC2T46YU",
53
+ :amount => "9.00",
54
+ :description => "Awesome - Monthly Subscription"
55
+ })
56
+ response = ppr.request_payment
57
+ response.approved?
58
+ response.completed?
59
+
60
+ Finally, you need to create a new recurring profile.
61
+
62
+ ppr = PayPal::Recurring.new({
63
+ :amount => "9.00",
64
+ :currency => "USD",
65
+ :description => "Awesome - Monthly Subscription",
66
+ :ipn_url => "http://example.com/paypal/ipn",
67
+ :frequency => 1,
68
+ :token => "EC-05C46042TU8306821",
69
+ :period => :monthly,
70
+ :reference => "1234",
71
+ :payer_id => "WTTS5KC2T46YU",
72
+ :start_at => Time.now,
73
+ :failed => 1,
74
+ :outstanding => :next_billing
75
+ })
76
+
77
+ response = ppr.create_recurring_profile
78
+ puts response.profile_id
79
+
80
+ (Optionally) You can specify a trial period, frequency, and length.
81
+
82
+ ppr = PayPal::Recurring.new({
83
+ :amount => "9.00",
84
+ :currency => "USD",
85
+ :description => "Awesome - Monthly Subscription",
86
+ :ipn_url => "http://example.com/paypal/ipn",
87
+ :frequency => 1,
88
+ :token => "EC-05C46042TU8306821",
89
+ :period => :monthly,
90
+ :reference => "1234",
91
+ :payer_id => "WTTS5KC2T46YU",
92
+ :start_at => Time.now,
93
+ :failed => 1,
94
+ :outstanding => :next_billing,
95
+ :trial_length => 1,
96
+ :trial_period => :monthly,
97
+ :trial_frequency => 1
98
+ })
99
+
100
+ You can manage your recurring profile.
101
+
102
+ ppr = PayPal::Recurring.new(:profile_id => "I-VCEL6TRG35CU")
103
+
104
+ ppr.suspend
105
+ ppr.reactivate
106
+ ppr.cancel
107
+
108
+ === What information do I need to keep?
109
+
110
+ You should save two paramaters to your database: <tt>TOKEN</tt> and <tt>PROFILEID</tt>.
111
+ <tt>TOKEN</tt> is required when user returns to your website after he authorizes (or not) the billing process. You
112
+ need to save it so you can find him later. You can remove this info after payment and recurring profile are set.
113
+
114
+ The <tt>PROFILEID</tt> allows you to manage the recurring profile, like cancelling billing when an user don't
115
+ want to use your service anymore.
116
+
117
+ <b>NOTE:</b> TOKEN will expire after approximately 3 hours.
118
+
119
+ == Maintainer
120
+
121
+ * Nando Vieira (http://nandovieira.com.br)
122
+
123
+ == License
124
+
125
+ (The MIT License)
126
+
127
+ Permission is hereby granted, free of charge, to any person obtaining
128
+ a copy of this software and associated documentation files (the
129
+ 'Software'), to deal in the Software without restriction, including
130
+ without limitation the rights to use, copy, modify, merge, publish,
131
+ distribute, sublicense, and/or sell copies of the Software, and to
132
+ permit persons to whom the Software is furnished to do so, subject to
133
+ the following conditions:
134
+
135
+ The above copyright notice and this permission notice shall be
136
+ included in all copies or substantial portions of the Software.
137
+
138
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
139
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
140
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
141
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
142
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
143
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
144
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec/core/rake_task"
5
+ RSpec::Core::RakeTask.new
Binary file
Binary file
@@ -0,0 +1 @@
1
+ require "paypal/recurring"
@@ -0,0 +1,110 @@
1
+ require "net/https"
2
+ require "cgi"
3
+ require "uri"
4
+ require "ostruct"
5
+ require "time"
6
+
7
+ module PayPal
8
+ module Recurring
9
+ autoload :Base, "paypal/recurring/base"
10
+ autoload :Notification, "paypal/recurring/notification"
11
+ autoload :Request, "paypal/recurring/request"
12
+ autoload :Response, "paypal/recurring/response"
13
+ autoload :Version, "paypal/recurring/version"
14
+ autoload :Utils, "paypal/recurring/utils"
15
+
16
+ ENDPOINTS = {
17
+ :sandbox => {
18
+ :api => "https://api-3t.sandbox.paypal.com/nvp",
19
+ :site => "https://www.sandbox.paypal.com/cgi-bin/webscr"
20
+ },
21
+ :production => {
22
+ :api => "https://api-3t.paypal.com/nvp",
23
+ :site => "https://www.paypal.com/cgi-bin/webscr"
24
+ }
25
+ }
26
+
27
+ class << self
28
+ # Define if requests should be made to PayPal's
29
+ # sandbox environment. This is specially useful when running
30
+ # on development or test mode.
31
+ #
32
+ # PayPal::Recurring.sandbox = true
33
+ #
34
+ attr_accessor :sandbox
35
+
36
+ # Set PayPal's API username.
37
+ #
38
+ attr_accessor :username
39
+
40
+ # Set PayPal's API password.
41
+ #
42
+ attr_accessor :password
43
+
44
+ # Set PayPal's API signature.
45
+ #
46
+ attr_accessor :signature
47
+
48
+ # Set seller id. Will be used to verify IPN.
49
+ #
50
+ #
51
+ attr_accessor :seller_id
52
+
53
+ # The seller e-mail. Will be used to verify IPN.
54
+ #
55
+ attr_accessor :email
56
+ end
57
+
58
+ # Just a shortcut for <tt>PayPal::Recurring::Base.new</tt>.
59
+ #
60
+ def self.new(options = {})
61
+ Base.new(options)
62
+ end
63
+
64
+ # Configure PayPal::Recurring options.
65
+ #
66
+ # PayPal::Recurring.configure do |config|
67
+ # config.sandbox = true
68
+ # end
69
+ #
70
+ def self.configure(&block)
71
+ yield PayPal::Recurring
72
+ end
73
+
74
+ # Detect if sandbox mode is enabled.
75
+ #
76
+ def self.sandbox?
77
+ sandbox == true
78
+ end
79
+
80
+ # Return a name for current environment mode (sandbox or production).
81
+ #
82
+ def self.environment
83
+ sandbox? ? :sandbox : :production
84
+ end
85
+
86
+ # Return URL endpoints for current environment.
87
+ #
88
+ def self.endpoints
89
+ ENDPOINTS[environment]
90
+ end
91
+
92
+ # Return API endpoint based on current environment.
93
+ #
94
+ def self.api_endpoint
95
+ endpoints[:api]
96
+ end
97
+
98
+ # Return PayPal's API version.
99
+ #
100
+ def self.api_version
101
+ "72.0"
102
+ end
103
+
104
+ # Return site endpoint based on current environment.
105
+ #
106
+ def self.site_endpoint
107
+ endpoints[:site]
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,286 @@
1
+ module PayPal
2
+ module Recurring
3
+ class Base
4
+ attr_accessor :amount
5
+ attr_accessor :cancel_url
6
+ attr_accessor :currency
7
+ attr_accessor :description
8
+ attr_accessor :note
9
+ attr_accessor :email
10
+ attr_accessor :failed
11
+ attr_accessor :frequency
12
+ attr_accessor :initial_amount
13
+ attr_accessor :initial_amount_action
14
+ attr_accessor :ipn_url
15
+ attr_accessor :locale
16
+ attr_accessor :outstanding
17
+ attr_accessor :payer_id
18
+ attr_accessor :period
19
+ attr_accessor :profile_id
20
+ attr_accessor :reference
21
+ attr_accessor :refund_type
22
+ attr_accessor :return_url
23
+ attr_accessor :start_at
24
+ attr_accessor :token
25
+ attr_accessor :transaction_id
26
+ attr_accessor :item_category
27
+ attr_accessor :item_name
28
+ attr_accessor :item_amount
29
+ attr_accessor :item_quantity
30
+ attr_accessor :trial_frequency
31
+ attr_accessor :trial_length
32
+ attr_accessor :trial_period
33
+ attr_accessor :trial_amount
34
+ attr_accessor :brand_name
35
+ attr_accessor :page_style
36
+
37
+ def initialize(options = {})
38
+ options.each {|name, value| send("#{name}=", value)}
39
+ end
40
+
41
+ # Just a shortcut convenience.
42
+ #
43
+ def request # :nodoc:
44
+ @request ||= Request.new
45
+ end
46
+
47
+ # Request a checkout token.
48
+ #
49
+ # ppr = PayPal::Recurring.new({
50
+ # :return_url => "http://example.com/checkout/thank_you",
51
+ # :cancel_url => "http://example.com/checkout/canceled",
52
+ # :ipn_url => "http://example.com/paypal/ipn",
53
+ # :description => "Awesome - Monthly Subscription",
54
+ # :amount => "9.00",
55
+ # :currency => "USD"
56
+ # })
57
+ #
58
+ # response = ppr.request_token
59
+ # response.checkout_url
60
+ #
61
+ def checkout
62
+ params = collect(
63
+ :locale,
64
+ :amount,
65
+ :return_url,
66
+ :cancel_url,
67
+ :currency,
68
+ :description,
69
+ :ipn_url,
70
+ :item_category,
71
+ :item_name,
72
+ :item_amount,
73
+ :item_quantity,
74
+ :brand_name,
75
+ :page_style,
76
+ ).merge(
77
+ :payment_action => "Authorization",
78
+ :no_shipping => 1,
79
+ :L_BILLINGTYPE0 => "RecurringPayments"
80
+ )
81
+
82
+ request.run(:checkout, params)
83
+ end
84
+
85
+ # Suspend a recurring profile.
86
+ # Suspended profiles can be reactivated.
87
+ #
88
+ # ppr = PayPal::Recurring.new(:profile_id => "I-HYRKXBMNLFSK")
89
+ # response = ppr.suspend
90
+ #
91
+ def suspend
92
+ request.run(:manage_profile, :action => :suspend, :profile_id => profile_id)
93
+ end
94
+
95
+ # Reactivate a suspended recurring profile.
96
+ #
97
+ # ppr = PayPal::Recurring.new(:profile_id => "I-HYRKXBMNLFSK")
98
+ # response = ppr.reactivate
99
+ #
100
+ def reactivate
101
+ request.run(:manage_profile, :action => :reactivate, :profile_id => profile_id)
102
+ end
103
+
104
+ # Cancel a recurring profile.
105
+ # Cancelled profiles cannot be reactivated.
106
+ #
107
+ # ppr = PayPal::Recurring.new(:profile_id => "I-HYRKXBMNLFSK")
108
+ # response = ppr.cancel
109
+ #
110
+ def cancel
111
+ request.run(:manage_profile, :action => :cancel, :profile_id => profile_id)
112
+ end
113
+
114
+ # Return checkout details.
115
+ #
116
+ # ppr = PayPal::Recurring.new(:token => "EC-6LX60229XS426623E")
117
+ # response = ppr.checkout_details
118
+ #
119
+ def checkout_details
120
+ request.run(:details, :token => token)
121
+ end
122
+
123
+ # Request payment.
124
+ #
125
+ # # ppr = PayPal::Recurring.new({
126
+ # :token => "EC-6LX60229XS426623E",
127
+ # :payer_id => "WTTS5KC2T46YU",
128
+ # :amount => "9.00",
129
+ # :description => "Awesome - Monthly Subscription"
130
+ # })
131
+ # response = ppr.request_payment
132
+ # response.completed? && response.approved?
133
+ #
134
+ def request_payment
135
+ params = collect(
136
+ :amount,
137
+ :return_url,
138
+ :cancel_url,
139
+ :ipn_url,
140
+ :currency,
141
+ :description,
142
+ :payer_id,
143
+ :token,
144
+ :reference,
145
+ :item_category,
146
+ :item_name,
147
+ :item_amount,
148
+ :item_quantity
149
+ ).merge(:payment_action => "Sale")
150
+
151
+ request.run(:payment, params)
152
+ end
153
+
154
+ # Create a recurring billing profile.
155
+ #
156
+ # ppr = PayPal::Recurring.new({
157
+ # :amount => "9.00",
158
+ # :initial_amount => "9.00",
159
+ # :initial_amount_action => :cancel,
160
+ # :currency => "USD",
161
+ # :description => "Awesome - Monthly Subscription",
162
+ # :ipn_url => "http://example.com/paypal/ipn",
163
+ # :frequency => 1,
164
+ # :token => "EC-05C46042TU8306821",
165
+ # :period => :monthly,
166
+ # :reference => "1234",
167
+ # :payer_id => "WTTS5KC2T46YU",
168
+ # :start_at => Time.now,
169
+ # :failed => 1,
170
+ # :outstanding => :next_billing,
171
+ # :trial_period => :monthly,
172
+ # :trial_length => 1,
173
+ # :trial_frequency => 1,
174
+ # :trial_amount => 0.00
175
+ # })
176
+ #
177
+ # response = ppr.create_recurring_profile
178
+ #
179
+ def create_recurring_profile
180
+ params = collect(
181
+ :amount,
182
+ :initial_amount,
183
+ :initial_amount_action,
184
+ :currency,
185
+ :description,
186
+ :payer_id,
187
+ :token,
188
+ :reference,
189
+ :start_at,
190
+ :failed,
191
+ :outstanding,
192
+ :ipn_url,
193
+ :frequency,
194
+ :period,
195
+ :email,
196
+ :trial_length,
197
+ :trial_period,
198
+ :trial_frequency,
199
+ :trial_amount,
200
+ :item_category,
201
+ :item_name,
202
+ :item_amount,
203
+ :item_quantity
204
+ )
205
+ request.run(:create_profile, params)
206
+ end
207
+
208
+ # Update a recurring billing profile.
209
+ #
210
+ # ppr = PayPal::Recurring.new({
211
+ # :amount => "99.00",
212
+ # :currency => "USD",
213
+ # :description => "Awesome - Monthly Subscription",
214
+ # :note => "Changed plan to Gold",
215
+ # :ipn_url => "http://example.com/paypal/ipn",
216
+ # :reference => "1234",
217
+ # :profile_id => "I-VCEL6TRG35CU",
218
+ # :start_at => Time.now,
219
+ # :outstanding => :next_billing
220
+ # })
221
+ #
222
+ # response = ppr.update_recurring_profile
223
+ #
224
+ def update_recurring_profile
225
+ params = collect(
226
+ :amount,
227
+ :currency,
228
+ :description,
229
+ :note,
230
+ :profile_id,
231
+ :reference,
232
+ :start_at,
233
+ :outstanding,
234
+ :ipn_url,
235
+ :email
236
+ )
237
+
238
+ request.run(:update_profile, params)
239
+ end
240
+
241
+ # Retrieve information about existing recurring profile.
242
+ #
243
+ # ppr = PayPal::Recurring.new(:profile_id => "I-VCEL6TRG35CU")
244
+ # response = ppr.profile
245
+ #
246
+ def profile
247
+ request.run(:profile, :profile_id => profile_id)
248
+ end
249
+
250
+ # Request a refund.
251
+ # ppr = PayPal::Recurring.new({
252
+ # :profile_id => "I-VCEL6TRG35CU",
253
+ # :transaction_id => "ABCEDFGH",
254
+ # :reference => "1234",
255
+ # :refund_type => :partial,
256
+ # :amount => "9.00",
257
+ # :currency => "USD"
258
+ # })
259
+ # response = ppr.refund
260
+ #
261
+ def refund
262
+ params = collect(
263
+ :transaction_id,
264
+ :reference,
265
+ :refund_type,
266
+ :amount,
267
+ :currency,
268
+ :note
269
+ )
270
+
271
+ request.run(:refund, params)
272
+ end
273
+
274
+ private
275
+ # Collect specified attributes and build a hash out of it.
276
+ #
277
+ def collect(*args) # :nodoc:
278
+ args.inject({}) do |buffer, attr_name|
279
+ value = send(attr_name)
280
+ buffer[attr_name] = value if value
281
+ buffer
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end