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