1use crate::client::ConcurClient;
6use crate::error::Result;
7use reqwest::Method;
8use serde::{Deserialize, Serialize};
9
10pub struct InvoicePayApi<'a> {
12 client: &'a ConcurClient,
13}
14
15impl<'a> InvoicePayApi<'a> {
16 pub fn new(client: &'a ConcurClient) -> Self {
17 Self { client }
18 }
19
20 pub async fn list_payments(&self, query: &PaymentQuery) -> Result<PaymentsResponse> {
22 let mut path = "/invoice/provider-payment/v4/payments".to_string();
23 let mut params: Vec<(String, String)> = Vec::new();
24 if let Some(v) = &query.invoice_id {
25 params.push(("invoiceId".to_string(), v.clone()));
26 }
27 if let Some(v) = &query.invoice_date {
28 params.push(("invoiceDate".to_string(), v.clone()));
29 }
30 if let Some(v) = &query.create_date {
31 params.push(("createDate".to_string(), v.clone()));
32 }
33 if let Some(v) = &query.vendor_name {
34 params.push(("vendorName".to_string(), v.clone()));
35 }
36 if let Some(v) = &query.vendor_code {
37 params.push(("vendorCode".to_string(), v.clone()));
38 }
39 if let Some(v) = &query.vendor_addr_code {
40 params.push(("vendorAddrCode".to_string(), v.clone()));
41 }
42 if let Some(v) = &query.payment_status {
43 params.push(("PaymentStatus".to_string(), v.clone()));
44 }
45 if let Some(v) = &query.payment_group {
46 params.push(("PaymentGroup".to_string(), v.clone()));
47 }
48 if let Some(v) = &query.invoice_number {
49 params.push(("invoiceNumber".to_string(), v.clone()));
50 }
51 if let Some(v) = &query.payment_id {
52 params.push(("paymentId".to_string(), v.clone()));
53 }
54 if !params.is_empty() {
55 path.push('?');
56 path.push_str(
57 ¶ms
58 .iter()
59 .map(|(k, v)| format!("{}={}", k, urlencoding::encode(v)))
60 .collect::<Vec<_>>()
61 .join("&"),
62 );
63 }
64 self.client
65 .request(Method::GET, &path)
66 .await?
67 .send()
68 .await?
69 .json()
70 .await
71 .map_err(Into::into)
72 }
73
74 pub async fn update_payment(
76 &self,
77 payment_id: &str,
78 update: &PaymentUpdate,
79 ) -> Result<PaymentUpdateResult> {
80 let req = self
81 .client
82 .request(
83 Method::POST,
84 &format!("/invoice/provider-payment/v4/payments/{}", payment_id),
85 )
86 .await?;
87 let req = ConcurClient::with_json(req, update)?;
88 self.client.execute(req).await
89 }
90
91 pub async fn bulk_update_payments(
93 &self,
94 updates: &[PaymentUpdate],
95 ) -> Result<BulkUpdateResult> {
96 let req = self
97 .client
98 .request(
99 Method::POST,
100 "/invoice/provider-payment/v4/payments/bulkUpdate",
101 )
102 .await?;
103 let req = ConcurClient::with_json(req, updates)?;
104 self.client.execute(req).await
105 }
106}
107
108#[derive(Debug, Clone, Default)]
109pub struct PaymentQuery {
110 pub invoice_id: Option<String>,
111 pub invoice_date: Option<String>,
112 pub create_date: Option<String>,
113 pub vendor_name: Option<String>,
114 pub vendor_code: Option<String>,
115 pub vendor_addr_code: Option<String>,
116 pub payment_status: Option<String>,
117 pub payment_group: Option<String>,
118 pub invoice_number: Option<String>,
119 pub payment_id: Option<String>,
120}
121
122#[derive(Debug, Clone, Deserialize)]
123pub struct PaymentsResponse {
124 pub payments: Vec<serde_json::Value>,
125}
126
127#[derive(Debug, Clone, Default, Serialize, Deserialize)]
128pub struct PaymentUpdate {
129 #[serde(rename = "paymentId")]
130 pub payment_id: Option<String>,
131 #[serde(rename = "providerReference")]
132 pub provider_reference: Option<String>,
133 pub status: String,
134 #[serde(rename = "statusMessage")]
135 pub status_message: Option<String>,
136 #[serde(rename = "statusDate")]
137 pub status_date: Option<String>,
138 #[serde(rename = "paymentInitiationDate")]
139 pub payment_initiation_date: Option<String>,
140 #[serde(rename = "paymentSettlementDate")]
141 pub payment_settlement_date: Option<String>,
142 #[serde(rename = "thirdPartyPaymentIdentifier")]
143 pub third_party_payment_identifier: Option<String>,
144 #[serde(rename = "paymentMethod")]
145 pub payment_method: Option<String>,
146 #[serde(rename = "paidAmount")]
147 pub paid_amount: Option<Money>,
148 #[serde(rename = "paymentAdjustmentNotes")]
149 pub payment_adjustment_notes: Option<String>,
150 #[serde(rename = "fundingSourceRef")]
151 pub funding_source_ref: Option<String>,
152 #[serde(rename = "cashAccountCode")]
153 pub cash_account_code: Option<String>,
154 #[serde(rename = "liabilityAccountCode")]
155 pub liability_account_code: Option<String>,
156 #[serde(rename = "fundingRequestRef")]
157 pub funding_request_ref: Option<String>,
158 #[serde(rename = "checkNumber")]
159 pub check_number: Option<String>,
160 #[serde(rename = "fundingSettlementDate")]
161 pub funding_settlement_date: Option<String>,
162 #[serde(rename = "fundingCurrency")]
163 pub funding_currency: Option<String>,
164 #[serde(rename = "paymentCurrency")]
165 pub payment_currency: Option<String>,
166 #[serde(rename = "foreignExchangeRate")]
167 pub foreign_exchange_rate: Option<String>,
168}
169
170#[derive(Debug, Clone, Default, Serialize, Deserialize)]
171pub struct Money {
172 pub amount: String,
173 pub currency: String,
174}
175
176#[derive(Debug, Clone, Deserialize)]
177pub struct PaymentUpdateResult {
178 #[serde(rename = "paymentId")]
179 pub payment_id: String,
180 pub status: String,
181 #[serde(rename = "statusMessage")]
182 pub status_message: Option<String>,
183 #[serde(rename = "statusDate")]
184 pub status_date: Option<String>,
185}
186
187#[derive(Debug, Clone, Deserialize)]
188pub struct BulkUpdateResult {
189 #[serde(rename = "successfulPayments")]
190 pub successful_payments: Option<Vec<PaymentUpdateResult>>,
191 #[serde(rename = "failedPayments")]
192 pub failed_payments: Option<Vec<serde_json::Value>>,
193}