Skip to content

Commit a02c7da

Browse files
committed
Merge remote-tracking branch 'origin/main' into 6969-feature-expose-tokenize-endpoints
2 parents 67e79d5 + 9f334c1 commit a02c7da

File tree

54 files changed

+1804
-556
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1804
-556
lines changed

.github/workflows/cypress-tests-runner.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ jobs:
128128
CONNECTOR_AUTH_PASSPHRASE: ${{ secrets.CONNECTOR_AUTH_PASSPHRASE }}
129129
CONNECTOR_CREDS_S3_BUCKET_URI: ${{ secrets.CONNECTOR_CREDS_S3_BUCKET_URI}}
130130
DESTINATION_FILE_NAME: "creds.json.gpg"
131-
S3_SOURCE_FILE_NAME: "5b3ebdad-1067-421b-83e5-3ceb73c3eeeb.json.gpg"
131+
S3_SOURCE_FILE_NAME: "57a07166-894a-4f43-b4b5-ee1155138ec9.json.gpg"
132132
shell: bash
133133
run: |
134134
mkdir -p ".github/secrets" ".github/test"

CHANGELOG.md

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

55
- - -
66

7+
## 2025.02.24.0
8+
9+
### Features
10+
11+
- **connector:**
12+
- Add Samsung pay mandate support for Cybersource ([#7298](https://github.com/juspay/hyperswitch/pull/7298)) ([`9bc8fd4`](https://github.com/juspay/hyperswitch/commit/9bc8fd4d8c4be1b54050398dfb3b574e924e4b5f))
13+
- Add support for passive churn recovery webhooks ([#7109](https://github.com/juspay/hyperswitch/pull/7109)) ([`0688972`](https://github.com/juspay/hyperswitch/commit/0688972814cf03edbff4bf125a59c338a7e49593))
14+
- **router:** Add `merchant_configuration_id` in netcetera metadata and make other merchant configurations optional ([#7347](https://github.com/juspay/hyperswitch/pull/7347)) ([`57ab869`](https://github.com/juspay/hyperswitch/commit/57ab8693e26a54cd5fe73b28459c9b03235e5d5b))
15+
- **samsung_pay:** Collect customer address details form Samsung Pay based on business profile config and connector required fields ([#7320](https://github.com/juspay/hyperswitch/pull/7320)) ([`c14519e`](https://github.com/juspay/hyperswitch/commit/c14519ebd958abc79879244f8180686b2be30d31))
16+
17+
### Bug Fixes
18+
19+
- **connector:** [DATATRANS] Fix Force Sync Flow ([#7331](https://github.com/juspay/hyperswitch/pull/7331)) ([`0e96e24`](https://github.com/juspay/hyperswitch/commit/0e96e2470c6906fe77b35c14821e3ebcfa454e39))
20+
- **routing:** Fixed 5xx error logs in dynamic routing metrics ([#7335](https://github.com/juspay/hyperswitch/pull/7335)) ([`049fcdb`](https://github.com/juspay/hyperswitch/commit/049fcdb3fb19c6af45392a5ef3a0cbf642598af8))
21+
- **samsung_pay:** Add payment_method_type duplication check ([#7337](https://github.com/juspay/hyperswitch/pull/7337)) ([`11ff437`](https://github.com/juspay/hyperswitch/commit/11ff437456f9d97205ce07e4d4df63006f3ad0c6))
22+
23+
### Miscellaneous Tasks
24+
25+
- **masking:** Add peek_mut to PeekInterface ([#7281](https://github.com/juspay/hyperswitch/pull/7281)) ([`890a265`](https://github.com/juspay/hyperswitch/commit/890a265e7b1b06aeea100994efbebe3ce898a125))
26+
27+
**Full Changelog:** [`2025.02.21.0...2025.02.24.0`](https://github.com/juspay/hyperswitch/compare/2025.02.21.0...2025.02.24.0)
28+
29+
- - -
30+
731
## 2025.02.21.0
832

933
### Features

api-reference-v2/openapi_spec.json

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13481,6 +13481,19 @@
1348113481
}
1348213482
}
1348313483
},
13484+
"PaymentAttemptFeatureMetadata": {
13485+
"type": "object",
13486+
"properties": {
13487+
"revenue_recovery": {
13488+
"allOf": [
13489+
{
13490+
"$ref": "#/components/schemas/PaymentAttemptRevenueRecoveryData"
13491+
}
13492+
],
13493+
"nullable": true
13494+
}
13495+
}
13496+
},
1348413497
"PaymentAttemptResponse": {
1348513498
"type": "object",
1348613499
"required": [
@@ -13489,7 +13502,8 @@
1348913502
"amount",
1349013503
"authentication_type",
1349113504
"created_at",
13492-
"modified_at"
13505+
"modified_at",
13506+
"connector_payment_id"
1349313507
],
1349413508
"properties": {
1349513509
"id": {
@@ -13585,9 +13599,7 @@
1358513599
},
1358613600
"connector_payment_id": {
1358713601
"type": "string",
13588-
"description": "A unique identifier for a payment provided by the connector",
13589-
"example": "993672945374576J",
13590-
"nullable": true
13602+
"description": "A unique identifier for a payment provided by the connector"
1359113603
},
1359213604
"payment_method_id": {
1359313605
"type": "string",
@@ -13604,6 +13616,27 @@
1360413616
"type": "string",
1360513617
"description": "Value passed in X-CLIENT-VERSION header during payments confirm request by the client",
1360613618
"nullable": true
13619+
},
13620+
"feature_metadata": {
13621+
"allOf": [
13622+
{
13623+
"$ref": "#/components/schemas/PaymentAttemptFeatureMetadata"
13624+
}
13625+
],
13626+
"nullable": true
13627+
}
13628+
}
13629+
},
13630+
"PaymentAttemptRevenueRecoveryData": {
13631+
"type": "object",
13632+
"properties": {
13633+
"attempt_triggered_by": {
13634+
"allOf": [
13635+
{
13636+
"$ref": "#/components/schemas/TriggeredBy"
13637+
}
13638+
],
13639+
"nullable": true
1360713640
}
1360813641
}
1360913642
},
@@ -20372,7 +20405,9 @@
2037220405
"merchant",
2037320406
"amount",
2037420407
"protocol",
20375-
"allowed_brands"
20408+
"allowed_brands",
20409+
"billing_address_required",
20410+
"shipping_address_required"
2037620411
],
2037720412
"properties": {
2037820413
"version": {
@@ -20402,6 +20437,14 @@
2040220437
"type": "string"
2040320438
},
2040420439
"description": "List of supported card brands"
20440+
},
20441+
"billing_address_required": {
20442+
"type": "boolean",
20443+
"description": "Is billing address required to be collected from wallet"
20444+
},
20445+
"shipping_address_required": {
20446+
"type": "boolean",
20447+
"description": "Is shipping address required to be collected from wallet"
2040520448
}
2040620449
}
2040720450
},
@@ -21707,6 +21750,13 @@
2170721750
"payout"
2170821751
]
2170921752
},
21753+
"TriggeredBy": {
21754+
"type": "string",
21755+
"enum": [
21756+
"internal",
21757+
"external"
21758+
]
21759+
},
2171021760
"UIWidgetFormLayout": {
2171121761
"type": "string",
2171221762
"enum": [

api-reference/openapi_spec.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24951,7 +24951,9 @@
2495124951
"merchant",
2495224952
"amount",
2495324953
"protocol",
24954-
"allowed_brands"
24954+
"allowed_brands",
24955+
"billing_address_required",
24956+
"shipping_address_required"
2495524957
],
2495624958
"properties": {
2495724959
"version": {
@@ -24981,6 +24983,14 @@
2498124983
"type": "string"
2498224984
},
2498324985
"description": "List of supported card brands"
24986+
},
24987+
"billing_address_required": {
24988+
"type": "boolean",
24989+
"description": "Is billing address required to be collected from wallet"
24990+
},
24991+
"shipping_address_required": {
24992+
"type": "boolean",
24993+
"description": "Is shipping address required to be collected from wallet"
2498424994
}
2498524995
}
2498624996
},
@@ -26332,6 +26342,13 @@
2633226342
"payout"
2633326343
]
2633426344
},
26345+
"TriggeredBy": {
26346+
"type": "string",
26347+
"enum": [
26348+
"internal",
26349+
"external"
26350+
]
26351+
},
2633526352
"UIWidgetFormLayout": {
2633626353
"type": "string",
2633726354
"enum": [

crates/api_models/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ customer_v2 = ["common_utils/customer_v2"]
2222
payment_methods_v2 = ["common_utils/payment_methods_v2"]
2323
dynamic_routing = []
2424
control_center_theme = ["dep:actix-web", "dep:actix-multipart"]
25+
revenue_recovery = []
2526

2627
[dependencies]
2728
actix-multipart = { version = "0.6.1", optional = true }

crates/api_models/src/payments.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,8 +1511,8 @@ pub struct PaymentAttemptResponse {
15111511
pub payment_method_subtype: Option<api_enums::PaymentMethodType>,
15121512

15131513
/// A unique identifier for a payment provided by the connector
1514-
#[schema(value_type = Option<String>, example = "993672945374576J")]
1515-
pub connector_payment_id: Option<String>,
1514+
#[schema(value_type = String)]
1515+
pub connector_payment_id: Option<common_utils::types::ConnectorTransactionId>,
15161516

15171517
/// Identifier for Payment Method used for the payment attempt
15181518
#[schema(value_type = Option<String>, example = "12345_pm_01926c58bc6e77c09e809964e72af8c8")]
@@ -1522,6 +1522,24 @@ pub struct PaymentAttemptResponse {
15221522
pub client_source: Option<String>,
15231523
/// Value passed in X-CLIENT-VERSION header during payments confirm request by the client
15241524
pub client_version: Option<String>,
1525+
1526+
/// Additional data that might be required by hyperswitch, to enable some specific features.
1527+
pub feature_metadata: Option<PaymentAttemptFeatureMetadata>,
1528+
}
1529+
1530+
#[cfg(feature = "v2")]
1531+
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)]
1532+
pub struct PaymentAttemptFeatureMetadata {
1533+
/// Revenue recovery metadata that might be required by hyperswitch.
1534+
pub revenue_recovery: Option<PaymentAttemptRevenueRecoveryData>,
1535+
}
1536+
1537+
#[cfg(feature = "v2")]
1538+
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)]
1539+
pub struct PaymentAttemptRevenueRecoveryData {
1540+
/// Flag to find out whether an attempt was created by external or internal system.
1541+
#[schema(value_type = Option<TriggeredBy>, example = "internal")]
1542+
pub attempt_triggered_by: common_enums::TriggeredBy,
15251543
}
15261544

15271545
#[derive(
@@ -5563,6 +5581,26 @@ pub struct PaymentsRetrieveResponse {
55635581
pub attempts: Option<Vec<PaymentAttemptResponse>>,
55645582
}
55655583

5584+
#[cfg(feature = "v2")]
5585+
impl PaymentsRetrieveResponse {
5586+
pub fn find_attempt_in_attempts_list_using_connector_transaction_id(
5587+
self,
5588+
connector_transaction_id: &common_utils::types::ConnectorTransactionId,
5589+
) -> Option<PaymentAttemptResponse> {
5590+
self.attempts
5591+
.as_ref()
5592+
.and_then(|attempts| {
5593+
attempts.iter().find(|attempt| {
5594+
attempt
5595+
.connector_payment_id
5596+
.as_ref()
5597+
.is_some_and(|txn_id| txn_id == connector_transaction_id)
5598+
})
5599+
})
5600+
.cloned()
5601+
}
5602+
}
5603+
55665604
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
55675605
#[cfg(feature = "v2")]
55685606
pub struct PaymentStartRedirectionRequest {
@@ -6861,6 +6899,10 @@ pub struct SamsungPaySessionTokenResponse {
68616899
pub protocol: SamsungPayProtocolType,
68626900
/// List of supported card brands
68636901
pub allowed_brands: Vec<String>,
6902+
/// Is billing address required to be collected from wallet
6903+
pub billing_address_required: bool,
6904+
/// Is shipping address required to be collected from wallet
6905+
pub shipping_address_required: bool,
68646906
}
68656907

68666908
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, ToSchema)]

crates/api_models/src/webhooks.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ pub enum IncomingWebhookEvent {
5757
PayoutExpired,
5858
#[cfg(feature = "payouts")]
5959
PayoutReversed,
60+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
61+
RecoveryPaymentFailure,
62+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
63+
RecoveryPaymentSuccess,
64+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
65+
RecoveryPaymentPending,
66+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
67+
RecoveryInvoiceCancel,
6068
}
6169

6270
pub enum WebhookFlow {
@@ -71,6 +79,8 @@ pub enum WebhookFlow {
7179
Mandate,
7280
ExternalAuthentication,
7381
FraudCheck,
82+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
83+
Recovery,
7484
}
7585

7686
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
@@ -197,6 +207,11 @@ impl From<IncomingWebhookEvent> for WebhookFlow {
197207
| IncomingWebhookEvent::PayoutCreated
198208
| IncomingWebhookEvent::PayoutExpired
199209
| IncomingWebhookEvent::PayoutReversed => Self::Payout,
210+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
211+
IncomingWebhookEvent::RecoveryInvoiceCancel
212+
| IncomingWebhookEvent::RecoveryPaymentFailure
213+
| IncomingWebhookEvent::RecoveryPaymentPending
214+
| IncomingWebhookEvent::RecoveryPaymentSuccess => Self::Recovery,
200215
}
201216
}
202217
}
@@ -236,6 +251,14 @@ pub enum ObjectReferenceId {
236251
ExternalAuthenticationID(AuthenticationIdType),
237252
#[cfg(feature = "payouts")]
238253
PayoutId(PayoutIdType),
254+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
255+
InvoiceId(InvoiceIdType),
256+
}
257+
258+
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
259+
#[derive(Clone)]
260+
pub enum InvoiceIdType {
261+
ConnectorInvoiceId(String),
239262
}
240263

241264
pub struct IncomingWebhookDetails {
@@ -303,3 +326,15 @@ pub struct ConnectorWebhookSecrets {
303326
pub secret: Vec<u8>,
304327
pub additional_secret: Option<masking::Secret<String>>,
305328
}
329+
330+
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
331+
impl IncomingWebhookEvent {
332+
pub fn is_recovery_transaction_event(&self) -> bool {
333+
matches!(
334+
self,
335+
Self::RecoveryPaymentFailure
336+
| Self::RecoveryPaymentSuccess
337+
| Self::RecoveryPaymentPending
338+
)
339+
}
340+
}

crates/common_enums/src/enums.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,12 @@ pub enum PaymentMethodType {
16511651
DirectCarrierBilling,
16521652
}
16531653

1654+
impl PaymentMethodType {
1655+
pub fn should_check_for_customer_saved_payment_method_type(self) -> bool {
1656+
matches!(self, Self::ApplePay | Self::GooglePay | Self::SamsungPay)
1657+
}
1658+
}
1659+
16541660
impl masking::SerializableSecret for PaymentMethodType {}
16551661

16561662
/// Indicates the type of payment method. Eg: 'card', 'wallet', etc.
@@ -7585,3 +7591,28 @@ pub enum PaymentConnectorTransmission {
75857591
/// Payment Connector call succeeded
75867592
ConnectorCallSucceeded,
75877593
}
7594+
7595+
#[derive(
7596+
Clone,
7597+
Copy,
7598+
Debug,
7599+
Default,
7600+
Eq,
7601+
Hash,
7602+
PartialEq,
7603+
serde::Deserialize,
7604+
serde::Serialize,
7605+
strum::Display,
7606+
strum::EnumString,
7607+
ToSchema,
7608+
)]
7609+
#[router_derive::diesel_enum(storage_type = "db_enum")]
7610+
#[strum(serialize_all = "snake_case")]
7611+
#[serde(rename_all = "snake_case")]
7612+
pub enum TriggeredBy {
7613+
/// Denotes payment attempt is been created by internal system.
7614+
#[default]
7615+
Internal,
7616+
/// Denotes payment attempt is been created by external system.
7617+
External,
7618+
}

0 commit comments

Comments
 (0)