moneytree-rails 0.1.0 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/README.md +63 -30
- data/Rakefile +30 -4
- data/app/assets/config/moneytree_manifest.js +1 -0
- data/app/assets/stylesheets/moneytree/application.css +15 -0
- data/app/controllers/moneytree/application_controller.rb +9 -0
- data/app/controllers/moneytree/oauth/square_controller.rb +14 -0
- data/app/controllers/moneytree/oauth/stripe_controller.rb +44 -0
- data/app/controllers/moneytree/webhooks/square_controller.rb +9 -0
- data/app/controllers/moneytree/webhooks/stripe_controller.rb +67 -0
- data/app/jobs/moneytree/application_job.rb +4 -0
- data/app/mailers/moneytree/application_mailer.rb +6 -0
- data/app/models/moneytree/application_record.rb +5 -0
- data/app/models/moneytree/payment.rb +23 -0
- data/app/models/moneytree/payment_gateway.rb +47 -0
- data/app/models/moneytree/refund.rb +46 -0
- data/app/models/moneytree/transaction.rb +30 -0
- data/app/views/layouts/moneytree/application.html.erb +15 -0
- data/config/routes.rb +8 -0
- data/db/migrate/20200914151648_create_moneytree_payment_gateways.rb +11 -0
- data/db/migrate/20201008161617_create_moneytree_transactions.rb +18 -0
- data/lib/moneytree-rails.rb +1 -0
- data/lib/moneytree.rb +16 -16
- data/lib/moneytree/account.rb +4 -34
- data/lib/moneytree/engine.rb +5 -0
- data/lib/moneytree/order.rb +15 -0
- data/lib/moneytree/payment_provider/base.rb +5 -2
- data/lib/moneytree/payment_provider/stripe.rb +80 -0
- data/lib/moneytree/transaction_response.rb +15 -0
- data/lib/moneytree/version.rb +1 -1
- data/lib/tasks/moneytree_tasks.rake +4 -0
- metadata +45 -33
- data/.github/workflows/ruby.yml +0 -33
- data/.gitignore +0 -12
- data/.rspec +0 -3
- data/.travis.yml +0 -6
- data/CHANGELOG.md +0 -7
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -15
- data/Gemfile.lock +0 -248
- data/Guardfile +0 -70
- data/LICENSE.txt +0 -21
- data/app/controllers/moneytree/oauth_controller.rb +0 -18
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/config.ru +0 -9
- data/lib/generators/moneytree/activerecord_generator.rb +0 -41
- data/lib/generators/moneytree/base_generator.rb +0 -13
- data/lib/generators/moneytree/install_generator.rb +0 -43
- data/lib/generators/moneytree/templates/active_record_event_model.rb.tt +0 -10
- data/lib/generators/moneytree/templates/active_record_migration.rb.tt +0 -62
- data/lib/generators/moneytree/templates/active_record_visit_model.rb.tt +0 -6
- data/lib/generators/moneytree/templates/base_store_initializer.rb.tt +0 -20
- data/lib/generators/moneytree/templates/moneytree_initializer.rb.tt +0 -15
- data/lib/moneytree/transaction.rb +0 -9
- data/moneytree.gemspec +0 -29
@@ -0,0 +1,46 @@
|
|
1
|
+
module Moneytree
|
2
|
+
class Refund < Transaction
|
3
|
+
belongs_to :payment, class_name: 'Moneytree::Payment'
|
4
|
+
|
5
|
+
before_validation :set_order, :set_payment_gateway
|
6
|
+
|
7
|
+
validates_presence_of :payment
|
8
|
+
|
9
|
+
validates_numericality_of :amount, less_than: 0
|
10
|
+
validates_numericality_of :app_fee_amount, less_than_or_equal_to: 0
|
11
|
+
|
12
|
+
validate :order_matches_payment, :gateway_matches_payment
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def execute_transaction(metadata: {})
|
17
|
+
process_response(
|
18
|
+
payment_gateway.refund(
|
19
|
+
amount,
|
20
|
+
payment.details,
|
21
|
+
metadata: metadata.merge(moneytree_transaction_id: id)
|
22
|
+
)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
# validates_presence_of :payment
|
27
|
+
def set_order
|
28
|
+
self.order ||= payment&.order
|
29
|
+
end
|
30
|
+
|
31
|
+
# validates_presence_of :payment
|
32
|
+
def set_payment_gateway
|
33
|
+
self.payment_gateway ||= payment&.payment_gateway
|
34
|
+
end
|
35
|
+
|
36
|
+
# validates
|
37
|
+
def order_matches_payment
|
38
|
+
errors.add(:order_id, :mismatch) if order_id != payment&.order_id
|
39
|
+
end
|
40
|
+
|
41
|
+
# validates
|
42
|
+
def gateway_matches_payment
|
43
|
+
errors.add(:payment_gateway_id, :mismatch) if payment_gateway_id != payment&.payment_gateway_id
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Moneytree
|
2
|
+
class Transaction < ApplicationRecord
|
3
|
+
belongs_to :payment_gateway
|
4
|
+
belongs_to :order, polymorphic: true
|
5
|
+
|
6
|
+
validates_presence_of :psp_error, if: :failed?
|
7
|
+
|
8
|
+
enum status: %i[initialized pending completed failed]
|
9
|
+
|
10
|
+
serialize :details
|
11
|
+
|
12
|
+
after_create_commit :execute_transaction
|
13
|
+
|
14
|
+
def process_response(response)
|
15
|
+
if response.success?
|
16
|
+
update!(
|
17
|
+
status: :completed,
|
18
|
+
psp_error: response.message,
|
19
|
+
details: (details || {}).merge(response.body)
|
20
|
+
)
|
21
|
+
else
|
22
|
+
# FIXME: pending state
|
23
|
+
update!(
|
24
|
+
status: :failed,
|
25
|
+
psp_error: response.message
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateMoneytreePaymentGateways < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :moneytree_payment_gateways do |t|
|
4
|
+
t.text :psp_credentials
|
5
|
+
t.integer :psp, null: false
|
6
|
+
t.references :account, polymorphic: true, index: { name: 'index_moneytree_pg_account_type_and_account_id' }
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateMoneytreeTransactions < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :moneytree_transactions do |t|
|
4
|
+
t.decimal :amount, null: false, default: 0
|
5
|
+
t.decimal :app_fee_amount, null: false, default: 0
|
6
|
+
t.integer :status, null: false, default: 0
|
7
|
+
t.string :type, null: false, default: 'Moneytree::Payment'
|
8
|
+
t.references :order, polymorphic: true, null: false
|
9
|
+
t.references :payment_gateway, null: false
|
10
|
+
t.references :payment, foreign_key: { to_table: :moneytree_transactions }
|
11
|
+
t.text :psp_error
|
12
|
+
t.text :details
|
13
|
+
t.text :refund_reason
|
14
|
+
|
15
|
+
t.timestamps
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'moneytree'
|
data/lib/moneytree.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
# dependencies
|
2
|
-
require '
|
3
|
-
require 'active_support/core_ext'
|
2
|
+
# require 'rails'
|
3
|
+
# require 'active_support/core_ext'
|
4
4
|
|
5
5
|
# modules
|
6
6
|
# FIXME: autoload instead? https :/ / github.com / excid3 / noticed / blob / master / lib / noticed.rb
|
7
7
|
require 'moneytree/version'
|
8
|
+
require 'moneytree/transaction_response'
|
8
9
|
require 'moneytree/account'
|
9
|
-
require 'moneytree/
|
10
|
-
require 'moneytree/payment_provider/
|
11
|
-
|
12
|
-
require
|
10
|
+
require 'moneytree/order'
|
11
|
+
require 'moneytree/payment_provider/base'
|
12
|
+
require 'moneytree/payment_provider/stripe'
|
13
|
+
require 'moneytree/engine'
|
13
14
|
|
14
15
|
module Moneytree
|
15
|
-
PSPS = %i[
|
16
|
+
PSPS = %i[stripe].freeze
|
16
17
|
|
17
18
|
mattr_accessor :enabled_psps
|
18
|
-
mattr_accessor :
|
19
|
-
mattr_accessor :order_class
|
20
|
-
mattr_accessor :transaction_class
|
21
|
-
mattr_accessor :square_credentials
|
19
|
+
mattr_accessor :stripe_credentials
|
22
20
|
mattr_accessor :current_account
|
21
|
+
mattr_accessor :oauth_redirect
|
22
|
+
mattr_accessor :refund_application_fee
|
23
|
+
mattr_accessor :order_status_trigger_method
|
23
24
|
|
24
25
|
@@enabled_psps = PSPS
|
25
|
-
@@
|
26
|
-
@@
|
27
|
-
@@
|
28
|
-
@@current_account = 'current_account'
|
26
|
+
@@current_account = :current_account
|
27
|
+
@@oauth_redirect = '/'
|
28
|
+
@@refund_application_fee = false
|
29
29
|
|
30
30
|
def self.setup
|
31
31
|
yield self
|
@@ -35,7 +35,7 @@ module Moneytree
|
|
35
35
|
class Error < StandardError; end
|
36
36
|
end
|
37
37
|
|
38
|
-
# FIXME: See if we need this
|
38
|
+
# FIXME: See if we need this
|
39
39
|
ActiveSupport.on_load(:action_controller) do
|
40
40
|
# include Moneytree::Controller
|
41
41
|
end
|
data/lib/moneytree/account.rb
CHANGED
@@ -1,42 +1,12 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
1
3
|
module Moneytree
|
2
4
|
module Account
|
3
5
|
extend ActiveSupport::Concern
|
6
|
+
# FIXME: see if we can remove config.current_account = :current_merchant and set it from here
|
4
7
|
|
5
8
|
included do
|
6
|
-
|
7
|
-
serialize :psp_credentials
|
8
|
-
# encrypts :psp_credentials
|
9
|
-
# FIXME: enable https://github.com/ankane/lockbox
|
10
|
-
delegate :client, :oauth_link, to: :psp
|
11
|
-
end
|
12
|
-
|
13
|
-
def oauth_callback(params)
|
14
|
-
update! psp_credentials: psp.oauth_callback(params)
|
15
|
-
end
|
16
|
-
|
17
|
-
def psp_connected?
|
18
|
-
false
|
19
|
-
# moneytree_psp && psp_credentials
|
20
|
-
end
|
21
|
-
|
22
|
-
def needs_oauth?
|
23
|
-
true
|
24
|
-
end
|
25
|
-
|
26
|
-
def charge; end
|
27
|
-
|
28
|
-
def refund; end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def psp
|
33
|
-
@psp ||=
|
34
|
-
case moneytree_psp
|
35
|
-
when 'square'
|
36
|
-
Moneytree::PaymentProvider::Square.new(self)
|
37
|
-
else
|
38
|
-
raise 'BOOM'
|
39
|
-
end
|
9
|
+
has_one :moneytree_payment_gateway, class_name: 'Moneytree::PaymentGateway', foreign_key: 'account_id', inverse_of: :account, as: :account
|
40
10
|
end
|
41
11
|
end
|
42
12
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Moneytree
|
4
|
+
module Order
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
has_many :moneytree_transactions, class_name: 'Moneytree::Transaction', foreign_key: 'order_id', inverse_of: :order, as: :order
|
9
|
+
end
|
10
|
+
|
11
|
+
def new_payment(*args)
|
12
|
+
moneytree_transactions << Payment.new(*args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
module Moneytree
|
2
2
|
module PaymentProvider
|
3
3
|
class Base
|
4
|
-
|
5
|
-
|
4
|
+
attr_reader :payment_gateway, :account
|
5
|
+
|
6
|
+
def initialize(payment_gateway)
|
7
|
+
@payment_gateway = payment_gateway
|
8
|
+
@account = @payment_gateway.account
|
6
9
|
end
|
7
10
|
end
|
8
11
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Moneytree
|
2
|
+
module PaymentProvider
|
3
|
+
class Stripe < Base
|
4
|
+
# The permissions we request from Square OAuth, we store them in the database
|
5
|
+
PERMISSION = :read_write
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
raise Error, 'Please set your Stripe credentials' if credentitals.nil?
|
9
|
+
raise Error, 'Please include the stripe gem to your Gemfile' unless Object.const_defined?('::Stripe')
|
10
|
+
|
11
|
+
::Stripe.api_key = credentitals[:api_key]
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_access_token(params)
|
16
|
+
# FIXME: add error handling
|
17
|
+
::Stripe::OAuth.token(
|
18
|
+
{
|
19
|
+
grant_type: 'authorization_code',
|
20
|
+
code: params[:code]
|
21
|
+
}
|
22
|
+
).to_hash
|
23
|
+
end
|
24
|
+
|
25
|
+
def scope
|
26
|
+
PERMISSION.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def charge(amount, details, app_fee_amount: 0, description: "Charge for #{account.name}", metadata:)
|
30
|
+
# `source` is obtained with Stripe.js; see https://stripe.com/docs/payments/accept-a-payment-charges#web-create-token
|
31
|
+
response = ::Stripe::Charge.create(
|
32
|
+
{
|
33
|
+
amount: (amount * 100).to_i,
|
34
|
+
currency: account.currency_code,
|
35
|
+
source: details[:card_token],
|
36
|
+
description: description,
|
37
|
+
metadata: metadata,
|
38
|
+
application_fee_amount: (app_fee_amount * 100).to_i
|
39
|
+
},
|
40
|
+
stripe_account: payment_gateway.psp_credentials[:stripe_user_id]
|
41
|
+
)
|
42
|
+
# succeeded, pending, or failed
|
43
|
+
TransactionResponse.new(
|
44
|
+
{ succeeded: :success, pending: :pending, failed: :failed }[response[:status].to_sym],
|
45
|
+
response[:failure_message],
|
46
|
+
{ charge_id: response[:id] }
|
47
|
+
)
|
48
|
+
rescue ::Stripe::StripeError => e
|
49
|
+
TransactionResponse.new(:failed, e.message)
|
50
|
+
end
|
51
|
+
|
52
|
+
def refund(amount, details, metadata:)
|
53
|
+
response = ::Stripe::Refund.create(
|
54
|
+
{
|
55
|
+
charge: details[:charge_id],
|
56
|
+
amount: (-amount * 100).to_i,
|
57
|
+
metadata: metadata,
|
58
|
+
refund_application_fee: Moneytree.refund_application_fee
|
59
|
+
},
|
60
|
+
stripe_account: payment_gateway.psp_credentials[:stripe_user_id]
|
61
|
+
)
|
62
|
+
|
63
|
+
# succeeded, pending, or failed
|
64
|
+
TransactionResponse.new(
|
65
|
+
{ succeeded: :success, pending: :pending, failed: :failed }[response[:status].to_sym],
|
66
|
+
response[:failure_message],
|
67
|
+
{ refund_id: response[:id] }
|
68
|
+
)
|
69
|
+
rescue ::Stripe::StripeError => e
|
70
|
+
TransactionResponse.new(:failed, e.message)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def credentitals
|
76
|
+
Moneytree.stripe_credentials
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Moneytree
|
2
|
+
class TransactionResponse
|
3
|
+
attr_reader :message, :status, :body
|
4
|
+
|
5
|
+
def initialize(status, message, body = {})
|
6
|
+
@status = status
|
7
|
+
@message = message
|
8
|
+
@body = body
|
9
|
+
end
|
10
|
+
|
11
|
+
def success?
|
12
|
+
@status == :success
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/moneytree/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moneytree-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kieran Klaassen
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
description: A payments engine for rails centered aorund transactional payments and
|
28
42
|
orders.
|
29
43
|
email:
|
@@ -32,44 +46,42 @@ executables: []
|
|
32
46
|
extensions: []
|
33
47
|
extra_rdoc_files: []
|
34
48
|
files:
|
35
|
-
-
|
36
|
-
- ".gitignore"
|
37
|
-
- ".rspec"
|
38
|
-
- ".travis.yml"
|
39
|
-
- CHANGELOG.md
|
40
|
-
- CODE_OF_CONDUCT.md
|
41
|
-
- Gemfile
|
42
|
-
- Gemfile.lock
|
43
|
-
- Guardfile
|
44
|
-
- LICENSE.txt
|
49
|
+
- MIT-LICENSE
|
45
50
|
- README.md
|
46
51
|
- Rakefile
|
47
|
-
- app/
|
48
|
-
-
|
49
|
-
-
|
50
|
-
-
|
51
|
-
-
|
52
|
-
-
|
53
|
-
-
|
54
|
-
-
|
55
|
-
-
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
52
|
+
- app/assets/config/moneytree_manifest.js
|
53
|
+
- app/assets/stylesheets/moneytree/application.css
|
54
|
+
- app/controllers/moneytree/application_controller.rb
|
55
|
+
- app/controllers/moneytree/oauth/square_controller.rb
|
56
|
+
- app/controllers/moneytree/oauth/stripe_controller.rb
|
57
|
+
- app/controllers/moneytree/webhooks/square_controller.rb
|
58
|
+
- app/controllers/moneytree/webhooks/stripe_controller.rb
|
59
|
+
- app/jobs/moneytree/application_job.rb
|
60
|
+
- app/mailers/moneytree/application_mailer.rb
|
61
|
+
- app/models/moneytree/application_record.rb
|
62
|
+
- app/models/moneytree/payment.rb
|
63
|
+
- app/models/moneytree/payment_gateway.rb
|
64
|
+
- app/models/moneytree/refund.rb
|
65
|
+
- app/models/moneytree/transaction.rb
|
66
|
+
- app/views/layouts/moneytree/application.html.erb
|
67
|
+
- config/routes.rb
|
68
|
+
- db/migrate/20200914151648_create_moneytree_payment_gateways.rb
|
69
|
+
- db/migrate/20201008161617_create_moneytree_transactions.rb
|
70
|
+
- lib/moneytree-rails.rb
|
59
71
|
- lib/moneytree.rb
|
60
72
|
- lib/moneytree/account.rb
|
73
|
+
- lib/moneytree/engine.rb
|
74
|
+
- lib/moneytree/order.rb
|
61
75
|
- lib/moneytree/payment_provider/base.rb
|
62
76
|
- lib/moneytree/payment_provider/square.rb
|
63
|
-
- lib/moneytree/
|
77
|
+
- lib/moneytree/payment_provider/stripe.rb
|
78
|
+
- lib/moneytree/transaction_response.rb
|
64
79
|
- lib/moneytree/version.rb
|
65
|
-
-
|
80
|
+
- lib/tasks/moneytree_tasks.rake
|
66
81
|
homepage: https://github.com/kieranklaassen/moneytree
|
67
82
|
licenses:
|
68
83
|
- MIT
|
69
|
-
metadata:
|
70
|
-
homepage_uri: https://github.com/kieranklaassen/moneytree
|
71
|
-
source_code_uri: https://github.com/kieranklaassen/moneytree
|
72
|
-
changelog_uri: https://github.com/kieranklaassen/moneytree/blob/master/CHANGELOG.md
|
84
|
+
metadata: {}
|
73
85
|
post_install_message:
|
74
86
|
rdoc_options: []
|
75
87
|
require_paths:
|
@@ -78,14 +90,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
90
|
requirements:
|
79
91
|
- - ">="
|
80
92
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
93
|
+
version: '0'
|
82
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
95
|
requirements:
|
84
96
|
- - ">="
|
85
97
|
- !ruby/object:Gem::Version
|
86
98
|
version: '0'
|
87
99
|
requirements: []
|
88
|
-
rubygems_version: 3.1.
|
100
|
+
rubygems_version: 3.1.4
|
89
101
|
signing_key:
|
90
102
|
specification_version: 4
|
91
103
|
summary: A payments engine for rails centered aorund transactional payments and orders.
|