mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 01:57:45 +08:00 
			
		
		
		
	feat: Convert QrData into Qr data image source url (#1674)
This commit is contained in:
		 Sangamesh Kulkarni
					Sangamesh Kulkarni
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							ccd74613db
						
					
				
				
					commit
					55ff761e9e
				
			| @ -68,6 +68,14 @@ pub enum CryptoError { | |||||||
|     SignatureVerificationFailed, |     SignatureVerificationFailed, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Errors for Qr code handling | ||||||
|  | #[derive(Debug, thiserror::Error)] | ||||||
|  | pub enum QrCodeError { | ||||||
|  |     /// Failed to encode data into Qr code | ||||||
|  |     #[error("Failed to create Qr code")] | ||||||
|  |     FailedToCreateQrCode, | ||||||
|  | } | ||||||
|  |  | ||||||
| /// Allows [error_stack::Report] to change between error contexts | /// Allows [error_stack::Report] to change between error contexts | ||||||
| /// using the dependent [ErrorSwitch] trait to define relations & mappings between traits | /// using the dependent [ErrorSwitch] trait to define relations & mappings between traits | ||||||
| pub trait ReportSwitchExt<T, U> { | pub trait ReportSwitchExt<T, U> { | ||||||
|  | |||||||
| @ -54,6 +54,7 @@ frunk_core = "0.4.1" | |||||||
| futures = "0.3.28" | futures = "0.3.28" | ||||||
| hex = "0.4.3" | hex = "0.4.3" | ||||||
| http = "0.2.9" | http = "0.2.9" | ||||||
|  | image = "0.23.14" | ||||||
| infer = "0.13.0" | infer = "0.13.0" | ||||||
| josekit = "0.8.3" | josekit = "0.8.3" | ||||||
| jsonwebtoken = "8.3.0" | jsonwebtoken = "8.3.0" | ||||||
| @ -65,6 +66,7 @@ moka = { version = "0.11", features = ["future"] } | |||||||
| nanoid = "0.4.0" | nanoid = "0.4.0" | ||||||
| num_cpus = "1.15.0" | num_cpus = "1.15.0" | ||||||
| once_cell = "1.18.0" | once_cell = "1.18.0" | ||||||
|  | qrcode = "0.12.0" | ||||||
| rand = "0.8.5" | rand = "0.8.5" | ||||||
| regex = "1.8.4" | regex = "1.8.4" | ||||||
| reqwest = { version = "0.11.18", features = ["json", "native-tls", "gzip", "multipart"] } | reqwest = { version = "0.11.18", features = ["json", "native-tls", "gzip", "multipart"] } | ||||||
|  | |||||||
| @ -32,3 +32,7 @@ pub(crate) const PUB_SUB_CHANNEL: &str = "hyperswitch_invalidate"; | |||||||
| // Apple Pay validation url | // Apple Pay validation url | ||||||
| pub(crate) const APPLEPAY_VALIDATION_URL: &str = | pub(crate) const APPLEPAY_VALIDATION_URL: &str = | ||||||
|     "https://apple-pay-gateway-cert.apple.com/paymentservices/startSession"; |     "https://apple-pay-gateway-cert.apple.com/paymentservices/startSession"; | ||||||
|  |  | ||||||
|  | // Qr Image data source starts with this string | ||||||
|  | // The base64 image data will be appended to it to image data source | ||||||
|  | pub(crate) const QR_IMAGE_DATA_SOURCE_STRING: &str = "data:image/png;base64"; | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ pub mod ext_traits; | |||||||
| #[cfg(feature = "kv_store")] | #[cfg(feature = "kv_store")] | ||||||
| pub mod storage_partitioning; | pub mod storage_partitioning; | ||||||
|  |  | ||||||
|  | use base64::Engine; | ||||||
| pub use common_utils::{ | pub use common_utils::{ | ||||||
|     crypto, |     crypto, | ||||||
|     ext_traits::{ByteSliceExt, BytesExt, Encode, StringExt, ValueExt}, |     ext_traits::{ByteSliceExt, BytesExt, Encode, StringExt, ValueExt}, | ||||||
| @ -12,7 +13,9 @@ pub use common_utils::{ | |||||||
|     validation::validate_email, |     validation::validate_email, | ||||||
| }; | }; | ||||||
| use error_stack::{IntoReport, ResultExt}; | use error_stack::{IntoReport, ResultExt}; | ||||||
|  | use image::Luma; | ||||||
| use nanoid::nanoid; | use nanoid::nanoid; | ||||||
|  | use qrcode; | ||||||
| use serde::de::DeserializeOwned; | use serde::de::DeserializeOwned; | ||||||
|  |  | ||||||
| pub use self::ext_traits::{OptionExt, ValidateCall}; | pub use self::ext_traits::{OptionExt, ValidateCall}; | ||||||
| @ -155,3 +158,46 @@ pub fn to_currency_base_unit_asf64( | |||||||
| pub fn get_payment_attempt_id(payment_id: impl std::fmt::Display, attempt_count: i16) -> String { | pub fn get_payment_attempt_id(payment_id: impl std::fmt::Display, attempt_count: i16) -> String { | ||||||
|     format!("{payment_id}_{attempt_count}") |     format!("{payment_id}_{attempt_count}") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct QrImage { | ||||||
|  |     pub data: String, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl QrImage { | ||||||
|  |     pub fn new_from_data( | ||||||
|  |         data: String, | ||||||
|  |     ) -> Result<Self, error_stack::Report<common_utils::errors::QrCodeError>> { | ||||||
|  |         let qr_code = qrcode::QrCode::new(data.as_bytes()) | ||||||
|  |             .into_report() | ||||||
|  |             .change_context(common_utils::errors::QrCodeError::FailedToCreateQrCode)?; | ||||||
|  |  | ||||||
|  |         // Renders the QR code into an image. | ||||||
|  |         let qrcode_image_buffer = qr_code.render::<Luma<u8>>().build(); | ||||||
|  |         let qrcode_dynamic_image = image::DynamicImage::ImageLuma8(qrcode_image_buffer); | ||||||
|  |  | ||||||
|  |         let mut image_bytes = Vec::new(); | ||||||
|  |  | ||||||
|  |         // Encodes qrcode_dynamic_image and write it to image_bytes | ||||||
|  |         let _ = qrcode_dynamic_image.write_to(&mut image_bytes, image::ImageOutputFormat::Png); | ||||||
|  |  | ||||||
|  |         let image_data_source = format!( | ||||||
|  |             "{},{}", | ||||||
|  |             consts::QR_IMAGE_DATA_SOURCE_STRING, | ||||||
|  |             consts::BASE64_ENGINE.encode(image_bytes) | ||||||
|  |         ); | ||||||
|  |         Ok(Self { | ||||||
|  |             data: image_data_source, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use crate::utils; | ||||||
|  |     #[test] | ||||||
|  |     fn test_image_data_source_url() { | ||||||
|  |         let qr_image_data_source_url = utils::QrImage::new_from_data("Hyperswitch".to_string()); | ||||||
|  |         assert!(qr_image_data_source_url.is_ok()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user