@mostajs/payment 0.5.2 → 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.
- package/README.md +45 -0
- package/dist/core/abstract-provider.d.ts +22 -0
- package/dist/core/abstract-provider.d.ts.map +1 -0
- package/dist/core/abstract-provider.js +54 -0
- package/dist/core/abstract-provider.js.map +1 -0
- package/dist/core/auto-register.d.ts +28 -0
- package/dist/core/auto-register.d.ts.map +1 -0
- package/dist/core/auto-register.js +90 -0
- package/dist/core/auto-register.js.map +1 -0
- package/dist/core/checkout-service.d.ts +70 -0
- package/dist/core/checkout-service.d.ts.map +1 -0
- package/dist/core/checkout-service.js +107 -0
- package/dist/core/checkout-service.js.map +1 -0
- package/dist/providers/chargily.provider.d.ts +5 -4
- package/dist/providers/chargily.provider.d.ts.map +1 -1
- package/dist/providers/chargily.provider.js +33 -15
- package/dist/providers/chargily.provider.js.map +1 -1
- package/dist/providers/manual.provider.d.ts +5 -4
- package/dist/providers/manual.provider.d.ts.map +1 -1
- package/dist/providers/manual.provider.js +14 -4
- package/dist/providers/manual.provider.js.map +1 -1
- package/dist/providers/paypal.provider.d.ts +5 -4
- package/dist/providers/paypal.provider.d.ts.map +1 -1
- package/dist/providers/paypal.provider.js +5 -3
- package/dist/providers/paypal.provider.js.map +1 -1
- package/dist/providers/satim.provider.d.ts +5 -4
- package/dist/providers/satim.provider.d.ts.map +1 -1
- package/dist/providers/satim.provider.js +5 -3
- package/dist/providers/satim.provider.js.map +1 -1
- package/dist/providers/stripe.provider.d.ts +5 -4
- package/dist/providers/stripe.provider.d.ts.map +1 -1
- package/dist/providers/stripe.provider.js +5 -3
- package/dist/providers/stripe.provider.js.map +1 -1
- package/dist/schemas/payment.schema.d.ts.map +1 -1
- package/dist/schemas/payment.schema.js +5 -0
- package/dist/schemas/payment.schema.js.map +1 -1
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +6 -0
- package/dist/server.js.map +1 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/llms.txt +117 -0
- package/package.json +3 -2
package/llms.txt
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# @mostajs/payment — fiche LLM
|
|
2
|
+
> Module de paiement multi-provider (Stripe, Satim/CIB, Chargily, PayPal, Manuel), multi-méthode, multi-devise.
|
|
3
|
+
|
|
4
|
+
- Version: 0.6.0 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
|
|
5
|
+
- Chemin: mostajs/mosta-payment · Statut audit: complet (dist/)
|
|
6
|
+
|
|
7
|
+
## RÔLE
|
|
8
|
+
Abstraction unifiée du paiement pour l'écosystème `@mostajs/*`. Un contrat `PaymentProvider` commun couvre 5 providers (Stripe, Satim, Chargily, PayPal, Manuel). Fournit checkout, webhooks normalisés, billing/abonnements (Stripe), schéma ORM `Payment`, composant React `PaymentPage` et handlers de routes Next.js App Router. Sélection automatique du provider par devise (DZD → Chargily, autres → Stripe).
|
|
9
|
+
|
|
10
|
+
## MODÈLE DIALECTE (v0.6) — calqué sur @mostajs/orm
|
|
11
|
+
Chaque **fournisseur = un dialecte de paiement**, exactement comme un dialecte ORM :
|
|
12
|
+
- `PaymentProvider` (contrat) ≡ `IDialect`.
|
|
13
|
+
- `AbstractPaymentProvider` (base, v0.6) ≡ `AbstractSqlDialect` : méthodes *template* publiques `createCheckout`/`verifyWebhook` (validation + garantie `metadata.orderId` + garde de devise) qui délèguent aux *primitives* `protected abstract doCheckout`/`doVerifyWebhook`. Les 5 providers l'étendent.
|
|
14
|
+
- `payment-engine` (register/get/forCurrency) ≡ registre des dialectes.
|
|
15
|
+
- **Orchestration** `createPaymentCheckout` / `settlePaymentFromWebhook` (v0.6) ≡ `BaseRepository`/`createConnection` : *utilise* un dialecte + persiste la ligne `Payment` (data-plug), sans réimplémenter la logique fournisseur.
|
|
16
|
+
|
|
17
|
+
## INSTALLATION
|
|
18
|
+
npm i @mostajs/payment stripe
|
|
19
|
+
|
|
20
|
+
## EXPORTS
|
|
21
|
+
Entrée `.` (client + serveur léger) :
|
|
22
|
+
- Composant React: `PaymentPage`
|
|
23
|
+
- Schémas: `PaymentSchema`, `createPaymentSchema`
|
|
24
|
+
- Constante: `moduleInfo`
|
|
25
|
+
- Types: `PaymentConfig`, `PaymentStatus`, `PaymentMethodType`, `LineItem`, `CheckoutRequest`, `CheckoutResult`, `OrderSummary`, `PaymentDTO`, `WebhookHandlers`
|
|
26
|
+
|
|
27
|
+
## EXPORTS PAR SOUS-CHEMIN
|
|
28
|
+
Entrée `@mostajs/payment/server` (serveur uniquement) :
|
|
29
|
+
- Engine: `registerProvider`, `setDefaultProvider`, `getProvider`, `listProviders`, `getProviderForCurrency`, `resetProviders`
|
|
30
|
+
- Dialecte base (v0.6): `AbstractPaymentProvider` (classe abstraite — étendue par les 5 providers)
|
|
31
|
+
- Orchestration (v0.6): `createPaymentCheckout(input)`, `settlePaymentFromWebhook(input)` + types `CreateCheckoutInput`/`CreateCheckoutOutput`/`SettleWebhookInput`/`SettleWebhookOutput`
|
|
32
|
+
- Auto-enregistrement (v0.5.4+): `registerProvidersFromEnv(opts?)`, `ensureProvidersFromEnv(opts?)`, `resetEnsuredProviders()` + type `AutoRegisterOptions`
|
|
33
|
+
- Providers (classes + factories env): `StripeProvider`/`createStripeProvider`, `SatimProvider`/`createSatimProvider`, `ChargilyProvider`/`createChargilyProvider`, `PayPalProvider`/`createPayPalProvider`, `ManualProvider`/`createManualProvider`
|
|
34
|
+
- Stripe bas niveau: `createStripeClient`, `createCheckoutSession`, `handleWebhook`, `createBillingSession`, `createPortalSession`, `handleBillingWebhook`
|
|
35
|
+
- Webhook helpers: `handleProviderWebhook`, `pickSignatureHeader`, `getProviderByName`, `isPaidEvent`, `isFailedEvent`, `isRefundedEvent`, `extractOrderId`, `pickProviderByCurrency`, `isKnownProvider`, constantes `KNOWN_PROVIDERS`, `CURRENCY_TO_PROVIDER`
|
|
36
|
+
- Repo: `getPaymentRepo`, `resetPaymentRepo`
|
|
37
|
+
- Routes Next.js: `createCheckoutHandler`, `createPaymentHandlers`
|
|
38
|
+
- Module: `getSchemas`, `moduleInfo`, `paymentModuleRegistration`
|
|
39
|
+
- Types: `PaymentProvider`, `CheckoutParams`, `CheckoutResult`, `CustomerParams`, `SubscriptionParams`, `SubscriptionResult`, `RefundParams`, `RefundResult`, `InvoiceResult`, `WebhookEvent`, `ProviderName`, `HandleProviderWebhookArgs`, `HandleProviderWebhookResult`, configs `StripeConfig`/`SatimConfig`/`ChargilyConfig`/`PayPalConfig`/`ManualConfig`, `SmtpDriverConfig` n/a
|
|
40
|
+
|
|
41
|
+
## API — SIGNATURES
|
|
42
|
+
- `createPaymentSchema(options?: { currency?; relationTarget?; relationRequired?; subscriptionTarget?; invoiceTarget? }): EntitySchema`
|
|
43
|
+
- `createCheckoutHandler(config: PaymentConfig): (req: Request) => Promise<Response>`
|
|
44
|
+
- `createPaymentHandlers(dialect: IDialect): { GET; POST }`
|
|
45
|
+
- `getPaymentRepo(dialect: IDialect): BaseRepository<PaymentDTO>` — cache WeakMap par identité du dialect
|
|
46
|
+
- `registerProvider(p: PaymentProvider): void` · `setDefaultProvider(name): void` · `getProvider(name?): PaymentProvider` · `getProviderForCurrency(currency): PaymentProvider | null`
|
|
47
|
+
- `registerProvidersFromEnv(opts?: { providers?: ProviderName[]; setDefault?: ProviderName; force?: boolean }): string[]` — enregistre depuis l'env (cascade `MOSTA_ENV`) les providers configurés ; ordre = résolution devise (Chargily/Satim avant Stripe). `manual` exclu sauf si listé.
|
|
48
|
+
- `ensureProvidersFromEnv(opts?): string[]` — variante idempotente « une fois par process » (à appeler en tête de route handler) · `resetEnsuredProviders(): void` (tests)
|
|
49
|
+
- `pickProviderByCurrency(currency, fallback?: ProviderName): { name; provider }`
|
|
50
|
+
- `createPaymentCheckout(input: { dialect: IDialect; orderId; amount; currency; successUrl; cancelUrl; webhookUrl?; description?; method?: PaymentMethodType; metadata?; providerName? }): Promise<{ payment: PaymentDTO; checkout: CheckoutResult; provider: string }>` — sélectionne le dialecte (explicite > registre/devise > mapping), crée le checkout ET persiste la `Payment` (status 'pending', provider, transactionRef=sessionId, orderId, metadata)
|
|
51
|
+
- `settlePaymentFromWebhook(input: { dialect: IDialect; providerName: ProviderName; body: string; headers }): Promise<{ ok; reason?; event?; orderId?; status?: PaymentStatus; payment?: PaymentDTO|null }>` — vérifie le webhook, mappe l'event (paid/failed/refunded), retrouve la `Payment` par `orderId` et la met à jour (paidAt si paid). Le métier post-paiement reste au caller.
|
|
52
|
+
- `handleProviderWebhook(args: HandleProviderWebhookArgs): Promise<HandleProviderWebhookResult>`
|
|
53
|
+
- `isPaidEvent/isFailedEvent/isRefundedEvent(event: WebhookEvent): boolean` · `extractOrderId(event): string | null`
|
|
54
|
+
- Stripe: `createStripeClient(config)`, `createCheckoutSession(stripe, request, config)`, `handleWebhook(stripe, body, sig, secret)`, `createBillingSession(stripe, {...})`, `createPortalSession(stripe, customerId, returnUrl)`, `handleBillingWebhook(stripe, body, sig, secret, handlers)`
|
|
55
|
+
Interface `PaymentProvider` : `name`, `supportedCurrencies`, `supportedMethods`, `createCheckout(params)`, `verifyWebhook(body, sig)` requis ; `createCustomer/getCustomer/updateCustomer/createSubscription/getSubscription/cancelSubscription/changeSubscription/pauseSubscription/resumeSubscription/createRefund/listInvoices/getUpcomingInvoice/createPortal` optionnels.
|
|
56
|
+
|
|
57
|
+
## TYPES CLÉS
|
|
58
|
+
- `PaymentStatus = 'pending'|'paid'|'refunded'|'failed'`
|
|
59
|
+
- `PaymentMethodType = 'card'|'transfer'|'cash'|'tpe'`
|
|
60
|
+
- `ProviderName = 'chargily'|'stripe'|'satim'|'paypal'|'manual'`
|
|
61
|
+
- `PaymentConfig { currency: string; defaultCurrency?; stripeSecretKey?; stripePublicKey?; stripeWebhookSecret?; successUrlTemplate: string; cancelUrlTemplate: string; methods?: PaymentMethodType[]; bankInfo?: { rib; bankName; holder } }` — templates avec `{orderId}` substitué
|
|
62
|
+
- `LineItem { name; description?; unitAmount: number; quantity: number }` — unitAmount en unités de base (PAS en centimes)
|
|
63
|
+
- `CheckoutRequest { orderId; lineItems: LineItem[]; currency?; returnUrl?; metadata? }`
|
|
64
|
+
- `CheckoutResult { url: string | null; sessionId: string }`
|
|
65
|
+
- `CheckoutParams { orderId; amount; currency?; description?; successUrl; cancelUrl; webhookUrl?; metadata?; customerId?; priceId?; trialDays? }`
|
|
66
|
+
- `WebhookEvent { type: string; data: Record<string,unknown>; raw? }`
|
|
67
|
+
- `HandleProviderWebhookResult = { ok: true; event: WebhookEvent } | { ok: false; reason: 'bad_signature'|'malformed'|'unknown_provider'; error: string }`
|
|
68
|
+
- `PaymentDTO { id; amount; currency; method: PaymentMethodType; status: PaymentStatus; transactionRef?; paidAt?: Date; orderId?; provider?; metadata? }` (provider/metadata ajoutés v0.6 ; schéma `Payment` = 9 champs + index sur `orderId`)
|
|
69
|
+
- `WebhookHandlers { onCheckoutCompleted?; onInvoicePaid?; onSubscriptionUpdated?; onSubscriptionDeleted?; onPaymentFailed? }`
|
|
70
|
+
|
|
71
|
+
## PATTERN
|
|
72
|
+
```ts
|
|
73
|
+
// Route checkout Next.js
|
|
74
|
+
import { createCheckoutHandler } from '@mostajs/payment/server'
|
|
75
|
+
export const POST = createCheckoutHandler({
|
|
76
|
+
currency: 'EUR',
|
|
77
|
+
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
|
|
78
|
+
successUrlTemplate: '/confirmation/{orderId}?paid=true',
|
|
79
|
+
cancelUrlTemplate: '/payment/{orderId}?cancelled=true',
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Webhook provider-agnostic
|
|
83
|
+
import { handleProviderWebhook, isPaidEvent, extractOrderId } from '@mostajs/payment/server'
|
|
84
|
+
const r = await handleProviderWebhook({ body: await req.text(), headers: req.headers, providerName: 'chargily' })
|
|
85
|
+
if (!r.ok) return Response.json({ error: r.error }, { status: 400 })
|
|
86
|
+
if (isPaidEvent(r.event)) { /* MAJ DB métier via extractOrderId(r.event) */ }
|
|
87
|
+
|
|
88
|
+
// Orchestration v0.6 — checkout + persistance en un appel
|
|
89
|
+
import { ensureProvidersFromEnv, createPaymentCheckout, settlePaymentFromWebhook } from '@mostajs/payment/server'
|
|
90
|
+
ensureProvidersFromEnv() // dialectes depuis .env (cascade MOSTA_ENV)
|
|
91
|
+
const { checkout } = await createPaymentCheckout({
|
|
92
|
+
dialect, orderId, amount: 50000, currency: 'DZD', // → Chargily
|
|
93
|
+
successUrl, cancelUrl, webhookUrl, metadata: { campaignId },
|
|
94
|
+
})
|
|
95
|
+
// route webhook :
|
|
96
|
+
const s = await settlePaymentFromWebhook({ dialect, providerName: 'chargily', body: await req.text(), headers: req.headers })
|
|
97
|
+
if (s.status === 'paid') { /* activer la campagne sponsor (métier) */ }
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## DÉPEND DE
|
|
101
|
+
- `@mostajs/config` (dependency) — résolution env avec cascade `MOSTA_ENV` (`TEST_*`/`DEV_*`/`PROD_*`).
|
|
102
|
+
- `@mostajs/data-plug` (peer dep `^1.2.4`) — façade ORM : `BaseRepository`, `IDialect`, `EntitySchema`. Le module n'importe jamais `@mostajs/orm` directement.
|
|
103
|
+
- `stripe` (dependency) — SDK Stripe.
|
|
104
|
+
- `next` et `react` en peer deps optionnelles (routes + `PaymentPage`).
|
|
105
|
+
|
|
106
|
+
## PIÈGES
|
|
107
|
+
- `LineItem.unitAmount` est en unités de base de la devise, pas en centimes — la conversion Stripe est interne.
|
|
108
|
+
- Le body du webhook DOIT être lu brut (`req.text()`) avant tout parse JSON : la signature est calculée sur les bytes exacts.
|
|
109
|
+
- Le sous-chemin `/server` contient toute la logique sensible (clés, providers) — ne jamais l'importer côté client ; `PaymentPage`/`PaymentSchema` sont sur `.`.
|
|
110
|
+
- Sélection devise : `CURRENCY_TO_PROVIDER` mappe DZD → Chargily, le reste → Stripe ; pour CIB-only Algérie sans Chargily, passer `fallback` à `pickProviderByCurrency`.
|
|
111
|
+
- Les factories `create*Provider` lisent l'env en fallback (cascade `@mostajs/config`) ; defaults testMode : Chargily test-on (`!== 'false'`), Satim test-off (`=== 'true'`), PayPal test-on.
|
|
112
|
+
- `ChargilyProvider` : préférer `CHARGILY_SECRET_KEY` ; `CHARGILY_API_KEY` est un alias legacy.
|
|
113
|
+
- `getPaymentRepo` met en cache via WeakMap par identité de dialect — un changement de dialect reconstruit le repo ; `resetPaymentRepo` est un no-op de rétro-compat.
|
|
114
|
+
- Méthodes optionnelles de `PaymentProvider` (subscriptions, refunds…) : seul Stripe les implémente toutes ; vérifier la présence avant appel sur Satim/Chargily/Manual.
|
|
115
|
+
|
|
116
|
+
## RÉFÉRENCES
|
|
117
|
+
README.md · docs/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/payment",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Payment module for @mostajs — Multi-provider (Stripe, Satim/CIB, Chargily, PayPal), multi-method, multi-currency",
|
|
5
5
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"dist",
|
|
24
|
-
"README.md"
|
|
24
|
+
"README.md",
|
|
25
|
+
"llms.txt"
|
|
25
26
|
],
|
|
26
27
|
"scripts": {
|
|
27
28
|
"build": "tsc",
|