mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 17:47:54 +08:00
feat(api_models): add api_models for external 3ds authentication flow (#3858)
Co-authored-by: hrithikesh026 <hrithikesh.vm@juspay.in> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
03cfb735af
commit
0a43ceb14e
@ -96,6 +96,15 @@ pub struct MerchantAccountCreate {
|
||||
pub organization_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, ToSchema)]
|
||||
pub struct AuthenticationConnectorDetails {
|
||||
/// List of authentication connectors
|
||||
#[schema(value_type = Vec<AuthenticationConnectors>)]
|
||||
pub authentication_connectors: Vec<enums::AuthenticationConnectors>,
|
||||
/// URL of the (customer service) website that will be shown to the shopper in case of technical errors during the 3D Secure 2 process.
|
||||
pub three_ds_requestor_url: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, ToSchema)]
|
||||
pub struct MerchantAccountMetadata {
|
||||
pub compatible_connector: Option<api_enums::Connector>,
|
||||
@ -897,6 +906,9 @@ pub struct BusinessProfileCreate {
|
||||
|
||||
/// Default Payment Link config for all payment links created under this business profile
|
||||
pub payment_link_config: Option<BusinessPaymentLinkConfig>,
|
||||
|
||||
/// External 3DS authentication details
|
||||
pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, ToSchema, Serialize)]
|
||||
@ -963,6 +975,9 @@ pub struct BusinessProfileResponse {
|
||||
|
||||
/// Default Payment Link config for all payment links created under this business profile
|
||||
pub payment_link_config: Option<serde_json::Value>,
|
||||
|
||||
/// External 3DS authentication details
|
||||
pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, ToSchema, Serialize)]
|
||||
@ -1021,6 +1036,9 @@ pub struct BusinessProfileUpdate {
|
||||
|
||||
/// Default Payment Link config for all payment links created under this business profile
|
||||
pub payment_link_config: Option<BusinessPaymentLinkConfig>,
|
||||
|
||||
/// External 3DS authentication details
|
||||
pub authentication_connector_details: Option<AuthenticationConnectorDetails>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)]
|
||||
|
||||
@ -150,6 +150,25 @@ impl Connector {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
Hash,
|
||||
PartialEq,
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum AuthenticationConnectors {
|
||||
Threedsecureio,
|
||||
}
|
||||
|
||||
#[cfg(feature = "payouts")]
|
||||
#[derive(
|
||||
Clone,
|
||||
@ -552,3 +571,7 @@ pub enum PmAuthConnectors {
|
||||
pub fn convert_pm_auth_connector(connector_name: &str) -> Option<PmAuthConnectors> {
|
||||
PmAuthConnectors::from_str(connector_name).ok()
|
||||
}
|
||||
|
||||
pub fn convert_authentication_connector(connector_name: &str) -> Option<AuthenticationConnectors> {
|
||||
AuthenticationConnectors::from_str(connector_name).ok()
|
||||
}
|
||||
|
||||
@ -9,9 +9,10 @@ use crate::{
|
||||
payments::{
|
||||
PaymentIdType, PaymentListConstraints, PaymentListFilterConstraints, PaymentListFilters,
|
||||
PaymentListResponse, PaymentListResponseV2, PaymentsApproveRequest, PaymentsCancelRequest,
|
||||
PaymentsCaptureRequest, PaymentsIncrementalAuthorizationRequest, PaymentsRejectRequest,
|
||||
PaymentsRequest, PaymentsResponse, PaymentsRetrieveRequest, PaymentsStartRequest,
|
||||
RedirectionResponse,
|
||||
PaymentsCaptureRequest, PaymentsExternalAuthenticationRequest,
|
||||
PaymentsExternalAuthenticationResponse, PaymentsIncrementalAuthorizationRequest,
|
||||
PaymentsRejectRequest, PaymentsRequest, PaymentsResponse, PaymentsRetrieveRequest,
|
||||
PaymentsStartRequest, RedirectionResponse,
|
||||
},
|
||||
};
|
||||
impl ApiEventMetric for PaymentsRetrieveRequest {
|
||||
@ -181,3 +182,13 @@ impl ApiEventMetric for PaymentsIncrementalAuthorizationRequest {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsExternalAuthenticationResponse {}
|
||||
|
||||
impl ApiEventMetric for PaymentsExternalAuthenticationRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payment {
|
||||
payment_id: self.payment_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use std::{fmt, num::NonZeroI64};
|
||||
use std::{collections::HashMap, fmt, num::NonZeroI64};
|
||||
|
||||
use cards::CardNumber;
|
||||
use common_utils::{
|
||||
@ -448,6 +448,10 @@ pub struct PaymentsRequest {
|
||||
|
||||
/// additional data related to some frm connectors
|
||||
pub frm_metadata: Option<serde_json::Value>,
|
||||
|
||||
/// Whether to perform external authentication (if applicable)
|
||||
#[schema(example = true)]
|
||||
pub request_external_three_ds_authentication: Option<bool>,
|
||||
}
|
||||
|
||||
impl PaymentsRequest {
|
||||
@ -2142,6 +2146,32 @@ pub enum NextActionData {
|
||||
display_from_timestamp: i128,
|
||||
display_to_timestamp: Option<i128>,
|
||||
},
|
||||
/// Contains the information regarding three_ds_method_data submission, three_ds authentication, and authorization flows
|
||||
ThreeDsInvoke { three_ds_data: ThreeDsData },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, ToSchema)]
|
||||
pub struct ThreeDsData {
|
||||
/// ThreeDS authentication url - to initiate authentication
|
||||
pub three_ds_authentication_url: String,
|
||||
/// ThreeDS authorize url - to complete the payment authorization after authentication
|
||||
pub three_ds_authorize_url: String,
|
||||
/// ThreeDS method details
|
||||
pub three_ds_method_details: ThreeDsMethodData,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, ToSchema)]
|
||||
#[serde(tag = "three_ds_method_key")]
|
||||
pub enum ThreeDsMethodData {
|
||||
#[serde(rename = "threeDSMethodData")]
|
||||
AcsThreeDsMethodData {
|
||||
/// Whether ThreeDS method data submission is required
|
||||
three_ds_method_data_submission: bool,
|
||||
/// ThreeDS method data
|
||||
three_ds_method_data: String,
|
||||
/// ThreeDS method url
|
||||
three_ds_method_url: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
@ -2535,6 +2565,12 @@ pub struct PaymentsResponse {
|
||||
/// List of incremental authorizations happened to the payment
|
||||
pub incremental_authorizations: Option<Vec<IncrementalAuthorizationResponse>>,
|
||||
|
||||
/// Details of external authentication
|
||||
pub external_authentication_details: Option<ExternalAuthenticationDetailsResponse>,
|
||||
|
||||
/// Flag indicating if external 3ds authentication is made or not
|
||||
pub request_external_3ds_authentication: Option<bool>,
|
||||
|
||||
/// Date Time expiry of the payment
|
||||
#[schema(example = "2022-09-10T10:11:12Z")]
|
||||
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
|
||||
@ -2544,6 +2580,26 @@ pub struct PaymentsResponse {
|
||||
pub fingerprint: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Setter, Clone, Default, Debug, PartialEq, serde::Serialize, ToSchema)]
|
||||
pub struct ExternalAuthenticationDetailsResponse {
|
||||
/// Authentication Type - Challenge / Frictionless
|
||||
#[schema(value_type = Option<DecoupledAuthenticationType>)]
|
||||
pub authentication_flow: Option<enums::DecoupledAuthenticationType>,
|
||||
/// Electronic Commerce Indicator (eci)
|
||||
pub electronic_commerce_indicator: Option<String>,
|
||||
/// Authentication Status
|
||||
#[schema(value_type = AuthenticationStatus)]
|
||||
pub status: enums::AuthenticationStatus,
|
||||
/// DS Transaction ID
|
||||
pub ds_transaction_id: Option<String>,
|
||||
/// Message Version
|
||||
pub version: Option<String>,
|
||||
/// Error Code
|
||||
pub error_code: Option<String>,
|
||||
/// Error Message
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, ToSchema, serde::Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct PaymentListConstraints {
|
||||
@ -3381,6 +3437,107 @@ pub struct PaymentsIncrementalAuthorizationRequest {
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, ToSchema)]
|
||||
pub struct PaymentsExternalAuthenticationRequest {
|
||||
/// The identifier for the payment
|
||||
#[serde(skip)]
|
||||
pub payment_id: String,
|
||||
/// Client Secret
|
||||
#[schema(value_type = String)]
|
||||
pub client_secret: Secret<String>,
|
||||
/// SDK Information if request is from SDK
|
||||
pub sdk_information: Option<SdkInformation>,
|
||||
/// Device Channel indicating whether request is coming from App or Browser
|
||||
pub device_channel: DeviceChannel,
|
||||
/// Indicates if 3DS method data was successfully completed or not
|
||||
pub threeds_method_comp_ind: ThreeDsCompletionIndicator,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, ToSchema)]
|
||||
pub enum ThreeDsCompletionIndicator {
|
||||
/// 3DS method successfully completed
|
||||
#[serde(rename = "Y")]
|
||||
Success,
|
||||
/// 3DS method was not successful
|
||||
#[serde(rename = "N")]
|
||||
Failure,
|
||||
/// 3DS method URL was unavailable
|
||||
#[serde(rename = "U")]
|
||||
NotAvailable,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, ToSchema, Eq, PartialEq)]
|
||||
pub enum DeviceChannel {
|
||||
#[serde(rename = "APP")]
|
||||
App,
|
||||
#[serde(rename = "BRW")]
|
||||
Browser,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, serde::Serialize, serde::Deserialize, Clone, ToSchema)]
|
||||
pub struct SdkInformation {
|
||||
/// Unique ID created on installations of the 3DS Requestor App on a Consumer Device
|
||||
pub sdk_app_id: String,
|
||||
/// JWE Object containing data encrypted by the SDK for the DS to decrypt
|
||||
pub sdk_enc_data: String,
|
||||
/// Public key component of the ephemeral key pair generated by the 3DS SDK
|
||||
pub sdk_ephem_pub_key: HashMap<String, String>,
|
||||
/// Unique transaction identifier assigned by the 3DS SDK
|
||||
pub sdk_trans_id: String,
|
||||
/// Identifies the vendor and version for the 3DS SDK that is integrated in a 3DS Requestor App
|
||||
pub sdk_reference_number: String,
|
||||
/// Indicates maximum amount of time in minutes
|
||||
pub sdk_max_timeout: u8,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq, ToSchema)]
|
||||
pub enum TransactionStatus {
|
||||
/// Authentication/ Account Verification Successful
|
||||
#[serde(rename = "Y")]
|
||||
Success,
|
||||
/// Not Authenticated /Account Not Verified; Transaction denied
|
||||
#[default]
|
||||
#[serde(rename = "N")]
|
||||
Failure,
|
||||
/// Authentication/ Account Verification Could Not Be Performed; Technical or other problem, as indicated in Authentication Response(ARes) or Result Request (RReq)
|
||||
#[serde(rename = "U")]
|
||||
VerificationNotPerformed,
|
||||
/// Attempts Processing Performed; Not Authenticated/Verified , but a proof of attempted authentication/verification is provided
|
||||
#[serde(rename = "A")]
|
||||
NotVerified,
|
||||
/// Authentication/ Account Verification Rejected; Issuer is rejecting authentication/verification and request that authorisation not be attempted.
|
||||
#[serde(rename = "R")]
|
||||
Rejected,
|
||||
/// Challenge Required; Additional authentication is required using the Challenge Request (CReq) / Challenge Response (CRes)
|
||||
#[serde(rename = "C")]
|
||||
ChallengeRequired,
|
||||
/// Challenge Required; Decoupled Authentication confirmed.
|
||||
#[serde(rename = "D")]
|
||||
ChallengeRequiredDecoupledAuthentication,
|
||||
/// Informational Only; 3DS Requestor challenge preference acknowledged.
|
||||
#[serde(rename = "I")]
|
||||
InformationOnly,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, ToSchema)]
|
||||
pub struct PaymentsExternalAuthenticationResponse {
|
||||
/// Indicates the trans status
|
||||
#[serde(rename = "trans_status")]
|
||||
pub transaction_status: TransactionStatus,
|
||||
/// Access Server URL to be used for challenge submission
|
||||
pub acs_url: Option<String>,
|
||||
/// Challenge request which should be sent to acs_url
|
||||
pub challenge_request: Option<String>,
|
||||
/// Unique identifier assigned by the EMVCo
|
||||
pub acs_reference_number: Option<String>,
|
||||
/// Unique identifier assigned by the ACS to identify a single transaction
|
||||
pub acs_trans_id: Option<String>,
|
||||
/// Unique identifier assigned by the 3DS Server to identify a single transaction
|
||||
pub three_dsserver_trans_id: Option<String>,
|
||||
/// Contains the JWS object created by the ACS for the ARes message
|
||||
pub acs_signed_content: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
|
||||
pub struct PaymentsApproveRequest {
|
||||
/// The identifier for the payment
|
||||
|
||||
Reference in New Issue
Block a user