@fleetless/contracts 6.3.0-next.1 → 6.3.0-next.2
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.
- package/artifacts/openapi.json +1 -1
- package/artifacts/routes.json +5 -3
- package/dist/billing.d.ts +5 -0
- package/dist/billing.js +8 -1
- package/dist/errors.js +4 -2
- package/dist/routes.js +12 -10
- package/package.json +1 -1
package/artifacts/openapi.json
CHANGED
|
@@ -9605,7 +9605,7 @@
|
|
|
9605
9605
|
}
|
|
9606
9606
|
}
|
|
9607
9607
|
},
|
|
9608
|
-
"description": "`available: false` when `MOLLIE_API_KEY` is not configured — this cloud takes no payments, and every
|
|
9608
|
+
"description": "`available: false` when `MOLLIE_API_KEY` is not configured — this cloud takes no payments, and every billing route that charges or opens a Mollie checkout answers `503 billing_unavailable` instead of acting; cancel, resume, the details and the VAT-ID check need no Mollie and answer normally. `account` is `null` before the org has ever checked out; the plan and its limits still come from `GET /api/org/plan` (#103) and are not repeated here."
|
|
9609
9609
|
}
|
|
9610
9610
|
},
|
|
9611
9611
|
"/api/billing/checkout": {
|
package/artifacts/routes.json
CHANGED
|
@@ -6495,7 +6495,7 @@
|
|
|
6495
6495
|
"tier_required"
|
|
6496
6496
|
],
|
|
6497
6497
|
"transport": "http",
|
|
6498
|
-
"notes": "`available: false` when `MOLLIE_API_KEY` is not configured — this cloud takes no payments, and every
|
|
6498
|
+
"notes": "`available: false` when `MOLLIE_API_KEY` is not configured — this cloud takes no payments, and every billing route that charges or opens a Mollie checkout answers `503 billing_unavailable` instead of acting; cancel, resume, the details and the VAT-ID check need no Mollie and answer normally. `account` is `null` before the org has ever checked out; the plan and its limits still come from `GET /api/org/plan` (#103) and are not repeated here."
|
|
6499
6499
|
},
|
|
6500
6500
|
{
|
|
6501
6501
|
"method": "POST",
|
|
@@ -6789,9 +6789,11 @@
|
|
|
6789
6789
|
"query": null,
|
|
6790
6790
|
"request": null,
|
|
6791
6791
|
"response": null,
|
|
6792
|
-
"errors": [
|
|
6792
|
+
"errors": [
|
|
6793
|
+
"rate_limited"
|
|
6794
|
+
],
|
|
6793
6795
|
"transport": "http",
|
|
6794
|
-
"notes": "**The body is never trusted**: it names only a payment id (`id=tr_…`, form-encoded, Mollie's own shape), and this route does nothing with it but call `reconcilePayment(deps, molliePaymentId)` — the same function `GET /api/billing/checkout/:id` and the hourly sweep call — which fetches the payment from Mollie itself and applies what Mollie says, idempotently. Rate limited on the `billing.webhook` bucket, per ip, 600/min — generous, because this is Mollie's own infrastructure calling, not a browser. **Every answer is `200`**, including an id this cloud does not recognise, which is logged and otherwise ignored, **except a processing fault, which is `500`** so Mollie retries the notification rather than this cloud losing it. `auth: 'none'` because Mollie signs nothing Fleetless checks here — the payment is only ever trusted once fetched back from Mollie's own API with the configured key."
|
|
6796
|
+
"notes": "**The body is never trusted**: it names only a payment id (`id=tr_…`, form-encoded, Mollie's own shape), and this route does nothing with it but call `reconcilePayment(deps, molliePaymentId)` — the same function `GET /api/billing/checkout/:id` and the hourly sweep call — which fetches the payment from Mollie itself and applies what Mollie says, idempotently. Rate limited on the `billing.webhook` bucket, per ip, 600/min — generous, because this is Mollie's own infrastructure calling, not a browser; over it the answer is `429 rate_limited`, and Mollie retries the notification later. **Every other answer is `200`**, including an id this cloud does not recognise, which is logged and otherwise ignored, **except a processing fault, which is `500`** so Mollie retries the notification rather than this cloud losing it. `auth: 'none'` because Mollie signs nothing Fleetless checks here — the payment is only ever trusted once fetched back from Mollie's own API with the configured key."
|
|
6795
6797
|
},
|
|
6796
6798
|
{
|
|
6797
6799
|
"method": "POST",
|
package/dist/billing.d.ts
CHANGED
|
@@ -174,6 +174,11 @@ export interface CheckoutQuote extends ChargeAmounts {
|
|
|
174
174
|
* The first charge of a checkout: one full period of `plan` + `addons`.
|
|
175
175
|
* One line for the plan, then one line per add-on actually bought
|
|
176
176
|
* (quantity 0 is omitted, not a zero-amount line).
|
|
177
|
+
*
|
|
178
|
+
* The VAT is rounded once, over the whole net amount, because that is what
|
|
179
|
+
* is charged. Rounding it per line can land a cent off that total, so the
|
|
180
|
+
* plan line absorbs the difference: the gross lines always add up to
|
|
181
|
+
* `gross_cents`, and the amount a person sees is the amount charged.
|
|
177
182
|
*/
|
|
178
183
|
export declare function checkoutQuote(input: {
|
|
179
184
|
plan: 'plus' | 'pro';
|
package/dist/billing.js
CHANGED
|
@@ -201,6 +201,11 @@ export function changeNetCents(input) {
|
|
|
201
201
|
* The first charge of a checkout: one full period of `plan` + `addons`.
|
|
202
202
|
* One line for the plan, then one line per add-on actually bought
|
|
203
203
|
* (quantity 0 is omitted, not a zero-amount line).
|
|
204
|
+
*
|
|
205
|
+
* The VAT is rounded once, over the whole net amount, because that is what
|
|
206
|
+
* is charged. Rounding it per line can land a cent off that total, so the
|
|
207
|
+
* plan line absorbs the difference: the gross lines always add up to
|
|
208
|
+
* `gross_cents`, and the amount a person sees is the amount charged.
|
|
204
209
|
*/
|
|
205
210
|
export function checkoutQuote(input) {
|
|
206
211
|
const { plan, addons, cycle, currency, rate_percent } = input;
|
|
@@ -218,7 +223,9 @@ export function checkoutQuote(input) {
|
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
225
|
const netCents = lines.reduce((sum, line) => sum + line.net_cents, 0);
|
|
221
|
-
|
|
226
|
+
const total = chargeAmounts(netCents, rate_percent);
|
|
227
|
+
lines[0].gross_cents += total.gross_cents - lines.reduce((sum, line) => sum + line.gross_cents, 0);
|
|
228
|
+
return { ...total, lines, rate_percent, currency, cycle };
|
|
222
229
|
}
|
|
223
230
|
/** Dunning after a failed renewal: retries on these days after the charge's due date. */
|
|
224
231
|
export const BILLING_RETRY_DAYS = [3, 7];
|
package/dist/errors.js
CHANGED
|
@@ -1042,8 +1042,10 @@ export const ERROR_CODES = [
|
|
|
1042
1042
|
// 2026-10-04 — billing through Mollie (#104).
|
|
1043
1043
|
/**
|
|
1044
1044
|
* `503`: this cloud takes no payments, because no payment provider is
|
|
1045
|
-
* configured — `MOLLIE_API_KEY` is unset. Every
|
|
1046
|
-
*
|
|
1045
|
+
* configured — `MOLLIE_API_KEY` is unset. Every billing route that
|
|
1046
|
+
* charges or opens a Mollie checkout answers it; the routes that need no
|
|
1047
|
+
* Mollie (cancel, resume, the details, the VAT-ID check) answer normally,
|
|
1048
|
+
* and `GET /api/billing` answers `200` with
|
|
1047
1049
|
* `available: false` instead, so a caller can render "billing is off"
|
|
1048
1050
|
* without parsing an error. An upgrade or an add-on is a request to
|
|
1049
1051
|
* Fleetless instead, exactly as it is today (#103's Feedback request).
|
package/dist/routes.js
CHANGED
|
@@ -99,8 +99,9 @@ const DEVELOPER_GUARD = ['unauthorized', 'token_expired', 'token_revoked'];
|
|
|
99
99
|
* billing's own infrastructure rather than from what the caller sent
|
|
100
100
|
* (2026-10-04, fleetless/fleetless#104): `BILLING_OFF` is no payment
|
|
101
101
|
* provider configured at all, `MOLLIE` is Mollie itself not
|
|
102
|
-
* answering. Every
|
|
103
|
-
* lists both; a route that only reads or edits local state lists neither
|
|
102
|
+
* answering. Every billing route that charges or opens a Mollie checkout
|
|
103
|
+
* lists both; a route that only reads or edits local state lists neither,
|
|
104
|
+
* and answers normally without a key.
|
|
104
105
|
*/
|
|
105
106
|
const BILLING_OFF = ['billing_unavailable'];
|
|
106
107
|
const MOLLIE = ['payment_provider_unavailable'];
|
|
@@ -2868,9 +2869,9 @@ export const ROUTES = [
|
|
|
2868
2869
|
* developer answers `403 tier_required` and `GET /api/billing`
|
|
2869
2870
|
* is no exception — a developer reads #103's plan cards from
|
|
2870
2871
|
* `GET /api/org/plan` instead, without the payer, payment method or
|
|
2871
|
-
* invoices
|
|
2872
|
-
* `payment_provider_unavailable`
|
|
2873
|
-
*
|
|
2872
|
+
* invoices. The routes that list `billing_unavailable` and
|
|
2873
|
+
* `payment_provider_unavailable` spread them from the `BILLING_OFF` and
|
|
2874
|
+
* `MOLLIE` constants near the top of this file.
|
|
2874
2875
|
*/
|
|
2875
2876
|
{
|
|
2876
2877
|
method: 'GET', path: '/api/billing', section: 'billing',
|
|
@@ -2878,8 +2879,9 @@ export const ROUTES = [
|
|
|
2878
2879
|
audience: 'developer', auth: 'developer', rateLimited: false, ownerTier: true, status: 200,
|
|
2879
2880
|
params: [], query: null, request: null, response: billingView,
|
|
2880
2881
|
errors: [...DEVELOPER_GUARD, 'tier_required'], transport: 'http',
|
|
2881
|
-
notes: '`available: false` when `MOLLIE_API_KEY` is not configured — this cloud takes no payments, and every
|
|
2882
|
-
'
|
|
2882
|
+
notes: '`available: false` when `MOLLIE_API_KEY` is not configured — this cloud takes no payments, and every billing route that ' +
|
|
2883
|
+
'charges or opens a Mollie checkout answers `503 billing_unavailable` instead of acting; cancel, resume, the details and the ' +
|
|
2884
|
+
'VAT-ID check need no Mollie and answer normally. `account` is `null` before the org has ever checked out; the plan ' +
|
|
2883
2885
|
'and its limits still come from `GET /api/org/plan` (#103) and are not repeated here.',
|
|
2884
2886
|
},
|
|
2885
2887
|
{
|
|
@@ -3013,12 +3015,12 @@ export const ROUTES = [
|
|
|
3013
3015
|
summary: "Takes Mollie's payment-changed notification and reconciles the payment.",
|
|
3014
3016
|
audience: 'internal', auth: 'none', rateLimited: true, ownerTier: false, status: 200,
|
|
3015
3017
|
params: [], query: null, request: null, response: null,
|
|
3016
|
-
errors: [], transport: 'http',
|
|
3018
|
+
errors: ['rate_limited'], transport: 'http',
|
|
3017
3019
|
notes: '**The body is never trusted**: it names only a payment id (`id=tr_…`, form-encoded, Mollie\'s own shape), and this route ' +
|
|
3018
3020
|
'does nothing with it but call `reconcilePayment(deps, molliePaymentId)` — the same function `GET /api/billing/checkout/:id` and ' +
|
|
3019
3021
|
'the hourly sweep call — which fetches the payment from Mollie itself and applies what Mollie says, idempotently. Rate limited on ' +
|
|
3020
|
-
'the `billing.webhook` bucket, per ip, 600/min — generous, because this is Mollie\'s own infrastructure calling, not a browser
|
|
3021
|
-
'**Every answer is `200`**, including an id this cloud does not recognise, which is logged and otherwise ignored, **except a ' +
|
|
3022
|
+
'the `billing.webhook` bucket, per ip, 600/min — generous, because this is Mollie\'s own infrastructure calling, not a browser; ' +
|
|
3023
|
+
'over it the answer is `429 rate_limited`, and Mollie retries the notification later. **Every other answer is `200`**, including an id this cloud does not recognise, which is logged and otherwise ignored, **except a ' +
|
|
3022
3024
|
'processing fault, which is `500`** so Mollie retries the notification rather than this cloud losing it. `auth: \'none\'` because ' +
|
|
3023
3025
|
'Mollie signs nothing Fleetless checks here — the payment is only ever trusted once fetched back from Mollie\'s own API with the ' +
|
|
3024
3026
|
'configured key.',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetless/contracts",
|
|
3
|
-
"version": "6.3.0-next.
|
|
3
|
+
"version": "6.3.0-next.2",
|
|
4
4
|
"description": "Fleetless wire contracts: the bridge-cloud protocol, the REST API schemas and the error codes, as zod schemas with generated JSON Schema and OpenAPI artifacts.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Dehne Robotik GmbH",
|