forked from StellarSplit/StellarSplit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpayment.entity.ts
More file actions
122 lines (101 loc) · 2.94 KB
/
Copy pathpayment.entity.ts
File metadata and controls
122 lines (101 loc) · 2.94 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
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn, Index } from 'typeorm';
import { Participant } from './participant.entity';
/**
* Payment settlement states for tracking on-chain reconciliation
*/
export enum PaymentSettlementStatus {
/** Payment submitted, awaiting Horizon confirmation */
SUBMITTED = 'submitted',
/** Payment confirmed on-chain */
CONFIRMED = 'confirmed',
/** Payment failed on-chain */
FAILED = 'failed',
/** Payment requires manual review (stale, disputed, etc.) */
REVIEW_REQUIRED = 'review_required',
/** Payment is being reconciled */
RECONCILING = 'reconciling',
}
/**
* Payment processing states
*/
export enum PaymentProcessingStatus {
PENDING = 'pending',
CONFIRMED = 'confirmed',
FAILED = 'failed',
PARTIAL = 'partial',
}
@Entity('payments')
export class Payment {
@PrimaryGeneratedColumn('uuid')
id!: string;
/**
* Idempotency key to prevent duplicate submissions
* Generated from: splitId + participantId + txHash
*/
@Column({ type: 'varchar', unique: true, nullable: true })
@Index()
idempotencyKey?: string;
@Column({ type: 'uuid' })
splitId!: string;
@Column({ type: 'uuid' })
participantId!: string;
@Column({ type: 'varchar' })
@Index()
txHash!: string;
@Column({ type: 'decimal', precision: 10, scale: 2 })
amount!: number;
@Column({ type: 'varchar' })
asset!: string;
/**
* Processing status (pending, confirmed, failed, partial)
*/
@Column({ type: 'varchar', default: 'pending' })
status!: PaymentProcessingStatus;
/**
* Settlement status for on-chain reconciliation
*/
@Column({ type: 'varchar', default: PaymentSettlementStatus.SUBMITTED })
settlementStatus!: PaymentSettlementStatus;
/**
* Last time the settlement status was checked on-chain
*/
@Column({ type: 'timestamp', nullable: true })
lastSettlementCheck?: Date;
/**
* Number of reconciliation attempts
*/
@Column({ type: 'int', default: 0 })
reconciliationAttempts!: number;
/**
* Maximum reconciliation attempts before marking for review
*/
@Column({ type: 'int', default: 5 })
maxReconciliationAttempts!: number;
/**
* Error message if settlement fails
*/
@Column({ type: 'text', nullable: true })
settlementError?: string;
/**
* Whether notifications have been sent (prevents duplicate notifications)
*/
@Column({ type: 'boolean', default: false })
notificationsSent!: boolean;
/**
* Timestamp when payment was first processed
*/
@Column({ type: 'timestamp', nullable: true })
processedAt?: Date;
/**
* External reference for webhook replay support
*/
@Column({ type: 'varchar', nullable: true })
externalReference?: string;
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
@ManyToOne(() => Participant, participant => participant.id)
@JoinColumn({ name: 'participantId' })
participant?: Participant;
}