Skip to main content

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")]
390pub enum TransactionPartner {
391    /// Describes the affiliate program that issued the affiliate commission received via this transaction.
392    AffiliateProgram(TransactionPartnerAffiliateProgramParameters),
393    /// Describes a transaction with a chat.
394    Chat(TransactionPartnerChatParameters),
395    /// Describes a withdrawal transaction with Fragment.
396    Fragment(Option<RevenueWithdrawalState>),
397    /// Describes a transaction with an unknown source or recipient.
398    Other,
399    /// Describes a withdrawal transaction to the Telegram Ads platform.
400    TelegramAds,
401    /// Describes a transaction with payment for paid broadcasting.
402    TelegramApi {
403        /// The number of successful requests that exceeded regular limits and were therefore billed.
404        request_count: Integer,
405    },
406    /// Describes a transaction with a user.
407    User(TransactionPartnerUserParameters),
408}
409
410#[serde_with::skip_serializing_none]
411#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
412#[serde(tag = "type", rename_all = "snake_case")]
413enum RawTransactionPartner {
414    AffiliateProgram(TransactionPartnerAffiliateProgramParameters),
415    Chat(TransactionPartnerChatParameters),
416    Fragment {
417        withdrawal_state: Option<RevenueWithdrawalState>,
418    },
419    Other {},
420    TelegramAds {},
421    TelegramApi {
422        request_count: Integer,
423    },
424    User(TransactionPartnerUserParameters),
425}
426
427impl From<RawTransactionPartner> for TransactionPartner {
428    fn from(value: RawTransactionPartner) -> Self {
429        match value {
430            RawTransactionPartner::AffiliateProgram(parameters) => Self::AffiliateProgram(parameters),
431            RawTransactionPartner::Chat(parameters) => Self::Chat(parameters),
432            RawTransactionPartner::Fragment { withdrawal_state } => Self::Fragment(withdrawal_state),
433            RawTransactionPartner::Other {} => Self::Other,
434            RawTransactionPartner::TelegramAds {} => Self::TelegramAds,
435            RawTransactionPartner::TelegramApi { request_count } => Self::TelegramApi { request_count },
436            RawTransactionPartner::User(parameters) => Self::User(parameters),
437        }
438    }
439}
440
441impl From<TransactionPartner> for RawTransactionPartner {
442    fn from(value: TransactionPartner) -> Self {
443        match value {
444            TransactionPartner::AffiliateProgram(parameters) => Self::AffiliateProgram(parameters),
445            TransactionPartner::Chat(parameters) => Self::Chat(parameters),
446            TransactionPartner::Fragment(withdrawal_state) => Self::Fragment { withdrawal_state },
447            TransactionPartner::Other => Self::Other {},
448            TransactionPartner::TelegramAds => Self::TelegramAds {},
449            TransactionPartner::TelegramApi { request_count } => Self::TelegramApi { request_count },
450            TransactionPartner::User(parameters) => Self::User(parameters),
451        }
452    }
453}
454
455/// Describes the state of a revenue withdrawal operation.
456#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
457#[serde(from = "RawRevenueWithdrawalState", into = "RawRevenueWithdrawalState")]
458pub enum RevenueWithdrawalState {
459    /// The withdrawal failed and the transaction was refunded.
460    Failed,
461    /// The withdrawal is in progress.
462    Pending,
463    /// The withdrawal succeeded.
464    Succeeded {
465        /// Date the withdrawal was completed in Unix time.
466        date: Integer,
467        /// An HTTPS URL that can be used to see transaction details.
468        url: String,
469    },
470}
471
472#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
473#[serde(tag = "type", rename_all = "snake_case")]
474enum RawRevenueWithdrawalState {
475    Failed {},
476    Pending {},
477    Succeeded { date: Integer, url: String },
478}
479
480impl From<RawRevenueWithdrawalState> for RevenueWithdrawalState {
481    fn from(value: RawRevenueWithdrawalState) -> Self {
482        use self::RawRevenueWithdrawalState::*;
483        match value {
484            Failed {} => Self::Failed,
485            Pending {} => Self::Pending,
486            Succeeded { date, url } => Self::Succeeded { date, url },
487        }
488    }
489}
490
491impl From<RevenueWithdrawalState> for RawRevenueWithdrawalState {
492    fn from(value: RevenueWithdrawalState) -> Self {
493        use self::RevenueWithdrawalState::*;
494        match value {
495            Failed => Self::Failed {},
496            Pending => Self::Pending {},
497            Succeeded { date, url } => Self::Succeeded { date, url },
498        }
499    }
500}
501
502/// Returns the bot's Telegram Star transactions in chronological order.
503#[serde_with::skip_serializing_none]
504#[derive(Clone, Copy, Debug, Default, Serialize)]
505pub struct GetStarTransactions {
506    offset: Option<Integer>,
507    limit: Option<Integer>,
508}
509
510impl GetStarTransactions {
511    /// Sets a new offset.
512    ///
513    /// # Arguments
514    ///
515    /// * `value` - Number of transactions to skip in the response.
516    pub fn with_offset(mut self, value: Integer) -> Self {
517        self.offset = Some(value);
518        self
519    }
520
521    /// Sets a new limit.
522    ///
523    /// # Arguments
524    ///
525    /// * `value` - The maximum number of transactions to be retrieved.
526    ///
527    /// Values between 1-100 are accepted.
528    /// Defaults to 100.
529    pub fn with_limit(mut self, value: Integer) -> Self {
530        self.limit = Some(value);
531        self
532    }
533}
534
535impl Method for GetStarTransactions {
536    type Response = StarTransactions;
537
538    fn into_payload(self) -> Payload {
539        Payload::json("getStarTransactions", self)
540    }
541}