Skip to main content

oanda_client/
order.rs

1//! OANDA order endpoint contracts.
2
3use crate::client::RequestParts;
4use crate::ids::{
5    AccountID, ClientRequestID, InstrumentName, OrderID, OrderSpecifier, TransactionID,
6};
7use crate::models::{
8    ClientExtensions, Order, OrderCancelRejectTransaction, OrderCancelTransaction,
9    OrderClientExtensionsModifyRejectTransaction, OrderClientExtensionsModifyTransaction,
10    OrderFillTransaction, OrderRequest, OrderStateFilter, Transaction,
11};
12use crate::validation::Validate;
13use crate::{Client, Error, Result};
14use reqwest::Method;
15use serde::{Deserialize, Serialize};
16
17/// Request body for `create_order`.
18#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct CreateOrderBody {
21    /// Specification of the Order to create
22    #[serde(rename = "order", default, skip_serializing_if = "Option::is_none")]
23    pub order: Option<OrderRequest>,
24}
25
26impl Validate for CreateOrderBody {
27    fn validate(&self) -> Result<()> {
28        self.order
29            .as_ref()
30            .ok_or_else(|| Error::InvalidInput("order request is required".into()))?
31            .validate()
32    }
33}
34
35/// Successful response for `create_order`.
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37#[serde(rename_all = "camelCase")]
38pub struct CreateOrderResponse {
39    /// The Transaction that created the Order specified by the request.
40    #[serde(
41        rename = "orderCreateTransaction",
42        default,
43        skip_serializing_if = "Option::is_none"
44    )]
45    pub order_create_transaction: Option<Transaction>,
46    /// The Transaction that filled the newly created Order. Only provided when the Order was immediately filled.
47    #[serde(
48        rename = "orderFillTransaction",
49        default,
50        skip_serializing_if = "Option::is_none"
51    )]
52    pub order_fill_transaction: Option<OrderFillTransaction>,
53    /// The Transaction that cancelled the newly created Order. Only provided when the Order was immediately
54    /// cancelled.
55    #[serde(
56        rename = "orderCancelTransaction",
57        default,
58        skip_serializing_if = "Option::is_none"
59    )]
60    pub order_cancel_transaction: Option<OrderCancelTransaction>,
61    /// The Transaction that reissues the Order. Only provided when the Order is configured to be reissued for
62    /// its remaining units after a partial fill and the reissue was successful.
63    #[serde(
64        rename = "orderReissueTransaction",
65        default,
66        skip_serializing_if = "Option::is_none"
67    )]
68    pub order_reissue_transaction: Option<Transaction>,
69    /// The Transaction that rejects the reissue of the Order. Only provided when the Order is configured to be
70    /// reissued for its remaining units after a partial fill and the reissue was rejected.
71    #[serde(
72        rename = "orderReissueRejectTransaction",
73        default,
74        skip_serializing_if = "Option::is_none"
75    )]
76    pub order_reissue_reject_transaction: Option<Transaction>,
77    /// The IDs of all Transactions that were created while satisfying the request.
78    #[serde(
79        rename = "relatedTransactionIDs",
80        default,
81        skip_serializing_if = "Option::is_none"
82    )]
83    pub related_transaction_ids: Option<Vec<TransactionID>>,
84    /// The ID of the most recent Transaction created for the Account
85    #[serde(
86        rename = "lastTransactionID",
87        default,
88        skip_serializing_if = "Option::is_none"
89    )]
90    pub last_transaction_id: Option<TransactionID>,
91}
92
93/// Documented rejection fields for `create_order`.
94#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
95#[serde(rename_all = "camelCase")]
96pub struct CreateOrderRejection {
97    /// The Transaction that rejected the creation of the Order as requested
98    #[serde(
99        rename = "orderRejectTransaction",
100        default,
101        skip_serializing_if = "Option::is_none"
102    )]
103    pub order_reject_transaction: Option<Transaction>,
104    /// The IDs of all Transactions that were created while satisfying the request.
105    #[serde(
106        rename = "relatedTransactionIDs",
107        default,
108        skip_serializing_if = "Option::is_none"
109    )]
110    pub related_transaction_ids: Option<Vec<TransactionID>>,
111    /// The ID of the most recent Transaction created for the Account
112    #[serde(
113        rename = "lastTransactionID",
114        default,
115        skip_serializing_if = "Option::is_none"
116    )]
117    pub last_transaction_id: Option<TransactionID>,
118    /// The code of the error that has occurred. This field may not be returned for some errors.
119    #[serde(rename = "errorCode", default, skip_serializing_if = "Option::is_none")]
120    pub error_code: Option<String>,
121    /// The human-readable description of the error that has occurred.
122    #[serde(rename = "errorMessage")]
123    pub error_message: String,
124}
125
126impl Client {
127    /// Create order.
128    ///
129    /// # Errors
130    ///
131    /// Returns [`crate::OperationError::Client`] for invalid input, admission, transport, or
132    /// malformed response failures. Provider refusals return [`crate::OperationError::Rejected`]
133    /// or [`crate::OperationError::RejectedUnreadable`] when the rejection body cannot be read.
134    /// An uncertain sent mutation fences this account until caller-acknowledged reconciliation.
135    pub async fn create_order(
136        &self,
137        account_id: &AccountID,
138        body: &CreateOrderBody,
139    ) -> std::result::Result<
140        crate::ApiResponse<CreateOrderResponse>,
141        crate::OperationError<CreateOrderRejection>,
142    > {
143        let account_id_encoded = crate::client::segment(account_id.as_str());
144        let path = format!("/v3/accounts/{account_id_encoded}/orders");
145        self.execute(
146            RequestParts::new(Method::POST, &path)
147                .body(body)?
148                .mutation(crate::client::MutationAdmission::Ordinary(account_id)),
149        )
150        .await
151    }
152}
153
154/// Query parameters for `list_orders`.
155#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
156#[serde(rename_all = "camelCase")]
157pub struct ListOrdersQuery {
158    /// List of Order IDs to retrieve
159    #[serde(rename = "ids", default, skip_serializing_if = "Option::is_none")]
160    pub ids: Option<Vec<OrderID>>,
161    /// The state to filter the requested Orders by \[default=PENDING\]
162    #[serde(rename = "state", default, skip_serializing_if = "Option::is_none")]
163    pub state: Option<OrderStateFilter>,
164    /// The instrument to filter the requested orders by
165    #[serde(
166        rename = "instrument",
167        default,
168        skip_serializing_if = "Option::is_none"
169    )]
170    pub instrument: Option<InstrumentName>,
171    /// The maximum number of Orders to return \[default=50, maximum=500\]
172    #[serde(rename = "count", default, skip_serializing_if = "Option::is_none")]
173    pub count: Option<i64>,
174    /// The maximum Order ID to return. If not provided the most recent Orders in the Account are returned
175    #[serde(rename = "beforeID", default, skip_serializing_if = "Option::is_none")]
176    pub before_id: Option<OrderID>,
177}
178
179impl Validate for ListOrdersQuery {
180    fn validate(&self) -> Result<()> {
181        if let Some(ids) = &self.ids {
182            crate::validation::nonempty(ids, "ids")?;
183        }
184        crate::validation::count(self.count, 500)
185    }
186}
187
188/// Successful response for `list_orders`.
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
190#[serde(rename_all = "camelCase")]
191pub struct ListOrdersResponse {
192    /// The list of Order detail objects
193    #[serde(rename = "orders", default, skip_serializing_if = "Option::is_none")]
194    pub orders: Option<Vec<Order>>,
195    /// The ID of the most recent Transaction created for the Account
196    #[serde(
197        rename = "lastTransactionID",
198        default,
199        skip_serializing_if = "Option::is_none"
200    )]
201    pub last_transaction_id: Option<TransactionID>,
202}
203
204impl Client {
205    /// List orders.
206    ///
207    /// # Errors
208    ///
209    /// Returns [`crate::OperationError::Client`] for invalid input, admission, transport, or
210    /// malformed response failures. Provider refusals return [`crate::OperationError::Rejected`]
211    /// or [`crate::OperationError::RejectedUnreadable`] when the rejection body cannot be read.
212    pub async fn list_orders(
213        &self,
214        account_id: &AccountID,
215        query: Option<&ListOrdersQuery>,
216    ) -> std::result::Result<
217        crate::ApiResponse<ListOrdersResponse>,
218        crate::OperationError<crate::GenericRejection>,
219    > {
220        let account_id_encoded = crate::client::segment(account_id.as_str());
221        let path = format!("/v3/accounts/{account_id_encoded}/orders");
222        let request = RequestParts::new(Method::GET, &path);
223        let request = match query {
224            Some(query) => request.query(query)?,
225            None => request,
226        };
227        self.execute(request).await
228    }
229}
230
231/// Successful response for `list_pending_orders`.
232#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
233#[serde(rename_all = "camelCase")]
234pub struct ListPendingOrdersResponse {
235    /// The list of pending Order details
236    #[serde(rename = "orders", default, skip_serializing_if = "Option::is_none")]
237    pub orders: Option<Vec<Order>>,
238    /// The ID of the most recent Transaction created for the Account
239    #[serde(
240        rename = "lastTransactionID",
241        default,
242        skip_serializing_if = "Option::is_none"
243    )]
244    pub last_transaction_id: Option<TransactionID>,
245}
246
247impl Client {
248    /// List pending orders.
249    ///
250    /// # Errors
251    ///
252    /// Returns [`crate::OperationError::Client`] for invalid input, admission, transport, or
253    /// malformed response failures. Provider refusals return [`crate::OperationError::Rejected`]
254    /// or [`crate::OperationError::RejectedUnreadable`] when the rejection body cannot be read.
255    pub async fn list_pending_orders(
256        &self,
257        account_id: &AccountID,
258    ) -> std::result::Result<
259        crate::ApiResponse<ListPendingOrdersResponse>,
260        crate::OperationError<crate::GenericRejection>,
261    > {
262        let account_id_encoded = crate::client::segment(account_id.as_str());
263        let path = format!("/v3/accounts/{account_id_encoded}/pendingOrders");
264        self.execute(RequestParts::new(Method::GET, &path)).await
265    }
266}
267
268/// Successful response for `order_details`.
269#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
270#[serde(rename_all = "camelCase")]
271pub struct OrderDetailsResponse {
272    /// The details of the Order requested
273    #[serde(rename = "order", default, skip_serializing_if = "Option::is_none")]
274    pub order: Option<Order>,
275    /// The ID of the most recent Transaction created for the Account
276    #[serde(
277        rename = "lastTransactionID",
278        default,
279        skip_serializing_if = "Option::is_none"
280    )]
281    pub last_transaction_id: Option<TransactionID>,
282}
283
284impl Client {
285    /// Order details.
286    ///
287    /// # Errors
288    ///
289    /// Returns [`crate::OperationError::Client`] for invalid input, admission, transport, or
290    /// malformed response failures. Provider refusals return [`crate::OperationError::Rejected`]
291    /// or [`crate::OperationError::RejectedUnreadable`] when the rejection body cannot be read.
292    pub async fn order_details(
293        &self,
294        account_id: &AccountID,
295        order_specifier: &OrderSpecifier,
296    ) -> std::result::Result<
297        crate::ApiResponse<OrderDetailsResponse>,
298        crate::OperationError<crate::GenericRejection>,
299    > {
300        let account_id_encoded = crate::client::segment(account_id.as_str());
301        let order_specifier_encoded = crate::client::segment(order_specifier.as_str());
302        let path = format!("/v3/accounts/{account_id_encoded}/orders/{order_specifier_encoded}");
303        self.execute(RequestParts::new(Method::GET, &path)).await
304    }
305}
306
307/// Request body for `replace_order`.
308#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
309#[serde(rename_all = "camelCase")]
310pub struct ReplaceOrderBody {
311    /// Specification of the replacing Order
312    #[serde(rename = "order", default, skip_serializing_if = "Option::is_none")]
313    pub order: Option<OrderRequest>,
314}
315
316impl Validate for ReplaceOrderBody {
317    fn validate(&self) -> Result<()> {
318        self.order
319            .as_ref()
320            .ok_or_else(|| Error::InvalidInput("order request is required".into()))?
321            .validate()
322    }
323}
324
325/// Successful response for `replace_order`.
326#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
327#[serde(rename_all = "camelCase")]
328pub struct ReplaceOrderResponse {
329    /// The Transaction that cancelled the Order to be replaced.
330    #[serde(
331        rename = "orderCancelTransaction",
332        default,
333        skip_serializing_if = "Option::is_none"
334    )]
335    pub order_cancel_transaction: Option<OrderCancelTransaction>,
336    /// The Transaction that created the replacing Order as requested.
337    #[serde(
338        rename = "orderCreateTransaction",
339        default,
340        skip_serializing_if = "Option::is_none"
341    )]
342    pub order_create_transaction: Option<Transaction>,
343    /// The Transaction that filled the replacing Order. This is only provided when the replacing Order was
344    /// immediately filled.
345    #[serde(
346        rename = "orderFillTransaction",
347        default,
348        skip_serializing_if = "Option::is_none"
349    )]
350    pub order_fill_transaction: Option<OrderFillTransaction>,
351    /// The Transaction that reissues the replacing Order. Only provided when the replacing Order was partially
352    /// filled immediately and is configured to be reissued for its remaining units.
353    #[serde(
354        rename = "orderReissueTransaction",
355        default,
356        skip_serializing_if = "Option::is_none"
357    )]
358    pub order_reissue_transaction: Option<Transaction>,
359    /// The Transaction that rejects the reissue of the Order. Only provided when the replacing Order was
360    /// partially filled immediately and was configured to be reissued, however the reissue was rejected.
361    #[serde(
362        rename = "orderReissueRejectTransaction",
363        default,
364        skip_serializing_if = "Option::is_none"
365    )]
366    pub order_reissue_reject_transaction: Option<Transaction>,
367    /// The Transaction that cancelled the replacing Order. Only provided when the replacing Order was
368    /// immediately cancelled.
369    #[serde(
370        rename = "replacingOrderCancelTransaction",
371        default,
372        skip_serializing_if = "Option::is_none"
373    )]
374    pub replacing_order_cancel_transaction: Option<OrderCancelTransaction>,
375    /// The IDs of all Transactions that were created while satisfying the request.
376    #[serde(
377        rename = "relatedTransactionIDs",
378        default,
379        skip_serializing_if = "Option::is_none"
380    )]
381    pub related_transaction_ids: Option<Vec<TransactionID>>,
382    /// The ID of the most recent Transaction created for the Account
383    #[serde(
384        rename = "lastTransactionID",
385        default,
386        skip_serializing_if = "Option::is_none"
387    )]
388    pub last_transaction_id: Option<TransactionID>,
389}
390
391/// Documented rejection fields for `replace_order`.
392#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
393#[serde(rename_all = "camelCase")]
394pub struct ReplaceOrderRejection {
395    /// The Transaction that rejected the creation of the replacing Order
396    #[serde(
397        rename = "orderRejectTransaction",
398        default,
399        skip_serializing_if = "Option::is_none"
400    )]
401    pub order_reject_transaction: Option<Transaction>,
402    /// The IDs of all Transactions that were created while satisfying the request.
403    #[serde(
404        rename = "relatedTransactionIDs",
405        default,
406        skip_serializing_if = "Option::is_none"
407    )]
408    pub related_transaction_ids: Option<Vec<TransactionID>>,
409    /// The ID of the most recent Transaction created for the Account.
410    #[serde(
411        rename = "lastTransactionID",
412        default,
413        skip_serializing_if = "Option::is_none"
414    )]
415    pub last_transaction_id: Option<TransactionID>,
416    /// The code of the error that has occurred. This field may not be returned for some errors.
417    #[serde(rename = "errorCode", default, skip_serializing_if = "Option::is_none")]
418    pub error_code: Option<String>,
419    /// The human-readable description of the error that has occurred.
420    #[serde(rename = "errorMessage")]
421    pub error_message: String,
422    /// The Transaction that rejected the cancellation of the Order to be replaced. Only present if the Account
423    /// exists.
424    #[serde(
425        rename = "orderCancelRejectTransaction",
426        default,
427        skip_serializing_if = "Option::is_none"
428    )]
429    pub order_cancel_reject_transaction: Option<Transaction>,
430}
431
432impl Client {
433    /// Replace order.
434    ///
435    /// # Errors
436    ///
437    /// Returns [`crate::OperationError::Client`] for invalid input, admission, transport, or
438    /// malformed response failures. Provider refusals return [`crate::OperationError::Rejected`]
439    /// or [`crate::OperationError::RejectedUnreadable`] when the rejection body cannot be read.
440    /// An uncertain sent mutation fences this account until caller-acknowledged reconciliation.
441    pub async fn replace_order(
442        &self,
443        account_id: &AccountID,
444        order_specifier: &OrderSpecifier,
445        body: &ReplaceOrderBody,
446        client_request_id: Option<&ClientRequestID>,
447    ) -> std::result::Result<
448        crate::ApiResponse<ReplaceOrderResponse>,
449        crate::OperationError<ReplaceOrderRejection>,
450    > {
451        let account_id_encoded = crate::client::segment(account_id.as_str());
452        let order_specifier_encoded = crate::client::segment(order_specifier.as_str());
453        let path = format!("/v3/accounts/{account_id_encoded}/orders/{order_specifier_encoded}");
454        self.execute(
455            RequestParts::new(Method::PUT, &path)
456                .body(body)?
457                .mutation(crate::client::MutationAdmission::Ordinary(account_id))
458                .client_request_id(client_request_id),
459        )
460        .await
461    }
462}
463
464/// Successful response for `cancel_order`.
465#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
466#[serde(rename_all = "camelCase")]
467pub struct CancelOrderResponse {
468    /// The Transaction that cancelled the Order
469    #[serde(
470        rename = "orderCancelTransaction",
471        default,
472        skip_serializing_if = "Option::is_none"
473    )]
474    pub order_cancel_transaction: Option<OrderCancelTransaction>,
475    /// The IDs of all Transactions that were created while satisfying the request.
476    #[serde(
477        rename = "relatedTransactionIDs",
478        default,
479        skip_serializing_if = "Option::is_none"
480    )]
481    pub related_transaction_ids: Option<Vec<TransactionID>>,
482    /// The ID of the most recent Transaction created for the Account
483    #[serde(
484        rename = "lastTransactionID",
485        default,
486        skip_serializing_if = "Option::is_none"
487    )]
488    pub last_transaction_id: Option<TransactionID>,
489}
490
491/// Documented rejection fields for `cancel_order`.
492#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
493#[serde(rename_all = "camelCase")]
494pub struct CancelOrderRejection {
495    /// The Transaction that rejected the cancellation of the Order. Only present if the Account exists.
496    #[serde(
497        rename = "orderCancelRejectTransaction",
498        default,
499        skip_serializing_if = "Option::is_none"
500    )]
501    pub order_cancel_reject_transaction: Option<OrderCancelRejectTransaction>,
502    /// The IDs of all Transactions that were created while satisfying the request. Only present if the Account
503    /// exists.
504    #[serde(
505        rename = "relatedTransactionIDs",
506        default,
507        skip_serializing_if = "Option::is_none"
508    )]
509    pub related_transaction_ids: Option<Vec<TransactionID>>,
510    /// The ID of the most recent Transaction created for the Account. Only present if the Account exists.
511    #[serde(
512        rename = "lastTransactionID",
513        default,
514        skip_serializing_if = "Option::is_none"
515    )]
516    pub last_transaction_id: Option<TransactionID>,
517    /// The code of the error that has occurred. This field may not be returned for some errors.
518    #[serde(rename = "errorCode", default, skip_serializing_if = "Option::is_none")]
519    pub error_code: Option<String>,
520    /// The human-readable description of the error that has occurred.
521    #[serde(rename = "errorMessage")]
522    pub error_message: String,
523}
524
525impl Client {
526    /// Cancel order.
527    ///
528    /// # Errors
529    ///
530    /// Returns [`crate::OperationError::Client`] for invalid input, admission, transport, or
531    /// malformed response failures. Provider refusals return [`crate::OperationError::Rejected`]
532    /// or [`crate::OperationError::RejectedUnreadable`] when the rejection body cannot be read.
533    /// An uncertain sent mutation fences this account until caller-acknowledged reconciliation.
534    pub async fn cancel_order(
535        &self,
536        account_id: &AccountID,
537        order_specifier: &OrderSpecifier,
538        client_request_id: Option<&ClientRequestID>,
539    ) -> std::result::Result<
540        crate::ApiResponse<CancelOrderResponse>,
541        crate::OperationError<CancelOrderRejection>,
542    > {
543        let account_id_encoded = crate::client::segment(account_id.as_str());
544        let order_specifier_encoded = crate::client::segment(order_specifier.as_str());
545        let path =
546            format!("/v3/accounts/{account_id_encoded}/orders/{order_specifier_encoded}/cancel");
547        self.execute(
548            RequestParts::new(Method::PUT, &path)
549                .mutation(crate::client::MutationAdmission::Exit(account_id))
550                .client_request_id(client_request_id),
551        )
552        .await
553    }
554}
555
556/// Request body for `update_order_client_extensions`.
557#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
558#[serde(rename_all = "camelCase")]
559pub struct UpdateOrderClientExtensionsBody {
560    /// The Client Extensions to update for the Order. Do not set, modify, or delete clientExtensions if your
561    /// account is associated with MT4.
562    #[serde(
563        rename = "clientExtensions",
564        default,
565        skip_serializing_if = "Option::is_none"
566    )]
567    pub client_extensions: Option<ClientExtensions>,
568    /// The Client Extensions to update for the Trade created when the Order is filled. Do not set, modify, or
569    /// delete clientExtensions if your account is associated with MT4.
570    #[serde(
571        rename = "tradeClientExtensions",
572        default,
573        skip_serializing_if = "Option::is_none"
574    )]
575    pub trade_client_extensions: Option<ClientExtensions>,
576}
577
578impl Validate for UpdateOrderClientExtensionsBody {
579    fn validate(&self) -> Result<()> {
580        if self.client_extensions.is_none() && self.trade_client_extensions.is_none() {
581            return Err(Error::InvalidInput(
582                "mutation body must not be empty".into(),
583            ));
584        }
585        Ok(())
586    }
587}
588
589/// Successful response for `update_order_client_extensions`.
590#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
591#[serde(rename_all = "camelCase")]
592pub struct UpdateOrderClientExtensionsResponse {
593    /// The Transaction that modified the Client Extensions for the Order
594    #[serde(
595        rename = "orderClientExtensionsModifyTransaction",
596        default,
597        skip_serializing_if = "Option::is_none"
598    )]
599    pub order_client_extensions_modify_transaction: Option<OrderClientExtensionsModifyTransaction>,
600    /// The ID of the most recent Transaction created for the Account
601    #[serde(
602        rename = "lastTransactionID",
603        default,
604        skip_serializing_if = "Option::is_none"
605    )]
606    pub last_transaction_id: Option<TransactionID>,
607    /// The IDs of all Transactions that were created while satisfying the request.
608    #[serde(
609        rename = "relatedTransactionIDs",
610        default,
611        skip_serializing_if = "Option::is_none"
612    )]
613    pub related_transaction_ids: Option<Vec<TransactionID>>,
614}
615
616/// Documented rejection fields for `update_order_client_extensions`.
617#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
618#[serde(rename_all = "camelCase")]
619pub struct UpdateOrderClientExtensionsRejection {
620    /// The Transaction that rejected the modification of the Client Extensions for the Order
621    #[serde(
622        rename = "orderClientExtensionsModifyRejectTransaction",
623        default,
624        skip_serializing_if = "Option::is_none"
625    )]
626    pub order_client_extensions_modify_reject_transaction:
627        Option<OrderClientExtensionsModifyRejectTransaction>,
628    /// The ID of the most recent Transaction created for the Account
629    #[serde(
630        rename = "lastTransactionID",
631        default,
632        skip_serializing_if = "Option::is_none"
633    )]
634    pub last_transaction_id: Option<TransactionID>,
635    /// The IDs of all Transactions that were created while satisfying the request.
636    #[serde(
637        rename = "relatedTransactionIDs",
638        default,
639        skip_serializing_if = "Option::is_none"
640    )]
641    pub related_transaction_ids: Option<Vec<TransactionID>>,
642    /// The code of the error that has occurred. This field may not be returned for some errors.
643    #[serde(rename = "errorCode", default, skip_serializing_if = "Option::is_none")]
644    pub error_code: Option<String>,
645    /// The human-readable description of the error that has occurred.
646    #[serde(rename = "errorMessage")]
647    pub error_message: String,
648}
649
650impl Client {
651    /// Update order client extensions.
652    ///
653    /// # Errors
654    ///
655    /// Returns [`crate::OperationError::Client`] for invalid input, admission, transport, or
656    /// malformed response failures. Provider refusals return [`crate::OperationError::Rejected`]
657    /// or [`crate::OperationError::RejectedUnreadable`] when the rejection body cannot be read.
658    /// An uncertain sent mutation fences this account until caller-acknowledged reconciliation.
659    pub async fn update_order_client_extensions(
660        &self,
661        account_id: &AccountID,
662        order_specifier: &OrderSpecifier,
663        body: &UpdateOrderClientExtensionsBody,
664    ) -> std::result::Result<
665        crate::ApiResponse<UpdateOrderClientExtensionsResponse>,
666        crate::OperationError<UpdateOrderClientExtensionsRejection>,
667    > {
668        let account_id_encoded = crate::client::segment(account_id.as_str());
669        let order_specifier_encoded = crate::client::segment(order_specifier.as_str());
670        let path = format!(
671            "/v3/accounts/{account_id_encoded}/orders/{order_specifier_encoded}/clientExtensions"
672        );
673        self.execute(
674            RequestParts::new(Method::PUT, &path)
675                .body(body)?
676                .mutation(crate::client::MutationAdmission::Ordinary(account_id)),
677        )
678        .await
679    }
680}