mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
feat(connector) : add PayPal wallet support for Paypal (#893)
Co-authored-by: Arjun Karthik <m.arjunkarthik@gmail.com>
This commit is contained in:
@ -19,6 +19,7 @@ use crate::{
|
|||||||
types::{
|
types::{
|
||||||
self,
|
self,
|
||||||
api::{self, CompleteAuthorize, ConnectorCommon, ConnectorCommonExt},
|
api::{self, CompleteAuthorize, ConnectorCommon, ConnectorCommonExt},
|
||||||
|
storage::enums as storage_enums,
|
||||||
ErrorResponse, Response,
|
ErrorResponse, Response,
|
||||||
},
|
},
|
||||||
utils::{self, BytesExt},
|
utils::{self, BytesExt},
|
||||||
@ -44,10 +45,19 @@ impl api::RefundSync for Paypal {}
|
|||||||
impl Paypal {
|
impl Paypal {
|
||||||
pub fn connector_transaction_id(
|
pub fn connector_transaction_id(
|
||||||
&self,
|
&self,
|
||||||
|
payment_method: Option<storage_enums::PaymentMethod>,
|
||||||
connector_meta: &Option<serde_json::Value>,
|
connector_meta: &Option<serde_json::Value>,
|
||||||
) -> CustomResult<Option<String>, errors::ConnectorError> {
|
) -> CustomResult<Option<String>, errors::ConnectorError> {
|
||||||
let meta: PaypalMeta = to_connector_meta(connector_meta.clone())?;
|
match payment_method {
|
||||||
Ok(meta.authorize_id)
|
Some(storage_models::enums::PaymentMethod::Wallet) => {
|
||||||
|
let meta: PaypalMeta = to_connector_meta(connector_meta.clone())?;
|
||||||
|
Ok(Some(meta.order_id))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let meta: PaypalMeta = to_connector_meta(connector_meta.clone())?;
|
||||||
|
Ok(meta.authorize_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_order_error_response(
|
pub fn get_order_error_response(
|
||||||
@ -187,13 +197,11 @@ impl
|
|||||||
types::PaymentsResponseData,
|
types::PaymentsResponseData,
|
||||||
> for Paypal
|
> for Paypal
|
||||||
{
|
{
|
||||||
// Not Implemented (R)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectorIntegration<api::Session, types::PaymentsSessionData, types::PaymentsResponseData>
|
impl ConnectorIntegration<api::Session, types::PaymentsSessionData, types::PaymentsResponseData>
|
||||||
for Paypal
|
for Paypal
|
||||||
{
|
{
|
||||||
//TODO: implement sessions flow
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, types::AccessToken>
|
impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, types::AccessToken>
|
||||||
@ -317,7 +325,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
|
|||||||
_req: &types::PaymentsAuthorizeRouterData,
|
_req: &types::PaymentsAuthorizeRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
Ok(format!("{}v2/checkout/orders", self.base_url(connectors),))
|
Ok(format!("{}v2/checkout/orders", self.base_url(connectors)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_request_body(
|
fn get_request_body(
|
||||||
@ -355,15 +363,30 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
|
|||||||
data: &types::PaymentsAuthorizeRouterData,
|
data: &types::PaymentsAuthorizeRouterData,
|
||||||
res: Response,
|
res: Response,
|
||||||
) -> CustomResult<types::PaymentsAuthorizeRouterData, errors::ConnectorError> {
|
) -> CustomResult<types::PaymentsAuthorizeRouterData, errors::ConnectorError> {
|
||||||
let response: paypal::PaypalOrdersResponse = res
|
match data.payment_method {
|
||||||
.response
|
storage_models::enums::PaymentMethod::Wallet => {
|
||||||
.parse_struct("Paypal PaymentsAuthorizeResponse")
|
let response: paypal::PaypalRedirectResponse = res
|
||||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
.response
|
||||||
types::RouterData::try_from(types::ResponseRouterData {
|
.parse_struct("paypal PaymentsRedirectResponse")
|
||||||
response,
|
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||||
data: data.clone(),
|
types::RouterData::try_from(types::ResponseRouterData {
|
||||||
http_code: res.status_code,
|
response,
|
||||||
})
|
data: data.clone(),
|
||||||
|
http_code: res.status_code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let response: paypal::PaypalOrdersResponse = res
|
||||||
|
.response
|
||||||
|
.parse_struct("paypal PaymentsOrderResponse")
|
||||||
|
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||||
|
types::RouterData::try_from(types::ResponseRouterData {
|
||||||
|
response,
|
||||||
|
data: data.clone(),
|
||||||
|
http_code: res.status_code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_error_response(
|
fn get_error_response(
|
||||||
@ -381,6 +404,74 @@ impl
|
|||||||
types::PaymentsResponseData,
|
types::PaymentsResponseData,
|
||||||
> for Paypal
|
> for Paypal
|
||||||
{
|
{
|
||||||
|
fn get_headers(
|
||||||
|
&self,
|
||||||
|
req: &types::PaymentsCompleteAuthorizeRouterData,
|
||||||
|
connectors: &settings::Connectors,
|
||||||
|
) -> CustomResult<Vec<(String, 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: &types::PaymentsCompleteAuthorizeRouterData,
|
||||||
|
connectors: &settings::Connectors,
|
||||||
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
|
let paypal_meta: PaypalMeta = to_connector_meta(req.request.connector_meta.clone())?;
|
||||||
|
Ok(format!(
|
||||||
|
"{}v2/checkout/orders/{}/capture",
|
||||||
|
self.base_url(connectors),
|
||||||
|
paypal_meta.order_id
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_request(
|
||||||
|
&self,
|
||||||
|
req: &types::PaymentsCompleteAuthorizeRouterData,
|
||||||
|
connectors: &settings::Connectors,
|
||||||
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
Ok(Some(
|
||||||
|
services::RequestBuilder::new()
|
||||||
|
.method(services::Method::Post)
|
||||||
|
.url(&types::PaymentsCompleteAuthorizeType::get_url(
|
||||||
|
self, req, connectors,
|
||||||
|
)?)
|
||||||
|
.headers(types::PaymentsCompleteAuthorizeType::get_headers(
|
||||||
|
self, req, connectors,
|
||||||
|
)?)
|
||||||
|
.body(types::PaymentsCompleteAuthorizeType::get_request_body(
|
||||||
|
self, req,
|
||||||
|
)?)
|
||||||
|
.build(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_response(
|
||||||
|
&self,
|
||||||
|
data: &types::PaymentsCompleteAuthorizeRouterData,
|
||||||
|
res: Response,
|
||||||
|
) -> CustomResult<types::PaymentsCompleteAuthorizeRouterData, errors::ConnectorError> {
|
||||||
|
let response: paypal::PaypalOrdersResponse = res
|
||||||
|
.response
|
||||||
|
.parse_struct("paypal PaymentsOrderResponse")
|
||||||
|
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||||
|
types::RouterData::try_from(types::ResponseRouterData {
|
||||||
|
response,
|
||||||
|
data: data.clone(),
|
||||||
|
http_code: res.status_code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_error_response(
|
||||||
|
&self,
|
||||||
|
res: Response,
|
||||||
|
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
|
||||||
|
self.build_error_response(res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>
|
impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>
|
||||||
@ -403,22 +494,31 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
|
|||||||
req: &types::PaymentsSyncRouterData,
|
req: &types::PaymentsSyncRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
let capture_id = req
|
|
||||||
.request
|
|
||||||
.connector_transaction_id
|
|
||||||
.get_connector_transaction_id()
|
|
||||||
.change_context(errors::ConnectorError::MissingConnectorTransactionID)?;
|
|
||||||
let paypal_meta: PaypalMeta = to_connector_meta(req.request.connector_meta.clone())?;
|
let paypal_meta: PaypalMeta = to_connector_meta(req.request.connector_meta.clone())?;
|
||||||
let psync_url = match paypal_meta.psync_flow {
|
match req.payment_method {
|
||||||
transformers::PaypalPaymentIntent::Authorize => format!(
|
storage_models::enums::PaymentMethod::Wallet => Ok(format!(
|
||||||
"v2/payments/authorizations/{}",
|
"{}v2/checkout/orders/{}",
|
||||||
paypal_meta.authorize_id.unwrap_or_default()
|
self.base_url(connectors),
|
||||||
),
|
paypal_meta.order_id
|
||||||
transformers::PaypalPaymentIntent::Capture => {
|
)),
|
||||||
format!("v2/payments/captures/{}", capture_id)
|
_ => {
|
||||||
|
let capture_id = req
|
||||||
|
.request
|
||||||
|
.connector_transaction_id
|
||||||
|
.get_connector_transaction_id()
|
||||||
|
.change_context(errors::ConnectorError::MissingConnectorTransactionID)?;
|
||||||
|
let psync_url = match paypal_meta.psync_flow {
|
||||||
|
transformers::PaypalPaymentIntent::Authorize => format!(
|
||||||
|
"v2/payments/authorizations/{}",
|
||||||
|
paypal_meta.authorize_id.unwrap_or_default()
|
||||||
|
),
|
||||||
|
transformers::PaypalPaymentIntent::Capture => {
|
||||||
|
format!("v2/payments/captures/{}", capture_id)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(format!("{}{}", self.base_url(connectors), psync_url))
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Ok(format!("{}{}", self.base_url(connectors), psync_url,))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_request(
|
fn build_request(
|
||||||
@ -440,15 +540,30 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
|
|||||||
data: &types::PaymentsSyncRouterData,
|
data: &types::PaymentsSyncRouterData,
|
||||||
res: Response,
|
res: Response,
|
||||||
) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> {
|
) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> {
|
||||||
let response: paypal::PaypalPaymentsSyncResponse = res
|
match data.payment_method {
|
||||||
.response
|
storage_models::enums::PaymentMethod::Wallet => {
|
||||||
.parse_struct("paypal PaymentsSyncResponse")
|
let response: paypal::PaypalOrdersResponse = res
|
||||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
.response
|
||||||
types::RouterData::try_from(types::ResponseRouterData {
|
.parse_struct("paypal PaymentsOrderResponse")
|
||||||
response,
|
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||||
data: data.clone(),
|
types::RouterData::try_from(types::ResponseRouterData {
|
||||||
http_code: res.status_code,
|
response,
|
||||||
})
|
data: data.clone(),
|
||||||
|
http_code: res.status_code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let response: paypal::PaypalPaymentsSyncResponse = res
|
||||||
|
.response
|
||||||
|
.parse_struct("paypal PaymentsSyncResponse")
|
||||||
|
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||||
|
types::RouterData::try_from(types::ResponseRouterData {
|
||||||
|
response,
|
||||||
|
data: data.clone(),
|
||||||
|
http_code: res.status_code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_error_response(
|
fn get_error_response(
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use common_utils::errors::CustomResult;
|
use common_utils::errors::CustomResult;
|
||||||
use masking::Secret;
|
use masking::Secret;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
connector::utils::{
|
connector::utils::{
|
||||||
@ -8,7 +9,7 @@ use crate::{
|
|||||||
PaymentsAuthorizeRequestData,
|
PaymentsAuthorizeRequestData,
|
||||||
},
|
},
|
||||||
core::errors,
|
core::errors,
|
||||||
pii,
|
pii, services,
|
||||||
types::{self, api, storage::enums as storage_enums, transformers::ForeignFrom},
|
types::{self, api, storage::enums as storage_enums, transformers::ForeignFrom},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,10 +48,28 @@ pub struct CardRequest {
|
|||||||
security_code: Option<Secret<String>>,
|
security_code: Option<Secret<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct RedirectRequest {
|
||||||
|
name: Secret<String>,
|
||||||
|
country_code: api_models::enums::CountryCode,
|
||||||
|
experience_context: ContextStruct,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct ContextStruct {
|
||||||
|
return_url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct PaypalRedirectionRequest {
|
||||||
|
experience_context: ContextStruct,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum PaymentSourceItem {
|
pub enum PaymentSourceItem {
|
||||||
Card(CardRequest),
|
Card(CardRequest),
|
||||||
|
Paypal(PaypalRedirectionRequest),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
@ -111,6 +130,35 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaypalPaymentsRequest {
|
|||||||
payment_source,
|
payment_source,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
api::PaymentMethodData::Wallet(ref wallet_data) => match wallet_data {
|
||||||
|
api_models::payments::WalletData::PaypalRedirect(_) => {
|
||||||
|
let intent = PaypalPaymentIntent::Capture;
|
||||||
|
let amount = OrderAmount {
|
||||||
|
currency_code: item.request.currency,
|
||||||
|
value: item.request.amount.to_string(),
|
||||||
|
};
|
||||||
|
let reference_id = item.attempt_id.clone();
|
||||||
|
let purchase_units = vec![PurchaseUnitRequest {
|
||||||
|
reference_id,
|
||||||
|
amount,
|
||||||
|
}];
|
||||||
|
let payment_source =
|
||||||
|
Some(PaymentSourceItem::Paypal(PaypalRedirectionRequest {
|
||||||
|
experience_context: ContextStruct {
|
||||||
|
return_url: item.request.complete_authorize_url.clone(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
intent,
|
||||||
|
purchase_units,
|
||||||
|
payment_source,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => Err(errors::ConnectorError::NotImplemented(
|
||||||
|
"Payment Method".to_string(),
|
||||||
|
))?,
|
||||||
|
},
|
||||||
_ => Err(errors::ConnectorError::NotImplemented("Payment Method".to_string()).into()),
|
_ => Err(errors::ConnectorError::NotImplemented("Payment Method".to_string()).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,10 +246,9 @@ impl ForeignFrom<(PaypalOrderStatus, PaypalPaymentIntent)> for storage_enums::At
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaypalOrderStatus::Voided => Self::Voided,
|
PaypalOrderStatus::Voided => Self::Voided,
|
||||||
PaypalOrderStatus::Created | PaypalOrderStatus::Saved | PaypalOrderStatus::Approved => {
|
PaypalOrderStatus::Created | PaypalOrderStatus::Saved => Self::Pending,
|
||||||
Self::Pending
|
PaypalOrderStatus::Approved => Self::AuthenticationSuccessful,
|
||||||
}
|
PaypalOrderStatus::PayerActionRequired => Self::AuthenticationPending,
|
||||||
PaypalOrderStatus::PayerActionRequired => Self::Authorizing,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,6 +282,20 @@ pub struct PaypalOrdersResponse {
|
|||||||
purchase_units: Vec<PurchaseUnitItem>,
|
purchase_units: Vec<PurchaseUnitItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PaypalLinks {
|
||||||
|
href: Option<Url>,
|
||||||
|
rel: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PaypalRedirectResponse {
|
||||||
|
id: String,
|
||||||
|
intent: PaypalPaymentIntent,
|
||||||
|
status: PaypalOrderStatus,
|
||||||
|
links: Vec<PaypalLinks>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct PaypalPaymentsSyncResponse {
|
pub struct PaypalPaymentsSyncResponse {
|
||||||
id: String,
|
id: String,
|
||||||
@ -312,11 +373,13 @@ impl<F, T>
|
|||||||
types::ResponseId::NoResponseId,
|
types::ResponseId::NoResponseId,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
let status = storage_enums::AttemptStatus::foreign_from((
|
||||||
|
item.response.status,
|
||||||
|
item.response.intent,
|
||||||
|
));
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
status: storage_enums::AttemptStatus::foreign_from((
|
status,
|
||||||
item.response.status,
|
|
||||||
item.response.intent,
|
|
||||||
)),
|
|
||||||
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||||
resource_id: capture_id,
|
resource_id: capture_id,
|
||||||
redirection_data: None,
|
redirection_data: None,
|
||||||
@ -328,6 +391,54 @@ impl<F, T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_redirect_url(
|
||||||
|
item: PaypalRedirectResponse,
|
||||||
|
) -> CustomResult<Option<Url>, errors::ConnectorError> {
|
||||||
|
let mut link: Option<Url> = None;
|
||||||
|
let link_vec = item.links;
|
||||||
|
for item2 in link_vec.iter() {
|
||||||
|
if item2.rel == "payer-action" {
|
||||||
|
link = item2.href.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(link)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, T>
|
||||||
|
TryFrom<types::ResponseRouterData<F, PaypalRedirectResponse, T, types::PaymentsResponseData>>
|
||||||
|
for types::RouterData<F, T, types::PaymentsResponseData>
|
||||||
|
{
|
||||||
|
type Error = error_stack::Report<errors::ConnectorError>;
|
||||||
|
fn try_from(
|
||||||
|
item: types::ResponseRouterData<F, PaypalRedirectResponse, T, types::PaymentsResponseData>,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
let status = storage_enums::AttemptStatus::foreign_from((
|
||||||
|
item.response.clone().status,
|
||||||
|
item.response.intent.clone(),
|
||||||
|
));
|
||||||
|
let link = get_redirect_url(item.response.clone())?;
|
||||||
|
let connector_meta = serde_json::json!(PaypalMeta {
|
||||||
|
authorize_id: None,
|
||||||
|
order_id: item.response.id,
|
||||||
|
psync_flow: item.response.intent
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
status,
|
||||||
|
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||||
|
resource_id: types::ResponseId::NoResponseId,
|
||||||
|
redirection_data: Some(services::RedirectForm::from((
|
||||||
|
link.ok_or(errors::ConnectorError::ResponseDeserializationFailed)?,
|
||||||
|
services::Method::Get,
|
||||||
|
))),
|
||||||
|
mandate_reference: None,
|
||||||
|
connector_metadata: Some(connector_meta),
|
||||||
|
}),
|
||||||
|
..item.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F, T>
|
impl<F, T>
|
||||||
TryFrom<
|
TryFrom<
|
||||||
types::ResponseRouterData<F, PaypalPaymentsSyncResponse, T, types::PaymentsResponseData>,
|
types::ResponseRouterData<F, PaypalPaymentsSyncResponse, T, types::PaymentsResponseData>,
|
||||||
|
|||||||
@ -568,7 +568,12 @@ impl api::ConnectorTransactionId for Paypal {
|
|||||||
&self,
|
&self,
|
||||||
payment_attempt: storage::PaymentAttempt,
|
payment_attempt: storage::PaymentAttempt,
|
||||||
) -> Result<Option<String>, errors::ApiErrorResponse> {
|
) -> Result<Option<String>, errors::ApiErrorResponse> {
|
||||||
let metadata = Self::connector_transaction_id(self, &payment_attempt.connector_metadata);
|
let payment_method = payment_attempt.payment_method;
|
||||||
|
let metadata = Self::connector_transaction_id(
|
||||||
|
self,
|
||||||
|
payment_method,
|
||||||
|
&payment_attempt.connector_metadata,
|
||||||
|
);
|
||||||
match metadata {
|
match metadata {
|
||||||
Ok(data) => Ok(data),
|
Ok(data) => Ok(data),
|
||||||
_ => Err(errors::ApiErrorResponse::ResourceIdNotFound),
|
_ => Err(errors::ApiErrorResponse::ResourceIdNotFound),
|
||||||
@ -577,7 +582,7 @@ impl api::ConnectorTransactionId for Paypal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCaptureData {
|
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCaptureData {
|
||||||
type Error = errors::ApiErrorResponse;
|
type Error = error_stack::Report<errors::ApiErrorResponse>;
|
||||||
|
|
||||||
fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
|
fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
|
||||||
let payment_data = additional_data.payment_data;
|
let payment_data = additional_data.payment_data;
|
||||||
@ -585,12 +590,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCaptureD
|
|||||||
&additional_data.state.conf.connectors,
|
&additional_data.state.conf.connectors,
|
||||||
&additional_data.connector_name,
|
&additional_data.connector_name,
|
||||||
api::GetToken::Connector,
|
api::GetToken::Connector,
|
||||||
);
|
)?;
|
||||||
let connectors = match connector {
|
|
||||||
Ok(conn) => *conn.connector,
|
|
||||||
_ => Err(errors::ApiErrorResponse::ResourceIdNotFound)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
let amount_to_capture: i64 = payment_data
|
let amount_to_capture: i64 = payment_data
|
||||||
.payment_attempt
|
.payment_attempt
|
||||||
.amount_to_capture
|
.amount_to_capture
|
||||||
@ -598,7 +598,8 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCaptureD
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
amount_to_capture,
|
amount_to_capture,
|
||||||
currency: payment_data.currency,
|
currency: payment_data.currency,
|
||||||
connector_transaction_id: connectors
|
connector_transaction_id: connector
|
||||||
|
.connector
|
||||||
.connector_transaction_id(payment_data.payment_attempt.clone())?
|
.connector_transaction_id(payment_data.payment_attempt.clone())?
|
||||||
.ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?,
|
.ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?,
|
||||||
payment_amount: payment_data.amount.into(),
|
payment_amount: payment_data.amount.into(),
|
||||||
@ -608,7 +609,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCaptureD
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCancelData {
|
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCancelData {
|
||||||
type Error = errors::ApiErrorResponse;
|
type Error = error_stack::Report<errors::ApiErrorResponse>;
|
||||||
|
|
||||||
fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
|
fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
|
||||||
let payment_data = additional_data.payment_data;
|
let payment_data = additional_data.payment_data;
|
||||||
@ -616,15 +617,12 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsCancelDa
|
|||||||
&additional_data.state.conf.connectors,
|
&additional_data.state.conf.connectors,
|
||||||
&additional_data.connector_name,
|
&additional_data.connector_name,
|
||||||
api::GetToken::Connector,
|
api::GetToken::Connector,
|
||||||
);
|
)?;
|
||||||
let connectors = match connector {
|
|
||||||
Ok(conn) => *conn.connector,
|
|
||||||
_ => Err(errors::ApiErrorResponse::ResourceIdNotFound)?,
|
|
||||||
};
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
amount: Some(payment_data.amount.into()),
|
amount: Some(payment_data.amount.into()),
|
||||||
currency: Some(payment_data.currency),
|
currency: Some(payment_data.currency),
|
||||||
connector_transaction_id: connectors
|
connector_transaction_id: connector
|
||||||
|
.connector
|
||||||
.connector_transaction_id(payment_data.payment_attempt.clone())?
|
.connector_transaction_id(payment_data.payment_attempt.clone())?
|
||||||
.ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?,
|
.ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?,
|
||||||
cancellation_reason: payment_data.payment_attempt.cancellation_reason,
|
cancellation_reason: payment_data.payment_attempt.cancellation_reason,
|
||||||
@ -693,6 +691,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::CompleteAuthoriz
|
|||||||
let browser_info: Option<types::BrowserInformation> = payment_data
|
let browser_info: Option<types::BrowserInformation> = payment_data
|
||||||
.payment_attempt
|
.payment_attempt
|
||||||
.browser_info
|
.browser_info
|
||||||
|
.clone()
|
||||||
.map(|b| b.parse_value("BrowserInformation"))
|
.map(|b| b.parse_value("BrowserInformation"))
|
||||||
.transpose()
|
.transpose()
|
||||||
.change_context(errors::ApiErrorResponse::InvalidDataValue {
|
.change_context(errors::ApiErrorResponse::InvalidDataValue {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ function find_prev_connector() {
|
|||||||
git checkout $self
|
git checkout $self
|
||||||
cp $self $self.tmp
|
cp $self $self.tmp
|
||||||
# add new connector to existing list and sort it
|
# add new connector to existing list and sort it
|
||||||
connectors=(aci adyen airwallex applepay authorizedotnet bambora bluesnap braintree checkout coinbase cybersource dlocal fiserv forte globalpay klarna mollie multisafepay nexinets nuvei opennode payeezy payu rapyd shift4 stripe trustpay worldline worldpay "$1")
|
connectors=(aci adyen airwallex applepay authorizedotnet bambora bluesnap braintree checkout coinbase cybersource dlocal fiserv forte globalpay klarna mollie multisafepay nexinets nuvei opennode paypal payeezy payu rapyd shift4 stripe trustpay worldline worldpay "$1")
|
||||||
IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS
|
IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS
|
||||||
res=`echo ${sorted[@]}`
|
res=`echo ${sorted[@]}`
|
||||||
sed -i'' -e "s/^ connectors=.*/ connectors=($res \"\$1\")/" $self.tmp
|
sed -i'' -e "s/^ connectors=.*/ connectors=($res \"\$1\")/" $self.tmp
|
||||||
|
|||||||
Reference in New Issue
Block a user