mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 11:24:45 +08:00
feat: support gpay and applepay session response for all connectors (#839)
Co-authored-by: Arun Raj M <jarnura47@gmail.com>
This commit is contained in:
committed by
GitHub
parent
465933ba72
commit
d23e14c57a
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -2767,7 +2767,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
dependencies = [
|
||||
"opentelemetry_api",
|
||||
"opentelemetry_sdk",
|
||||
@ -2776,7 +2776,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "opentelemetry-otlp"
|
||||
version = "0.11.0"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
@ -2793,7 +2793,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "opentelemetry-proto"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"futures-util",
|
||||
@ -2805,7 +2805,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "opentelemetry_api"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"futures-channel",
|
||||
@ -2820,7 +2820,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "opentelemetry_sdk"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"crossbeam-channel",
|
||||
|
||||
@ -668,16 +668,6 @@ pub enum RoutableConnectors {
|
||||
Worldpay,
|
||||
}
|
||||
|
||||
/// Wallets which support obtaining session object
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SupportedWallets {
|
||||
Paypal,
|
||||
ApplePay,
|
||||
Klarna,
|
||||
Gpay,
|
||||
}
|
||||
|
||||
/// Name of banks supported by Hyperswitch
|
||||
#[derive(
|
||||
Clone,
|
||||
|
||||
@ -1339,8 +1339,8 @@ pub struct PaymentsSessionRequest {
|
||||
/// This is a token which expires after 15 minutes, used from the client to authenticate and create sessions from the SDK
|
||||
pub client_secret: String,
|
||||
/// The list of the supported wallets
|
||||
#[schema(value_type = Vec<SupportedWallets>)]
|
||||
pub wallets: Vec<api_enums::SupportedWallets>,
|
||||
#[schema(value_type = Vec<PaymentMethodType>)]
|
||||
pub wallets: Vec<api_enums::PaymentMethodType>,
|
||||
/// Merchant connector details used to make payments.
|
||||
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
|
||||
}
|
||||
@ -1412,6 +1412,44 @@ pub struct GpaySessionTokenData {
|
||||
pub data: GpayMetaData,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplepaySessionRequest {
|
||||
pub merchant_identifier: String,
|
||||
pub display_name: String,
|
||||
pub initiative: String,
|
||||
pub initiative_context: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ApplepaySessionTokenData {
|
||||
#[serde(rename = "apple_pay")]
|
||||
pub data: ApplePayMetadata,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ApplePayMetadata {
|
||||
pub payment_request_data: PaymentRequestMetadata,
|
||||
pub session_token_data: SessionTokenInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct PaymentRequestMetadata {
|
||||
pub supported_networks: Vec<String>,
|
||||
pub merchant_capabilities: Vec<String>,
|
||||
pub label: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct SessionTokenInfo {
|
||||
pub certificate: String,
|
||||
pub certificate_keys: String,
|
||||
pub merchant_identifier: String,
|
||||
pub display_name: String,
|
||||
pub initiative: String,
|
||||
pub initiative_context: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, ToSchema)]
|
||||
#[serde(tag = "wallet_name")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@ -1435,6 +1473,7 @@ pub struct GpaySessionTokenResponse {
|
||||
pub allowed_payment_methods: Vec<GpayAllowedPaymentMethods>,
|
||||
/// The transaction info Google Pay requires
|
||||
pub transaction_info: GpayTransactionInfo,
|
||||
pub connector: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, ToSchema)]
|
||||
@ -1460,9 +1499,11 @@ pub struct ApplepaySessionTokenResponse {
|
||||
pub session_token_data: ApplePaySessionResponse,
|
||||
/// Payment request object for Apple Pay
|
||||
pub payment_request_data: ApplePayPaymentRequest,
|
||||
pub connector: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, ToSchema, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplePaySessionResponse {
|
||||
/// Timestamp at which session is requested
|
||||
pub epoch_timestamp: u64,
|
||||
@ -1501,6 +1542,7 @@ pub struct ApplePayPaymentRequest {
|
||||
pub merchant_capabilities: Vec<String>,
|
||||
/// The list of supported networks
|
||||
pub supported_networks: Vec<String>,
|
||||
pub merchant_identifier: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, ToSchema, serde::Deserialize)]
|
||||
@ -1514,6 +1556,13 @@ pub struct AmountInfo {
|
||||
pub amount: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplepayErrorResponse {
|
||||
pub status_code: String,
|
||||
pub status_message: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, serde::Serialize, Clone, ToSchema)]
|
||||
pub struct PaymentsSessionResponse {
|
||||
/// The identifier for the payment
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
pub mod aci;
|
||||
pub mod adyen;
|
||||
pub mod airwallex;
|
||||
pub mod applepay;
|
||||
pub mod authorizedotnet;
|
||||
pub mod bambora;
|
||||
pub mod bluesnap;
|
||||
@ -32,11 +31,11 @@ pub mod worldpay;
|
||||
pub mod mollie;
|
||||
|
||||
pub use self::{
|
||||
aci::Aci, adyen::Adyen, airwallex::Airwallex, applepay::Applepay,
|
||||
authorizedotnet::Authorizedotnet, bambora::Bambora, bluesnap::Bluesnap, braintree::Braintree,
|
||||
checkout::Checkout, coinbase::Coinbase, cybersource::Cybersource, dlocal::Dlocal,
|
||||
fiserv::Fiserv, forte::Forte, globalpay::Globalpay, klarna::Klarna, mollie::Mollie,
|
||||
multisafepay::Multisafepay, nexinets::Nexinets, nuvei::Nuvei, opennode::Opennode,
|
||||
payeezy::Payeezy, paypal::Paypal, payu::Payu, rapyd::Rapyd, shift4::Shift4, stripe::Stripe,
|
||||
trustpay::Trustpay, worldline::Worldline, worldpay::Worldpay,
|
||||
aci::Aci, adyen::Adyen, airwallex::Airwallex, authorizedotnet::Authorizedotnet,
|
||||
bambora::Bambora, bluesnap::Bluesnap, braintree::Braintree, checkout::Checkout,
|
||||
coinbase::Coinbase, cybersource::Cybersource, dlocal::Dlocal, fiserv::Fiserv, forte::Forte,
|
||||
globalpay::Globalpay, klarna::Klarna, mollie::Mollie, multisafepay::Multisafepay,
|
||||
nexinets::Nexinets, nuvei::Nuvei, opennode::Opennode, payeezy::Payeezy, paypal::Paypal,
|
||||
payu::Payu, rapyd::Rapyd, shift4::Shift4, stripe::Stripe, trustpay::Trustpay,
|
||||
worldline::Worldline, worldpay::Worldpay,
|
||||
};
|
||||
|
||||
@ -1,273 +0,0 @@
|
||||
mod transformers;
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use common_utils::ext_traits::ValueExt;
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
|
||||
use self::transformers as applepay;
|
||||
use crate::{
|
||||
configs::settings,
|
||||
core::errors::{self, CustomResult},
|
||||
headers, services,
|
||||
types::{
|
||||
self,
|
||||
api::{self, ConnectorCommon},
|
||||
},
|
||||
utils::{self, BytesExt, OptionExt},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Applepay;
|
||||
|
||||
impl ConnectorCommon for Applepay {
|
||||
fn id(&self) -> &'static str {
|
||||
"applepay"
|
||||
}
|
||||
|
||||
fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str {
|
||||
connectors.applepay.base_url.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl api::Payment for Applepay {}
|
||||
impl api::PaymentAuthorize for Applepay {}
|
||||
impl api::PaymentSync for Applepay {}
|
||||
impl api::PaymentVoid for Applepay {}
|
||||
impl api::PaymentCapture for Applepay {}
|
||||
impl api::PreVerify for Applepay {}
|
||||
impl api::PaymentSession for Applepay {}
|
||||
impl api::ConnectorAccessToken for Applepay {}
|
||||
impl api::PaymentToken for Applepay {}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::PaymentMethodToken,
|
||||
types::PaymentMethodTokenizationData,
|
||||
types::PaymentsResponseData,
|
||||
> for Applepay
|
||||
{
|
||||
// Not Implemented (R)
|
||||
}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::AccessTokenAuth,
|
||||
types::AccessTokenRequestData,
|
||||
types::AccessToken,
|
||||
> for Applepay
|
||||
{
|
||||
// Not Implemented (R)
|
||||
}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::Verify,
|
||||
types::VerifyRequestData,
|
||||
types::PaymentsResponseData,
|
||||
> for Applepay
|
||||
{
|
||||
}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::Capture,
|
||||
types::PaymentsCaptureData,
|
||||
types::PaymentsResponseData,
|
||||
> for Applepay
|
||||
{
|
||||
}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>
|
||||
for Applepay
|
||||
{
|
||||
}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::Authorize,
|
||||
types::PaymentsAuthorizeData,
|
||||
types::PaymentsResponseData,
|
||||
> for Applepay
|
||||
{
|
||||
}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::Void,
|
||||
types::PaymentsCancelData,
|
||||
types::PaymentsResponseData,
|
||||
> for Applepay
|
||||
{
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::Session,
|
||||
types::PaymentsSessionData,
|
||||
types::PaymentsResponseData,
|
||||
> for Applepay
|
||||
{
|
||||
fn get_headers(
|
||||
&self,
|
||||
_req: &types::PaymentsSessionRouterData,
|
||||
_connectors: &settings::Connectors,
|
||||
) -> CustomResult<Vec<(String, String)>, errors::ConnectorError> {
|
||||
let header = vec![(
|
||||
headers::CONTENT_TYPE.to_string(),
|
||||
types::PaymentsSessionType::get_content_type(self).to_string(),
|
||||
)];
|
||||
Ok(header)
|
||||
}
|
||||
|
||||
fn get_url(
|
||||
&self,
|
||||
_req: &types::PaymentsSessionRouterData,
|
||||
connectors: &settings::Connectors,
|
||||
) -> CustomResult<String, errors::ConnectorError> {
|
||||
Ok(format!(
|
||||
"{}{}",
|
||||
self.base_url(connectors),
|
||||
"paymentservices/paymentSession"
|
||||
))
|
||||
}
|
||||
|
||||
fn get_request_body(
|
||||
&self,
|
||||
req: &types::PaymentsSessionRouterData,
|
||||
) -> CustomResult<Option<String>, errors::ConnectorError> {
|
||||
let connector_req = applepay::ApplepaySessionRequest::try_from(req)?;
|
||||
let req = utils::Encode::<applepay::ApplepaySessionRequest>::encode_to_string_of_json(
|
||||
&connector_req,
|
||||
)
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
|
||||
Ok(Some(req))
|
||||
}
|
||||
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &types::PaymentsSessionRouterData,
|
||||
connectors: &settings::Connectors,
|
||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||
let request = services::RequestBuilder::new()
|
||||
.method(services::Method::Post)
|
||||
.url(&types::PaymentsSessionType::get_url(self, req, connectors)?)
|
||||
.attach_default_headers()
|
||||
.headers(types::PaymentsSessionType::get_headers(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.body(types::PaymentsSessionType::get_request_body(self, req)?)
|
||||
.add_certificate(types::PaymentsSessionType::get_certificate(self, req)?)
|
||||
.add_certificate_key(types::PaymentsSessionType::get_certificate_key(self, req)?)
|
||||
.build();
|
||||
Ok(Some(request))
|
||||
}
|
||||
|
||||
fn handle_response(
|
||||
&self,
|
||||
data: &types::PaymentsSessionRouterData,
|
||||
res: types::Response,
|
||||
) -> CustomResult<types::PaymentsSessionRouterData, errors::ConnectorError> {
|
||||
let response: applepay::ApplepaySessionTokenResponse = res
|
||||
.response
|
||||
.parse_struct("ApplepaySessionResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
|
||||
types::RouterData::try_from(types::ResponseRouterData {
|
||||
response,
|
||||
data: data.clone(),
|
||||
http_code: res.status_code,
|
||||
})
|
||||
.change_context(errors::ConnectorError::ResponseHandlingFailed)
|
||||
}
|
||||
|
||||
fn get_error_response(
|
||||
&self,
|
||||
res: types::Response,
|
||||
) -> CustomResult<types::ErrorResponse, errors::ConnectorError> {
|
||||
let response: applepay::ErrorResponse = res
|
||||
.response
|
||||
.parse_struct("ErrorResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
Ok(types::ErrorResponse {
|
||||
status_code: res.status_code,
|
||||
code: response.status_code,
|
||||
message: response.status_message,
|
||||
reason: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_certificate(
|
||||
&self,
|
||||
req: &types::PaymentsSessionRouterData,
|
||||
) -> CustomResult<Option<String>, errors::ConnectorError> {
|
||||
let metadata = req
|
||||
.connector_meta_data
|
||||
.to_owned()
|
||||
.get_required_value("connector_meta_data")
|
||||
.change_context(errors::ConnectorError::NoConnectorMetaData)?;
|
||||
|
||||
let metadata: transformers::ApplePayMetadata = metadata
|
||||
.parse_value("ApplePayMetaData")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
|
||||
|
||||
Ok(Some(metadata.session_token_data.certificate))
|
||||
}
|
||||
|
||||
fn get_certificate_key(
|
||||
&self,
|
||||
req: &types::PaymentsSessionRouterData,
|
||||
) -> CustomResult<Option<String>, errors::ConnectorError> {
|
||||
let metadata = req
|
||||
.connector_meta_data
|
||||
.to_owned()
|
||||
.get_required_value("connector_meta_data")
|
||||
.change_context(errors::ConnectorError::NoConnectorMetaData)?;
|
||||
|
||||
let metadata: transformers::ApplePayMetadata = metadata
|
||||
.parse_value("ApplePayMetaData")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
|
||||
|
||||
Ok(Some(metadata.session_token_data.certificate_keys))
|
||||
}
|
||||
}
|
||||
|
||||
impl api::Refund for Applepay {}
|
||||
impl api::RefundExecute for Applepay {}
|
||||
impl api::RefundSync for Applepay {}
|
||||
|
||||
impl services::ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData>
|
||||
for Applepay
|
||||
{
|
||||
}
|
||||
|
||||
impl services::ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponseData>
|
||||
for Applepay
|
||||
{
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl api::IncomingWebhook for Applepay {
|
||||
fn get_webhook_object_reference_id(
|
||||
&self,
|
||||
_request: &api::IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> {
|
||||
Err(errors::ConnectorError::WebhooksNotImplemented).into_report()
|
||||
}
|
||||
|
||||
fn get_webhook_event_type(
|
||||
&self,
|
||||
_request: &api::IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<api::IncomingWebhookEvent, errors::ConnectorError> {
|
||||
Err(errors::ConnectorError::WebhooksNotImplemented).into_report()
|
||||
}
|
||||
|
||||
fn get_webhook_resource_object(
|
||||
&self,
|
||||
_request: &api::IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<serde_json::Value, errors::ConnectorError> {
|
||||
Err(errors::ConnectorError::WebhooksNotImplemented).into_report()
|
||||
}
|
||||
}
|
||||
@ -1,228 +0,0 @@
|
||||
use api_models::payments;
|
||||
use common_utils::ext_traits::ValueExt;
|
||||
use error_stack::ResultExt;
|
||||
use masking::{Deserialize, Serialize};
|
||||
|
||||
use crate::{connector::utils, core::errors, types, utils::OptionExt};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplepaySessionRequest {
|
||||
merchant_identifier: String,
|
||||
display_name: String,
|
||||
initiative: String,
|
||||
initiative_context: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplepaySessionTokenResponse {
|
||||
pub epoch_timestamp: u64,
|
||||
pub expires_at: u64,
|
||||
pub merchant_session_identifier: String,
|
||||
pub nonce: String,
|
||||
pub merchant_identifier: String,
|
||||
pub domain_name: String,
|
||||
pub display_name: String,
|
||||
pub signature: String,
|
||||
pub operational_analytics_identifier: String,
|
||||
pub retries: u8,
|
||||
pub psp_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ErrorResponse {
|
||||
pub status_code: String,
|
||||
pub status_message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct ApplePayMetadata {
|
||||
pub payment_request_data: PaymentRequestMetadata,
|
||||
pub session_token_data: SessionRequest,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct PaymentRequestMetadata {
|
||||
pub supported_networks: Vec<String>,
|
||||
pub merchant_capabilities: Vec<String>,
|
||||
pub label: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct SessionRequest {
|
||||
pub certificate: String,
|
||||
pub certificate_keys: String,
|
||||
pub merchant_identifier: String,
|
||||
pub display_name: String,
|
||||
pub initiative: String,
|
||||
pub initiative_context: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct PaymentRequest {
|
||||
pub apple_pay_merchant_id: String,
|
||||
pub country_code: api_models::enums::CountryCode,
|
||||
pub currency_code: String,
|
||||
pub total: AmountInfo,
|
||||
pub merchant_capabilities: Vec<String>,
|
||||
pub supported_networks: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct AmountInfo {
|
||||
pub label: String,
|
||||
#[serde(rename = "type")]
|
||||
pub label_type: String,
|
||||
pub amount: String,
|
||||
}
|
||||
|
||||
impl TryFrom<&types::PaymentsSessionRouterData> for ApplepaySessionRequest {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(item: &types::PaymentsSessionRouterData) -> Result<Self, Self::Error> {
|
||||
let metadata = item
|
||||
.connector_meta_data
|
||||
.to_owned()
|
||||
.get_required_value("connector_meta_data")
|
||||
.change_context(errors::ConnectorError::NoConnectorMetaData)?;
|
||||
|
||||
let metadata: ApplePayMetadata = metadata
|
||||
.parse_value("ApplePayMetadata")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
|
||||
|
||||
Ok(Self {
|
||||
merchant_identifier: metadata.session_token_data.merchant_identifier,
|
||||
display_name: metadata.session_token_data.display_name,
|
||||
initiative: metadata.session_token_data.initiative,
|
||||
initiative_context: metadata.session_token_data.initiative_context,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<F>
|
||||
TryFrom<
|
||||
types::ResponseRouterData<
|
||||
F,
|
||||
ApplepaySessionTokenResponse,
|
||||
types::PaymentsSessionData,
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
> for types::RouterData<F, types::PaymentsSessionData, types::PaymentsResponseData>
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: types::ResponseRouterData<
|
||||
F,
|
||||
ApplepaySessionTokenResponse,
|
||||
types::PaymentsSessionData,
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let metadata = item
|
||||
.data
|
||||
.connector_meta_data
|
||||
.to_owned()
|
||||
.get_required_value("connector_meta_data")
|
||||
.change_context(errors::ConnectorError::NoConnectorMetaData)?;
|
||||
|
||||
let metadata: ApplePayMetadata = metadata
|
||||
.parse_value("ApplePayMetadata")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
|
||||
|
||||
let amount_info = AmountInfo {
|
||||
label: metadata.payment_request_data.label,
|
||||
label_type: "final".to_string(),
|
||||
amount: utils::to_currency_base_unit(
|
||||
item.data.request.amount,
|
||||
item.data.request.currency,
|
||||
)?,
|
||||
};
|
||||
|
||||
let payment_request = PaymentRequest {
|
||||
country_code: item
|
||||
.data
|
||||
.request
|
||||
.country
|
||||
.to_owned()
|
||||
.get_required_value("country_code")
|
||||
.change_context(errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "country_code",
|
||||
})?,
|
||||
currency_code: item.data.request.currency.to_string(),
|
||||
total: amount_info,
|
||||
merchant_capabilities: metadata.payment_request_data.merchant_capabilities,
|
||||
supported_networks: metadata.payment_request_data.supported_networks,
|
||||
apple_pay_merchant_id: metadata.session_token_data.merchant_identifier,
|
||||
};
|
||||
|
||||
let applepay_session = ApplepaySessionTokenResponse {
|
||||
epoch_timestamp: item.response.epoch_timestamp,
|
||||
expires_at: item.response.expires_at,
|
||||
merchant_session_identifier: item.response.merchant_session_identifier,
|
||||
nonce: item.response.nonce,
|
||||
merchant_identifier: item.response.merchant_identifier,
|
||||
domain_name: item.response.domain_name,
|
||||
display_name: item.response.display_name,
|
||||
signature: item.response.signature,
|
||||
operational_analytics_identifier: item.response.operational_analytics_identifier,
|
||||
retries: item.response.retries,
|
||||
psp_id: item.response.psp_id,
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: {
|
||||
api_models::payments::SessionToken::ApplePay(Box::new(
|
||||
payments::ApplepaySessionTokenResponse {
|
||||
session_token_data: applepay_session.into(),
|
||||
payment_request_data: payment_request.into(),
|
||||
},
|
||||
))
|
||||
},
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PaymentRequest> for payments::ApplePayPaymentRequest {
|
||||
fn from(value: PaymentRequest) -> Self {
|
||||
Self {
|
||||
country_code: value.country_code,
|
||||
currency_code: value.currency_code,
|
||||
total: value.total.into(),
|
||||
merchant_capabilities: value.merchant_capabilities,
|
||||
supported_networks: value.supported_networks,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AmountInfo> for payments::AmountInfo {
|
||||
fn from(value: AmountInfo) -> Self {
|
||||
Self {
|
||||
label: value.label,
|
||||
total_type: value.label_type,
|
||||
amount: value.amount,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ApplepaySessionTokenResponse> for payments::ApplePaySessionResponse {
|
||||
fn from(value: ApplepaySessionTokenResponse) -> Self {
|
||||
Self {
|
||||
epoch_timestamp: value.epoch_timestamp,
|
||||
expires_at: value.expires_at,
|
||||
merchant_session_identifier: value.merchant_session_identifier,
|
||||
nonce: value.nonce,
|
||||
merchant_identifier: value.merchant_identifier,
|
||||
domain_name: value.domain_name,
|
||||
display_name: value.display_name,
|
||||
signature: value.signature,
|
||||
operational_analytics_identifier: value.operational_analytics_identifier,
|
||||
retries: value.retries,
|
||||
psp_id: value.psp_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,6 @@ macro_rules! default_imp_for_complete_authorize{
|
||||
default_imp_for_complete_authorize!(
|
||||
connector::Aci,
|
||||
connector::Adyen,
|
||||
connector::Applepay,
|
||||
connector::Authorizedotnet,
|
||||
connector::Bambora,
|
||||
connector::Bluesnap,
|
||||
@ -132,7 +131,6 @@ macro_rules! default_imp_for_connector_redirect_response{
|
||||
default_imp_for_connector_redirect_response!(
|
||||
connector::Aci,
|
||||
connector::Adyen,
|
||||
connector::Applepay,
|
||||
connector::Authorizedotnet,
|
||||
connector::Bambora,
|
||||
connector::Bluesnap,
|
||||
@ -166,7 +164,6 @@ default_imp_for_connector_request_id!(
|
||||
connector::Aci,
|
||||
connector::Adyen,
|
||||
connector::Airwallex,
|
||||
connector::Applepay,
|
||||
connector::Authorizedotnet,
|
||||
connector::Bambora,
|
||||
connector::Bluesnap,
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
use api_models::payments as payment_types;
|
||||
use async_trait::async_trait;
|
||||
use error_stack::ResultExt;
|
||||
use common_utils::ext_traits::ByteSliceExt;
|
||||
use error_stack::{report, ResultExt};
|
||||
|
||||
use super::{ConstructFlowSpecificData, Feature};
|
||||
use crate::{
|
||||
connector,
|
||||
core::{
|
||||
errors::{self, ConnectorErrorExt, RouterResult},
|
||||
payments::{self, access_token, transformers, PaymentData},
|
||||
},
|
||||
headers,
|
||||
routes::{self, metrics},
|
||||
services,
|
||||
types::{self, api, storage},
|
||||
utils::OptionExt,
|
||||
utils::{self, OptionExt},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -73,8 +76,159 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_applepay_session_request(
|
||||
state: &routes::AppState,
|
||||
router_data: &types::PaymentsSessionRouterData,
|
||||
) -> RouterResult<(services::Request, payment_types::ApplepaySessionTokenData)> {
|
||||
let connector_metadata = router_data.connector_meta_data.clone();
|
||||
|
||||
let applepay_metadata = connector_metadata
|
||||
.parse_value::<payment_types::ApplepaySessionTokenData>("ApplepaySessionTokenData")
|
||||
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
|
||||
field_name: "connector_metadata".to_string(),
|
||||
expected_format: "applepay_metadata_format".to_string(),
|
||||
})?;
|
||||
let request = payment_types::ApplepaySessionRequest {
|
||||
merchant_identifier: applepay_metadata
|
||||
.data
|
||||
.session_token_data
|
||||
.merchant_identifier
|
||||
.clone(),
|
||||
display_name: applepay_metadata
|
||||
.data
|
||||
.session_token_data
|
||||
.display_name
|
||||
.clone(),
|
||||
initiative: applepay_metadata.data.session_token_data.initiative.clone(),
|
||||
initiative_context: applepay_metadata
|
||||
.data
|
||||
.session_token_data
|
||||
.initiative_context
|
||||
.clone(),
|
||||
};
|
||||
|
||||
let applepay_session_request =
|
||||
utils::Encode::<payment_types::ApplepaySessionRequest>::encode_to_string_of_json(&request)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to encode ApplePay session request to a string of json")?;
|
||||
|
||||
let mut url = state.conf.connectors.applepay.base_url.to_owned();
|
||||
url.push_str("paymentservices/paymentSession");
|
||||
|
||||
let session_request = services::RequestBuilder::new()
|
||||
.method(services::Method::Post)
|
||||
.url(url.as_str())
|
||||
.attach_default_headers()
|
||||
.headers(vec![(
|
||||
headers::CONTENT_TYPE.to_string(),
|
||||
"application/json".to_string(),
|
||||
)])
|
||||
.body(Some(applepay_session_request))
|
||||
.add_certificate(Some(
|
||||
applepay_metadata
|
||||
.data
|
||||
.session_token_data
|
||||
.certificate
|
||||
.clone(),
|
||||
))
|
||||
.add_certificate_key(Some(
|
||||
applepay_metadata
|
||||
.data
|
||||
.session_token_data
|
||||
.certificate_keys
|
||||
.clone(),
|
||||
))
|
||||
.build();
|
||||
Ok((session_request, applepay_metadata))
|
||||
}
|
||||
|
||||
async fn create_applepay_session_token(
|
||||
state: &routes::AppState,
|
||||
router_data: &types::PaymentsSessionRouterData,
|
||||
connector: &api::ConnectorData,
|
||||
) -> RouterResult<types::PaymentsSessionRouterData> {
|
||||
let (applepay_session_request, applepay_metadata) =
|
||||
mk_applepay_session_request(state, router_data)?;
|
||||
let response = services::call_connector_api(state, applepay_session_request)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failure in calling connector api")?;
|
||||
let session_response: payment_types::ApplePaySessionResponse = match response {
|
||||
Ok(resp) => resp
|
||||
.response
|
||||
.parse_struct("ApplePaySessionResponse")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to parse ApplePaySessionResponse struct"),
|
||||
Err(err) => {
|
||||
let error_response: payment_types::ApplepayErrorResponse = err
|
||||
.response
|
||||
.parse_struct("ApplepayErrorResponse")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to parse ApplepayErrorResponse struct")?;
|
||||
Err(
|
||||
report!(errors::ApiErrorResponse::InternalServerError).attach_printable(format!(
|
||||
"Failed with {} status code and the error response is {:?}",
|
||||
err.status_code, error_response
|
||||
)),
|
||||
)
|
||||
}
|
||||
}?;
|
||||
|
||||
let amount_info = payment_types::AmountInfo {
|
||||
label: applepay_metadata.data.payment_request_data.label,
|
||||
total_type: "final".to_string(),
|
||||
amount: connector::utils::to_currency_base_unit(
|
||||
router_data.request.amount,
|
||||
router_data.request.currency,
|
||||
)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to convert currency to base unit")?,
|
||||
};
|
||||
|
||||
let applepay_payment_request = payment_types::ApplePayPaymentRequest {
|
||||
country_code: router_data
|
||||
.request
|
||||
.country
|
||||
.to_owned()
|
||||
.get_required_value("country_code")
|
||||
.change_context(errors::ApiErrorResponse::MissingRequiredField {
|
||||
field_name: "country_code",
|
||||
})?,
|
||||
currency_code: router_data.request.currency.to_string(),
|
||||
total: amount_info,
|
||||
merchant_capabilities: applepay_metadata
|
||||
.data
|
||||
.payment_request_data
|
||||
.merchant_capabilities,
|
||||
supported_networks: applepay_metadata
|
||||
.data
|
||||
.payment_request_data
|
||||
.supported_networks,
|
||||
merchant_identifier: applepay_metadata
|
||||
.data
|
||||
.session_token_data
|
||||
.merchant_identifier,
|
||||
};
|
||||
|
||||
let response_router_data = types::PaymentsSessionRouterData {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: payment_types::SessionToken::ApplePay(Box::new(
|
||||
payment_types::ApplepaySessionTokenResponse {
|
||||
session_token_data: session_response,
|
||||
payment_request_data: applepay_payment_request,
|
||||
connector: connector.connector_name.to_string(),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
..router_data.clone()
|
||||
};
|
||||
|
||||
Ok(response_router_data)
|
||||
}
|
||||
|
||||
fn create_gpay_session_token(
|
||||
router_data: &types::PaymentsSessionRouterData,
|
||||
connector: &api::ConnectorData,
|
||||
) -> RouterResult<types::PaymentsSessionRouterData> {
|
||||
let connector_metadata = router_data.connector_meta_data.clone();
|
||||
|
||||
@ -105,6 +259,7 @@ fn create_gpay_session_token(
|
||||
merchant_info: gpay_data.data.merchant_info,
|
||||
allowed_payment_methods: gpay_data.data.allowed_payment_methods,
|
||||
transaction_info,
|
||||
connector: connector.connector_name.to_string(),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
@ -124,7 +279,10 @@ impl types::PaymentsSessionRouterData {
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
) -> RouterResult<Self> {
|
||||
match connector.get_token {
|
||||
api::GetToken::Metadata => create_gpay_session_token(self),
|
||||
api::GetToken::GpayMetadata => create_gpay_session_token(self, connector),
|
||||
api::GetToken::ApplePayMetadata => {
|
||||
create_applepay_session_token(state, self, connector).await
|
||||
}
|
||||
api::GetToken::Connector => {
|
||||
let connector_integration: services::BoxedConnectorIntegration<
|
||||
'_,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use std::{collections::HashSet, marker::PhantomData};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use api_models::admin::PaymentMethodsEnabled;
|
||||
use async_trait::async_trait;
|
||||
@ -18,7 +18,7 @@ use crate::{
|
||||
pii::Secret,
|
||||
routes::AppState,
|
||||
types::{
|
||||
api::{self, enums as api_enums, PaymentIdTypeExt},
|
||||
api::{self, PaymentIdTypeExt},
|
||||
storage::{self, enums as storage_enums},
|
||||
transformers::ForeignInto,
|
||||
},
|
||||
@ -293,8 +293,6 @@ where
|
||||
let connectors = &state.conf.connectors;
|
||||
let db = &state.store;
|
||||
|
||||
let supported_connectors: &Vec<String> = state.conf.connectors.supported.wallets.as_ref();
|
||||
|
||||
let connector_accounts = db
|
||||
.find_merchant_connector_account_by_merchant_id_and_disabled_list(
|
||||
&merchant_account.merchant_id,
|
||||
@ -304,127 +302,73 @@ where
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Database error when querying for merchant connector accounts")?;
|
||||
|
||||
let normal_connector_names: HashSet<String> = connector_accounts
|
||||
.iter()
|
||||
.filter(|connector_account| {
|
||||
connector_account
|
||||
let mut connector_and_supporting_payment_method_type = Vec::new();
|
||||
|
||||
for connector_account in connector_accounts {
|
||||
let payment_methods = connector_account
|
||||
.payment_methods_enabled
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.any(|payment_method| {
|
||||
.unwrap_or_default();
|
||||
for payment_method in payment_methods {
|
||||
let parsed_payment_method_result: Result<
|
||||
PaymentMethodsEnabled,
|
||||
error_stack::Report<errors::ParsingError>,
|
||||
> = payment_method.clone().parse_value("payment_method");
|
||||
|
||||
match parsed_payment_method_result {
|
||||
Ok(parsed_payment_method) => parsed_payment_method
|
||||
Ok(parsed_payment_method) => {
|
||||
let payment_method_types = parsed_payment_method
|
||||
.payment_method_types
|
||||
.map(|payment_method_types| {
|
||||
payment_method_types.iter().any(|payment_method_type| {
|
||||
matches!(
|
||||
.unwrap_or_default();
|
||||
for payment_method_type in payment_method_types {
|
||||
if matches!(
|
||||
payment_method_type.payment_experience,
|
||||
Some(api_models::enums::PaymentExperience::InvokeSdkClient)
|
||||
)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false),
|
||||
Err(parsing_error) => {
|
||||
logger::debug!(session_token_parsing_error=?parsing_error);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.map(|filtered_connector| filtered_connector.connector_name.clone())
|
||||
.collect();
|
||||
|
||||
// Parse the payment methods enabled to check if the merchant has enabled googlepay ( wallet ) using that connector.
|
||||
// A single connector can support creating session token from metadata as well as by calling the connector.
|
||||
let session_token_from_metadata_connectors = connector_accounts
|
||||
.iter()
|
||||
.filter(|connector_account| {
|
||||
connector_account
|
||||
.payment_methods_enabled
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.any(|payment_method| {
|
||||
let parsed_payment_method_result: Result<
|
||||
PaymentMethodsEnabled,
|
||||
error_stack::Report<errors::ParsingError>,
|
||||
> = payment_method.clone().parse_value("payment_method");
|
||||
|
||||
match parsed_payment_method_result {
|
||||
Ok(parsed_payment_method) => parsed_payment_method
|
||||
.payment_method_types
|
||||
.map(|payment_method_types| {
|
||||
payment_method_types.iter().any(|payment_method_type| {
|
||||
matches!(
|
||||
) {
|
||||
let connector_and_wallet = (
|
||||
connector_account.connector_name.to_owned(),
|
||||
payment_method_type.payment_method_type,
|
||||
api_models::enums::PaymentMethodType::GooglePay
|
||||
)
|
||||
})
|
||||
})
|
||||
.unwrap_or(false),
|
||||
);
|
||||
connector_and_supporting_payment_method_type
|
||||
.push(connector_and_wallet);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(parsing_error) => {
|
||||
logger::debug!(session_token_parsing_error=?parsing_error);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.map(|filtered_connector| filtered_connector.connector_name.clone())
|
||||
.collect::<HashSet<String>>();
|
||||
}
|
||||
}
|
||||
|
||||
let given_wallets = request.wallets.clone();
|
||||
let requested_payment_method_types = request.wallets.clone();
|
||||
|
||||
let connectors_data = if !given_wallets.is_empty() {
|
||||
// Create connectors for provided wallets
|
||||
let mut connectors_data = Vec::with_capacity(supported_connectors.len());
|
||||
for wallet in given_wallets {
|
||||
let (connector_name, connector_type) = match wallet {
|
||||
api_enums::SupportedWallets::Gpay => ("adyen", api::GetToken::Metadata),
|
||||
api_enums::SupportedWallets::ApplePay => ("applepay", api::GetToken::Connector),
|
||||
api_enums::SupportedWallets::Paypal => ("braintree", api::GetToken::Connector),
|
||||
api_enums::SupportedWallets::Klarna => ("klarna", api::GetToken::Connector),
|
||||
};
|
||||
|
||||
// Check if merchant has enabled the required merchant connector account
|
||||
if session_token_from_metadata_connectors.contains(connector_name)
|
||||
|| normal_connector_names.contains(connector_name)
|
||||
let connectors_data = if !requested_payment_method_types.is_empty() {
|
||||
let mut connectors_data = Vec::new();
|
||||
for payment_method_type in requested_payment_method_types {
|
||||
for connector_and_payment_method_type in
|
||||
&connector_and_supporting_payment_method_type
|
||||
{
|
||||
connectors_data.push(api::ConnectorData::get_connector_by_name(
|
||||
if connector_and_payment_method_type.1 == payment_method_type {
|
||||
let connector_details = api::ConnectorData::get_connector_by_name(
|
||||
connectors,
|
||||
connector_name,
|
||||
connector_type,
|
||||
)?);
|
||||
connector_and_payment_method_type.0.as_str(),
|
||||
api::GetToken::from(connector_and_payment_method_type.1),
|
||||
)?;
|
||||
connectors_data.push(connector_details);
|
||||
}
|
||||
}
|
||||
}
|
||||
connectors_data
|
||||
} else {
|
||||
// Create connectors for all enabled wallets
|
||||
let mut connectors_data = Vec::with_capacity(
|
||||
normal_connector_names.len() + session_token_from_metadata_connectors.len(),
|
||||
);
|
||||
let mut connectors_data = Vec::new();
|
||||
|
||||
for connector_name in normal_connector_names {
|
||||
let connector_data = api::ConnectorData::get_connector_by_name(
|
||||
for connector_and_payment_method_type in connector_and_supporting_payment_method_type {
|
||||
let connector_details = api::ConnectorData::get_connector_by_name(
|
||||
connectors,
|
||||
&connector_name,
|
||||
api::GetToken::Connector,
|
||||
connector_and_payment_method_type.0.as_str(),
|
||||
api::GetToken::from(connector_and_payment_method_type.1),
|
||||
)?;
|
||||
connectors_data.push(connector_data);
|
||||
}
|
||||
|
||||
for connector_name in session_token_from_metadata_connectors {
|
||||
let connector_data = api::ConnectorData::get_connector_by_name(
|
||||
connectors,
|
||||
&connector_name,
|
||||
api::GetToken::Metadata,
|
||||
)?;
|
||||
connectors_data.push(connector_data);
|
||||
connectors_data.push(connector_details);
|
||||
}
|
||||
connectors_data
|
||||
};
|
||||
@ -432,3 +376,13 @@ where
|
||||
Ok(api::ConnectorChoice::SessionMultiple(connectors_data))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<api_models::enums::PaymentMethodType> for api::GetToken {
|
||||
fn from(value: api_models::enums::PaymentMethodType) -> Self {
|
||||
match value {
|
||||
api_models::enums::PaymentMethodType::GooglePay => Self::GpayMetadata,
|
||||
api_models::enums::PaymentMethodType::ApplePay => Self::ApplePayMetadata,
|
||||
_ => Self::Connector,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +140,6 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::enums::AuthenticationType,
|
||||
api_models::enums::Connector,
|
||||
api_models::enums::PaymentMethod,
|
||||
api_models::enums::SupportedWallets,
|
||||
api_models::enums::PaymentMethodIssuerCode,
|
||||
api_models::enums::MandateStatus,
|
||||
api_models::enums::PaymentExperience,
|
||||
|
||||
@ -131,9 +131,10 @@ type BoxedConnector = Box<&'static (dyn Connector + Sync)>;
|
||||
|
||||
// Normal flow will call the connector and follow the flow specific operations (capture, authorize)
|
||||
// SessionTokenFromMetadata will avoid calling the connector instead create the session token ( for sdk )
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub enum GetToken {
|
||||
Metadata,
|
||||
GpayMetadata,
|
||||
ApplePayMetadata,
|
||||
Connector,
|
||||
}
|
||||
|
||||
@ -189,7 +190,6 @@ impl ConnectorData {
|
||||
"aci" => Ok(Box::new(&connector::Aci)),
|
||||
"adyen" => Ok(Box::new(&connector::Adyen)),
|
||||
"airwallex" => Ok(Box::new(&connector::Airwallex)),
|
||||
"applepay" => Ok(Box::new(&connector::Applepay)),
|
||||
"authorizedotnet" => Ok(Box::new(&connector::Authorizedotnet)),
|
||||
"bambora" => Ok(Box::new(&connector::Bambora)),
|
||||
"bluesnap" => Ok(Box::new(&connector::Bluesnap)),
|
||||
|
||||
Reference in New Issue
Block a user