Skip to content

Commit d8fcd3c

Browse files
swangi-kumariThisIsManigithub-actions[bot]
authored
refactor(connector): [Paypal] Add support for both BodyKey and SignatureKey (#2633)
Co-authored-by: Mani Chandra Dulam <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Mani Chandra <[email protected]>
1 parent 938b63a commit d8fcd3c

File tree

2 files changed

+325
-56
lines changed

2 files changed

+325
-56
lines changed

crates/router/src/connector/paypal.rs

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use base64::Engine;
55
use common_utils::ext_traits::ByteSliceExt;
66
use diesel_models::enums;
77
use error_stack::{IntoReport, ResultExt};
8-
use masking::PeekInterface;
8+
use masking::{ExposeInterface, PeekInterface, Secret};
99
use transformers as paypal;
1010

11-
use self::transformers::{PaypalAuthResponse, PaypalMeta, PaypalWebhookEventType};
11+
use self::transformers::{auth_headers, PaypalAuthResponse, PaypalMeta, PaypalWebhookEventType};
1212
use super::utils::PaymentsCompleteAuthorizeRequestData;
1313
use crate::{
1414
configs::settings,
@@ -31,7 +31,7 @@ use crate::{
3131
self,
3232
api::{self, CompleteAuthorize, ConnectorCommon, ConnectorCommonExt, VerifyWebhookSource},
3333
transformers::ForeignFrom,
34-
ErrorResponse, Response,
34+
ConnectorAuthType, ErrorResponse, Response,
3535
},
3636
utils::{self, BytesExt},
3737
};
@@ -110,8 +110,8 @@ where
110110
.clone()
111111
.ok_or(errors::ConnectorError::FailedToObtainAuthType)?;
112112
let key = &req.attempt_id;
113-
114-
Ok(vec![
113+
let auth = paypal::PaypalAuthType::try_from(&req.connector_auth_type)?;
114+
let mut headers = vec![
115115
(
116116
headers::CONTENT_TYPE.to_string(),
117117
self.get_content_type().to_string().into(),
@@ -121,17 +121,57 @@ where
121121
format!("Bearer {}", access_token.token.peek()).into_masked(),
122122
),
123123
(
124-
"Prefer".to_string(),
124+
auth_headers::PREFER.to_string(),
125125
"return=representation".to_string().into(),
126126
),
127127
(
128-
"PayPal-Request-Id".to_string(),
128+
auth_headers::PAYPAL_REQUEST_ID.to_string(),
129129
key.to_string().into_masked(),
130130
),
131-
])
131+
];
132+
if let Ok(paypal::PaypalConnectorCredentials::PartnerIntegration(credentials)) =
133+
auth.get_credentials()
134+
{
135+
let auth_assertion_header =
136+
construct_auth_assertion_header(&credentials.payer_id, &credentials.client_id);
137+
headers.extend(vec![
138+
(
139+
auth_headers::PAYPAL_AUTH_ASSERTION.to_string(),
140+
auth_assertion_header.to_string().into_masked(),
141+
),
142+
(
143+
auth_headers::PAYPAL_PARTNER_ATTRIBUTION_ID.to_string(),
144+
"HyperSwitchPPCP_SP".to_string().into(),
145+
),
146+
])
147+
} else {
148+
headers.extend(vec![(
149+
auth_headers::PAYPAL_PARTNER_ATTRIBUTION_ID.to_string(),
150+
"HyperSwitchlegacy_Ecom".to_string().into(),
151+
)])
152+
}
153+
Ok(headers)
132154
}
133155
}
134156

157+
fn construct_auth_assertion_header(
158+
payer_id: &Secret<String>,
159+
client_id: &Secret<String>,
160+
) -> String {
161+
let algorithm = consts::BASE64_ENGINE
162+
.encode("{\"alg\":\"none\"}")
163+
.to_string();
164+
let merchant_credentials = format!(
165+
"{{\"iss\":\"{}\",\"payer_id\":\"{}\"}}",
166+
client_id.clone().expose(),
167+
payer_id.clone().expose()
168+
);
169+
let encoded_credentials = consts::BASE64_ENGINE
170+
.encode(merchant_credentials)
171+
.to_string();
172+
format!("{algorithm}.{encoded_credentials}.")
173+
}
174+
135175
impl ConnectorCommon for Paypal {
136176
fn id(&self) -> &'static str {
137177
"paypal"
@@ -151,14 +191,14 @@ impl ConnectorCommon for Paypal {
151191

152192
fn get_auth_header(
153193
&self,
154-
auth_type: &types::ConnectorAuthType,
194+
auth_type: &ConnectorAuthType,
155195
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
156-
let auth: paypal::PaypalAuthType = auth_type
157-
.try_into()
158-
.change_context(errors::ConnectorError::FailedToObtainAuthType)?;
196+
let auth = paypal::PaypalAuthType::try_from(auth_type)?;
197+
let credentials = auth.get_credentials()?;
198+
159199
Ok(vec![(
160200
headers::AUTHORIZATION.to_string(),
161-
auth.api_key.into_masked(),
201+
credentials.get_client_secret().into_masked(),
162202
)])
163203
}
164204

@@ -260,15 +300,9 @@ impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, t
260300
req: &types::RefreshTokenRouterData,
261301
_connectors: &settings::Connectors,
262302
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
263-
let auth: paypal::PaypalAuthType = (&req.connector_auth_type)
264-
.try_into()
265-
.change_context(errors::ConnectorError::FailedToObtainAuthType)?;
266-
267-
let auth_id = auth
268-
.key1
269-
.zip(auth.api_key)
270-
.map(|(key1, api_key)| format!("{}:{}", key1, api_key));
271-
let auth_val = format!("Basic {}", consts::BASE64_ENGINE.encode(auth_id.peek()));
303+
let auth = paypal::PaypalAuthType::try_from(&req.connector_auth_type)?;
304+
let credentials = auth.get_credentials()?;
305+
let auth_val = credentials.generate_authorization_value();
272306

273307
Ok(vec![
274308
(
@@ -998,15 +1032,9 @@ impl
9981032
>,
9991033
_connectors: &settings::Connectors,
10001034
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
1001-
let auth: paypal::PaypalAuthType = (&req.connector_auth_type)
1002-
.try_into()
1003-
.change_context(errors::ConnectorError::FailedToObtainAuthType)?;
1004-
1005-
let auth_id = auth
1006-
.key1
1007-
.zip(auth.api_key)
1008-
.map(|(key1, api_key)| format!("{}:{}", key1, api_key));
1009-
let auth_val = format!("Basic {}", consts::BASE64_ENGINE.encode(auth_id.peek()));
1035+
let auth = paypal::PaypalAuthType::try_from(&req.connector_auth_type)?;
1036+
let credentials = auth.get_credentials()?;
1037+
let auth_val = credentials.generate_authorization_value();
10101038

10111039
Ok(vec![
10121040
(

0 commit comments

Comments
 (0)