From b12bd0cdd629b93a1dc76def083f0d74eb59463d Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Fri, 21 Aug 2026 08:10:37 +0400 Subject: [PATCH] release: @marketplaces/payment 0.1.0 (5ffc1b1) --- dist/.npmignore | 2 + dist/fesm2022/marketplaces-payment.mjs | 210 +++++++++++++++++++++ dist/fesm2022/marketplaces-payment.mjs.map | 1 + dist/index.d.ts | 1 - dist/index.js | 1 - dist/package.json | 34 ++++ dist/types/marketplaces-payment.d.ts | 104 ++++++++++ package.json | 17 +- 8 files changed, 365 insertions(+), 5 deletions(-) create mode 100644 dist/.npmignore create mode 100644 dist/fesm2022/marketplaces-payment.mjs create mode 100644 dist/fesm2022/marketplaces-payment.mjs.map delete mode 100644 dist/index.d.ts delete mode 100644 dist/index.js create mode 100644 dist/package.json create mode 100644 dist/types/marketplaces-payment.d.ts diff --git a/dist/.npmignore b/dist/.npmignore new file mode 100644 index 0000000..c97ccf2 --- /dev/null +++ b/dist/.npmignore @@ -0,0 +1,2 @@ +# Nested package.json's are only needed for development. +**/package.json \ No newline at end of file diff --git a/dist/fesm2022/marketplaces-payment.mjs b/dist/fesm2022/marketplaces-payment.mjs new file mode 100644 index 0000000..a113297 --- /dev/null +++ b/dist/fesm2022/marketplaces-payment.mjs @@ -0,0 +1,210 @@ +import * as i0 from '@angular/core'; +import { InjectionToken, makeEnvironmentProviders, inject, Injectable, input, booleanAttribute, output, signal, DestroyRef, Component } from '@angular/core'; +import * as QRCode from 'qrcode'; +import { catchError, throwError, timer, switchMap } from 'rxjs'; +import { HttpHeaders, HttpClient, HttpErrorResponse } from '@angular/common/http'; + +const MARKETPLACES_PAYMENT_CONFIG = new InjectionToken('@marketplaces/payment config'); +function provideMarketplacesPayment(config) { + return makeEnvironmentProviders([{ + provide: MARKETPLACES_PAYMENT_CONFIG, + useValue: { + ...config, + apiUrl: config.apiUrl.replace(/\/$/, ''), + paymentsPath: config.paymentsPath ?? '/api/v1/payments', + pollIntervalMs: config.pollIntervalMs ?? 1500, + }, + }]); +} + +const MARKETPLACE_DOMAIN_HEADER = 'X-Marketplace-Domain'; +function normalizeMarketplaceDomain(domain) { + return domain.trim().toLowerCase().replace(/\.$/, ''); +} +class PaymentMarketplaceContext { + constructor() { + this.config = inject(MARKETPLACES_PAYMENT_CONFIG); + } + domain() { + const configured = this.config.marketplaceDomain; + const domain = typeof configured === 'function' ? configured() : configured ?? (typeof location === 'undefined' ? '' : location.hostname); + return normalizeMarketplaceDomain(domain); + } + headers() { + const domain = this.domain(); + if (!domain) + throw new Error('Marketplace domain cannot be resolved'); + return new HttpHeaders({ [MARKETPLACE_DOMAIN_HEADER]: domain }); + } + static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PaymentMarketplaceContext, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } + static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PaymentMarketplaceContext, providedIn: 'root' }); } +} +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PaymentMarketplaceContext, decorators: [{ + type: Injectable, + args: [{ providedIn: 'root' }] + }] }); + +const MARKETPLACES_PAYMENT_GATEWAY = new InjectionToken('@marketplaces/payment gateway', { providedIn: 'root', factory: () => inject(HttpMarketplacesPaymentGateway) }); +class HttpMarketplacesPaymentGateway { + constructor() { + this.http = inject(HttpClient); + this.config = inject(MARKETPLACES_PAYMENT_CONFIG); + this.context = inject(PaymentMarketplaceContext); + } + create(method, request) { + return this.http.post(this.baseUrl(), { ...request, method }, { headers: this.context.headers() }).pipe(this.handle(method)); + } + status(paymentId, method) { + return this.http.get(`${this.baseUrl()}/${encodeURIComponent(paymentId)}`, { headers: this.context.headers() }).pipe(this.handle(method)); + } + cancel(paymentId) { + return this.http.post(`${this.baseUrl()}/${encodeURIComponent(paymentId)}/cancel`, {}, { headers: this.context.headers() }); + } + baseUrl() { + const path = this.config.paymentsPath ?? ''; + return `${this.config.apiUrl}${path.startsWith('/') ? path : `/${path}`}`; + } + handle(method) { + return (source) => source.pipe(catchError(cause => { + const response = cause instanceof HttpErrorResponse ? cause : null; + const failure = { + method, code: response?.status === 402 ? 'declined' : 'backend', + message: response?.error?.message || response?.message || 'Payment failed', cause, + }; + return throwError(() => failure); + })); + } + static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HttpMarketplacesPaymentGateway, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } + static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HttpMarketplacesPaymentGateway, providedIn: 'root' }); } +} +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HttpMarketplacesPaymentGateway, decorators: [{ + type: Injectable, + args: [{ providedIn: 'root' }] + }] }); + +class MarketplacesPaymentComponent { + constructor() { + this.qr = input(false, { ...(ngDevMode ? { debugName: "qr" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); + this.card = input(false, { ...(ngDevMode ? { debugName: "card" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); + this.sbp = input(false, { ...(ngDevMode ? { debugName: "sbp" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); + this.yandexPay = input(false, { ...(ngDevMode ? { debugName: "yandexPay" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); + this.request = input.required(/* @ts-ignore */ + ...(ngDevMode ? [{ debugName: "request" }] : /* istanbul ignore next */ [])); + this.title = input('Оплата', /* @ts-ignore */ + ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ [])); + this.completed = output(); + this.paymentError = output(); + this.cancelled = output(); + this.busy = signal(false, /* @ts-ignore */ + ...(ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ [])); + this.error = signal(null, /* @ts-ignore */ + ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ [])); + this.attempt = signal(null, /* @ts-ignore */ + ...(ngDevMode ? [{ debugName: "attempt" }] : /* istanbul ignore next */ [])); + this.qrImage = signal(null, /* @ts-ignore */ + ...(ngDevMode ? [{ debugName: "qrImage" }] : /* istanbul ignore next */ [])); + this.actionUrl = signal(null, /* @ts-ignore */ + ...(ngDevMode ? [{ debugName: "actionUrl" }] : /* istanbul ignore next */ [])); + this.gateway = inject(MARKETPLACES_PAYMENT_GATEWAY); + this.config = inject(MARKETPLACES_PAYMENT_CONFIG); + inject(DestroyRef).onDestroy(() => this.poll?.unsubscribe()); + } + pay(method) { + this.poll?.unsubscribe(); + this.error.set(null); + this.busy.set(true); + this.qrImage.set(null); + this.gateway.create(method, this.request()).subscribe({ + next: created => void this.handleCreated(created).catch(cause => this.fail(method, cause)), + error: cause => this.fail(method, cause), + }); + } + cancel() { + const current = this.attempt(); + this.poll?.unsubscribe(); + this.busy.set(false); + this.attempt.set(null); + if (current) + this.gateway.cancel(current.paymentId).subscribe({ error: () => undefined }); + this.cancelled.emit(); + } + async handleCreated(created) { + this.attempt.set(created); + if (created.action?.url) { + this.actionUrl.set(created.action.url); + if (created.action.type === 'qr') + this.qrImage.set(await QRCode.toDataURL(created.action.url, { width: 320, margin: 1 })); + else if (typeof window !== 'undefined' && !window.open(created.action.url, '_blank', 'noopener')) { + this.fail(created.method, { method: created.method, code: 'popup_blocked', message: 'Браузер заблокировал окно оплаты' }); + return; + } + } + if (created.status === 'paid' || created.status === 'authorized') { + this.finish(created); + return; + } + if (created.status === 'failed' || created.status === 'expired') { + this.fail(created.method, created.failureMessage ?? 'Платёж отклонён'); + return; + } + this.poll = timer(0, this.config.pollIntervalMs ?? 1500).pipe(switchMap(() => this.gateway.status(created.paymentId, created.method))) + .subscribe({ next: status => this.handleStatus(status), error: cause => this.fail(created.method, cause) }); + } + handleStatus(current) { + this.attempt.set(current); + if (current.status === 'paid' || current.status === 'authorized') + this.finish(current); + else if (current.status === 'failed' || current.status === 'expired' || current.status === 'cancelled') + this.fail(current.method, current.failureMessage ?? 'Платёж не завершён'); + } + finish(attempt) { this.poll?.unsubscribe(); this.busy.set(false); this.attempt.set(null); this.completed.emit(attempt); } + fail(method, cause) { + this.poll?.unsubscribe(); + this.busy.set(false); + const failure = this.isFailure(cause) ? cause : { method, code: 'backend', message: typeof cause === 'string' ? cause : 'Не удалось провести платёж', cause }; + this.error.set(failure); + this.paymentError.emit(failure); + } + isFailure(value) { return !!value && typeof value === 'object' && 'code' in value && 'message' in value; } + static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MarketplacesPaymentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } + static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: MarketplacesPaymentComponent, isStandalone: true, selector: "mp-payment, marketplaces-payment", inputs: { qr: { classPropertyName: "qr", publicName: "qr", isSignal: true, isRequired: false, transformFunction: null }, card: { classPropertyName: "card", publicName: "card", isSignal: true, isRequired: false, transformFunction: null }, sbp: { classPropertyName: "sbp", publicName: "sbp", isSignal: true, isRequired: false, transformFunction: null }, yandexPay: { classPropertyName: "yandexPay", publicName: "yandexPay", isSignal: true, isRequired: false, transformFunction: null }, request: { classPropertyName: "request", publicName: "request", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { completed: "completed", paymentError: "paymentError", cancelled: "cancelled" }, ngImport: i0, template: ` +
+

{{ title() }}

+
+ @if (qr()) { } + @if (card()) { } + @if (sbp()) { } + @if (yandexPay()) { } +
+ @if (qrImage()) { QR-код оплаты } + @if (busy()) {

Проверяем оплату…

} + @if (error()) { } + @if (attempt()) { } +
+ `, isInline: true, styles: [":host{display:block}.mp-payment{font:inherit;color:inherit;display:grid;gap:1rem;max-width:26rem}h2,p{margin:0}.methods{display:flex;gap:.6rem;flex-wrap:wrap}button{font:inherit;cursor:pointer;border:1px solid #111;border-radius:.65rem;padding:.75rem 1rem;background:#111;color:#fff}button:disabled{opacity:.55;cursor:wait}.cancel{background:transparent;color:inherit;border-color:#c7c7c7}img{display:block;width:min(15rem,100%);height:auto}.error{color:#b42318}\n"] }); } +} +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: MarketplacesPaymentComponent, decorators: [{ + type: Component, + args: [{ selector: 'mp-payment, marketplaces-payment', standalone: true, template: ` +
+

{{ title() }}

+
+ @if (qr()) { } + @if (card()) { } + @if (sbp()) { } + @if (yandexPay()) { } +
+ @if (qrImage()) { QR-код оплаты } + @if (busy()) {

Проверяем оплату…

} + @if (error()) { } + @if (attempt()) { } +
+ `, styles: [":host{display:block}.mp-payment{font:inherit;color:inherit;display:grid;gap:1rem;max-width:26rem}h2,p{margin:0}.methods{display:flex;gap:.6rem;flex-wrap:wrap}button{font:inherit;cursor:pointer;border:1px solid #111;border-radius:.65rem;padding:.75rem 1rem;background:#111;color:#fff}button:disabled{opacity:.55;cursor:wait}.cancel{background:transparent;color:inherit;border-color:#c7c7c7}img{display:block;width:min(15rem,100%);height:auto}.error{color:#b42318}\n"] }] + }], ctorParameters: () => [], propDecorators: { qr: [{ type: i0.Input, args: [{ isSignal: true, alias: "qr", required: false }] }], card: [{ type: i0.Input, args: [{ isSignal: true, alias: "card", required: false }] }], sbp: [{ type: i0.Input, args: [{ isSignal: true, alias: "sbp", required: false }] }], yandexPay: [{ type: i0.Input, args: [{ isSignal: true, alias: "yandexPay", required: false }] }], request: [{ type: i0.Input, args: [{ isSignal: true, alias: "request", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], completed: [{ type: i0.Output, args: ["completed"] }], paymentError: [{ type: i0.Output, args: ["paymentError"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } }); + +/** + * Generated bundle index. Do not edit. + */ + +export { HttpMarketplacesPaymentGateway, MARKETPLACES_PAYMENT_CONFIG, MARKETPLACES_PAYMENT_GATEWAY, MARKETPLACE_DOMAIN_HEADER, MarketplacesPaymentComponent, PaymentMarketplaceContext, normalizeMarketplaceDomain, provideMarketplacesPayment }; +//# sourceMappingURL=marketplaces-payment.mjs.map diff --git a/dist/fesm2022/marketplaces-payment.mjs.map b/dist/fesm2022/marketplaces-payment.mjs.map new file mode 100644 index 0000000..e0f5637 --- /dev/null +++ b/dist/fesm2022/marketplaces-payment.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"marketplaces-payment.mjs","sources":["../../src/payment.config.ts","../../src/marketplace-context.ts","../../src/payment.gateway.ts","../../src/payment.component.ts","../../src/marketplaces-payment.ts"],"sourcesContent":["import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';\n\nexport interface MarketplacesPaymentConfig {\n /** Central payment service URL. It is not the tenant API URL. */\n apiUrl: string;\n marketplaceDomain?: string | (() => string);\n paymentsPath?: string;\n pollIntervalMs?: number;\n}\nexport const MARKETPLACES_PAYMENT_CONFIG = new InjectionToken('@marketplaces/payment config');\nexport function provideMarketplacesPayment(config: MarketplacesPaymentConfig): EnvironmentProviders {\n return makeEnvironmentProviders([{\n provide: MARKETPLACES_PAYMENT_CONFIG,\n useValue: {\n ...config,\n apiUrl: config.apiUrl.replace(/\\/$/, ''),\n paymentsPath: config.paymentsPath ?? '/api/v1/payments',\n pollIntervalMs: config.pollIntervalMs ?? 1500,\n },\n }]);\n}\n","import { HttpHeaders } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { MARKETPLACES_PAYMENT_CONFIG } from './payment.config';\n\nexport const MARKETPLACE_DOMAIN_HEADER = 'X-Marketplace-Domain';\nexport function normalizeMarketplaceDomain(domain: string): string {\n return domain.trim().toLowerCase().replace(/\\.$/, '');\n}\n@Injectable({ providedIn: 'root' })\nexport class PaymentMarketplaceContext {\n private readonly config = inject(MARKETPLACES_PAYMENT_CONFIG);\n domain(): string {\n const configured = this.config.marketplaceDomain;\n const domain = typeof configured === 'function' ? configured() : configured ?? (typeof location === 'undefined' ? '' : location.hostname);\n return normalizeMarketplaceDomain(domain);\n }\n headers(): HttpHeaders {\n const domain = this.domain();\n if (!domain) throw new Error('Marketplace domain cannot be resolved');\n return new HttpHeaders({ [MARKETPLACE_DOMAIN_HEADER]: domain });\n }\n}\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { Injectable, InjectionToken, inject } from '@angular/core';\nimport { Observable, catchError, throwError } from 'rxjs';\nimport { PaymentMarketplaceContext } from './marketplace-context';\nimport { MARKETPLACES_PAYMENT_CONFIG } from './payment.config';\nimport { PaymentAttempt, PaymentFailure, PaymentMethod, PaymentRequest } from './payment.models';\n\nexport interface MarketplacesPaymentGateway {\n create(method: PaymentMethod, request: PaymentRequest): Observable;\n status(paymentId: string, method: PaymentMethod): Observable;\n cancel(paymentId: string): Observable;\n}\nexport const MARKETPLACES_PAYMENT_GATEWAY = new InjectionToken(\n '@marketplaces/payment gateway', { providedIn: 'root', factory: () => inject(HttpMarketplacesPaymentGateway) }\n);\n@Injectable({ providedIn: 'root' })\nexport class HttpMarketplacesPaymentGateway implements MarketplacesPaymentGateway {\n private readonly http = inject(HttpClient);\n private readonly config = inject(MARKETPLACES_PAYMENT_CONFIG);\n private readonly context = inject(PaymentMarketplaceContext);\n create(method: PaymentMethod, request: PaymentRequest): Observable {\n return this.http.post(this.baseUrl(), { ...request, method }, { headers: this.context.headers() }).pipe(this.handle(method));\n }\n status(paymentId: string, method: PaymentMethod): Observable {\n return this.http.get(`${this.baseUrl()}/${encodeURIComponent(paymentId)}`, { headers: this.context.headers() }).pipe(this.handle(method));\n }\n cancel(paymentId: string): Observable {\n return this.http.post(`${this.baseUrl()}/${encodeURIComponent(paymentId)}/cancel`, {}, { headers: this.context.headers() });\n }\n private baseUrl(): string {\n const path = this.config.paymentsPath ?? '';\n return `${this.config.apiUrl}${path.startsWith('/') ? path : `/${path}`}`;\n }\n private handle(method: PaymentMethod) {\n return (source: Observable) => source.pipe(catchError(cause => {\n const response = cause instanceof HttpErrorResponse ? cause : null;\n const failure: PaymentFailure = {\n method, code: response?.status === 402 ? 'declined' : 'backend',\n message: response?.error?.message || response?.message || 'Payment failed', cause,\n };\n return throwError(() => failure);\n }));\n }\n}\n","import { Component, DestroyRef, booleanAttribute, inject, input, output, signal } from '@angular/core';\nimport * as QRCode from 'qrcode';\nimport { Subscription, switchMap, timer } from 'rxjs';\nimport { MARKETPLACES_PAYMENT_CONFIG } from './payment.config';\nimport { MARKETPLACES_PAYMENT_GATEWAY } from './payment.gateway';\nimport { PaymentAttempt, PaymentFailure, PaymentMethod, PaymentRequest, PaymentResult } from './payment.models';\n\n@Component({\n selector: 'mp-payment, marketplaces-payment',\n standalone: true,\n template: `\n
\n

{{ title() }}

\n
\n @if (qr()) { }\n @if (card()) { }\n @if (sbp()) { }\n @if (yandexPay()) { }\n
\n @if (qrImage()) { \"QR-код }\n @if (busy()) {

Проверяем оплату…

}\n @if (error()) {

{{ error()!.message }}

}\n @if (attempt()) { }\n
\n `,\n styles: [`\n :host{display:block}.mp-payment{font:inherit;color:inherit;display:grid;gap:1rem;max-width:26rem}\n h2,p{margin:0}.methods{display:flex;gap:.6rem;flex-wrap:wrap}button{font:inherit;cursor:pointer;border:1px solid #111;border-radius:.65rem;padding:.75rem 1rem;background:#111;color:#fff}\n button:disabled{opacity:.55;cursor:wait}.cancel{background:transparent;color:inherit;border-color:#c7c7c7}img{display:block;width:min(15rem,100%);height:auto}.error{color:#b42318}\n `],\n})\nexport class MarketplacesPaymentComponent {\n readonly qr = input(false, { transform: booleanAttribute });\n readonly card = input(false, { transform: booleanAttribute });\n readonly sbp = input(false, { transform: booleanAttribute });\n readonly yandexPay = input(false, { transform: booleanAttribute });\n readonly request = input.required();\n readonly title = input('Оплата');\n readonly completed = output();\n readonly paymentError = output();\n readonly cancelled = output();\n readonly busy = signal(false);\n readonly error = signal(null);\n readonly attempt = signal(null);\n readonly qrImage = signal(null);\n readonly actionUrl = signal(null);\n private readonly gateway = inject(MARKETPLACES_PAYMENT_GATEWAY);\n private readonly config = inject(MARKETPLACES_PAYMENT_CONFIG);\n private poll?: Subscription;\n\n constructor() { inject(DestroyRef).onDestroy(() => this.poll?.unsubscribe()); }\n pay(method: PaymentMethod): void {\n this.poll?.unsubscribe(); this.error.set(null); this.busy.set(true); this.qrImage.set(null);\n this.gateway.create(method, this.request()).subscribe({\n next: created => void this.handleCreated(created).catch(cause => this.fail(method, cause)),\n error: cause => this.fail(method, cause),\n });\n }\n cancel(): void {\n const current = this.attempt();\n this.poll?.unsubscribe(); this.busy.set(false); this.attempt.set(null);\n if (current) this.gateway.cancel(current.paymentId).subscribe({ error: () => undefined });\n this.cancelled.emit();\n }\n private async handleCreated(created: PaymentAttempt): Promise {\n this.attempt.set(created);\n if (created.action?.url) {\n this.actionUrl.set(created.action.url);\n if (created.action.type === 'qr') this.qrImage.set(await QRCode.toDataURL(created.action.url, { width: 320, margin: 1 }));\n else if (typeof window !== 'undefined' && !window.open(created.action.url, '_blank', 'noopener')) {\n this.fail(created.method, { method: created.method, code: 'popup_blocked', message: 'Браузер заблокировал окно оплаты' });\n return;\n }\n }\n if (created.status === 'paid' || created.status === 'authorized') { this.finish(created); return; }\n if (created.status === 'failed' || created.status === 'expired') { this.fail(created.method, created.failureMessage ?? 'Платёж отклонён'); return; }\n this.poll = timer(0, this.config.pollIntervalMs ?? 1500).pipe(switchMap(() => this.gateway.status(created.paymentId, created.method)))\n .subscribe({ next: status => this.handleStatus(status), error: cause => this.fail(created.method, cause) });\n }\n private handleStatus(current: PaymentAttempt): void {\n this.attempt.set(current);\n if (current.status === 'paid' || current.status === 'authorized') this.finish(current);\n else if (current.status === 'failed' || current.status === 'expired' || current.status === 'cancelled') this.fail(current.method, current.failureMessage ?? 'Платёж не завершён');\n }\n private finish(attempt: PaymentAttempt): void { this.poll?.unsubscribe(); this.busy.set(false); this.attempt.set(null); this.completed.emit(attempt as PaymentResult); }\n private fail(method: PaymentMethod, cause: unknown): void {\n this.poll?.unsubscribe(); this.busy.set(false);\n const failure: PaymentFailure = this.isFailure(cause) ? cause : { method, code: 'backend', message: typeof cause === 'string' ? cause : 'Не удалось провести платёж', cause };\n this.error.set(failure); this.paymentError.emit(failure);\n }\n private isFailure(value: unknown): value is PaymentFailure { return !!value && typeof value === 'object' && 'code' in value && 'message' in value; }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/dist/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index cb0ff5c..0000000 --- a/dist/index.js +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/package.json b/dist/package.json new file mode 100644 index 0000000..736d0b4 --- /dev/null +++ b/dist/package.json @@ -0,0 +1,34 @@ +{ + "name": "@marketplaces/payment", + "version": "0.1.0", + "description": "Standalone Angular payment UI and central payment API client.", + "module": "fesm2022/marketplaces-payment.mjs", + "typings": "types/marketplaces-payment.d.ts", + "files": [ + "dist" + ], + "dependencies": { + "qrcode": "^1.5.4", + "tslib": "^2.8.0" + }, + "peerDependencies": { + "@angular/core": ">=22.0.0", + "@angular/common": ">=22.0.0", + "rxjs": ">=7.8.0" + }, + "publishConfig": { + "access": "restricted" + }, + "license": "UNLICENSED", + "exports": { + "./package.json": { + "default": "./package.json" + }, + ".": { + "types": "./types/marketplaces-payment.d.ts", + "default": "./fesm2022/marketplaces-payment.mjs" + } + }, + "sideEffects": false, + "type": "module" +} \ No newline at end of file diff --git a/dist/types/marketplaces-payment.d.ts b/dist/types/marketplaces-payment.d.ts new file mode 100644 index 0000000..802244e --- /dev/null +++ b/dist/types/marketplaces-payment.d.ts @@ -0,0 +1,104 @@ +import * as _angular_core from '@angular/core'; +import { InjectionToken, EnvironmentProviders } from '@angular/core'; +import { HttpHeaders } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +type PaymentMethod = 'qr' | 'card' | 'sbp' | 'yandex-pay'; +type PaymentStatus = 'created' | 'pending' | 'authorized' | 'paid' | 'failed' | 'cancelled' | 'expired'; +/** Central payment API resolves amount/currency/routing from this server checkout id. */ +interface PaymentRequest { + checkoutSessionId: string; + returnUrl?: string; + metadata?: Readonly>; +} +interface PaymentAttempt { + paymentId: string; + method: PaymentMethod; + status: PaymentStatus; + action?: { + type: 'redirect' | 'qr'; + url: string; + }; + failureMessage?: string; +} +interface PaymentResult extends PaymentAttempt { + status: 'paid' | 'authorized'; +} +interface PaymentFailure { + method: PaymentMethod; + code: 'configuration' | 'backend' | 'declined' | 'expired' | 'popup_blocked'; + message: string; + cause?: unknown; +} + +declare class MarketplacesPaymentComponent { + readonly qr: _angular_core.InputSignalWithTransform; + readonly card: _angular_core.InputSignalWithTransform; + readonly sbp: _angular_core.InputSignalWithTransform; + readonly yandexPay: _angular_core.InputSignalWithTransform; + readonly request: _angular_core.InputSignal; + readonly title: _angular_core.InputSignal; + readonly completed: _angular_core.OutputEmitterRef; + readonly paymentError: _angular_core.OutputEmitterRef; + readonly cancelled: _angular_core.OutputEmitterRef; + readonly busy: _angular_core.WritableSignal; + readonly error: _angular_core.WritableSignal; + readonly attempt: _angular_core.WritableSignal; + readonly qrImage: _angular_core.WritableSignal; + readonly actionUrl: _angular_core.WritableSignal; + private readonly gateway; + private readonly config; + private poll?; + constructor(); + pay(method: PaymentMethod): void; + cancel(): void; + private handleCreated; + private handleStatus; + private finish; + private fail; + private isFailure; + static ɵfac: _angular_core.ɵɵFactoryDeclaration; + static ɵcmp: _angular_core.ɵɵComponentDeclaration; +} + +interface MarketplacesPaymentConfig { + /** Central payment service URL. It is not the tenant API URL. */ + apiUrl: string; + marketplaceDomain?: string | (() => string); + paymentsPath?: string; + pollIntervalMs?: number; +} +declare const MARKETPLACES_PAYMENT_CONFIG: InjectionToken; +declare function provideMarketplacesPayment(config: MarketplacesPaymentConfig): EnvironmentProviders; + +declare const MARKETPLACE_DOMAIN_HEADER = "X-Marketplace-Domain"; +declare function normalizeMarketplaceDomain(domain: string): string; +declare class PaymentMarketplaceContext { + private readonly config; + domain(): string; + headers(): HttpHeaders; + static ɵfac: _angular_core.ɵɵFactoryDeclaration; + static ɵprov: _angular_core.ɵɵInjectableDeclaration; +} + +interface MarketplacesPaymentGateway { + create(method: PaymentMethod, request: PaymentRequest): Observable; + status(paymentId: string, method: PaymentMethod): Observable; + cancel(paymentId: string): Observable; +} +declare const MARKETPLACES_PAYMENT_GATEWAY: InjectionToken; +declare class HttpMarketplacesPaymentGateway implements MarketplacesPaymentGateway { + private readonly http; + private readonly config; + private readonly context; + create(method: PaymentMethod, request: PaymentRequest): Observable; + status(paymentId: string, method: PaymentMethod): Observable; + cancel(paymentId: string): Observable; + private baseUrl; + private handle; + static ɵfac: _angular_core.ɵɵFactoryDeclaration; + static ɵprov: _angular_core.ɵɵInjectableDeclaration; +} + +export { HttpMarketplacesPaymentGateway, MARKETPLACES_PAYMENT_CONFIG, MARKETPLACES_PAYMENT_GATEWAY, MARKETPLACE_DOMAIN_HEADER, MarketplacesPaymentComponent, PaymentMarketplaceContext, normalizeMarketplaceDomain, provideMarketplacesPayment }; +export type { MarketplacesPaymentConfig, MarketplacesPaymentGateway, PaymentAttempt, PaymentFailure, PaymentMethod, PaymentRequest, PaymentResult, PaymentStatus }; diff --git a/package.json b/package.json index c590fc0..b148f9a 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,25 @@ { "name": "@marketplaces/payment", "version": "0.1.0", - "description": "Shared payment/finance client (FX, pricing, checkout gateways) for marketplaces projects. Thin by design — payment business logic stays server-side per the Phase 1/7 backend contracts.", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "description": "Standalone Angular payment UI and central payment API client.", + "module": "dist/fesm2022/marketplaces-payment.mjs", + "typings": "dist/types/marketplaces-payment.d.ts", "files": ["dist"], + "scripts": { + "build": "ng-packagr -p ng-package.json -c tsconfig.json", + "test": "node --test test/*.test.mjs" + }, + "dependencies": { + "qrcode": "^1.5.4", + "tslib": "^2.8.0" + }, "peerDependencies": { "@angular/core": ">=22.0.0", "@angular/common": ">=22.0.0", "rxjs": ">=7.8.0" }, + "publishConfig": { + "access": "restricted" + }, "license": "UNLICENSED" }