@mostajs/payment 0.2.0 → 0.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/dist/core/payment-engine.d.ts +26 -0
- package/dist/core/payment-engine.d.ts.map +1 -0
- package/dist/core/payment-engine.js +57 -0
- package/dist/core/payment-engine.js.map +1 -0
- package/dist/core/provider.interface.d.ts +101 -0
- package/dist/core/provider.interface.d.ts.map +1 -0
- package/dist/core/provider.interface.js +4 -0
- package/dist/core/provider.interface.js.map +1 -0
- package/dist/lib/module-info.js +1 -1
- package/dist/providers/chargily.provider.d.ts +30 -0
- package/dist/providers/chargily.provider.d.ts.map +1 -0
- package/dist/providers/chargily.provider.js +112 -0
- package/dist/providers/chargily.provider.js.map +1 -0
- package/dist/providers/manual.provider.d.ts +20 -0
- package/dist/providers/manual.provider.d.ts.map +1 -0
- package/dist/providers/manual.provider.js +26 -0
- package/dist/providers/manual.provider.js.map +1 -0
- package/dist/providers/paypal.provider.d.ts +44 -0
- package/dist/providers/paypal.provider.d.ts.map +1 -0
- package/dist/providers/paypal.provider.js +160 -0
- package/dist/providers/paypal.provider.js.map +1 -0
- package/dist/providers/satim.provider.d.ts +38 -0
- package/dist/providers/satim.provider.d.ts.map +1 -0
- package/dist/providers/satim.provider.js +107 -0
- package/dist/providers/satim.provider.js.map +1 -0
- package/dist/providers/stripe.provider.d.ts +36 -0
- package/dist/providers/stripe.provider.d.ts.map +1 -0
- package/dist/providers/stripe.provider.js +203 -0
- package/dist/providers/stripe.provider.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +12 -6
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PaymentProvider } from './provider.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Register a payment provider.
|
|
4
|
+
*/
|
|
5
|
+
export declare function registerProvider(provider: PaymentProvider): void;
|
|
6
|
+
/**
|
|
7
|
+
* Set the default provider.
|
|
8
|
+
*/
|
|
9
|
+
export declare function setDefaultProvider(name: string): void;
|
|
10
|
+
/**
|
|
11
|
+
* Get a registered provider by name.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getProvider(name?: string): PaymentProvider;
|
|
14
|
+
/**
|
|
15
|
+
* List registered provider names.
|
|
16
|
+
*/
|
|
17
|
+
export declare function listProviders(): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Get the best provider for a given currency.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getProviderForCurrency(currency: string): PaymentProvider | null;
|
|
22
|
+
/**
|
|
23
|
+
* Reset all providers (for testing).
|
|
24
|
+
*/
|
|
25
|
+
export declare function resetProviders(): void;
|
|
26
|
+
//# sourceMappingURL=payment-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment-engine.d.ts","sourceRoot":"","sources":["../../src/core/payment-engine.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAK9D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAGhE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAM1D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAO/E;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// @mostajs/payment — Payment Engine (provider router)
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
const _providers = new Map();
|
|
4
|
+
let _defaultProvider = null;
|
|
5
|
+
/**
|
|
6
|
+
* Register a payment provider.
|
|
7
|
+
*/
|
|
8
|
+
export function registerProvider(provider) {
|
|
9
|
+
_providers.set(provider.name, provider);
|
|
10
|
+
if (!_defaultProvider)
|
|
11
|
+
_defaultProvider = provider.name;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Set the default provider.
|
|
15
|
+
*/
|
|
16
|
+
export function setDefaultProvider(name) {
|
|
17
|
+
if (!_providers.has(name))
|
|
18
|
+
throw new Error(`[payment] Provider '${name}' not registered`);
|
|
19
|
+
_defaultProvider = name;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get a registered provider by name.
|
|
23
|
+
*/
|
|
24
|
+
export function getProvider(name) {
|
|
25
|
+
const key = name ?? _defaultProvider;
|
|
26
|
+
if (!key)
|
|
27
|
+
throw new Error('[payment] No provider registered');
|
|
28
|
+
const p = _providers.get(key);
|
|
29
|
+
if (!p)
|
|
30
|
+
throw new Error(`[payment] Provider '${key}' not registered`);
|
|
31
|
+
return p;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* List registered provider names.
|
|
35
|
+
*/
|
|
36
|
+
export function listProviders() {
|
|
37
|
+
return Array.from(_providers.keys());
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the best provider for a given currency.
|
|
41
|
+
*/
|
|
42
|
+
export function getProviderForCurrency(currency) {
|
|
43
|
+
for (const p of _providers.values()) {
|
|
44
|
+
if (p.supportedCurrencies.includes('*') || p.supportedCurrencies.includes(currency.toUpperCase())) {
|
|
45
|
+
return p;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reset all providers (for testing).
|
|
52
|
+
*/
|
|
53
|
+
export function resetProviders() {
|
|
54
|
+
_providers.clear();
|
|
55
|
+
_defaultProvider = null;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=payment-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment-engine.js","sourceRoot":"","sources":["../../src/core/payment-engine.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,wCAAwC;AAIxC,MAAM,UAAU,GAAG,IAAI,GAAG,EAA2B,CAAA;AACrD,IAAI,gBAAgB,GAAkB,IAAI,CAAA;AAE1C;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAyB;IACxD,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACvC,IAAI,CAAC,gBAAgB;QAAE,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAA;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,kBAAkB,CAAC,CAAA;IACzF,gBAAgB,GAAG,IAAI,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,gBAAgB,CAAA;IACpC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IAC7D,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC7B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,kBAAkB,CAAC,CAAA;IACrE,OAAO,CAAC,CAAA;AACV,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;QACpC,IAAI,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAClG,OAAO,CAAC,CAAA;QACV,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,UAAU,CAAC,KAAK,EAAE,CAAA;IAClB,gBAAgB,GAAG,IAAI,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export interface CheckoutParams {
|
|
2
|
+
orderId: string;
|
|
3
|
+
amount: number;
|
|
4
|
+
currency?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
successUrl: string;
|
|
7
|
+
cancelUrl: string;
|
|
8
|
+
webhookUrl?: string;
|
|
9
|
+
metadata?: Record<string, string>;
|
|
10
|
+
/** For subscription billing */
|
|
11
|
+
customerId?: string;
|
|
12
|
+
priceId?: string;
|
|
13
|
+
trialDays?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface CheckoutResult {
|
|
16
|
+
url: string | null;
|
|
17
|
+
sessionId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CustomerParams {
|
|
20
|
+
email: string;
|
|
21
|
+
name: string;
|
|
22
|
+
metadata?: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
export interface SubscriptionParams {
|
|
25
|
+
customerId: string;
|
|
26
|
+
priceId: string;
|
|
27
|
+
trialDays?: number;
|
|
28
|
+
metadata?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
export interface SubscriptionResult {
|
|
31
|
+
id: string;
|
|
32
|
+
status: string;
|
|
33
|
+
customerId: string;
|
|
34
|
+
currentPeriodEnd?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface RefundParams {
|
|
37
|
+
paymentId: string;
|
|
38
|
+
amount?: number;
|
|
39
|
+
reason?: string;
|
|
40
|
+
metadata?: Record<string, string>;
|
|
41
|
+
}
|
|
42
|
+
export interface RefundResult {
|
|
43
|
+
id: string;
|
|
44
|
+
amount: number;
|
|
45
|
+
status: string;
|
|
46
|
+
}
|
|
47
|
+
export interface InvoiceResult {
|
|
48
|
+
id: string;
|
|
49
|
+
amount: number;
|
|
50
|
+
currency: string;
|
|
51
|
+
status: string;
|
|
52
|
+
paidAt?: string;
|
|
53
|
+
pdfUrl?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface WebhookEvent {
|
|
56
|
+
type: string;
|
|
57
|
+
data: Record<string, unknown>;
|
|
58
|
+
raw?: unknown;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* PaymentProvider — contract for all payment providers.
|
|
62
|
+
* Implemented by: Satim, PayPal, Chargily, Stripe, Manual
|
|
63
|
+
*/
|
|
64
|
+
export interface PaymentProvider {
|
|
65
|
+
readonly name: string;
|
|
66
|
+
readonly supportedCurrencies: string[];
|
|
67
|
+
readonly supportedMethods: string[];
|
|
68
|
+
/** Create a checkout session (redirect user to payment page) */
|
|
69
|
+
createCheckout(params: CheckoutParams): Promise<CheckoutResult>;
|
|
70
|
+
/** Verify and parse a webhook payload */
|
|
71
|
+
verifyWebhook(body: string, signature: string): Promise<WebhookEvent>;
|
|
72
|
+
/** Create a customer (optional — not all providers support) */
|
|
73
|
+
createCustomer?(params: CustomerParams): Promise<string>;
|
|
74
|
+
/** Get customer details */
|
|
75
|
+
getCustomer?(customerId: string): Promise<Record<string, unknown>>;
|
|
76
|
+
/** Update customer */
|
|
77
|
+
updateCustomer?(customerId: string, params: Partial<CustomerParams>): Promise<Record<string, unknown>>;
|
|
78
|
+
/** Create a subscription */
|
|
79
|
+
createSubscription?(params: SubscriptionParams): Promise<SubscriptionResult>;
|
|
80
|
+
/** Get subscription details */
|
|
81
|
+
getSubscription?(subscriptionId: string): Promise<SubscriptionResult>;
|
|
82
|
+
/** Cancel a subscription */
|
|
83
|
+
cancelSubscription?(subscriptionId: string, immediate?: boolean): Promise<void>;
|
|
84
|
+
/** Change subscription plan */
|
|
85
|
+
changeSubscription?(subscriptionId: string, newPriceId: string): Promise<SubscriptionResult>;
|
|
86
|
+
/** Pause subscription */
|
|
87
|
+
pauseSubscription?(subscriptionId: string): Promise<void>;
|
|
88
|
+
/** Resume subscription */
|
|
89
|
+
resumeSubscription?(subscriptionId: string): Promise<void>;
|
|
90
|
+
/** Create a refund */
|
|
91
|
+
createRefund?(params: RefundParams): Promise<RefundResult>;
|
|
92
|
+
/** List invoices for a customer */
|
|
93
|
+
listInvoices?(customerId: string, limit?: number): Promise<InvoiceResult[]>;
|
|
94
|
+
/** Get upcoming invoice */
|
|
95
|
+
getUpcomingInvoice?(customerId: string): Promise<InvoiceResult | null>;
|
|
96
|
+
/** Create a billing portal session (self-service) */
|
|
97
|
+
createPortal?(customerId: string, returnUrl: string): Promise<{
|
|
98
|
+
url: string;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=provider.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.interface.d.ts","sourceRoot":"","sources":["../../src/core/provider.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.interface.js","sourceRoot":"","sources":["../../src/core/provider.interface.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,wCAAwC"}
|
package/dist/lib/module-info.js
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PaymentProvider, CheckoutParams, CheckoutResult, CustomerParams, WebhookEvent } from '../core/provider.interface.js';
|
|
2
|
+
export interface ChargilyConfig {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
testMode?: boolean;
|
|
5
|
+
successUrl: string;
|
|
6
|
+
failureUrl: string;
|
|
7
|
+
webhookUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class ChargilyProvider implements PaymentProvider {
|
|
10
|
+
private config;
|
|
11
|
+
readonly name = "chargily";
|
|
12
|
+
readonly supportedCurrencies: string[];
|
|
13
|
+
readonly supportedMethods: string[];
|
|
14
|
+
private baseUrl;
|
|
15
|
+
constructor(config: ChargilyConfig);
|
|
16
|
+
private headers;
|
|
17
|
+
createCheckout(params: CheckoutParams): Promise<CheckoutResult>;
|
|
18
|
+
createCustomer(params: CustomerParams): Promise<string>;
|
|
19
|
+
getCustomer(customerId: string): Promise<Record<string, unknown>>;
|
|
20
|
+
/**
|
|
21
|
+
* Get payment details by checkout ID.
|
|
22
|
+
*/
|
|
23
|
+
getPayment(checkoutId: string): Promise<Record<string, unknown>>;
|
|
24
|
+
verifyWebhook(body: string, signature: string): Promise<WebhookEvent>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create a Chargily provider from environment variables.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createChargilyProvider(config?: Partial<ChargilyConfig>): ChargilyProvider;
|
|
30
|
+
//# sourceMappingURL=chargily.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chargily.provider.d.ts","sourceRoot":"","sources":["../../src/providers/chargily.provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAGlI,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,gBAAiB,YAAW,eAAe;IAO1C,OAAO,CAAC,MAAM;IAN1B,QAAQ,CAAC,IAAI,cAAa;IAC1B,QAAQ,CAAC,mBAAmB,WAAU;IACtC,QAAQ,CAAC,gBAAgB,WAAsB;IAE/C,OAAO,CAAC,OAAO,CAAQ;gBAEH,MAAM,EAAE,cAAc;IAM1C,OAAO,CAAC,OAAO;IAOT,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAwB/D,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBvD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMvE;;OAEG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMhE,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA0B5E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,gBAAgB,CAQzF"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// @mostajs/payment — Chargily Pay V2 provider (CIB + EDAHABIA — Algerie)
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
// Ref: https://dev.chargily.com/pay-v2/api-reference/
|
|
4
|
+
// GitHub: https://github.com/chargily
|
|
5
|
+
import { createHmac } from 'node:crypto';
|
|
6
|
+
export class ChargilyProvider {
|
|
7
|
+
config;
|
|
8
|
+
name = 'chargily';
|
|
9
|
+
supportedCurrencies = ['DZD'];
|
|
10
|
+
supportedMethods = ['cib', 'edahabia'];
|
|
11
|
+
baseUrl;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.baseUrl = config.testMode
|
|
15
|
+
? 'https://pay.chargily.net/test/api/v2'
|
|
16
|
+
: 'https://pay.chargily.net/api/v2';
|
|
17
|
+
}
|
|
18
|
+
headers() {
|
|
19
|
+
return {
|
|
20
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async createCheckout(params) {
|
|
25
|
+
const res = await fetch(`${this.baseUrl}/checkouts`, {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: this.headers(),
|
|
28
|
+
body: JSON.stringify({
|
|
29
|
+
amount: params.amount, // DZD (pas centimes — Chargily attend le montant reel)
|
|
30
|
+
currency: 'dzd',
|
|
31
|
+
success_url: params.successUrl ?? this.config.successUrl,
|
|
32
|
+
failure_url: params.cancelUrl ?? this.config.failureUrl,
|
|
33
|
+
webhook_endpoint: params.webhookUrl ?? this.config.webhookUrl,
|
|
34
|
+
description: params.description ?? `Commande ${params.orderId}`,
|
|
35
|
+
metadata: { orderId: params.orderId, ...params.metadata },
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
const err = await res.json().catch(() => ({}));
|
|
40
|
+
throw new Error(`[chargily] Checkout failed: ${err.message ?? res.statusText}`);
|
|
41
|
+
}
|
|
42
|
+
const data = await res.json();
|
|
43
|
+
return { url: data.checkout_url, sessionId: data.id };
|
|
44
|
+
}
|
|
45
|
+
async createCustomer(params) {
|
|
46
|
+
const res = await fetch(`${this.baseUrl}/customers`, {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: this.headers(),
|
|
49
|
+
body: JSON.stringify({
|
|
50
|
+
name: params.name,
|
|
51
|
+
email: params.email,
|
|
52
|
+
metadata: params.metadata,
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
if (!res.ok)
|
|
56
|
+
throw new Error(`[chargily] Create customer failed: ${res.statusText}`);
|
|
57
|
+
const data = await res.json();
|
|
58
|
+
return data.id;
|
|
59
|
+
}
|
|
60
|
+
async getCustomer(customerId) {
|
|
61
|
+
const res = await fetch(`${this.baseUrl}/customers/${customerId}`, { headers: this.headers() });
|
|
62
|
+
if (!res.ok)
|
|
63
|
+
throw new Error(`[chargily] Get customer failed: ${res.statusText}`);
|
|
64
|
+
return res.json();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get payment details by checkout ID.
|
|
68
|
+
*/
|
|
69
|
+
async getPayment(checkoutId) {
|
|
70
|
+
const res = await fetch(`${this.baseUrl}/checkouts/${checkoutId}`, { headers: this.headers() });
|
|
71
|
+
if (!res.ok)
|
|
72
|
+
throw new Error(`[chargily] Get payment failed: ${res.statusText}`);
|
|
73
|
+
return res.json();
|
|
74
|
+
}
|
|
75
|
+
async verifyWebhook(body, signature) {
|
|
76
|
+
// Chargily signs with HMAC-SHA256 using the API key as secret
|
|
77
|
+
const computed = createHmac('sha256', this.config.apiKey).update(body).digest('hex');
|
|
78
|
+
if (computed !== signature) {
|
|
79
|
+
throw new Error('[chargily] Invalid webhook signature');
|
|
80
|
+
}
|
|
81
|
+
const data = JSON.parse(body);
|
|
82
|
+
const type = data.status === 'paid' ? 'payment.success'
|
|
83
|
+
: data.status === 'failed' ? 'payment.failed'
|
|
84
|
+
: data.status === 'canceled' ? 'payment.canceled'
|
|
85
|
+
: 'payment.pending';
|
|
86
|
+
return {
|
|
87
|
+
type,
|
|
88
|
+
data: {
|
|
89
|
+
checkoutId: data.id,
|
|
90
|
+
amount: data.amount,
|
|
91
|
+
currency: data.currency,
|
|
92
|
+
status: data.status,
|
|
93
|
+
metadata: data.metadata,
|
|
94
|
+
orderId: data.metadata?.orderId,
|
|
95
|
+
},
|
|
96
|
+
raw: data,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create a Chargily provider from environment variables.
|
|
102
|
+
*/
|
|
103
|
+
export function createChargilyProvider(config) {
|
|
104
|
+
return new ChargilyProvider({
|
|
105
|
+
apiKey: config?.apiKey ?? process.env.CHARGILY_API_KEY ?? '',
|
|
106
|
+
testMode: config?.testMode ?? process.env.CHARGILY_TEST_MODE !== 'false',
|
|
107
|
+
successUrl: config?.successUrl ?? process.env.CHARGILY_SUCCESS_URL ?? '/payment/success',
|
|
108
|
+
failureUrl: config?.failureUrl ?? process.env.CHARGILY_FAILURE_URL ?? '/payment/failed',
|
|
109
|
+
webhookUrl: config?.webhookUrl ?? process.env.CHARGILY_WEBHOOK_URL,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=chargily.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chargily.provider.js","sourceRoot":"","sources":["../../src/providers/chargily.provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PaymentProvider, CheckoutParams, CheckoutResult, WebhookEvent } from '../core/provider.interface.js';
|
|
2
|
+
export interface ManualConfig {
|
|
3
|
+
bankInfo?: {
|
|
4
|
+
rib: string;
|
|
5
|
+
bankName: string;
|
|
6
|
+
holder: string;
|
|
7
|
+
};
|
|
8
|
+
confirmationUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class ManualProvider implements PaymentProvider {
|
|
11
|
+
private config;
|
|
12
|
+
readonly name = "manual";
|
|
13
|
+
readonly supportedCurrencies: string[];
|
|
14
|
+
readonly supportedMethods: string[];
|
|
15
|
+
constructor(config?: ManualConfig);
|
|
16
|
+
createCheckout(params: CheckoutParams): Promise<CheckoutResult>;
|
|
17
|
+
verifyWebhook(body: string, _signature: string): Promise<WebhookEvent>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createManualProvider(config?: ManualConfig): ManualProvider;
|
|
20
|
+
//# sourceMappingURL=manual.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual.provider.d.ts","sourceRoot":"","sources":["../../src/providers/manual.provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAElH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,qBAAa,cAAe,YAAW,eAAe;IAKxC,OAAO,CAAC,MAAM;IAJ1B,QAAQ,CAAC,IAAI,YAAW;IACxB,QAAQ,CAAC,mBAAmB,WAAQ;IACpC,QAAQ,CAAC,gBAAgB,WAA8B;gBAEnC,MAAM,GAAE,YAAiB;IAEvC,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAQ/D,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAI7E;AAED,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAE1E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @mostajs/payment — Manual provider (cash, bank transfer, TPE)
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
export class ManualProvider {
|
|
4
|
+
config;
|
|
5
|
+
name = 'manual';
|
|
6
|
+
supportedCurrencies = ['*'];
|
|
7
|
+
supportedMethods = ['cash', 'transfer', 'tpe'];
|
|
8
|
+
constructor(config = {}) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
}
|
|
11
|
+
async createCheckout(params) {
|
|
12
|
+
// No external redirect — return confirmation page URL
|
|
13
|
+
const url = this.config.confirmationUrl
|
|
14
|
+
? `${this.config.confirmationUrl}?orderId=${params.orderId}`
|
|
15
|
+
: params.successUrl;
|
|
16
|
+
return { url, sessionId: `manual_${params.orderId}` };
|
|
17
|
+
}
|
|
18
|
+
async verifyWebhook(body, _signature) {
|
|
19
|
+
const data = JSON.parse(body);
|
|
20
|
+
return { type: 'payment.manual', data };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function createManualProvider(config) {
|
|
24
|
+
return new ManualProvider(config);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=manual.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual.provider.js","sourceRoot":"","sources":["../../src/providers/manual.provider.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,wCAAwC;AASxC,MAAM,OAAO,cAAc;IAKL;IAJX,IAAI,GAAG,QAAQ,CAAA;IACf,mBAAmB,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3B,gBAAgB,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;IAEvD,YAAoB,SAAuB,EAAE;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAEjD,KAAK,CAAC,cAAc,CAAC,MAAsB;QACzC,sDAAsD;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe;YACrC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,YAAY,MAAM,CAAC,OAAO,EAAE;YAC5D,CAAC,CAAC,MAAM,CAAC,UAAU,CAAA;QACrB,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,MAAM,CAAC,OAAO,EAAE,EAAE,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,UAAkB;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC7B,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAA;IACzC,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAqB;IACxD,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAA;AACnC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PaymentProvider, CheckoutParams, CheckoutResult, RefundParams, RefundResult, WebhookEvent } from '../core/provider.interface.js';
|
|
2
|
+
export interface PayPalConfig {
|
|
3
|
+
clientId: string;
|
|
4
|
+
secret: string;
|
|
5
|
+
testMode?: boolean;
|
|
6
|
+
returnUrl: string;
|
|
7
|
+
cancelUrl: string;
|
|
8
|
+
webhookId?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class PayPalProvider implements PaymentProvider {
|
|
11
|
+
private config;
|
|
12
|
+
readonly name = "paypal";
|
|
13
|
+
readonly supportedCurrencies: string[];
|
|
14
|
+
readonly supportedMethods: string[];
|
|
15
|
+
private baseUrl;
|
|
16
|
+
private tokenCache;
|
|
17
|
+
constructor(config: PayPalConfig);
|
|
18
|
+
private getAccessToken;
|
|
19
|
+
private api;
|
|
20
|
+
createCheckout(params: CheckoutParams): Promise<CheckoutResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Capture a PayPal order after user approval.
|
|
23
|
+
* Call this when PayPal redirects back to returnUrl with ?token=ORDER_ID
|
|
24
|
+
*/
|
|
25
|
+
captureOrder(orderId: string): Promise<{
|
|
26
|
+
status: string;
|
|
27
|
+
data: Record<string, unknown>;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Get order details.
|
|
31
|
+
*/
|
|
32
|
+
getOrder(orderId: string): Promise<Record<string, unknown>>;
|
|
33
|
+
createRefund(params: RefundParams): Promise<RefundResult>;
|
|
34
|
+
verifyWebhook(body: string, signature: string): Promise<WebhookEvent>;
|
|
35
|
+
/**
|
|
36
|
+
* Verify webhook signature via PayPal API (production).
|
|
37
|
+
*/
|
|
38
|
+
verifyWebhookSignature(headers: Record<string, string>, body: string): Promise<boolean>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a PayPal provider from environment variables.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createPayPalProvider(config?: Partial<PayPalConfig>): PayPalProvider;
|
|
44
|
+
//# sourceMappingURL=paypal.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paypal.provider.d.ts","sourceRoot":"","sources":["../../src/providers/paypal.provider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAG9I,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,cAAe,YAAW,eAAe;IAQxC,OAAO,CAAC,MAAM;IAP1B,QAAQ,CAAC,IAAI,YAAW;IACxB,QAAQ,CAAC,mBAAmB,WAAoD;IAChF,QAAQ,CAAC,gBAAgB,WAAa;IAEtC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAAoD;gBAElD,MAAM,EAAE,YAAY;YAM1B,cAAc;YAwBd,GAAG;IAiBX,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IA0BrE;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAK/F;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAI3D,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAgBzD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAwB3E;;OAEG;IACG,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAa9F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,cAAc,CASnF"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// @mostajs/payment — PayPal REST API v2 provider
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
// Ref: https://developer.paypal.com/docs/api/orders/v2/
|
|
4
|
+
export class PayPalProvider {
|
|
5
|
+
config;
|
|
6
|
+
name = 'paypal';
|
|
7
|
+
supportedCurrencies = ['USD', 'EUR', 'GBP', 'CAD', 'AUD', 'JPY', 'CHF'];
|
|
8
|
+
supportedMethods = ['paypal'];
|
|
9
|
+
baseUrl;
|
|
10
|
+
tokenCache = null;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.baseUrl = config.testMode
|
|
14
|
+
? 'https://api-m.sandbox.paypal.com'
|
|
15
|
+
: 'https://api-m.paypal.com';
|
|
16
|
+
}
|
|
17
|
+
async getAccessToken() {
|
|
18
|
+
if (this.tokenCache && Date.now() < this.tokenCache.expiresAt) {
|
|
19
|
+
return this.tokenCache.token;
|
|
20
|
+
}
|
|
21
|
+
const auth = Buffer.from(`${this.config.clientId}:${this.config.secret}`).toString('base64');
|
|
22
|
+
const res = await fetch(`${this.baseUrl}/v1/oauth2/token`, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'Authorization': `Basic ${auth}`,
|
|
26
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
27
|
+
},
|
|
28
|
+
body: 'grant_type=client_credentials',
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok)
|
|
31
|
+
throw new Error(`[paypal] Token failed: ${res.statusText}`);
|
|
32
|
+
const data = await res.json();
|
|
33
|
+
this.tokenCache = {
|
|
34
|
+
token: data.access_token,
|
|
35
|
+
expiresAt: Date.now() + (data.expires_in - 60) * 1000, // refresh 1 min before expiry
|
|
36
|
+
};
|
|
37
|
+
return data.access_token;
|
|
38
|
+
}
|
|
39
|
+
async api(method, path, body) {
|
|
40
|
+
const token = await this.getAccessToken();
|
|
41
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
42
|
+
method,
|
|
43
|
+
headers: {
|
|
44
|
+
'Authorization': `Bearer ${token}`,
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
},
|
|
47
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
48
|
+
});
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
const err = await res.json().catch(() => ({}));
|
|
51
|
+
throw new Error(`[paypal] ${method} ${path} failed: ${err.message ?? err.error ?? res.statusText}`);
|
|
52
|
+
}
|
|
53
|
+
return res.status === 204 ? null : res.json();
|
|
54
|
+
}
|
|
55
|
+
async createCheckout(params) {
|
|
56
|
+
const currency = (params.currency ?? 'USD').toUpperCase();
|
|
57
|
+
const data = await this.api('POST', '/v2/checkout/orders', {
|
|
58
|
+
intent: 'CAPTURE',
|
|
59
|
+
purchase_units: [{
|
|
60
|
+
reference_id: params.orderId,
|
|
61
|
+
description: params.description,
|
|
62
|
+
amount: {
|
|
63
|
+
currency_code: currency,
|
|
64
|
+
value: params.amount.toFixed(2),
|
|
65
|
+
},
|
|
66
|
+
}],
|
|
67
|
+
application_context: {
|
|
68
|
+
return_url: params.successUrl ?? this.config.returnUrl,
|
|
69
|
+
cancel_url: params.cancelUrl ?? this.config.cancelUrl,
|
|
70
|
+
brand_name: 'OctoNet Cloud',
|
|
71
|
+
landing_page: 'LOGIN',
|
|
72
|
+
user_action: 'PAY_NOW',
|
|
73
|
+
},
|
|
74
|
+
...(params.metadata ? { metadata: params.metadata } : {}),
|
|
75
|
+
});
|
|
76
|
+
const approveLink = data.links?.find((l) => l.rel === 'approve');
|
|
77
|
+
return { url: approveLink?.href ?? null, sessionId: data.id };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Capture a PayPal order after user approval.
|
|
81
|
+
* Call this when PayPal redirects back to returnUrl with ?token=ORDER_ID
|
|
82
|
+
*/
|
|
83
|
+
async captureOrder(orderId) {
|
|
84
|
+
const data = await this.api('POST', `/v2/checkout/orders/${orderId}/capture`, {});
|
|
85
|
+
return { status: data.status, data };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get order details.
|
|
89
|
+
*/
|
|
90
|
+
async getOrder(orderId) {
|
|
91
|
+
return this.api('GET', `/v2/checkout/orders/${orderId}`);
|
|
92
|
+
}
|
|
93
|
+
async createRefund(params) {
|
|
94
|
+
// PayPal refunds work on captures, not orders
|
|
95
|
+
const body = {};
|
|
96
|
+
if (params.amount) {
|
|
97
|
+
body.amount = { value: params.amount.toFixed(2), currency_code: 'USD' };
|
|
98
|
+
}
|
|
99
|
+
if (params.reason)
|
|
100
|
+
body.note_to_payer = params.reason;
|
|
101
|
+
const data = await this.api('POST', `/v2/payments/captures/${params.paymentId}/refund`, body);
|
|
102
|
+
return {
|
|
103
|
+
id: data.id,
|
|
104
|
+
amount: parseFloat(data.amount?.value ?? '0'),
|
|
105
|
+
status: data.status,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async verifyWebhook(body, signature) {
|
|
109
|
+
// PayPal webhook verification requires calling their API
|
|
110
|
+
// For simplicity, parse the event and validate via API
|
|
111
|
+
const event = JSON.parse(body);
|
|
112
|
+
// In production, verify via POST /v1/notifications/verify-webhook-signature
|
|
113
|
+
// For now, trust the parsed event
|
|
114
|
+
const type = event.event_type === 'CHECKOUT.ORDER.APPROVED' ? 'payment.approved'
|
|
115
|
+
: event.event_type === 'PAYMENT.CAPTURE.COMPLETED' ? 'payment.success'
|
|
116
|
+
: event.event_type === 'PAYMENT.CAPTURE.DENIED' ? 'payment.failed'
|
|
117
|
+
: event.event_type ?? 'unknown';
|
|
118
|
+
return {
|
|
119
|
+
type,
|
|
120
|
+
data: {
|
|
121
|
+
orderId: event.resource?.id,
|
|
122
|
+
status: event.resource?.status,
|
|
123
|
+
amount: event.resource?.amount?.value,
|
|
124
|
+
currency: event.resource?.amount?.currency_code,
|
|
125
|
+
},
|
|
126
|
+
raw: event,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Verify webhook signature via PayPal API (production).
|
|
131
|
+
*/
|
|
132
|
+
async verifyWebhookSignature(headers, body) {
|
|
133
|
+
if (!this.config.webhookId)
|
|
134
|
+
return false;
|
|
135
|
+
const data = await this.api('POST', '/v1/notifications/verify-webhook-signature', {
|
|
136
|
+
auth_algo: headers['paypal-auth-algo'],
|
|
137
|
+
cert_url: headers['paypal-cert-url'],
|
|
138
|
+
transmission_id: headers['paypal-transmission-id'],
|
|
139
|
+
transmission_sig: headers['paypal-transmission-sig'],
|
|
140
|
+
transmission_time: headers['paypal-transmission-time'],
|
|
141
|
+
webhook_id: this.config.webhookId,
|
|
142
|
+
webhook_event: JSON.parse(body),
|
|
143
|
+
});
|
|
144
|
+
return data.verification_status === 'SUCCESS';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Create a PayPal provider from environment variables.
|
|
149
|
+
*/
|
|
150
|
+
export function createPayPalProvider(config) {
|
|
151
|
+
return new PayPalProvider({
|
|
152
|
+
clientId: config?.clientId ?? process.env.PAYPAL_CLIENT_ID ?? '',
|
|
153
|
+
secret: config?.secret ?? process.env.PAYPAL_SECRET ?? '',
|
|
154
|
+
testMode: config?.testMode ?? process.env.PAYPAL_TEST_MODE !== 'false',
|
|
155
|
+
returnUrl: config?.returnUrl ?? process.env.PAYPAL_RETURN_URL ?? '/payment/success',
|
|
156
|
+
cancelUrl: config?.cancelUrl ?? process.env.PAYPAL_CANCEL_URL ?? '/payment/canceled',
|
|
157
|
+
webhookId: config?.webhookId ?? process.env.PAYPAL_WEBHOOK_ID,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=paypal.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paypal.provider.js","sourceRoot":"","sources":["../../src/providers/paypal.provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { PaymentProvider, CheckoutParams, CheckoutResult, WebhookEvent } from '../core/provider.interface.js';
|
|
2
|
+
export interface SatimConfig {
|
|
3
|
+
merchantId: string;
|
|
4
|
+
password: string;
|
|
5
|
+
testMode?: boolean;
|
|
6
|
+
returnUrl: string;
|
|
7
|
+
failUrl: string;
|
|
8
|
+
/** ISO 4217 currency code, default '012' (DZD) */
|
|
9
|
+
currencyCode?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class SatimProvider implements PaymentProvider {
|
|
12
|
+
private config;
|
|
13
|
+
readonly name = "satim";
|
|
14
|
+
readonly supportedCurrencies: string[];
|
|
15
|
+
readonly supportedMethods: string[];
|
|
16
|
+
private baseUrl;
|
|
17
|
+
constructor(config: SatimConfig);
|
|
18
|
+
createCheckout(params: CheckoutParams): Promise<CheckoutResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Confirm an order after redirect callback.
|
|
21
|
+
* Call this when Satim redirects back to returnUrl.
|
|
22
|
+
*/
|
|
23
|
+
confirmOrder(orderId: string): Promise<{
|
|
24
|
+
paid: boolean;
|
|
25
|
+
actionCode: string;
|
|
26
|
+
errorMessage?: string;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Get order status.
|
|
30
|
+
*/
|
|
31
|
+
getOrderStatus(orderId: string): Promise<Record<string, unknown>>;
|
|
32
|
+
verifyWebhook(body: string, _signature: string): Promise<WebhookEvent>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a Satim provider from environment variables.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createSatimProvider(config?: Partial<SatimConfig>): SatimProvider;
|
|
38
|
+
//# sourceMappingURL=satim.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"satim.provider.d.ts","sourceRoot":"","sources":["../../src/providers/satim.provider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAElH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,qBAAa,aAAc,YAAW,eAAe;IAOvC,OAAO,CAAC,MAAM;IAN1B,QAAQ,CAAC,IAAI,WAAU;IACvB,QAAQ,CAAC,mBAAmB,WAAU;IACtC,QAAQ,CAAC,gBAAgB,WAAU;IAEnC,OAAO,CAAC,OAAO,CAAQ;gBAEH,MAAM,EAAE,WAAW;IAMjC,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IA6BrE;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAsB1G;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAiBjE,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAgB7E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,aAAa,CAQhF"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// @mostajs/payment — Satim/GIE Monetique provider (CIB — Algerie)
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
// Ref: https://test.satim.dz/payment/rest/ (sandbox)
|
|
4
|
+
export class SatimProvider {
|
|
5
|
+
config;
|
|
6
|
+
name = 'satim';
|
|
7
|
+
supportedCurrencies = ['DZD'];
|
|
8
|
+
supportedMethods = ['cib'];
|
|
9
|
+
baseUrl;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.baseUrl = config.testMode
|
|
13
|
+
? 'https://test.satim.dz/payment/rest'
|
|
14
|
+
: 'https://cib.satim.dz/payment/rest';
|
|
15
|
+
}
|
|
16
|
+
async createCheckout(params) {
|
|
17
|
+
const body = new URLSearchParams({
|
|
18
|
+
orderNumber: params.orderId,
|
|
19
|
+
amount: String(Math.round(params.amount * 100)), // centimes DZD
|
|
20
|
+
currency: this.config.currencyCode ?? '012', // ISO 4217 DZD
|
|
21
|
+
returnUrl: params.successUrl ?? this.config.returnUrl,
|
|
22
|
+
failUrl: params.cancelUrl ?? this.config.failUrl,
|
|
23
|
+
userName: this.config.merchantId,
|
|
24
|
+
password: this.config.password,
|
|
25
|
+
language: 'FR',
|
|
26
|
+
});
|
|
27
|
+
if (params.description)
|
|
28
|
+
body.set('description', params.description);
|
|
29
|
+
const res = await fetch(`${this.baseUrl}/register.do`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
32
|
+
body,
|
|
33
|
+
});
|
|
34
|
+
const data = await res.json();
|
|
35
|
+
if (data.errorCode && data.errorCode !== '0') {
|
|
36
|
+
throw new Error(`[satim] ${data.errorMessage ?? 'Registration failed'} (code: ${data.errorCode})`);
|
|
37
|
+
}
|
|
38
|
+
return { url: data.formUrl, sessionId: data.orderId };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Confirm an order after redirect callback.
|
|
42
|
+
* Call this when Satim redirects back to returnUrl.
|
|
43
|
+
*/
|
|
44
|
+
async confirmOrder(orderId) {
|
|
45
|
+
const body = new URLSearchParams({
|
|
46
|
+
orderId,
|
|
47
|
+
userName: this.config.merchantId,
|
|
48
|
+
password: this.config.password,
|
|
49
|
+
language: 'FR',
|
|
50
|
+
});
|
|
51
|
+
const res = await fetch(`${this.baseUrl}/confirmOrder.do`, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
54
|
+
body,
|
|
55
|
+
});
|
|
56
|
+
const data = await res.json();
|
|
57
|
+
return {
|
|
58
|
+
paid: data.actionCode === 0 || data.actionCode === '0',
|
|
59
|
+
actionCode: String(data.actionCode),
|
|
60
|
+
errorMessage: data.ErrorMessage ?? data.errorMessage,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get order status.
|
|
65
|
+
*/
|
|
66
|
+
async getOrderStatus(orderId) {
|
|
67
|
+
const body = new URLSearchParams({
|
|
68
|
+
orderId,
|
|
69
|
+
userName: this.config.merchantId,
|
|
70
|
+
password: this.config.password,
|
|
71
|
+
language: 'FR',
|
|
72
|
+
});
|
|
73
|
+
const res = await fetch(`${this.baseUrl}/getOrderStatus.do`, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
76
|
+
body,
|
|
77
|
+
});
|
|
78
|
+
return res.json();
|
|
79
|
+
}
|
|
80
|
+
async verifyWebhook(body, _signature) {
|
|
81
|
+
// Satim uses redirect-based callbacks, not webhooks
|
|
82
|
+
// Parse the callback params
|
|
83
|
+
const params = new URLSearchParams(body);
|
|
84
|
+
const orderId = params.get('orderId') ?? '';
|
|
85
|
+
if (orderId) {
|
|
86
|
+
const status = await this.confirmOrder(orderId);
|
|
87
|
+
return {
|
|
88
|
+
type: status.paid ? 'payment.success' : 'payment.failed',
|
|
89
|
+
data: { orderId, ...status },
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return { type: 'unknown', data: {} };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create a Satim provider from environment variables.
|
|
97
|
+
*/
|
|
98
|
+
export function createSatimProvider(config) {
|
|
99
|
+
return new SatimProvider({
|
|
100
|
+
merchantId: config?.merchantId ?? process.env.SATIM_MERCHANT_ID ?? '',
|
|
101
|
+
password: config?.password ?? process.env.SATIM_PASSWORD ?? '',
|
|
102
|
+
testMode: config?.testMode ?? process.env.SATIM_TEST_MODE === 'true',
|
|
103
|
+
returnUrl: config?.returnUrl ?? process.env.SATIM_RETURN_URL ?? '/payment/callback',
|
|
104
|
+
failUrl: config?.failUrl ?? process.env.SATIM_FAIL_URL ?? '/payment/failed',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=satim.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"satim.provider.js","sourceRoot":"","sources":["../../src/providers/satim.provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import Stripe from 'stripe';
|
|
2
|
+
import type { PaymentProvider, CheckoutParams, CheckoutResult, CustomerParams, SubscriptionParams, SubscriptionResult, RefundParams, RefundResult, InvoiceResult, WebhookEvent } from '../core/provider.interface.js';
|
|
3
|
+
export interface StripeConfig {
|
|
4
|
+
secretKey: string;
|
|
5
|
+
webhookSecret?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class StripeProvider implements PaymentProvider {
|
|
8
|
+
private config;
|
|
9
|
+
readonly name = "stripe";
|
|
10
|
+
readonly supportedCurrencies: string[];
|
|
11
|
+
readonly supportedMethods: string[];
|
|
12
|
+
stripe: Stripe;
|
|
13
|
+
constructor(config: StripeConfig);
|
|
14
|
+
createCheckout(params: CheckoutParams): Promise<CheckoutResult>;
|
|
15
|
+
createCustomer(params: CustomerParams): Promise<string>;
|
|
16
|
+
getCustomer(customerId: string): Promise<Record<string, unknown>>;
|
|
17
|
+
updateCustomer(customerId: string, params: Partial<CustomerParams>): Promise<Record<string, unknown>>;
|
|
18
|
+
createSubscription(params: SubscriptionParams): Promise<SubscriptionResult>;
|
|
19
|
+
getSubscription(subscriptionId: string): Promise<SubscriptionResult>;
|
|
20
|
+
cancelSubscription(subscriptionId: string, immediate?: boolean): Promise<void>;
|
|
21
|
+
changeSubscription(subscriptionId: string, newPriceId: string): Promise<SubscriptionResult>;
|
|
22
|
+
pauseSubscription(subscriptionId: string): Promise<void>;
|
|
23
|
+
resumeSubscription(subscriptionId: string): Promise<void>;
|
|
24
|
+
createRefund(params: RefundParams): Promise<RefundResult>;
|
|
25
|
+
listInvoices(customerId: string, limit?: number): Promise<InvoiceResult[]>;
|
|
26
|
+
getUpcomingInvoice(customerId: string): Promise<InvoiceResult | null>;
|
|
27
|
+
createPortal(customerId: string, returnUrl: string): Promise<{
|
|
28
|
+
url: string;
|
|
29
|
+
}>;
|
|
30
|
+
verifyWebhook(body: string, signature: string): Promise<WebhookEvent>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a Stripe provider from environment variables.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createStripeProvider(config?: Partial<StripeConfig>): StripeProvider;
|
|
36
|
+
//# sourceMappingURL=stripe.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.provider.d.ts","sourceRoot":"","sources":["../../src/providers/stripe.provider.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,KAAK,EACV,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAC/D,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAClE,aAAa,EAAE,YAAY,EAC5B,MAAM,+BAA+B,CAAA;AAEtC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,qBAAa,cAAe,YAAW,eAAe;IAOxC,OAAO,CAAC,MAAM;IAN1B,QAAQ,CAAC,IAAI,YAAW;IACxB,QAAQ,CAAC,mBAAmB,WAAQ;IACpC,QAAQ,CAAC,gBAAgB,WAAW;IAE7B,MAAM,EAAE,MAAM,CAAA;gBAED,MAAM,EAAE,YAAY;IAOlC,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAsC/D,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IASvD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAKjE,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAWrG,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAe3E,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAUpE,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9E,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAa3F,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxD,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzD,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAezD,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAY1E,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAgBrE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAU7E,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAmB5E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,cAAc,CAKnF"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// @mostajs/payment — Stripe provider (refactored from lib/stripe.ts)
|
|
2
|
+
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
+
import Stripe from 'stripe';
|
|
4
|
+
export class StripeProvider {
|
|
5
|
+
config;
|
|
6
|
+
name = 'stripe';
|
|
7
|
+
supportedCurrencies = ['*']; // all currencies
|
|
8
|
+
supportedMethods = ['card'];
|
|
9
|
+
stripe;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
if (!config.secretKey)
|
|
13
|
+
throw new Error('[stripe] secretKey is required');
|
|
14
|
+
this.stripe = new Stripe(config.secretKey);
|
|
15
|
+
}
|
|
16
|
+
// ─── Checkout ─────────────────────────────────
|
|
17
|
+
async createCheckout(params) {
|
|
18
|
+
if (params.priceId && params.customerId) {
|
|
19
|
+
// Subscription billing
|
|
20
|
+
const sessionParams = {
|
|
21
|
+
customer: params.customerId,
|
|
22
|
+
mode: 'subscription',
|
|
23
|
+
line_items: [{ price: params.priceId, quantity: 1 }],
|
|
24
|
+
success_url: params.successUrl,
|
|
25
|
+
cancel_url: params.cancelUrl,
|
|
26
|
+
metadata: params.metadata,
|
|
27
|
+
};
|
|
28
|
+
if (params.trialDays)
|
|
29
|
+
sessionParams.subscription_data = { trial_period_days: params.trialDays };
|
|
30
|
+
const session = await this.stripe.checkout.sessions.create(sessionParams);
|
|
31
|
+
return { url: session.url, sessionId: session.id };
|
|
32
|
+
}
|
|
33
|
+
// One-time payment
|
|
34
|
+
const currency = (params.currency ?? 'usd').toLowerCase();
|
|
35
|
+
const session = await this.stripe.checkout.sessions.create({
|
|
36
|
+
payment_method_types: ['card'],
|
|
37
|
+
line_items: [{
|
|
38
|
+
price_data: {
|
|
39
|
+
currency,
|
|
40
|
+
product_data: { name: params.description ?? `Order ${params.orderId}` },
|
|
41
|
+
unit_amount: Math.round(params.amount * 100),
|
|
42
|
+
},
|
|
43
|
+
quantity: 1,
|
|
44
|
+
}],
|
|
45
|
+
mode: 'payment',
|
|
46
|
+
success_url: params.successUrl,
|
|
47
|
+
cancel_url: params.cancelUrl,
|
|
48
|
+
metadata: { orderId: params.orderId, ...params.metadata },
|
|
49
|
+
});
|
|
50
|
+
return { url: session.url, sessionId: session.id };
|
|
51
|
+
}
|
|
52
|
+
// ─── Customers ────────────────────────────────
|
|
53
|
+
async createCustomer(params) {
|
|
54
|
+
const customer = await this.stripe.customers.create({
|
|
55
|
+
email: params.email,
|
|
56
|
+
name: params.name,
|
|
57
|
+
metadata: params.metadata,
|
|
58
|
+
});
|
|
59
|
+
return customer.id;
|
|
60
|
+
}
|
|
61
|
+
async getCustomer(customerId) {
|
|
62
|
+
const c = await this.stripe.customers.retrieve(customerId);
|
|
63
|
+
return c;
|
|
64
|
+
}
|
|
65
|
+
async updateCustomer(customerId, params) {
|
|
66
|
+
const c = await this.stripe.customers.update(customerId, {
|
|
67
|
+
...(params.name ? { name: params.name } : {}),
|
|
68
|
+
...(params.email ? { email: params.email } : {}),
|
|
69
|
+
...(params.metadata ? { metadata: params.metadata } : {}),
|
|
70
|
+
});
|
|
71
|
+
return c;
|
|
72
|
+
}
|
|
73
|
+
// ─── Subscriptions ────────────────────────────
|
|
74
|
+
async createSubscription(params) {
|
|
75
|
+
const sub = await this.stripe.subscriptions.create({
|
|
76
|
+
customer: params.customerId,
|
|
77
|
+
items: [{ price: params.priceId }],
|
|
78
|
+
trial_period_days: params.trialDays,
|
|
79
|
+
metadata: params.metadata,
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
id: sub.id,
|
|
83
|
+
status: sub.status,
|
|
84
|
+
customerId: sub.customer,
|
|
85
|
+
currentPeriodEnd: new Date(sub.current_period_end * 1000).toISOString(),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async getSubscription(subscriptionId) {
|
|
89
|
+
const sub = await this.stripe.subscriptions.retrieve(subscriptionId);
|
|
90
|
+
return {
|
|
91
|
+
id: sub.id,
|
|
92
|
+
status: sub.status,
|
|
93
|
+
customerId: sub.customer,
|
|
94
|
+
currentPeriodEnd: new Date(sub.current_period_end * 1000).toISOString(),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async cancelSubscription(subscriptionId, immediate) {
|
|
98
|
+
if (immediate) {
|
|
99
|
+
await this.stripe.subscriptions.cancel(subscriptionId);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
await this.stripe.subscriptions.update(subscriptionId, { cancel_at_period_end: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async changeSubscription(subscriptionId, newPriceId) {
|
|
106
|
+
const sub = await this.stripe.subscriptions.retrieve(subscriptionId);
|
|
107
|
+
const updated = await this.stripe.subscriptions.update(subscriptionId, {
|
|
108
|
+
items: [{ id: sub.items.data[0].id, price: newPriceId }],
|
|
109
|
+
proration_behavior: 'always_invoice',
|
|
110
|
+
});
|
|
111
|
+
return {
|
|
112
|
+
id: updated.id,
|
|
113
|
+
status: updated.status,
|
|
114
|
+
customerId: updated.customer,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async pauseSubscription(subscriptionId) {
|
|
118
|
+
await this.stripe.subscriptions.update(subscriptionId, {
|
|
119
|
+
pause_collection: { behavior: 'void' },
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async resumeSubscription(subscriptionId) {
|
|
123
|
+
await this.stripe.subscriptions.update(subscriptionId, {
|
|
124
|
+
pause_collection: '',
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// ─── Refunds ──────────────────────────────────
|
|
128
|
+
async createRefund(params) {
|
|
129
|
+
const refund = await this.stripe.refunds.create({
|
|
130
|
+
payment_intent: params.paymentId,
|
|
131
|
+
...(params.amount ? { amount: Math.round(params.amount * 100) } : {}),
|
|
132
|
+
...(params.metadata ? { metadata: params.metadata } : {}),
|
|
133
|
+
});
|
|
134
|
+
return {
|
|
135
|
+
id: refund.id,
|
|
136
|
+
amount: (refund.amount ?? 0) / 100,
|
|
137
|
+
status: refund.status ?? 'pending',
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// ─── Invoices ─────────────────────────────────
|
|
141
|
+
async listInvoices(customerId, limit) {
|
|
142
|
+
const invoices = await this.stripe.invoices.list({ customer: customerId, limit: limit ?? 10 });
|
|
143
|
+
return invoices.data.map(inv => ({
|
|
144
|
+
id: inv.id,
|
|
145
|
+
amount: (inv.amount_paid ?? 0) / 100,
|
|
146
|
+
currency: inv.currency ?? 'usd',
|
|
147
|
+
status: inv.status ?? 'draft',
|
|
148
|
+
paidAt: inv.status_transitions?.paid_at ? new Date(inv.status_transitions.paid_at * 1000).toISOString() : undefined,
|
|
149
|
+
pdfUrl: inv.invoice_pdf ?? undefined,
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
async getUpcomingInvoice(customerId) {
|
|
153
|
+
try {
|
|
154
|
+
const inv = await this.stripe.invoices.retrieveUpcoming({ customer: customerId });
|
|
155
|
+
return {
|
|
156
|
+
id: 'upcoming',
|
|
157
|
+
amount: (inv.amount_due ?? 0) / 100,
|
|
158
|
+
currency: inv.currency ?? 'usd',
|
|
159
|
+
status: 'upcoming',
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// ─── Portal ───────────────────────────────────
|
|
167
|
+
async createPortal(customerId, returnUrl) {
|
|
168
|
+
const session = await this.stripe.billingPortal.sessions.create({
|
|
169
|
+
customer: customerId,
|
|
170
|
+
return_url: returnUrl,
|
|
171
|
+
});
|
|
172
|
+
return { url: session.url };
|
|
173
|
+
}
|
|
174
|
+
// ─── Webhooks ─────────────────────────────────
|
|
175
|
+
async verifyWebhook(body, signature) {
|
|
176
|
+
if (!this.config.webhookSecret)
|
|
177
|
+
throw new Error('[stripe] webhookSecret required for webhook verification');
|
|
178
|
+
const event = this.stripe.webhooks.constructEvent(body, signature, this.config.webhookSecret);
|
|
179
|
+
const typeMap = {
|
|
180
|
+
'checkout.session.completed': 'payment.success',
|
|
181
|
+
'customer.subscription.created': 'subscription.created',
|
|
182
|
+
'customer.subscription.updated': 'subscription.updated',
|
|
183
|
+
'customer.subscription.deleted': 'subscription.deleted',
|
|
184
|
+
'invoice.paid': 'invoice.paid',
|
|
185
|
+
'invoice.payment_failed': 'invoice.failed',
|
|
186
|
+
};
|
|
187
|
+
return {
|
|
188
|
+
type: typeMap[event.type] ?? event.type,
|
|
189
|
+
data: event.data.object,
|
|
190
|
+
raw: event,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Create a Stripe provider from environment variables.
|
|
196
|
+
*/
|
|
197
|
+
export function createStripeProvider(config) {
|
|
198
|
+
return new StripeProvider({
|
|
199
|
+
secretKey: config?.secretKey ?? process.env.STRIPE_SECRET_KEY ?? '',
|
|
200
|
+
webhookSecret: config?.webhookSecret ?? process.env.STRIPE_WEBHOOK_SECRET,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=stripe.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.provider.js","sourceRoot":"","sources":["../../src/providers/stripe.provider.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,wCAAwC;AAExC,OAAO,MAAM,MAAM,QAAQ,CAAA;AAY3B,MAAM,OAAO,cAAc;IAOL;IANX,IAAI,GAAG,QAAQ,CAAA;IACf,mBAAmB,GAAG,CAAC,GAAG,CAAC,CAAA,CAAC,iBAAiB;IAC7C,gBAAgB,GAAG,CAAC,MAAM,CAAC,CAAA;IAE7B,MAAM,CAAQ;IAErB,YAAoB,MAAoB;QAApB,WAAM,GAAN,MAAM,CAAc;QACtC,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACxE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC5C,CAAC;IAED,iDAAiD;IAEjD,KAAK,CAAC,cAAc,CAAC,MAAsB;QACzC,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACxC,uBAAuB;YACvB,MAAM,aAAa,GAAQ;gBACzB,QAAQ,EAAE,MAAM,CAAC,UAAU;gBAC3B,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBACpD,WAAW,EAAE,MAAM,CAAC,UAAU;gBAC9B,UAAU,EAAE,MAAM,CAAC,SAAS;gBAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAA;YACD,IAAI,MAAM,CAAC,SAAS;gBAAE,aAAa,CAAC,iBAAiB,GAAG,EAAE,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,CAAA;YAC/F,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;YACzE,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAA;QACpD,CAAC;QAED,mBAAmB;QACnB,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;QACzD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;YACzD,oBAAoB,EAAE,CAAC,MAAM,CAAC;YAC9B,UAAU,EAAE,CAAC;oBACX,UAAU,EAAE;wBACV,QAAQ;wBACR,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,IAAI,SAAS,MAAM,CAAC,OAAO,EAAE,EAAE;wBACvE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC;qBAC7C;oBACD,QAAQ,EAAE,CAAC;iBACZ,CAAC;YACF,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,MAAM,CAAC,UAAU;YAC9B,UAAU,EAAE,MAAM,CAAC,SAAS;YAC5B,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE;SAC1D,CAAC,CAAA;QACF,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAA;IACpD,CAAC;IAED,iDAAiD;IAEjD,KAAK,CAAC,cAAc,CAAC,MAAsB;QACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;YAClD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC,CAAA;QACF,OAAO,QAAQ,CAAC,EAAE,CAAA;IACpB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,UAAkB;QAClC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;QAC1D,OAAO,CAAuC,CAAA;IAChD,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,UAAkB,EAAE,MAA+B;QACtE,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE;YACvD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1D,CAAC,CAAA;QACF,OAAO,CAAuC,CAAA;IAChD,CAAC;IAED,iDAAiD;IAEjD,KAAK,CAAC,kBAAkB,CAAC,MAA0B;QACjD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;YACjD,QAAQ,EAAE,MAAM,CAAC,UAAU;YAC3B,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YAClC,iBAAiB,EAAE,MAAM,CAAC,SAAS;YACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC,CAAA;QACF,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,UAAU,EAAE,GAAG,CAAC,QAAkB;YAClC,gBAAgB,EAAE,IAAI,IAAI,CAAE,GAAW,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;SACjF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,cAAsB;QAC1C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA;QACpE,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,UAAU,EAAE,GAAG,CAAC,QAAkB;YAClC,gBAAgB,EAAE,IAAI,IAAI,CAAE,GAAW,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;SACjF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,cAAsB,EAAE,SAAmB;QAClE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;QACxD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAA;QACxF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,cAAsB,EAAE,UAAkB;QACjE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA;QACpE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE;YACrE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;YACxD,kBAAkB,EAAE,gBAAgB;SACrC,CAAC,CAAA;QACF,OAAO;YACL,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,OAAO,CAAC,QAAkB;SACvC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,cAAsB;QAC5C,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE;YACrD,gBAAgB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;SACvC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,cAAsB;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE;YACrD,gBAAgB,EAAE,EAAE;SACd,CAAC,CAAA;IACX,CAAC;IAED,iDAAiD;IAEjD,KAAK,CAAC,YAAY,CAAC,MAAoB;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;YAC9C,cAAc,EAAE,MAAM,CAAC,SAAS;YAChC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1D,CAAC,CAAA;QACF,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG;YAClC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,SAAS;SACnC,CAAA;IACH,CAAC;IAED,iDAAiD;IAEjD,KAAK,CAAC,YAAY,CAAC,UAAkB,EAAE,KAAc;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAA;QAC9F,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/B,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,GAAG;YACpC,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,KAAK;YAC/B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,OAAO;YAC7B,MAAM,EAAE,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS;YACnH,MAAM,EAAE,GAAG,CAAC,WAAW,IAAI,SAAS;SACrC,CAAC,CAAC,CAAA;IACL,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,UAAkB;QACzC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAA;YACjF,OAAO;gBACL,EAAE,EAAE,UAAU;gBACd,MAAM,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,GAAG;gBACnC,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,KAAK;gBAC/B,MAAM,EAAE,UAAU;aACnB,CAAA;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,iDAAiD;IAEjD,KAAK,CAAC,YAAY,CAAC,UAAkB,EAAE,SAAiB;QACtD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC9D,QAAQ,EAAE,UAAU;YACpB,UAAU,EAAE,SAAS;SACtB,CAAC,CAAA;QACF,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAA;IAC7B,CAAC;IAED,iDAAiD;IAEjD,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,SAAiB;QACjD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa;YAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;QAC3G,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QAE7F,MAAM,OAAO,GAA2B;YACtC,4BAA4B,EAAE,iBAAiB;YAC/C,+BAA+B,EAAE,sBAAsB;YACvD,+BAA+B,EAAE,sBAAsB;YACvD,+BAA+B,EAAE,sBAAsB;YACvD,cAAc,EAAE,cAAc;YAC9B,wBAAwB,EAAE,gBAAgB;SAC3C,CAAA;QAED,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI;YACvC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAA4C;YAC7D,GAAG,EAAE,KAAK;SACX,CAAA;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAA8B;IACjE,OAAO,IAAI,cAAc,CAAC;QACxB,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE;QACnE,aAAa,EAAE,MAAM,EAAE,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB;KAC1E,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
export type { PaymentProvider, CheckoutParams, CheckoutResult, CustomerParams, SubscriptionParams, SubscriptionResult, RefundParams, RefundResult, InvoiceResult, WebhookEvent, } from './core/provider.interface.js';
|
|
2
|
+
export { registerProvider, setDefaultProvider, getProvider, listProviders, getProviderForCurrency, resetProviders, } from './core/payment-engine.js';
|
|
3
|
+
export { SatimProvider, createSatimProvider } from './providers/satim.provider.js';
|
|
4
|
+
export type { SatimConfig } from './providers/satim.provider.js';
|
|
5
|
+
export { ChargilyProvider, createChargilyProvider } from './providers/chargily.provider.js';
|
|
6
|
+
export type { ChargilyConfig } from './providers/chargily.provider.js';
|
|
7
|
+
export { PayPalProvider, createPayPalProvider } from './providers/paypal.provider.js';
|
|
8
|
+
export type { PayPalConfig } from './providers/paypal.provider.js';
|
|
9
|
+
export { StripeProvider, createStripeProvider } from './providers/stripe.provider.js';
|
|
10
|
+
export type { StripeConfig } from './providers/stripe.provider.js';
|
|
11
|
+
export { ManualProvider, createManualProvider } from './providers/manual.provider.js';
|
|
12
|
+
export type { ManualConfig } from './providers/manual.provider.js';
|
|
1
13
|
export { createStripeClient, createCheckoutSession, handleWebhook, createBillingSession, createPortalSession, handleBillingWebhook, } from './lib/stripe.js';
|
|
2
14
|
export type { WebhookHandlers } from './lib/stripe.js';
|
|
3
15
|
export { getPaymentRepo, resetPaymentRepo } from './lib/payment-factory.js';
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EACxD,oBAAoB,EAAE,mBAAmB,EAAE,oBAAoB,GAChE,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGtD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAG3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAG/D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAC/D,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAClE,aAAa,EAAE,YAAY,GAC5B,MAAM,8BAA8B,CAAA;AAErC,OAAO,EACL,gBAAgB,EAAE,kBAAkB,EAAE,WAAW,EACjD,aAAa,EAAE,sBAAsB,EAAE,cAAc,GACtD,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAClF,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAEhE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AAC3F,YAAY,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AACrF,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAElE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AACrF,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAElE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AACrF,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAGlE,OAAO,EACL,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EACxD,oBAAoB,EAAE,mBAAmB,EAAE,oBAAoB,GAChE,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGtD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAG3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAG/D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/server.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
// @mostajs/payment — Server-side exports
|
|
1
|
+
// @mostajs/payment v0.3 — Server-side exports
|
|
2
2
|
// Author: Dr Hamid MADANI drmdh@msn.com
|
|
3
|
-
|
|
3
|
+
export { registerProvider, setDefaultProvider, getProvider, listProviders, getProviderForCurrency, resetProviders, } from './core/payment-engine.js';
|
|
4
|
+
// ─── Providers ──────────────────────────────────
|
|
5
|
+
export { SatimProvider, createSatimProvider } from './providers/satim.provider.js';
|
|
6
|
+
export { ChargilyProvider, createChargilyProvider } from './providers/chargily.provider.js';
|
|
7
|
+
export { PayPalProvider, createPayPalProvider } from './providers/paypal.provider.js';
|
|
8
|
+
export { StripeProvider, createStripeProvider } from './providers/stripe.provider.js';
|
|
9
|
+
export { ManualProvider, createManualProvider } from './providers/manual.provider.js';
|
|
10
|
+
// ─── Legacy Stripe functions (backward compat) ─
|
|
4
11
|
export { createStripeClient, createCheckoutSession, handleWebhook, createBillingSession, createPortalSession, handleBillingWebhook, } from './lib/stripe.js';
|
|
5
|
-
// Repository
|
|
12
|
+
// ─── Repository ─────────────────────────────────
|
|
6
13
|
export { getPaymentRepo, resetPaymentRepo } from './lib/payment-factory.js';
|
|
7
|
-
// API handlers
|
|
14
|
+
// ─── API handlers ───────────────────────────────
|
|
8
15
|
export { createCheckoutHandler } from './api/checkout.route.js';
|
|
9
16
|
export { createPaymentHandlers } from './api/payments.route.js';
|
|
10
|
-
// Module info
|
|
17
|
+
// ─── Module info ────────────────────────────────
|
|
11
18
|
export { getSchemas, moduleInfo } from './lib/module-info.js';
|
|
12
|
-
// Registration
|
|
13
19
|
export { paymentModuleRegistration } from './register.js';
|
|
14
20
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,wCAAwC;AASxC,OAAO,EACL,gBAAgB,EAAE,kBAAkB,EAAE,WAAW,EACjD,aAAa,EAAE,sBAAsB,EAAE,cAAc,GACtD,MAAM,0BAA0B,CAAA;AAEjC,mDAAmD;AACnD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAGlF,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AAG3F,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAGrF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAGrF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAGrF,kDAAkD;AAClD,OAAO,EACL,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EACxD,oBAAoB,EAAE,mBAAmB,EAAE,oBAAoB,GAChE,MAAM,iBAAiB,CAAA;AAGxB,mDAAmD;AACnD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3E,mDAAmD;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAE/D,mDAAmD;AACnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/payment",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Payment module for @mostajs —
|
|
3
|
+
"version": "0.3.0",
|
|
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": "MIT",
|
|
7
7
|
"type": "module",
|