commit 20d95dafe4abacee0dc9f1ec1400958de632ef88
parent 9db73672548899f1626c9c8ab854f4b0b26a02bc
Author: Antoine A <>
Date: Wed, 17 Jun 2026 11:58:58 +0200
common: support ch_qrr
Diffstat:
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/common/taler-common/src/types/payto.rs b/common/taler-common/src/types/payto.rs
@@ -263,6 +263,8 @@ pub struct ParsedQuery {
receiver_name: Option<CompactString>,
amount: Option<Amount>,
message: Option<CompactString>,
+ #[serde(rename = "ch-qrr")]
+ ch_qrr: Option<CompactString>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, DeserializeFromStr, SerializeDisplay)]
@@ -490,6 +492,7 @@ pub struct ParsedPayto<P> {
pub name: Option<CompactString>,
pub amount: Option<Amount>,
pub subject: Option<CompactString>,
+ pub ch_qrr: Option<CompactString>,
}
impl<P: PaytoImpl> ParsedPayto<P> {
@@ -498,15 +501,26 @@ impl<P: PaytoImpl> ParsedPayto<P> {
name: Option<&str>,
amount: Option<Amount>,
subject: Option<&str>,
+ ch_qrr: Option<&str>,
) -> Self {
Self {
inner,
name: name.map(CompactString::new),
amount,
subject: subject.map(CompactString::new),
+ ch_qrr: ch_qrr.map(CompactString::new),
}
}
+ pub fn as_uri(&self) -> PaytoURI {
+ self.inner
+ .as_uri()
+ .with_query([("receiver-name", &self.name)])
+ .with_query([("amount", self.amount)])
+ .with_query([("message", &self.subject)])
+ .with_query([("ch-qrr", &self.ch_qrr)])
+ }
+
pub fn into_inner(self) -> P {
self.inner
}
@@ -523,6 +537,7 @@ impl<P: PaytoImpl> TryFrom<&PaytoURI> for ParsedPayto<P> {
name: query.receiver_name,
amount: query.amount,
subject: query.message,
+ ch_qrr: query.ch_qrr,
})
}
}
@@ -557,7 +572,7 @@ mod test {
use crate::types::{
amount::amount,
iban::IBAN,
- payto::{FullPayto, Payto, TransferPayto},
+ payto::{FullPayto, ParsedPayto, Payto, TransferPayto},
};
#[test]
@@ -634,6 +649,44 @@ mod test {
);
assert_eq!(full_payto, transfer_payto.clone().into());
+ // Parsed simple payto
+ let transfer_payto = ParsedPayto::new(iban, None, None, None, None);
+ assert_eq!(
+ transfer_payto,
+ ParsedPayto::from_str(&format!("payto://iban/{iban}")).unwrap()
+ );
+ assert_eq!(
+ transfer_payto,
+ ParsedPayto::try_from(&transfer_payto.as_uri()).unwrap()
+ );
+ assert_eq!(
+ transfer_payto,
+ ParsedPayto::from_str(&transfer_payto.as_uri().to_string()).unwrap()
+ );
+
+ // Parsed full payto
+ let transfer_payto = ParsedPayto::new(
+ iban,
+ Some("John Smith"),
+ Some(amount("EUR:12")),
+ Some("Wire transfer subject"),
+ Some("REFERENCE"),
+ );
+ assert_eq!(
+ transfer_payto,
+ ParsedPayto::from_str(&format!("payto://iban/{iban}?receiver-name=John+Smith&amount=EUR:12&message=Wire+transfer+subject&ch-qrr=REFERENCE"))
+ .unwrap()
+ );
+ assert_eq!(
+ transfer_payto,
+ ParsedPayto::try_from(&transfer_payto.as_uri()).unwrap()
+ );
+ assert_eq!(
+ transfer_payto,
+ ParsedPayto::from_str(&transfer_payto.as_uri().to_string()).unwrap()
+ );
+
+ // Malformed
let malformed = FullPayto::<IBAN>::from_str(
"payto://iban/CH0400766000103138557?receiver-name=NYM%20Technologies%SA",
)