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
//! Create and manage invoices.
//!
//! The Invoices API lets you create and manage invoices for orders that were created using the
//! Orders API. After you create the invoice and configure its delivery method, payment schedule,
//! and other invoice settings, you can publish the invoice. Depending on the invoice settings,
//! Square sends the invoice to the customer or automatically charges a card on file. Square also
//! hosts each invoice on a web page where customers can easily pay for it.
use crate::models::{
CreateInvoiceAttachmentRequest, CreateInvoiceAttachmentResponse,
DeleteInvoiceAttachmentResponse,
};
use crate::{
SquareClient,
config::Configuration,
http::client::HttpClient,
models::{
CancelInvoiceRequest, CancelInvoiceResponse, CreateInvoiceRequest, CreateInvoiceResponse,
DeleteInvoiceParameters, DeleteInvoiceResponse, GetInvoiceResponse, ListInvoicesParameters,
ListInvoicesResponse, PublishInvoiceRequest, PublishInvoiceResponse, SearchInvoicesRequest,
SearchInvoicesResponse, UpdateInvoiceRequest, UpdateInvoiceResponse,
errors::SquareApiError,
},
};
const DEFAULT_URI: &str = "/invoices";
/// Create and manage invoices.
pub struct InvoicesApi {
/// App config information
config: Configuration,
/// HTTP Client for requests to the Invoices API endpoints
http_client: HttpClient,
}
impl InvoicesApi {
/// Instantiates a new `InvoicesApi`
pub fn new(square_client: SquareClient) -> InvoicesApi {
InvoicesApi {
config: square_client.config,
http_client: square_client.http_client,
}
}
/// Returns a list of invoices for a given location.
///
/// The response is paginated. If truncated, the response includes a `cursor` that you use in a
/// subsequent request to retrieve the next set of invoices.
pub async fn list_invoices(
&self,
params: &ListInvoicesParameters,
) -> Result<ListInvoicesResponse, SquareApiError> {
let url = format!("{}{}", &self.url(), params.to_query_string());
let response = self.http_client.get(&url).await?;
response.deserialize().await
}
/// Creates a draft [Invoice] for an order created using the Orders API.
///
/// A draft invoice remains in your account and no action is taken. You must publish the invoice
/// before Square can process it (send it to the customer's email address or charge the
/// customer’s card on file).
pub async fn create_invoice(
&self,
body: &CreateInvoiceRequest,
) -> Result<CreateInvoiceResponse, SquareApiError> {
let response = self.http_client.post(&self.url(), body).await?;
response.deserialize().await
}
/// Searches for invoices from a location specified in the filter.
///
/// You can optionally specify customers in the filter for whom to retrieve invoices. In the
/// current implementation, you can only specify one location and optionally one customer.
///
/// The response is paginated. If truncated, the response includes a `cursor` that you use in a
/// subsequent request to retrieve the next set of invoices.
pub async fn search_invoices(
&self,
body: &SearchInvoicesRequest,
) -> Result<SearchInvoicesResponse, SquareApiError> {
let url = format!("{}/search", &self.url());
let response = self.http_client.post(&url, body).await?;
response.deserialize().await
}
/// Deletes the specified invoice.
///
/// When an invoice is deleted, the associated order status changes to CANCELED. You can only
/// delete a draft invoice (you cannot delete a published invoice, including one that is
/// scheduled for processing).
pub async fn delete_invoice(
&self,
invoice_id: impl AsRef<str>,
params: &DeleteInvoiceParameters,
) -> Result<DeleteInvoiceResponse, SquareApiError> {
let url = format!(
"{}/{}{}",
&self.url(),
invoice_id.as_ref(),
params.to_query_string()
);
let response = self.http_client.delete(&url).await?;
response.deserialize().await
}
/// Retrieves an invoice by invoice ID.
pub async fn get_invoice(
&self,
invoice_id: impl AsRef<str>,
) -> Result<GetInvoiceResponse, SquareApiError> {
let url = format!("{}/{}", &self.url(), invoice_id.as_ref());
let response = self.http_client.get(&url).await?;
response.deserialize().await
}
/// Updates an invoice by modifying fields, clearing fields, or both.
///
/// For most updates, you can use a sparse [Invoice] object to add fields or change values and
/// use the `fields_to_clear` field to specify fields to clear. However, some restrictions
/// apply. For example, you cannot change the `order_id` or `location_id` field and you must
/// provide the complete `custom_fields` list to update a custom field. Published invoices have
/// additional restrictions.
pub async fn update_invoice(
&self,
invoice_id: impl AsRef<str>,
body: &UpdateInvoiceRequest,
) -> Result<UpdateInvoiceResponse, SquareApiError> {
let url = format!("{}/{}", &self.url(), invoice_id.as_ref());
let response = self.http_client.put(&url, body).await?;
response.deserialize().await
}
/// Cancels an invoice.
///
/// The seller cannot collect payments for the canceled invoice.
///
/// You cannot cancel an invoice in the `DRAFT` state or in a terminal state: `PAID`,
/// `REFUNDED`, `CANCELED`, or `FAILED`.
pub async fn cancel_invoice(
&self,
invoice_id: impl AsRef<str>,
body: &CancelInvoiceRequest,
) -> Result<CancelInvoiceResponse, SquareApiError> {
let url = format!("{}/{}/cancel", &self.url(), invoice_id.as_ref());
let response = self.http_client.post(&url, body).await?;
response.deserialize().await
}
/// Publishes the specified draft invoice.
///
/// After an invoice is published, Square follows up based on the invoice configuration. For
/// example, Square sends the invoice to the customer's email address, charges the customer's
/// card on file, or does nothing. Square also makes the invoice available on a Square-hosted
/// invoice page.
///
/// The invoice `status` also changes from `DRAFT` to a status based on the invoice
/// configuration. For example, the status changes to `UNPAID` if Square emails the invoice or
/// `PARTIALLY_PAID` if Square charge a card on file for a portion of the invoice amount.
pub async fn publish_invoice(
&self,
invoice_id: impl AsRef<str>,
body: &PublishInvoiceRequest,
) -> Result<PublishInvoiceResponse, SquareApiError> {
let url = format!("{}/{}/publish", &self.url(), invoice_id.as_ref());
let response = self.http_client.post(&url, body).await?;
response.deserialize().await
}
/// Uploads a file and attaches it to an invoice.
///
/// This endpoint accepts HTTP multipart/form-data file uploads with a JSON request part and a file part. The
/// file part must be a readable stream that contains a file in a supported format: GIF, JPEG, PNG, TIFF, BMP, or
/// PDF.
///
/// Invoices can have up to 10 attachments with a total file size of 25 MB. Attachments can be added only to
/// invoices in the DRAFT, SCHEDULED, UNPAID, or PARTIALLY_PAID state
pub async fn create_invoice_attachment(
&self,
invoice_id: impl AsRef<str>,
body: &CreateInvoiceAttachmentRequest,
filepath: impl AsRef<str>,
) -> Result<CreateInvoiceAttachmentResponse, SquareApiError> {
let url = format!("{}/{}/attachments", &self.url(), invoice_id.as_ref());
let response = self
.http_client
.post_multipart(&url, body, filepath.as_ref())
.await?;
response.deserialize().await
}
/// Removes an attachment from an invoice and permanently deletes the file.
///
/// Attachments can be removed only from invoices in the DRAFT, SCHEDULED, UNPAID, or PARTIALLY_PAID state.
pub async fn delete_invoice_attachment(
&self,
invoice_id: impl AsRef<str>,
attachment_id: impl AsRef<str>,
) -> Result<DeleteInvoiceAttachmentResponse, SquareApiError> {
let url = format!(
"{}/{}/attachments/{}",
&self.url(),
invoice_id.as_ref(),
attachment_id.as_ref()
);
let response = self.http_client.delete(&url).await?;
response.deserialize().await
}
fn url(&self) -> String {
format!("{}{}", &self.config.get_base_url(), DEFAULT_URI)
}
}