tap_msg/message/
authorize.rs

1//! Authorize message type for the Transaction Authorization Protocol.
2//!
3//! This module defines the Authorize message type, which is used
4//! for authorizing transactions in the TAP protocol.
5
6use serde::{Deserialize, Serialize};
7
8use crate::error::{Error, Result};
9use crate::TapMessage;
10
11/// Authorize message body (TAIP-4).
12#[derive(Debug, Clone, Serialize, Deserialize, TapMessage)]
13#[tap(message_type = "https://tap.rsvp/schema/1.0#Authorize")]
14pub struct Authorize {
15    /// ID of the transaction being authorized.
16    #[tap(thread_id)]
17    pub transaction_id: String,
18
19    /// Optional settlement address in CAIP-10 format.
20    /// Required when sent by a VASP representing the beneficiary unless the original
21    /// request contains an agent with the settlementAddress role.
22    #[serde(rename = "settlementAddress", skip_serializing_if = "Option::is_none")]
23    pub settlement_address: Option<String>,
24
25    /// Optional expiry timestamp in ISO 8601 format.
26    /// After this time, if settlement has not occurred, the authorization should be
27    /// considered invalid and settlement should not proceed.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub expiry: Option<String>,
30}
31
32impl Authorize {
33    /// Create a new Authorize message
34    pub fn new(transaction_id: &str) -> Self {
35        Self {
36            transaction_id: transaction_id.to_string(),
37            settlement_address: None,
38            expiry: None,
39        }
40    }
41
42    /// Create a new Authorize message with a settlement address
43    pub fn with_settlement_address(transaction_id: &str, settlement_address: &str) -> Self {
44        Self {
45            transaction_id: transaction_id.to_string(),
46            settlement_address: Some(settlement_address.to_string()),
47            expiry: None,
48        }
49    }
50
51    /// Create a new Authorize message with all optional fields
52    pub fn with_all(
53        transaction_id: &str,
54        settlement_address: Option<&str>,
55        expiry: Option<&str>,
56    ) -> Self {
57        Self {
58            transaction_id: transaction_id.to_string(),
59            settlement_address: settlement_address.map(|s| s.to_string()),
60            expiry: expiry.map(|s| s.to_string()),
61        }
62    }
63}
64
65impl Authorize {
66    /// Custom validation for Authorize messages
67    pub fn validate_authorize(&self) -> Result<()> {
68        if self.transaction_id.is_empty() {
69            return Err(Error::Validation(
70                "Transaction ID is required in Authorize".to_string(),
71            ));
72        }
73
74        Ok(())
75    }
76}