activemerchant 1.29.3 → 1.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +39 -0
  3. data/CONTRIBUTORS +19 -0
  4. data/README.md +43 -41
  5. data/lib/active_merchant/billing/check.rb +15 -11
  6. data/lib/active_merchant/billing/credit_card.rb +5 -1
  7. data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
  8. data/lib/active_merchant/billing/gateway.rb +1 -1
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
  10. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +15 -4
  11. data/lib/active_merchant/billing/gateways/balanced.rb +9 -3
  12. data/lib/active_merchant/billing/gateways/banwire.rb +15 -1
  13. data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
  14. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +6 -2
  15. data/lib/active_merchant/billing/gateways/braintree_blue.rb +5 -2
  16. data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
  17. data/lib/active_merchant/billing/gateways/eway.rb +114 -171
  18. data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
  19. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +222 -0
  20. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
  21. data/lib/active_merchant/billing/gateways/litle.rb +50 -19
  22. data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
  23. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
  24. data/lib/active_merchant/billing/gateways/moneris.rb +2 -4
  25. data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
  26. data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
  27. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  28. data/lib/active_merchant/billing/gateways/optimal_payment.rb +18 -3
  29. data/lib/active_merchant/billing/gateways/orbital.rb +9 -5
  30. data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
  31. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
  32. data/lib/active_merchant/billing/gateways/paypal_express.rb +2 -0
  33. data/lib/active_merchant/billing/gateways/pin.rb +157 -0
  34. data/lib/active_merchant/billing/gateways/qbms.rb +3 -2
  35. data/lib/active_merchant/billing/gateways/quickpay.rb +66 -28
  36. data/lib/active_merchant/billing/gateways/sage_pay.rb +6 -0
  37. data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
  38. data/lib/active_merchant/billing/gateways/spreedly_core.rb +235 -0
  39. data/lib/active_merchant/billing/gateways/stripe.rb +1 -0
  40. data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
  41. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +4 -1
  42. data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
  43. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
  44. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +14 -14
  45. data/lib/active_merchant/version.rb +1 -1
  46. metadata +109 -49
  47. metadata.gz.sig +0 -0
@@ -65,6 +65,7 @@ module ActiveMerchant #:nodoc:
65
65
  add_credit_card(post, credit_card)
66
66
  add_address(post, options)
67
67
  add_customer_data(post, options)
68
+ add_optional_data(post, options)
68
69
 
69
70
  commit(:purchase, post)
70
71
  end
@@ -79,6 +80,7 @@ module ActiveMerchant #:nodoc:
79
80
  add_credit_card(post, credit_card)
80
81
  add_address(post, options)
81
82
  add_customer_data(post, options)
83
+ add_optional_data(post, options)
82
84
 
83
85
  commit(:authorization, post)
84
86
  end
@@ -156,6 +158,10 @@ module ActiveMerchant #:nodoc:
156
158
  add_pair(post, :ClientIPAddress, options[:ip])
157
159
  end
158
160
 
161
+ def add_optional_data(post, options)
162
+ add_pair(post, :GiftAidPayment, options[:gift_aid_payment]) unless options[:gift_aid_payment].blank?
163
+ end
164
+
159
165
  def add_address(post, options)
160
166
  if billing_address = options[:billing_address] || options[:address]
161
167
  first_name, last_name = parse_first_and_last_name(billing_address[:name])
@@ -221,7 +221,7 @@ module ActiveMerchant #:nodoc:
221
221
  parameters[:amount] = amount(money) if money
222
222
  response = parse( ssl_post(self.live_url, post_data(action,parameters)) )
223
223
  Response.new(response["response"] == "1", message_from(response), response,
224
- :authorization => response["transactionid"],
224
+ :authorization => (response["transactionid"] || response["customer_vault_id"]),
225
225
  :test => test?,
226
226
  :cvv_result => response["cvvresponse"],
227
227
  :avs_result => { :code => response["avsresponse"] }
@@ -0,0 +1,235 @@
1
+ require 'nokogiri'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # Public: This gateway allows you to interact with any gateway you've
6
+ # created in Spreedly Core (https://spreedlycore.com). It's an adapter
7
+ # which can be particularly useful if you already have code interacting with
8
+ # ActiveMerchant and want to easily take advantage of Core's vault.
9
+ class SpreedlyCoreGateway < Gateway
10
+ self.live_url = 'https://spreedlycore.com/v1'
11
+
12
+ self.supported_countries = %w(AD AE AT AU BD BE BG BN CA CH CY CZ DE DK EE EG ES FI FR GB
13
+ GI GR HK HU ID IE IL IM IN IS IT JO KW LB LI LK LT LU LV MC
14
+ MT MU MV MX MY NL NO NZ OM PH PL PT QA RO SA SE SG SI SK SM
15
+ TR TT UM US VA VN ZA)
16
+
17
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
18
+ self.homepage_url = 'https://spreedlycore.com'
19
+ self.display_name = 'Spreedly Core'
20
+ self.money_format = :cents
21
+ self.default_currency = 'USD'
22
+
23
+ # Public: Create a new Spreedly Core Gateway.
24
+ #
25
+ # options - A hash of options:
26
+ # :login - Your Spreedly Core API login.
27
+ # :password - Your Spreedly Core API secret.
28
+ # :gateway_token - The token of the gateway you've created in
29
+ # Spreedly Core.
30
+ def initialize(options = {})
31
+ requires!(options, :login, :password, :gateway_token)
32
+ super
33
+ end
34
+
35
+ # Public: Run a purchase transaction.
36
+ #
37
+ # money - The monetary amount of the transaction in cents.
38
+ # payment_method - The CreditCard or the Spreedly Core payment method
39
+ # token.
40
+ # options - A standard ActiveMerchant options hash
41
+ def purchase(money, payment_method, options = {})
42
+ if payment_method.is_a?(String)
43
+ purchase_with_token(money, payment_method, options)
44
+ else
45
+ MultiResponse.run do |r|
46
+ r.process { save_card(false, payment_method, options) }
47
+ r.process { purchase_with_token(money, r.authorization, options) }
48
+ end
49
+ end
50
+ end
51
+
52
+ # Public: Run an authorize transaction.
53
+ #
54
+ # money - The monetary amount of the transaction in cents.
55
+ # payment_method - The CreditCard or the Spreedly Core payment method
56
+ # token.
57
+ # options - A standard ActiveMerchant options hash
58
+ def authorize(money, payment_method, options = {})
59
+ if payment_method.is_a?(String)
60
+ authorize_with_token(money, payment_method, options)
61
+ else
62
+ MultiResponse.run do |r|
63
+ r.process { save_card(false, payment_method, options) }
64
+ r.process { authorize_with_token(money, r.authorization, options) }
65
+ end
66
+ end
67
+ end
68
+
69
+ def capture(money, authorization, options={})
70
+ request = build_xml_request('transaction') do |doc|
71
+ add_invoice(doc, money, options)
72
+ end
73
+
74
+ commit("transactions/#{authorization}/capture.xml", request)
75
+ end
76
+
77
+ def refund(money, authorization, options={})
78
+ request = build_xml_request('transaction') do |doc|
79
+ add_invoice(doc, money, options)
80
+ end
81
+
82
+ commit("transactions/#{authorization}/credit.xml", request)
83
+ end
84
+
85
+ def void(authorization, options={})
86
+ commit("transactions/#{authorization}/void.xml", '')
87
+ end
88
+
89
+ # Public: Store a credit card in the Spreedly Core vault and retain it.
90
+ #
91
+ # credit_card - The CreditCard to store
92
+ # options - A standard ActiveMerchant options hash
93
+ def store(credit_card, options={})
94
+ save_card(true, credit_card, options)
95
+ end
96
+
97
+ # Public: Redact the CreditCard in Spreedly Core. This wipes the
98
+ # sensitive payment information from the card.
99
+ #
100
+ # credit_card - The CreditCard to store
101
+ # options - A standard ActiveMerchant options hash
102
+ def unstore(authorization, options={})
103
+ commit("payment_methods/#{authorization}/redact.xml", '', :put)
104
+ end
105
+
106
+ private
107
+ def save_card(retain, credit_card, options)
108
+ request = build_xml_request('payment_method') do |doc|
109
+ add_credit_card(doc, credit_card, options)
110
+ add_data(doc, options)
111
+ doc.retained(true) if retain
112
+ end
113
+
114
+ commit("payment_methods.xml", request, :post, :payment_method_token)
115
+ end
116
+
117
+ def purchase_with_token(money, payment_method_token, options)
118
+ request = auth_purchase_request(money, payment_method_token, options)
119
+ commit("gateways/#{@options[:gateway_token]}/purchase.xml", request)
120
+ end
121
+
122
+ def authorize_with_token(money, payment_method_token, options)
123
+ request = auth_purchase_request(money, payment_method_token, options)
124
+ commit("gateways/#{@options[:gateway_token]}/authorize.xml", request)
125
+ end
126
+
127
+ def auth_purchase_request(money, payment_method_token, options)
128
+ build_xml_request('transaction') do |doc|
129
+ add_invoice(doc, money, options)
130
+ doc.payment_method_token(payment_method_token)
131
+ end
132
+ end
133
+
134
+ def add_invoice(doc, money, options)
135
+ doc.amount amount(money)
136
+ doc.currency_code(options[:currency] || currency(money) || default_currency)
137
+ end
138
+
139
+ def add_credit_card(doc, credit_card, options)
140
+ doc.credit_card do
141
+ doc.number(credit_card.number)
142
+ doc.first_name(credit_card.first_name)
143
+ doc.last_name(credit_card.last_name)
144
+ doc.month(credit_card.month)
145
+ doc.year(credit_card.year)
146
+ doc.email(options[:email])
147
+ doc.address1(options[:billing_address].try(:[], :address1))
148
+ doc.address2(options[:billing_address].try(:[], :address2))
149
+ doc.city(options[:billing_address].try(:[], :city))
150
+ doc.state(options[:billing_address].try(:[], :state))
151
+ doc.zip(options[:billing_address].try(:[], :zip))
152
+ end
153
+ end
154
+
155
+ def add_data(doc, options)
156
+ doc.data do
157
+ data_to_doc(doc, options[:data])
158
+ end
159
+ end
160
+
161
+ def data_to_doc(doc, value)
162
+ return doc.text value unless value.kind_of? Hash
163
+ value.each do |k, v|
164
+ doc.send(k) do
165
+ data_to_doc(doc, v)
166
+ end
167
+ end
168
+ end
169
+
170
+ def parse(xml)
171
+ response = {}
172
+
173
+ doc = Nokogiri::XML(xml)
174
+ doc.root.xpath('*').each do |node|
175
+ if (node.elements.empty?)
176
+ response[node.name.downcase.to_sym] = node.text
177
+ else
178
+ node.elements.each do |childnode|
179
+ childnode_to_response(response, node, childnode)
180
+ end
181
+ end
182
+ end
183
+
184
+ response
185
+ end
186
+
187
+ def childnode_to_response(response, node, childnode)
188
+ name = "#{node.name.downcase}_#{childnode.name.downcase}"
189
+ if name == 'payment_method_data' && !childnode.elements.empty?
190
+ response[name.to_sym] = Hash.from_xml(childnode.to_s).values.first
191
+ else
192
+ response[name.to_sym] = childnode.text
193
+ end
194
+ end
195
+
196
+ def build_xml_request(root)
197
+ builder = Nokogiri::XML::Builder.new
198
+ builder.__send__(root) do |doc|
199
+ yield(doc)
200
+ end
201
+ builder.to_xml
202
+ end
203
+
204
+ def commit(relative_url, request, method = :post, authorization_field = :token)
205
+ begin
206
+ raw_response = ssl_request(method, "#{live_url}/#{relative_url}", request, headers)
207
+ rescue ResponseError => e
208
+ raw_response = e.response.body
209
+ end
210
+
211
+ response_from(raw_response, authorization_field)
212
+ end
213
+
214
+ def response_from(raw_response, authorization_field)
215
+ parsed = parse(raw_response)
216
+ options = {
217
+ :authorization => parsed[authorization_field],
218
+ :test => (parsed[:on_test_gateway] == 'true'),
219
+ :avs_result => { :code => parsed[:response_avs_code] },
220
+ :cvv_result => parsed[:response_cvv_code]
221
+ }
222
+
223
+ Response.new(parsed[:succeeded] == 'true', parsed[:message] || parsed[:error], parsed, options)
224
+ end
225
+
226
+ def headers
227
+ {
228
+ 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:login]}:#{@options[:password]}").chomp),
229
+ 'Content-Type' => 'text/xml'
230
+ }
231
+ end
232
+ end
233
+ end
234
+ end
235
+
@@ -50,6 +50,7 @@ module ActiveMerchant #:nodoc:
50
50
  add_customer(post, options)
51
51
  add_customer_data(post,options)
52
52
  post[:description] = options[:description] || options[:email]
53
+ post[:application_fee] = options[:application_fee] if options[:application_fee]
53
54
  add_flags(post, options)
54
55
 
55
56
  meta = generate_meta(options)
@@ -16,7 +16,7 @@ module ActiveMerchant #:nodoc:
16
16
  'xsi:noNamespaceSchemaLocation' => 'wirecard.xsd'
17
17
  }
18
18
 
19
- PERMITTED_TRANSACTIONS = %w[ AUTHORIZATION CAPTURE_AUTHORIZATION PURCHASE ]
19
+ PERMITTED_TRANSACTIONS = %w[ PREAUTHORIZATION CAPTURE PURCHASE ]
20
20
 
21
21
  RETURN_CODES = %w[ ACK NOK ]
22
22
 
@@ -63,13 +63,13 @@ module ActiveMerchant #:nodoc:
63
63
  # Authorization
64
64
  def authorize(money, creditcard, options = {})
65
65
  options[:credit_card] = creditcard
66
- commit(:authorization, money, options)
66
+ commit(:preauthorization, money, options)
67
67
  end
68
68
 
69
69
  # Capture Authorization
70
70
  def capture(money, authorization, options = {})
71
- options[:authorization] = authorization
72
- commit(:capture_authorization, money, options)
71
+ options[:preauthorization] = authorization
72
+ commit(:capture, money, options)
73
73
  end
74
74
 
75
75
  # Purchase
@@ -148,16 +148,17 @@ module ActiveMerchant #:nodoc:
148
148
  options[:order_id] ||= generate_unique_id
149
149
 
150
150
  xml.tag! "FNC_CC_#{options[:action].to_s.upcase}" do
151
- xml.tag! 'FunctionID', options[:description]
151
+ xml.tag! 'FunctionID', options[:description].to_s.slice(0,32)
152
152
  xml.tag! 'CC_TRANSACTION' do
153
153
  xml.tag! 'TransactionID', options[:order_id]
154
154
  case options[:action]
155
- when :authorization, :purchase
155
+ when :preauthorization, :purchase
156
156
  add_invoice(xml, money, options)
157
157
  add_creditcard(xml, options[:credit_card])
158
158
  add_address(xml, options[:billing_address])
159
- when :capture_authorization
160
- xml.tag! 'GuWID', options[:authorization]
159
+ when :capture
160
+ xml.tag! 'GuWID', options[:preauthorization]
161
+ add_amount(xml, money)
161
162
  end
162
163
  end
163
164
  end
@@ -165,7 +166,7 @@ module ActiveMerchant #:nodoc:
165
166
 
166
167
  # Includes the payment (amount, currency, country) to the transaction-xml
167
168
  def add_invoice(xml, money, options)
168
- xml.tag! 'Amount', amount(money)
169
+ add_amount(xml, money)
169
170
  xml.tag! 'Currency', options[:currency] || currency(money)
170
171
  xml.tag! 'CountryCode', options[:billing_address][:country]
171
172
  xml.tag! 'RECURRING_TRANSACTION' do
@@ -173,6 +174,11 @@ module ActiveMerchant #:nodoc:
173
174
  end
174
175
  end
175
176
 
177
+ # Include the amount in the transaction-xml
178
+ def add_amount(xml, money)
179
+ xml.tag! 'Amount', amount(money)
180
+ end
181
+
176
182
  # Includes the credit-card data to the transaction-xml
177
183
  def add_creditcard(xml, creditcard)
178
184
  raise "Creditcard must be supplied!" if creditcard.nil?
@@ -20,7 +20,6 @@ module ActiveMerchant #:nodoc:
20
20
  mapping :credential2, 'pwd'
21
21
  mapping :credential3, 'partner'
22
22
  mapping :order, 'user1'
23
- mapping :description, 'description'
24
23
 
25
24
  mapping :amount, 'amt'
26
25
 
@@ -35,6 +34,10 @@ module ActiveMerchant #:nodoc:
35
34
 
36
35
  mapping :customer, :name => 'name'
37
36
 
37
+ def description(value)
38
+ add_field('description', "#{value}".delete("#"))
39
+ end
40
+
38
41
  def customer(params = {})
39
42
  add_field(mappings[:customer][:name], [params.delete(:first_name), params.delete(:last_name)].compact.join(' '))
40
43
  end
@@ -1,16 +1,17 @@
1
1
  require 'net/http'
2
+ require 'time'
2
3
 
3
4
  module ActiveMerchant #:nodoc:
4
5
  module Billing #:nodoc:
5
6
  module Integrations #:nodoc:
6
7
  module Paypal
7
- # Parser and handler for incoming Instant payment notifications from paypal.
8
+ # Parser and handler for incoming Instant payment notifications from paypal.
8
9
  # The Example shows a typical handler in a rails application. Note that this
9
10
  # is an example, please read the Paypal API documentation for all the details
10
11
  # on creating a safe payment controller.
11
12
  #
12
13
  # Example
13
- #
14
+ #
14
15
  # class BackendController < ApplicationController
15
16
  # include ActiveMerchant::Billing::Integrations
16
17
  #
@@ -20,28 +21,28 @@ module ActiveMerchant #:nodoc:
20
21
  # if notify.masspay?
21
22
  # masspay_items = notify.items
22
23
  # end
23
- #
24
+ #
24
25
  # order = Order.find(notify.item_id)
25
- #
26
- # if notify.acknowledge
26
+ #
27
+ # if notify.acknowledge
27
28
  # begin
28
- #
29
+ #
29
30
  # if notify.complete? and order.total == notify.amount
30
- # order.status = 'success'
31
- #
31
+ # order.status = 'success'
32
+ #
32
33
  # shop.ship(order)
33
34
  # else
34
35
  # logger.error("Failed to verify Paypal's notification, please investigate")
35
36
  # end
36
- #
37
+ #
37
38
  # rescue => e
38
- # order.status = 'failed'
39
+ # order.status = 'failed'
39
40
  # raise
40
41
  # ensure
41
42
  # order.save
42
43
  # end
43
44
  # end
44
- #
45
+ #
45
46
  # render :nothing
46
47
  # end
47
48
  # end
@@ -52,7 +53,7 @@ module ActiveMerchant #:nodoc:
52
53
  super
53
54
  extend MassPayNotification if masspay?
54
55
  end
55
-
56
+
56
57
  # Was the transaction complete?
57
58
  def complete?
58
59
  status == "Completed"
@@ -63,13 +64,20 @@ module ActiveMerchant #:nodoc:
63
64
  type == "masspay"
64
65
  end
65
66
 
66
- # When was this payment received by the client.
67
- # sometimes it can happen that we get the notification much later.
68
- # One possible scenario is that our web application was down. In this case paypal tries several
67
+ # When was this payment received by the client.
68
+ # sometimes it can happen that we get the notification much later.
69
+ # One possible scenario is that our web application was down. In this case paypal tries several
69
70
  # times an hour to inform us about the notification
70
71
  def received_at
71
- parsed_time_fields = DateTime._strptime(params['payment_date'], "%H:%M:%S %b %d, %Y %z")
72
- Time.mktime(*parsed_time_fields.values_at(:year, :mon, :mday, :hour, :min, :sec, :zone))
72
+ parsed_time_fields = DateTime._strptime(params['payment_date'], "%H:%M:%S %b %d, %Y %Z")
73
+ Time.gm(
74
+ parsed_time_fields[:year],
75
+ parsed_time_fields[:mon],
76
+ parsed_time_fields[:mday],
77
+ parsed_time_fields[:hour],
78
+ parsed_time_fields[:min],
79
+ parsed_time_fields[:sec]
80
+ ) + Time.zone_offset(parsed_time_fields[:zone])
73
81
  end
74
82
 
75
83
  # Status of transaction. List of possible values:
@@ -94,8 +102,8 @@ module ActiveMerchant #:nodoc:
94
102
  params['txn_id']
95
103
  end
96
104
 
97
- # What type of transaction are we dealing with?
98
- # "cart" "send_money" "web_accept" are possible here.
105
+ # What type of transaction are we dealing with?
106
+ # "cart" "send_money" "web_accept" are possible here.
99
107
  def type
100
108
  params['txn_type']
101
109
  end
@@ -115,37 +123,37 @@ module ActiveMerchant #:nodoc:
115
123
  params['mc_currency']
116
124
  end
117
125
 
118
- # This is the item number which we submitted to paypal
126
+ # This is the item number which we submitted to paypal
119
127
  # The custom field is also mapped to item_id because PayPal
120
128
  # doesn't return item_number in dispute notifications
121
129
  def item_id
122
130
  params['item_number'] || params['custom']
123
131
  end
124
132
 
125
- # This is the invoice which you passed to paypal
133
+ # This is the invoice which you passed to paypal
126
134
  def invoice
127
135
  params['invoice']
128
- end
136
+ end
129
137
 
130
138
  # Was this a test transaction?
131
139
  def test?
132
140
  params['test_ipn'] == '1'
133
141
  end
134
-
142
+
135
143
  def account
136
144
  params['business'] || params['receiver_email']
137
145
  end
138
146
 
139
- # Acknowledge the transaction to paypal. This method has to be called after a new
140
- # ipn arrives. Paypal will verify that all the information we received are correct and will return a
141
- # ok or a fail.
142
- #
147
+ # Acknowledge the transaction to paypal. This method has to be called after a new
148
+ # ipn arrives. Paypal will verify that all the information we received are correct and will return a
149
+ # ok or a fail.
150
+ #
143
151
  # Example:
144
- #
152
+ #
145
153
  # def paypal_ipn
146
154
  # notify = PaypalNotification.new(request.raw_post)
147
155
  #
148
- # if notify.acknowledge
156
+ # if notify.acknowledge
149
157
  # ... process order ... if notify.complete?
150
158
  # else
151
159
  # ... log possible hacking attempt ...
@@ -153,11 +161,11 @@ module ActiveMerchant #:nodoc:
153
161
  def acknowledge
154
162
  payload = raw
155
163
 
156
- response = ssl_post(Paypal.service_url + '?cmd=_notify-validate', payload,
164
+ response = ssl_post(Paypal.service_url + '?cmd=_notify-validate', payload,
157
165
  'Content-Length' => "#{payload.size}",
158
166
  'User-Agent' => "Active Merchant -- http://activemerchant.org"
159
167
  )
160
-
168
+
161
169
  raise StandardError.new("Faulty paypal result: #{response}") unless ["VERIFIED", "INVALID"].include?(response)
162
170
 
163
171
  response == "VERIFIED"