pr-pin 0.1.0
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +140 -0
- data/lib/pr-pin.rb +1 -0
- data/lib/pr/pin.rb +68 -0
- data/lib/pr/pin/adapter.rb +15 -0
- data/lib/pr/pin/adapter/commands.rb +27 -0
- data/lib/pr/pin/adapter/dataset.rb +17 -0
- data/lib/pr/pin/adapter/errors.rb +19 -0
- data/lib/pr/pin/adapter/gateway.rb +8 -0
- data/lib/pr/pin/adapter/handlers/json_request.rb +46 -0
- data/lib/pr/pin/adapter/handlers/json_response.rb +35 -0
- data/lib/pr/pin/adapter/paginated_response.rb +46 -0
- data/lib/pr/pin/adapter/relation.rb +27 -0
- data/lib/pr/pin/adapter/response.rb +15 -0
- data/lib/pr/pin/api/error.rb +48 -0
- data/lib/pr/pin/api/result.rb +25 -0
- data/lib/pr/pin/error.rb +5 -0
- data/lib/pr/pin/inflector.rb +7 -0
- data/lib/pr/pin/relations/charges.rb +31 -0
- data/lib/pr/pin/relations/customers.rb +14 -0
- data/lib/pr/pin/relations/plans.rb +26 -0
- data/lib/pr/pin/relations/subscriptions.rb +20 -0
- data/lib/pr/pin/repositories.rb +9 -0
- data/lib/pr/pin/repositories/charges.rb +9 -0
- data/lib/pr/pin/repositories/concerns/common.rb +28 -0
- data/lib/pr/pin/repositories/customers.rb +9 -0
- data/lib/pr/pin/repositories/plans.rb +9 -0
- data/lib/pr/pin/repositories/subscriptions.rb +9 -0
- data/lib/pr/pin/struct.rb +6 -0
- data/lib/pr/pin/types.rb +9 -0
- data/lib/pr/pin/version.rb +5 -0
- metadata +217 -0
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,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,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
|
data/lib/pr/pin/error.rb
ADDED
@@ -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,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
|
data/lib/pr/pin/types.rb
ADDED
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: []
|