pr-pin 0.1.0

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: 351423e96e140be0cfc71d237c63843bb817c7c18412b61cef905dca087a6c81
4
+ data.tar.gz: 3dd044b2514e87abc637f079800422d553a393e491b0b7455270e723259f6869
5
+ SHA512:
6
+ metadata.gz: e959f6b6d6d2999789fec7333556dea26f4ee37e90177e00c003804bcc88b21e771b408703468e4a692d4cf38281418181070574aeda4b3b649a719e5d2e0292
7
+ data.tar.gz: b49f72a07fe9bcd745f427ea44883c349b931f9bd8c5d155361ce6234e59ae73fedd4363a71e757c361d27169c5655335c77b4a7c50e1e90507e28ebddf0bef5
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 AMHOL
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # PR::Pin
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'pr-pin'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install pr-pin
18
+
19
+ ## Usage
20
+
21
+ ```ruby
22
+ # Require the gem
23
+ require 'pr-pin'
24
+
25
+ # Connect using your Pin Payments secret key
26
+ PR::Pin.connect(
27
+ secret_key: 'your_secret_key',
28
+ sandbox: true # Defaults to true, false for production
29
+ )
30
+
31
+ # Create a charge using a token, you can get a card token
32
+ # using Pin Payments hosted fields, or by creating a card
33
+ # via the API, this can be used to take a one-off payment
34
+ charge = PR::Pin.charges.create(
35
+ email: 'a.user@petrescue.com.au',
36
+ description: 'A $10 donation',
37
+ amount: 1000,
38
+ ip_address: '127.0.0.1',
39
+ card_token: 'card_58b6c52f131956c4394ba7'
40
+ )
41
+
42
+ charge.success? # => true
43
+ charge.error? # => false
44
+ charge # => #<PR::Pin::Struct::Charge>
45
+
46
+ # For a subscription, create a customer using a card token
47
+ customer = PR::Pin.customers.create(
48
+ email: 'a.user@petrescue.com.au',
49
+ card_token: 'card_58b6c52f131956c4394ba7'
50
+ )
51
+ customer.success? # => true
52
+ customer.error? # => false
53
+ customer # => #<PR::Pin::Struct::Customer>
54
+
55
+ # And then attach a subscription using the plan token from
56
+ # the plans endpoint (you may need to create the plan first)
57
+ subscription = PR::Pin.subscriptions.create(
58
+ plan_token: 'plan_2d16b31863015a57820b70',
59
+ customer_token: 'cus_9d18a4516a6ae777-NDecB'
60
+ )
61
+ subscription.success? # => true
62
+ subscription.error? # => false
63
+ subscription # => #<PR::Pin::Struct::Subscription>
64
+ ```
65
+
66
+ ## API Coverage
67
+
68
+ Coverage of https://pinpayments.com/developers/api-reference
69
+
70
+ | Relation | Endpoint | Description | Docs | Implemented |
71
+ |--|--|--|--|--|
72
+ | Balance | GET /balance | Returns the current balance of your Pin Payments account | [:link:](https://pinpayments.com/developers/api-reference/balance) | :x: |
73
+ | Bank Accounts | POST /bank_accounts | Creates a bank account token | [:link:](https://pinpayments.com/developers/api-reference/bank-accounts) | :x: |
74
+ | Cards | POST /cards | Securely stores a card's details | [:link:](https://pinpayments.com/developers/api-reference/cards) | :x: |
75
+ | Charges | POST /charges | Creates a new charge | [:link:](https://pinpayments.com/developers/api-reference/charges#post-charges) | :heavy_check_mark: |
76
+ | Charges | PUT /charges/charge-token/capture | Captures a previously authorised charge | [:link:](https://pinpayments.com/developers/api-reference/charges#put-charges) | :x: |
77
+ | Charges | GET /charges | Returns a paginated list of all charges | [:link:](https://pinpayments.com/developers/api-reference/charges#get-charges) | :heavy_check_mark: |
78
+ | Charges | GET /charges/search | Returns a paginated list of charges matching the search criteria | [:link:](https://pinpayments.com/developers/api-reference/charges#search-charges) | :x: |
79
+ | Charges | GET /charges/charge-token | Returns the details of a charge | [:link:](https://pinpayments.com/developers/api-reference/charges#get-charge) | :x: |
80
+ | Customers | POST /customers | Creates a new customer | [:link:](https://pinpayments.com/developers/api-reference/customers#post-customers) | :heavy_check_mark: |
81
+ | Customers | GET /customers | Returns a paginated list of all customers | [:link:](https://pinpayments.com/developers/api-reference/customers#get-customers) | :heavy_check_mark: |
82
+ | Customers | GET /customers/customer-token | Returns the details of a customer | [:link:](https://pinpayments.com/developers/api-reference/customers#get-customer) | :x: |
83
+ | Customers | PUT /customers/customer-token | Updates the details of a customer | [:link:](https://pinpayments.com/developers/api-reference/customers#put-customer) | :x: |
84
+ | Customers | DELETE /customers/customer-token | Deletes a customer and all of its cards | [:link:](https://pinpayments.com/developers/api-reference/customers#delete-customer) | :x: |
85
+ | Customers | GET /customers/customer-token/charges | Returns a paginated list of a customer's charges | [:link:](https://pinpayments.com/developers/api-reference/customers#get-customers-charges) | :x: |
86
+ | Customers | GET /customers/customer-token/cards | Returns a paginated list of a customer's cards | [:link:](https://pinpayments.com/developers/api-reference/customers#get-customers-cards) | :x: |
87
+ | Customers | POST /customers/customer-token/cards | Creates an additional card for the specified customer | [:link:](https://pinpayments.com/developers/api-reference/customers#post-customers-cards) | :x: |
88
+ | Customers | DELETE /customers/customer-token/cards/card-token | Deletes a customer's non-primary card | [:link:](https://pinpayments.com/developers/api-reference/customers#delete-customers-card) | :x: |
89
+ | Customers | GET /customers/customer-token/subscriptions | Retrieves the specified customer's subscriptions | [:link:](https://pinpayments.com/developers/api-reference/customers#customers-subscriptions) | :x: |
90
+ | Events | GET /events | Returns a paginated list of all events | [:link:](https://pinpayments.com/developers/api-reference/events#get-events) | :x: |
91
+ | Events | GET /events/event-token | Returns the details of the specified event | [:link:](https://pinpayments.com/developers/api-reference/events#get-event) | :x: |
92
+ | Plans | POST /plans | Creates a new plan | [:link:](https://pinpayments.com/developers/api-reference/plans#post-plans) | :heavy_check_mark: |
93
+ | Plans | GET /plans | Returns a paginated list of all plans | [:link:](https://pinpayments.com/developers/api-reference/plans#get-plans) | :heavy_check_mark: |
94
+ | Plans | GET /plans/plan-token | Returns the details of a specified plan | [:link:](https://pinpayments.com/developers/api-reference/plans#get-plan) | :x: |
95
+ | Plans | PUT /plans/plan-token | Update the specified plan | [:link:](https://pinpayments.com/developers/api-reference/plans#put-plan) | :x: |
96
+ | Plans | DELETE /plans/plan-token | Deletes a plan and all of its subscriptions | [:link:](https://pinpayments.com/developers/api-reference/plans#delete-plan) | :x: |
97
+ | Plans | POST /plans/plan-token/subscriptions | Creates a new subscription to the specified plan | [:link:](https://pinpayments.com/developers/api-reference/plans#create-plan-subscription) | :x: |
98
+ | Plans | GET /plans/plan-token/subscriptions | Returns a paginated list of subscriptions for a plan | [:link:](https://pinpayments.com/developers/api-reference/plans#get-plan-subscriptions) | :x: |
99
+ | Subscriptions | POST /subscriptions | Activate a new subscription and returns its details | [:link:](https://pinpayments.com/developers/api-reference/subscriptions#post-subscriptions) | :heavy_check_mark: |
100
+ | Subscriptions | GET /subscriptions | Returns a paginated list of all subscriptions | [:link:](https://pinpayments.com/developers/api-reference/subscriptions#get-subscriptions) | :heavy_check_mark: |
101
+ | Subscriptions | GET /subscriptions/sub-token | Returns the details of the subscription identified by subscription token | [:link:](https://pinpayments.com/developers/api-reference/subscriptions#get-subscription) | :x: |
102
+ | Subscriptions | PUT /subscriptions/sub-token | Updates the card associated with a subscription identified by subscription token | [:link:](https://pinpayments.com/developers/api-reference/subscriptions#update-subscription) | :x: |
103
+ | Subscriptions | DELETE /subscriptions/sub-token | Cancels the subscription identified by subscription token | [:link:](https://pinpayments.com/developers/api-reference/subscriptions#delete-subscription) | :x: |
104
+ | Subscriptions | PUT /subscriptions/sub-token/reactivate | Reactivates the subscription identified by subscription token | [:link:](https://pinpayments.com/developers/api-reference/subscriptions#reactivate-subscription) | :x: |
105
+ | Subscriptions | GET /subscriptions/sub-token/ledger | Fetch the ledger entries relating to a subscription identified by subscription token | [:link:](https://pinpayments.com/developers/api-reference/subscriptions#ledger-subscription) | :x: |
106
+ | Recipients | POST /recipients | Creates a new recipient | [:link:](https://pinpayments.com/developers/api-reference/recipients#post-recipients) | :x: |
107
+ | Recipients | GET /recipients | Returns a paginated list of all recipients | [:link:](https://pinpayments.com/developers/api-reference/recipients#get-recipients) | :x: |
108
+ | Recipients | GET /recipients/recipient-token | Returns the details of a recipient | [:link:](https://pinpayments.com/developers/api-reference/recipients#get-recipient) | :x: |
109
+ | Recipients | PUT /recipients/recipient-token | Updates the details of a recipient | [:link:](https://pinpayments.com/developers/api-reference/recipients#put-recipient) | :x: |
110
+ | Recipients | GET /recipients/recipient-token/transfers | Returns a paginated list of a recipient's transfers | [:link:](https://pinpayments.com/developers/api-reference/recipients#get-recipients-transfers) | :x: |
111
+ | Refunds | GET /refunds | Returns a paginated list of all refunds | [:link:](https://pinpayments.com/developers/api-reference/refunds#get-refunds) | :x: |
112
+ | Refunds | GET /refunds/refund-token | Returns the details of the specified refund | [:link:](https://pinpayments.com/developers/api-reference/refunds#get-refund) | :x: |
113
+ | Refunds | POST /charges/charge-token/refunds | Creates a new refund and returns its details | [:link:](https://pinpayments.com/developers/api-reference/refunds#post-refunds) | :x: |
114
+ | Refunds | GET /charges/charge-token/refunds | Returns a list of all refunds for the specified charge | [:link:](https://pinpayments.com/developers/api-reference/refunds#get-token-refunds) | :x: |
115
+ | Transfers | POST /transfers | Creates a new transfer | [:link:](https://pinpayments.com/developers/api-reference/transfers#post-transfers) | :x: |
116
+ | Transfers | GET /transfers | Returns a paginated list of all transfers | [:link:](https://pinpayments.com/developers/api-reference/transfers#get-transfers) | :x: |
117
+ | Transfers | GET /transfers/search | Returns a paginated list of transfers matching the search criteria | [:link:](https://pinpayments.com/developers/api-reference/transfers#search-transfers) | :x: |
118
+ | Transfers | GET /transfers/transfer-token | Returns the details of the specified transfer | [:link:](https://pinpayments.com/developers/api-reference/transfers#get-transfer) | :x: |
119
+ | Transfers | GET /transfers/transfer-token/line_items | Returns a paginated list of line items associated with the specified transfer | [:link:](https://pinpayments.com/developers/api-reference/transfers#get-transfer-line-items) | :x: |
120
+ | Webhook Endpoints | POST /webhook_endpoints | Creates a new webhook endpoint | [:link:](https://pinpayments.com/developers/api-reference/webhook-endpoints#post-webhook_endpoints) | :x: |
121
+ | Webhook Endpoints | GET /webhook_endpoints | Returns a paginated list of all webhook endpoints | [:link:](https://pinpayments.com/developers/api-reference/webhook-endpoints#get-webhook_endpoints) | :x: |
122
+ | Webhook Endpoints | GET /webhook_endpoints/webhook-endpoint-token | Returns the details of the specified webhook endpoint | [:link:](https://pinpayments.com/developers/api-reference/webhook-endpoints#get-webhook_endpoints-token) | :x: |
123
+ | Webhook Endpoints | DELETE /webhook_endpoints/webhook-endpoint-token | Deletes a webhook endpoint and all of its webhook requests | [:link:](https://pinpayments.com/developers/api-reference/webhook-endpoints#delete-webhook_endpoints) | :x: |
124
+ | Webhooks | GET /webhooks | Returns a paginated list of all webhooks | [:link:](https://pinpayments.com/developers/api-reference/webhooks#get-webhooks) | :x: |
125
+ | Webhooks | GET /webhooks/webhook-token | Returns the details of a webhook | [:link:](https://pinpayments.com/developers/api-reference/webhooks#get-webhook) | :x: |
126
+ | Webhooks | PUT /webhooks/webhook-token/replay | Replays a webhook | [:link:](https://pinpayments.com/developers/api-reference/webhooks#put-webhook-replay) | :x: |
127
+
128
+ ## Development
129
+
130
+ 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.
131
+
132
+ 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).
133
+
134
+ ## Contributing
135
+
136
+ Bug reports and pull requests are welcome on GitHub at https://github.com/PetRescue/pr-pin.
137
+
138
+ ## License
139
+
140
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/lib/pr-pin.rb ADDED
@@ -0,0 +1 @@
1
+ require 'pr/pin'
data/lib/pr/pin.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'dry-container'
2
+ require 'pr/pin/version'
3
+ require 'pr/pin/adapter'
4
+ require 'pr/pin/error'
5
+ require 'pr/pin/repositories'
6
+ require 'pr/pin/types'
7
+
8
+ module PR
9
+ module Pin
10
+ LIVE_URL = 'https://api.pinpayments.com/1'.freeze
11
+ SANDBOX_URL = 'https://test-api.pinpayments.com/1'.freeze
12
+
13
+ extend Dry::Container::Mixin
14
+
15
+ register(:environments, memoize: true) do
16
+ Concurrent::Hash.new
17
+ end
18
+
19
+ register(:default_error_handler) { |error| error }
20
+
21
+ class << self
22
+ def connect(
23
+ identifier = :default,
24
+ secret_key:,
25
+ sandbox: true,
26
+ error_handler: nil
27
+ )
28
+ configuration = ROM::Configuration.new(:pr_pin, {
29
+ uri: sandbox ? SANDBOX_URL : LIVE_URL,
30
+ secret_key: secret_key,
31
+ error_handler: error_handler || resolve(:default_error_handler),
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ 'Accept': 'application/json',
35
+ 'User-Agent': "pr-pin:#{VERSION}"
36
+ }
37
+ })
38
+
39
+ configuration.auto_registration(
40
+ File.expand_path('pin', __dir__),
41
+ namespace: 'PR::Pin'
42
+ )
43
+
44
+ environments[identifier] = ROM.container(configuration)
45
+ end
46
+
47
+ def environments
48
+ resolve(:environments)
49
+ end
50
+
51
+ def charges(identifier = :default)
52
+ Repositories::Charges.new(environments[identifier])
53
+ end
54
+
55
+ def customers(identifier = :default)
56
+ Repositories::Customers.new(environments[identifier])
57
+ end
58
+
59
+ def plans(identifier = :default)
60
+ Repositories::Plans.new(environments[identifier])
61
+ end
62
+
63
+ def subscriptions(identifier = :default)
64
+ Repositories::Subscriptions.new(environments[identifier])
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,15 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'rom-http'
4
+ require 'pr/pin/inflector'
5
+ require 'pr/pin/adapter/errors'
6
+ require 'pr/pin/adapter/paginated_response'
7
+ require 'pr/pin/adapter/response'
8
+ require 'pr/pin/adapter/handlers/json_request'
9
+ require 'pr/pin/adapter/handlers/json_response'
10
+ require 'pr/pin/adapter/gateway'
11
+ require 'pr/pin/adapter/dataset'
12
+ require 'pr/pin/adapter/relation'
13
+ require 'pr/pin/adapter/commands'
14
+
15
+ ROM.register_adapter(:pr_pin, PR::Pin::Adapter)
@@ -0,0 +1,27 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ module Commands
5
+ class Create < ROM::HTTP::Commands::Create
6
+ adapter :pr_pin
7
+
8
+ def execute(*args, &block)
9
+ relation.new(super.map(&:to_h)).to_a
10
+ end
11
+ end
12
+
13
+ class Update < ROM::HTTP::Commands::Update
14
+ adapter :pr_pin
15
+
16
+ def execute(*args, &block)
17
+ relation.new(super.map(&:to_h)).to_a
18
+ end
19
+ end
20
+
21
+ class Delete < ROM::HTTP::Commands::Delete
22
+ adapter :pr_pin
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ class Dataset < ROM::HTTP::Dataset
5
+ config.default_request_handler = Handlers::JSONRequest
6
+ config.default_response_handler = Handlers::JSONResponse
7
+
8
+ option :secret_key, type: ROM::Types::Strict::String
9
+ option :error_handler
10
+
11
+ def materialize
12
+ response
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ Error = Class.new(StandardError)
5
+ NoPaginationError = Class.new(Error)
6
+
7
+ class ResponseError < Error
8
+ attr_reader :response, :result
9
+
10
+ def initialize(response, result)
11
+ @response = response
12
+ @result = result
13
+
14
+ super(result[:error_description])
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ class Gateway < ROM::HTTP::Gateway
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,46 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ class Handlers
5
+ class JSONRequest
6
+ class << self
7
+ def client(host, port)
8
+ clients["#{host}:#{port}"] ||= Net::HTTP.new(
9
+ host,
10
+ port
11
+ ).tap do |client|
12
+ client.use_ssl = true
13
+ client.verify_mode = OpenSSL::SSL::VERIFY_PEER
14
+ end
15
+ end
16
+
17
+ def call(dataset)
18
+ uri = dataset.uri
19
+
20
+ request_class = Net::HTTP.const_get(
21
+ PR::Pin::Inflector.classify(dataset.request_method)
22
+ )
23
+
24
+ request = request_class.new(uri.request_uri)
25
+ request.basic_auth(dataset.secret_key, '')
26
+
27
+ dataset.headers.each_with_object(request) do |(header, value), request|
28
+ request[header.to_s] = value
29
+ end
30
+
31
+ request.body = dataset.params.to_json if dataset.params.any?
32
+
33
+ client(uri.host, uri.port).request(request)
34
+ end
35
+
36
+ private
37
+
38
+ def clients
39
+ @clients ||= Concurrent::Hash.new
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,35 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ class Handlers
5
+ class JSONResponse
6
+ SUCCESS_CODES = %w(200 201).freeze
7
+
8
+ def self.call(response, dataset)
9
+ result = JSON.parse(
10
+ response.body,
11
+ symbolize_names: true
12
+ )
13
+ pagination_result = result.fetch(:pagination, false)
14
+
15
+ if SUCCESS_CODES.include?(response.code)
16
+ if %i(post put patch).include?(dataset.request_method)
17
+ response = result[:response]
18
+ else
19
+ response = Array([result[:response]]).flatten(1)
20
+ end
21
+
22
+ if pagination_result
23
+ PaginatedResponse.new(response, pagination_result)
24
+ else
25
+ Response.new(response)
26
+ end
27
+ else
28
+ raise(ResponseError.new(response, result))
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,46 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ class PaginatedResponse < SimpleDelegator
5
+ attr_reader :pagination_params
6
+
7
+ def initialize(dataset, pagination_params = {})
8
+ super(dataset)
9
+ @pagination_params = pagination_params
10
+ end
11
+
12
+ def paginates?
13
+ true
14
+ end
15
+
16
+ def current_page
17
+ pagination_params[:current]
18
+ end
19
+
20
+ def per_page
21
+ pagination_params[:per_page]
22
+ end
23
+
24
+ def next_page
25
+ current_page.next if current_page && current_page < total_pages
26
+ end
27
+
28
+ def prev_page
29
+ current_page.pred if current_page && current_page > 1
30
+ end
31
+
32
+ def total_pages
33
+ (total_count / per_page.to_f).ceil if total_count && per_page
34
+ end
35
+
36
+ def total_count
37
+ pagination_params[:count]
38
+ end
39
+
40
+ def class
41
+ __getobj__.class
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,27 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ class Relation < ROM::HTTP::Relation
5
+ adapter :pr_pin
6
+
7
+ def paginate
8
+ materialized = dataset.materialize
9
+
10
+ raise(
11
+ NoPaginationError,
12
+ dataset.uri
13
+ ) unless materialized.paginates?
14
+
15
+ PaginatedResponse.new(
16
+ new(materialized).to_a,
17
+ materialized.pagination_params
18
+ )
19
+ end
20
+
21
+ def input_schema
22
+ ROM::Command.input
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module PR
2
+ module Pin
3
+ module Adapter
4
+ class Response < SimpleDelegator
5
+ def paginates?
6
+ false
7
+ end
8
+
9
+ def class
10
+ __getobj__.class
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,48 @@
1
+ module PR
2
+ module Pin
3
+ module API
4
+ class Error < PR::Pin::Error
5
+ attr_reader :response, :result
6
+
7
+ def initialize(error)
8
+ @response = error.response
9
+ @result = error.result
10
+
11
+ super(error.message)
12
+ end
13
+
14
+ def response_code
15
+ response.code
16
+ end
17
+
18
+ def to_h
19
+ result
20
+ end
21
+
22
+ def code
23
+ result[:error]
24
+ end
25
+
26
+ def description
27
+ result[:error_description]
28
+ end
29
+
30
+ def messages
31
+ result.fetch(:messages, [])
32
+ end
33
+
34
+ def success?
35
+ false
36
+ end
37
+
38
+ def error?
39
+ true
40
+ end
41
+
42
+ def inspect
43
+ "#<#{self.class} - Status: `#{response_code}', Code: `#{code}', Message: `#{description}'>"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ module PR
2
+ module Pin
3
+ module API
4
+ class Result < SimpleDelegator
5
+ def self.wrap(relation, &block)
6
+ new(block.call)
7
+ rescue PR::Pin::Adapter::ResponseError => error
8
+ relation.dataset.error_handler.(Error.new(error))
9
+ end
10
+
11
+ def success?
12
+ true
13
+ end
14
+
15
+ def error?
16
+ false
17
+ end
18
+
19
+ def inspect
20
+ "#<#{self.class} - #{__getobj__}>"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module PR
2
+ module Pin
3
+ Error = Class.new(StandardError)
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'dry-inflector'
2
+
3
+ module PR
4
+ module Pin
5
+ Inflector = Dry::Inflector.new
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ module PR
2
+ module Pin
3
+ module Relations
4
+ class Charges < ROM::Relation[:pr_pin]
5
+ schema(:charges) do
6
+ attribute :token, PR::Pin::Types::Strict::String
7
+ attribute :success, Types::Strict::Bool
8
+ attribute :amount, Types::Strict::Integer
9
+ attribute :currency, Types::Strict::String
10
+ attribute :description, Types::Strict::String
11
+ attribute :email, Types::Strict::String
12
+ attribute :ip_address, Types::Strict::String
13
+ attribute :created_at, Types::JSON::DateTime
14
+ attribute :status_message, Types::Strict::String
15
+ attribute :error_message, Types::Strict::String.optional
16
+ attribute :card, Types::JSON::Hash
17
+ attribute :transfer, Types::Array.of(Types::JSON::Hash)
18
+ attribute :amount_refunded, Types::Strict::Integer
19
+ attribute :total_fees, Types::Strict::Integer
20
+ attribute :merchant_entitlement, Types::Strict::Integer
21
+ attribute :refund_pending, Types::Strict::Bool
22
+ attribute :authorisation_expired, Types::Strict::Bool
23
+ attribute :captured, Types::Strict::Bool
24
+ attribute :captured_at, Types::JSON::DateTime
25
+ attribute :settlement_currency, Types::Strict::String
26
+ attribute :metadata, Types::JSON::Hash
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ module PR
2
+ module Pin
3
+ module Relations
4
+ class Customers < ROM::Relation[:pr_pin]
5
+ schema(:customers) do
6
+ attribute :token, Types::Strict::String
7
+ attribute :email, Types::Strict::String
8
+ attribute :created_at, Types::JSON::DateTime
9
+ attribute :card, Types::JSON::Hash
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ module PR
2
+ module Pin
3
+ module Relations
4
+ class Plans < ROM::Relation[:pr_pin]
5
+ schema(:plans) do
6
+ attribute :name, Types::Strict::String
7
+ attribute :amount, Types::Strict::Integer
8
+ attribute :currency, Types::Strict::String
9
+ attribute :setup_amount, Types::Strict::Integer
10
+ attribute :trial_amount, Types::Strict::Integer
11
+ attribute :interval, Types::Strict::Integer
12
+ attribute :interval_unit, Types::Strict::String
13
+ attribute :intervals, Types::Strict::Integer
14
+ attribute :trial_interval, Types::Strict::Integer
15
+ attribute :trial_interval_unit, Types::Strict::String
16
+ attribute :created_at, Types::JSON::DateTime
17
+ attribute :token, Types::Strict::String
18
+ attribute :customer_permissions, Types::JSON::Array.of(
19
+ Types::Strict::String
20
+ )
21
+ attribute :subscription_counts, Types::JSON::Hash
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ module PR
2
+ module Pin
3
+ module Relations
4
+ class Subscriptions < ROM::Relation[:pr_pin]
5
+ schema(:subscriptions) do
6
+ attribute :state, Types::Strict::String
7
+ attribute :next_billing_date, Types::JSON::DateTime
8
+ attribute :active_interval_started_at, Types::JSON::DateTime
9
+ attribute :active_interval_finishes_at, Types::JSON::DateTime.optional
10
+ attribute :cancelled_at, Types::JSON::DateTime.optional
11
+ attribute :created_at, Types::JSON::DateTime
12
+ attribute :token, Types::Strict::String
13
+ attribute :plan_token, Types::Strict::String
14
+ attribute :customer_token, Types::Strict::String.optional
15
+ attribute :card_token, Types::Strict::String.optional
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ require 'rom-repository'
2
+ require 'pr/pin/api/error'
3
+ require 'pr/pin/api/result'
4
+ require 'pr/pin/struct'
5
+ require 'pr/pin/repositories/concerns/common'
6
+ require 'pr/pin/repositories/charges'
7
+ require 'pr/pin/repositories/customers'
8
+ require 'pr/pin/repositories/plans'
9
+ require 'pr/pin/repositories/subscriptions'
@@ -0,0 +1,9 @@
1
+ module PR
2
+ module Pin
3
+ module Repositories
4
+ class Charges < ROM::Repository[:charges]
5
+ include Concerns::Common
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ module PR
2
+ module Pin
3
+ module Repositories
4
+ module Concerns
5
+ module Common
6
+ def self.included(mod)
7
+ mod.struct_namespace(PR::Pin::Struct)
8
+ end
9
+
10
+ def create(*args)
11
+ API::Result.wrap(root) do
12
+ root.command(:create).call(*args)
13
+ end
14
+ end
15
+
16
+ def list(page: 1, per_page: nil)
17
+ API::Result.wrap(root) do
18
+ root.with_params(
19
+ page: page,
20
+ per_page: per_page
21
+ ).paginate
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ module PR
2
+ module Pin
3
+ module Repositories
4
+ class Customers < ROM::Repository[:customers]
5
+ include Concerns::Common
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module PR
2
+ module Pin
3
+ module Repositories
4
+ class Plans < ROM::Repository[:plans]
5
+ include Concerns::Common
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module PR
2
+ module Pin
3
+ module Repositories
4
+ class Subscriptions < ROM::Repository[:subscriptions]
5
+ include Concerns::Common
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module PR
2
+ module Pin
3
+ module Struct
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ require 'dry-types'
2
+
3
+ module PR
4
+ module Pin
5
+ module Types
6
+ include ROM::HTTP::Types
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module PR
2
+ module Pin
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,217 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pr-pin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - AMHOL
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-11-18 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: '1.17'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.17'
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
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dry-container
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: dry-inflector
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: dry-types
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rom
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 5.1.2
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 5.1.2
139
+ - !ruby/object:Gem::Dependency
140
+ name: rom-http
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: 0.8.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 0.8.0
153
+ description: Pin Payments API wrapper inplemented using rom-rb HTTP adapter.
154
+ email:
155
+ - andyholland1991@aol.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - LICENSE
161
+ - README.md
162
+ - lib/pr-pin.rb
163
+ - lib/pr/pin.rb
164
+ - lib/pr/pin/adapter.rb
165
+ - lib/pr/pin/adapter/commands.rb
166
+ - lib/pr/pin/adapter/dataset.rb
167
+ - lib/pr/pin/adapter/errors.rb
168
+ - lib/pr/pin/adapter/gateway.rb
169
+ - lib/pr/pin/adapter/handlers/json_request.rb
170
+ - lib/pr/pin/adapter/handlers/json_response.rb
171
+ - lib/pr/pin/adapter/paginated_response.rb
172
+ - lib/pr/pin/adapter/relation.rb
173
+ - lib/pr/pin/adapter/response.rb
174
+ - lib/pr/pin/api/error.rb
175
+ - lib/pr/pin/api/result.rb
176
+ - lib/pr/pin/error.rb
177
+ - lib/pr/pin/inflector.rb
178
+ - lib/pr/pin/relations/charges.rb
179
+ - lib/pr/pin/relations/customers.rb
180
+ - lib/pr/pin/relations/plans.rb
181
+ - lib/pr/pin/relations/subscriptions.rb
182
+ - lib/pr/pin/repositories.rb
183
+ - lib/pr/pin/repositories/charges.rb
184
+ - lib/pr/pin/repositories/concerns/common.rb
185
+ - lib/pr/pin/repositories/customers.rb
186
+ - lib/pr/pin/repositories/plans.rb
187
+ - lib/pr/pin/repositories/subscriptions.rb
188
+ - lib/pr/pin/struct.rb
189
+ - lib/pr/pin/types.rb
190
+ - lib/pr/pin/version.rb
191
+ homepage: https://github.com/PetRescue/pr-pin
192
+ licenses:
193
+ - MIT
194
+ metadata:
195
+ homepage_uri: https://github.com/PetRescue/pr-pin
196
+ source_code_uri: https://github.com/PetRescue/pr-pin
197
+ bug_tracker_uri: https://github.com/PetRescue/pr-pin/issues
198
+ post_install_message:
199
+ rdoc_options: []
200
+ require_paths:
201
+ - lib
202
+ required_ruby_version: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
207
+ required_rubygems_version: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ version: '0'
212
+ requirements: []
213
+ rubygems_version: 3.0.3
214
+ signing_key:
215
+ specification_version: 4
216
+ summary: Pin Payments API wrapper inplemented using rom-rb HTTP adapter.
217
+ test_files: []