@crvouga/mockingbird-service-paddle 2.1.0 → 2.3.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.
- package/CHANGELOG.md +16 -0
- package/DISCOVERY.md +2 -2
- package/README.md +18 -18
- package/SUPPORT.md +3 -3
- package/dist/{chunk-RX7CMM47.js → chunk-TQ4AJYOC.js} +260 -172
- package/dist/chunk-TQ4AJYOC.js.map +7 -0
- package/dist/{chunk-VDA33BHD.js → chunk-XSOS4D65.js} +8 -6
- package/dist/chunk-XSOS4D65.js.map +7 -0
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +84 -69
- package/dist/index.js +1 -1
- package/dist/server.d.ts +129 -96
- package/dist/server.js +2 -2
- package/openapi.yaml +4 -4
- package/package.json +4 -4
- package/dist/chunk-RX7CMM47.js.map +0 -7
- package/dist/chunk-VDA33BHD.js.map +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-paddle
|
|
2
2
|
|
|
3
|
+
## 2.3.0 (2026-10-09)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- match Emulate provider coverage ([16b65ce](https://github.com/crvouga/mockingbird/commit/16b65ce791fa216f28ec1521df636f57771d9c5e))
|
|
8
|
+
|
|
9
|
+
### Dependencies
|
|
10
|
+
|
|
11
|
+
- `@crvouga/mockingbird-service-sqlite`
|
|
12
|
+
|
|
13
|
+
## 2.2.0 (2026-10-08)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
- redesign emulator experience ([d6038c2](https://github.com/crvouga/mockingbird/commit/d6038c27eebbaa1751f02bc9305002a5b1304779))
|
|
18
|
+
|
|
3
19
|
## 2.1.0 (2026-10-07)
|
|
4
20
|
|
|
5
21
|
### Features
|
package/DISCOVERY.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @crvouga/mockingbird-service-paddle discovery
|
|
2
2
|
|
|
3
3
|
This is the installed-package index for coding agents and tooling. All relative links resolve
|
|
4
|
-
inside `node_modules/@crvouga/mockingbird-service-paddle/`; no repository checkout is needed to discover the
|
|
4
|
+
inside `node_modules/@crvouga/mockingbird-service-paddle/`; no repository checkout is needed to discover the emulator's
|
|
5
5
|
supported surface or documented behavior.
|
|
6
6
|
|
|
7
7
|
## Capability and behavior sources
|
|
@@ -48,7 +48,7 @@ designed for assertions and diagnosis by consuming test suites.
|
|
|
48
48
|
## Report a mismatch or missing capability
|
|
49
49
|
|
|
50
50
|
Follow the [agent reporting contract](https://github.com/crvouga/mockingbird/blob/main/docs/REPORTING_ISSUES.md). Include package version,
|
|
51
|
-
operation/command, a minimal redacted request, actual
|
|
51
|
+
operation/command, a minimal redacted request, actual emulator result, expected oracle result or vendor
|
|
52
52
|
documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
|
|
53
53
|
customer data, prompts, PHI, card data, or unredacted recordings.
|
|
54
54
|
|
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# @crvouga/mockingbird-service-paddle
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Local emulators. Real API contracts. Part of [Mockingbird](https://github.com/crvouga/mockingbird).
|
|
4
4
|
|
|
5
|
-
Stateful
|
|
5
|
+
Stateful emulator of the **Paddle Billing** API for test suites. Customers, addresses, businesses,
|
|
6
6
|
products and prices behave as Paddle's do (validation, `invalid_field` errors, `include=`,
|
|
7
7
|
cursor pagination). Transactions carry **computed totals**. Subscriptions are created the way
|
|
8
|
-
Paddle creates them, when a transaction with recurring prices is paid, and the
|
|
8
|
+
Paddle creates them, when a transaction with recurring prices is paid, and the emulator's admin
|
|
9
9
|
routes stand in for the hosted checkout and the billing engine: **pay a transaction, complete a
|
|
10
10
|
checkout in one call, run a renewal, fail a payment**. Every change produces the event Paddle
|
|
11
11
|
would emit, listed at `GET /events` and delivered as a `Paddle-Signature` webhook that the
|
|
@@ -28,7 +28,7 @@ any Fetch server.
|
|
|
28
28
|
## Usage
|
|
29
29
|
|
|
30
30
|
The SDK maps `environment` to a base URL and otherwise uses the value verbatim, so point it at
|
|
31
|
-
the
|
|
31
|
+
the emulator by passing the emulator's URL as the environment. Give the app the same `pdl_ntfset_…`
|
|
32
32
|
secret as `--webhook-secret`.
|
|
33
33
|
|
|
34
34
|
```bash
|
|
@@ -43,9 +43,9 @@ PADDLE_API_BASE_URL=http://127.0.0.1:8795 node app.js
|
|
|
43
43
|
import { createServer } from "@crvouga/mockingbird-service-paddle/server"
|
|
44
44
|
import { Paddle } from "@paddle/paddle-node-sdk"
|
|
45
45
|
|
|
46
|
-
const
|
|
47
|
-
// In TypeScript: `{ environment:
|
|
48
|
-
const paddle = new Paddle("pdl_sdbx_apikey_test", { environment:
|
|
46
|
+
const emulator = await createServer({ paymentLink: "https://pay.example.com/checkout" })
|
|
47
|
+
// In TypeScript: `{ environment: emulator.url as Environment }`.
|
|
48
|
+
const paddle = new Paddle("pdl_sdbx_apikey_test", { environment: emulator.url })
|
|
49
49
|
|
|
50
50
|
const product = await paddle.products.create({ name: "Pro plan", taxCategory: "saas" })
|
|
51
51
|
const price = await paddle.prices.create({
|
|
@@ -64,11 +64,11 @@ const transaction = await paddle.transactions.create({
|
|
|
64
64
|
// transaction.status === "ready", transaction.details.totals.grandTotal === "5800",
|
|
65
65
|
// transaction.checkout.url === "https://pay.example.com/checkout?_ptxn=txn_…"
|
|
66
66
|
|
|
67
|
-
// The customer pays on the hosted checkout: the
|
|
68
|
-
await fetch(`${
|
|
67
|
+
// The customer pays on the hosted checkout: the emulator's admin route stands in for it.
|
|
68
|
+
await fetch(`${emulator.url}/__admin/transactions/${transaction.id}/pay`, { method: "POST" })
|
|
69
69
|
const [subscription] = await paddle.subscriptions.list({ customerId: [customer.id] }).next()
|
|
70
70
|
// subscription.status === "active", subscription.nextBilledAt one month out
|
|
71
|
-
await
|
|
71
|
+
await emulator.close()
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
Without the SDK, the same over HTTP:
|
|
@@ -76,18 +76,18 @@ Without the SDK, the same over HTTP:
|
|
|
76
76
|
```ts
|
|
77
77
|
import { createServer } from "@crvouga/mockingbird-service-paddle/server"
|
|
78
78
|
|
|
79
|
-
const
|
|
79
|
+
const emulator = await createServer({ fixtures: true })
|
|
80
80
|
const headers = { authorization: "Bearer pdl_sdbx_apikey_test", "content-type": "application/json" }
|
|
81
|
-
const { data: products } = await (await fetch(`${
|
|
81
|
+
const { data: products } = await (await fetch(`${emulator.url}/products?include=prices`, { headers })).json()
|
|
82
82
|
const checkout = await (
|
|
83
|
-
await fetch(`${
|
|
83
|
+
await fetch(`${emulator.url}/__admin/checkout`, {
|
|
84
84
|
method: "POST",
|
|
85
85
|
headers,
|
|
86
86
|
body: JSON.stringify({ email: "new@example.com", items: [{ price_id: products[0].prices[0].id }] }),
|
|
87
87
|
})
|
|
88
88
|
).json()
|
|
89
89
|
// checkout.transaction.status === "completed", checkout.subscription.status === "active"
|
|
90
|
-
await
|
|
90
|
+
await emulator.close()
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
### Routes
|
|
@@ -112,7 +112,7 @@ transactions 30; more than the maximum gets the maximum, as Paddle documents) an
|
|
|
112
112
|
| `PATCH /transactions/{id}` | `draft` and `ready` transactions take every create field again (totals are recomputed); `billed` and `past_due` ones only `{status: "canceled"}`; anything else is 400 `transaction_immutable`. |
|
|
113
113
|
| `POST /transactions/preview` | Totals for `{items, customer_id?, address_id?, currency_code?, address?: {country_code}}` without storing anything (non-catalog `price` objects are priced, not created); `include_in_totals: false` items are listed, not summed. |
|
|
114
114
|
| `GET /transactions/{id}/invoice` | `{url}` for `billed`, `paid` and `completed` transactions; else 400 `transaction_invoice_not_available`. |
|
|
115
|
-
| `GET /subscriptions`, `GET /subscriptions/{id}` | Filters: `id`, `customer_id`, `address_id`, `price_id`, `status`, `collection_mode`, `scheduled_change_action`; `include=next_transaction,recurring_transaction_details` embeds the previews. `management_urls` are placeholder links on the
|
|
115
|
+
| `GET /subscriptions`, `GET /subscriptions/{id}` | Filters: `id`, `customer_id`, `address_id`, `price_id`, `status`, `collection_mode`, `scheduled_change_action`; `include=next_transaction,recurring_transaction_details` embeds the previews. `management_urls` are placeholder links on the emulator's origin. |
|
|
116
116
|
| `PATCH /subscriptions/{id}` | `custom_data`, `next_billed_at`, `collection_mode` + `billing_details`, `customer_id`/`address_id`/`business_id`, `scheduled_change: null` (removes a scheduled pause or cancel), and `items` with a required `proration_billing_mode`: `*_immediately` modes bill what the change adds (new prices, quantity increases) in full at once as a `subscription_update` transaction, with no proration and no credit for what it removes; the other modes bill nothing now. Canceled subscriptions are 400 `subscription_update_when_canceled`. |
|
|
117
117
|
| `POST /subscriptions/{id}/activate` | `trialing` → `active`: bills the first period now and starts the billing cycle. |
|
|
118
118
|
| `POST /subscriptions/{id}/pause` | `{effective_from?: next_billing_period (default) \| immediately, resume_at?}`. Scheduled: `scheduled_change: {action: "pause", effective_at: next_billed_at}`. Immediate: `paused`, `paused_at`, no `next_billed_at`; with `resume_at` a `resume` change is scheduled. |
|
|
@@ -166,7 +166,7 @@ Types: `customer|address|business|product|price.created|updated`, `transaction.c
|
|
|
166
166
|
billed|paid|completed|canceled|payment_failed|past_due|updated`, `subscription.created|
|
|
167
167
|
activated|trialing|updated|paused|resumed|canceled|past_due`. Each delivery carries
|
|
168
168
|
`Paddle-Signature: ts=<unix seconds>;h1=<hex HMAC-SHA256(secret, "<ts>:<raw body>")>` with a
|
|
169
|
-
wall-clock `ts` (even when the
|
|
169
|
+
wall-clock `ts` (even when the emulator clock moves), which `paddle.webhooks.unmarshal(body,
|
|
170
170
|
secret, signature)` and `isSignatureValid` accept. Non-2xx answers are retried (immediately,
|
|
171
171
|
5 s, 5 min, 30 min, 2 h). `GET /__admin/webhooks`, `…/events`, `…/flush`, `…/:id/replay` and
|
|
172
172
|
`PUT /__admin/webhook-endpoints` (per-namespace receivers, `events: ["subscription.*"]`-style
|
|
@@ -212,8 +212,8 @@ map API keys to namespaces: `PUT /__admin/credentials {"credentials": {"<PADDLE_
|
|
|
212
212
|
|
|
213
213
|
| Export | Kind | Description |
|
|
214
214
|
| --- | --- | --- |
|
|
215
|
-
| `PaddleAPI` | class | The in-process
|
|
216
|
-
| `createRuntime` | function | The
|
|
215
|
+
| `PaddleAPI` | class | The in-process emulator: `fetch(request)`, `reset()`, `events()`, `state`, and the billing methods the admin routes call: `createCustomer`, `createAddress`, `createBusiness`, `createProduct`, `createPrice`, `createTransaction`, `payTransaction`, `checkout`, `renewSubscription`, `failPayment`, `seedFixtures`. Options: `sqlite`, `now`, `namespace`, `publicNamespace`, `paymentLink`, `onEvent`, `fixtures`. |
|
|
216
|
+
| `createRuntime` | function | The emulator with the full service contract (health, admin, namespaces, credentials, presets, `Paddle-Signature` webhooks, checkout and billing routes). Options: `webhooks: {url, secret, events?, retryDelaysMs?, fetch?}`, `paymentLink`, `fixtures`, `clock`, `seed`, `adminKey`, `onLog`, `sqlite`. |
|
|
217
217
|
| `paddleSigner` | function | The `Paddle-Signature` webhook signer (`ts=…;h1=…`). |
|
|
218
218
|
| `PADDLE_PRESETS` | object | Every named fault preset. |
|
|
219
219
|
| `PADDLE_NAMESPACE` | string | The service name, `"paddle"`. |
|
package/SUPPORT.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
Generated from `openapi.yaml`; do not edit by hand.
|
|
4
4
|
|
|
5
5
|
- operations in spec: **50**
|
|
6
|
-
- supported by the
|
|
6
|
+
- supported by the emulator: **42**
|
|
7
7
|
- parity enabled: **42**
|
|
8
8
|
|
|
9
|
-
| operationId | route |
|
|
9
|
+
| operationId | route | emulator | parity | notes |
|
|
10
10
|
| --- | --- | --- | --- | --- |
|
|
11
11
|
| `ListCustomers` | `GET /customers` | ✅ supported | ✅ | |
|
|
12
12
|
| `CreateCustomer` | `POST /customers` | ✅ supported | ⚠️ unsafe (opt-in) | |
|
|
@@ -47,7 +47,7 @@ Generated from `openapi.yaml`; do not edit by hand.
|
|
|
47
47
|
| `CancelSubscription` | `POST /subscriptions/{subscription_id}/cancel` | ✅ supported | ⚠️ unsafe (opt-in) | |
|
|
48
48
|
| `CreateSubscriptionCharge` | `POST /subscriptions/{subscription_id}/charge` | ✅ supported | ⚠️ unsafe (opt-in) | |
|
|
49
49
|
| `PreviewSubscriptionCharge` | `POST /subscriptions/{subscription_id}/charge/preview` | ❌ unsupported | — | One-time charge previews are not modelled; create the charge instead. |
|
|
50
|
-
| `GetSubscriptionPaymentMethodChangeTransaction` | `GET /subscriptions/{subscription_id}/update-payment-method-transaction` | ❌ unsupported | — | Payment method changes go through the hosted checkout, which the
|
|
50
|
+
| `GetSubscriptionPaymentMethodChangeTransaction` | `GET /subscriptions/{subscription_id}/update-payment-method-transaction` | ❌ unsupported | — | Payment method changes go through the hosted checkout, which the emulator does not serve. |
|
|
51
51
|
| `ListEvents` | `GET /events` | ✅ supported | ✅ | |
|
|
52
52
|
| `ListNotificationSettings` | `GET /notification-settings` | ✅ supported | ✅ | |
|
|
53
53
|
| `CreateNotificationSetting` | `POST /notification-settings` | ✅ supported | ⚠️ unsafe (opt-in) | |
|