tgbot/types/payment/checkout/
mod.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{
4    api::{Method, Payload},
5    types::{Integer, OrderInfo, User},
6};
7
8#[cfg(test)]
9mod tests;
10
11/// Represents an incoming pre-checkout query.
12#[serde_with::skip_serializing_none]
13#[derive(Clone, Debug, Deserialize, PartialOrd, PartialEq, Serialize)]
14pub struct PreCheckoutQuery {
15    /// Three-letter ISO 4217 currency code.
16    pub currency: String,
17    /// User who sent the query.
18    pub from: User,
19    /// Unique query identifier.
20    pub id: String,
21    /// Bot specified invoice payload.
22    pub invoice_payload: String,
23    /// Total price in the smallest units of the currency (integer, not float/double).
24    ///
25    /// For example, for a price of US$ 1.45 pass amount = 145.
26    /// See the exp parameter in [currencies.json][1], it shows the number of digits past the
27    /// decimal point for each currency (2 for the majority of currencies).
28    ///
29    /// [1]: https://core.telegram.org/bots/payments/currencies.json
30    pub total_amount: Integer,
31    /// Order info provided by the user.
32    pub order_info: Option<OrderInfo>,
33    /// Identifier of the shipping option chosen by the user.
34    pub shipping_option_id: Option<String>,
35}
36
37impl PreCheckoutQuery {
38    /// Creates a new `PreCheckoutQuery`.
39    ///
40    /// # Arguments
41    ///
42    /// * `currency` - Three-letter ISO 4217 currency code.
43    /// * `from` - User who sent the query.
44    /// * `id` - Unique query identifier.
45    /// * `invoice_payload` - Bot specified invoice payload.
46    /// * `total_amount` - Total price in the smallest units of the currency.
47    pub fn new<A, B, C>(currency: A, from: User, id: B, invoice_payload: C, total_amount: Integer) -> Self
48    where
49        A: Into<String>,
50        B: Into<String>,
51        C: Into<String>,
52    {
53        Self {
54            currency: currency.into(),
55            from,
56            id: id.into(),
57            invoice_payload: invoice_payload.into(),
58            total_amount,
59            order_info: None,
60            shipping_option_id: None,
61        }
62    }
63
64    /// Sets a new order info.
65    ///
66    /// # Arguments
67    ///
68    /// * `value` - Order info.
69    pub fn with_order_info(mut self, value: OrderInfo) -> Self {
70        self.order_info = Some(value);
71        self
72    }
73    /// Sets a new shipping option ID.
74    ///
75    /// # Arguments
76    ///
77    /// * `value` - Shipping option ID.
78    pub fn with_shipping_option_id<T>(mut self, value: T) -> Self
79    where
80        T: Into<String>,
81    {
82        self.shipping_option_id = Some(value.into());
83        self
84    }
85}
86
87/// Responds to a pre-checkout query.
88///
89/// Once the user has confirmed their payment and shipping details,
90/// the Bot API sends the final confirmation in the form of an
91/// [`crate::types::UpdateType::PreCheckoutQuery`].
92///
93/// # Notes
94///
95/// The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent.
96#[serde_with::skip_serializing_none]
97#[derive(Clone, Debug, Serialize)]
98pub struct AnswerPreCheckoutQuery {
99    ok: bool,
100    pre_checkout_query_id: String,
101    error_message: Option<String>,
102}
103
104impl AnswerPreCheckoutQuery {
105    /// Creates a new `AnswerPreCheckoutQuery` with a success answer.
106    ///
107    /// # Arguments
108    ///
109    /// * `id` - Unique identifier of the query to be answered.
110    pub fn ok<T>(id: T) -> Self
111    where
112        T: Into<String>,
113    {
114        Self {
115            pre_checkout_query_id: id.into(),
116            ok: true,
117            error_message: None,
118        }
119    }
120
121    /// Creates a new `AnswerPreCheckoutQuery` with an error answer.
122    ///
123    /// # Arguments
124    ///
125    /// * `id` - Unique identifier of the query to be answered.
126    /// * `message` - Error message in human readable form
127    ///   that explains the reason for failure to proceed with the checkout.
128    pub fn error<A, B>(id: A, message: B) -> Self
129    where
130        A: Into<String>,
131        B: Into<String>,
132    {
133        Self {
134            ok: false,
135            pre_checkout_query_id: id.into(),
136            error_message: Some(message.into()),
137        }
138    }
139}
140
141impl Method for AnswerPreCheckoutQuery {
142    type Response = bool;
143
144    fn into_payload(self) -> Payload {
145        Payload::json("answerPreCheckoutQuery", self)
146    }
147}