@ambushsoftworks/nestjs-payments-graphql 0.1.0 → 0.1.3
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 +100 -0
- package/LICENSE +21 -0
- package/README.md +612 -0
- package/dist/gateways/payment-gateway.interface.d.ts +7 -1
- package/dist/gateways/stripe/stripe-webhook.controller.js +4 -0
- package/dist/gateways/stripe/stripe-webhook.controller.js.map +1 -1
- package/dist/gateways/stripe/stripe.gateway.d.ts +2 -2
- package/dist/gateways/stripe/stripe.gateway.js +6 -2
- package/dist/gateways/stripe/stripe.gateway.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/services/payment.service.js +6 -0
- package/dist/services/payment.service.js.map +1 -1
- package/package.json +41 -2
- package/prisma/payment-models.prisma +504 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.3] - 2026-05-15
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **`NormalizedWebhookEvent` / `IgnoredWebhookEvent` types** exported from the package root. `PaymentGateway.handleWebhook` now returns the discriminated union; the `'ignored'` variant signals "received but no action needed" so the webhook controller responds 200 instead of 400 + Stripe retry loop. See "Stripe Gateway & Webhooks" in the README.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- **Stripe webhook controller now responds 200 for unrecognized Stripe event types** (e.g. `payment_intent.created`, `charge.updated`, `charge.succeeded`). Previously it threw inside the gateway's `normalizeWebhookEvent` and the controller's signature-verification try/catch re-threw as `BadRequestException('Webhook signature verification failed')`, causing Stripe to retry the delivery for ~3 days and filling logs with misleading "signature verification failed" messages. The new behavior matches Stripe's documented contract: log unrecognized events at `debug`, acknowledge with 200. Real signature failures are unchanged (still 400 with the correct error message).
|
|
17
|
+
- **`PaymentService` now logs a WARN when a SUCCEEDED payment lands on an invoice in a non-payable status** (DRAFT, VOID, PAID, REFUNDED, …). Previously this was a silent skip — the consumer's card was charged but the invoice never updated. Affects both `handlePaymentSucceeded` (webhook path) and `reconcilePayment` (reconciliation scheduler path). Most commonly hit when a consumer creates a DRAFT invoice and starts checkout without first calling `InvoiceService.sendInvoice` to transition it to SENT.
|
|
18
|
+
- **`PaymentGateway.handleWebhook` return type widened from `Promise<PaymentWebhookEvent>` to `Promise<NormalizedWebhookEvent>`** to express the new `'ignored'` variant. TypeScript covariance: existing custom-gateway implementations whose `handleWebhook` is declared as `Promise<PaymentWebhookEvent>` continue to satisfy the interface without modification (no TS error). Callers who destructure the return value should add a guard on the discriminator (`if (event.type === 'ignored') return;`) before accessing `PaymentWebhookEvent`-only fields.
|
|
19
|
+
|
|
20
|
+
## [0.1.2] - 2026-04-19
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- **CI publish pipeline** — switched the publish job to `node:24`, which ships with npm 11.x and supports OIDC trusted publishing natively. The previous config ran `npm install -g npm@latest` on top of node:22's bundled npm 10.9.x, which failed with `MODULE_NOT_FOUND: promise-retry` during npm's self-upgrade. 0.1.2 is the first version since 0.1.0 to actually land on the npm registry.
|
|
24
|
+
|
|
25
|
+
0.1.2 contains all the 0.1.1 content — README, CHANGELOG, CONTRIBUTING, LICENSE, `prisma/payment-models.prisma`, Jest config and tests, and the `package.json` metadata additions.
|
|
26
|
+
|
|
27
|
+
## [0.1.1] - 2026-04-19
|
|
28
|
+
|
|
29
|
+
> **Note:** Tagged in git but never published to npm — the CI publish stage failed on an upstream `npm install -g npm@latest` self-upgrade bug. Superseded by 0.1.2 with an identical feature set.
|
|
30
|
+
|
|
31
|
+
Docs and tooling release. No runtime code changed — compiled `dist/` output is identical to 0.1.0.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- `README.md` — full public-facing documentation (design principles, install, quick-start, features, configuration reference, reserved GraphQL type names, exception table, critical integration requirements, local development workflow).
|
|
35
|
+
- `CHANGELOG.md`, `CONTRIBUTING.md`, `LICENSE` (MIT).
|
|
36
|
+
- `prisma/payment-models.prisma` — documentation-only reference schema shipped inside the package tarball. Covers every model and enum (core, payment plans, recurring invoices, payment customers, webhook idempotency). Consumer-owned relations marked `// CONSUMER:` for easy copy-paste into a host `schema.prisma`.
|
|
37
|
+
- Jest configuration (inline in `package.json`) and the first test suites: `recurring-interval.util.spec.ts` (19 cases covering DAYS/MONTHS math, month-end clamp, leap years, year rollover, round-tripping with `computeCycleCount`) and `invoice-number.service.spec.ts` (7 cases covering first-number, increment, zero-padding past 10k, unparseable-max fallback, and global numbering across divisions). `.gitlab-ci.yml`'s `test` stage now exercises real code instead of silently passing.
|
|
38
|
+
- `package.json` metadata: `keywords`, `homepage`, `bugs` URL. `CHANGELOG.md` added to `files[]`.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- `.gitignore` now excludes `*.tsbuildinfo` (TypeScript incremental build cache was previously tracked by accident) and `docs/archive/` (local-only planning docs).
|
|
42
|
+
|
|
43
|
+
## [0.1.0] - 2026-04-19
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
Initial public release. Extracted from the Ariadne monorepo (`apps/api/src/payments/core/`) into a standalone, ORM-agnostic NestJS package.
|
|
48
|
+
|
|
49
|
+
#### Core features
|
|
50
|
+
|
|
51
|
+
- **Invoicing** — `InvoiceService` creates DRAFT invoices with optional line items, tax rate resolution, metadata, and globally unique invoice numbers (via `InvoiceNumberService` with retry-on-collision).
|
|
52
|
+
- **Payments** — `PaymentService` records manual payments, online/Stripe payments, and e-transfer payments. Uses row-level locking and sum-of-pending-confirmation checks to prevent over-payment.
|
|
53
|
+
- **Refunds** — `RefundService` supports full and partial refunds, Stripe-backed and manual, with automatic invoice status transitions.
|
|
54
|
+
- **Payment plans** — `PaymentPlanService` splits invoices into installments with per-installment due dates and status tracking.
|
|
55
|
+
- **Recurring invoices** — `RecurringInvoiceService` auto-generates invoices on a schedule with anchor-date interval math (`DAYS`/`MONTHS`), optional auto-charge via stored `PaymentCustomer`, and consecutive-failure auto-pause.
|
|
56
|
+
- **E-transfer** — `ETransferService` generates prefixed codes + security answers and GraphQL instructions for Canadian Interac e-transfer flows.
|
|
57
|
+
- **Composable email notifications** — `IPaymentEmailSender` + `IPaymentEmailTemplateRenderer` + `IPaymentEmailBrandingResolver` + `IPaymentClientResolver`. Ships `StaticBrandingResolver` and `DefaultPaymentEmailTemplateRenderer`.
|
|
58
|
+
- **Event listeners** — consumer-registered `IPaymentEventListener` with hooks for `onInvoicePaid`, `onInvoiceRefunded`, `onRecurringInvoiceGenerated`, `onRecurringPaymentFailed`, `onRecurringInvoicePaused`. Event payloads include invoice metadata and full line items.
|
|
59
|
+
|
|
60
|
+
#### Stripe integration
|
|
61
|
+
|
|
62
|
+
- Bundled `StripeGateway` plus `StripeWebhookController` mounted at `POST /webhooks/stripe`.
|
|
63
|
+
- `@PaymentsWebhook()` decorator (also sets `isPublic` + `skipTenant` metadata) and `PAYMENTS_WEBHOOK` string constant for consumer auth-guard exemption.
|
|
64
|
+
- Webhook idempotency via `IWebhookIdempotencyRepository`.
|
|
65
|
+
- Signature verification requires `rawBody: true` in `NestFactory.create()`.
|
|
66
|
+
- Payment-succeeded retry loop (3 attempts, 2s delay) for out-of-order webhook deliveries.
|
|
67
|
+
- Optional `webhook.errorReporter` hook for Sentry/GlitchTip/etc.
|
|
68
|
+
- `stripe@^17.0.0` bundled as a hard dependency.
|
|
69
|
+
|
|
70
|
+
#### Module & DI
|
|
71
|
+
|
|
72
|
+
- `PaymentsModule.forRootAsync()` dynamic module registered as `global: true`.
|
|
73
|
+
- Instance-based DI for all repositories and adapters.
|
|
74
|
+
- Startup validation throws when feature flags are enabled without their backing repositories or config.
|
|
75
|
+
- All tokens are exported as `Symbol` constants (`INVOICE_REPOSITORY`, `PAYMENT_REPOSITORY`, `TRANSACTION_MANAGER`, …).
|
|
76
|
+
- Internal services use `ModuleRef.get()` instead of `@Optional() @Inject()` to work around a NestJS DI bug affecting optional tokens with `forwardRef()` imports.
|
|
77
|
+
|
|
78
|
+
#### GraphQL types
|
|
79
|
+
|
|
80
|
+
- 17 `@ObjectType` classes, 8 `@registerEnumType` enums, and 15+ `@InputType` classes exported. Enums are registered as a side effect of importing `PaymentsModule` — consumers must not re-register them.
|
|
81
|
+
|
|
82
|
+
#### Exceptions
|
|
83
|
+
|
|
84
|
+
- Domain exceptions (`InvalidInvoiceStateException`, `PaymentAmountExceededException`, `PaymentGatewayException`, `DuplicatePaymentException`, `InvoiceNotPayableException`, `InvoiceNumberExhaustedException`, `RefundNotAllowedException`, `InvalidPaymentStateException`, `InvalidRecurringInvoiceStateException`, `UniqueConstraintViolationException`) all extend `PaymentException` with stable `.code` strings.
|
|
85
|
+
|
|
86
|
+
#### Utilities
|
|
87
|
+
|
|
88
|
+
- `computeNextInvoiceDate` / `computeCycleCount` — anchor-based recurring-interval math.
|
|
89
|
+
- `StaticBrandingResolver` — single-tenant branding resolver.
|
|
90
|
+
- `DefaultPaymentEmailTemplateRenderer` — responsive inline-styled email HTML.
|
|
91
|
+
|
|
92
|
+
### CI/CD
|
|
93
|
+
|
|
94
|
+
- GitLab pipeline at `.gitlab-ci.yml`.
|
|
95
|
+
- `test` stage runs on merge requests and tags.
|
|
96
|
+
- `publish` stage runs on git tags, publishing to npm via OIDC provenance (`npm publish --provenance --access public`). No static npm token required.
|
|
97
|
+
|
|
98
|
+
### Infrastructure
|
|
99
|
+
|
|
100
|
+
- Currently running in production on the Ariadne API (Railway deployment, consumes `@ambushsoftworks/nestjs-payments-graphql@^0.1.0` from npm).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ambush Softworks
|
|
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 all
|
|
13
|
+
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 THE
|
|
21
|
+
SOFTWARE.
|