Skip to main content

allsource_core/application/dto/
transaction_dto.rs

1use crate::domain::entities::{Blockchain, Transaction, TransactionStatus};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6/// DTO for initiating a payment transaction
7#[derive(Debug, Deserialize)]
8pub struct InitiatePaymentRequest {
9    pub tenant_id: String,
10    pub article_id: String,
11    pub reader_wallet: String,
12    pub tx_signature: String,
13    pub blockchain: Option<BlockchainDto>,
14}
15
16/// DTO for payment initiation response
17#[derive(Debug, Serialize)]
18pub struct InitiatePaymentResponse {
19    pub transaction: TransactionDto,
20}
21
22/// DTO for confirming a transaction
23#[derive(Debug, Deserialize)]
24pub struct ConfirmTransactionRequest {
25    pub transaction_id: String,
26}
27
28/// DTO for transaction confirmation response
29#[derive(Debug, Serialize)]
30pub struct ConfirmTransactionResponse {
31    pub transaction: TransactionDto,
32    pub access_token: Option<String>,
33}
34
35/// DTO for refunding a transaction
36#[derive(Debug, Deserialize)]
37pub struct RefundTransactionRequest {
38    pub transaction_id: String,
39    pub refund_tx_signature: String,
40    pub reason: Option<String>,
41}
42
43/// DTO for refund response
44#[derive(Debug, Serialize)]
45pub struct RefundTransactionResponse {
46    pub transaction: TransactionDto,
47}
48
49/// DTO for listing transactions response
50#[derive(Debug, Serialize)]
51pub struct ListTransactionsResponse {
52    pub transactions: Vec<TransactionDto>,
53    pub count: usize,
54}
55
56/// DTO for blockchain type
57#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
58#[serde(rename_all = "snake_case")]
59pub enum BlockchainDto {
60    #[default]
61    Solana,
62    Base,
63    Polygon,
64}
65
66impl From<Blockchain> for BlockchainDto {
67    fn from(blockchain: Blockchain) -> Self {
68        match blockchain {
69            Blockchain::Solana => BlockchainDto::Solana,
70            Blockchain::Base => BlockchainDto::Base,
71            Blockchain::Polygon => BlockchainDto::Polygon,
72        }
73    }
74}
75
76impl From<BlockchainDto> for Blockchain {
77    fn from(dto: BlockchainDto) -> Self {
78        match dto {
79            BlockchainDto::Solana => Blockchain::Solana,
80            BlockchainDto::Base => Blockchain::Base,
81            BlockchainDto::Polygon => Blockchain::Polygon,
82        }
83    }
84}
85
86/// DTO for transaction status
87#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
88#[serde(rename_all = "snake_case")]
89pub enum TransactionStatusDto {
90    Pending,
91    Confirmed,
92    Failed,
93    Refunded,
94    Disputed,
95}
96
97impl From<TransactionStatus> for TransactionStatusDto {
98    fn from(status: TransactionStatus) -> Self {
99        match status {
100            TransactionStatus::Pending => TransactionStatusDto::Pending,
101            TransactionStatus::Confirmed => TransactionStatusDto::Confirmed,
102            TransactionStatus::Failed => TransactionStatusDto::Failed,
103            TransactionStatus::Refunded => TransactionStatusDto::Refunded,
104            TransactionStatus::Disputed => TransactionStatusDto::Disputed,
105        }
106    }
107}
108
109/// DTO for a transaction in responses
110#[derive(Debug, Clone, Serialize)]
111pub struct TransactionDto {
112    pub id: Uuid,
113    pub tenant_id: String,
114    pub article_id: String,
115    pub creator_id: String,
116    pub reader_wallet: String,
117    pub amount_cents: u64,
118    pub platform_fee_cents: u64,
119    pub creator_amount_cents: u64,
120    pub blockchain: BlockchainDto,
121    pub tx_signature: String,
122    pub status: TransactionStatusDto,
123    pub explorer_url: String,
124    pub created_at: DateTime<Utc>,
125    pub confirmed_at: Option<DateTime<Utc>>,
126    pub refunded_at: Option<DateTime<Utc>>,
127}
128
129impl From<&Transaction> for TransactionDto {
130    fn from(tx: &Transaction) -> Self {
131        Self {
132            id: tx.id().as_uuid(),
133            tenant_id: tx.tenant_id().to_string(),
134            article_id: tx.article_id().to_string(),
135            creator_id: tx.creator_id().as_uuid().to_string(),
136            reader_wallet: tx.reader_wallet().to_string(),
137            amount_cents: tx.amount_cents(),
138            platform_fee_cents: tx.platform_fee_cents(),
139            creator_amount_cents: tx.creator_amount_cents(),
140            blockchain: tx.blockchain().into(),
141            tx_signature: tx.tx_signature().to_string(),
142            status: tx.status().into(),
143            explorer_url: tx.explorer_url(),
144            created_at: tx.created_at(),
145            confirmed_at: tx.confirmed_at(),
146            refunded_at: tx.refunded_at(),
147        }
148    }
149}
150
151impl From<Transaction> for TransactionDto {
152    fn from(tx: Transaction) -> Self {
153        TransactionDto::from(&tx)
154    }
155}
156
157/// DTO for revenue summary
158#[derive(Debug, Serialize)]
159pub struct RevenueSummaryDto {
160    pub total_revenue_cents: u64,
161    pub total_transactions: u64,
162    pub total_platform_fees_cents: u64,
163    pub total_creator_earnings_cents: u64,
164}