sumup 0.5.9

Rust SDK for the SumUp API.
Documentation
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
// The contents of this file are generated; do not modify them.

//! The Receipts model obtains receipt-like details for specific transactions.
use super::common::*;
/// Receipt details for a transaction.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct Receipt {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_data: Option<ReceiptTransaction>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub merchant_data: Option<ReceiptMerchantData>,
    /// EMV-specific metadata returned for card-present payments.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub emv_data: Option<serde_json::Value>,
    /// Acquirer-specific metadata related to the card authorization.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub acquirer_data: Option<ReceiptAcquirerData>,
}
/// Payment card details displayed on the receipt.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptCard {
    /// Card last 4 digits.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub last_4_digits: Option<String>,
    /// Card Scheme.
    #[serde(rename = "type")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub r#type: Option<String>,
}
/// Transaction event details as rendered on the receipt.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptEvent {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<EventId>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_id: Option<TransactionId>,
    #[serde(rename = "type")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub r#type: Option<EventType>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<EventStatus>,
    /// Amount of the event.
    ///
    /// Constraints:
    /// - format: `double`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub amount: Option<f64>,
    /// Date and time of the transaction event.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub timestamp: Option<crate::datetime::DateTime>,
    /// Receipt number associated with the event.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub receipt_no: Option<String>,
}
/// Receipt merchant data
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptMerchantData {
    /// Merchant profile details displayed on the receipt.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub merchant_profile: Option<ReceiptMerchantDataMerchantProfile>,
    /// Locale used for rendering localized receipt fields.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub locale: Option<String>,
}
/// Card reader details displayed on the receipt.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptReader {
    /// Reader serial number.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub code: Option<String>,
    /// Reader type.
    #[serde(rename = "type")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub r#type: Option<String>,
}
/// Transaction information.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptTransaction {
    /// Transaction code.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_code: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_id: Option<TransactionId>,
    /// Merchant code.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub merchant_code: Option<String>,
    /// Transaction amount.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub amount: Option<String>,
    /// Transaction VAT amount.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub vat_amount: Option<String>,
    /// Tip amount (included in transaction amount).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tip_amount: Option<String>,
    /// Transaction currency.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub currency: Option<String>,
    /// Time created at.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub timestamp: Option<crate::datetime::DateTime>,
    /// Transaction processing status.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<String>,
    /// Transaction type.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub payment_type: Option<String>,
    /// Transaction entry mode.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub entry_mode: Option<String>,
    /// Cardholder verification method.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub verification_method: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub card_reader: Option<ReceiptReader>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub card: Option<ReceiptCard>,
    /// Number of installments.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub installments_count: Option<i64>,
    /// Debit/Credit.
    ///
    /// Example: `CREDIT`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub process_as: Option<ReceiptTransactionProcessAs>,
    /// Products
    #[serde(skip_serializing_if = "Option::is_none")]
    pub products: Option<Vec<ReceiptTransactionProductsItem>>,
    /// Vat rates.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub vat_rates: Option<Vec<ReceiptTransactionVatRatesItem>>,
    /// Events
    #[serde(skip_serializing_if = "Option::is_none")]
    pub events: Option<Vec<ReceiptEvent>>,
    /// Receipt number
    #[serde(skip_serializing_if = "Option::is_none")]
    pub receipt_no: Option<String>,
}
/// Acquirer-specific metadata related to the card authorization.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptAcquirerData {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tid: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub authorization_code: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub return_code: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub local_time: Option<String>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptMerchantDataMerchantProfileAddress {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub address_line1: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub address_line2: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub city: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub country: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub country_en_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub country_native_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub region_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub post_code: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub landline: Option<String>,
}
/// Merchant profile details displayed on the receipt.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptMerchantDataMerchantProfile {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub merchant_code: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub business_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub company_registration_number: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub vat_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub website: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub email: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub language: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub address: Option<ReceiptMerchantDataMerchantProfileAddress>,
}
/// Debit/Credit.
///
/// Example: `CREDIT`
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum ReceiptTransactionProcessAs {
    #[serde(rename = "CREDIT")]
    Credit,
    #[serde(rename = "DEBIT")]
    Debit,
    #[serde(untagged)]
    Other(String),
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptTransactionProductsItem {
    /// Product name
    ///
    /// Example: `Coffee`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    /// Product description
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    /// Product price
    ///
    /// Constraints:
    /// - format: `double`
    ///
    /// Example: `150.0`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub price: Option<f64>,
    /// VAT rate
    ///
    /// Constraints:
    /// - format: `double`
    ///
    /// Example: `0.0`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub vat_rate: Option<f64>,
    /// VAT amount for a single product
    ///
    /// Constraints:
    /// - format: `double`
    ///
    /// Example: `0.0`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub single_vat_amount: Option<f64>,
    /// Product price including VAT
    ///
    /// Constraints:
    /// - format: `double`
    ///
    /// Example: `150.0`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub price_with_vat: Option<f64>,
    /// VAT amount
    ///
    /// Constraints:
    /// - format: `double`
    ///
    /// Example: `0.0`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub vat_amount: Option<f64>,
    /// Product quantity
    ///
    /// Example: `1`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub quantity: Option<i64>,
    /// Quantity x product price
    ///
    /// Constraints:
    /// - format: `double`
    ///
    /// Example: `150.0`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub total_price: Option<f64>,
    /// Total price including VAT
    ///
    /// Constraints:
    /// - format: `double`
    ///
    /// Example: `150.0`
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        deserialize_with = "crate::string_or_number::deserialize_option"
    )]
    pub total_with_vat: Option<f64>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ReceiptTransactionVatRatesItem {
    /// Gross
    #[serde(skip_serializing_if = "Option::is_none")]
    pub gross: Option<f32>,
    /// Net
    #[serde(skip_serializing_if = "Option::is_none")]
    pub net: Option<f32>,
    /// Rate
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rate: Option<f32>,
    /// Vat
    #[serde(skip_serializing_if = "Option::is_none")]
    pub vat: Option<f32>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct GetParams {
    /// Merchant code.
    pub mid: String,
    /// The ID of the transaction event (refund).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tx_event_id: Option<i64>,
}
use crate::client::Client;
#[derive(Debug)]
pub enum GetErrorBody {
    BadRequest(Error),
    Unauthorized(Problem),
    NotFound(Error),
}
/// Client for the Receipts API endpoints.
#[derive(Debug)]
pub struct ReceiptsClient<'a> {
    client: &'a Client,
}
impl<'a> ReceiptsClient<'a> {
    pub(crate) fn new(client: &'a Client) -> Self {
        Self { client }
    }
    /// Returns a reference to the underlying client.
    pub fn client(&self) -> &Client {
        self.client
    }
    /// Retrieve receipt details
    ///
    /// Retrieves receipt specific data for a transaction.
    ///
    /// Responses:
    /// - 200: Returns receipt details for the requested transaction.
    /// - 400: The request is invalid for the submitted parameters.
    /// - 401: The request is not authorized.
    /// - 404: The requested transaction event does not exist for the provided transaction.
    pub async fn get(
        &self,
        id: impl Into<String>,
        params: GetParams,
    ) -> crate::error::SdkResult<Receipt, GetErrorBody> {
        let path = format!("/v1.1/receipts/{}", id.into());
        let url = format!("{}{}", self.client.base_url(), path);
        let mut request = self
            .client
            .http_client()
            .get(&url)
            .header("User-Agent", crate::version::user_agent())
            .timeout(self.client.timeout());
        if let Some(authorization) = self.client.authorization() {
            request = request.header("Authorization", format!("Bearer {}", authorization));
        }
        for (header_name, header_value) in self.client.runtime_headers() {
            request = request.header(*header_name, header_value);
        }
        request = request.query(&[("mid", &params.mid)]);
        if let Some(ref value) = params.tx_event_id {
            request = request.query(&[("tx_event_id", value)]);
        }
        let response = request.send().await?;
        let status = response.status();
        match status {
            reqwest::StatusCode::OK => {
                let data: Receipt = response.json().await?;
                Ok(data)
            }
            reqwest::StatusCode::BAD_REQUEST => {
                let body: Error = response.json().await?;
                Err(crate::error::SdkError::api(GetErrorBody::BadRequest(body)))
            }
            reqwest::StatusCode::UNAUTHORIZED => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(GetErrorBody::Unauthorized(
                    body,
                )))
            }
            reqwest::StatusCode::NOT_FOUND => {
                let body: Error = response.json().await?;
                Err(crate::error::SdkError::api(GetErrorBody::NotFound(body)))
            }
            _ => {
                let body_bytes = response.bytes().await?;
                let body = crate::error::UnknownApiBody::from_bytes(body_bytes.as_ref());
                Err(crate::error::SdkError::unexpected(status, body))
            }
        }
    }
}