active_paypal_adaptive_payment 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ ## 0.2.1
2
+
3
+ - Removed action pack as a dependency
4
+
5
+ ## 0.2.0
6
+
7
+ - Fix tests.
8
+ - Added fixtures.yml.
9
+
10
+ ## 0.1.2
11
+
12
+ - Few typo fixes by LeviRosol
@@ -1,308 +1,299 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  dir = File.dirname(__FILE__)
3
- require dir + '/paypal_adaptive_payments/ext.rb'
4
- require dir + '/paypal_adaptive_payments/utils.rb'
5
- require dir + '/paypal_adaptive_payments/exceptions.rb'
6
- require dir + '/paypal_adaptive_payments/adaptive_payment_response.rb'
7
- require 'json/add/rails'
3
+ [ '/paypal_adaptive_payments/exceptions.rb',
4
+ '/paypal_adaptive_payments/adaptive_payment_response.rb',
5
+ '/paypal_adaptive_payments/ext.rb'
6
+ ].each { |f| require File.join(dir, f) }
8
7
 
9
- module ActiveMerchant; module Billingl class PaypalAdaptivePaymentGateway < Gateway
8
+ require 'money'
10
9
 
11
- include AdaptivePaymentResponses
12
- include AdaptiveUtils
10
+ module ActiveMerchant #:nodoc:
11
+ module Billing #:nodoc:
12
+ class PaypalAdaptivePayment < Gateway # :nodoc:
13
13
 
14
- TEST_URL = 'https://svcs.sandbox.paypal.com/AdaptivePayments/'
15
- LIVE_URL = 'https://svcs.paypal.com/AdaptivePayments/'
14
+ TEST_URL = 'https://svcs.sandbox.paypal.com/AdaptivePayments/'
15
+ LIVE_URL = 'https://svcs.paypal.com/AdaptivePayments/'
16
16
 
17
- # The countries the gateway supports merchants from as 2 digit ISO country codes
18
- self.supported_countries = ['US']
17
+ EMBEDDED_FLOW_TEST_URL = 'https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/pay'
18
+ EMBEDDED_FLOW_LIVE_URL = 'https://www.paypal.com/webapps/adaptivepayment/flow/pay'
19
19
 
20
- # The homepage URL of the gateway
21
- self.homepage_url = 'http://x.com/'
20
+ module FeesPayer
21
+ OPTIONS = %w(SENDER PRIMARYRECEIVER EACHRECEIVER SECONDARYONLY)
22
+ OPTIONS.each { |opt| const_set(opt, opt) }
23
+ end
22
24
 
23
- # The name of the gateway
24
- self.display_name = 'Paypal Adaptive Payments'
25
+ module PaymentType
26
+ TYPES = %w(DIGITALGOODS)
27
+ TYPES.each { |pt| const_set(pt, pt) }
28
+ end
25
29
 
26
- attr_accessor :config_path
27
- @config_path = "#{RAILS_ROOT}/config/paypal.yml"
30
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
31
+ self.supported_countries = ['US']
28
32
 
29
- def initialize(options = {})
30
- @config = {}
31
- if options.empty?
32
- load_config
33
- else
34
- @config.merge! options
35
- end
36
- end
33
+ # The homepage URL of the gateway
34
+ self.homepage_url = 'http://x.com/'
37
35
 
38
- def pay(options)
39
- commit 'Pay', build_adaptive_payment_pay_request(options)
40
- end
36
+ # The name of the gateway
37
+ self.display_name = 'Paypal Adaptive Payments'
41
38
 
42
- def details_for_payment options
43
- commit 'PaymentDetails', build_adaptive_payment_details_request(options)
44
- end
39
+ def initialize(config = {})
40
+ requires!(config, :login, :password, :signature, :appid)
41
+ @config = config.dup
42
+ super
43
+ end
45
44
 
46
- def refund options
47
- commit 'Refund', build_adaptive_refund_details(options)
48
- end
45
+ def pay(options)
46
+ commit('Pay', build_adaptive_payment_pay_request(options))
47
+ end
49
48
 
50
- # Send a preapproval request to pay pal
51
- #
52
- # ==== Options
53
- #
54
- # * +:end_date+ - _xs:datetime_ The ending date
55
- # * +:start_date+ - _xs:datetime_ The start date (defaults: current)
56
- # * +:max_amount+ - _xs:decimal_ The preapproved maximum total amount of all payments.
57
- # * +:currency_code+ - The currency code (defaults: USD)
58
- # * +:cancel_url+ - URL to redirect the sender’s browser to after canceling the preapproval
59
- # * +:return_url+ - URL to redirect the sender’s browser to after the sender has logged into PayPal and confirmed the preapproval
60
- # * +:notify_url+ - The URL to which you want all IPN messages for this preapproval to be sent. (Optional)
61
- #
62
- # To get more details on fields see +Paypal PreApproval API+ at https://www.x.com/docs/DOC-1419
63
- def preapprove_payment options
64
- commit 'Preapproval', build_preapproval_payment(options)
65
- end
49
+ def details_for_payment(options)
50
+ commit('PaymentDetails', build_adaptive_payment_details_request(options))
51
+ end
66
52
 
67
- def cancel_preapproval options
68
- commit 'CancelPreapproval', build_cancel_preapproval(options)
69
- end
53
+ def refund(options)
54
+ commit('Refund', build_adaptive_refund_details(options))
55
+ end
70
56
 
71
- def preapproval_details_for options
72
- commit 'PreapprovalDetails', build_preapproval_details(options)
73
- end
57
+ # Send a preapproval request to pay pal
58
+ #
59
+ # ==== Options
60
+ #
61
+ # * +:end_date+ - _xs:datetime_ The ending date
62
+ # * +:start_date+ - _xs:datetime_ The start date (defaults: current)
63
+ # * +:max_amount+ - _xs:decimal_ The preapproved maximum total amount of all payments.
64
+ # * +:currency_code+ - The currency code (defaults: USD)
65
+ # * +:cancel_url+ - URL to redirect the sender’s browser to after canceling the preapproval
66
+ # * +:return_url+ - URL to redirect the sender’s browser to after the sender has logged into PayPal and confirmed the preapproval
67
+ # * +:notify_url+ - The URL to which you want all IPN messages for this preapproval to be sent. (Optional)
68
+ #
69
+ # To get more details on fields see +Paypal PreApproval API+ at https://www.x.com/docs/DOC-1419
70
+ def preapprove_payment(options)
71
+ commit('Preapproval', build_preapproval_payment(options))
72
+ end
74
73
 
75
- def convert_currency options
76
- commit 'ConvertCurrency', build_currency_conversion(options)
77
- end
74
+ def cancel_preapproval(options)
75
+ commit('CancelPreapproval', build_cancel_preapproval(options))
76
+ end
78
77
 
79
- #debug method, provides an easy to use debug method for the class
80
- def debug
81
- "Url: #{@url}\n\n JSON: #{@xml} \n\n Raw: #{@raw}"
82
- end
78
+ def preapproval_details_for(options)
79
+ commit('PreapprovalDetails', build_preapproval_details(options))
80
+ end
83
81
 
84
- private
82
+ def convert_currency(options)
83
+ commit('ConvertCurrency', build_currency_conversion(options))
84
+ end
85
85
 
86
- #loads config from default file if it is not provided to the constructor
87
- def load_config
88
- raise ConfigDoesNotExist if !File.exists?(@config_path);
89
- @config.merge! Yaml.load_file(@config_path)[RAILS_ENV].symbolize_keys!
90
- end
86
+ def embedded_flow_url
87
+ test? ? EMBEDDED_FLOW_TEST_URL : EMBEDDED_FLOW_LIVE_URL
88
+ end
91
89
 
92
- def build_adaptive_payment_pay_request opts
93
- @xml = ''
94
- xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
95
- xml.instruct!
96
- xml.PayRequest do |x|
97
- x.requestEnvelope do |x|
98
- x.detailLevel 'ReturnAll'
99
- x.errorLanguage opts[:error_language] ||= 'en_US'
90
+ #debug method, provides an easy to use debug method for the class
91
+ def debug
92
+ "Url: #{@url}\n\n Request: #{@xml} \n\n Response: #{@response.json}"
100
93
  end
101
- x.actionType 'PAY'
102
- x.senderEmail opts[:senderEmail]
103
- x.cancelUrl opts[:cancel_url]
104
- x.returnUrl opts[:return_url]
105
- if opts[:notify_url]
106
- x.ipnNotificationUrl opts[:notify_url]
94
+
95
+ private
96
+ def build_adaptive_payment_pay_request(opts)
97
+ @xml = ''
98
+ xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
99
+ xml.instruct!
100
+ xml.PayRequest do |x|
101
+ x.requestEnvelope do |x|
102
+ x.detailLevel 'ReturnAll'
103
+ x.errorLanguage opts[:error_language] ||= 'en_US'
104
+ end
105
+ x.actionType 'PAY'
106
+ x.senderEmail opts[:sender_email] if opts.key?(:sender_email)
107
+ x.cancelUrl opts[:cancel_url]
108
+ x.returnUrl opts[:return_url]
109
+ x.ipnNotificationUrl opts[:ipn_notification_url] if opts[:ipn_notification_url]
110
+ x.memo opts[:memo] if opts.key?(:memo)
111
+ x.feesPayer opts[:fees_payer] if opts[:fees_payer]
112
+ x.pin opts[:pin] if opts[:pin]
113
+ x.currencyCode opts[:currency_code] ||= 'USD'
114
+ x.receiverList do |x|
115
+ opts[:receiver_list].each do |receiver|
116
+ x.receiver do |x|
117
+ x.email receiver[:email]
118
+ x.amount receiver[:amount].to_s
119
+ x.primary receiver[:primary] if receiver.key?(:primary)
120
+ x.paymentType receiver[:payment_type] if receiver.key?(:payment_type)
121
+ x.invoiceId receiver[:invoice_id] if receiver.key?(:invoice_id)
122
+ end
123
+ end
124
+ end
125
+ x.reverseAllParallelPaymentsOnError opts[:reverse_all_parallel_payments_on_error] || 'false'
126
+ x.trackingId opts[:tracking_id] if opts[:tracking_id]
127
+ end
107
128
  end
108
- x.memo opts[:memo] if opts[:memo]
109
- x.feesPayer opts[:feesPayer] if opts[:feesPayer]
110
- x.pin opts[:pin] if opts[:pin]
111
- x.currencyCode opts[:currency_code] ||= 'USD'
112
- x.receiverList do |x|
113
- opts[:receiver_list].each do |receiver|
114
- x.receiver do |x|
115
- x.email receiver[:email]
116
- x.amount currency_to_two_places(receiver[:amount])
117
- x.primary receiver[:primary] if receiver[:primary]
118
- x.paymentType receiver[:payment_type] ||= 'GOODS'
119
- x.invoiceId receiver[:invoice_id] if receiver[:invoice_id]
129
+
130
+ def build_adaptive_payment_details_request(opts)
131
+ @xml = ''
132
+ xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
133
+ xml.instruct!
134
+ xml.PayRequest do |x|
135
+ x.requestEnvelope do |x|
136
+ x.detailLevel 'ReturnAll'
137
+ x.errorLanguage opts[:error_language] ||= 'en_US'
120
138
  end
139
+ x.payKey opts[:paykey]
121
140
  end
122
141
  end
123
- x.reverseAllParallelPaymentsOnError opts[:reverse_all_parallel_payments_on_error] || 'false'
124
- end
125
- end
126
142
 
127
- def build_adaptive_payment_details_request opts
128
- @xml = ''
129
- xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
130
- xml.instruct!
131
- xml.PayRequest do |x|
132
- x.requestEnvelope do |x|
133
- x.detailLevel 'ReturnAll'
134
- x.errorLanguage opts[:error_language] ||= 'en_US'
143
+ def build_adaptive_refund_details(options)
144
+ @xml = ''
145
+ xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
146
+ xml.instruct!
147
+ xml.RefundRequest do |x|
148
+ x.requestEnvelope do |x|
149
+ x.detailLevel 'ReturnAll'
150
+ x.errorLanguage options[:error_language] ||= 'en_US'
151
+ end
152
+ x.actionType 'REFUND'
153
+ if options[:pay_key]
154
+ x.payKey options[:pay_key]
155
+ end
156
+ if options[:transaction_id]
157
+ x.payKey options[:transaction_id]
158
+ end
159
+ if options[:tracking_id]
160
+ x.trackingId options[:tracking_id]
161
+ end
162
+ x.cancelUrl options[:cancel_url]
163
+ x.returnUrl options[:return_url]
164
+ x.currencyCode options[:currency_code] ||= 'USD'
165
+ x.receiverList do |x|
166
+ options[:receiver_list].each do |receiver|
167
+ x.receiver do |x|
168
+ x.amount receiver[:amount]
169
+ x.paymentType receiver[:payment_type] ||= 'GOODS'
170
+ x.invoiceId receiver[:invoice_id] if receiver[:invoice_id]
171
+ x.email receiver[:email]
172
+ end
173
+ end
174
+ end
175
+ x.feesPayer options[:fees_payer] ||= 'EACHRECEIVER'
176
+ end
135
177
  end
136
- x.payKey opts[:paykey]
137
- end
138
- end
139
178
 
140
- def build_adaptive_refund_details options
141
- @xml = ''
142
- xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
143
- xml.instruct!
144
- xml.RefundRequest do |x|
145
- x.requestEnvelope do |x|
146
- x.detailLevel 'ReturnAll'
147
- x.errorLanguage options[:error_language] ||= 'en_US'
148
- end
149
- x.actionType 'REFUND'
150
- if options[:pay_key]
151
- x.payKey options[:pay_key]
152
- end
153
- if options[:transaction_id]
154
- x.payKey options[:transaction_id]
155
- end
156
- if options[:tracking_id]
157
- x.trackingId options[:tracking_id]
179
+ def build_preapproval_payment(options)
180
+ opts = {
181
+ :currency_code => "USD",
182
+ :start_date => DateTime.current
183
+ }.update(options)
184
+
185
+ @xml = ''
186
+ xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
187
+ xml.instruct!
188
+ xml.PreapprovalRequest do |x|
189
+ # request envelope
190
+ x.requestEnvelope do |x|
191
+ x.detailLevel 'ReturnAll'
192
+ x.errorLanguage opts[:error_language] ||= 'en_US'
193
+ x.senderEmail opts[:senderEmail]
194
+ end
195
+
196
+ # required preapproval fields
197
+ x.endingDate opts[:end_date].strftime("%Y-%m-%dT%H:%M:%S")
198
+ x.startingDate opts[:start_date].strftime("%Y-%m-%dT%H:%M:%S")
199
+ x.maxTotalAmountOfAllPayments opts[:max_amount]
200
+ x.maxNumberOfPayments opts[:maxNumberOfPayments] if opts.has_key?(:maxNumberOfPayments)
201
+ x.currencyCode options[:currency_code]
202
+ x.cancelUrl opts[:cancel_url]
203
+ x.returnUrl opts[:return_url]
204
+
205
+ # notify url
206
+ x.ipnNotificationUrl opts[:notify_url] if opts.has_key?(:notify_url)
207
+ end
158
208
  end
159
- x.cancelUrl options[:cancel_url]
160
- x.returnUrl options[:return_url]
161
- x.currencyCode options[:currency_code] ||= 'USD'
162
- x.receiverList do |x|
163
- options[:receiver_list].each do |receiver|
164
- x.receiver do |x|
165
- x.amount receiver[:amount]
166
- x.paymentType receiver[:payment_type] ||= 'GOODS'
167
- x.invoiceId receiver[:invoice_id] if receiver[:invoice_id]
168
- x.email receiver[:email]
209
+
210
+ def build_preapproval_details(options)
211
+ @xml = ''
212
+ xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
213
+ xml.instruct!
214
+ xml.PreapprovalDetailsRequest do |x|
215
+ x.requestEnvelope do |x|
216
+ x.detailLevel 'ReturnAll'
217
+ x.errorLanguage options[:error_language] ||= 'en_US'
169
218
  end
219
+ x.preapprovalKey options[:preapproval_key]
220
+ x.getBillingAddress options[:get_billing_address] if options[:get_billing_address]
170
221
  end
171
222
  end
172
- x.feesPayer options[:fees_payer] ||= 'EACHRECEIVER'
173
- end
174
- end
175
223
 
176
- def build_preapproval_payment options
177
- opts = {
178
- :currency_code => "USD",
179
- :start_date => DateTime.current
180
- }.update(options)
181
-
182
- @xml = ''
183
- xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
184
- xml.instruct!
185
- xml.PreapprovalRequest do |x|
186
- # request envelope
187
- x.requestEnvelope do |x|
188
- x.detailLevel 'ReturnAll'
189
- x.errorLanguage opts[:error_language] ||= 'en_US'
190
- x.senderEmail opts[:senderEmail]
224
+ def build_cancel_preapproval(options)
225
+ @xml = ''
226
+ xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
227
+ xml.instruct!
228
+ xml.PreapprovalDetailsRequest do |x|
229
+ x.requestEnvelope do |x|
230
+ x.detailLevel 'ReturnAll'
231
+ x.errorLanguage options[:error_language] ||= 'en_US'
232
+ end
233
+ x.preapprovalKey options[:preapproval_key]
234
+ end
191
235
  end
192
236
 
193
- # required preapproval fields
194
- x.endingDate opts[:end_date].strftime("%Y-%m-%dT%H%%3a%M%%3a%S")
195
- x.startingDate opts[:start_date].strftime("%Y-%m-%dT%H%%3a%M%%3a%S")
196
- x.maxTotalAmountOfAllPayments opts[:max_amount]
197
- x.maxNumberOfPayments opts[:maxNumberOfPayments]
198
- x.currencyCode options[:currency_code]
199
- x.cancelUrl opts[:cancel_url]
200
- x.returnUrl opts[:return_url]
201
-
202
- # notify url
203
- if opts[:notify_url]
204
- x.ipnNotificationUrl opts[:notify_url]
237
+ def build_currency_conversion(options)
238
+ @xml = ''
239
+ xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
240
+ xml.instruct!
241
+ xml.ConvertCurrencyRequest do |x|
242
+ x.requestEnvelope do |x|
243
+ x.detailLevel 'ReturnAll'
244
+ x.errorLanguage options[:error_language] ||= 'en_US'
245
+ end
246
+ x.baseAmountList do |x|
247
+ options[:currency_list].each do |currency|
248
+ x.currency do |x|
249
+ x.amount currency[:amount]
250
+ x.code currency[:code ]
251
+ end
252
+ end
253
+ end
254
+ x.convertToCurrencyList do |x|
255
+ options[:to_currencies].each do |k,v|
256
+ x.currencyCode "#{v}"
257
+ end
258
+ end
259
+ end
205
260
  end
206
- end
207
- end
208
261
 
209
- def build_preapproval_details options
210
- @xml = ''
211
- xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
212
- xml.instruct!
213
- xml.PreapprovalDetailsRequest do |x|
214
- x.requestEnvelope do |x|
215
- x.detailLevel 'ReturnAll'
216
- x.errorLanguage options[:error_language] ||= 'en_US'
262
+ def commit(action, data)
263
+ @response = AdaptivePaymentResponse.new(post_through_ssl(action, data))
217
264
  end
218
- x.preapprovalKey options[:preapproval_key]
219
- x.getBillingAddress options[:get_billing_address] if options[:get_billing_address]
220
- end
221
- end
222
265
 
223
- def build_cancel_preapproval options
224
- @xml = ''
225
- xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
226
- xml.instruct!
227
- xml.PreapprovalDetailsRequest do |x|
228
- x.requestEnvelope do |x|
229
- x.detailLevel 'ReturnAll'
230
- x.errorLanguage options[:error_language] ||= 'en_US'
266
+ def post_through_ssl(action, parameters = {})
267
+ headers = {
268
+ "X-PAYPAL-REQUEST-DATA-FORMAT" => "XML",
269
+ "X-PAYPAL-RESPONSE-DATA-FORMAT" => "JSON",
270
+ "X-PAYPAL-SECURITY-USERID" => @config[:login],
271
+ "X-PAYPAL-SECURITY-PASSWORD" => @config[:password],
272
+ "X-PAYPAL-SECURITY-SIGNATURE" => @config[:signature],
273
+ "X-PAYPAL-APPLICATION-ID" => @config[:appid]
274
+ }
275
+ action_url(action)
276
+ request = Net::HTTP::Post.new(@url.path)
277
+ request.body = @xml
278
+ headers.each_pair { |k,v| request[k] = v }
279
+ request.content_type = 'text/xml'
280
+ server = Net::HTTP.new(@url.host, 443)
281
+ server.use_ssl = true
282
+ server.start { |http| http.request(request) }.body
231
283
  end
232
- x.preapprovalKey options[:preapproval_key]
233
- end
234
- end
235
284
 
236
- def build_currency_conversion options
237
- @xml = ''
238
- xml = Builder::XmlMarkup.new :target => @xml, :indent => 2
239
- xml.instruct!
240
- xml.ConvertCurrencyRequest do |x|
241
- x.requestEnvelope do |x|
242
- x.detailLevel 'ReturnAll'
243
- x.errorLanguage options[:error_language] ||= 'en_US'
285
+ def endpoint_url
286
+ test? ? TEST_URL : LIVE_URL
244
287
  end
245
288
 
246
- x.baseAmountList do |x|
247
- options[:currency_list].each do |currency|
248
- x.currency do |x|
249
- x.amount currency[:amount]
250
- x.code currency[:code ]
251
- end
252
- end
289
+ def test?
290
+ Base.gateway_mode == :test
253
291
  end
254
292
 
255
- x.convertToCurrencyList do |x|
256
- options[:to_currencies].each do |k,v|
257
- x.currencyCode "#{v}"
258
- end
293
+ def action_url(action)
294
+ @url = URI.parse(endpoint_url + action)
259
295
  end
260
- end
261
- end
262
296
 
263
- def parse json
264
- @raw = json
265
- resp = JSON.parse json
266
- if resp['responseEnvelope']['ack'] == 'Failure'
267
- error = AdaptivePaypalErrorResponse.new(json)
268
- else
269
- AdaptivePaypalSuccessResponse.new(resp)
270
297
  end
271
298
  end
272
-
273
- def commit(action, data)
274
- @response = parse(post_through_ssl(action, data))
275
- end
276
-
277
- def post_through_ssl(action, parameters = {})
278
- headers = {
279
- "X-PAYPAL-REQUEST-DATA-FORMAT" => "XML",
280
- "X-PAYPAL-RESPONSE-DATA-FORMAT" => "JSON",
281
- "X-PAYPAL-SECURITY-USERID" => @config[:login],
282
- "X-PAYPAL-SECURITY-PASSWORD" => @config[:password],
283
- "X-PAYPAL-SECURITY-SIGNATURE" => @config[:signature],
284
- "X-PAYPAL-APPLICATION-ID" => @config[:appid]
285
- }
286
- url action
287
- request = Net::HTTP::Post.new(@url.path)
288
- request.body = @xml
289
- headers.each_pair { |k,v| request[k] = v }
290
- request.content_type = 'text/xml'
291
- server = Net::HTTP.new(@url.host, 443)
292
- server.use_ssl = true
293
- server.start { |http| http.request(request) }.body
294
- end
295
-
296
- def endpoint_url
297
- test? ? TEST_URL : LIVE_URL
298
- end
299
-
300
- def test?
301
- Base.gateway_mode == :test
302
- end
303
-
304
- def url action
305
- @url = URI.parse(endpoint_url + action)
306
- end
307
-
308
- end; end; end
299
+ end
@@ -1,134 +1,52 @@
1
- module ActiveMerchant; module Billing; module AdaptivePaymentResponses
1
+ require 'multi_json'
2
+ require 'hashie'
3
+ require 'rash'
2
4
 
3
- class AdaptivePaypalSuccessResponse
5
+ module ActiveMerchant
6
+ module Billing
7
+ class AdaptivePaymentResponse
4
8
 
5
- REDIRECT_URL = 'https://www.paypal.com/webscr?cmd=_ap-payment&paykey='
6
- TEST_REDIRECT_URL = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_ap-payment&paykey='
9
+ REDIRECT_URL = 'https://www.paypal.com/webscr?cmd=_ap-payment&paykey='
10
+ TEST_REDIRECT_URL = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_ap-payment&paykey='
7
11
 
8
- attr_reader :paykey
12
+ SUCCESS = 'Success'.freeze
9
13
 
10
- def initialize json
11
- @paykey = json['payKey']
12
- @params = json
13
- end
14
+ attr_reader :json
15
+ alias :raw :json
14
16
 
15
- def redirect_url_for
16
- Base.gateway_mode == :test ? (TEST_REDIRECT_URL + @paykey) : (REDIRECT_URL + @paykey)
17
- end
17
+ def initialize(json)
18
+ @json = json
19
+ @response_rash = Hashie::Rash.new(MultiJson.decode(json))
20
+ end
18
21
 
19
- def ack
20
- @params['responseEnvelope']['ack']
21
- end
22
+ def method_missing(method, *args, &block)
23
+ @response_rash.send(method, *args, &block)
24
+ end
22
25
 
23
- def paymentExecStatus
24
- @params['paymentExecStatus']
25
- end
26
+ def redirect_url_for
27
+ Base.gateway_mode == :test ? (TEST_REDIRECT_URL + pay_key) : (REDIRECT_URL + pay_key)
28
+ end
26
29
 
27
- def transactionStatus
28
- @params['transactionStatus']
29
- end
30
-
31
- def senderEmail
32
- @params['senderEmail']
33
- end
34
-
35
- def actionType
36
- @params['actionType']
37
- end
38
-
39
- def feesPayer
40
- @params['feesPayer']
41
- end
42
-
43
- def currencyCode
44
- @params['currencyCode']
45
- end
46
-
47
- def payKey
48
- @params['payKey']
49
- end
50
-
51
- def correlationId
52
- @params['responseEnvelope']['correlationId']
53
- end
54
-
55
- def build
56
- @params['responseEnvelope']['build']
57
- end
58
-
59
- def refundInfoList
60
- @params['refundInfoList']
61
- end
62
-
63
- def preapprovalKey
64
- @params['preapprovalKey']
65
- end
66
-
67
- def curPaymentsAmount
68
- @params['curPaymentsAmount']
69
- end
30
+ def ack
31
+ response_envelope.ack
32
+ end
70
33
 
71
- def status
72
- @params['status']
73
- end
34
+ def timestamp
35
+ response_envelope.timestamp
36
+ end
74
37
 
75
- def curPeriodAttempts
76
- @params['curPeriodAttempts']
77
- end
38
+ def build
39
+ response_envelope.build
40
+ end
78
41
 
79
- def approved
80
- @params['approved']
81
- end
42
+ def correlation_id
43
+ response_envelope.correlation_id
44
+ end
45
+ alias :correlationId :correlation_id
82
46
 
83
- def method_missing name
84
- begin
85
- @params[name.to_s]
86
- rescue
87
- raise AttributenotFound
47
+ def success?
48
+ ack == SUCCESS
49
+ end
88
50
  end
89
51
  end
90
-
91
- def [](key)
92
- return @params[key] if @params.include? key
93
- raise AttributenotFound
94
- end
95
-
96
- def status
97
- @params['status']
98
- end
99
-
100
52
  end
101
-
102
- class AdaptivePaypalErrorResponse
103
-
104
- def initialize error
105
- @raw = error
106
- @errlist = ActiveSupport::JSON.decode(error)
107
- end
108
-
109
- def debug
110
- @raw.inspect
111
- end
112
-
113
- def ack
114
- @raw['responseEnvelope']['ack']
115
- end
116
-
117
- def timestamp
118
- @raw['responseEnvelope']['timestamp']
119
- end
120
-
121
- def build
122
- @raw['responseEnvelope']['build']
123
- end
124
-
125
- def correlationId
126
- @raw['responseEnvelope']['correlationId']
127
- end
128
-
129
- def errormessage
130
- @errlist['error']
131
- end
132
- end
133
-
134
- end; end; end
@@ -1,10 +1,12 @@
1
1
  # fix for case sensitive headers in paypal (issue #1)
2
- module Net; module HTTPHeader
3
- def []= key, val
4
- unless val
5
- @header.delete key
6
- return val
2
+ module Net
3
+ module HTTPHeader
4
+ def []= key, val
5
+ unless val
6
+ @header.delete key
7
+ return val
8
+ end
9
+ @header[key] = [val]
7
10
  end
8
- @header[key] = [val]
9
11
  end
10
- end; end
12
+ end
@@ -1,13 +1,4 @@
1
- $:.unshift File.dirname(__FILE__)
2
-
3
- begin
4
- require 'active_support'
5
- require 'active_merchant/common'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'active_support'
9
- require 'active_merchant/common'
10
- end
1
+ require 'active_merchant'
11
2
 
12
3
  dir = File.dirname(__FILE__) + '/active_merchant/billing/gateways'
13
4
  require dir + '/paypal_adaptive_payment'
@@ -4,8 +4,7 @@ This library is meant to interface with PayPal web services Adaptive Payment Gat
4
4
 
5
5
  [Active Merchant]:http://www.activemerchant.org
6
6
 
7
- ![Active PayPal Adaptive Payment](https://github.com/jpablobr/active_paypal_adaptive_payment/raw/master/doc/split.jpg)
8
-
7
+ [iAuction: An Adaptive Payments Tutorial Featuring Parallel Payments](https://www.x.com/docs/DOC-2505)
9
8
  ## Supported
10
9
 
11
10
  * payments
@@ -18,23 +17,28 @@ This library is meant to interface with PayPal web services Adaptive Payment Gat
18
17
 
19
18
  Add the following line to your app Gemfile:
20
19
 
21
- gem "active_paypal_adaptive_payment", "~> 0.1.0"
20
+ gem "active_paypal_adaptive_payment"
22
21
 
23
22
  ## Implementation
24
23
 
25
- In your { payment/order }_controller.rb
24
+ See ![Active PayPal Adaptive Payment](https://github.com/jpablobr/active_paypal_adaptive_payment/raw/master/doc/split.jpg) tutorial for more info.
26
25
 
27
- def gateway
28
- @gateway ||= PaypalAdaptivePaymentGateway.new(
29
- :login => 'your_email',
30
- :password => 'your_password',
31
- :signature => ' your_signature',
32
- :appid => 'your_app_id'
33
- )
34
- end
26
+ ### Pre-approved paymen
35
27
 
36
- ## Payment process
28
+ gateway.preapprove_payment (
29
+ :return_url => "returnURL",
30
+ :cancel_url => "cancelURL",
31
+ :senderEmail =>"email address of sender",
32
+ :start_date => Time.now,
33
+ :end_date => Time.now + (60*60*24) * 30,
34
+ :currency_code =>"currency code",
35
+ :max_amount => "maxTotalAmountOfAllPayments",
36
+ :maxNumberOfPayments => "maxNumberOfPayments" )
37
37
 
38
+ ### Cancel pre-approved payment
39
+
40
+ gateway.cancel_preapproval(:preapproval_key => "preapprovalkey"
41
+ )
38
42
  ### Chained payments
39
43
 
40
44
  def checkout
@@ -63,16 +67,21 @@ response, the xml sent and the url it was posted to.
63
67
 
64
68
  From the Rails console it can be accessed like such:
65
69
 
66
- ActiveMerchant::Billing::PaypalAdaptivePaymentGateway
70
+ ActiveMerchant::Billing::PaypalAdaptivePayment
71
+
72
+ `PaypalAdaptivePayment#debug` or `AdaptivePaymentResponse#debug` return the raw
73
+ xml request, raw json response and the URL of the endpoint.
67
74
 
68
75
  ## TODO
69
76
 
70
- * Better documentation
77
+ * Documentation
78
+ * More tests
71
79
 
72
80
  ## Contributors
73
81
 
74
82
  * Jose Pablo Barrantes (<http://jpablobr.com/>)
75
83
  * Zarne Dravitzki (<http://github.com/zarno>)
84
+ * LeviRosol (<https://github.com/LeviRosol>)
76
85
 
77
86
  ## Other previous contributors where some code was taken from.
78
87
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_paypal_adaptive_payment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-28 00:00:00.000000000 +10:00
13
- default_executable:
12
+ date: 2011-08-12 00:00:00.000000000Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: activemerchant
17
- requirement: &13160920 !ruby/object:Gem::Requirement
16
+ requirement: &11874900 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ! '>='
@@ -22,29 +21,40 @@ dependencies:
22
21
  version: 1.5.1
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *13160920
24
+ version_requirements: *11874900
26
25
  - !ruby/object:Gem::Dependency
27
- name: activesupport
28
- requirement: &13160440 !ruby/object:Gem::Requirement
26
+ name: multi_json
27
+ requirement: &11874420 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
30
  - - ! '>='
32
31
  - !ruby/object:Gem::Version
33
- version: 3.0.7
32
+ version: 1.0.0
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: *13160440
35
+ version_requirements: *11874420
37
36
  - !ruby/object:Gem::Dependency
38
- name: builder
39
- requirement: &13159960 !ruby/object:Gem::Requirement
37
+ name: rash
38
+ requirement: &11873820 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
41
  - - ! '>='
43
42
  - !ruby/object:Gem::Version
44
- version: 2.0.0
43
+ version: 0.3.0
45
44
  type: :runtime
46
45
  prerelease: false
47
- version_requirements: *13159960
46
+ version_requirements: *11873820
47
+ - !ruby/object:Gem::Dependency
48
+ name: money
49
+ requirement: &11873220 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.6.0
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *11873220
48
58
  description: This library is meant to interface with PayPal web services Adaptive
49
59
  Payment Gateway Library.
50
60
  email:
@@ -55,14 +65,12 @@ extra_rdoc_files: []
55
65
  files:
56
66
  - lib/active_paypal_adaptive_payment.rb
57
67
  - lib/active_merchant/billing/gateways/paypal_adaptive_payments/exceptions.rb
58
- - lib/active_merchant/billing/gateways/paypal_adaptive_payments/utils.rb
59
68
  - lib/active_merchant/billing/gateways/paypal_adaptive_payments/adaptive_payment_response.rb
60
69
  - lib/active_merchant/billing/gateways/paypal_adaptive_payments/ext.rb
61
70
  - lib/active_merchant/billing/gateways/paypal_adaptive_payment.rb
62
71
  - MIT-LICENSE
63
- - README.markdown
64
- - CHANGELOG
65
- has_rdoc: true
72
+ - readme.md
73
+ - CHANGELOG.md
66
74
  homepage: http://github.com/jpablobr/active_paypal_adaptive_payment
67
75
  licenses: []
68
76
  post_install_message:
@@ -83,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
91
  version: 1.3.6
84
92
  requirements: []
85
93
  rubyforge_project:
86
- rubygems_version: 1.6.2
94
+ rubygems_version: 1.8.7
87
95
  signing_key:
88
96
  specification_version: 3
89
97
  summary: ActiveMercant PayPal Adaptive Payment Library
data/CHANGELOG DELETED
File without changes
@@ -1,8 +0,0 @@
1
- module ActiveMerchant; module Billing; module AdaptiveUtils
2
-
3
- def currency_to_two_places amount
4
- return 0.01 if amount < 1
5
- ("%.2f" % amount).to_f
6
- end
7
-
8
- end; end; end