active_payment 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/controllers/active_payment/paypal_adaptive_payment_callback_controller.rb +26 -0
- data/app/controllers/active_payment/paypal_express_checkout_callback_controller.rb +33 -0
- data/app/models/active_payment/transaction.rb +18 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20150813161144_create_payments_transactions.rb +22 -0
- data/lib/active_payment/configuration.rb +14 -0
- data/lib/active_payment/engine.rb +23 -0
- data/lib/active_payment/gateway.rb +125 -0
- data/lib/active_payment/gateways/paypal_adaptive_payment.rb +85 -0
- data/lib/active_payment/gateways/paypal_express_checkout.rb +86 -0
- data/lib/active_payment/models/concerns/payable.rb +32 -0
- data/lib/active_payment/models/concerns/payee.rb +27 -0
- data/lib/active_payment/models/concerns/payer.rb +13 -0
- data/lib/active_payment/models/sale.rb +60 -0
- data/lib/active_payment/models/sales.rb +78 -0
- data/lib/active_payment/version.rb +3 -0
- data/lib/active_payment.rb +36 -0
- data/spec/active_payment/configuration_spec.rb +59 -0
- data/spec/active_payment/controllers/paypal_adaptive_payment_callback_controller_spec.rb +77 -0
- data/spec/active_payment/controllers/paypal_express_checkout_callback_controller_spec.rb +102 -0
- data/spec/active_payment/gateway_spec.rb +140 -0
- data/spec/active_payment/gateways/paypal_adaptive_payment_spec.rb +105 -0
- data/spec/active_payment/gateways/paypal_express_checkout_spec.rb +144 -0
- data/spec/active_payment/models/sale_spec.rb +109 -0
- data/spec/active_payment/models/sales_spec.rb +93 -0
- data/spec/active_payment/models/transaction_spec.rb +31 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +29 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +32 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/active_payment.rb +7 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20150813161144_create_payments_transactions.rb +22 -0
- data/spec/dummy/db/schema.rb +35 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +33 -0
- data/spec/dummy/log/test.log +73016 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/transaction.rb +15 -0
- data/spec/helper.rb +86 -0
- metadata +298 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13454003f9a1b0df32efb32c30378f63983dabcf
|
4
|
+
data.tar.gz: d1d0536e55d51f5ae1d0397d9ddc0bc51b63db4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a7aca4a74ca3bc90e5d07dde125a1c5d51f750abbdc243881601fb3c11224ee77ced3d3fb6c00ddbb4c5b02a13cb5df77c4d001af230bd4d2d973566cf43cbaa
|
7
|
+
data.tar.gz: c68190e976e1b7c4e28bd7924789cdc6e8b7a0f70fce7fbea2656cbda515caa8b60d1aec89661045790343367795fafb604f14d361ff27cd3f06276d8a4e1c3d
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
class PaypalAdaptivePaymentCallbackController < ActionController::Base
|
3
|
+
protect_from_forgery with: :null_session
|
4
|
+
|
5
|
+
def success
|
6
|
+
flash[:success] = 'Thank you!'
|
7
|
+
redirect_to '/'
|
8
|
+
end
|
9
|
+
|
10
|
+
def cancel
|
11
|
+
ActivePayment::Gateway.cancel_purchase_from_request(
|
12
|
+
gateway: 'paypal_adaptive_payment',
|
13
|
+
request: request)
|
14
|
+
flash[:error] = 'Your transaction has been canceled'
|
15
|
+
redirect_to '/'
|
16
|
+
end
|
17
|
+
|
18
|
+
def ipn
|
19
|
+
ActivePayment::Gateway.verify_purchase_from_request(
|
20
|
+
gateway: 'paypal_adaptive_payment',
|
21
|
+
request: request,
|
22
|
+
data: request.raw_post)
|
23
|
+
head :ok
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
class PaypalExpressCheckoutCallbackController < ActionController::Base
|
3
|
+
protect_from_forgery with: :null_session
|
4
|
+
|
5
|
+
def success
|
6
|
+
ActivePayment::Gateway.verify_purchase_from_request(
|
7
|
+
gateway: 'paypal_express_checkout',
|
8
|
+
request: request,
|
9
|
+
data: purchase_params)
|
10
|
+
flash[:success] = 'Thank you!'
|
11
|
+
|
12
|
+
redirect_to '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
def cancel
|
16
|
+
ActivePayment::Gateway.cancel_purchase_from_request(
|
17
|
+
gateway: 'paypal_express_checkout',
|
18
|
+
request: request)
|
19
|
+
flash[:error] = 'Your transaction has been cancelled'
|
20
|
+
|
21
|
+
redirect_to '/'
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def purchase_params
|
27
|
+
{
|
28
|
+
ip: request.remote_ip,
|
29
|
+
token: params[:token]
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
class Transaction < ActiveRecord::Base
|
3
|
+
enum state: [:pending, :completed, :canceled, :error]
|
4
|
+
serialize :metadata
|
5
|
+
|
6
|
+
validates :amount, :currency, :external_id, :ip_address,
|
7
|
+
:payee_id, :payer_id, :gateway, :state, presence: true
|
8
|
+
|
9
|
+
# in cents
|
10
|
+
validates :amount, numericality: { only_integer: true, greater_than: 0 }
|
11
|
+
|
12
|
+
after_initialize do
|
13
|
+
if self.new_record?
|
14
|
+
self.state ||= Transaction.states[:pending]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
ActivePayment::Engine.routes.draw do
|
2
|
+
#payments callbacks
|
3
|
+
get '/paypal/success', to: 'paypal_express_checkout_callback#success'
|
4
|
+
get '/paypal/cancel', to: 'paypal_express_checkout_callback#cancel'
|
5
|
+
|
6
|
+
get '/paypal_adaptive/success', to: 'paypal_adaptive_payment_callback#success'
|
7
|
+
get '/paypal_adaptive/cancel', to: 'paypal_adaptive_payment_callback#cancel'
|
8
|
+
post '/paypal_adaptive/ipn', to: 'paypal_adaptive_payment_callback#ipn'
|
9
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class CreatePaymentsTransactions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :active_payment_transactions do |t|
|
4
|
+
t.integer :amount
|
5
|
+
t.string :currency
|
6
|
+
t.string :reference_number
|
7
|
+
t.string :external_id
|
8
|
+
t.integer :payee_id
|
9
|
+
t.integer :payer_id
|
10
|
+
t.integer :payable_id
|
11
|
+
t.string :payable_type
|
12
|
+
t.string :gateway
|
13
|
+
t.integer :source
|
14
|
+
t.integer :state
|
15
|
+
t.text :metadata
|
16
|
+
t.string :ip_address
|
17
|
+
t.datetime :paid_at, default: nil
|
18
|
+
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :paypal_login, :paypal_password, :paypal_signature, :paypal_appid
|
4
|
+
attr_accessor :min_amount, :ip_security
|
5
|
+
attr_accessor :default_url_host
|
6
|
+
attr_accessor :test
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@min_amount = 0
|
10
|
+
@ip_security = false
|
11
|
+
@test = false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace ActivePayment
|
4
|
+
|
5
|
+
# append migrations
|
6
|
+
initializer :append_migrations do |app|
|
7
|
+
unless app.root.to_s.match root.to_s
|
8
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
9
|
+
app.config.paths["db/migrate"] << expanded_path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Force routes to be loaded if we are doing any eager load.
|
15
|
+
config.before_eager_load { |app| app.reload_routes! }
|
16
|
+
|
17
|
+
config.generators do |g|
|
18
|
+
g.test_framework :rspec
|
19
|
+
g.assets false
|
20
|
+
g.helper false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
class Gateway
|
3
|
+
attr_accessor :gateway, :purchase_token, :transactions
|
4
|
+
|
5
|
+
def initialize(name)
|
6
|
+
@transactions = []
|
7
|
+
|
8
|
+
name_str = name.to_s.strip.downcase
|
9
|
+
raise(ArgumentError, 'A gateway provider must be specified') if name_str.blank?
|
10
|
+
|
11
|
+
ActiveMerchant::Billing::Base.mode = :test if ActivePayment.configuration.test
|
12
|
+
|
13
|
+
begin
|
14
|
+
@gateway = ActivePayment::Gateways.const_get("#{name_str}".camelize).new
|
15
|
+
rescue SyntaxError, NameError
|
16
|
+
raise ArgumentError, "The specified gateway is not valid (#{name_str})"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup_purchase(sales, ip_address)
|
21
|
+
amount = sales.amount_in_cents
|
22
|
+
raise ActivePayment::InvalidAmountError unless amount >= ActivePayment.configuration.min_amount
|
23
|
+
|
24
|
+
url = @gateway.setup_purchase(sales)
|
25
|
+
@purchase_token = @gateway.purchase_token
|
26
|
+
create_transactions(ip_address)
|
27
|
+
|
28
|
+
url
|
29
|
+
end
|
30
|
+
|
31
|
+
def verify_purchase(external_id, remote_ip, raw_data)
|
32
|
+
@transactions = ActivePayment::Transaction.where(external_id: external_id)
|
33
|
+
fail ActivePayment::NoTransactionError unless @transactions.size > 0
|
34
|
+
verify_ip_address(@transactions, remote_ip)
|
35
|
+
|
36
|
+
if raw_data.is_a?(Hash) && raw_data[:amount].blank?
|
37
|
+
raw_data[:amount] = @transactions.map(&:amount).inject(0, &:+)
|
38
|
+
end
|
39
|
+
|
40
|
+
if @gateway.verify_purchase(raw_data)
|
41
|
+
transactions_success(@transactions)
|
42
|
+
else
|
43
|
+
transactions_error(@transactions)
|
44
|
+
fail ActivePayment::InvalidGatewayResponseError
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def cancel_purchase(external_id, remote_ip)
|
49
|
+
@transactions = ActivePayment::Transaction.where(external_id: external_id)
|
50
|
+
fail ActivePayment::NoTransactionError unless @transactions.size > 0
|
51
|
+
verify_ip_address(@transactions, remote_ip)
|
52
|
+
|
53
|
+
transactions_cancel(@transactions)
|
54
|
+
end
|
55
|
+
|
56
|
+
def external_id_from_request(request)
|
57
|
+
@gateway.external_id_from_request(request)
|
58
|
+
end
|
59
|
+
|
60
|
+
def livemode?
|
61
|
+
@gateway.livemode?
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.verify_purchase_from_request(gateway:, request:, data:)
|
65
|
+
payment_gateway = ActivePayment::Gateway.new(gateway)
|
66
|
+
external_id = payment_gateway.external_id_from_request(request)
|
67
|
+
payment_gateway.verify_purchase(external_id, request.remote_ip, data)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.cancel_purchase_from_request(gateway:, request:)
|
71
|
+
payment_gateway = ActivePayment::Gateway.new(gateway)
|
72
|
+
external_id = payment_gateway.external_id_from_request(request)
|
73
|
+
payment_gateway.cancel_purchase(external_id, request.remote_ip)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def create_transactions(ip_address)
|
79
|
+
fail 'You must called setup_purchase before creating a transaction' unless @gateway.sales
|
80
|
+
|
81
|
+
@gateway.sales.each do |sale|
|
82
|
+
@transactions << ActivePayment::Transaction.create({
|
83
|
+
currency: 'USD',
|
84
|
+
gateway: @gateway.class.to_s,
|
85
|
+
amount: sale.amount_in_cents,
|
86
|
+
ip_address: ip_address,
|
87
|
+
payee_id: sale.payee.id,
|
88
|
+
payer_id: sale.payer.id,
|
89
|
+
payable_id: sale.payable ? sale.payable.id : nil,
|
90
|
+
payable_type: sale.payable ? sale.payable.class.to_s : nil,
|
91
|
+
reference_number: sale.payable.reference,
|
92
|
+
external_id: @purchase_token,
|
93
|
+
metadata: { description: sale.payable.description }
|
94
|
+
})
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def verify_ip_address(transactions, remote_ip)
|
99
|
+
if ActivePayment.configuration.ip_security
|
100
|
+
transactions.each do |transaction|
|
101
|
+
fail ActivePayment::SecurityError unless transaction.ip_address == remote_ip
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def transactions_success(transactions)
|
107
|
+
transactions.each do |transaction|
|
108
|
+
transaction.paid_at = DateTime.now
|
109
|
+
transaction.completed!
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def transactions_error(transactions)
|
114
|
+
transactions.each do |transaction|
|
115
|
+
transaction.error!
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def transactions_cancel(transactions)
|
120
|
+
transactions.each do |transaction|
|
121
|
+
transaction.canceled!
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'active_merchant'
|
2
|
+
|
3
|
+
module ActivePayment
|
4
|
+
module Gateways
|
5
|
+
class PaypalAdaptivePayment
|
6
|
+
include ActionView::Helpers
|
7
|
+
include ActionDispatch::Routing
|
8
|
+
include ActivePayment::Engine.routes.url_helpers
|
9
|
+
|
10
|
+
attr_accessor :purchase_token, :sales
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@gateway = ActiveMerchant::Billing::PaypalAdaptivePayment.new(paypal_options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup_purchase(sales)
|
17
|
+
@sales = sales
|
18
|
+
|
19
|
+
response = @gateway.setup_purchase(purchase_data(sales))
|
20
|
+
raise ActivePayment::InvalidGatewayResponseError unless response.success?
|
21
|
+
|
22
|
+
@purchase_token = response['payKey']
|
23
|
+
@gateway.set_payment_options(payment_options_data(@purchase_token, @sales))
|
24
|
+
@gateway.redirect_url_for(response['payKey'])
|
25
|
+
end
|
26
|
+
|
27
|
+
# return boolean
|
28
|
+
def verify_purchase(params)
|
29
|
+
notify = ActiveMerchant::Billing::Integrations::PaypalAdaptivePayment.notification(params)
|
30
|
+
|
31
|
+
notify.acknowledge && notify.complete?
|
32
|
+
end
|
33
|
+
|
34
|
+
def livemode?
|
35
|
+
ActiveMerchant::Billing::Base.mode != :test
|
36
|
+
end
|
37
|
+
|
38
|
+
def external_id_from_request(request)
|
39
|
+
notify = ActiveMerchant::Billing::Integrations::PaypalAdaptivePayment.notification(request.raw_post)
|
40
|
+
|
41
|
+
notify.params['pay_key']
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def paypal_options
|
47
|
+
{
|
48
|
+
action_type: "CREATE",
|
49
|
+
login: ActivePayment.configuration.paypal_login,
|
50
|
+
password: ActivePayment.configuration.paypal_password,
|
51
|
+
signature: ActivePayment.configuration.paypal_signature,
|
52
|
+
appid: ActivePayment.configuration.paypal_appid
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def purchase_data(sales)
|
57
|
+
{
|
58
|
+
return_url: return_url,
|
59
|
+
cancel_url: cancel_return_url,
|
60
|
+
ipn_notification_url: ipn_notification_url,
|
61
|
+
receiver_list: sales.paypal_recipients,
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def payment_options_data(key, sales)
|
66
|
+
{
|
67
|
+
pa_key: key,
|
68
|
+
receiver_options: sales.paypal_hash,
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def return_url
|
73
|
+
url_for(controller: 'active_payment/paypal_adaptive_payment_callback', action: :success, only_path: false, host: ActivePayment.configuration.default_url_host)
|
74
|
+
end
|
75
|
+
|
76
|
+
def cancel_return_url
|
77
|
+
url_for(controller: 'active_payment/paypal_adaptive_payment_callback', action: :cancel, only_path: false, host: ActivePayment.configuration.default_url_host)
|
78
|
+
end
|
79
|
+
|
80
|
+
def ipn_notification_url
|
81
|
+
url_for(controller: 'active_payment/paypal_adaptive_payment_callback', action: :ipn, only_path: false, host: ActivePayment.configuration.default_url_host)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'active_merchant'
|
2
|
+
|
3
|
+
module ActivePayment
|
4
|
+
module Gateways
|
5
|
+
class PaypalExpressCheckout
|
6
|
+
include ActionView::Helpers
|
7
|
+
include ActionDispatch::Routing
|
8
|
+
include ActivePayment::Engine.routes.url_helpers
|
9
|
+
|
10
|
+
attr_accessor :purchase_token, :sales
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@gateway = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup_purchase(sales)
|
17
|
+
@sales = sales
|
18
|
+
|
19
|
+
payables = @sales.map(&:payable)
|
20
|
+
amount = @sales.amount_in_cents.to_i
|
21
|
+
|
22
|
+
response = @gateway.setup_purchase(amount, paypal_data(payables))
|
23
|
+
raise ActivePayment::InvalidGatewayResponseError unless response.success?
|
24
|
+
|
25
|
+
@purchase_token = response.token
|
26
|
+
@gateway.redirect_url_for(response.token)
|
27
|
+
end
|
28
|
+
|
29
|
+
# return boolean
|
30
|
+
def verify_purchase(params)
|
31
|
+
token = params[:token]
|
32
|
+
|
33
|
+
begin
|
34
|
+
response = @gateway.details_for(token)
|
35
|
+
fail ActivePayment::InvalidGatewayResponseError unless response.success?
|
36
|
+
|
37
|
+
amount = params[:amount]
|
38
|
+
purchase_response = @gateway.purchase(amount, params.merge(payer_id: response.payer_id))
|
39
|
+
fail ActivePayment::InvalidGatewayResponseError unless purchase_response.success?
|
40
|
+
rescue ActivePayment::InvalidGatewayResponseError
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def external_id_from_request(request)
|
48
|
+
request.params[:token]
|
49
|
+
end
|
50
|
+
|
51
|
+
def livemode?
|
52
|
+
ActiveMerchant::Billing::Base.mode != :test
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def paypal_options
|
58
|
+
{
|
59
|
+
login: ActivePayment.configuration.paypal_login,
|
60
|
+
password: ActivePayment.configuration.paypal_password,
|
61
|
+
signature: ActivePayment.configuration.paypal_signature,
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def paypal_data(payables)
|
66
|
+
{
|
67
|
+
items: payables.map(&:to_paypal_hash),
|
68
|
+
return_url: return_url,
|
69
|
+
cancel_return_url: cancel_return_url,
|
70
|
+
currency_code: 'USD',
|
71
|
+
allow_note: false,
|
72
|
+
allow_guest_checkout: true
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def return_url
|
77
|
+
url_for(controller: 'active_payment/paypal_express_checkout_callback', action: :success, only_path: false, host: ActivePayment.configuration.default_url_host)
|
78
|
+
end
|
79
|
+
|
80
|
+
def cancel_return_url
|
81
|
+
url_for(controller: 'active_payment/paypal_express_checkout_callback', action: :cancel, only_path: false, host: ActivePayment.configuration.default_url_host)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
module Models
|
3
|
+
module Payable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def to_paypal_hash
|
7
|
+
{
|
8
|
+
name: description,
|
9
|
+
amount: amount.to_i,
|
10
|
+
number: 1,
|
11
|
+
quantity: 1,
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def shipping
|
16
|
+
shipping
|
17
|
+
end
|
18
|
+
|
19
|
+
def tax
|
20
|
+
tax
|
21
|
+
end
|
22
|
+
|
23
|
+
def reference
|
24
|
+
id
|
25
|
+
end
|
26
|
+
|
27
|
+
def description
|
28
|
+
description
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
module Models
|
3
|
+
module Payee
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
if superclass == ActiveRecord::Base
|
8
|
+
has_many :received_transactions, foreign_key: 'payee_id', class_name: ActivePayment::Transaction
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_paypal_hash
|
13
|
+
{
|
14
|
+
email: paypal_identifier,
|
15
|
+
primary: false
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def paypal_identifier
|
20
|
+
paypal
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
module Models
|
3
|
+
module Payer
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
if superclass == ActiveRecord::Base
|
8
|
+
has_many :sent_transactions, foreign_key: 'payer_id', class_name: ActivePayment::Transaction
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
module Models
|
3
|
+
class Sale
|
4
|
+
attr_accessor :payable, :payer, :payee
|
5
|
+
|
6
|
+
def initialize(payable:, payer:, payee:)
|
7
|
+
@payable = payable
|
8
|
+
@payer = payer
|
9
|
+
@payee = payee
|
10
|
+
end
|
11
|
+
|
12
|
+
def amount
|
13
|
+
payable.amount.to_f / 100
|
14
|
+
end
|
15
|
+
|
16
|
+
def amount_in_cents
|
17
|
+
payable.amount.to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
payable.description
|
22
|
+
end
|
23
|
+
|
24
|
+
def shipping
|
25
|
+
payable.shipping || 0
|
26
|
+
end
|
27
|
+
|
28
|
+
def tax
|
29
|
+
payable.tax || 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def paypal_recipient
|
33
|
+
{
|
34
|
+
email: payee.paypal_identifier,
|
35
|
+
amount: amount,
|
36
|
+
primary: false
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def paypal_hash
|
41
|
+
{
|
42
|
+
description: payable.description,
|
43
|
+
invoice_data: {
|
44
|
+
item: [{
|
45
|
+
name: payable.description,
|
46
|
+
item_count: 1,
|
47
|
+
item_price: amount,
|
48
|
+
price: amount
|
49
|
+
}],
|
50
|
+
total_shipping: payable.shipping,
|
51
|
+
total_tax: payable.tax
|
52
|
+
},
|
53
|
+
receiver: {
|
54
|
+
email: @payee.paypal_identifier
|
55
|
+
}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ActivePayment
|
2
|
+
module Models
|
3
|
+
class Sales
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_accessor :sales
|
7
|
+
|
8
|
+
def initialize(sales = [])
|
9
|
+
@sales = sales
|
10
|
+
end
|
11
|
+
|
12
|
+
def amount
|
13
|
+
@sales.map(&:amount).inject(0, &:+)
|
14
|
+
end
|
15
|
+
|
16
|
+
def amount_in_cents
|
17
|
+
@sales.map(&:amount_in_cents).inject(0, &:+)
|
18
|
+
end
|
19
|
+
|
20
|
+
def total_shipping
|
21
|
+
total_shipping = 0
|
22
|
+
|
23
|
+
@sales.each do |sale|
|
24
|
+
total_shipping += sale.shipping if sale.shipping
|
25
|
+
end
|
26
|
+
|
27
|
+
total_shipping
|
28
|
+
end
|
29
|
+
|
30
|
+
def total_tax
|
31
|
+
total_tax = 0
|
32
|
+
|
33
|
+
@sales.each do |sale|
|
34
|
+
total_tax += sale.tax if sale.tax
|
35
|
+
end
|
36
|
+
|
37
|
+
total_tax
|
38
|
+
end
|
39
|
+
|
40
|
+
def paypal_hash
|
41
|
+
paypal_hash = []
|
42
|
+
@sales.each do |sale|
|
43
|
+
paypal_hash << sale.paypal_hash
|
44
|
+
end
|
45
|
+
|
46
|
+
paypal_hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def each
|
50
|
+
@sales.each do |sale|
|
51
|
+
yield sale
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def paypal_recipients
|
56
|
+
recipients = []
|
57
|
+
@sales.each do |sale|
|
58
|
+
recipients << sale.paypal_recipient
|
59
|
+
end
|
60
|
+
|
61
|
+
recipients
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def items_data
|
68
|
+
data = []
|
69
|
+
|
70
|
+
@sales.each do |sale|
|
71
|
+
data << { name: sale.description, item_count: 1, item_price: sale.amount, price: sale.amount }
|
72
|
+
end
|
73
|
+
|
74
|
+
data
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|