Skip to content

Commit

Permalink
feat(pm_auth): Added /link and /exchange APIs with corresponding changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Sarthak1799 committed Dec 4, 2023
1 parent 643da1e commit eccf642
Show file tree
Hide file tree
Showing 29 changed files with 1,569 additions and 102 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 57 additions & 53 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ adyen = { banks = "blik_psp,place_zipko,m_bank,pay_with_ing,santander_przelew24,
stripe = { banks = "alior_bank,bank_millennium,bank_nowy_bfg_sa,bank_pekao_sa,banki_spbdzielcze,blik,bnp_paribas,boz,citi,credit_agricole,e_transfer_pocztowy24,getin_bank,idea_bank,inteligo,mbank_mtransfer,nest_przelew,noble_pay,pbac_z_ipko,plus_bank,santander_przelew24,toyota_bank,volkswagen_bank" }

[bank_config.open_banking_uk]
adyen = { banks = "aib,bank_of_scotland,danske_bank,first_direct,first_trust,halifax,lloyds,monzo,nat_west,nationwide_bank,royal_bank_of_scotland,starling,tsb_bank,tesco_bank,ulster_bank,barclays,hsbc_bank,revolut,santander_przelew24,open_bank_success,open_bank_failure,open_bank_cancelled"}
adyen = { banks = "aib,bank_of_scotland,danske_bank,first_direct,first_trust,halifax,lloyds,monzo,nat_west,nationwide_bank,royal_bank_of_scotland,starling,tsb_bank,tesco_bank,ulster_bank,barclays,hsbc_bank,revolut,santander_przelew24,open_bank_success,open_bank_failure,open_bank_cancelled" }

[bank_config.online_banking_fpx]
adyen.banks = "affin_bank,agro_bank,alliance_bank,am_bank,bank_islam,bank_muamalat,bank_rakyat,bank_simpanan_nasional,cimb_bank,hong_leong_bank,hsbc_bank,kuwait_finance_house,may_bank,ocbc_bank,public_bank,rhb_bank,standard_chartered_bank,uob_bank"
Expand Down Expand Up @@ -292,45 +292,45 @@ giropay = { country = "DE", currency = "EUR" }
eps = { country = "AT", currency = "EUR" }
sofort = { country = "ES,UK,SE,AT,NL,DE,CH,BE,FR,FI,IT,PL", currency = "EUR" }
ideal = { country = "NL", currency = "EUR" }
blik = {country = "PL", currency = "PLN"}
trustly = {country = "ES,UK,SE,NO,AT,NL,DE,DK,FI,EE,LT,LV", currency = "CZK,DKK,EUR,GBP,NOK,SEK"}
online_banking_czech_republic = {country = "CZ", currency = "EUR,CZK"}
online_banking_finland = {country = "FI", currency = "EUR"}
online_banking_poland = {country = "PL", currency = "PLN"}
online_banking_slovakia = {country = "SK", currency = "EUR,CZK"}
bancontact_card = {country = "BE", currency = "EUR"}
ach = {country = "US", currency = "USD"}
bacs = {country = "UK", currency = "GBP"}
sepa = {country = "ES,SK,AT,NL,DE,BE,FR,FI,PT,IE,EE,LT,LV,IT", currency = "EUR"}
ali_pay_hk = {country = "HK", currency = "HKD"}
bizum = {country = "ES", currency = "EUR"}
go_pay = {country = "ID", currency = "IDR"}
kakao_pay = {country = "KR", currency = "KRW"}
momo = {country = "VN", currency = "VND"}
gcash = {country = "PH", currency = "PHP"}
online_banking_fpx = {country = "MY", currency = "MYR"}
online_banking_thailand = {country = "TH", currency = "THB"}
touch_n_go = {country = "MY", currency = "MYR"}
atome = {country = "MY,SG", currency = "MYR,SGD"}
swish = {country = "SE", currency = "SEK"}
permata_bank_transfer = {country = "ID", currency = "IDR"}
bca_bank_transfer = {country = "ID", currency = "IDR"}
bni_va = {country = "ID", currency = "IDR"}
bri_va = {country = "ID", currency = "IDR"}
cimb_va = {country = "ID", currency = "IDR"}
danamon_va = {country = "ID", currency = "IDR"}
mandiri_va = {country = "ID", currency = "IDR"}
alfamart = {country = "ID", currency = "IDR"}
indomaret = {country = "ID", currency = "IDR"}
open_banking_uk = {country = "GB", currency = "GBP"}
oxxo = {country = "MX", currency = "MXN"}
pay_safe_card = {country = "AT,AU,BE,BR,BE,CA,HR,CY,CZ,DK,FI,FR,GE,DE,GI,HU,IS,IE,KW,LV,IE,LI,LT,LU,MT,MX,MD,ME,NL,NZ,NO,PY,PE,PL,PT,RO,SA,RS,SK,SI,ES,SE,CH,TR,UAE,UK,US,UY", currency = "EUR,AUD,BRL,CAD,CZK,DKK,GEL,GIP,HUF,ISK,KWD,CHF,MXN,MDL,NZD,NOK,PYG,PEN,PLN,RON,SAR,RSD,SEK,TRY,AED,GBP,USD,UYU"}
seven_eleven = {country = "JP", currency = "JPY"}
lawson = {country = "JP", currency = "JPY"}
mini_stop = {country = "JP", currency = "JPY"}
family_mart = {country = "JP", currency = "JPY"}
seicomart = {country = "JP", currency = "JPY"}
pay_easy = {country = "JP", currency = "JPY"}
blik = { country = "PL", currency = "PLN" }
trustly = { country = "ES,UK,SE,NO,AT,NL,DE,DK,FI,EE,LT,LV", currency = "CZK,DKK,EUR,GBP,NOK,SEK" }
online_banking_czech_republic = { country = "CZ", currency = "EUR,CZK" }
online_banking_finland = { country = "FI", currency = "EUR" }
online_banking_poland = { country = "PL", currency = "PLN" }
online_banking_slovakia = { country = "SK", currency = "EUR,CZK" }
bancontact_card = { country = "BE", currency = "EUR" }
ach = { country = "US", currency = "USD" }
bacs = { country = "UK", currency = "GBP" }
sepa = { country = "ES,SK,AT,NL,DE,BE,FR,FI,PT,IE,EE,LT,LV,IT", currency = "EUR" }
ali_pay_hk = { country = "HK", currency = "HKD" }
bizum = { country = "ES", currency = "EUR" }
go_pay = { country = "ID", currency = "IDR" }
kakao_pay = { country = "KR", currency = "KRW" }
momo = { country = "VN", currency = "VND" }
gcash = { country = "PH", currency = "PHP" }
online_banking_fpx = { country = "MY", currency = "MYR" }
online_banking_thailand = { country = "TH", currency = "THB" }
touch_n_go = { country = "MY", currency = "MYR" }
atome = { country = "MY,SG", currency = "MYR,SGD" }
swish = { country = "SE", currency = "SEK" }
permata_bank_transfer = { country = "ID", currency = "IDR" }
bca_bank_transfer = { country = "ID", currency = "IDR" }
bni_va = { country = "ID", currency = "IDR" }
bri_va = { country = "ID", currency = "IDR" }
cimb_va = { country = "ID", currency = "IDR" }
danamon_va = { country = "ID", currency = "IDR" }
mandiri_va = { country = "ID", currency = "IDR" }
alfamart = { country = "ID", currency = "IDR" }
indomaret = { country = "ID", currency = "IDR" }
open_banking_uk = { country = "GB", currency = "GBP" }
oxxo = { country = "MX", currency = "MXN" }
pay_safe_card = { country = "AT,AU,BE,BR,BE,CA,HR,CY,CZ,DK,FI,FR,GE,DE,GI,HU,IS,IE,KW,LV,IE,LI,LT,LU,MT,MX,MD,ME,NL,NZ,NO,PY,PE,PL,PT,RO,SA,RS,SK,SI,ES,SE,CH,TR,UAE,UK,US,UY", currency = "EUR,AUD,BRL,CAD,CZK,DKK,GEL,GIP,HUF,ISK,KWD,CHF,MXN,MDL,NZD,NOK,PYG,PEN,PLN,RON,SAR,RSD,SEK,TRY,AED,GBP,USD,UYU" }
seven_eleven = { country = "JP", currency = "JPY" }
lawson = { country = "JP", currency = "JPY" }
mini_stop = { country = "JP", currency = "JPY" }
family_mart = { country = "JP", currency = "JPY" }
seicomart = { country = "JP", currency = "JPY" }
pay_easy = { country = "JP", currency = "JPY" }

[pm_filters.braintree]
paypal = { currency = "AUD,BRL,CAD,CNY,CZK,DKK,EUR,HKD,HUF,ILS,JPY,MYR,MXN,TWD,NZD,NOK,PHP,PLN,GBP,RUB,SGD,SEK,CHF,THB,USD" }
Expand Down Expand Up @@ -398,17 +398,17 @@ debit = { currency = "USD" }
stripe = { long_lived_token = false, payment_method = "wallet", payment_method_type = { type = "disable_only", list = "google_pay" } }
checkout = { long_lived_token = false, payment_method = "wallet" }
stax = { long_lived_token = true, payment_method = "card,bank_debit" }
mollie = {long_lived_token = false, payment_method = "card"}
square = {long_lived_token = false, payment_method = "card"}
mollie = { long_lived_token = false, payment_method = "card" }
square = { long_lived_token = false, payment_method = "card" }
braintree = { long_lived_token = false, payment_method = "card" }
payme = {long_lived_token = false, payment_method = "card"}
gocardless = {long_lived_token = true, payment_method = "bank_debit"}
payme = { long_lived_token = false, payment_method = "card" }
gocardless = { long_lived_token = true, payment_method = "bank_debit" }

[temp_locker_enable_config]
stripe = {payment_method = "bank_transfer"}
nuvei = {payment_method = "card"}
shift4 = {payment_method = "card"}
bluesnap = {payment_method = "card"}
stripe = { payment_method = "bank_transfer" }
nuvei = { payment_method = "card" }
shift4 = { payment_method = "card" }
bluesnap = { payment_method = "card" }

[connector_customer]
connector_list = "gocardless,stax,stripe"
Expand Down Expand Up @@ -447,9 +447,9 @@ wallet.apple_pay = { connector_list = "stripe,adyen" }
wallet.paypal = { connector_list = "adyen" }
card.credit = { connector_list = "stripe,adyen,authorizedotnet,globalpay,worldpay,multisafepay,nmi,nexinets,noon" }
card.debit = { connector_list = "stripe,adyen,authorizedotnet,globalpay,worldpay,multisafepay,nmi,nexinets,noon" }
bank_debit.ach = { connector_list = "gocardless"}
bank_debit.becs = { connector_list = "gocardless"}
bank_debit.sepa = { connector_list = "gocardless"}
bank_debit.ach = { connector_list = "gocardless" }
bank_debit.becs = { connector_list = "gocardless" }
bank_debit.sepa = { connector_list = "gocardless" }

[connector_request_reference_id_config]
merchant_ids_send_payment_id_as_connector_request_id = []
Expand All @@ -469,8 +469,12 @@ apple_pay_merchant_cert_key = "APPLE_PAY_MERCHNAT_CERTIFICATE_KEY"
[payment_link]
sdk_url = "http://localhost:9090/dist/HyperLoader.js"

[payment_method_auth]
redis_expiry = 900
pm_auth_key = "Some_pm_auth_key"

[lock_settings]
redis_lock_expiry_seconds = 180 # 3 * 60 seconds
redis_lock_expiry_seconds = 180 # 3 * 60 seconds
delay_between_retries_in_milliseconds = 500

[kv_config]
Expand Down Expand Up @@ -504,4 +508,4 @@ port = 5432
dbname = "hyperswitch_db"
pool_size = 5
connection_timeout = 10
queue_strategy = "Fifo"
queue_strategy = "Fifo"
2 changes: 2 additions & 0 deletions crates/api_models/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ strum = { version = "0.25", features = ["derive"] }
time = { version = "0.3.21", features = ["serde", "serde-well-known", "std"] }
url = { version = "2.4.0", features = ["serde"] }
utoipa = { version = "3.3.0", features = ["preserve_order"] }
frunk = "0.4.1"
frunk_core = "0.4.1"

# First party crates
cards = { version = "0.1.0", path = "../cards" }
Expand Down
24 changes: 24 additions & 0 deletions crates/api_models/src/enums.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub use common_enums::*;
use std::str::FromStr;
use utoipa::ToSchema;

#[derive(
Expand Down Expand Up @@ -470,3 +471,26 @@ pub enum LockerChoice {
Basilisk,
Tartarus,
}

#[derive(
Clone,
Copy,
Debug,
Eq,
PartialEq,
serde::Serialize,
serde::Deserialize,
strum::Display,
strum::EnumString,
frunk::LabelledGeneric,
ToSchema,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum PmAuthConnectors {
Plaid,
}

pub fn convert_pm_auth_connector(connector_name: &str) -> Option<PmAuthConnectors> {
PmAuthConnectors::from_str(connector_name).ok()
}
1 change: 1 addition & 0 deletions crates/api_models/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub mod payment_methods;
pub mod payments;
#[cfg(feature = "payouts")]
pub mod payouts;
pub mod pm_auth;
pub mod refunds;
pub mod routing;
pub mod surcharge_decision_configs;
Expand Down
57 changes: 57 additions & 0 deletions crates/api_models/src/pm_auth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use common_enums::{PaymentMethod, PaymentMethodType};
use common_utils::{
events::{ApiEventMetric, ApiEventsType},
impl_misc_api_event_type,
};

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub struct LinkTokenCreateRequest {
pub language: Option<String>, // optional language field to be passed
pub client_secret: Option<String>, // client secret to be passed in req body
pub payment_id: String, // payment_id to be passed in req body for redis pm_auth connector name fetch
pub payment_method: PaymentMethod, // payment_method to be used for filtering pm_auth connector
pub payment_method_type: PaymentMethodType, // payment_method_type to be used for filtering pm_auth connector
}

#[derive(Debug, Clone, serde::Serialize)]
pub struct LinkTokenCreateResponse {
pub link_token: String, // link_token received in response
pub connector: String, // pm_auth connector name in response
}

#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]

pub struct ExchangeTokenCreateRequest {
pub public_token: String,
pub client_secret: Option<String>,
pub payment_id: String,
pub payment_method: PaymentMethod,
pub payment_method_type: PaymentMethodType,
}

#[derive(Debug, Clone, serde::Serialize)]
pub struct ExchangeTokenCreateResponse {
pub access_token: String,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PaymentMethodAuthConfig {
pub enabled_payment_methods: Vec<PaymentMethodAuthConnectorChoice>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PaymentMethodAuthConnectorChoice {
pub payment_method: PaymentMethod,
pub payment_method_type: PaymentMethodType,
pub connector_name: String,
pub mca_id: String,
}

impl_misc_api_event_type!(
LinkTokenCreateRequest,
LinkTokenCreateResponse,
ExchangeTokenCreateRequest,
ExchangeTokenCreateResponse
);
87 changes: 86 additions & 1 deletion crates/pm_auth/src/connector/plaid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
types::{
self as auth_types,
api::{
auth_service::{self, ExchangeToken, LinkToken},
auth_service::{self, BankAccountCredentials, ExchangeToken, LinkToken},
ConnectorCommon, ConnectorCommonExt, ConnectorIntegration,
},
},
Expand Down Expand Up @@ -266,3 +266,88 @@ impl
self.build_error_response(res)
}
}

impl auth_service::AuthServiceBankAccountCredentials for Plaid {}

impl
ConnectorIntegration<
BankAccountCredentials,
auth_types::BankAccountCredentialsRequest,
auth_types::BankAccountCredentialsResponse,
> for Plaid
{
fn get_headers(
&self,
req: &auth_types::BankDetailsRouterData,
connectors: &auth_types::PaymentMethodAuthConnectors,
) -> errors::CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
self.build_headers(req, connectors)
}

fn get_content_type(&self) -> &'static str {
self.common_get_content_type()
}

fn get_url(
&self,
_req: &auth_types::BankDetailsRouterData,
connectors: &auth_types::PaymentMethodAuthConnectors,
) -> errors::CustomResult<String, errors::ConnectorError> {
Ok(format!("{}{}", self.base_url(connectors), "/auth/get"))
}

fn get_request_body(
&self,
req: &auth_types::BankDetailsRouterData,
) -> errors::CustomResult<Option<RequestBody>, errors::ConnectorError> {
let req_obj = plaid::PlaidBankAccountCredentialsRequest::try_from(req)?;
let plaid_req = RequestBody::log_and_get_request_body(
&req_obj,
Encode::<plaid::PlaidBankAccountCredentialsRequest>::encode_to_string_of_json,
)
.change_context(errors::ConnectorError::RequestEncodingFailed)?;
Ok(Some(plaid_req))
}

fn build_request(
&self,
req: &auth_types::BankDetailsRouterData,
connectors: &auth_types::PaymentMethodAuthConnectors,
) -> errors::CustomResult<Option<Request>, errors::ConnectorError> {
Ok(Some(
RequestBuilder::new()
.method(Method::Post)
.url(&auth_types::PaymentAuthBankAccountDetailsType::get_url(
self, req, connectors,
)?)
.attach_default_headers()
.headers(auth_types::PaymentAuthBankAccountDetailsType::get_headers(
self, req, connectors,
)?)
.body(auth_types::PaymentAuthBankAccountDetailsType::get_request_body(self, req)?)
.build(),
))
}

fn handle_response(
&self,
data: &auth_types::BankDetailsRouterData,
res: auth_types::Response,
) -> errors::CustomResult<auth_types::BankDetailsRouterData, errors::ConnectorError> {
let response: plaid::PlaidBankAccountCredentialsResponse = res
.response
.parse_struct("PlaidBankAccountCredentialsResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
<auth_types::BankDetailsRouterData>::try_from(auth_types::ResponseRouterData {
response,
data: data.clone(),
http_code: res.status_code,
})
}
fn get_error_response(
&self,
res: auth_types::Response,
) -> errors::CustomResult<auth_types::ErrorResponse, errors::ConnectorError> {
self.build_error_response(res)
}
}
Loading

0 comments on commit eccf642

Please sign in to comment.