trado_paypal_module 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +34 -0
- data/app/controllers/trado_paypal_module/ipn_controller.rb +26 -0
- data/app/controllers/trado_paypal_module/paypal_controller.rb +36 -0
- data/config/routes.rb +3 -0
- data/lib/generators/templates/controller.rb +6 -0
- data/lib/generators/templates/helper.rb +6 -0
- data/lib/generators/templates/migration.rb +13 -0
- data/lib/generators/trado_paypal_module/install_generator.rb +91 -0
- data/lib/tasks/trado_paypal_module_tasks.rake +4 -0
- data/lib/trado_paypal_module.rb +12 -0
- data/lib/trado_paypal_module/active_record.rb +15 -0
- data/lib/trado_paypal_module/engine.rb +6 -0
- data/lib/trado_paypal_module/paypaler.rb +219 -0
- data/lib/trado_paypal_module/version.rb +3 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/test_helper.rb +20 -0
- data/test/trado_paypal_module_test.rb +7 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eb0fc1e85e04eec3a1950232e9d16b9209263dba
|
4
|
+
data.tar.gz: 2865fc5e70d08593d5fa176c9be02582f0fa73bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9ce411a3afd6fd97697e65cb7d6f24c130d75b94da7b4326fafadaa5ac8e01db4f8d49a5310a39c7ec67978d961397ead41b8c34a58592f37193fe31baec63ee
|
7
|
+
data.tar.gz: 388365d0b59ccfa689da49dc8876a12c2b226c31d1785e34af14f5dfdf3fe52707db304f98243bc2bf122775f224498d287ca7cb46549aca448f49a2c1ff20e2
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 Tom Dallimore
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'TradoPaypalModule'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'lib'
|
28
|
+
t.libs << 'test'
|
29
|
+
t.pattern = 'test/**/*_test.rb'
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
task default: :test
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class TradoPaypalModule::IpnController < ApplicationController
|
2
|
+
skip_before_action :authenticate_user!
|
3
|
+
|
4
|
+
# TODO: Find out why this is throwing an error.
|
5
|
+
include ActiveMerchant::Billing::Integrations
|
6
|
+
|
7
|
+
# Handler for incoming Instant Payment Notifications from paypal about orders
|
8
|
+
def update
|
9
|
+
notify = Paypal::Notification.new(request.raw_post)
|
10
|
+
|
11
|
+
if notify.acknowledge
|
12
|
+
transaction = Transaction.where(order_id: notify.params['invoice']).first
|
13
|
+
if notify.complete? and transaction.gross_amount.to_s == notify.params['mc_gross']
|
14
|
+
transaction.fee = notify.params['mc_fee']
|
15
|
+
transaction.completed!
|
16
|
+
else
|
17
|
+
transaction.failed!
|
18
|
+
end
|
19
|
+
if transaction.save
|
20
|
+
Mailatron4000::Orders.confirmation_email(transaction.order) rescue Rails.logger.warn("PayPal IPN: Order #{transaction.order.id} confirmation email failed to send")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
render nothing: true
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class TradoPaypalModule::PaypalController < ApplicationController
|
2
|
+
skip_before_action :authenticate_user!
|
3
|
+
include CartBuilder
|
4
|
+
|
5
|
+
def confirm
|
6
|
+
set_order
|
7
|
+
set_cart_totals
|
8
|
+
set_grouped_countries
|
9
|
+
set_browser_data
|
10
|
+
@order.attributes = params[:order]
|
11
|
+
if @order.save
|
12
|
+
@order.calculate(current_cart, Store.tax_rate)
|
13
|
+
generate_payment_url
|
14
|
+
if @redirect_url.nil?
|
15
|
+
flash_message :error, 'An error ocurred with your order. Please try again.'
|
16
|
+
Rails.logger.error "PayPal: Unable to generate redirect URL."
|
17
|
+
redirect_to checkout_carts_url
|
18
|
+
else
|
19
|
+
redirect_to @redirect_url
|
20
|
+
end
|
21
|
+
else
|
22
|
+
flash_message :error, 'An error ocurred with your order. Please try again.'
|
23
|
+
render theme_presenter.page_template_path('carts/checkout'), layout: theme_presenter.layout_template_path
|
24
|
+
end
|
25
|
+
rescue ActiveMerchant::ConnectionError
|
26
|
+
flash_message :error, 'An error ocurred with your order. Please try again.'
|
27
|
+
Rails.logger.error "PayPal: API is temporarily unavailable."
|
28
|
+
redirect_to checkout_carts_url
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def generate_payment_url
|
34
|
+
@redirect_url = Store::PayProvider.new(cart: current_cart, order: @order, provider: @order.payment_type, ip_address: request.remote_ip).build
|
35
|
+
end
|
36
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class AddPaypalAttributes < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :transactions, :paypal_id, :string
|
4
|
+
add_column :orders, :paypal_express_token, :string
|
5
|
+
add_column :orders, :paypal_express_payer_id, :string
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.down
|
9
|
+
remove_column :transactions, :paypal_id
|
10
|
+
remove_column :orders, :paypal_express_token
|
11
|
+
remove_column :orders, :paypal_express_payer_id
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module TradoPaypalModule
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
def copy_migration
|
7
|
+
unless paypal_migration_already_exists?
|
8
|
+
timestamp_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
|
9
|
+
copy_file "migration.rb", "db/migrate/#{timestamp_number}_add_paypal_attributes.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def copy_helper
|
14
|
+
template "helper.rb", "app/helpers/paypal_helper.rb"
|
15
|
+
end
|
16
|
+
|
17
|
+
def copy_controller
|
18
|
+
template "controller.rb", "app/controllers/carts/paypal_controller.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup_routes
|
22
|
+
route_content = <<-CONTENT
|
23
|
+
|
24
|
+
mount TradoPaypalModule::Engine => '/paypal'
|
25
|
+
CONTENT
|
26
|
+
inject_into_file "config/routes.rb", route_content, after: "Trado::Application.routes.draw do"
|
27
|
+
end
|
28
|
+
|
29
|
+
def assign_model_concerns
|
30
|
+
order_content = <<-CONTENT
|
31
|
+
|
32
|
+
has_order_paypal
|
33
|
+
CONTENT
|
34
|
+
transaction_content = <<-CONTENT
|
35
|
+
|
36
|
+
has_transaction_paypal
|
37
|
+
CONTENT
|
38
|
+
|
39
|
+
inject_into_file "app/models/order.rb", order_content, after: "class Order < ActiveRecord::Base"
|
40
|
+
inject_into_file "app/models/transaction.rb", transaction_content, after: "class Transaction < ActiveRecord::Base"
|
41
|
+
end
|
42
|
+
|
43
|
+
def setup_env_configs
|
44
|
+
development_content = <<-CONTENT
|
45
|
+
|
46
|
+
# PayPal settings
|
47
|
+
config.after_initialize do
|
48
|
+
ActiveMerchant::Billing::Base.mode = :test
|
49
|
+
paypal_options = {
|
50
|
+
login: Rails.application.secrets.paypal_login,
|
51
|
+
password: Rails.application.secrets.paypal_password,
|
52
|
+
signature: Rails.application.secrets.paypal_signature
|
53
|
+
}
|
54
|
+
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
|
55
|
+
end
|
56
|
+
CONTENT
|
57
|
+
|
58
|
+
test_content = <<-CONTENT
|
59
|
+
|
60
|
+
# PayPal settings
|
61
|
+
config.after_initialize do
|
62
|
+
ActiveMerchant::Billing::Base.mode = :test
|
63
|
+
::EXPRESS_GATEWAY = ActiveMerchant::Billing::BogusGateway.new
|
64
|
+
end
|
65
|
+
CONTENT
|
66
|
+
|
67
|
+
production_content = <<-CONTENT
|
68
|
+
|
69
|
+
# PayPal settings
|
70
|
+
config.after_initialize do
|
71
|
+
paypal_options = {
|
72
|
+
login: Rails.application.secrets.paypal_login,
|
73
|
+
password: Rails.application.secrets.paypal_password,
|
74
|
+
signature: Rails.application.secrets.paypal_signature
|
75
|
+
}
|
76
|
+
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
|
77
|
+
end
|
78
|
+
CONTENT
|
79
|
+
inject_into_file "config/environments/development.rb", development_content, after: "Trado::Application.configure do"
|
80
|
+
inject_into_file "config/environments/test.rb", test_content, after: "Trado::Application.configure do"
|
81
|
+
inject_into_file "config/environments/production.rb", production_content, after: "Trado::Application.configure do"
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def paypal_migration_already_exists?
|
87
|
+
Dir.glob("#{File.join(destination_root, File.join("db", "migrate"))}/[0-9]*_*.rb").grep(/\d+_add_paypal_attributes.rb$/).first
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module TradoPaypalModule
|
2
|
+
end
|
3
|
+
|
4
|
+
require 'activemerchant'
|
5
|
+
require 'offsite_payments'
|
6
|
+
|
7
|
+
require 'trado_paypal_module/engine'
|
8
|
+
require 'trado_paypal_module/version'
|
9
|
+
require 'trado_paypal_module/active_record'
|
10
|
+
require 'trado_paypal_module/paypaler'
|
11
|
+
|
12
|
+
ActiveRecord::Base.send(:include, TradoPaypalModule::ActiveRecord)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module TradoPaypalModule
|
2
|
+
module ActiveRecord
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def has_order_paypal
|
7
|
+
attr_accessible :paypal_express_token, :paypal_express_payer_id
|
8
|
+
end
|
9
|
+
|
10
|
+
def has_transaction_paypal
|
11
|
+
attr_accessible :paypal_id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require_dependency 'lib/payatron_4000'
|
2
|
+
|
3
|
+
module TradoPaypalModule
|
4
|
+
|
5
|
+
class Paypaler
|
6
|
+
|
7
|
+
# Builds the a PayPal purchase request from the order data
|
8
|
+
# If successful, redirect to PayPal for the user to login
|
9
|
+
# If unsuccessful, redirect to failed order page
|
10
|
+
#
|
11
|
+
# @param cart [Object]
|
12
|
+
# @param order [Object]
|
13
|
+
# @param ip_address [String]
|
14
|
+
# @return [String] redirect url
|
15
|
+
def self.build cart, order, ip_address
|
16
|
+
response = EXPRESS_GATEWAY.setup_purchase(
|
17
|
+
Store::Price.new(price: order.gross_amount, tax_type: 'net').singularize,
|
18
|
+
TradoPaypalModule::Paypaler.express_setup_options(
|
19
|
+
order,
|
20
|
+
cart,
|
21
|
+
ip_address,
|
22
|
+
Rails.application.routes.url_helpers.confirm_order_url(order, host: Trado::Application.config.action_mailer.default_url_options[:host]),
|
23
|
+
Rails.application.routes.url_helpers.mycart_carts_url(host: Trado::Application.config.action_mailer.default_url_options[:host])
|
24
|
+
)
|
25
|
+
)
|
26
|
+
if response.success?
|
27
|
+
return EXPRESS_GATEWAY.redirect_url_for(response.token)
|
28
|
+
else
|
29
|
+
TradoPaypalModule::Paypaler.failed(response, order)
|
30
|
+
Payatron4000.decommission_order(order)
|
31
|
+
return Rails.application.routes.url_helpers.failed_order_url(order, host: Trado::Application.config.action_mailer.default_url_options[:host])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Creates the payment information object for PayPal to parse in the login
|
36
|
+
#
|
37
|
+
# @param order [Object]
|
38
|
+
# @param cart [Object]
|
39
|
+
# @param ip_address [String]
|
40
|
+
# @param return_url [String]
|
41
|
+
# @param cancel_url [String]
|
42
|
+
# @return [Object] order data from the store for PayPal
|
43
|
+
def self.express_setup_options order, cart, ip_address, return_url, cancel_url
|
44
|
+
{
|
45
|
+
:subtotal => Store::Price.new(price: (order.net_amount - order.delivery.price), tax_type: 'net').singularize,
|
46
|
+
:shipping => Store::Price.new(price: order.delivery.price, tax_type: 'net').singularize,
|
47
|
+
:tax => Store::Price.new(price: order.tax_amount, tax_type: 'net').singularize,
|
48
|
+
:handling => 0,
|
49
|
+
:order_id => order.id,
|
50
|
+
:items => TradoPaypalModule::Paypaler.express_items(cart.cart_items),
|
51
|
+
:address_override => 1,
|
52
|
+
:shipping_address => order.delivery_address.full_address,
|
53
|
+
:req_confirm_shipping => 0,
|
54
|
+
:ip => ip_address,
|
55
|
+
:return_url => return_url,
|
56
|
+
:cancel_return_url => cancel_url,
|
57
|
+
:currency => Store.settings.currency_code,
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
# Creates the payment information object for PayPal to parse in the confirmation step and complete the purchase
|
62
|
+
#
|
63
|
+
# @param order [Object]
|
64
|
+
# @return [Object] current customer order
|
65
|
+
def self.express_purchase_options order, ip_address
|
66
|
+
{
|
67
|
+
:subtotal => Store::Price.new(price: (order.net_amount - order.delivery.price), tax_type: 'net').singularize,
|
68
|
+
:shipping => Store::Price.new(price: order.delivery.price, tax_type: 'net').singularize,
|
69
|
+
:tax => Store::Price.new(price: order.tax_amount, tax_type: 'net').singularize,
|
70
|
+
:handling => 0,
|
71
|
+
:items => TradoPaypalModule::Paypaler.express_items(order.order_items),
|
72
|
+
:token => order.paypal_express_token,
|
73
|
+
:payer_id => order.paypal_express_payer_id,
|
74
|
+
:currency => Store.settings.currency_code,
|
75
|
+
:ip => ip_address,
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
# Creates an aray of items which represent cart_items or order_items
|
80
|
+
# This is passed into the express_setup_options and express_purchase_options methods
|
81
|
+
#
|
82
|
+
# @return [Array] list of cart or order items for PayPal
|
83
|
+
def self.express_items items
|
84
|
+
items.collect do |item|
|
85
|
+
{
|
86
|
+
:name => "#{item.sku.product.name} (#{item.sku.variants.map{|v| v.name.titleize}.join(' / ')})",
|
87
|
+
:description => "#{item.sku.product.name} (#{item.sku.variants.map{|v| v.name.titleize}.join(' / ')})",
|
88
|
+
:amount => Store::Price.new(price: item.price, tax_type: 'net').singularize,
|
89
|
+
:quantity => item.quantity
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Assign PayPal token to order after user logs into their account
|
95
|
+
#
|
96
|
+
# @param token [String]
|
97
|
+
# @param payer_id [Integer]
|
98
|
+
# @param order [Object]
|
99
|
+
def self.assign_paypal_token token, payer_id, order
|
100
|
+
order.paypal_express_token = token
|
101
|
+
order.paypal_express_payer_id = payer_id
|
102
|
+
order.save(validate: false)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Completes the order process by communicating with PayPal; receives a response and in turn creates the relevant transaction records,
|
106
|
+
# sends a confirmation email and redirects the user.
|
107
|
+
#
|
108
|
+
# @param order [Object]
|
109
|
+
# @param session [Object
|
110
|
+
def self.complete order, session, ip_address
|
111
|
+
order.transfer(order.cart)
|
112
|
+
response = EXPRESS_GATEWAY.purchase(Store::Price.new(price: order.gross_amount, tax_type: 'net').singularize,
|
113
|
+
TradoPaypalModule::Paypaler.express_purchase_options(order, ip_address)
|
114
|
+
)
|
115
|
+
if response.success?
|
116
|
+
TradoPaypalModule::Paypaler.successful(response, order)
|
117
|
+
Payatron4000.destroy_cart(session)
|
118
|
+
Payatron4000.decommission_order(order)
|
119
|
+
order.reload
|
120
|
+
Mailatron4000::Orders.confirmation_email(order)
|
121
|
+
return Rails.application.routes.url_helpers.success_order_url(order, host: Trado::Application.config.action_mailer.default_url_options[:host])
|
122
|
+
else
|
123
|
+
TradoPaypalModule::Paypaler.failed(response, order)
|
124
|
+
order.reload
|
125
|
+
Mailatron4000::Orders.confirmation_email(order)
|
126
|
+
return Rails.application.routes.url_helpers.failed_order_url(order, host: Trado::Application.config.action_mailer.default_url_options[:host])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Upon successfully completing an order with a PayPal payment option a new transaction record is created, stock is updated for the relevant SKU
|
131
|
+
#
|
132
|
+
# @param response [Object]
|
133
|
+
# @param order [Object]
|
134
|
+
def self.successful response, order
|
135
|
+
Transaction.new( :fee => response.params['PaymentInfo']['FeeAmount'],
|
136
|
+
:order_id => order.id,
|
137
|
+
:payment_status => response.params['PaymentInfo']['PaymentStatus'].downcase,
|
138
|
+
:transaction_type => 'Credit',
|
139
|
+
:tax_amount => response.params['PaymentInfo']['TaxAmount'],
|
140
|
+
:paypal_id => response.params['PaymentInfo']['TransactionID'],
|
141
|
+
:payment_type => 'paypal',
|
142
|
+
:net_amount => response.params['PaymentInfo']['GrossAmount'].to_d - response.params['PaymentInfo']['TaxAmount'].to_d,
|
143
|
+
:gross_amount => response.params['PaymentInfo']['GrossAmount'],
|
144
|
+
:status_reason => response.params['PaymentInfo']['PendingReason']
|
145
|
+
).save(validate: false)
|
146
|
+
Payatron4000.update_stock(order)
|
147
|
+
Payatron4000.increment_product_order_count(order.products)
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
# When an order has failed to complete, a new transaction record is created with a logged status reason
|
152
|
+
#
|
153
|
+
# @param response [Object]
|
154
|
+
# @param order [Object]
|
155
|
+
def self.failed response, order
|
156
|
+
Transaction.new( :fee => 0,
|
157
|
+
:gross_amount => order.gross_amount,
|
158
|
+
:order_id => order.id,
|
159
|
+
:payment_status => 'failed',
|
160
|
+
:transaction_type => 'Credit',
|
161
|
+
:tax_amount => order.tax_amount,
|
162
|
+
:paypal_id => nil,
|
163
|
+
:payment_type => 'paypal',
|
164
|
+
:net_amount => order.net_amount,
|
165
|
+
:status_reason => response.message,
|
166
|
+
:error_code => response.params["error_codes"].to_i
|
167
|
+
).save(validate: false)
|
168
|
+
Payatron4000.increment_product_order_count(order.products)
|
169
|
+
end
|
170
|
+
|
171
|
+
# A list of available currency codes for the PayPal payment system
|
172
|
+
#
|
173
|
+
# @return [Array] available currency codes
|
174
|
+
def self.currency_codes
|
175
|
+
return [
|
176
|
+
"AUD",
|
177
|
+
"CAD",
|
178
|
+
"CZK",
|
179
|
+
"DKK",
|
180
|
+
"EUR",
|
181
|
+
"HKD",
|
182
|
+
"HUF",
|
183
|
+
"ILS",
|
184
|
+
"JPY",
|
185
|
+
"MXN",
|
186
|
+
"NOK",
|
187
|
+
"NZD",
|
188
|
+
"PHP",
|
189
|
+
"PLN",
|
190
|
+
"GBP",
|
191
|
+
"RUB",
|
192
|
+
"SGD",
|
193
|
+
"SEK",
|
194
|
+
"CHF",
|
195
|
+
"TWD",
|
196
|
+
"THB",
|
197
|
+
"USD"
|
198
|
+
]
|
199
|
+
end
|
200
|
+
|
201
|
+
# A list of fatal error codes for an order
|
202
|
+
# If the passed in error code parameter is included in the fatal codes array, return true
|
203
|
+
#
|
204
|
+
# @param error_code [Integer] payment error code
|
205
|
+
# @return [Boolean]
|
206
|
+
def self.fatal_error_code? error_code
|
207
|
+
@fatal_codes =
|
208
|
+
[
|
209
|
+
10412, # PayPal: Payment has already been made for this InvoiceID.
|
210
|
+
10415 # PayPal: A successful transaction has already been completed for this token.
|
211
|
+
]
|
212
|
+
return @fatal_codes.include?(error_code) ? true : false
|
213
|
+
end
|
214
|
+
|
215
|
+
def self.valid_tokens? params
|
216
|
+
params[:token].present? && params[:PayerID].present?
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|