punch-library 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.
- package/README.md +342 -0
- package/bin/punch.js +20 -0
- package/dist/app/health.controller.d.ts +5 -0
- package/dist/app/health.controller.js +29 -0
- package/dist/app/health.controller.js.map +1 -0
- package/dist/app.module.d.ts +4 -0
- package/dist/app.module.js +30 -0
- package/dist/app.module.js.map +1 -0
- package/dist/cli/punch.d.ts +2 -0
- package/dist/cli/punch.js +598 -0
- package/dist/cli/punch.js.map +1 -0
- package/dist/common/correlation-id.middleware.d.ts +12 -0
- package/dist/common/correlation-id.middleware.js +26 -0
- package/dist/common/correlation-id.middleware.js.map +1 -0
- package/dist/common/http-logging.interceptor.d.ts +7 -0
- package/dist/common/http-logging.interceptor.js +40 -0
- package/dist/common/http-logging.interceptor.js.map +1 -0
- package/dist/common/provider.constants.d.ts +1 -0
- package/dist/common/provider.constants.js +5 -0
- package/dist/common/provider.constants.js.map +1 -0
- package/dist/config/load-env.d.ts +1 -0
- package/dist/config/load-env.js +30 -0
- package/dist/config/load-env.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +23 -0
- package/dist/main.js.map +1 -0
- package/dist/payments/application/dto/cancel-payment.dto.d.ts +4 -0
- package/dist/payments/application/dto/cancel-payment.dto.js +26 -0
- package/dist/payments/application/dto/cancel-payment.dto.js.map +1 -0
- package/dist/payments/application/dto/capture-payment.dto.d.ts +7 -0
- package/dist/payments/application/dto/capture-payment.dto.js +42 -0
- package/dist/payments/application/dto/capture-payment.dto.js.map +1 -0
- package/dist/payments/application/dto/create-intent.dto.d.ts +10 -0
- package/dist/payments/application/dto/create-intent.dto.js +52 -0
- package/dist/payments/application/dto/create-intent.dto.js.map +1 -0
- package/dist/payments/application/dto/custom-operation.dto.d.ts +11 -0
- package/dist/payments/application/dto/custom-operation.dto.js +60 -0
- package/dist/payments/application/dto/custom-operation.dto.js.map +1 -0
- package/dist/payments/application/dto/payment-provider.dto.d.ts +4 -0
- package/dist/payments/application/dto/payment-provider.dto.js +23 -0
- package/dist/payments/application/dto/payment-provider.dto.js.map +1 -0
- package/dist/payments/application/dto/refund-payment.dto.d.ts +8 -0
- package/dist/payments/application/dto/refund-payment.dto.js +46 -0
- package/dist/payments/application/dto/refund-payment.dto.js.map +1 -0
- package/dist/payments/application/dto/webhook-dlq-item.dto.d.ts +3 -0
- package/dist/payments/application/dto/webhook-dlq-item.dto.js +21 -0
- package/dist/payments/application/dto/webhook-dlq-item.dto.js.map +1 -0
- package/dist/payments/application/dto/webhook-provider.dto.d.ts +4 -0
- package/dist/payments/application/dto/webhook-provider.dto.js +23 -0
- package/dist/payments/application/dto/webhook-provider.dto.js.map +1 -0
- package/dist/payments/application/payments-exception.filter.d.ts +4 -0
- package/dist/payments/application/payments-exception.filter.js +58 -0
- package/dist/payments/application/payments-exception.filter.js.map +1 -0
- package/dist/payments/application/payments.controller.d.ts +50 -0
- package/dist/payments/application/payments.controller.js +231 -0
- package/dist/payments/application/payments.controller.js.map +1 -0
- package/dist/payments/application/payments.service.d.ts +43 -0
- package/dist/payments/application/payments.service.js +169 -0
- package/dist/payments/application/payments.service.js.map +1 -0
- package/dist/payments/domain/errors.d.ts +30 -0
- package/dist/payments/domain/errors.js +64 -0
- package/dist/payments/domain/errors.js.map +1 -0
- package/dist/payments/domain/payment-gateway.port.d.ts +12 -0
- package/dist/payments/domain/payment-gateway.port.js +3 -0
- package/dist/payments/domain/payment-gateway.port.js.map +1 -0
- package/dist/payments/domain/payment.types.d.ts +77 -0
- package/dist/payments/domain/payment.types.js +3 -0
- package/dist/payments/domain/payment.types.js.map +1 -0
- package/dist/payments/domain/provider-name.d.ts +3 -0
- package/dist/payments/domain/provider-name.js +25 -0
- package/dist/payments/domain/provider-name.js.map +1 -0
- package/dist/payments/infrastructure/gateway-registry.d.ts +6 -0
- package/dist/payments/infrastructure/gateway-registry.js +10 -0
- package/dist/payments/infrastructure/gateway-registry.js.map +1 -0
- package/dist/payments/infrastructure/json-file-state.store.d.ts +11 -0
- package/dist/payments/infrastructure/json-file-state.store.js +52 -0
- package/dist/payments/infrastructure/json-file-state.store.js.map +1 -0
- package/dist/payments/infrastructure/payment-outbox.service.d.ts +15 -0
- package/dist/payments/infrastructure/payment-outbox.service.js +46 -0
- package/dist/payments/infrastructure/payment-outbox.service.js.map +1 -0
- package/dist/payments/infrastructure/payment-provider-resilience.service.d.ts +35 -0
- package/dist/payments/infrastructure/payment-provider-resilience.service.js +105 -0
- package/dist/payments/infrastructure/payment-provider-resilience.service.js.map +1 -0
- package/dist/payments/infrastructure/payment-webhook-dlq.service.d.ts +21 -0
- package/dist/payments/infrastructure/payment-webhook-dlq.service.js +75 -0
- package/dist/payments/infrastructure/payment-webhook-dlq.service.js.map +1 -0
- package/dist/payments/infrastructure/payment-webhook-idempotency.service.d.ts +9 -0
- package/dist/payments/infrastructure/payment-webhook-idempotency.service.js +46 -0
- package/dist/payments/infrastructure/payment-webhook-idempotency.service.js.map +1 -0
- package/dist/payments/infrastructure/provider-registry.service.d.ts +8 -0
- package/dist/payments/infrastructure/provider-registry.service.js +42 -0
- package/dist/payments/infrastructure/provider-registry.service.js.map +1 -0
- package/dist/payments/payments.module.d.ts +2 -0
- package/dist/payments/payments.module.js +73 -0
- package/dist/payments/payments.module.js.map +1 -0
- package/dist/payments/providers/adyen/adyen.gateway.d.ts +42 -0
- package/dist/payments/providers/adyen/adyen.gateway.js +233 -0
- package/dist/payments/providers/adyen/adyen.gateway.js.map +1 -0
- package/dist/payments/providers/base-gateway.d.ts +26 -0
- package/dist/payments/providers/base-gateway.js +200 -0
- package/dist/payments/providers/base-gateway.js.map +1 -0
- package/dist/payments/providers/braintree/braintree.gateway.d.ts +5 -0
- package/dist/payments/providers/braintree/braintree.gateway.js +23 -0
- package/dist/payments/providers/braintree/braintree.gateway.js.map +1 -0
- package/dist/payments/providers/checkout/checkout.gateway.d.ts +5 -0
- package/dist/payments/providers/checkout/checkout.gateway.js +23 -0
- package/dist/payments/providers/checkout/checkout.gateway.js.map +1 -0
- package/dist/payments/providers/hepsipay/hepsipay.gateway.d.ts +5 -0
- package/dist/payments/providers/hepsipay/hepsipay.gateway.js +23 -0
- package/dist/payments/providers/hepsipay/hepsipay.gateway.js.map +1 -0
- package/dist/payments/providers/iyzico/iyzico.gateway.d.ts +5 -0
- package/dist/payments/providers/iyzico/iyzico.gateway.js +23 -0
- package/dist/payments/providers/iyzico/iyzico.gateway.js.map +1 -0
- package/dist/payments/providers/paddle/paddle.gateway.d.ts +5 -0
- package/dist/payments/providers/paddle/paddle.gateway.js +23 -0
- package/dist/payments/providers/paddle/paddle.gateway.js.map +1 -0
- package/dist/payments/providers/parampos/parampos.gateway.d.ts +5 -0
- package/dist/payments/providers/parampos/parampos.gateway.js +23 -0
- package/dist/payments/providers/parampos/parampos.gateway.js.map +1 -0
- package/dist/payments/providers/paypal/paypal.gateway.d.ts +30 -0
- package/dist/payments/providers/paypal/paypal.gateway.js +266 -0
- package/dist/payments/providers/paypal/paypal.gateway.js.map +1 -0
- package/dist/payments/providers/paytr/paytr.gateway.d.ts +5 -0
- package/dist/payments/providers/paytr/paytr.gateway.js +23 -0
- package/dist/payments/providers/paytr/paytr.gateway.js.map +1 -0
- package/dist/payments/providers/provider-catalog.d.ts +12 -0
- package/dist/payments/providers/provider-catalog.js +156 -0
- package/dist/payments/providers/provider-catalog.js.map +1 -0
- package/dist/payments/providers/razorpay/razorpay.gateway.d.ts +5 -0
- package/dist/payments/providers/razorpay/razorpay.gateway.js +23 -0
- package/dist/payments/providers/razorpay/razorpay.gateway.js.map +1 -0
- package/dist/payments/providers/sipay/sipay.gateway.d.ts +5 -0
- package/dist/payments/providers/sipay/sipay.gateway.js +23 -0
- package/dist/payments/providers/sipay/sipay.gateway.js.map +1 -0
- package/dist/payments/providers/square/square.gateway.d.ts +27 -0
- package/dist/payments/providers/square/square.gateway.js +207 -0
- package/dist/payments/providers/square/square.gateway.js.map +1 -0
- package/dist/payments/providers/stripe/stripe.gateway.d.ts +22 -0
- package/dist/payments/providers/stripe/stripe.gateway.js +175 -0
- package/dist/payments/providers/stripe/stripe.gateway.js.map +1 -0
- package/dist/payments/providers/stub-gateway.d.ts +19 -0
- package/dist/payments/providers/stub-gateway.js +256 -0
- package/dist/payments/providers/stub-gateway.js.map +1 -0
- package/dist/payments/providers/twocheckout/twocheckout.gateway.d.ts +5 -0
- package/dist/payments/providers/twocheckout/twocheckout.gateway.js +23 -0
- package/dist/payments/providers/twocheckout/twocheckout.gateway.js.map +1 -0
- package/dist/payments/providers/worldpay/worldpay.gateway.d.ts +5 -0
- package/dist/payments/providers/worldpay/worldpay.gateway.js +23 -0
- package/dist/payments/providers/worldpay/worldpay.gateway.js.map +1 -0
- package/dist/payments/punch-client.d.ts +4 -0
- package/dist/payments/punch-client.js +8 -0
- package/dist/payments/punch-client.js.map +1 -0
- package/dist/payments/punch.d.ts +39 -0
- package/dist/payments/punch.js +109 -0
- package/dist/payments/punch.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +83 -0
package/README.md
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# punch-api
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<picture>
|
|
5
|
+
<source srcset="docs/assets/punch-library.png" type="image/png" />
|
|
6
|
+
<img src="docs/assets/punch-logo.svg" alt="Punch Library logo" width="700" />
|
|
7
|
+
</picture>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
Framework-agnostic payment orchestration library for Node.js with a `punch` CLI.
|
|
11
|
+
|
|
12
|
+
Documentation is powered by Docsify.
|
|
13
|
+
|
|
14
|
+
## Maintainer
|
|
15
|
+
|
|
16
|
+
- Name: Oguzhan Cart
|
|
17
|
+
- Website: `https://oguzhancart.dev`
|
|
18
|
+
- Email: `oguzhancart1@gmail.com`
|
|
19
|
+
- LinkedIn: `https://www.linkedin.com/in/o%C4%9Fuzhan-%C3%A7art-b73405199/`
|
|
20
|
+
- GitHub: `http://github.com/oguzhan18`
|
|
21
|
+
- Medium: `https://medium.com/@oguzhancart1`
|
|
22
|
+
- CodePen: `https://codepen.io/oguzhan1881`
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- Unified payment API across providers (`create/capture/cancel/refund`)
|
|
27
|
+
- Provider-level `custom-operation` API to access advanced provider endpoints beyond unified contract
|
|
28
|
+
- Provider catalog with payment/webhook documentation links
|
|
29
|
+
- Programmatic webhook parsing API (`parseWebhook`)
|
|
30
|
+
- Idempotency key support (`x-idempotency-key` or `idempotencyKey`)
|
|
31
|
+
- Correlation ID support (`x-correlation-id`) + structured HTTP logs
|
|
32
|
+
- Phase-3 platform controls:
|
|
33
|
+
- Provider rate limiting
|
|
34
|
+
- Provider circuit breaker
|
|
35
|
+
- Webhook idempotency handling
|
|
36
|
+
- Webhook dead-letter queue (DLQ)
|
|
37
|
+
- Outbox event store (memory or file)
|
|
38
|
+
- Stripe support:
|
|
39
|
+
- Payment intent creation
|
|
40
|
+
- Capture, cancel, refund
|
|
41
|
+
- Webhook signature verification (`stripe-signature`)
|
|
42
|
+
- PayPal support:
|
|
43
|
+
- OAuth2 token flow
|
|
44
|
+
- Order create/capture + capture refund
|
|
45
|
+
- Webhook signature verification (verify-webhook-signature API)
|
|
46
|
+
- Adyen support:
|
|
47
|
+
- Payment create/capture/cancel/refund
|
|
48
|
+
- Webhook signature verification (HMAC)
|
|
49
|
+
- Square support:
|
|
50
|
+
- Payment create/capture/cancel/refund
|
|
51
|
+
- Webhook signature verification
|
|
52
|
+
|
|
53
|
+
## Supported Providers
|
|
54
|
+
|
|
55
|
+
`stripe`, `paypal`, `adyen`, `square`, `braintree`, `checkout`, `worldpay`, `razorpay`, `paddle`, `twocheckout`, `iyzico`, `paytr`, `parampos`, `sipay`, `hepsipay`
|
|
56
|
+
|
|
57
|
+
## Current Status
|
|
58
|
+
|
|
59
|
+
Full live API + webhook support is not complete for all providers yet.
|
|
60
|
+
|
|
61
|
+
- Implemented: `stripe`, `paypal`, `adyen`, `square`
|
|
62
|
+
- Stub adapters: all other providers (visible in catalog)
|
|
63
|
+
|
|
64
|
+
## Setup
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm install
|
|
68
|
+
npm run build
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Run Docs (Docsify)
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm run docs:serve
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Then open:
|
|
78
|
+
- `http://localhost:3004`
|
|
79
|
+
|
|
80
|
+
## Library API
|
|
81
|
+
|
|
82
|
+
Instantiate the library:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { Punch } from 'punch-api';
|
|
86
|
+
|
|
87
|
+
const punch = new Punch({
|
|
88
|
+
exposeUnconfiguredProviders: false,
|
|
89
|
+
stateStoreMode: 'memory'
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Main methods:
|
|
94
|
+
|
|
95
|
+
- `listProviders()`
|
|
96
|
+
- `listCatalog()`
|
|
97
|
+
- `createIntent()` / `createPayment()`
|
|
98
|
+
- `capturePayment()`
|
|
99
|
+
- `cancelPayment()`
|
|
100
|
+
- `refundPayment()`
|
|
101
|
+
- `executeCustomOperation()`
|
|
102
|
+
- `parseWebhook()`
|
|
103
|
+
- `listOutbox()` / `clearOutbox()`
|
|
104
|
+
- `listWebhookDlq()` / `replayWebhookDlqItem()` / `clearWebhookDlq()`
|
|
105
|
+
- `resilienceSnapshot()`
|
|
106
|
+
|
|
107
|
+
Example intent payload:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"provider": "stripe",
|
|
112
|
+
"amount": 1000,
|
|
113
|
+
"currency": "TRY",
|
|
114
|
+
"idempotencyKey": "pay-create-ord-42",
|
|
115
|
+
"customerId": "cust_1",
|
|
116
|
+
"metadata": {
|
|
117
|
+
"orderId": "ORD-42"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Example custom operation payload:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"endpoint": "/payment_intents",
|
|
127
|
+
"method": "POST",
|
|
128
|
+
"bodyType": "form",
|
|
129
|
+
"idempotencyKey": "custom-op-42",
|
|
130
|
+
"body": {
|
|
131
|
+
"amount": 1000,
|
|
132
|
+
"currency": "usd",
|
|
133
|
+
"automatic_payment_methods[enabled]": true
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Environment Variables
|
|
139
|
+
|
|
140
|
+
- `PUNCH_STRIPE_API_KEY`
|
|
141
|
+
- `PUNCH_STRIPE_WEBHOOK_SECRET` (required for Stripe webhook verification)
|
|
142
|
+
- `PUNCH_PAYPAL_CLIENT_ID`, `PUNCH_PAYPAL_CLIENT_SECRET`, `PUNCH_PAYPAL_WEBHOOK_ID`
|
|
143
|
+
- `PUNCH_ADYEN_API_KEY`, `PUNCH_ADYEN_MERCHANT_ACCOUNT`
|
|
144
|
+
- `PUNCH_ADYEN_HMAC_KEY` (required for Adyen webhook verification)
|
|
145
|
+
- `PUNCH_SQUARE_API_KEY`, `PUNCH_SQUARE_LOCATION_ID`
|
|
146
|
+
- `PUNCH_SQUARE_WEBHOOK_SIGNATURE_KEY`, `PUNCH_SQUARE_WEBHOOK_NOTIFICATION_URL`
|
|
147
|
+
- `PUNCH_<PROVIDER>_API_KEY` for other providers
|
|
148
|
+
- Stub provider live mode (for `braintree`, `checkout`, `worldpay`, `razorpay`, `paddle`, `twocheckout`, `iyzico`, `paytr`, `parampos`, `sipay`, `hepsipay`):
|
|
149
|
+
- If API key includes `_mock_`, mock mode is used.
|
|
150
|
+
- If API key does not include `_mock_`, these are required:
|
|
151
|
+
- `PUNCH_<PROVIDER>_CREATE_ENDPOINT`
|
|
152
|
+
- `PUNCH_<PROVIDER>_CAPTURE_ENDPOINT`
|
|
153
|
+
- `PUNCH_<PROVIDER>_CANCEL_ENDPOINT`
|
|
154
|
+
- `PUNCH_<PROVIDER>_REFUND_ENDPOINT`
|
|
155
|
+
- Optional:
|
|
156
|
+
- `PUNCH_<PROVIDER>_AUTH_MODE` (`bearer|basic|api_key`)
|
|
157
|
+
- `PUNCH_<PROVIDER>_BASIC_USERNAME`, `PUNCH_<PROVIDER>_BASIC_PASSWORD`
|
|
158
|
+
- `PUNCH_<PROVIDER>_API_KEY_HEADER`
|
|
159
|
+
- `PUNCH_<PROVIDER>_IDEMPOTENCY_HEADER`
|
|
160
|
+
- `PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_REQUIRED`
|
|
161
|
+
- `PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_HEADER`
|
|
162
|
+
- `PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_SECRET`
|
|
163
|
+
- `PUNCH_<PROVIDER>_WEBHOOK_SIGNATURE_ALGORITHM`
|
|
164
|
+
- Optional base URLs for custom operation mode:
|
|
165
|
+
- `PUNCH_STRIPE_BASE_URL`
|
|
166
|
+
- `PUNCH_PAYPAL_BASE_URL`
|
|
167
|
+
- `PUNCH_ADYEN_BASE_URL`
|
|
168
|
+
- `PUNCH_SQUARE_BASE_URL`
|
|
169
|
+
- `PUNCH_CHECKOUT_BASE_URL`
|
|
170
|
+
- `PUNCH_WORLDPAY_BASE_URL`
|
|
171
|
+
- `PUNCH_RAZORPAY_BASE_URL`
|
|
172
|
+
- `PUNCH_PADDLE_BASE_URL`
|
|
173
|
+
- `PUNCH_IYZICO_BASE_URL`
|
|
174
|
+
- `PUNCH_PAYTR_BASE_URL`
|
|
175
|
+
- `PUNCH_BRAINTREE_BASE_URL`
|
|
176
|
+
- `PUNCH_TWOCHECKOUT_BASE_URL`
|
|
177
|
+
- `PUNCH_PARAMPOS_BASE_URL`
|
|
178
|
+
- `PUNCH_SIPAY_BASE_URL`
|
|
179
|
+
- `PUNCH_HEPSIPAY_BASE_URL`
|
|
180
|
+
- `PUNCH_EXPOSE_UNCONFIGURED_PROVIDERS=true` to expose unconfigured providers in API responses
|
|
181
|
+
- `PUNCH_RATE_LIMIT_WINDOW_MS`, `PUNCH_RATE_LIMIT_MAX`
|
|
182
|
+
- `PUNCH_CIRCUIT_FAILURE_THRESHOLD`, `PUNCH_CIRCUIT_OPEN_MS`
|
|
183
|
+
- `PUNCH_WEBHOOK_IDEMPOTENCY_TTL_MS`
|
|
184
|
+
- `PUNCH_WEBHOOK_MAX_ATTEMPTS`, `PUNCH_WEBHOOK_RETRY_DELAY_MS`
|
|
185
|
+
- `PUNCH_STATE_STORE_MODE` (`memory` or `file`)
|
|
186
|
+
- `PUNCH_STATE_STORE_DIR` (default `.punch-state`)
|
|
187
|
+
|
|
188
|
+
## CLI (Direct `punch ...` Usage)
|
|
189
|
+
|
|
190
|
+
Link the CLI once:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npm run cli:link
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Then use it directly:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
punch list
|
|
200
|
+
punch status
|
|
201
|
+
punch new stripe
|
|
202
|
+
punch new paypal --key=live_or_sandbox_key
|
|
203
|
+
punch remove stripe
|
|
204
|
+
punch doctor
|
|
205
|
+
punch doctor --fix
|
|
206
|
+
punch template stripe
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Disable CLI banner if needed:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
PUNCH_NO_BANNER=true punch status
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
CLI commands:
|
|
216
|
+
|
|
217
|
+
- `punch new <provider>`
|
|
218
|
+
- Creates/updates provider API key in `.env`
|
|
219
|
+
- Adds provider-specific extra keys for implemented providers (Stripe/PayPal/Adyen/Square)
|
|
220
|
+
- Updates `PUNCH_ENABLED_PROVIDERS`
|
|
221
|
+
- Creates/updates `punch.providers.json`
|
|
222
|
+
- `--key=...` to provide a custom API key
|
|
223
|
+
- `--no-enable` to skip enabling provider in `PUNCH_ENABLED_PROVIDERS`
|
|
224
|
+
- `punch status [--json]`
|
|
225
|
+
- Shows provider configuration status from `.env` and `punch.providers.json`
|
|
226
|
+
- `punch list [--json]`
|
|
227
|
+
- Lists provider, env key, and docs URL
|
|
228
|
+
- `punch remove <provider>`
|
|
229
|
+
- Removes provider key and enablement from `.env`
|
|
230
|
+
- Removes provider from `punch.providers.json`
|
|
231
|
+
- `punch doctor [--json]`
|
|
232
|
+
- Validates `.env` and `punch.providers.json` consistency
|
|
233
|
+
- Returns exit code `1` on critical errors
|
|
234
|
+
- `punch doctor --fix [--json]`
|
|
235
|
+
- Auto-creates missing `.env`
|
|
236
|
+
- Backfills `PUNCH_ENABLED_PROVIDERS` from `punch.providers.json` when missing
|
|
237
|
+
- Adds mock API keys for enabled providers that are missing keys
|
|
238
|
+
- Synchronizes `punch.providers.json` with `PUNCH_ENABLED_PROVIDERS`
|
|
239
|
+
- `punch template <provider> [--print]`
|
|
240
|
+
- Generates provider-specific custom operation templates
|
|
241
|
+
- Writes template to `punch.templates/<provider>.json`
|
|
242
|
+
- `--print` returns JSON template to stdout
|
|
243
|
+
|
|
244
|
+
Unlink when needed:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
npm run cli:unlink
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Library Usage
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { PunchClient } from 'punch-api';
|
|
254
|
+
|
|
255
|
+
const client = new PunchClient();
|
|
256
|
+
const payment = await client.createPayment({
|
|
257
|
+
provider: 'stripe',
|
|
258
|
+
amount: 1200,
|
|
259
|
+
currency: 'TRY'
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
await client.refundPayment({
|
|
263
|
+
provider: 'stripe',
|
|
264
|
+
paymentId: payment.id,
|
|
265
|
+
amount: 1200,
|
|
266
|
+
currency: 'TRY'
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
await client.executeCustomOperation({
|
|
270
|
+
provider: 'stripe',
|
|
271
|
+
endpoint: '/customers',
|
|
272
|
+
method: 'POST',
|
|
273
|
+
bodyType: 'form',
|
|
274
|
+
body: {
|
|
275
|
+
email: 'dev@company.com'
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
import { Punch } from 'punch-api';
|
|
280
|
+
|
|
281
|
+
const punch = new Punch({ stateStoreMode: 'file' });
|
|
282
|
+
const providers = punch.listProviders();
|
|
283
|
+
console.log(providers);
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Tests
|
|
287
|
+
|
|
288
|
+
- `test/provider-registry.spec.ts`: configured provider filtering
|
|
289
|
+
- `test/stripe-webhook.spec.ts`: Stripe webhook signature verification
|
|
290
|
+
- `test/cli.spec.ts`: CLI integration checks (`new/remove/doctor/template`)
|
|
291
|
+
- `test/payment-provider-resilience.spec.ts`: rate limit + circuit breaker checks
|
|
292
|
+
- `test/payment-webhook-idempotency.spec.ts`: webhook duplicate detection
|
|
293
|
+
- `test/payments.service.phase3.spec.ts`: outbox + DLQ behavior
|
|
294
|
+
- `test/provider-definition-of-done.spec.ts`: per-provider Definition of Done contract checks
|
|
295
|
+
- `test/persistent-storage.spec.ts`: file-backed outbox + DLQ persistence checks
|
|
296
|
+
- `test/stub-provider-standardization.spec.ts`: standardized lifecycle on stub providers
|
|
297
|
+
- `test/payments.e2e.ts`: e2e API flow checks
|
|
298
|
+
|
|
299
|
+
Quality gates:
|
|
300
|
+
- GitHub Actions CI: `.github/workflows/ci.yml` (build + unit/integration + e2e on Node 20/22)
|
|
301
|
+
|
|
302
|
+
## Release
|
|
303
|
+
|
|
304
|
+
Before publish:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
npm run release:preflight
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Publish to npm:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
npm login
|
|
314
|
+
npm run publish:npm
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
If your account requires publish 2FA:
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
NPM_OTP=123456 npm run publish:npm
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Publish with Yarn Berry:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
yarn npm login
|
|
327
|
+
npm run publish:yarn
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Publish with Yarn Classic:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
npm run publish:yarn:classic
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Documentation Files
|
|
337
|
+
|
|
338
|
+
- Docsify app entry: `docs/index.html`
|
|
339
|
+
- Sidebar: `docs/_sidebar.md`
|
|
340
|
+
- Navbar: `docs/_navbar.md`
|
|
341
|
+
- Home page: `docs/README.md`
|
|
342
|
+
- Technical reference: `docs/technical-documentation.md`
|
package/bin/punch.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { existsSync } = require('node:fs');
|
|
3
|
+
const { resolve } = require('node:path');
|
|
4
|
+
|
|
5
|
+
const distCli = resolve(__dirname, '../dist/cli/punch.js');
|
|
6
|
+
const tsCli = resolve(__dirname, '../src/cli/punch.ts');
|
|
7
|
+
|
|
8
|
+
if (existsSync(distCli)) {
|
|
9
|
+
require(distCli);
|
|
10
|
+
process.exit(0);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
require('ts-node/register/transpile-only');
|
|
15
|
+
require(tsCli);
|
|
16
|
+
process.exit(0);
|
|
17
|
+
} catch (_error) {
|
|
18
|
+
process.stderr.write('Cannot run `punch`. Build project (`npm run build`) or install dependencies (`npm install`).\n');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.HealthController = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
let HealthController = class HealthController {
|
|
15
|
+
ping() {
|
|
16
|
+
return { status: 'ok' };
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
exports.HealthController = HealthController;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, common_1.Get)(),
|
|
22
|
+
__metadata("design:type", Function),
|
|
23
|
+
__metadata("design:paramtypes", []),
|
|
24
|
+
__metadata("design:returntype", void 0)
|
|
25
|
+
], HealthController.prototype, "ping", null);
|
|
26
|
+
exports.HealthController = HealthController = __decorate([
|
|
27
|
+
(0, common_1.Controller)('health')
|
|
28
|
+
], HealthController);
|
|
29
|
+
//# sourceMappingURL=health.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.controller.js","sourceRoot":"","sources":["../../src/app/health.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AAG1C,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAE3B,IAAI;QACF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;CACF,CAAA;AALY,4CAAgB;AAE3B;IADC,IAAA,YAAG,GAAE;;;;4CAGL;2BAJU,gBAAgB;IAD5B,IAAA,mBAAU,EAAC,QAAQ,CAAC;GACR,gBAAgB,CAK5B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.AppModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const config_1 = require("@nestjs/config");
|
|
12
|
+
const health_controller_1 = require("./app/health.controller");
|
|
13
|
+
const correlation_id_middleware_1 = require("./common/correlation-id.middleware");
|
|
14
|
+
const payments_module_1 = require("./payments/payments.module");
|
|
15
|
+
let AppModule = class AppModule {
|
|
16
|
+
configure(consumer) {
|
|
17
|
+
consumer.apply(correlation_id_middleware_1.CorrelationIdMiddleware).forRoutes('*');
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
exports.AppModule = AppModule;
|
|
21
|
+
exports.AppModule = AppModule = __decorate([
|
|
22
|
+
(0, common_1.Module)({
|
|
23
|
+
imports: [
|
|
24
|
+
config_1.ConfigModule.forRoot({ isGlobal: true }),
|
|
25
|
+
payments_module_1.PaymentsModule
|
|
26
|
+
],
|
|
27
|
+
controllers: [health_controller_1.HealthController]
|
|
28
|
+
})
|
|
29
|
+
], AppModule);
|
|
30
|
+
//# sourceMappingURL=app.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwE;AACxE,2CAA8C;AAC9C,+DAA2D;AAC3D,kFAA6E;AAC7E,gEAA4D;AASrD,IAAM,SAAS,GAAf,MAAM,SAAS;IACpB,SAAS,CAAC,QAA4B;QACpC,QAAQ,CAAC,KAAK,CAAC,mDAAuB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;CACF,CAAA;AAJY,8BAAS;oBAAT,SAAS;IAPrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,qBAAY,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACxC,gCAAc;SACf;QACD,WAAW,EAAE,CAAC,oCAAgB,CAAC;KAChC,CAAC;GACW,SAAS,CAIrB"}
|