compensated 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8ef6a5718683783e493fdad36e304f857635c301b12c12bd6ac790259bb39756
4
+ data.tar.gz: 79de21133b8dc3fc4704b70b98264c6301ab8bb48d113201f0292a4456c8d1be
5
+ SHA512:
6
+ metadata.gz: e2180e9ef30642ff344db949945aeed11aebba04a5a9e45659b7b80c450a873c55586eabfbef5cec8ac6afe71975b7aa4866edf348c96bee25dc6cb992f7b18a
7
+ data.tar.gz: 5038cb753bc272195f7354fff615c60961ee707f375d5f846a38cf213deac6c2bf082c794c287dcda620a92d06ca68972f6e2bf9cd2d1682996bd92fe38667e7
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in compensated-ruby.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ compensated (0.1.0.pre1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (10.5.0)
11
+ rspec (3.8.0)
12
+ rspec-core (~> 3.8.0)
13
+ rspec-expectations (~> 3.8.0)
14
+ rspec-mocks (~> 3.8.0)
15
+ rspec-core (3.8.2)
16
+ rspec-support (~> 3.8.0)
17
+ rspec-expectations (3.8.4)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.8.0)
20
+ rspec-mocks (3.8.1)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.8.0)
23
+ rspec-support (3.8.2)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 2.0)
30
+ compensated!
31
+ rake (~> 10.0)
32
+ rspec (~> 3.0)
33
+
34
+ BUNDLED WITH
35
+ 2.0.2
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Compensated
2
+
3
+ Compensated makes it easy to adjust your customer experience based upon whether or not someone has paaaaiiiiiiiid.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'compensated'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install compensated
20
+
21
+ ## Usage
22
+
23
+ Right now, we do not provide a Rack plugin or Rails engine for use with Compensated; this is because we don't really know what the best interface is. Part of our goal for 1.0 is a very boring set of defaults, but we don't want to codify that yet.
24
+
25
+
26
+ ### Rails Example
27
+ ```rb
28
+ class PaymentProcessorEventsController < ApplicationController
29
+ def create
30
+ # We provide a basic request handler that normalizes the payment processor event data
31
+ # for your convenience.
32
+ handler = Compensated::PaymentProcessorEventRequestHandler.new(request)
33
+
34
+
35
+ # If you use ActiveRecord, we provide a model for persisting the
36
+ # events in your database.
37
+
38
+ # We strongly encourage keeping payment processor events around
39
+ # for conflict reconciliation, fraud detection, etc.
40
+ event = Compensated::PaymentProcessorEvent.create(handler.normalized_event_data)
41
+ if event.persisted?
42
+ head :ok
43
+ else
44
+ # Some payment processors will retry sending of the event
45
+ # if you tell them things didn't work out right.
46
+
47
+ # We encourage you to return a 5XX status code to trigger
48
+ # the retry behavior.
49
+ head :internal_server_error
50
+ end
51
+ end
52
+ end
53
+ ```
54
+
55
+
56
+ ## Development
57
+
58
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
59
+
60
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
61
+
62
+ ## Contributing
63
+
64
+ Bug reports and pull requests are welcome on GitHub at https://github.com/zinc-technology/compensated. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
65
+
66
+ ## Code of Conduct
67
+
68
+ Everyone interacting in the Compensated project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/zinc-technology/compensated/blob/primary/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "compensated"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/bin/rspec ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rspec-core", "rspec")
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,40 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "compensated/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "compensated"
7
+ spec.version = Compensated::VERSION
8
+ spec.authors = ["Zee"]
9
+ spec.email = ["zee@zincma.de"]
10
+
11
+ spec.summary = "Provide value (In Ruby!). Get paid."
12
+ spec.description = "Compensated makes handling transactions slightly less of a nightmare."
13
+ spec.homepage = "https://github.com/zinc-technology/compensated"
14
+
15
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
16
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
17
+ if spec.respond_to?(:metadata)
18
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
19
+
20
+ spec.metadata["homepage_uri"] = spec.homepage
21
+ spec.metadata["source_code_uri"] = "https://github.com/zinc-technology/compensated"
22
+ spec.metadata["changelog_uri"] = "https://github.com/zinc-technology/compensated/primary/CHANGELOG.md"
23
+ else
24
+ raise "RubyGems 2.0 or newer is required to protect against " \
25
+ "public gem pushes."
26
+ end
27
+
28
+ # Specify which files should be added to the gem when it is released.
29
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
+ spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
32
+ end
33
+ spec.bindir = "exe"
34
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
+ spec.require_paths = ["lib"]
36
+
37
+ spec.add_development_dependency "bundler", "~> 2.0"
38
+ spec.add_development_dependency "rake", "~> 10.0"
39
+ spec.add_development_dependency "rspec", "~> 3.0"
40
+ end
@@ -0,0 +1,36 @@
1
+ source "https://rubygems.org"
2
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
+
4
+ ruby "2.6.3"
5
+
6
+ # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
7
+ gem "rails", "~> 5.2.3"
8
+ # Use sqlite3 as the database for Active Record
9
+ gem "sqlite3"
10
+
11
+ # Core compensated library
12
+ gem "compensated", "../compensated-ruby"
13
+
14
+ # Plugin to provide stripe integration for compensated
15
+ gem "compensated-stripe", "../compensated-ruby-stripe"
16
+
17
+ # Plugin to provide gumroad integration for compensated
18
+ gem "compensated-gumroad", "../compensated-ruby-gumroad"
19
+ # Use Puma as the app server
20
+ gem "puma", "~> 3.11"
21
+ # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
22
+ gem "jbuilder", "~> 2.5"
23
+
24
+ group :development, :test do
25
+ # Call 'byebug' anywhere in the code to stop execution and get a debugger console
26
+ gem "byebug", platforms: [:mri, :mingw, :x64_mingw]
27
+ end
28
+
29
+ group :development do
30
+ # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
31
+ gem "web-console", ">= 3.3.0"
32
+ gem "listen", ">= 3.0.5", "< 3.2"
33
+ end
34
+
35
+ # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
36
+ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
@@ -0,0 +1,34 @@
1
+ module Compensated
2
+ # Normalizes events by passing them to an EventParser
3
+ # Which transforms them into a hash that can be
4
+ # persisted to a database.
5
+ class PaymentProcessorEventRequestHandler
6
+ attr_accessor :event_request
7
+ # @param event_request [Request] A rack-compatible HTTP request triggered
8
+ # by the payment processor
9
+ def initialize(event_request)
10
+ self.event_request = event_request
11
+ end
12
+
13
+ # @return Hash
14
+ def normalized_event_data
15
+ event_parser.parse(event_request_body_data)
16
+ end
17
+
18
+ protected def event_parser
19
+ return @event_parser unless @event_parser.nil?
20
+ @event_parser = Compensated.event_parsers.find { |parser| parser.parses?(event_request_body_data) }
21
+ raise NoParserForEventError, event_request_body_data if @event_parser.nil?
22
+ @event_parser
23
+ end
24
+
25
+ protected def event_request_body_data
26
+ @event_request_body_data ||= Compensated.json_adapter.parse(event_request_body)
27
+ end
28
+
29
+ protected def event_request_body
30
+ return @event_request_body unless @event_request_body.nil?
31
+ @event_request_body = event_request.body
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ module Compensated
2
+ module Stripe
3
+ SUPPORTED_EVENTS = %w[charge.succeeded invoice.payment_succeeded]
4
+ class EventParser
5
+ def parses?(input_event)
6
+ return false if input_event.nil? || !input_event.respond_to?(:key)
7
+ SUPPORTED_EVENTS.include?(input_event[:type])
8
+ end
9
+
10
+ def parse(input_event)
11
+ {
12
+ raw_body: Compensated.json_adapter.dump(input_event),
13
+ raw_event_type: input_event[:type].to_sym,
14
+ raw_event_id: input_event[:id],
15
+ payment_processor: :stripe,
16
+ }
17
+ end
18
+ end
19
+ end
20
+
21
+ # Ensure Compensated is aware that the stripe event parser is available.
22
+ event_parsers.push(Stripe::EventParser.new)
23
+ end
@@ -0,0 +1,5 @@
1
+ module Compensated
2
+ module Stripe
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require_relative "stripe/version"
2
+ require_relative "stripe/event_parser"
3
+
4
+ module Compensated
5
+ module Stripe
6
+ class Error < Compensated::Error; end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module Compensated
2
+ VERSION = "0.1.0.pre1"
3
+ end
@@ -0,0 +1,70 @@
1
+ require_relative "compensated/version"
2
+ require_relative "compensated/payment_processor_event_request_handler"
3
+
4
+ module Compensated
5
+ class Error < StandardError; end
6
+ class NoParserForEventError < Error; end
7
+
8
+ # Collection of parsers useful in the application
9
+ # Plugins like compensated-stripe, compensated-iap-android,
10
+ # compensated-iap-apple, and compensated-gumroad.
11
+ def self.event_parsers
12
+ @event_parsers ||= []
13
+ end
14
+
15
+ # A singletonesque JSON parser for use in plugins that need to interact
16
+ # with JSON from IO streams.
17
+ def self.json_adapter
18
+ @json_adapter ||= RewindingJSONAdapter.new
19
+ end
20
+
21
+ # Provides an affordance for overriding the built in
22
+ # rewinding JSON parser/dumper in favor of one that's more appropriate for
23
+ # your use case
24
+ def self.json_adapter=(json_adapter)
25
+ @json_adapter = json_adapter
26
+ end
27
+
28
+ # By default, we use the JSON standard library provided by Ruby.
29
+ # In cases where the default JSON parser is unacceptable, configure
30
+ # the json engine using `Compensated.json_engine = <Your preferred JSON parser>`
31
+ def self.json_engine
32
+ require "json" unless @json_engine
33
+ @json_engine ||= JSON
34
+ end
35
+
36
+ def self.json_engine=json_engine
37
+ @json_engine = json_engine
38
+ end
39
+
40
+ # Wraps the built in JSON library to support IO streams that may
41
+ # have been read from already, and ensures provided sources are
42
+ # rewound for later consumption
43
+ class RewindingJSONAdapter
44
+ def parse(io_source)
45
+ # We rewind the IO stream so that if something else has already
46
+ # read from the stream we get the whole thing
47
+ io_source.rewind if io_source.respond_to?(:rewind)
48
+
49
+ # If the io source responds to read, use the content to parse the json,
50
+ content = io_source.respond_to?(:read) ? io_source.read : io_source
51
+ # We default to symbolizing names so plugins don't need to guess about
52
+ # it.
53
+ object = engine.parse(content, symbolize_names: true)
54
+
55
+ # And we rewind it again when we're done so anyone
56
+ # downstream can use the stream
57
+ io_source.rewind if io_source.respond_to?(:rewind)
58
+ object
59
+ end
60
+
61
+ def dump(object)
62
+ engine.dump(object)
63
+ end
64
+
65
+ # Ensure we use the json engine specified by the consumer
66
+ private def engine
67
+ Compensated.json_engine
68
+ end
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: compensated
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre1
5
+ platform: ruby
6
+ authors:
7
+ - Zee
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-07-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Compensated makes handling transactions slightly less of a nightmare.
56
+ email:
57
+ - zee@zincma.de
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/rake
70
+ - bin/rspec
71
+ - bin/setup
72
+ - compensated.gemspec
73
+ - examples/compensated-rails-5/Gemfile
74
+ - lib/compensated.rb
75
+ - lib/compensated/payment_processor_event_request_handler.rb
76
+ - lib/compensated/stripe.rb
77
+ - lib/compensated/stripe/event_parser.rb
78
+ - lib/compensated/stripe/version.rb
79
+ - lib/compensated/version.rb
80
+ homepage: https://github.com/zinc-technology/compensated
81
+ licenses: []
82
+ metadata:
83
+ homepage_uri: https://github.com/zinc-technology/compensated
84
+ source_code_uri: https://github.com/zinc-technology/compensated
85
+ changelog_uri: https://github.com/zinc-technology/compensated/primary/CHANGELOG.md
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">"
98
+ - !ruby/object:Gem::Version
99
+ version: 1.3.1
100
+ requirements: []
101
+ rubygems_version: 3.0.3
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Provide value (In Ruby!). Get paid.
105
+ test_files: []