Repository navigation
Expand file tree
/
Copy pathpayment-processor.interface.ts
More file actions
181 lines (165 loc) · 6.38 KB
/
Copy pathpayment-processor.interface.ts
File metadata and controls
181 lines (165 loc) · 6.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
* Payment-processor plugin contract.
*
* Every payment backend (Stellar, Grantfox, …) implements {@link IPaymentProcessor}.
* The registry and factory operate against this base contract, so adding a new
* processor is a drop-in: implement the interface, tag the class with
* `@RegisterPaymentProcessor()`, and it auto-registers on module init.
*
* Amounts are always **decimal strings** (e.g. "10.5"), never floats — this
* avoids IEEE-754 rounding on monetary values across every processor.
*/
/**
* Canonical lifecycle status shared by all processors. Individual processors
* map their native/provider-specific states onto these values so callers get a
* uniform status regardless of backend.
*/
export enum PaymentStatus {
/** Created locally, nothing sent to the network yet. */
PENDING = "PENDING",
/** In flight / provider is working on it. */
PROCESSING = "PROCESSING",
/** Signed transaction submitted, awaiting confirmation. */
SUBMITTED = "SUBMITTED",
/** Settled / confirmed on the network or by the provider. */
CONFIRMED = "CONFIRMED",
/** Terminal failure. */
FAILED = "FAILED",
/** Fully refunded. */
REFUNDED = "REFUNDED",
/** Partially refunded (remaining balance still settled). */
PARTIALLY_REFUNDED = "PARTIALLY_REFUNDED",
}
/** A request to create (but not yet submit) a payment. */
export interface PaymentRequest {
/** Decimal string, e.g. "10.5". */
amount: string;
/** Asset/currency code, e.g. "XLM", "USD". */
currency: string;
/** Recipient identifier (Stellar public key, provider account id, …). */
destination: string;
/** Optional payer identifier; defaults to the processor's configured source. */
source?: string;
/** Optional human-readable memo/reference. */
reference?: string;
/**
* Caller-supplied key that makes retries safe. Processors forward it to the
* backend; true dedup requires persistence (see the DB seam in the README).
*/
idempotencyKey: string;
/** Optional payment rate quote id (locks exchange rate for 15 minutes). */
quoteId?: string;
/** Free-form processor-specific extras. */
metadata?: Record<string, unknown>;
}
/** The result of {@link IPaymentProcessor.createPayment}. */
export interface CreatedPayment {
paymentId: string;
/** Recovery checkpoint id assigned by Trellis. */
recoveryId?: string;
status: PaymentStatus;
/**
* Backend-specific unsigned payload (e.g. a Stellar transaction XDR) that the
* caller passes to `signTransaction`. Absent when the processor signs and
* submits server-side in a single step.
*/
unsignedTransaction?: unknown;
/** Raw backend response, for debugging/audit. */
raw?: unknown;
}
/** The result of {@link IPaymentProcessor.signTransaction}. */
export interface SignedTransaction {
paymentId: string;
/** Opaque signed payload passed on to `submitTransaction`. */
signedPayload: string;
/** Address/account that produced the signature, when known. */
signerAddress?: string;
}
/** The result of {@link IPaymentProcessor.submitTransaction}. */
export interface SubmittedTransaction {
paymentId: string;
transactionHash: string;
status: PaymentStatus;
raw?: unknown;
}
/** The result of {@link IPaymentProcessor.getStatus}. */
export interface PaymentStatusResult {
paymentId: string;
status: PaymentStatus;
transactionHash?: string;
/** Decimal string of the amount confirmed settled, when known. */
confirmedAmount?: string;
raw?: unknown;
}
/** A request to refund a previously submitted payment. */
export interface RefundRequest {
paymentId: string;
/** Decimal string; omit for a full refund. */
amount?: string;
reason?: string;
idempotencyKey: string;
}
/** The result of {@link IPaymentProcessor.refund}. */
export interface RefundResult {
refundId: string;
paymentId: string;
status: PaymentStatus;
/** Decimal string of the amount actually refunded. */
refundedAmount: string;
raw?: unknown;
}
/** Static, declarative description of what a processor can do. */
export interface PaymentCapabilities {
/** Whether {@link RefundRequest.amount} (partial refunds) is honoured. */
supportsPartialRefund: boolean;
/**
* When true, `createPayment` returns an unsigned payload the client must
* sign; when false the processor signs server-side and `signTransaction`
* is effectively a passthrough/no-op.
*/
requiresClientSideSigning: boolean;
/** Currencies/assets the processor accepts. */
currencies: string[];
}
/**
* The plugin contract every payment backend implements.
*
* Generics let each adapter narrow its config and native request/response
* shapes while the registry/factory keep working against the base interface:
*
* - `TConfig` — the shape accepted by {@link initialize}.
* - `TCreate` — the (possibly extended) create request the adapter accepts.
* - `TCreated` — the (possibly extended) created-payment the adapter returns.
*/
export interface IPaymentProcessor<
TConfig = Record<string, unknown>,
TCreate extends PaymentRequest = PaymentRequest,
TCreated extends CreatedPayment = CreatedPayment,
> {
/** Stable, lowercase key used for selection/registration, e.g. "stellar". */
readonly name: string;
/** Human-readable label for UIs. */
readonly displayName: string;
/** Declarative capabilities (see {@link PaymentCapabilities}). */
readonly capabilities: PaymentCapabilities;
/** Idempotent (re)configuration; safe to call more than once. */
initialize(config?: Partial<TConfig>): Promise<void>;
createPayment(request: TCreate): Promise<TCreated>;
signTransaction(created: TCreated): Promise<SignedTransaction>;
submitTransaction(signed: SignedTransaction): Promise<SubmittedTransaction>;
getStatus(paymentId: string): Promise<PaymentStatusResult>;
refund(request: RefundRequest): Promise<RefundResult>;
/** Whether resubmitting the exact same signed payload cannot duplicate effects. */
readonly supportsSafeSubmissionRetry?: boolean;
/** Stable external transaction identifier derivable before submission. */
getSubmissionHash?(signed: SignedTransaction): string;
/** Verify that a client-signed payload matches the saved create response. */
matchesCreatedPayment?(created: TCreated, signed: SignedTransaction): boolean;
}
/** Lightweight, serialisable view of a processor for list endpoints. */
export interface PaymentProcessorInfo {
name: string;
displayName: string;
enabled: boolean;
capabilities: PaymentCapabilities;
}