Skip to content

Commit 1fab8aa

Browse files
committed
Merge branch 'main' of github.com:juspay/hyperswitch into refactor-add-memory-cache
* 'main' of github.com:juspay/hyperswitch: feat(connector): [Novalnet] Add zero auth mandate (#6631) feat(router): add support for relay refund incoming webhooks (#6974) chore(version): 2025.01.10.0
2 parents 7e77c1c + 7b306a9 commit 1fab8aa

File tree

27 files changed

+968
-121
lines changed

27 files changed

+968
-121
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ All notable changes to HyperSwitch will be documented here.
44

55
- - -
66

7+
## 2025.01.10.0
8+
9+
### Testing
10+
11+
- **cypress:** Add test for In Memory Cache ([#6961](https://github.com/juspay/hyperswitch/pull/6961)) ([`d8d8c40`](https://github.com/juspay/hyperswitch/commit/d8d8c400bbda49b9a0cd5edbe37e929ae6d38eb4))
12+
13+
**Full Changelog:** [`2025.01.09.1...2025.01.10.0`](https://github.com/juspay/hyperswitch/compare/2025.01.09.1...2025.01.10.0)
14+
15+
- - -
16+
717
## 2025.01.09.1
818

919
### Bug Fixes

crates/api_models/src/webhooks.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ pub enum WebhookResponseTracker {
120120
status: common_enums::MandateStatus,
121121
},
122122
NoEffect,
123+
Relay {
124+
relay_id: common_utils::id_type::RelayId,
125+
status: common_enums::RelayStatus,
126+
},
123127
}
124128

125129
impl WebhookResponseTracker {
@@ -132,6 +136,7 @@ impl WebhookResponseTracker {
132136
Self::NoEffect | Self::Mandate { .. } => None,
133137
#[cfg(feature = "payouts")]
134138
Self::Payout { .. } => None,
139+
Self::Relay { .. } => None,
135140
}
136141
}
137142

@@ -144,6 +149,7 @@ impl WebhookResponseTracker {
144149
Self::NoEffect | Self::Mandate { .. } => None,
145150
#[cfg(feature = "payouts")]
146151
Self::Payout { .. } => None,
152+
Self::Relay { .. } => None,
147153
}
148154
}
149155
}

crates/common_utils/src/id_type/relay.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::str::FromStr;
2+
13
crate::id_type!(
24
RelayId,
35
"A type for relay_id that can be used for relay ids"
@@ -11,3 +13,12 @@ crate::impl_queryable_id_type!(RelayId);
1113
crate::impl_to_sql_from_sql_id_type!(RelayId);
1214

1315
crate::impl_debug_id_type!(RelayId);
16+
17+
impl FromStr for RelayId {
18+
type Err = error_stack::Report<crate::errors::ValidationError>;
19+
20+
fn from_str(s: &str) -> Result<Self, Self::Err> {
21+
let cow_string = std::borrow::Cow::Owned(s.to_string());
22+
Self::try_from(cow_string)
23+
}
24+
}

crates/diesel_models/src/query/relay.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use diesel::{associations::HasTable, ExpressionMethods};
1+
use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};
22

33
use super::generics;
44
use crate::{
@@ -46,4 +46,18 @@ impl Relay {
4646
)
4747
.await
4848
}
49+
50+
pub async fn find_by_profile_id_connector_reference_id(
51+
conn: &PgPooledConn,
52+
profile_id: &common_utils::id_type::ProfileId,
53+
connector_reference_id: &str,
54+
) -> StorageResult<Self> {
55+
generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
56+
conn,
57+
dsl::profile_id
58+
.eq(profile_id.to_owned())
59+
.and(dsl::connector_reference_id.eq(connector_reference_id.to_owned())),
60+
)
61+
.await
62+
}
4963
}

crates/hyperswitch_connectors/src/connectors/novalnet.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use hyperswitch_domain_models::{
2828
router_response_types::{PaymentsResponseData, RefundsResponseData},
2929
types::{
3030
PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
31-
PaymentsSyncRouterData, RefundSyncRouterData, RefundsRouterData,
31+
PaymentsSyncRouterData, RefundSyncRouterData, RefundsRouterData, SetupMandateRouterData,
3232
},
3333
};
3434
use hyperswitch_interfaces::{
@@ -231,6 +231,79 @@ impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken>
231231
impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
232232
for Novalnet
233233
{
234+
fn get_headers(
235+
&self,
236+
req: &SetupMandateRouterData,
237+
connectors: &Connectors,
238+
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
239+
self.build_headers(req, connectors)
240+
}
241+
242+
fn get_content_type(&self) -> &'static str {
243+
self.common_get_content_type()
244+
}
245+
246+
fn get_url(
247+
&self,
248+
_req: &SetupMandateRouterData,
249+
connectors: &Connectors,
250+
) -> CustomResult<String, errors::ConnectorError> {
251+
let endpoint = self.base_url(connectors);
252+
Ok(format!("{}/payment", endpoint))
253+
}
254+
255+
fn get_request_body(
256+
&self,
257+
req: &SetupMandateRouterData,
258+
_connectors: &Connectors,
259+
) -> CustomResult<RequestContent, errors::ConnectorError> {
260+
let connector_req = novalnet::NovalnetPaymentsRequest::try_from(req)?;
261+
Ok(RequestContent::Json(Box::new(connector_req)))
262+
}
263+
264+
fn build_request(
265+
&self,
266+
req: &SetupMandateRouterData,
267+
connectors: &Connectors,
268+
) -> CustomResult<Option<Request>, errors::ConnectorError> {
269+
Ok(Some(
270+
RequestBuilder::new()
271+
.method(Method::Post)
272+
.url(&types::SetupMandateType::get_url(self, req, connectors)?)
273+
.attach_default_headers()
274+
.headers(types::SetupMandateType::get_headers(self, req, connectors)?)
275+
.set_body(types::SetupMandateType::get_request_body(
276+
self, req, connectors,
277+
)?)
278+
.build(),
279+
))
280+
}
281+
282+
fn handle_response(
283+
&self,
284+
data: &SetupMandateRouterData,
285+
event_builder: Option<&mut ConnectorEvent>,
286+
res: Response,
287+
) -> CustomResult<SetupMandateRouterData, errors::ConnectorError> {
288+
let response: novalnet::NovalnetPaymentsResponse = res
289+
.response
290+
.parse_struct("Novalnet PaymentsAuthorizeResponse")
291+
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
292+
event_builder.map(|i| i.set_response_body(&response));
293+
router_env::logger::info!(connector_response=?response);
294+
RouterData::try_from(ResponseRouterData {
295+
response,
296+
data: data.clone(),
297+
http_code: res.status_code,
298+
})
299+
}
300+
fn get_error_response(
301+
&self,
302+
res: Response,
303+
event_builder: Option<&mut ConnectorEvent>,
304+
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
305+
self.build_error_response(res, event_builder)
306+
}
234307
}
235308

236309
impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData> for Novalnet {

0 commit comments

Comments
 (0)