straddle_pay 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/CHANGELOG.md +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +229 -0
- data/lib/straddle_pay/client.rb +136 -0
- data/lib/straddle_pay/config.rb +32 -0
- data/lib/straddle_pay/engine.rb +9 -0
- data/lib/straddle_pay/errors.rb +22 -0
- data/lib/straddle_pay/resources/base.rb +28 -0
- data/lib/straddle_pay/resources/bridge.rb +15 -0
- data/lib/straddle_pay/resources/bridge_links.rb +37 -0
- data/lib/straddle_pay/resources/charges.rb +48 -0
- data/lib/straddle_pay/resources/customer_reviews.rb +23 -0
- data/lib/straddle_pay/resources/customers.rb +40 -0
- data/lib/straddle_pay/resources/embed.rb +12 -0
- data/lib/straddle_pay/resources/embed_accounts.rb +43 -0
- data/lib/straddle_pay/resources/embed_linked_bank_accounts.rb +41 -0
- data/lib/straddle_pay/resources/embed_organizations.rb +23 -0
- data/lib/straddle_pay/resources/embed_representatives.rb +38 -0
- data/lib/straddle_pay/resources/funding_events.rb +17 -0
- data/lib/straddle_pay/resources/paykeys.rb +37 -0
- data/lib/straddle_pay/resources/payments.rb +12 -0
- data/lib/straddle_pay/resources/payouts.rb +49 -0
- data/lib/straddle_pay/resources/reports.rb +12 -0
- data/lib/straddle_pay/version.rb +5 -0
- data/lib/straddle_pay.rb +49 -0
- metadata +90 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 23aebc721853de383064f4e317d3f9a6e73705d06f2f4d0e8376873dbf05bace
|
|
4
|
+
data.tar.gz: 1996288b18fc0434b255e7638e8e75b83db350687eeca1dc93cd46f091525ac9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 36203c68e86e4df953735bdcb7b811a7d9db9c7867a8fa10c1ace55663ce894146621983a7d56f5490e8b1dc9cd62be65a27bb314bd4aed467e63215d78e0967
|
|
7
|
+
data.tar.gz: ff082a8507a7146e55ddee23a5286834212d7b97924821ce55f7a6c4c516c9653897b480173d5e363c333d6050504cd13399450972405ff2665d31bfb3ef9b72
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## [0.1.0] - 2026-02-19
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- Initial release
|
|
5
|
+
- Full Straddle API v1 coverage (59 endpoints)
|
|
6
|
+
- Faraday-based HTTP client with configurable timeouts
|
|
7
|
+
- Global config with per-instance overrides
|
|
8
|
+
- Error hierarchy with validation detail accessors
|
|
9
|
+
- Auto-unwrapped response envelope
|
|
10
|
+
- Rails Engine support
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dpaluy
|
|
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,229 @@
|
|
|
1
|
+
# StraddlePay
|
|
2
|
+
|
|
3
|
+
Ruby client for the [Straddle](https://straddle.dev) payment infrastructure API.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/rb/straddle_pay)
|
|
6
|
+
[](https://github.com/dpaluy/straddle_pay/actions/workflows/ci.yml)
|
|
7
|
+
|
|
8
|
+
Lightweight, idiomatic Ruby wrapper using Faraday. No auto-generated code, no type system overhead — just clean Hash responses.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
bundle add straddle_pay
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
Configure once:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
StraddlePay.configure do |config|
|
|
22
|
+
config.api_key = ENV.fetch("STRADDLE_API_KEY")
|
|
23
|
+
config.base_url = StraddlePay::Config::PRODUCTION_URL # default: sandbox
|
|
24
|
+
end
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Per-instance overrides:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
client = StraddlePay::Client.new(
|
|
31
|
+
api_key: "sk_different_key",
|
|
32
|
+
base_url: "https://production.straddle.io"
|
|
33
|
+
)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Environments
|
|
37
|
+
|
|
38
|
+
| Environment | URL |
|
|
39
|
+
|-------------|-----|
|
|
40
|
+
| Sandbox (default) | `https://sandbox.straddle.io` |
|
|
41
|
+
| Production | `https://production.straddle.io` |
|
|
42
|
+
|
|
43
|
+
### Rails
|
|
44
|
+
|
|
45
|
+
Create `config/initializers/straddle_pay.rb`:
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
StraddlePay.configure do |config|
|
|
49
|
+
config.api_key = Rails.application.credentials.straddle_api_key
|
|
50
|
+
config.base_url = StraddlePay::Config::PRODUCTION_URL
|
|
51
|
+
config.logger = Rails.logger
|
|
52
|
+
end
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Charges
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
client = StraddlePay::Client.new
|
|
59
|
+
|
|
60
|
+
charge = client.charges.create(
|
|
61
|
+
paykey: "pk_abc123",
|
|
62
|
+
amount: 10_000,
|
|
63
|
+
currency: "usd",
|
|
64
|
+
description: "Monthly subscription",
|
|
65
|
+
payment_date: "2026-03-01",
|
|
66
|
+
consent_type: "internet",
|
|
67
|
+
device: { ip_address: "192.168.1.1" },
|
|
68
|
+
external_id: "order_456"
|
|
69
|
+
)
|
|
70
|
+
charge["id"] # => "ch_..."
|
|
71
|
+
|
|
72
|
+
client.charges.get("ch_abc123")
|
|
73
|
+
client.charges.update("ch_abc123", amount: 15_000)
|
|
74
|
+
client.charges.cancel("ch_abc123")
|
|
75
|
+
client.charges.hold("ch_abc123")
|
|
76
|
+
client.charges.release("ch_abc123")
|
|
77
|
+
client.charges.unmask("ch_abc123")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Payouts
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
payout = client.payouts.create(
|
|
84
|
+
paykey: "pk_abc123",
|
|
85
|
+
amount: 5_000,
|
|
86
|
+
currency: "usd",
|
|
87
|
+
description: "Vendor payment",
|
|
88
|
+
payment_date: "2026-03-01",
|
|
89
|
+
device: { ip_address: "192.168.1.1" },
|
|
90
|
+
external_id: "payout_789"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Cancel/hold/release require a reason
|
|
94
|
+
client.payouts.cancel("po_abc123", reason: "Duplicate payment")
|
|
95
|
+
client.payouts.hold("po_abc123", reason: "Under review")
|
|
96
|
+
client.payouts.release("po_abc123", reason: "Review complete")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Customers
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
customer = client.customers.create(
|
|
103
|
+
name: "John Doe",
|
|
104
|
+
type: "individual",
|
|
105
|
+
email: "john@example.com",
|
|
106
|
+
phone: "+15551234567",
|
|
107
|
+
device: { ip_address: "192.168.1.1" }
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
customers = client.customers.list(page_number: 1, page_size: 25)
|
|
111
|
+
|
|
112
|
+
# Identity review
|
|
113
|
+
review = client.customers.reviews.get("cust_abc123")
|
|
114
|
+
client.customers.reviews.decision("cust_abc123", status: "approved")
|
|
115
|
+
client.customers.reviews.refresh("cust_abc123")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Bridge (Bank Account Linking)
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
session = client.bridge.initialize_session(customer_id: "cust_abc123")
|
|
122
|
+
|
|
123
|
+
# Direct bank account link
|
|
124
|
+
client.bridge.links.bank_account(
|
|
125
|
+
customer_id: "cust_abc123",
|
|
126
|
+
account_number: "1234567890",
|
|
127
|
+
routing_number: "021000021",
|
|
128
|
+
account_type: "checking"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Or via Plaid/Quiltt
|
|
132
|
+
client.bridge.links.plaid(customer_id: "cust_abc123", plaid_token: "plaid_token")
|
|
133
|
+
client.bridge.links.quiltt(customer_id: "cust_abc123", quiltt_token: "quiltt_token")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Paykeys
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
client.paykeys.get("pk_abc123")
|
|
140
|
+
client.paykeys.list
|
|
141
|
+
client.paykeys.reveal("pk_abc123")
|
|
142
|
+
client.paykeys.cancel("pk_abc123")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Embedded Accounts
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
org = client.embed.organizations.create(name: "Partner Corp")
|
|
149
|
+
|
|
150
|
+
account = client.embed.accounts.create(
|
|
151
|
+
organization_id: org["id"],
|
|
152
|
+
account_type: "standard",
|
|
153
|
+
business_profile: { name: "Partner Corp" },
|
|
154
|
+
access_level: "standard"
|
|
155
|
+
)
|
|
156
|
+
client.embed.accounts.onboard(account["id"], terms_of_service: { accepted: true })
|
|
157
|
+
|
|
158
|
+
client.embed.representatives.create(
|
|
159
|
+
account_id: account["id"],
|
|
160
|
+
first_name: "Jane", last_name: "Smith",
|
|
161
|
+
email: "jane@partner.com", dob: "1985-06-15",
|
|
162
|
+
mobile_number: "+15559876543", relationship: "owner", ssn_last4: "4321"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
client.embed.linked_bank_accounts.create(
|
|
166
|
+
account_id: account["id"],
|
|
167
|
+
bank_account: { account_number: "9876543210", routing_number: "021000021" },
|
|
168
|
+
description: "Operating account"
|
|
169
|
+
)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Scoped Requests
|
|
173
|
+
|
|
174
|
+
Pass `straddle_account_id` to scope requests to an embedded account:
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
client.charges.create(
|
|
178
|
+
paykey: "pk_abc",
|
|
179
|
+
amount: 10_000,
|
|
180
|
+
currency: "usd",
|
|
181
|
+
description: "Scoped charge",
|
|
182
|
+
payment_date: "2026-03-01",
|
|
183
|
+
consent_type: "internet",
|
|
184
|
+
device: { ip_address: "1.2.3.4" },
|
|
185
|
+
external_id: "ext_1",
|
|
186
|
+
straddle_account_id: "acct_partner123"
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Headers `request_id`, `correlation_id`, and `idempotency_key` are also supported on all methods.
|
|
191
|
+
|
|
192
|
+
## Error Handling
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
begin
|
|
196
|
+
client.charges.create(...)
|
|
197
|
+
rescue StraddlePay::AuthenticationError => e
|
|
198
|
+
# 401 or 403
|
|
199
|
+
rescue StraddlePay::ClientError => e
|
|
200
|
+
# 400, 404, 409, 422
|
|
201
|
+
e.error_type # => "validation_error"
|
|
202
|
+
e.error_items # => [{"reference" => "email", "detail" => "is invalid"}]
|
|
203
|
+
rescue StraddlePay::RateLimitError
|
|
204
|
+
# 429 - retry with backoff
|
|
205
|
+
rescue StraddlePay::ServerError
|
|
206
|
+
# 500+
|
|
207
|
+
rescue StraddlePay::NetworkError
|
|
208
|
+
# Timeout or connection failure
|
|
209
|
+
end
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### API Reference
|
|
213
|
+
|
|
214
|
+
Full endpoint details: [straddle.dev/api-reference](https://straddle.dev/api-reference)
|
|
215
|
+
|
|
216
|
+
## Development
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
bundle exec rake test
|
|
220
|
+
bundle exec rubocop
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Contributing
|
|
224
|
+
|
|
225
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/dpaluy/straddle_pay.
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "faraday"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module StraddlePay
|
|
7
|
+
class Client
|
|
8
|
+
attr_reader :api_key, :base_url
|
|
9
|
+
|
|
10
|
+
def initialize(api_key: nil, base_url: nil, logger: nil, open_timeout: nil, read_timeout: nil)
|
|
11
|
+
configuration = StraddlePay.config
|
|
12
|
+
@api_key = api_key || configuration.api_key
|
|
13
|
+
@base_url = base_url || configuration.base_url
|
|
14
|
+
@logger = logger || configuration.logger
|
|
15
|
+
@open_timeout = open_timeout || configuration.open_timeout
|
|
16
|
+
@read_timeout = read_timeout || configuration.read_timeout
|
|
17
|
+
|
|
18
|
+
raise ArgumentError, "Missing API key for StraddlePay" if @api_key.to_s.empty?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def customers = @customers ||= Resources::Customers.new(self)
|
|
22
|
+
def bridge = @bridge ||= Resources::Bridge.new(self)
|
|
23
|
+
def paykeys = @paykeys ||= Resources::Paykeys.new(self)
|
|
24
|
+
def charges = @charges ||= Resources::Charges.new(self)
|
|
25
|
+
def payouts = @payouts ||= Resources::Payouts.new(self)
|
|
26
|
+
def payments = @payments ||= Resources::Payments.new(self)
|
|
27
|
+
def funding_events = @funding_events ||= Resources::FundingEvents.new(self)
|
|
28
|
+
def reports = @reports ||= Resources::Reports.new(self)
|
|
29
|
+
def embed = @embed ||= Resources::Embed.new(self)
|
|
30
|
+
|
|
31
|
+
def get(path, params: nil, headers: {})
|
|
32
|
+
request(:get, path, params: params, headers: headers)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def post(path, body = nil, headers: {})
|
|
36
|
+
request(:post, path, body: body, headers: headers)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def put(path, body = nil, headers: {})
|
|
40
|
+
request(:put, path, body: body, headers: headers)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def patch(path, body = nil, headers: {})
|
|
44
|
+
request(:patch, path, body: body, headers: headers)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def delete(path, body = nil, headers: {})
|
|
48
|
+
request(:delete, path, body: body, headers: headers)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def request(method, path, body: nil, params: nil, headers: {})
|
|
54
|
+
response = connection.public_send(method, path) do |req|
|
|
55
|
+
apply_headers(req, headers)
|
|
56
|
+
apply_body(req, body) if body
|
|
57
|
+
req.params.update(params) if params
|
|
58
|
+
end
|
|
59
|
+
log_response(method, path, response)
|
|
60
|
+
handle_response(response)
|
|
61
|
+
rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e
|
|
62
|
+
raise NetworkError, "Network error: #{e.message}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def connection
|
|
66
|
+
@connection ||= Faraday.new(url: @base_url) do |f|
|
|
67
|
+
f.options.timeout = @read_timeout
|
|
68
|
+
f.options.open_timeout = @open_timeout
|
|
69
|
+
f.adapter Faraday.default_adapter
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def apply_headers(req, extra = {})
|
|
74
|
+
req.headers["Authorization"] = "Bearer #{@api_key}"
|
|
75
|
+
req.headers["Content-Type"] = "application/json"
|
|
76
|
+
req.headers["Accept"] = "application/json"
|
|
77
|
+
extra.each { |k, v| req.headers[k.to_s] = v.to_s if v }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def apply_body(req, body)
|
|
81
|
+
req.headers["Content-Type"] = "application/json"
|
|
82
|
+
req.body = JSON.generate(body)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def handle_response(response)
|
|
86
|
+
body = parse_body(response.body)
|
|
87
|
+
return unwrap_data(body) if success?(response.status)
|
|
88
|
+
|
|
89
|
+
raise_error(response.status, body)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def unwrap_data(body)
|
|
93
|
+
return body unless body.is_a?(Hash) && body.key?("data")
|
|
94
|
+
|
|
95
|
+
body["data"]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def success?(status)
|
|
99
|
+
(200..299).cover?(status)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def parse_body(body)
|
|
103
|
+
return {} if body.nil? || (body.is_a?(String) && body.empty?)
|
|
104
|
+
return body unless body.is_a?(String)
|
|
105
|
+
|
|
106
|
+
JSON.parse(body)
|
|
107
|
+
rescue JSON::ParserError
|
|
108
|
+
body
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def raise_error(status, body)
|
|
112
|
+
message = error_message(status, body)
|
|
113
|
+
case status
|
|
114
|
+
when 401, 403 then raise AuthenticationError.new(message, status: status, body: body)
|
|
115
|
+
when 400, 404, 409, 422 then raise ClientError.new(message, status: status, body: body)
|
|
116
|
+
when 429 then raise RateLimitError.new(message, status: status, body: body)
|
|
117
|
+
when 500..599 then raise ServerError.new(message, status: status, body: body)
|
|
118
|
+
else raise Error.new(message, status: status, body: body)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def error_message(status, body)
|
|
123
|
+
detail = if body.is_a?(Hash)
|
|
124
|
+
err = body["error"] || {}
|
|
125
|
+
err.is_a?(Hash) ? (err["detail"] || err["title"] || err.to_json) : err.to_s
|
|
126
|
+
else
|
|
127
|
+
body.to_s
|
|
128
|
+
end
|
|
129
|
+
"HTTP #{status}: #{detail}"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def log_response(method, path, response)
|
|
133
|
+
@logger&.debug { "StraddlePay #{method.upcase} #{path} -> #{response.status}" }
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "logger"
|
|
4
|
+
|
|
5
|
+
module StraddlePay
|
|
6
|
+
class Config
|
|
7
|
+
SANDBOX_URL = "https://sandbox.straddle.io"
|
|
8
|
+
PRODUCTION_URL = "https://production.straddle.io"
|
|
9
|
+
|
|
10
|
+
attr_accessor :api_key, :base_url, :open_timeout, :read_timeout
|
|
11
|
+
attr_writer :logger
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@api_key = ENV.fetch("STRADDLE_API_KEY", nil)
|
|
15
|
+
@base_url = ENV.fetch("STRADDLE_BASE_URL", SANDBOX_URL)
|
|
16
|
+
@open_timeout = integer_or_default("STRADDLE_OPEN_TIMEOUT", 5)
|
|
17
|
+
@read_timeout = integer_or_default("STRADDLE_READ_TIMEOUT", 30)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def logger
|
|
21
|
+
@logger ||= (defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger) || Logger.new($stderr)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def integer_or_default(key, default)
|
|
27
|
+
Integer(ENV.fetch(key, default))
|
|
28
|
+
rescue StandardError
|
|
29
|
+
default
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
class Error < StandardError
|
|
5
|
+
attr_reader :status, :body, :error_type, :error_items
|
|
6
|
+
|
|
7
|
+
def initialize(message = nil, status: nil, body: nil)
|
|
8
|
+
error_hash = body.is_a?(Hash) ? (body["error"] || {}) : {}
|
|
9
|
+
@error_type = error_hash["type"] if error_hash.is_a?(Hash)
|
|
10
|
+
@error_items = (error_hash.is_a?(Hash) ? error_hash["items"] : nil) || []
|
|
11
|
+
super(message)
|
|
12
|
+
@status = status
|
|
13
|
+
@body = body
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class AuthenticationError < Error; end
|
|
18
|
+
class ClientError < Error; end
|
|
19
|
+
class RateLimitError < Error; end
|
|
20
|
+
class ServerError < Error; end
|
|
21
|
+
class NetworkError < Error; end
|
|
22
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Base
|
|
6
|
+
HEADER_KEYS = {
|
|
7
|
+
straddle_account_id: "Straddle-Account-Id",
|
|
8
|
+
request_id: "Request-Id",
|
|
9
|
+
correlation_id: "Correlation-Id",
|
|
10
|
+
idempotency_key: "Idempotency-Key"
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
def initialize(client)
|
|
14
|
+
@client = client
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def extract_headers(params)
|
|
20
|
+
headers = {}
|
|
21
|
+
HEADER_KEYS.each do |key, header|
|
|
22
|
+
headers[header] = params.delete(key).to_s if params.key?(key)
|
|
23
|
+
end
|
|
24
|
+
headers
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Bridge < Base
|
|
6
|
+
def links = @links ||= BridgeLinks.new(@client)
|
|
7
|
+
|
|
8
|
+
def initialize_session(customer_id:, **options)
|
|
9
|
+
payload = { customer_id: customer_id, **options }.compact
|
|
10
|
+
headers = extract_headers(payload)
|
|
11
|
+
@client.post("v1/bridge/initialize", payload, headers: headers)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class BridgeLinks < Base
|
|
6
|
+
def bank_account(customer_id:, account_number:, routing_number:, account_type:, **options)
|
|
7
|
+
payload = {
|
|
8
|
+
customer_id: customer_id, account_number: account_number,
|
|
9
|
+
routing_number: routing_number, account_type: account_type, **options
|
|
10
|
+
}.compact
|
|
11
|
+
headers = extract_headers(payload)
|
|
12
|
+
@client.post("v1/bridge/bank_account", payload, headers: headers)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def plaid(customer_id:, plaid_token:, **options)
|
|
16
|
+
payload = { customer_id: customer_id, plaid_token: plaid_token, **options }.compact
|
|
17
|
+
headers = extract_headers(payload)
|
|
18
|
+
@client.post("v1/bridge/plaid", payload, headers: headers)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def quiltt(customer_id:, quiltt_token:, **options)
|
|
22
|
+
payload = { customer_id: customer_id, quiltt_token: quiltt_token, **options }.compact
|
|
23
|
+
headers = extract_headers(payload)
|
|
24
|
+
@client.post("v1/bridge/quiltt", payload, headers: headers)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def tan(customer_id:, routing_number:, account_type:, tan:, **options)
|
|
28
|
+
payload = {
|
|
29
|
+
customer_id: customer_id, routing_number: routing_number,
|
|
30
|
+
account_type: account_type, tan: tan, **options
|
|
31
|
+
}.compact
|
|
32
|
+
headers = extract_headers(payload)
|
|
33
|
+
@client.post("v1/bridge/tan", payload, headers: headers)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Charges < Base
|
|
6
|
+
def create(paykey:, amount:, currency:, description:, payment_date:, consent_type:, device:, external_id:,
|
|
7
|
+
**options)
|
|
8
|
+
payload = {
|
|
9
|
+
paykey: paykey, amount: amount, currency: currency, description: description,
|
|
10
|
+
payment_date: payment_date, consent_type: consent_type, device: device,
|
|
11
|
+
external_id: external_id, **options
|
|
12
|
+
}.compact
|
|
13
|
+
headers = extract_headers(payload)
|
|
14
|
+
@client.post("v1/charges", payload, headers: headers)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get(id, **options)
|
|
18
|
+
headers = extract_headers(options)
|
|
19
|
+
@client.get("v1/charges/#{id}", headers: headers)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def update(id, **options)
|
|
23
|
+
headers = extract_headers(options)
|
|
24
|
+
@client.put("v1/charges/#{id}", options, headers: headers)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def cancel(id, **options)
|
|
28
|
+
headers = extract_headers(options)
|
|
29
|
+
@client.put("v1/charges/#{id}/cancel", options, headers: headers)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def hold(id, **options)
|
|
33
|
+
headers = extract_headers(options)
|
|
34
|
+
@client.put("v1/charges/#{id}/hold", options, headers: headers)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def release(id, **options)
|
|
38
|
+
headers = extract_headers(options)
|
|
39
|
+
@client.put("v1/charges/#{id}/release", options, headers: headers)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def unmask(id, **options)
|
|
43
|
+
headers = extract_headers(options)
|
|
44
|
+
@client.get("v1/charges/#{id}/unmask", headers: headers)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class CustomerReviews < Base
|
|
6
|
+
def get(customer_id, **options)
|
|
7
|
+
headers = extract_headers(options)
|
|
8
|
+
@client.get("v1/customers/#{customer_id}/review", headers: headers)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def decision(customer_id, status:, **options)
|
|
12
|
+
payload = { status: status, **options }.compact
|
|
13
|
+
headers = extract_headers(payload)
|
|
14
|
+
@client.patch("v1/customers/#{customer_id}/review", payload, headers: headers)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def refresh(customer_id, **options)
|
|
18
|
+
headers = extract_headers(options)
|
|
19
|
+
@client.put("v1/customers/#{customer_id}/refresh_review", options, headers: headers)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Customers < Base
|
|
6
|
+
def reviews = @reviews ||= CustomerReviews.new(@client)
|
|
7
|
+
|
|
8
|
+
def create(name:, type:, email:, phone:, device:, **options)
|
|
9
|
+
payload = { name: name, type: type, email: email, phone: phone, device: device, **options }.compact
|
|
10
|
+
headers = extract_headers(payload)
|
|
11
|
+
@client.post("v1/customers", payload, headers: headers)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get(id, **options)
|
|
15
|
+
headers = extract_headers(options)
|
|
16
|
+
@client.get("v1/customers/#{id}", headers: headers)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def list(**options)
|
|
20
|
+
headers = extract_headers(options)
|
|
21
|
+
@client.get("v1/customers", params: options, headers: headers)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def update(id, **options)
|
|
25
|
+
headers = extract_headers(options)
|
|
26
|
+
@client.put("v1/customers/#{id}", options, headers: headers)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def delete(id, **options)
|
|
30
|
+
headers = extract_headers(options)
|
|
31
|
+
@client.delete("v1/customers/#{id}", headers: headers)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def unmasked(id, **options)
|
|
35
|
+
headers = extract_headers(options)
|
|
36
|
+
@client.get("v1/customers/#{id}/unmasked", headers: headers)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Embed < Base
|
|
6
|
+
def accounts = @accounts ||= EmbedAccounts.new(@client)
|
|
7
|
+
def organizations = @organizations ||= EmbedOrganizations.new(@client)
|
|
8
|
+
def representatives = @representatives ||= EmbedRepresentatives.new(@client)
|
|
9
|
+
def linked_bank_accounts = @linked_bank_accounts ||= EmbedLinkedBankAccounts.new(@client)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class EmbedAccounts < Base
|
|
6
|
+
def create(organization_id:, account_type:, business_profile:, access_level:, **options)
|
|
7
|
+
payload = {
|
|
8
|
+
organization_id: organization_id, account_type: account_type,
|
|
9
|
+
business_profile: business_profile, access_level: access_level, **options
|
|
10
|
+
}.compact
|
|
11
|
+
headers = extract_headers(payload)
|
|
12
|
+
@client.post("v1/accounts", payload, headers: headers)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get(id, **options)
|
|
16
|
+
headers = extract_headers(options)
|
|
17
|
+
@client.get("v1/accounts/#{id}", headers: headers)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def list(**options)
|
|
21
|
+
headers = extract_headers(options)
|
|
22
|
+
@client.get("v1/accounts", params: options, headers: headers)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def update(id, **options)
|
|
26
|
+
headers = extract_headers(options)
|
|
27
|
+
@client.put("v1/accounts/#{id}", options, headers: headers)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def onboard(id, terms_of_service:, **options)
|
|
31
|
+
payload = { terms_of_service: terms_of_service, **options }.compact
|
|
32
|
+
headers = extract_headers(payload)
|
|
33
|
+
@client.post("v1/accounts/#{id}/onboard", payload, headers: headers)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def simulate(id, final_status:, **options)
|
|
37
|
+
payload = { final_status: final_status, **options }.compact
|
|
38
|
+
headers = extract_headers(payload)
|
|
39
|
+
@client.post("v1/accounts/#{id}/simulate", payload, headers: headers)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class EmbedLinkedBankAccounts < Base
|
|
6
|
+
def create(account_id:, bank_account:, description:, **options)
|
|
7
|
+
payload = {
|
|
8
|
+
account_id: account_id, bank_account: bank_account,
|
|
9
|
+
description: description, **options
|
|
10
|
+
}.compact
|
|
11
|
+
headers = extract_headers(payload)
|
|
12
|
+
@client.post("v1/linked_bank_accounts", payload, headers: headers)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get(id, **options)
|
|
16
|
+
headers = extract_headers(options)
|
|
17
|
+
@client.get("v1/linked_bank_accounts/#{id}", headers: headers)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def list(**options)
|
|
21
|
+
headers = extract_headers(options)
|
|
22
|
+
@client.get("v1/linked_bank_accounts", params: options, headers: headers)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def update(id, **options)
|
|
26
|
+
headers = extract_headers(options)
|
|
27
|
+
@client.put("v1/linked_bank_accounts/#{id}", options, headers: headers)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def cancel(id, **options)
|
|
31
|
+
headers = extract_headers(options)
|
|
32
|
+
@client.patch("v1/linked_bank_accounts/#{id}/cancel", options.empty? ? nil : options, headers: headers)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def unmask(id, **options)
|
|
36
|
+
headers = extract_headers(options)
|
|
37
|
+
@client.get("v1/linked_bank_accounts/#{id}/unmask", headers: headers)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class EmbedOrganizations < Base
|
|
6
|
+
def create(name:, **options)
|
|
7
|
+
payload = { name: name, **options }.compact
|
|
8
|
+
headers = extract_headers(payload)
|
|
9
|
+
@client.post("v1/organizations", payload, headers: headers)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get(id, **options)
|
|
13
|
+
headers = extract_headers(options)
|
|
14
|
+
@client.get("v1/organizations/#{id}", headers: headers)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def list(**options)
|
|
18
|
+
headers = extract_headers(options)
|
|
19
|
+
@client.get("v1/organizations", params: options, headers: headers)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class EmbedRepresentatives < Base
|
|
6
|
+
def create(account_id:, first_name:, last_name:, email:, dob:, mobile_number:, relationship:, ssn_last4:,
|
|
7
|
+
**options)
|
|
8
|
+
payload = {
|
|
9
|
+
account_id: account_id, first_name: first_name, last_name: last_name,
|
|
10
|
+
email: email, dob: dob, mobile_number: mobile_number,
|
|
11
|
+
relationship: relationship, ssn_last4: ssn_last4, **options
|
|
12
|
+
}.compact
|
|
13
|
+
headers = extract_headers(payload)
|
|
14
|
+
@client.post("v1/representatives", payload, headers: headers)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get(id, **options)
|
|
18
|
+
headers = extract_headers(options)
|
|
19
|
+
@client.get("v1/representatives/#{id}", headers: headers)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def list(**options)
|
|
23
|
+
headers = extract_headers(options)
|
|
24
|
+
@client.get("v1/representatives", params: options, headers: headers)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def update(id, **options)
|
|
28
|
+
headers = extract_headers(options)
|
|
29
|
+
@client.put("v1/representatives/#{id}", options, headers: headers)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def unmask(id, **options)
|
|
33
|
+
headers = extract_headers(options)
|
|
34
|
+
@client.get("v1/representatives/#{id}/unmask", headers: headers)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class FundingEvents < Base
|
|
6
|
+
def list(**options)
|
|
7
|
+
headers = extract_headers(options)
|
|
8
|
+
@client.get("v1/funding-events", params: options, headers: headers)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def get(id, **options)
|
|
12
|
+
headers = extract_headers(options)
|
|
13
|
+
@client.get("v1/funding-events/#{id}", headers: headers)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Paykeys < Base
|
|
6
|
+
def get(id, **options)
|
|
7
|
+
headers = extract_headers(options)
|
|
8
|
+
@client.get("v1/paykeys/#{id}", headers: headers)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def list(**options)
|
|
12
|
+
headers = extract_headers(options)
|
|
13
|
+
@client.get("v1/paykeys", params: options, headers: headers)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def unmasked(id, **options)
|
|
17
|
+
headers = extract_headers(options)
|
|
18
|
+
@client.get("v1/paykeys/#{id}/unmasked", headers: headers)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def reveal(id, **options)
|
|
22
|
+
headers = extract_headers(options)
|
|
23
|
+
@client.get("v1/paykeys/#{id}/reveal", headers: headers)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def cancel(id, **options)
|
|
27
|
+
headers = extract_headers(options)
|
|
28
|
+
@client.put("v1/paykeys/#{id}/cancel", options, headers: headers)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def review(id, **options)
|
|
32
|
+
headers = extract_headers(options)
|
|
33
|
+
@client.patch("v1/paykeys/#{id}/review", options, headers: headers)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Payouts < Base
|
|
6
|
+
def create(paykey:, amount:, currency:, description:, payment_date:, device:, external_id:, **options)
|
|
7
|
+
payload = {
|
|
8
|
+
paykey: paykey, amount: amount, currency: currency, description: description,
|
|
9
|
+
payment_date: payment_date, device: device, external_id: external_id, **options
|
|
10
|
+
}.compact
|
|
11
|
+
headers = extract_headers(payload)
|
|
12
|
+
@client.post("v1/payouts", payload, headers: headers)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get(id, **options)
|
|
16
|
+
headers = extract_headers(options)
|
|
17
|
+
@client.get("v1/payouts/#{id}", headers: headers)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def update(id, **options)
|
|
21
|
+
headers = extract_headers(options)
|
|
22
|
+
@client.put("v1/payouts/#{id}", options, headers: headers)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def cancel(id, reason:, **options)
|
|
26
|
+
payload = { reason: reason, **options }.compact
|
|
27
|
+
headers = extract_headers(payload)
|
|
28
|
+
@client.put("v1/payouts/#{id}/cancel", payload, headers: headers)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def hold(id, reason:, **options)
|
|
32
|
+
payload = { reason: reason, **options }.compact
|
|
33
|
+
headers = extract_headers(payload)
|
|
34
|
+
@client.put("v1/payouts/#{id}/hold", payload, headers: headers)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def release(id, reason:, **options)
|
|
38
|
+
payload = { reason: reason, **options }.compact
|
|
39
|
+
headers = extract_headers(payload)
|
|
40
|
+
@client.put("v1/payouts/#{id}/release", payload, headers: headers)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def unmask(id, **options)
|
|
44
|
+
headers = extract_headers(options)
|
|
45
|
+
@client.get("v1/payouts/#{id}/unmask", headers: headers)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StraddlePay
|
|
4
|
+
module Resources
|
|
5
|
+
class Reports < Base
|
|
6
|
+
def total_customers_by_status(**options)
|
|
7
|
+
headers = extract_headers(options)
|
|
8
|
+
@client.post("v1/reports/total_customers_by_status", options.empty? ? nil : options, headers: headers)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
data/lib/straddle_pay.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "straddle_pay/version"
|
|
4
|
+
|
|
5
|
+
module StraddlePay
|
|
6
|
+
autoload :Config, "straddle_pay/config"
|
|
7
|
+
autoload :Client, "straddle_pay/client"
|
|
8
|
+
autoload :Error, "straddle_pay/errors"
|
|
9
|
+
autoload :AuthenticationError, "straddle_pay/errors"
|
|
10
|
+
autoload :ClientError, "straddle_pay/errors"
|
|
11
|
+
autoload :RateLimitError, "straddle_pay/errors"
|
|
12
|
+
autoload :ServerError, "straddle_pay/errors"
|
|
13
|
+
autoload :NetworkError, "straddle_pay/errors"
|
|
14
|
+
|
|
15
|
+
module Resources
|
|
16
|
+
autoload :Base, "straddle_pay/resources/base"
|
|
17
|
+
autoload :Charges, "straddle_pay/resources/charges"
|
|
18
|
+
autoload :Payouts, "straddle_pay/resources/payouts"
|
|
19
|
+
autoload :Customers, "straddle_pay/resources/customers"
|
|
20
|
+
autoload :CustomerReviews, "straddle_pay/resources/customer_reviews"
|
|
21
|
+
autoload :Bridge, "straddle_pay/resources/bridge"
|
|
22
|
+
autoload :BridgeLinks, "straddle_pay/resources/bridge_links"
|
|
23
|
+
autoload :Paykeys, "straddle_pay/resources/paykeys"
|
|
24
|
+
autoload :Payments, "straddle_pay/resources/payments"
|
|
25
|
+
autoload :FundingEvents, "straddle_pay/resources/funding_events"
|
|
26
|
+
autoload :Reports, "straddle_pay/resources/reports"
|
|
27
|
+
autoload :Embed, "straddle_pay/resources/embed"
|
|
28
|
+
autoload :EmbedAccounts, "straddle_pay/resources/embed_accounts"
|
|
29
|
+
autoload :EmbedOrganizations, "straddle_pay/resources/embed_organizations"
|
|
30
|
+
autoload :EmbedRepresentatives, "straddle_pay/resources/embed_representatives"
|
|
31
|
+
autoload :EmbedLinkedBankAccounts, "straddle_pay/resources/embed_linked_bank_accounts"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
def config
|
|
36
|
+
@config ||= Config.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def configure
|
|
40
|
+
yield(config)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def reset_configuration!
|
|
44
|
+
@config = nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
require_relative "straddle_pay/engine"
|
metadata
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: straddle_pay
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- dpaluy
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: faraday
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.9'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '2.9'
|
|
26
|
+
description: StraddlePay provides a lightweight Faraday-based wrapper for Straddle's
|
|
27
|
+
payment API including charges, payouts, customers, bridge, paykeys, and embedded
|
|
28
|
+
account management.
|
|
29
|
+
email:
|
|
30
|
+
- dpaluy@users.noreply.github.com
|
|
31
|
+
executables: []
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files:
|
|
34
|
+
- CHANGELOG.md
|
|
35
|
+
- LICENSE.txt
|
|
36
|
+
- README.md
|
|
37
|
+
files:
|
|
38
|
+
- CHANGELOG.md
|
|
39
|
+
- LICENSE.txt
|
|
40
|
+
- README.md
|
|
41
|
+
- lib/straddle_pay.rb
|
|
42
|
+
- lib/straddle_pay/client.rb
|
|
43
|
+
- lib/straddle_pay/config.rb
|
|
44
|
+
- lib/straddle_pay/engine.rb
|
|
45
|
+
- lib/straddle_pay/errors.rb
|
|
46
|
+
- lib/straddle_pay/resources/base.rb
|
|
47
|
+
- lib/straddle_pay/resources/bridge.rb
|
|
48
|
+
- lib/straddle_pay/resources/bridge_links.rb
|
|
49
|
+
- lib/straddle_pay/resources/charges.rb
|
|
50
|
+
- lib/straddle_pay/resources/customer_reviews.rb
|
|
51
|
+
- lib/straddle_pay/resources/customers.rb
|
|
52
|
+
- lib/straddle_pay/resources/embed.rb
|
|
53
|
+
- lib/straddle_pay/resources/embed_accounts.rb
|
|
54
|
+
- lib/straddle_pay/resources/embed_linked_bank_accounts.rb
|
|
55
|
+
- lib/straddle_pay/resources/embed_organizations.rb
|
|
56
|
+
- lib/straddle_pay/resources/embed_representatives.rb
|
|
57
|
+
- lib/straddle_pay/resources/funding_events.rb
|
|
58
|
+
- lib/straddle_pay/resources/paykeys.rb
|
|
59
|
+
- lib/straddle_pay/resources/payments.rb
|
|
60
|
+
- lib/straddle_pay/resources/payouts.rb
|
|
61
|
+
- lib/straddle_pay/resources/reports.rb
|
|
62
|
+
- lib/straddle_pay/version.rb
|
|
63
|
+
homepage: https://github.com/dpaluy/straddle_pay
|
|
64
|
+
licenses:
|
|
65
|
+
- MIT
|
|
66
|
+
metadata:
|
|
67
|
+
rubygems_mfa_required: 'true'
|
|
68
|
+
homepage_uri: https://github.com/dpaluy/straddle_pay
|
|
69
|
+
documentation_uri: https://rubydoc.info/gems/straddle_pay
|
|
70
|
+
source_code_uri: https://github.com/dpaluy/straddle_pay
|
|
71
|
+
changelog_uri: https://github.com/dpaluy/straddle_pay/blob/master/CHANGELOG.md
|
|
72
|
+
bug_tracker_uri: https://github.com/dpaluy/straddle_pay/issues
|
|
73
|
+
rdoc_options: []
|
|
74
|
+
require_paths:
|
|
75
|
+
- lib
|
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - ">="
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: 3.2.0
|
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
requirements: []
|
|
87
|
+
rubygems_version: 4.0.3
|
|
88
|
+
specification_version: 4
|
|
89
|
+
summary: Ruby client for the Straddle payment infrastructure API.
|
|
90
|
+
test_files: []
|