Skip to content

Commit 2e13771

Browse files
feat(payment-methods): add filtering logic for payment method list v2 (#8606)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
1 parent b91e6d9 commit 2e13771

File tree

16 files changed

+616
-187
lines changed

16 files changed

+616
-187
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api-reference/v2/openapi_spec_v2.json

Lines changed: 75 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -12837,6 +12837,78 @@
1283712837
}
1283812838
}
1283912839
},
12840+
"ListMethodsForPaymentMethodsRequest": {
12841+
"type": "object",
12842+
"properties": {
12843+
"client_secret": {
12844+
"type": "string",
12845+
"description": "This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK",
12846+
"example": "secret_k2uj3he2893eiu2d",
12847+
"nullable": true,
12848+
"maxLength": 30,
12849+
"minLength": 30
12850+
},
12851+
"accepted_countries": {
12852+
"type": "array",
12853+
"items": {
12854+
"$ref": "#/components/schemas/CountryAlpha2"
12855+
},
12856+
"description": "The two-letter ISO currency code",
12857+
"example": [
12858+
"US",
12859+
"UK",
12860+
"IN"
12861+
],
12862+
"nullable": true
12863+
},
12864+
"amount": {
12865+
"allOf": [
12866+
{
12867+
"$ref": "#/components/schemas/MinorUnit"
12868+
}
12869+
],
12870+
"nullable": true
12871+
},
12872+
"accepted_currencies": {
12873+
"type": "array",
12874+
"items": {
12875+
"$ref": "#/components/schemas/Currency"
12876+
},
12877+
"description": "The three-letter ISO currency code",
12878+
"example": [
12879+
"USD",
12880+
"EUR"
12881+
],
12882+
"nullable": true
12883+
},
12884+
"recurring_enabled": {
12885+
"type": "boolean",
12886+
"description": "Indicates whether the payment method supports recurring payments. Optional.",
12887+
"example": true,
12888+
"nullable": true
12889+
},
12890+
"card_networks": {
12891+
"type": "array",
12892+
"items": {
12893+
"$ref": "#/components/schemas/CardNetwork"
12894+
},
12895+
"description": "Indicates whether the payment method is eligible for card netwotks",
12896+
"example": [
12897+
"visa",
12898+
"mastercard"
12899+
],
12900+
"nullable": true
12901+
},
12902+
"limit": {
12903+
"type": "integer",
12904+
"format": "int64",
12905+
"description": "Indicates the limit of last used payment methods",
12906+
"example": 1,
12907+
"nullable": true
12908+
}
12909+
},
12910+
"additionalProperties": false
12911+
},
1284012912
"LocalBankTransferAdditionalData": {
1284112913
"type": "object",
1284212914
"properties": {
@@ -17402,78 +17474,6 @@
1740217474
}
1740317475
]
1740417476
},
17405-
"PaymentMethodListRequest": {
17406-
"type": "object",
17407-
"properties": {
17408-
"client_secret": {
17409-
"type": "string",
17410-
"description": "This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK",
17411-
"example": "secret_k2uj3he2893eiu2d",
17412-
"nullable": true,
17413-
"maxLength": 30,
17414-
"minLength": 30
17415-
},
17416-
"accepted_countries": {
17417-
"type": "array",
17418-
"items": {
17419-
"$ref": "#/components/schemas/CountryAlpha2"
17420-
},
17421-
"description": "The two-letter ISO currency code",
17422-
"example": [
17423-
"US",
17424-
"UK",
17425-
"IN"
17426-
],
17427-
"nullable": true
17428-
},
17429-
"amount": {
17430-
"allOf": [
17431-
{
17432-
"$ref": "#/components/schemas/MinorUnit"
17433-
}
17434-
],
17435-
"nullable": true
17436-
},
17437-
"accepted_currencies": {
17438-
"type": "array",
17439-
"items": {
17440-
"$ref": "#/components/schemas/Currency"
17441-
},
17442-
"description": "The three-letter ISO currency code",
17443-
"example": [
17444-
"USD",
17445-
"EUR"
17446-
],
17447-
"nullable": true
17448-
},
17449-
"recurring_enabled": {
17450-
"type": "boolean",
17451-
"description": "Indicates whether the payment method supports recurring payments. Optional.",
17452-
"example": true,
17453-
"nullable": true
17454-
},
17455-
"card_networks": {
17456-
"type": "array",
17457-
"items": {
17458-
"$ref": "#/components/schemas/CardNetwork"
17459-
},
17460-
"description": "Indicates whether the payment method is eligible for card netwotks",
17461-
"example": [
17462-
"visa",
17463-
"mastercard"
17464-
],
17465-
"nullable": true
17466-
},
17467-
"limit": {
17468-
"type": "integer",
17469-
"format": "int64",
17470-
"description": "Indicates the limit of last used payment methods",
17471-
"example": 1,
17472-
"nullable": true
17473-
}
17474-
},
17475-
"additionalProperties": false
17476-
},
1747717477
"PaymentMethodListResponseForPayments": {
1747817478
"type": "object",
1747917479
"required": [
@@ -22738,7 +22738,8 @@
2273822738
"type": "object",
2273922739
"required": [
2274022740
"payment_method_type",
22741-
"payment_method_subtype"
22741+
"payment_method_subtype",
22742+
"required_fields"
2274222743
],
2274322744
"properties": {
2274422745
"payment_method_type": {
@@ -22756,12 +22757,7 @@
2275622757
"nullable": true
2275722758
},
2275822759
"required_fields": {
22759-
"allOf": [
22760-
{
22761-
"$ref": "#/components/schemas/RequiredFieldInfo"
22762-
}
22763-
],
22764-
"nullable": true
22760+
"$ref": "#/components/schemas/RequiredFieldInfo"
2276522761
},
2276622762
"surcharge_details": {
2276722763
"allOf": [

config/payment_required_fields_v2.toml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,19 +2159,19 @@ non_mandate = []
21592159
# Payment method type: Sepa
21602160
[required_fields.bank_debit.sepa.fields.Stripe]
21612161
common = [
2162-
{ required_field = "payment_method_data.billing.address.first_name", display_name = "billing_address_first_name", field_type = "text" },
2163-
{ required_field = "payment_method_data.billing.address.last_name", display_name = "billing_address_last_name", field_type = "text" },
2164-
{ required_field = "payment_method_data.bank_debit.sepa.iban", display_name = "iban", field_type = "text" },
2165-
{ required_field = "email", display_name = "email", field_type = "text" }
2162+
{ required_field = "payment_method_data.billing.address.first_name", display_name = "owner_name", field_type = "user_billing_name" },
2163+
{ required_field = "payment_method_data.billing.address.last_name", display_name = "owner_name", field_type = "user_billing_name" },
2164+
{ required_field = "payment_method_data.bank_debit.sepa_bank_debit.iban", display_name = "iban", field_type = "user_iban" },
2165+
{ required_field = "email", display_name = "email", field_type = "user_iban" }
21662166
]
21672167
mandate = []
21682168
non_mandate = []
21692169

21702170
[required_fields.bank_debit.sepa.fields.Adyen]
21712171
common = [
2172-
{ required_field = "payment_method_data.billing.address.first_name", display_name = "billing_address_first_name", field_type = "text" },
2173-
{ required_field = "payment_method_data.billing.address.last_name", display_name = "billing_address_last_name", field_type = "text" },
2174-
{ required_field = "payment_method_data.bank_debit.sepa.iban", display_name = "iban", field_type = "text" }
2172+
{ required_field = "payment_method_data.billing.address.first_name", display_name = "owner_name", field_type = "user_billing_name" },
2173+
{ required_field = "payment_method_data.billing.address.last_name", display_name = "owner_name", field_type = "user_billing_name" },
2174+
{ required_field = "payment_method_data.bank_debit.sepa_bank_debit.iban", display_name = "iban", field_type = "user_iban" }
21752175
]
21762176
mandate = []
21772177
non_mandate = []
@@ -2230,10 +2230,10 @@ non_mandate = []
22302230

22312231
[required_fields.bank_debit.becs.fields.Adyen]
22322232
common = [
2233-
{ required_field = "payment_method_data.billing.address.first_name", display_name = "billing_address_first_name", field_type = "text" },
2234-
{ required_field = "payment_method_data.billing.address.last_name", display_name = "billing_address_last_name", field_type = "text" },
2235-
{ required_field = "payment_method_data.bank_debit.becs.account_number", display_name = "account_number", field_type = "text" },
2236-
{ required_field = "payment_method_data.bank_debit.bacs.sort_code", display_name = "sort_code", field_type = "text" } # Corrected from becs.sort_code as per V1
2233+
{ required_field = "payment_method_data.billing.address.first_name", display_name = "owner_name", field_type = "user_billing_name" },
2234+
{ required_field = "payment_method_data.billing.address.last_name", display_name = "owner_name", field_type = "user_billing_name" },
2235+
{ required_field = "ppayment_method_data.bank_debit.becs_bank_debit.account_number", display_name = "bank_account_number", field_type = "user_bank_account_number" },
2236+
{ required_field = "payment_method_data.bank_debit.becs_bank_debit.sort_code", display_name = "bank_sort_code", field_type = "user_bank_sort_code" } # Corrected from becs.sort_code as per V1
22372237
]
22382238
mandate = []
22392239
non_mandate = []

crates/api_models/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ time = { version = "0.3.41", features = ["serde", "serde-well-known", "std"] }
3636
url = { version = "2.5.4", features = ["serde"] }
3737
utoipa = { version = "4.2.3", features = ["preserve_order", "preserve_path_order"] }
3838
nutype = { version = "0.4.3", features = ["serde"] }
39+
deserialize_form_style_query_parameter = "0.2.2"
3940

4041
# First party crates
4142
cards = { version = "0.1.0", path = "../cards" }

crates/api_models/src/events/payment.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,25 @@ use super::{
66
PaymentsCreateIntentRequest, PaymentsGetIntentRequest, PaymentsIntentResponse, PaymentsRequest,
77
};
88
#[cfg(feature = "v2")]
9-
use crate::payment_methods::PaymentMethodListResponseForSession;
9+
use crate::payment_methods::{
10+
ListMethodsForPaymentMethodsRequest, PaymentMethodListResponseForSession,
11+
};
12+
use crate::{
13+
payment_methods::{
14+
self, ListCountriesCurrenciesRequest, ListCountriesCurrenciesResponse,
15+
PaymentMethodCollectLinkRenderRequest, PaymentMethodCollectLinkRequest,
16+
PaymentMethodCollectLinkResponse, PaymentMethodMigrateResponse, PaymentMethodResponse,
17+
PaymentMethodUpdate,
18+
},
19+
payments::{
20+
self, PaymentListConstraints, PaymentListFilters, PaymentListFiltersV2,
21+
PaymentListResponse, PaymentsAggregateResponse, PaymentsSessionResponse,
22+
RedirectionResponse,
23+
},
24+
};
1025
#[cfg(feature = "v1")]
1126
use crate::{
12-
payment_methods::PaymentMethodListResponse,
27+
payment_methods::{PaymentMethodListRequest, PaymentMethodListResponse},
1328
payments::{
1429
ExtendedCardInfoResponse, PaymentIdType, PaymentListFilterConstraints,
1530
PaymentListResponseV2, PaymentsApproveRequest, PaymentsCancelRequest,
@@ -22,19 +37,6 @@ use crate::{
2237
PaymentsStartRequest, PaymentsUpdateMetadataRequest, PaymentsUpdateMetadataResponse,
2338
},
2439
};
25-
use crate::{
26-
payment_methods::{
27-
self, ListCountriesCurrenciesRequest, ListCountriesCurrenciesResponse,
28-
PaymentMethodCollectLinkRenderRequest, PaymentMethodCollectLinkRequest,
29-
PaymentMethodCollectLinkResponse, PaymentMethodListRequest, PaymentMethodMigrateResponse,
30-
PaymentMethodResponse, PaymentMethodUpdate,
31-
},
32-
payments::{
33-
self, PaymentListConstraints, PaymentListFilters, PaymentListFiltersV2,
34-
PaymentListResponse, PaymentsAggregateResponse, PaymentsSessionResponse,
35-
RedirectionResponse,
36-
},
37-
};
3840

3941
#[cfg(feature = "v1")]
4042
impl ApiEventMetric for PaymentsRetrieveRequest {
@@ -305,6 +307,7 @@ impl ApiEventMetric for payment_methods::PaymentMethodDeleteResponse {
305307

306308
impl ApiEventMetric for payment_methods::CustomerPaymentMethodsListResponse {}
307309

310+
#[cfg(feature = "v1")]
308311
impl ApiEventMetric for PaymentMethodListRequest {
309312
fn get_api_event_type(&self) -> Option<ApiEventsType> {
310313
Some(ApiEventsType::PaymentMethodList {
@@ -317,6 +320,19 @@ impl ApiEventMetric for PaymentMethodListRequest {
317320
}
318321
}
319322

323+
#[cfg(feature = "v2")]
324+
impl ApiEventMetric for ListMethodsForPaymentMethodsRequest {
325+
fn get_api_event_type(&self) -> Option<ApiEventsType> {
326+
Some(ApiEventsType::PaymentMethodList {
327+
payment_id: self
328+
.client_secret
329+
.as_ref()
330+
.and_then(|cs| cs.rsplit_once("_secret_"))
331+
.map(|(pid, _)| pid.to_string()),
332+
})
333+
}
334+
}
335+
320336
impl ApiEventMetric for ListCountriesCurrenciesRequest {}
321337

322338
impl ApiEventMetric for ListCountriesCurrenciesResponse {}

crates/api_models/src/payment_methods.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,7 +1778,7 @@ impl<'de> serde::Deserialize<'de> for PaymentMethodListRequest {
17781778
//List Payment Method
17791779
#[derive(Debug, Clone, serde::Serialize, Default, ToSchema)]
17801780
#[serde(deny_unknown_fields)]
1781-
pub struct PaymentMethodListRequest {
1781+
pub struct ListMethodsForPaymentMethodsRequest {
17821782
/// This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK
17831783
#[schema(max_length = 30, min_length = 30, example = "secret_k2uj3he2893eiu2d")]
17841784
pub client_secret: Option<String>,
@@ -1809,15 +1809,15 @@ pub struct PaymentMethodListRequest {
18091809
}
18101810

18111811
#[cfg(feature = "v2")]
1812-
impl<'de> serde::Deserialize<'de> for PaymentMethodListRequest {
1812+
impl<'de> serde::Deserialize<'de> for ListMethodsForPaymentMethodsRequest {
18131813
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
18141814
where
18151815
D: serde::Deserializer<'de>,
18161816
{
18171817
struct FieldVisitor;
18181818

18191819
impl<'de> de::Visitor<'de> for FieldVisitor {
1820-
type Value = PaymentMethodListRequest;
1820+
type Value = ListMethodsForPaymentMethodsRequest;
18211821

18221822
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18231823
formatter.write_str("Failed while deserializing as map")
@@ -1827,7 +1827,7 @@ impl<'de> serde::Deserialize<'de> for PaymentMethodListRequest {
18271827
where
18281828
A: de::MapAccess<'de>,
18291829
{
1830-
let mut output = PaymentMethodListRequest::default();
1830+
let mut output = ListMethodsForPaymentMethodsRequest::default();
18311831

18321832
while let Some(key) = map.next_key()? {
18331833
match key {

0 commit comments

Comments
 (0)