mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
feat: Convert QrData into Qr data image source url (#1674)
This commit is contained in:
committed by
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