mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
refactor(connector): [Klarna] Refactor Authorize call and configs for prod (#4750)
Co-authored-by: Samraat Bansal <samraat.bansal@juspay.in>
This commit is contained in:
@ -195,7 +195,7 @@ gocardless.base_url = "https://api-sandbox.gocardless.com"
|
||||
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
|
||||
helcim.base_url = "https://api.helcim.com/"
|
||||
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
|
||||
klarna.base_url = "https://api-na.playground.klarna.com/"
|
||||
klarna.base_url = "https://api{{region_based_endpoint}}.playground.klarna.com/"
|
||||
mifinity.base_url = "https://demo.mifinity.com/"
|
||||
mollie.base_url = "https://api.mollie.com/v2/"
|
||||
mollie.secondary_base_url = "https://api.cc.mollie.com/v1/"
|
||||
|
||||
@ -49,7 +49,7 @@ gocardless.base_url = "https://api-sandbox.gocardless.com"
|
||||
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
|
||||
helcim.base_url = "https://api.helcim.com/"
|
||||
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
|
||||
klarna.base_url = "https://api-na.playground.klarna.com/"
|
||||
klarna.base_url = "https://api{{region_based_endpoint}}.playground.klarna.com/"
|
||||
mifinity.base_url = "https://demo.mifinity.com/"
|
||||
mollie.base_url = "https://api.mollie.com/v2/"
|
||||
mollie.secondary_base_url = "https://api.cc.mollie.com/v1/"
|
||||
|
||||
@ -53,7 +53,7 @@ gocardless.base_url = "https://api.gocardless.com"
|
||||
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
|
||||
helcim.base_url = "https://api.helcim.com/"
|
||||
iatapay.base_url = "https://iata-pay.iata.org/api/v1"
|
||||
klarna.base_url = "https://api-na.playground.klarna.com/"
|
||||
klarna.base_url = "https://api{{region_based_endpoint}}.klarna.com/"
|
||||
mifinity.base_url = "https://secure.mifinity.com/"
|
||||
mollie.base_url = "https://api.mollie.com/v2/"
|
||||
mollie.secondary_base_url = "https://api.cc.mollie.com/v1/"
|
||||
|
||||
@ -53,7 +53,7 @@ gocardless.base_url = "https://api-sandbox.gocardless.com"
|
||||
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
|
||||
helcim.base_url = "https://api.helcim.com/"
|
||||
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
|
||||
klarna.base_url = "https://api-na.playground.klarna.com/"
|
||||
klarna.base_url = "https://api{{region_based_endpoint}}.playground.klarna.com/"
|
||||
mifinity.base_url = "https://demo.mifinity.com/"
|
||||
mollie.base_url = "https://api.mollie.com/v2/"
|
||||
mollie.secondary_base_url = "https://api.cc.mollie.com/v1/"
|
||||
|
||||
@ -197,7 +197,7 @@ gocardless.base_url = "https://api-sandbox.gocardless.com"
|
||||
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
|
||||
helcim.base_url = "https://api.helcim.com/"
|
||||
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
|
||||
klarna.base_url = "https://api-na.playground.klarna.com/"
|
||||
klarna.base_url = "https://api{{region_based_endpoint}}.playground.klarna.com/"
|
||||
mifinity.base_url = "https://demo.mifinity.com/"
|
||||
mollie.base_url = "https://api.mollie.com/v2/"
|
||||
mollie.secondary_base_url = "https://api.cc.mollie.com/v1/"
|
||||
@ -404,8 +404,6 @@ debit = { currency = "USD" }
|
||||
|
||||
[pm_filters.klarna]
|
||||
klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NL,NZ,NO,PL,PT,ES,SE,CH,GB,US", currency = "AUD,EUR,EUR,CAD,CZK,DKK,EUR,EUR,EUR,EUR,EUR,EUR,EUR,NZD,NOK,PLN,EUR,EUR,SEK,CHF,GBP,USD" }
|
||||
credit = { not_available_flows = { capture_method = "manual" } }
|
||||
debit = { not_available_flows = { capture_method = "manual" } }
|
||||
|
||||
[pm_filters.zen]
|
||||
credit = { not_available_flows = { capture_method = "manual" } }
|
||||
|
||||
@ -133,7 +133,7 @@ gocardless.base_url = "https://api-sandbox.gocardless.com"
|
||||
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
|
||||
helcim.base_url = "https://api.helcim.com/"
|
||||
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
|
||||
klarna.base_url = "https://api-na.playground.klarna.com/"
|
||||
klarna.base_url = "https://api{{region_based_endpoint}}.playground.klarna.com/"
|
||||
mifinity.base_url = "https://demo.mifinity.com/"
|
||||
mollie.base_url = "https://api.mollie.com/v2/"
|
||||
mollie.secondary_base_url = "https://api.cc.mollie.com/v1/"
|
||||
|
||||
@ -97,6 +97,16 @@ pub struct ApiModelMetaData {
|
||||
pub three_ds_requestor_name: Option<String>,
|
||||
pub three_ds_requestor_id: Option<String>,
|
||||
pub pull_mechanism_for_external_3ds_enabled: Option<bool>,
|
||||
pub klarna_region: Option<KlarnaEndpoint>,
|
||||
}
|
||||
|
||||
#[serde_with::skip_serializing_none]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
|
||||
pub enum KlarnaEndpoint {
|
||||
Europe,
|
||||
NorthAmerica,
|
||||
Oceania,
|
||||
}
|
||||
|
||||
#[serde_with::skip_serializing_none]
|
||||
@ -199,4 +209,5 @@ pub struct DashboardMetaData {
|
||||
pub three_ds_requestor_name: Option<String>,
|
||||
pub three_ds_requestor_id: Option<String>,
|
||||
pub pull_mechanism_for_external_3ds_enabled: Option<bool>,
|
||||
pub klarna_region: Option<KlarnaEndpoint>,
|
||||
}
|
||||
|
||||
@ -71,6 +71,15 @@ pub enum ApplePayTomlConfig {
|
||||
Zen(ZenApplePay),
|
||||
}
|
||||
|
||||
#[serde_with::skip_serializing_none]
|
||||
#[derive(Debug, Clone, serde::Serialize, Deserialize)]
|
||||
|
||||
pub enum KlarnaEndpoint {
|
||||
Europe,
|
||||
NorthAmerica,
|
||||
Oceania,
|
||||
}
|
||||
|
||||
#[serde_with::skip_serializing_none]
|
||||
#[derive(Debug, Deserialize, serde::Serialize, Clone)]
|
||||
pub struct ConfigMetadata {
|
||||
@ -91,6 +100,7 @@ pub struct ConfigMetadata {
|
||||
pub three_ds_requestor_name: Option<String>,
|
||||
pub three_ds_requestor_id: Option<String>,
|
||||
pub pull_mechanism_for_external_3ds_enabled: Option<bool>,
|
||||
pub klarna_region: Option<KlarnaEndpoint>,
|
||||
}
|
||||
|
||||
#[serde_with::skip_serializing_none]
|
||||
|
||||
@ -322,6 +322,7 @@ impl From<ApiModelMetaData> for DashboardMetaData {
|
||||
three_ds_requestor_id: api_model.three_ds_requestor_id,
|
||||
pull_mechanism_for_external_3ds_enabled: api_model
|
||||
.pull_mechanism_for_external_3ds_enabled,
|
||||
klarna_region: api_model.klarna_region,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,6 +197,7 @@ impl DashboardRequestPayload {
|
||||
three_ds_requestor_id: None,
|
||||
pull_mechanism_for_external_3ds_enabled: None,
|
||||
paypal_sdk: None,
|
||||
klarna_region: None,
|
||||
};
|
||||
let meta_data = match request.metadata {
|
||||
Some(data) => data,
|
||||
@ -221,6 +222,7 @@ impl DashboardRequestPayload {
|
||||
let three_ds_requestor_id = meta_data.three_ds_requestor_id;
|
||||
let pull_mechanism_for_external_3ds_enabled =
|
||||
meta_data.pull_mechanism_for_external_3ds_enabled;
|
||||
let klarna_region = meta_data.klarna_region;
|
||||
|
||||
Some(ApiModelMetaData {
|
||||
google_pay,
|
||||
@ -241,6 +243,7 @@ impl DashboardRequestPayload {
|
||||
three_ds_requestor_name,
|
||||
three_ds_requestor_id,
|
||||
pull_mechanism_for_external_3ds_enabled,
|
||||
klarna_region,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -1137,8 +1137,11 @@ merchant_secret="Source verification key"
|
||||
[klarna]
|
||||
[[klarna.pay_later]]
|
||||
payment_method_type = "klarna"
|
||||
[klarna.connector_auth.HeaderKey]
|
||||
api_key="Klarna API Key"
|
||||
[klarna.connector_auth.BodyKey]
|
||||
key1="Klarna Merchant Username"
|
||||
api_key="Klarna Merchant ID Password"
|
||||
[klarna.metadata]
|
||||
klarna_region="Region of your Klarna Merchant Account"
|
||||
[klarna.connector_webhook_details]
|
||||
merchant_secret="Source verification key"
|
||||
|
||||
|
||||
@ -954,8 +954,11 @@ merchant_secret="Source verification key"
|
||||
[klarna]
|
||||
[[klarna.pay_later]]
|
||||
payment_method_type = "klarna"
|
||||
[klarna.connector_auth.HeaderKey]
|
||||
api_key="Klarna API Key"
|
||||
[klarna.connector_auth.BodyKey]
|
||||
key1="Klarna Merchant Username"
|
||||
api_key="Klarna Merchant ID Password"
|
||||
[klarna.metadata]
|
||||
klarna_region="Region of your Klarna Merchant Account"
|
||||
[klarna.connector_webhook_details]
|
||||
merchant_secret="Source verification key"
|
||||
|
||||
|
||||
@ -1137,8 +1137,11 @@ merchant_secret="Source verification key"
|
||||
[klarna]
|
||||
[[klarna.pay_later]]
|
||||
payment_method_type = "klarna"
|
||||
[klarna.connector_auth.HeaderKey]
|
||||
api_key="Klarna API Key"
|
||||
[klarna.connector_auth.BodyKey]
|
||||
key1="Klarna Merchant Username"
|
||||
api_key="Klarna Merchant ID Password"
|
||||
[klarna.metadata]
|
||||
klarna_region="Region of your Klarna Merchant Account"
|
||||
[klarna.connector_webhook_details]
|
||||
merchant_secret="Source verification key"
|
||||
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
pub mod transformers;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use api_models::enums;
|
||||
use base64::Engine;
|
||||
use common_utils::request::RequestContent;
|
||||
use error_stack::{report, ResultExt};
|
||||
use masking::PeekInterface;
|
||||
use transformers as klarna;
|
||||
|
||||
use crate::{
|
||||
@ -51,9 +54,14 @@ impl ConnectorCommon for Klarna {
|
||||
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
|
||||
let auth = klarna::KlarnaAuthType::try_from(auth_type)
|
||||
.change_context(errors::ConnectorError::FailedToObtainAuthType)?;
|
||||
let encoded_api_key = consts::BASE64_ENGINE.encode(format!(
|
||||
"{}:{}",
|
||||
auth.username.peek(),
|
||||
auth.password.peek()
|
||||
));
|
||||
Ok(vec![(
|
||||
headers::AUTHORIZATION.to_string(),
|
||||
auth.basic_token.into_masked(),
|
||||
format!("Basic {encoded_api_key}").into_masked(),
|
||||
)])
|
||||
}
|
||||
|
||||
@ -74,11 +82,13 @@ impl ConnectorCommon for Klarna {
|
||||
let reason = response
|
||||
.error_messages
|
||||
.map(|messages| messages.join(" & "))
|
||||
.or(response.error_message);
|
||||
.or(response.error_message.clone());
|
||||
Ok(types::ErrorResponse {
|
||||
status_code: res.status_code,
|
||||
code: response.error_code,
|
||||
message: consts::NO_ERROR_MESSAGE.to_string(),
|
||||
message: response
|
||||
.error_message
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: None,
|
||||
@ -86,7 +96,21 @@ impl ConnectorCommon for Klarna {
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorValidation for Klarna {}
|
||||
impl ConnectorValidation for Klarna {
|
||||
fn validate_capture_method(
|
||||
&self,
|
||||
capture_method: Option<enums::CaptureMethod>,
|
||||
_pmt: Option<enums::PaymentMethodType>,
|
||||
) -> CustomResult<(), errors::ConnectorError> {
|
||||
let capture_method = capture_method.unwrap_or_default();
|
||||
match capture_method {
|
||||
enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()),
|
||||
enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err(
|
||||
connector_utils::construct_not_supported_error_report(capture_method, self.id()),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl api::Payment for Klarna {}
|
||||
|
||||
@ -118,6 +142,22 @@ impl
|
||||
// Not Implemented (R)
|
||||
}
|
||||
|
||||
fn build_region_specific_endpoint(
|
||||
base_url: &str,
|
||||
connector_metadata: &Option<common_utils::pii::SecretSerdeValue>,
|
||||
) -> CustomResult<String, errors::ConnectorError> {
|
||||
let klarna_metadata_object =
|
||||
transformers::KlarnaConnectorMetadataObject::try_from(connector_metadata)?;
|
||||
let region_based_endpoint = klarna_metadata_object
|
||||
.klarna_region
|
||||
.ok_or(errors::ConnectorError::InvalidConnectorConfig {
|
||||
config: "merchant_connector_account.metadata.region_based_endpoint",
|
||||
})
|
||||
.map(String::from)?;
|
||||
|
||||
Ok(base_url.replace("{{region_based_endpoint}}", ®ion_based_endpoint))
|
||||
}
|
||||
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
api::Session,
|
||||
@ -147,14 +187,13 @@ impl
|
||||
|
||||
fn get_url(
|
||||
&self,
|
||||
_req: &types::PaymentsSessionRouterData,
|
||||
req: &types::PaymentsSessionRouterData,
|
||||
connectors: &settings::Connectors,
|
||||
) -> CustomResult<String, errors::ConnectorError> {
|
||||
Ok(format!(
|
||||
"{}{}",
|
||||
self.base_url(connectors),
|
||||
"payments/v1/sessions"
|
||||
))
|
||||
let endpoint =
|
||||
build_region_specific_endpoint(self.base_url(connectors), &req.connector_meta_data)?;
|
||||
|
||||
Ok(format!("{}{}", endpoint, "payments/v1/sessions"))
|
||||
}
|
||||
|
||||
fn get_request_body(
|
||||
@ -162,7 +201,14 @@ impl
|
||||
req: &types::PaymentsSessionRouterData,
|
||||
_connectors: &settings::Connectors,
|
||||
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||
let connector_req = klarna::KlarnaSessionRequest::try_from(req)?;
|
||||
let connector_router_data = klarna::KlarnaRouterData::try_from((
|
||||
&self.get_currency_unit(),
|
||||
req.request.currency,
|
||||
req.request.amount,
|
||||
req,
|
||||
))?;
|
||||
|
||||
let connector_req = klarna::KlarnaSessionRequest::try_from(&connector_router_data)?;
|
||||
// encode only for for urlencoded things.
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
@ -304,6 +350,8 @@ impl
|
||||
.payment_method_type
|
||||
.as_ref()
|
||||
.ok_or_else(connector_utils::missing_field_err("payment_method_type"))?;
|
||||
let endpoint =
|
||||
build_region_specific_endpoint(self.base_url(connectors), &req.connector_meta_data)?;
|
||||
|
||||
match payment_method_data {
|
||||
domain::PaymentMethodData::PayLater(domain::PayLaterData::KlarnaSdk { token }) => {
|
||||
@ -313,8 +361,7 @@ impl
|
||||
common_enums::PaymentMethodType::Klarna,
|
||||
) => Ok(format!(
|
||||
"{}payments/v1/authorizations/{}/order",
|
||||
self.base_url(connectors),
|
||||
token
|
||||
endpoint, token
|
||||
)),
|
||||
(
|
||||
common_enums::PaymentExperience::DisplayQrCode
|
||||
@ -430,9 +477,13 @@ impl
|
||||
| domain::PaymentMethodData::Upi(_)
|
||||
| domain::PaymentMethodData::Voucher(_)
|
||||
| domain::PaymentMethodData::GiftCard(_)
|
||||
| domain::PaymentMethodData::CardToken(_) => Err(error_stack::report!(
|
||||
errors::ConnectorError::MismatchedPaymentData
|
||||
)),
|
||||
| domain::PaymentMethodData::CardToken(_) => {
|
||||
Err(report!(errors::ConnectorError::NotImplemented(
|
||||
connector_utils::get_unimplemented_payment_method_error_message(
|
||||
req.connector.as_str(),
|
||||
),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
use api_models::payments;
|
||||
use error_stack::report;
|
||||
use common_utils::pii;
|
||||
use error_stack::{report, ResultExt};
|
||||
use masking::{ExposeInterface, Secret};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
connector::utils::{self, PaymentsAuthorizeRequestData, RouterData},
|
||||
core::errors,
|
||||
types::{self, storage::enums},
|
||||
types::{self, storage::enums, transformers::ForeignFrom},
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@ -32,16 +34,50 @@ impl<T> TryFrom<(&types::api::CurrencyUnit, enums::Currency, i64, T)> for Klarna
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Serialize)]
|
||||
pub struct KlarnaPaymentsRequest {
|
||||
order_lines: Vec<OrderLines>,
|
||||
order_amount: i64,
|
||||
purchase_country: String,
|
||||
purchase_currency: enums::Currency,
|
||||
merchant_reference1: String,
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct KlarnaConnectorMetadataObject {
|
||||
pub klarna_region: Option<KlarnaEndpoint>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum KlarnaEndpoint {
|
||||
Europe,
|
||||
NorthAmerica,
|
||||
Oceania,
|
||||
}
|
||||
|
||||
impl From<KlarnaEndpoint> for String {
|
||||
fn from(endpoint: KlarnaEndpoint) -> Self {
|
||||
Self::from(match endpoint {
|
||||
KlarnaEndpoint::Europe => "",
|
||||
KlarnaEndpoint::NorthAmerica => "-na",
|
||||
KlarnaEndpoint::Oceania => "-oc",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&Option<pii::SecretSerdeValue>> for KlarnaConnectorMetadataObject {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(meta_data: &Option<pii::SecretSerdeValue>) -> Result<Self, Self::Error> {
|
||||
let metadata: Self = utils::to_connector_meta_from_secret::<Self>(meta_data.clone())
|
||||
.change_context(errors::ConnectorError::InvalidConnectorConfig {
|
||||
config: "metadata",
|
||||
})?;
|
||||
Ok(metadata)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Serialize)]
|
||||
pub struct KlarnaPaymentsRequest {
|
||||
auto_capture: bool,
|
||||
order_lines: Vec<OrderLines>,
|
||||
order_amount: i64,
|
||||
purchase_country: enums::CountryAlpha2,
|
||||
purchase_currency: enums::Currency,
|
||||
merchant_reference1: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct KlarnaPaymentsResponse {
|
||||
order_id: String,
|
||||
fraud_status: KlarnaFraudStatus,
|
||||
@ -50,9 +86,8 @@ pub struct KlarnaPaymentsResponse {
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct KlarnaSessionRequest {
|
||||
intent: KlarnaSessionIntent,
|
||||
purchase_country: String,
|
||||
purchase_country: enums::CountryAlpha2,
|
||||
purchase_currency: enums::Currency,
|
||||
locale: String,
|
||||
order_amount: i64,
|
||||
order_lines: Vec<OrderLines>,
|
||||
}
|
||||
@ -60,20 +95,25 @@ pub struct KlarnaSessionRequest {
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct KlarnaSessionResponse {
|
||||
pub client_token: Secret<String>,
|
||||
pub session_id: Secret<String>,
|
||||
pub session_id: String,
|
||||
}
|
||||
|
||||
impl TryFrom<&types::PaymentsSessionRouterData> for KlarnaSessionRequest {
|
||||
impl TryFrom<&KlarnaRouterData<&types::PaymentsSessionRouterData>> for KlarnaSessionRequest {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(item: &types::PaymentsSessionRouterData) -> Result<Self, Self::Error> {
|
||||
let request = &item.request;
|
||||
fn try_from(
|
||||
item: &KlarnaRouterData<&types::PaymentsSessionRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let request = &item.router_data.request;
|
||||
match request.order_details.clone() {
|
||||
Some(order_details) => Ok(Self {
|
||||
intent: KlarnaSessionIntent::Buy,
|
||||
purchase_country: "US".to_string(),
|
||||
purchase_country: request.country.ok_or(
|
||||
errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "billing.address.country",
|
||||
},
|
||||
)?,
|
||||
purchase_currency: request.currency,
|
||||
order_amount: request.amount,
|
||||
locale: "en-US".to_string(),
|
||||
order_amount: item.amount,
|
||||
order_lines: order_details
|
||||
.iter()
|
||||
.map(|data| OrderLines {
|
||||
@ -85,7 +125,7 @@ impl TryFrom<&types::PaymentsSessionRouterData> for KlarnaSessionRequest {
|
||||
.collect(),
|
||||
}),
|
||||
None => Err(report!(errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "product_name",
|
||||
field_name: "order_details",
|
||||
})),
|
||||
}
|
||||
}
|
||||
@ -104,7 +144,7 @@ impl TryFrom<types::PaymentsSessionResponseRouterData<KlarnaSessionResponse>>
|
||||
session_token: types::api::SessionToken::Klarna(Box::new(
|
||||
payments::KlarnaSessionTokenResponse {
|
||||
session_token: response.client_token.clone().expose(),
|
||||
session_id: response.session_id.clone().expose(),
|
||||
session_id: response.session_id.clone(),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
@ -122,9 +162,9 @@ impl TryFrom<&KlarnaRouterData<&types::PaymentsAuthorizeRouterData>> for KlarnaP
|
||||
let request = &item.router_data.request;
|
||||
match request.order_details.clone() {
|
||||
Some(order_details) => Ok(Self {
|
||||
purchase_country: "US".to_string(),
|
||||
purchase_country: item.router_data.get_billing_country()?,
|
||||
purchase_currency: request.currency,
|
||||
order_amount: request.amount,
|
||||
order_amount: item.amount,
|
||||
order_lines: order_details
|
||||
.iter()
|
||||
.map(|data| OrderLines {
|
||||
@ -134,10 +174,11 @@ impl TryFrom<&KlarnaRouterData<&types::PaymentsAuthorizeRouterData>> for KlarnaP
|
||||
total_amount: i64::from(data.quantity) * (data.amount),
|
||||
})
|
||||
.collect(),
|
||||
merchant_reference1: item.router_data.connector_request_reference_id.clone(),
|
||||
merchant_reference1: Some(item.router_data.connector_request_reference_id.clone()),
|
||||
auto_capture: request.is_auto_capture()?,
|
||||
}),
|
||||
None => Err(report!(errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "product_name"
|
||||
field_name: "order_details"
|
||||
})),
|
||||
}
|
||||
}
|
||||
@ -163,11 +204,15 @@ impl TryFrom<types::PaymentsResponseRouterData<KlarnaPaymentsResponse>>
|
||||
incremental_authorization_allowed: None,
|
||||
charge_id: None,
|
||||
}),
|
||||
status: item.response.fraud_status.into(),
|
||||
status: enums::AttemptStatus::foreign_from((
|
||||
item.response.fraud_status,
|
||||
item.data.request.is_auto_capture()?,
|
||||
)),
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct OrderLines {
|
||||
name: String,
|
||||
@ -186,15 +231,17 @@ pub enum KlarnaSessionIntent {
|
||||
}
|
||||
|
||||
pub struct KlarnaAuthType {
|
||||
pub basic_token: Secret<String>,
|
||||
pub username: Secret<String>,
|
||||
pub password: Secret<String>,
|
||||
}
|
||||
|
||||
impl TryFrom<&types::ConnectorAuthType> for KlarnaAuthType {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
|
||||
if let types::ConnectorAuthType::HeaderKey { api_key } = auth_type {
|
||||
if let types::ConnectorAuthType::BodyKey { api_key, key1 } = auth_type {
|
||||
Ok(Self {
|
||||
basic_token: api_key.to_owned(),
|
||||
username: key1.to_owned(),
|
||||
password: api_key.to_owned(),
|
||||
})
|
||||
} else {
|
||||
Err(errors::ConnectorError::FailedToObtainAuthType.into())
|
||||
@ -202,19 +249,26 @@ impl TryFrom<&types::ConnectorAuthType> for KlarnaAuthType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum KlarnaFraudStatus {
|
||||
Accepted,
|
||||
#[default]
|
||||
Pending,
|
||||
Rejected,
|
||||
}
|
||||
|
||||
impl From<KlarnaFraudStatus> for enums::AttemptStatus {
|
||||
fn from(item: KlarnaFraudStatus) -> Self {
|
||||
match item {
|
||||
KlarnaFraudStatus::Accepted => Self::Charged,
|
||||
impl ForeignFrom<(KlarnaFraudStatus, bool)> for enums::AttemptStatus {
|
||||
fn foreign_from((klarna_status, is_auto_capture): (KlarnaFraudStatus, bool)) -> Self {
|
||||
match klarna_status {
|
||||
KlarnaFraudStatus::Accepted => {
|
||||
if is_auto_capture {
|
||||
Self::Charged
|
||||
} else {
|
||||
Self::Authorized
|
||||
}
|
||||
}
|
||||
KlarnaFraudStatus::Pending => Self::Authorizing,
|
||||
KlarnaFraudStatus::Rejected => Self::Failure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1947,6 +1947,7 @@ pub(crate) fn validate_auth_and_metadata_type(
|
||||
}
|
||||
api_enums::Connector::Klarna => {
|
||||
klarna::transformers::KlarnaAuthType::try_from(val)?;
|
||||
klarna::transformers::KlarnaConnectorMetadataObject::try_from(connector_meta_data)?;
|
||||
Ok(())
|
||||
}
|
||||
api_enums::Connector::Mollie => {
|
||||
|
||||
@ -100,7 +100,7 @@ gocardless.base_url = "https://api-sandbox.gocardless.com"
|
||||
gpayments.base_url = "https://{{merchant_endpoint_prefix}}-test.api.as1.gpayments.net"
|
||||
helcim.base_url = "https://api.helcim.com/"
|
||||
iatapay.base_url = "https://sandbox.iata-pay.iata.org/api/v1"
|
||||
klarna.base_url = "https://api-na.playground.klarna.com/"
|
||||
klarna.base_url = "https://api{{region_based_endpoint}}.playground.klarna.com/"
|
||||
mifinity.base_url = "https://demo.mifinity.com/"
|
||||
mollie.base_url = "https://api.mollie.com/v2/"
|
||||
mollie.secondary_base_url = "https://api.cc.mollie.com/v1/"
|
||||
|
||||
Reference in New Issue
Block a user