fiscalrail 0.4.0 → 0.6.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 +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +37 -7
- data/lib/fiscalrail/client.rb +2 -1
- data/lib/fiscalrail/generated/contract.rb +281 -81
- data/lib/fiscalrail/generated/models.rb +51 -10
- data/lib/fiscalrail/resource.rb +2 -2
- data/lib/fiscalrail/resources/accounts.rb +40 -10
- data/lib/fiscalrail/transport.rb +13 -1
- data/lib/fiscalrail/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 686707319e3f84edc7570df96ecde4325051ced614c1d7afb0706fb490730fbe
|
|
4
|
+
data.tar.gz: 9b72d4865f113b5d9e1d18668a390ec8d6900b1ab05d06ca9ef12cf933a47c90
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b72ea35beff00c975ccb4dcb1f4953b56805cd64b330dee8cd4d39086158043574a4f10e51d28eac3639bea26cde7dbd0bfdcf068cbf66a8bd4d1838e5b4836
|
|
7
|
+
data.tar.gz: aae2526ccbe70ba3872c6859861cb972f743e72b1fc653fd28006d8236b49275583f48651e034fae59f6dbd109e36e841fec16d842efb0d8770dfd88dc9e0d04
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
- Add ES-scoped issuer certificate file uploads, representation verification,
|
|
6
|
+
submission-verification retries and pending-change cancellation.
|
|
7
|
+
- Expose active submission readiness and pending verification results from the
|
|
8
|
+
deployed API contract (47 operations).
|
|
9
|
+
- Keep certificate uploads as native multipart requests without automatic retries.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## 0.5.0 — 2026-09-28
|
|
13
|
+
|
|
14
|
+
- Match the deployed current-account API routes and split invoicing settings into a dedicated resource.
|
|
15
|
+
- Use `/tax-ids/{id}` for tax ID retrieval.
|
|
16
|
+
- Regenerate response and request types from the updated FiscalRail OpenAPI contract.
|
|
17
|
+
|
|
3
18
|
## 0.4.0 — 2026-09-07
|
|
4
19
|
|
|
5
20
|
- Start at 0.4.0 to match the Python SDK release with full resource coverage.
|
data/README.md
CHANGED
|
@@ -5,7 +5,7 @@ A Ruby client for issuing immutable invoices through FiscalRail. Ruby 3.3 or lat
|
|
|
5
5
|
Install with Bundler:
|
|
6
6
|
|
|
7
7
|
```ruby
|
|
8
|
-
gem "fiscalrail", "~> 0.
|
|
8
|
+
gem "fiscalrail", "~> 0.6.0"
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Issue an invoice
|
|
@@ -83,9 +83,10 @@ By default, the SDK makes at most two retries for connection failures, timeouts,
|
|
|
83
83
|
|
|
84
84
|
| Resource | Methods |
|
|
85
85
|
| --- | --- |
|
|
86
|
-
| `accounts` | `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
86
|
+
| `accounts` | `retrieve`, `update` |
|
|
87
|
+
| `account_invoicing` | `retrieve`, `update` |
|
|
88
|
+
| `balances` | `retrieve` |
|
|
89
|
+
| `account_tax_regimes` | `retrieve` |
|
|
89
90
|
| `api_keys` | `list`, `create`, `retrieve`, `delete` |
|
|
90
91
|
| `customers` | `list`, `create`, `retrieve`, `update`, `delete` |
|
|
91
92
|
| `event_destinations` | `list`, `create`, `retrieve`, `update`, `delete`, `enable`, `disable` |
|
|
@@ -114,7 +115,7 @@ end
|
|
|
114
115
|
first_ten = client.customers.auto_paging_each.lazy.take(10).to_a
|
|
115
116
|
```
|
|
116
117
|
|
|
117
|
-
Automatic iteration proceeds forward and preserves filters. Use `list(starting_after: ...)` or `list(ending_before: ...)` to manage cursors yourself.
|
|
118
|
+
Automatic iteration proceeds forward and preserves filters. Use `list(starting_after: ...)` or `list(ending_before: ...)` to manage cursors yourself. Account, account invoicing, balance, and account tax regime resources return single objects.
|
|
118
119
|
|
|
119
120
|
## Payment instructions
|
|
120
121
|
|
|
@@ -129,7 +130,7 @@ instruction = client.payment_instructions.create(
|
|
|
129
130
|
}
|
|
130
131
|
)
|
|
131
132
|
|
|
132
|
-
client.
|
|
133
|
+
client.account_invoicing.update(default_payment_instructions: [instruction.id])
|
|
133
134
|
|
|
134
135
|
invoice = client.invoices.issue(
|
|
135
136
|
payment_terms: { due_date: Date.new(2026, 9, 30) },
|
|
@@ -182,7 +183,7 @@ FiscalRail::Client.open(
|
|
|
182
183
|
write_timeout: 30,
|
|
183
184
|
max_retries: 2
|
|
184
185
|
) do |client|
|
|
185
|
-
client.accounts.
|
|
186
|
+
client.accounts.retrieve
|
|
186
187
|
end
|
|
187
188
|
```
|
|
188
189
|
|
|
@@ -229,3 +230,32 @@ FISCALRAIL_APP_ROOT="$PWD" bundle exec ruby /absolute/path/to/ruby/test/rails_in
|
|
|
229
230
|
It creates a Test account inside a test transaction and checks customer creation, null clearing, payment defaults, issuance/replay, pagination, PDF download and amendment. Set `FISCALRAIL_SDK_PDF=/tmp/sdk-invoice.pdf` to retain the rendered PDF for inspection. This test is optional and is not part of the standalone gem CI.
|
|
230
231
|
|
|
231
232
|
See [RELEASING.md](RELEASING.md) for the release checklist.
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
## Spanish AEAT submission
|
|
236
|
+
|
|
237
|
+
Use a Live Spanish account key. Upload a `.p12`/`.pfx` file (up to 128 KiB),
|
|
238
|
+
including its private key, using native multipart upload. Omit the password for
|
|
239
|
+
an unprotected bundle. The certificate's issuer NIF must match the account.
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
File.open("issuer.p12", "rb") do |certificate|
|
|
243
|
+
setup = client.account_tax_regimes.es.upload_certificate(
|
|
244
|
+
certificate_file: certificate,
|
|
245
|
+
certificate_password: ENV.fetch("CERTIFICATE_PASSWORD")
|
|
246
|
+
)
|
|
247
|
+
end
|
|
248
|
+
setup = client.account_tax_regimes.retrieve
|
|
249
|
+
# Inspect setup.es.pending_submission.status / error_code and setup.es.submission.ready.
|
|
250
|
+
client.account_tax_regimes.es.verify_submission # retry the pending or active check
|
|
251
|
+
client.account_tax_regimes.es.cancel_submission_change
|
|
252
|
+
client.account_tax_regimes.es.verify_representation # after granting AEAT authority
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Each mutation above is a separate operation; choose the one needed. Upload and
|
|
256
|
+
verification return the account setup while AEAT checks run asynchronously.
|
|
257
|
+
Poll the generic account tax-regime resource for pending verification status,
|
|
258
|
+
error code and the active setup's readiness. A working setup remains active until
|
|
259
|
+
a replacement verifies; failed checks retain the pending certificate for retry.
|
|
260
|
+
Cancelling removes only the pending change. Uploads are not automatically retried.
|
|
261
|
+
The ES mutations use `/account/tax-regime/es/...`; reads use `/account/tax-regime`.
|
data/lib/fiscalrail/client.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module FiscalRail
|
|
4
4
|
class Client
|
|
5
|
-
attr_reader :accounts, :balances, :account_tax_regimes, :api_keys, :customers,
|
|
5
|
+
attr_reader :accounts, :account_invoicing, :balances, :account_tax_regimes, :api_keys, :customers,
|
|
6
6
|
:event_destinations, :events, :invoice_series, :invoices, :invoice_pdfs,
|
|
7
7
|
:payment_instructions, :tax_ids, :tax_regimes
|
|
8
8
|
|
|
@@ -20,6 +20,7 @@ module FiscalRail
|
|
|
20
20
|
@adapter = adapter || NetHTTPAdapter.new(open_timeout: open_timeout, read_timeout: read_timeout, write_timeout: write_timeout)
|
|
21
21
|
transport = Transport.new(api_key: api_key, base_url: base_url, max_retries: max_retries, adapter: @adapter)
|
|
22
22
|
@accounts = Resources::Accounts.new(transport)
|
|
23
|
+
@account_invoicing = Resources::AccountInvoicing.new(transport)
|
|
23
24
|
@balances = Resources::Balances.new(transport)
|
|
24
25
|
@account_tax_regimes = Resources::AccountTaxRegimes.new(transport)
|
|
25
26
|
@api_keys = Resources::ApiKeys.new(transport)
|
|
@@ -19,15 +19,6 @@ module FiscalRail
|
|
|
19
19
|
"format": "date-time",
|
|
20
20
|
"type": "string"
|
|
21
21
|
},
|
|
22
|
-
"default_payment_instructions": {
|
|
23
|
-
"items": {
|
|
24
|
-
"$ref": "#/components/schemas/PaymentInstructionId"
|
|
25
|
-
},
|
|
26
|
-
"type": "array"
|
|
27
|
-
},
|
|
28
|
-
"default_series": {
|
|
29
|
-
"$ref": "#/components/schemas/AccountDefaultSeries"
|
|
30
|
-
},
|
|
31
22
|
"email": {
|
|
32
23
|
"type": [
|
|
33
24
|
"string",
|
|
@@ -37,12 +28,6 @@ module FiscalRail
|
|
|
37
28
|
"id": {
|
|
38
29
|
"$ref": "#/components/schemas/AccountId"
|
|
39
30
|
},
|
|
40
|
-
"invoice_locale": {
|
|
41
|
-
"type": "string"
|
|
42
|
-
},
|
|
43
|
-
"invoice_numbering_scope": {
|
|
44
|
-
"$ref": "#/components/schemas/AccountInvoiceNumberingScope"
|
|
45
|
-
},
|
|
46
31
|
"live": {
|
|
47
32
|
"$ref": "#/components/schemas/Live"
|
|
48
33
|
},
|
|
@@ -84,10 +69,6 @@ module FiscalRail
|
|
|
84
69
|
"address",
|
|
85
70
|
"tax_regime",
|
|
86
71
|
"timezone",
|
|
87
|
-
"invoice_locale",
|
|
88
|
-
"invoice_numbering_scope",
|
|
89
|
-
"default_series",
|
|
90
|
-
"default_payment_instructions",
|
|
91
72
|
"created_at",
|
|
92
73
|
"updated_at"
|
|
93
74
|
],
|
|
@@ -133,30 +114,72 @@ module FiscalRail
|
|
|
133
114
|
"AccountInvoiceNumberingScope": {
|
|
134
115
|
"type": "string"
|
|
135
116
|
},
|
|
136
|
-
"
|
|
137
|
-
"model": "
|
|
117
|
+
"AccountInvoicing": {
|
|
118
|
+
"model": "AccountInvoicing",
|
|
138
119
|
"properties": {
|
|
139
|
-
"
|
|
120
|
+
"default_payment_instructions": {
|
|
140
121
|
"items": {
|
|
141
|
-
"$ref": "#/components/schemas/
|
|
122
|
+
"$ref": "#/components/schemas/PaymentInstructionId"
|
|
142
123
|
},
|
|
143
124
|
"type": "array"
|
|
144
125
|
},
|
|
145
|
-
"
|
|
146
|
-
"
|
|
126
|
+
"default_series": {
|
|
127
|
+
"$ref": "#/components/schemas/AccountDefaultSeries"
|
|
128
|
+
},
|
|
129
|
+
"footer": {
|
|
130
|
+
"type": [
|
|
131
|
+
"string",
|
|
132
|
+
"null"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"locale": {
|
|
136
|
+
"type": "string"
|
|
137
|
+
},
|
|
138
|
+
"numbering_scope": {
|
|
139
|
+
"$ref": "#/components/schemas/AccountInvoiceNumberingScope"
|
|
147
140
|
},
|
|
148
141
|
"object": {
|
|
149
|
-
"const": "
|
|
142
|
+
"const": "account_invoicing",
|
|
150
143
|
"type": "string"
|
|
151
144
|
}
|
|
152
145
|
},
|
|
153
146
|
"required": [
|
|
154
147
|
"object",
|
|
155
|
-
"
|
|
156
|
-
"
|
|
148
|
+
"locale",
|
|
149
|
+
"footer",
|
|
150
|
+
"numbering_scope",
|
|
151
|
+
"default_series",
|
|
152
|
+
"default_payment_instructions"
|
|
157
153
|
],
|
|
158
154
|
"type": "object"
|
|
159
155
|
},
|
|
156
|
+
"AccountInvoicingUpdate": {
|
|
157
|
+
"model": "AccountInvoicingUpdate",
|
|
158
|
+
"properties": {
|
|
159
|
+
"default_payment_instructions": {
|
|
160
|
+
"items": {
|
|
161
|
+
"$ref": "#/components/schemas/PaymentInstructionId"
|
|
162
|
+
},
|
|
163
|
+
"type": "array"
|
|
164
|
+
},
|
|
165
|
+
"default_series": {
|
|
166
|
+
"$ref": "#/components/schemas/AccountDefaultSeries"
|
|
167
|
+
},
|
|
168
|
+
"footer": {
|
|
169
|
+
"type": [
|
|
170
|
+
"string",
|
|
171
|
+
"null"
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
"locale": {
|
|
175
|
+
"type": "string"
|
|
176
|
+
},
|
|
177
|
+
"numbering_scope": {
|
|
178
|
+
"$ref": "#/components/schemas/AccountInvoiceNumberingScope"
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"type": "object"
|
|
182
|
+
},
|
|
160
183
|
"AccountNotConfiguredErrorResponse": {
|
|
161
184
|
"model": "AccountNotConfiguredErrorResponse",
|
|
162
185
|
"properties": {
|
|
@@ -206,17 +229,20 @@ module FiscalRail
|
|
|
206
229
|
"address": {
|
|
207
230
|
"$ref": "#/components/schemas/AddressUpdate"
|
|
208
231
|
},
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
|
|
213
|
-
|
|
232
|
+
"email": {
|
|
233
|
+
"type": [
|
|
234
|
+
"string",
|
|
235
|
+
"null"
|
|
236
|
+
]
|
|
214
237
|
},
|
|
215
|
-
"
|
|
216
|
-
"
|
|
238
|
+
"name": {
|
|
239
|
+
"type": "string"
|
|
217
240
|
},
|
|
218
|
-
"
|
|
219
|
-
"
|
|
241
|
+
"phone": {
|
|
242
|
+
"type": [
|
|
243
|
+
"string",
|
|
244
|
+
"null"
|
|
245
|
+
]
|
|
220
246
|
}
|
|
221
247
|
},
|
|
222
248
|
"type": "object"
|
|
@@ -2339,6 +2365,49 @@ module FiscalRail
|
|
|
2339
2365
|
],
|
|
2340
2366
|
"type": "object"
|
|
2341
2367
|
},
|
|
2368
|
+
"SpanishAccountSubmission": {
|
|
2369
|
+
"model": "SpanishAccountSubmission",
|
|
2370
|
+
"properties": {
|
|
2371
|
+
"certificate_expires_at": {
|
|
2372
|
+
"format": "date-time",
|
|
2373
|
+
"type": [
|
|
2374
|
+
"string",
|
|
2375
|
+
"null"
|
|
2376
|
+
]
|
|
2377
|
+
},
|
|
2378
|
+
"error_code": {
|
|
2379
|
+
"type": [
|
|
2380
|
+
"string",
|
|
2381
|
+
"null"
|
|
2382
|
+
]
|
|
2383
|
+
},
|
|
2384
|
+
"kind": {
|
|
2385
|
+
"type": "string"
|
|
2386
|
+
},
|
|
2387
|
+
"last_checked_at": {
|
|
2388
|
+
"format": "date-time",
|
|
2389
|
+
"type": [
|
|
2390
|
+
"string",
|
|
2391
|
+
"null"
|
|
2392
|
+
]
|
|
2393
|
+
},
|
|
2394
|
+
"ready": {
|
|
2395
|
+
"type": "boolean"
|
|
2396
|
+
},
|
|
2397
|
+
"status": {
|
|
2398
|
+
"type": "string"
|
|
2399
|
+
}
|
|
2400
|
+
},
|
|
2401
|
+
"required": [
|
|
2402
|
+
"kind",
|
|
2403
|
+
"ready",
|
|
2404
|
+
"certificate_expires_at",
|
|
2405
|
+
"status",
|
|
2406
|
+
"error_code",
|
|
2407
|
+
"last_checked_at"
|
|
2408
|
+
],
|
|
2409
|
+
"type": "object"
|
|
2410
|
+
},
|
|
2342
2411
|
"SpanishAccountTaxRegime": {
|
|
2343
2412
|
"model": "SpanishAccountTaxRegime",
|
|
2344
2413
|
"properties": {
|
|
@@ -2368,6 +2437,16 @@ module FiscalRail
|
|
|
2368
2437
|
"SpanishAccountTaxRegimeDetails": {
|
|
2369
2438
|
"model": "SpanishAccountTaxRegimeDetails",
|
|
2370
2439
|
"properties": {
|
|
2440
|
+
"pending_submission": {
|
|
2441
|
+
"oneOf": [
|
|
2442
|
+
{
|
|
2443
|
+
"$ref": "#/components/schemas/SpanishPendingSubmission"
|
|
2444
|
+
},
|
|
2445
|
+
{
|
|
2446
|
+
"type": "null"
|
|
2447
|
+
}
|
|
2448
|
+
]
|
|
2449
|
+
},
|
|
2371
2450
|
"representation": {
|
|
2372
2451
|
"oneOf": [
|
|
2373
2452
|
{
|
|
@@ -2377,10 +2456,22 @@ module FiscalRail
|
|
|
2377
2456
|
"type": "null"
|
|
2378
2457
|
}
|
|
2379
2458
|
]
|
|
2459
|
+
},
|
|
2460
|
+
"submission": {
|
|
2461
|
+
"oneOf": [
|
|
2462
|
+
{
|
|
2463
|
+
"$ref": "#/components/schemas/SpanishAccountSubmission"
|
|
2464
|
+
},
|
|
2465
|
+
{
|
|
2466
|
+
"type": "null"
|
|
2467
|
+
}
|
|
2468
|
+
]
|
|
2380
2469
|
}
|
|
2381
2470
|
},
|
|
2382
2471
|
"required": [
|
|
2383
|
-
"representation"
|
|
2472
|
+
"representation",
|
|
2473
|
+
"submission",
|
|
2474
|
+
"pending_submission"
|
|
2384
2475
|
],
|
|
2385
2476
|
"type": "object"
|
|
2386
2477
|
},
|
|
@@ -2434,6 +2525,89 @@ module FiscalRail
|
|
|
2434
2525
|
],
|
|
2435
2526
|
"type": "object"
|
|
2436
2527
|
},
|
|
2528
|
+
"SpanishPendingSubmission": {
|
|
2529
|
+
"model": "SpanishPendingSubmission",
|
|
2530
|
+
"properties": {
|
|
2531
|
+
"certificate_expires_at": {
|
|
2532
|
+
"format": "date-time",
|
|
2533
|
+
"type": [
|
|
2534
|
+
"string",
|
|
2535
|
+
"null"
|
|
2536
|
+
]
|
|
2537
|
+
},
|
|
2538
|
+
"error_code": {
|
|
2539
|
+
"type": [
|
|
2540
|
+
"string",
|
|
2541
|
+
"null"
|
|
2542
|
+
]
|
|
2543
|
+
},
|
|
2544
|
+
"kind": {
|
|
2545
|
+
"type": "string"
|
|
2546
|
+
},
|
|
2547
|
+
"last_checked_at": {
|
|
2548
|
+
"format": "date-time",
|
|
2549
|
+
"type": [
|
|
2550
|
+
"string",
|
|
2551
|
+
"null"
|
|
2552
|
+
]
|
|
2553
|
+
},
|
|
2554
|
+
"status": {
|
|
2555
|
+
"type": "string"
|
|
2556
|
+
}
|
|
2557
|
+
},
|
|
2558
|
+
"required": [
|
|
2559
|
+
"kind",
|
|
2560
|
+
"status",
|
|
2561
|
+
"error_code",
|
|
2562
|
+
"last_checked_at",
|
|
2563
|
+
"certificate_expires_at"
|
|
2564
|
+
],
|
|
2565
|
+
"type": "object"
|
|
2566
|
+
},
|
|
2567
|
+
"SubmissionConfigurationErrorResponse": {
|
|
2568
|
+
"model": "SubmissionConfigurationErrorResponse",
|
|
2569
|
+
"properties": {
|
|
2570
|
+
"error": {
|
|
2571
|
+
"model": "SubmissionConfigurationError",
|
|
2572
|
+
"properties": {
|
|
2573
|
+
"code": {
|
|
2574
|
+
"type": "string"
|
|
2575
|
+
},
|
|
2576
|
+
"details": {
|
|
2577
|
+
"items": {
|
|
2578
|
+
"model": "SubmissionConfigurationValidationDetail",
|
|
2579
|
+
"properties": {
|
|
2580
|
+
"field": {
|
|
2581
|
+
"type": "string"
|
|
2582
|
+
},
|
|
2583
|
+
"message": {
|
|
2584
|
+
"type": "string"
|
|
2585
|
+
}
|
|
2586
|
+
},
|
|
2587
|
+
"required": [
|
|
2588
|
+
"field",
|
|
2589
|
+
"message"
|
|
2590
|
+
],
|
|
2591
|
+
"type": "object"
|
|
2592
|
+
},
|
|
2593
|
+
"type": "array"
|
|
2594
|
+
},
|
|
2595
|
+
"message": {
|
|
2596
|
+
"type": "string"
|
|
2597
|
+
}
|
|
2598
|
+
},
|
|
2599
|
+
"required": [
|
|
2600
|
+
"code",
|
|
2601
|
+
"message"
|
|
2602
|
+
],
|
|
2603
|
+
"type": "object"
|
|
2604
|
+
}
|
|
2605
|
+
},
|
|
2606
|
+
"required": [
|
|
2607
|
+
"error"
|
|
2608
|
+
],
|
|
2609
|
+
"type": "object"
|
|
2610
|
+
},
|
|
2437
2611
|
"TaxId": {
|
|
2438
2612
|
"model": "TaxId",
|
|
2439
2613
|
"properties": {
|
|
@@ -2888,6 +3062,16 @@ module FiscalRail
|
|
|
2888
3062
|
}
|
|
2889
3063
|
}
|
|
2890
3064
|
},
|
|
3065
|
+
"cancelAccountSubmissionChange": {
|
|
3066
|
+
"method": "DELETE",
|
|
3067
|
+
"path": "/account/tax-regime/es/submission/pending",
|
|
3068
|
+
"parameters": [],
|
|
3069
|
+
"responses": {
|
|
3070
|
+
"200": {
|
|
3071
|
+
"$ref": "#/components/schemas/AccountTaxRegime"
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
},
|
|
2891
3075
|
"createApiKey": {
|
|
2892
3076
|
"method": "POST",
|
|
2893
3077
|
"path": "/api-keys",
|
|
@@ -3056,16 +3240,6 @@ module FiscalRail
|
|
|
3056
3240
|
}
|
|
3057
3241
|
}
|
|
3058
3242
|
},
|
|
3059
|
-
"listAccounts": {
|
|
3060
|
-
"method": "GET",
|
|
3061
|
-
"path": "/accounts",
|
|
3062
|
-
"parameters": [],
|
|
3063
|
-
"responses": {
|
|
3064
|
-
"200": {
|
|
3065
|
-
"$ref": "#/components/schemas/AccountList"
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
},
|
|
3069
3243
|
"listApiKeys": {
|
|
3070
3244
|
"method": "GET",
|
|
3071
3245
|
"path": "/api-keys",
|
|
@@ -3290,30 +3464,28 @@ module FiscalRail
|
|
|
3290
3464
|
},
|
|
3291
3465
|
"retrieveAccount": {
|
|
3292
3466
|
"method": "GET",
|
|
3293
|
-
"path": "/
|
|
3294
|
-
"parameters": [
|
|
3295
|
-
{
|
|
3296
|
-
"name": "id",
|
|
3297
|
-
"in": "path",
|
|
3298
|
-
"required": true
|
|
3299
|
-
}
|
|
3300
|
-
],
|
|
3467
|
+
"path": "/account",
|
|
3468
|
+
"parameters": [],
|
|
3301
3469
|
"responses": {
|
|
3302
3470
|
"200": {
|
|
3303
3471
|
"$ref": "#/components/schemas/Account"
|
|
3304
3472
|
}
|
|
3305
3473
|
}
|
|
3306
3474
|
},
|
|
3307
|
-
"
|
|
3475
|
+
"retrieveAccountInvoicing": {
|
|
3308
3476
|
"method": "GET",
|
|
3309
|
-
"path": "/
|
|
3310
|
-
"parameters": [
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
"
|
|
3314
|
-
"required": true
|
|
3477
|
+
"path": "/account/invoicing",
|
|
3478
|
+
"parameters": [],
|
|
3479
|
+
"responses": {
|
|
3480
|
+
"200": {
|
|
3481
|
+
"$ref": "#/components/schemas/AccountInvoicing"
|
|
3315
3482
|
}
|
|
3316
|
-
|
|
3483
|
+
}
|
|
3484
|
+
},
|
|
3485
|
+
"retrieveAccountTaxRegime": {
|
|
3486
|
+
"method": "GET",
|
|
3487
|
+
"path": "/account/tax-regime",
|
|
3488
|
+
"parameters": [],
|
|
3317
3489
|
"responses": {
|
|
3318
3490
|
"200": {
|
|
3319
3491
|
"$ref": "#/components/schemas/AccountTaxRegime"
|
|
@@ -3338,14 +3510,8 @@ module FiscalRail
|
|
|
3338
3510
|
},
|
|
3339
3511
|
"retrieveBalance": {
|
|
3340
3512
|
"method": "GET",
|
|
3341
|
-
"path": "/
|
|
3342
|
-
"parameters": [
|
|
3343
|
-
{
|
|
3344
|
-
"name": "account_id",
|
|
3345
|
-
"in": "path",
|
|
3346
|
-
"required": true
|
|
3347
|
-
}
|
|
3348
|
-
],
|
|
3513
|
+
"path": "/account/balance",
|
|
3514
|
+
"parameters": [],
|
|
3349
3515
|
"responses": {
|
|
3350
3516
|
"200": {
|
|
3351
3517
|
"$ref": "#/components/schemas/Balance"
|
|
@@ -3466,7 +3632,7 @@ module FiscalRail
|
|
|
3466
3632
|
},
|
|
3467
3633
|
"retrieveTaxId": {
|
|
3468
3634
|
"method": "GET",
|
|
3469
|
-
"path": "/
|
|
3635
|
+
"path": "/tax-ids/{id}",
|
|
3470
3636
|
"parameters": [
|
|
3471
3637
|
{
|
|
3472
3638
|
"name": "id",
|
|
@@ -3498,20 +3664,24 @@ module FiscalRail
|
|
|
3498
3664
|
},
|
|
3499
3665
|
"updateAccount": {
|
|
3500
3666
|
"method": "PATCH",
|
|
3501
|
-
"path": "/
|
|
3502
|
-
"parameters": [
|
|
3503
|
-
{
|
|
3504
|
-
"name": "id",
|
|
3505
|
-
"in": "path",
|
|
3506
|
-
"required": true
|
|
3507
|
-
}
|
|
3508
|
-
],
|
|
3667
|
+
"path": "/account",
|
|
3668
|
+
"parameters": [],
|
|
3509
3669
|
"responses": {
|
|
3510
3670
|
"200": {
|
|
3511
3671
|
"$ref": "#/components/schemas/Account"
|
|
3512
3672
|
}
|
|
3513
3673
|
}
|
|
3514
3674
|
},
|
|
3675
|
+
"updateAccountInvoicing": {
|
|
3676
|
+
"method": "PATCH",
|
|
3677
|
+
"path": "/account/invoicing",
|
|
3678
|
+
"parameters": [],
|
|
3679
|
+
"responses": {
|
|
3680
|
+
"200": {
|
|
3681
|
+
"$ref": "#/components/schemas/AccountInvoicing"
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
},
|
|
3515
3685
|
"updateCustomer": {
|
|
3516
3686
|
"method": "PATCH",
|
|
3517
3687
|
"path": "/customers/{id}",
|
|
@@ -3575,6 +3745,36 @@ module FiscalRail
|
|
|
3575
3745
|
"$ref": "#/components/schemas/PaymentInstruction"
|
|
3576
3746
|
}
|
|
3577
3747
|
}
|
|
3748
|
+
},
|
|
3749
|
+
"uploadAccountCertificate": {
|
|
3750
|
+
"method": "POST",
|
|
3751
|
+
"path": "/account/tax-regime/es/certificate",
|
|
3752
|
+
"parameters": [],
|
|
3753
|
+
"responses": {
|
|
3754
|
+
"202": {
|
|
3755
|
+
"$ref": "#/components/schemas/AccountTaxRegime"
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
},
|
|
3759
|
+
"verifyAccountRepresentation": {
|
|
3760
|
+
"method": "POST",
|
|
3761
|
+
"path": "/account/tax-regime/es/representation/verify",
|
|
3762
|
+
"parameters": [],
|
|
3763
|
+
"responses": {
|
|
3764
|
+
"202": {
|
|
3765
|
+
"$ref": "#/components/schemas/AccountTaxRegime"
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
},
|
|
3769
|
+
"verifyAccountSubmission": {
|
|
3770
|
+
"method": "POST",
|
|
3771
|
+
"path": "/account/tax-regime/es/submission/verify",
|
|
3772
|
+
"parameters": [],
|
|
3773
|
+
"responses": {
|
|
3774
|
+
"202": {
|
|
3775
|
+
"$ref": "#/components/schemas/AccountTaxRegime"
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3578
3778
|
}
|
|
3579
3779
|
}
|
|
3580
3780
|
}
|
|
@@ -6,12 +6,8 @@ module FiscalRail
|
|
|
6
6
|
class Account < Model
|
|
7
7
|
def address = self["address"]
|
|
8
8
|
def created_at = self["created_at"]
|
|
9
|
-
def default_payment_instructions = self["default_payment_instructions"]
|
|
10
|
-
def default_series = self["default_series"]
|
|
11
9
|
def email = self["email"]
|
|
12
10
|
def id = self["id"]
|
|
13
|
-
def invoice_locale = self["invoice_locale"]
|
|
14
|
-
def invoice_numbering_scope = self["invoice_numbering_scope"]
|
|
15
11
|
def live = self["live"]
|
|
16
12
|
def name = self["name"]
|
|
17
13
|
def object = self["object"]
|
|
@@ -28,12 +24,23 @@ module FiscalRail
|
|
|
28
24
|
def invoice = self["invoice"]
|
|
29
25
|
end
|
|
30
26
|
|
|
31
|
-
class
|
|
32
|
-
def
|
|
33
|
-
def
|
|
27
|
+
class AccountInvoicing < Model
|
|
28
|
+
def default_payment_instructions = self["default_payment_instructions"]
|
|
29
|
+
def default_series = self["default_series"]
|
|
30
|
+
def footer = self["footer"]
|
|
31
|
+
def locale = self["locale"]
|
|
32
|
+
def numbering_scope = self["numbering_scope"]
|
|
34
33
|
def object = self["object"]
|
|
35
34
|
end
|
|
36
35
|
|
|
36
|
+
class AccountInvoicingUpdate < Model
|
|
37
|
+
def default_payment_instructions = self["default_payment_instructions"]
|
|
38
|
+
def default_series = self["default_series"]
|
|
39
|
+
def footer = self["footer"]
|
|
40
|
+
def locale = self["locale"]
|
|
41
|
+
def numbering_scope = self["numbering_scope"]
|
|
42
|
+
end
|
|
43
|
+
|
|
37
44
|
class AccountNotConfiguredError < Model
|
|
38
45
|
def code = self["code"]
|
|
39
46
|
def message = self["message"]
|
|
@@ -45,9 +52,9 @@ module FiscalRail
|
|
|
45
52
|
|
|
46
53
|
class AccountUpdate < Model
|
|
47
54
|
def address = self["address"]
|
|
48
|
-
def
|
|
49
|
-
def
|
|
50
|
-
def
|
|
55
|
+
def email = self["email"]
|
|
56
|
+
def name = self["name"]
|
|
57
|
+
def phone = self["phone"]
|
|
51
58
|
end
|
|
52
59
|
|
|
53
60
|
class Address < Model
|
|
@@ -586,6 +593,15 @@ module FiscalRail
|
|
|
586
593
|
def verified_at = self["verified_at"]
|
|
587
594
|
end
|
|
588
595
|
|
|
596
|
+
class SpanishAccountSubmission < Model
|
|
597
|
+
def certificate_expires_at = self["certificate_expires_at"]
|
|
598
|
+
def error_code = self["error_code"]
|
|
599
|
+
def kind = self["kind"]
|
|
600
|
+
def last_checked_at = self["last_checked_at"]
|
|
601
|
+
def ready = self["ready"]
|
|
602
|
+
def status = self["status"]
|
|
603
|
+
end
|
|
604
|
+
|
|
589
605
|
class SpanishAccountTaxRegime < Model
|
|
590
606
|
def account = self["account"]
|
|
591
607
|
def es = self["es"]
|
|
@@ -594,7 +610,9 @@ module FiscalRail
|
|
|
594
610
|
end
|
|
595
611
|
|
|
596
612
|
class SpanishAccountTaxRegimeDetails < Model
|
|
613
|
+
def pending_submission = self["pending_submission"]
|
|
597
614
|
def representation = self["representation"]
|
|
615
|
+
def submission = self["submission"]
|
|
598
616
|
end
|
|
599
617
|
|
|
600
618
|
class SpanishInvoiceQr < Model
|
|
@@ -612,6 +630,29 @@ module FiscalRail
|
|
|
612
630
|
def verifactu = self["verifactu"]
|
|
613
631
|
end
|
|
614
632
|
|
|
633
|
+
class SpanishPendingSubmission < Model
|
|
634
|
+
def certificate_expires_at = self["certificate_expires_at"]
|
|
635
|
+
def error_code = self["error_code"]
|
|
636
|
+
def kind = self["kind"]
|
|
637
|
+
def last_checked_at = self["last_checked_at"]
|
|
638
|
+
def status = self["status"]
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
class SubmissionConfigurationError < Model
|
|
642
|
+
def code = self["code"]
|
|
643
|
+
def details = self["details"]
|
|
644
|
+
def message = self["message"]
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
class SubmissionConfigurationErrorResponse < Model
|
|
648
|
+
def error = self["error"]
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
class SubmissionConfigurationValidationDetail < Model
|
|
652
|
+
def field = self["field"]
|
|
653
|
+
def message = self["message"]
|
|
654
|
+
end
|
|
655
|
+
|
|
615
656
|
class TaxId < Model
|
|
616
657
|
def country = self["country"]
|
|
617
658
|
def id = self["id"]
|
data/lib/fiscalrail/resource.rb
CHANGED
|
@@ -10,7 +10,7 @@ module FiscalRail
|
|
|
10
10
|
|
|
11
11
|
private
|
|
12
12
|
|
|
13
|
-
def request(operation_id, path: {}, params: {}, body: nil, retry_safe: false, idempotency_key: nil, headers: {}, binary: false)
|
|
13
|
+
def request(operation_id, path: {}, params: {}, body: nil, multipart: nil, retry_safe: false, idempotency_key: nil, headers: {}, binary: false)
|
|
14
14
|
operation = Generated::OPERATIONS.fetch(operation_id)
|
|
15
15
|
route = operation.fetch("path").gsub(/\{([^}]+)\}/) do
|
|
16
16
|
value = path.fetch(Regexp.last_match(1).to_sym)
|
|
@@ -20,7 +20,7 @@ module FiscalRail
|
|
|
20
20
|
end
|
|
21
21
|
headers = headers.merge("Accept" => "application/pdf") if binary
|
|
22
22
|
response = @transport.request(method: operation.fetch("method"), path: route, params: params,
|
|
23
|
-
body: body, retry_safe: retry_safe, idempotency_key: idempotency_key, headers: headers)
|
|
23
|
+
body: body, multipart: multipart, retry_safe: retry_safe, idempotency_key: idempotency_key, headers: headers)
|
|
24
24
|
metadata = { request_id: response.headers["request-id"], idempotent_replayed: response.headers["idempotent-replayed"], idempotency_key: idempotency_key }
|
|
25
25
|
unless operation.fetch("responses").key?(response.status.to_s)
|
|
26
26
|
raise ResponseParseError.new("unexpected HTTP #{response.status}", model: operation_id, field: "$", **metadata.slice(:request_id, :idempotency_key))
|
|
@@ -3,28 +3,58 @@
|
|
|
3
3
|
module FiscalRail
|
|
4
4
|
module Resources
|
|
5
5
|
class Accounts < Resource
|
|
6
|
-
def
|
|
7
|
-
request("
|
|
6
|
+
def retrieve
|
|
7
|
+
request("retrieveAccount", retry_safe: true)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
request("
|
|
10
|
+
def update(**params)
|
|
11
|
+
request("updateAccount", body: params)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class AccountInvoicing < Resource
|
|
16
|
+
def retrieve
|
|
17
|
+
request("retrieveAccountInvoicing", retry_safe: true)
|
|
12
18
|
end
|
|
13
19
|
|
|
14
|
-
def update(
|
|
15
|
-
request("
|
|
20
|
+
def update(**params)
|
|
21
|
+
request("updateAccountInvoicing", body: params)
|
|
16
22
|
end
|
|
17
23
|
end
|
|
18
24
|
|
|
19
25
|
class Balances < Resource
|
|
20
|
-
def retrieve
|
|
21
|
-
request("retrieveBalance",
|
|
26
|
+
def retrieve
|
|
27
|
+
request("retrieveBalance", retry_safe: true)
|
|
22
28
|
end
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
class AccountTaxRegimes < Resource
|
|
26
|
-
def
|
|
27
|
-
|
|
32
|
+
def es
|
|
33
|
+
@es ||= SpanishSubmission.new(@transport)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def retrieve
|
|
37
|
+
request("retrieveAccountTaxRegime", retry_safe: true)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
class SpanishSubmission < Resource
|
|
41
|
+
def upload_certificate(certificate_file:, certificate_password: nil)
|
|
42
|
+
content = certificate_file.read(128 * 1024 + 1) || ""
|
|
43
|
+
raise ArgumentError, "certificate_file must be at most 128 KiB" if content.bytesize > 128 * 1024
|
|
44
|
+
|
|
45
|
+
request("uploadAccountCertificate", multipart: { certificate_file: content, certificate_password: certificate_password })
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def verify_representation
|
|
49
|
+
request("verifyAccountRepresentation")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def verify_submission
|
|
53
|
+
request("verifyAccountSubmission")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def cancel_submission_change
|
|
57
|
+
request("cancelAccountSubmissionChange")
|
|
28
58
|
end
|
|
29
59
|
end
|
|
30
60
|
end
|
data/lib/fiscalrail/transport.rb
CHANGED
|
@@ -4,6 +4,7 @@ require "net/http"
|
|
|
4
4
|
require "json"
|
|
5
5
|
require "uri"
|
|
6
6
|
require "thread"
|
|
7
|
+
require "securerandom"
|
|
7
8
|
|
|
8
9
|
module FiscalRail
|
|
9
10
|
# The adapter boundary also makes custom proxy/TLS/instrumentation possible.
|
|
@@ -63,7 +64,7 @@ module FiscalRail
|
|
|
63
64
|
@api_key, @base_url, @max_retries, @adapter, @sleeper = api_key, base_url.sub(%r{/+\z}, ""), max_retries, adapter, sleeper
|
|
64
65
|
end
|
|
65
66
|
|
|
66
|
-
def request(method:, path:, body: nil, params: {}, headers: {}, retry_safe:, idempotency_key: nil)
|
|
67
|
+
def request(method:, path:, body: nil, multipart: nil, params: {}, headers: {}, retry_safe:, idempotency_key: nil)
|
|
67
68
|
uri = URI("#{@base_url}#{path}")
|
|
68
69
|
query = Serialization.json_value(params.reject { |_, value| value.nil? })
|
|
69
70
|
uri.query = URI.encode_www_form(query) unless query.empty?
|
|
@@ -74,6 +75,17 @@ module FiscalRail
|
|
|
74
75
|
request_headers["Idempotency-Key"] = idempotency_key if idempotency_key
|
|
75
76
|
request_headers["Content-Type"] = "application/json" unless body.nil?
|
|
76
77
|
encoded = body.nil? ? nil : JSON.generate(Serialization.json_value(body))
|
|
78
|
+
if multipart
|
|
79
|
+
boundary = "fiscalrail-#{SecureRandom.hex(24)}"
|
|
80
|
+
request_headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
|
|
81
|
+
encoded = "--#{boundary}\r\nContent-Disposition: form-data; name=\"certificate_file\"; filename=\"certificate.p12\"\r\nContent-Type: application/x-pkcs12\r\n\r\n".b
|
|
82
|
+
encoded << multipart.fetch(:certificate_file).b << "\r\n".b
|
|
83
|
+
unless multipart[:certificate_password].nil?
|
|
84
|
+
encoded << "--#{boundary}\r\nContent-Disposition: form-data; name=\"certificate_password\"\r\n\r\n".b
|
|
85
|
+
encoded << multipart.fetch(:certificate_password).b << "\r\n".b
|
|
86
|
+
end
|
|
87
|
+
encoded << "--#{boundary}--\r\n".b
|
|
88
|
+
end
|
|
77
89
|
attempt = 0
|
|
78
90
|
loop do
|
|
79
91
|
begin
|
data/lib/fiscalrail/version.rb
CHANGED