tgbot/types/definitions/payment/
transaction.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{
4    api::{Method, Payload},
5    types::{Chat, Gift, Integer, PaidMedia, User},
6};
7
8/// Contains a list of Telegram Star transactions.
9#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
10pub struct StarTransactions {
11    /// The list of transactions.
12    pub transactions: Vec<StarTransaction>,
13}
14
15impl<T> From<T> for StarTransactions
16where
17    T: IntoIterator<Item = StarTransaction>,
18{
19    fn from(value: T) -> Self {
20        Self {
21            transactions: value.into_iter().collect(),
22        }
23    }
24}
25
26/// Describes a Telegram Star transaction.
27#[serde_with::skip_serializing_none]
28#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
29pub struct StarTransaction {
30    amount: Integer,
31    date: Integer,
32    id: String,
33    nanostar_amount: Option<Integer>,
34    source: Option<TransactionPartner>,
35    receiver: Option<TransactionPartner>,
36}
37
38impl StarTransaction {
39    /// Creates a new `StarTransaction`.
40    ///
41    /// # Arguments
42    ///
43    /// * `amount` - Number of Telegram Stars transferred by the transaction.
44    /// * `date` - Date the transaction was created in Unix time.
45    /// * `id` -  Unique identifier of the transaction;
46    ///   coincides with the identifer of the original transaction for refund transactions;
47    ///   coincides with `telegram_payment_charge_id` of [`crate::types::SuccessfulPayment`]
48    ///   for successful incoming payments from users.
49    pub fn new<T>(amount: Integer, date: Integer, id: T) -> Self
50    where
51        T: Into<String>,
52    {
53        Self {
54            amount,
55            date,
56            id: id.into(),
57            nanostar_amount: None,
58            source: None,
59            receiver: None,
60        }
61    }
62
63    /// Sets a new nanostar amount.
64    ///
65    /// # Arguments
66    ///
67    /// * `value` - The number of 1/1000000000 shares of Telegram Stars transferred by the transaction;
68    ///   from 0 to 999999999.
69    pub fn with_nanostar_amount(mut self, value: Integer) -> Self {
70        self.nanostar_amount = Some(value);
71        self
72    }
73
74    /// Sets a new source.
75    ///
76    /// # Arguments
77    ///
78    /// * `value` - Source of an incoming transaction.
79    ///   E.g., a user purchasing goods or services, Fragment refunding a failed withdrawal.
80    ///   Only for incoming transactions.
81    pub fn with_source(mut self, value: TransactionPartner) -> Self {
82        self.source = Some(value);
83        self
84    }
85
86    /// Sets a new receiver.
87    ///
88    /// # Arguments
89    ///
90    /// * `value` - Receiver of an outgoing transaction.
91    ///   E.g., a user for a purchase refund, Fragment for a withdrawal.
92    ///   Only for outgoing transactions.
93    pub fn with_receiver(mut self, value: TransactionPartner) -> Self {
94        self.receiver = Some(value);
95        self
96    }
97}
98
99/// Describes the affiliate program that issued the affiliate commission received via this transaction.
100#[serde_with::skip_serializing_none]
101#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
102pub struct TransactionPartnerAffiliateProgramParameters {
103    /// The number of Telegram Stars received by the bot for each 1000 Telegram Stars
104    /// received by the affiliate program sponsor from referred users.
105    pub commission_per_mille: Integer,
106    /// Information about the bot that sponsored the affiliate program
107    pub sponsor_user: Option<User>,
108}
109
110impl TransactionPartnerAffiliateProgramParameters {
111    /// Creates a new `TransactionPartnerAffiliateProgramParameters`.
112    ///
113    /// # Arguments
114    ///
115    /// * `commission_per_mille` - The number of Telegram Stars received by the bot.
116    pub fn new(commission_per_mille: Integer) -> Self {
117        Self {
118            commission_per_mille,
119            sponsor_user: None,
120        }
121    }
122
123    /// Sets a new sponsor user.
124    ///
125    /// # Arguments
126    ///
127    /// * `value` - Information about the bot that sponsored the affiliate program.
128    pub fn with_sponsor_user(mut self, value: User) -> Self {
129        self.sponsor_user = Some(value);
130        self
131    }
132}
133
134/// Contains information about the affiliate that received a commission via this transaction.
135#[serde_with::skip_serializing_none]
136#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
137pub struct AffiliateInfo {
138    /// Integer amount of Telegram Stars received by the affiliate from the transaction,
139    /// rounded to 0; can be negative for refunds.
140    pub amount: Integer,
141    /// The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars
142    /// received by the bot from referred users.
143    pub commission_per_mille: Integer,
144    /// The chat that received an affiliate commission if it was received by a chat.
145    pub affiliate_chat: Option<Chat>,
146    /// The bot or the user that received an affiliate commission if it was received by a bot or a user.
147    pub affiliate_user: Option<User>,
148    /// The number of 1/1000000000 shares of Telegram Stars received by the affiliate;
149    /// from -999999999 to 999999999; can be negative for refunds.
150    pub nanostar_amount: Option<Integer>,
151}
152
153impl AffiliateInfo {
154    /// Creates a new `AffiliateInfo`.
155    ///
156    /// # Arguments
157    ///
158    /// * `amount` - Integer amount of Telegram Stars received by the affiliate from the transaction
159    /// * `comission_per_mille` - The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars
160    pub fn new(amount: Integer, commission_per_mille: Integer) -> Self {
161        Self {
162            amount,
163            commission_per_mille,
164            affiliate_chat: None,
165            affiliate_user: None,
166            nanostar_amount: None,
167        }
168    }
169
170    /// Sets a new affiliate chat.
171    ///
172    /// # Arguments
173    ///
174    /// * `value` - The chat that received an affiliate commission if it was received by a chat.
175    pub fn with_affiliate_chat<T>(mut self, value: T) -> Self
176    where
177        T: Into<Chat>,
178    {
179        self.affiliate_chat = Some(value.into());
180        self
181    }
182
183    /// Sets a new affiliate user.
184    ///
185    /// # Arguments
186    ///
187    /// * `value` - The bot or the user that received an affiliate commission if it was received by a bot or a user.
188    pub fn with_affiliate_user(mut self, value: User) -> Self {
189        self.affiliate_user = Some(value);
190        self
191    }
192
193    /// Sets a new nanostar amount.
194    ///
195    /// # Arguments
196    ///
197    /// * `value` - The number of 1/1000000000 shares of Telegram Stars received by the affiliate.
198    pub fn with_nanostar_amount(mut self, value: Integer) -> Self {
199        self.nanostar_amount = Some(value);
200        self
201    }
202}
203
204/// Describes a transaction with a chat.
205#[serde_with::skip_serializing_none]
206#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
207pub struct TransactionPartnerChatParameters {
208    /// Information about the chat.
209    pub chat: Chat,
210    /// The gift sent to the chat by the bot.
211    pub gift: Option<Gift>,
212}
213
214impl TransactionPartnerChatParameters {
215    /// Creates a new `TransactionPartnerChatParameters`.
216    ///
217    /// # Arguments
218    ///
219    /// * `chat` - Information about the chat.
220    pub fn new<T>(chat: T) -> Self
221    where
222        T: Into<Chat>,
223    {
224        Self {
225            chat: chat.into(),
226            gift: None,
227        }
228    }
229
230    /// Sets a new gift
231    ///
232    /// # Arguments
233    ///
234    /// * `value` - The gift sent to the chat by the bot.
235    pub fn with_gift(mut self, value: Gift) -> Self {
236        self.gift = Some(value);
237        self
238    }
239}
240
241/// Type of the partner user transaction.
242#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
243#[serde(rename_all = "snake_case")]
244pub enum TransactionPartnerUserType {
245    /// For direct transfers from managed business accounts.
246    BusinessAccountTransfer,
247    /// For gifts sent by the bot.
248    GiftPurchase,
249    /// For payments via invoices.
250    InvoicePayment,
251    /// For payments for paid media.
252    PaidMediaPayment,
253    /// For Telegram Premium subscriptions gifted by the bot.
254    PremiumPurchase,
255}
256
257/// Describes a transaction with a user.
258#[serde_with::skip_serializing_none]
259#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
260pub struct TransactionPartnerUserParameters {
261    /// Type of the transaction.
262    pub transaction_type: TransactionPartnerUserType,
263    /// Information about the user.
264    pub user: User,
265    /// Information about the affiliate that received a commission via this transaction.
266    pub affiliate: Option<AffiliateInfo>,
267    /// The gift sent to the user by the bot.
268    pub gift: Option<String>,
269    /// Bot-specified invoice payload.
270    pub invoice_payload: Option<String>,
271    /// Information about the paid media bought by the user.
272    pub paid_media: Option<Vec<PaidMedia>>,
273    /// Bot-specified paid media payload.
274    pub paid_media_payload: Option<String>,
275    /// Number of months the gifted Telegram Premium subscription will be active for;
276    /// for “premium_purchase” transactions only.
277    pub premium_subscription_duration: Option<Integer>,
278    /// The duration of the paid subscription.
279    pub subscription_period: Option<Integer>,
280}
281
282impl TransactionPartnerUserParameters {
283    /// Creates a new `TransactionPartnerUserParameters`.
284    ///
285    /// # Arguments
286    ///
287    /// * `transaction_type` - Type of the transaction.
288    /// * `user` - Information about the user.
289    pub fn new(transaction_type: TransactionPartnerUserType, user: User) -> Self {
290        Self {
291            transaction_type,
292            user,
293            affiliate: None,
294            gift: None,
295            invoice_payload: None,
296            paid_media: None,
297            paid_media_payload: None,
298            premium_subscription_duration: None,
299            subscription_period: None,
300        }
301    }
302
303    /// Sets a new affiliate.
304    ///
305    /// # Arguments
306    ///
307    /// * `value` - Information about the affiliate that received a commission via this transaction.
308    pub fn with_affiliate(mut self, value: AffiliateInfo) -> Self {
309        self.affiliate = Some(value);
310        self
311    }
312
313    /// Sets a new gift.
314    ///
315    /// # Arguments
316    ///
317    /// * `value` - The gift sent to the user by the bot.
318    pub fn with_gift<T>(mut self, value: T) -> Self
319    where
320        T: Into<String>,
321    {
322        self.gift = Some(value.into());
323        self
324    }
325
326    /// Sets a new invoice payload.
327    ///
328    /// # Arguments
329    ///
330    /// * `value` - Bot-specified invoice payload.
331    pub fn with_invoice_payload<T>(mut self, value: T) -> Self
332    where
333        T: Into<String>,
334    {
335        self.invoice_payload = Some(value.into());
336        self
337    }
338
339    /// Sets a new paid media.
340    ///
341    /// # Arguments
342    ///
343    /// * `value` - Information about the paid media bought by the user.
344    pub fn with_paid_media<T>(mut self, value: T) -> Self
345    where
346        T: IntoIterator<Item = PaidMedia>,
347    {
348        self.paid_media = Some(value.into_iter().collect());
349        self
350    }
351
352    /// Sets a new paid media payload.
353    ///
354    /// # Arguments
355    ///
356    /// * `value` - Bot-specified paid media payload.
357    pub fn with_paid_media_payload<T>(mut self, value: T) -> Self
358    where
359        T: Into<String>,
360    {
361        self.paid_media_payload = Some(value.into());
362        self
363    }
364
365    /// Sets a new premium subscription duration.
366    ///
367    /// # Arguments
368    ///
369    /// * `value` - Number of months the gifted Telegram Premium subscription will be active for;
370    ///   for “premium_purchase” transactions only.
371    pub fn with_premium_subscription_duration(mut self, value: Integer) -> Self {
372        self.premium_subscription_duration = Some(value);
373        self
374    }
375
376    /// Sets a new subscription period.
377    ///
378    /// # Arguments
379    ///
380    /// * `value` - The duration of the paid subscription.
381    pub fn with_subscription_period(mut self, value: Integer) -> Self {
382        self.subscription_period = Some(value);
383        self
384    }
385}
386
387/// Describes the source of a transaction, or its recipient for outgoing transactions.
388#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
389#[serde(from = "RawTransactionPartner", into = "RawTransactionPartner")]
390#[allow(clippy::large_enum_variant)]
391pub enum TransactionPartner {
392    /// Describes the affiliate program that issued the affiliate commission received via this transaction.
393    AffiliateProgram(TransactionPartnerAffiliateProgramParameters),
394    /// Describes a transaction with a chat.
395    Chat(TransactionPartnerChatParameters),
396    /// Describes a withdrawal transaction with Fragment.
397    Fragment(Option<RevenueWithdrawalState>),
398    /// Describes a transaction with an unknown source or recipient.
399    Other,
400    /// Describes a withdrawal transaction to the Telegram Ads platform.
401    TelegramAds,
402    /// Describes a transaction with payment for paid broadcasting.
403    TelegramApi {
404        /// The number of successful requests that exceeded regular limits and were therefore billed.
405        request_count: Integer,
406    },
407    /// Describes a transaction with a user.
408    User(TransactionPartnerUserParameters),
409}
410
411#[serde_with::skip_serializing_none]
412#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
413#[serde(tag = "type", rename_all = "snake_case")]
414#[allow(clippy::large_enum_variant)]
415enum RawTransactionPartner {
416    AffiliateProgram(TransactionPartnerAffiliateProgramParameters),
417    Chat(TransactionPartnerChatParameters),
418    Fragment {
419        withdrawal_state: Option<RevenueWithdrawalState>,
420    },
421    Other {},
422    TelegramAds {},
423    TelegramApi {
424        request_count: Integer,
425    },
426    User(TransactionPartnerUserParameters),
427}
428
429impl From<RawTransactionPartner> for TransactionPartner {
430    fn from(value: RawTransactionPartner) -> Self {
431        match value {
432            RawTransactionPartner::AffiliateProgram(parameters) => Self::AffiliateProgram(parameters),
433            RawTransactionPartner::Chat(parameters) => Self::Chat(parameters),
434            RawTransactionPartner::Fragment { withdrawal_state } => Self::Fragment(withdrawal_state),
435            RawTransactionPartner::Other {} => Self::Other,
436            RawTransactionPartner::TelegramAds {} => Self::TelegramAds,
437            RawTransactionPartner::TelegramApi { request_count } => Self::TelegramApi { request_count },
438            RawTransactionPartner::User(parameters) => Self::User(parameters),
439        }
440    }
441}
442
443impl From<TransactionPartner> for RawTransactionPartner {
444    fn from(value: TransactionPartner) -> Self {
445        match value {
446            TransactionPartner::AffiliateProgram(parameters) => Self::AffiliateProgram(parameters),
447            TransactionPartner::Chat(parameters) => Self::Chat(parameters),
448            TransactionPartner::Fragment(withdrawal_state) => Self::Fragment { withdrawal_state },
449            TransactionPartner::Other => Self::Other {},
450            TransactionPartner::TelegramAds => Self::TelegramAds {},
451            TransactionPartner::TelegramApi { request_count } => Self::TelegramApi { request_count },
452            TransactionPartner::User(parameters) => Self::User(parameters),
453        }
454    }
455}
456
457/// Describes the state of a revenue withdrawal operation.
458#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
459#[serde(from = "RawRevenueWithdrawalState", into = "RawRevenueWithdrawalState")]
460pub enum RevenueWithdrawalState {
461    /// The withdrawal failed and the transaction was refunded.
462    Failed,
463    /// The withdrawal is in progress.
464    Pending,
465    /// The withdrawal succeeded.
466    Succeeded {
467        /// Date the withdrawal was completed in Unix time.
468        date: Integer,
469        /// An HTTPS URL that can be used to see transaction details.
470        url: String,
471    },
472}
473
474#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
475#[serde(tag = "type", rename_all = "snake_case")]
476enum RawRevenueWithdrawalState {
477    Failed {},
478    Pending {},
479    Succeeded { date: Integer, url: String },
480}
481
482impl From<RawRevenueWithdrawalState> for RevenueWithdrawalState {
483    fn from(value: RawRevenueWithdrawalState) -> Self {
484        use self::RawRevenueWithdrawalState::*;
485        match value {
486            Failed {} => Self::Failed,
487            Pending {} => Self::Pending,
488            Succeeded { date, url } => Self::Succeeded { date, url },
489        }
490    }
491}
492
493impl From<RevenueWithdrawalState> for RawRevenueWithdrawalState {
494    fn from(value: RevenueWithdrawalState) -> Self {
495        use self::RevenueWithdrawalState::*;
496        match value {
497            Failed => Self::Failed {},
498            Pending => Self::Pending {},
499            Succeeded { date, url } => Self::Succeeded { date, url },
500        }
501    }
502}
503
504/// Returns the bot's Telegram Star transactions in chronological order.
505#[serde_with::skip_serializing_none]
506#[derive(Clone, Copy, Debug, Default, Serialize)]
507pub struct GetStarTransactions {
508    offset: Option<Integer>,
509    limit: Option<Integer>,
510}
511
512impl GetStarTransactions {
513    /// Sets a new offset.
514    ///
515    /// # Arguments
516    ///
517    /// * `value` - Number of transactions to skip in the response.
518    pub fn with_offset(mut self, value: Integer) -> Self {
519        self.offset = Some(value);
520        self
521    }
522
523    /// Sets a new limit.
524    ///
525    /// # Arguments
526    ///
527    /// * `value` - The maximum number of transactions to be retrieved.
528    ///
529    /// Values between 1-100 are accepted.
530    /// Defaults to 100.
531    pub fn with_limit(mut self, value: Integer) -> Self {
532        self.limit = Some(value);
533        self
534    }
535}
536
537impl Method for GetStarTransactions {
538    type Response = StarTransactions;
539
540    fn into_payload(self) -> Payload {
541        Payload::json("getStarTransactions", self)
542    }
543}