diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index dbe13e3776..0ae089c5ea 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -2834,7 +2834,7 @@ } }, "/v2/customers/{id}/saved-payment-methods": { - "delete": { + "get": { "tags": [ "Payment Methods" ], @@ -7666,6 +7666,7 @@ "prophetpay", "rapyd", "razorpay", + "recurly", "shift4", "square", "stax", @@ -8651,7 +8652,8 @@ "recurring_enabled", "created", "requires_cvv", - "is_default" + "is_default", + "psp_tokenization_enabled" ], "properties": { "id": { @@ -8730,6 +8732,10 @@ } ], "nullable": true + }, + "psp_tokenization_enabled": { + "type": "boolean", + "description": "Whether psp_tokenization is enabled for the payment_method, this will be true when at least\none multi-use token with status `Active` is available for the payment method" } } }, @@ -11603,7 +11609,7 @@ "product_type": { "allOf": [ { - "$ref": "#/components/schemas/api_enums.MerchantProductType" + "$ref": "#/components/schemas/MerchantProductType" } ], "nullable": true @@ -11745,7 +11751,7 @@ "product_type": { "allOf": [ { - "$ref": "#/components/schemas/api_enums.MerchantProductType" + "$ref": "#/components/schemas/MerchantProductType" } ], "nullable": true @@ -12359,6 +12365,17 @@ }, "additionalProperties": false }, + "MerchantProductType": { + "type": "string", + "enum": [ + "orchestration", + "vault", + "recon", + "recovery", + "cost_observability", + "dynamic_routing" + ] + }, "MerchantRecipientData": { "oneOf": [ { @@ -12581,6 +12598,69 @@ } } }, + "NetworkTokenDetailsPaymentMethod": { + "type": "object", + "properties": { + "last4_digits": { + "type": "string", + "nullable": true + }, + "issuer_country": { + "type": "string", + "nullable": true + }, + "network_token_expiry_month": { + "type": "string", + "nullable": true + }, + "network_token_expiry_year": { + "type": "string", + "nullable": true + }, + "nick_name": { + "type": "string", + "nullable": true + }, + "card_holder_name": { + "type": "string", + "nullable": true + }, + "card_isin": { + "type": "string", + "nullable": true + }, + "card_issuer": { + "type": "string", + "nullable": true + }, + "card_network": { + "allOf": [ + { + "$ref": "#/components/schemas/CardNetwork" + } + ], + "nullable": true + }, + "card_type": { + "type": "string", + "nullable": true + }, + "saved_to_locker": { + "type": "boolean" + } + } + }, + "NetworkTokenResponse": { + "type": "object", + "required": [ + "payment_method_data" + ], + "properties": { + "payment_method_data": { + "$ref": "#/components/schemas/NetworkTokenDetailsPaymentMethod" + } + } + }, "NetworkTokenization": { "type": "object", "description": "The network tokenization configuration for creating the payment method session", @@ -13968,7 +14048,7 @@ "PaymentConnectorTransmission": { "type": "string", "enum": [ - "ConnectorCallFailed", + "ConnectorCallUnsuccessful", "ConnectorCallSucceeded" ] }, @@ -20385,6 +20465,7 @@ "prophetpay", "rapyd", "razorpay", + "recurly", "riskified", "shift4", "signifyd", diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 917efcea98..fa4ce7ae5e 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -9765,6 +9765,7 @@ "prophetpay", "rapyd", "razorpay", + "recurly", "shift4", "square", "stax", @@ -13933,7 +13934,7 @@ "product_type": { "allOf": [ { - "$ref": "#/components/schemas/api_enums.MerchantProductType" + "$ref": "#/components/schemas/MerchantProductType" } ], "nullable": true @@ -14174,7 +14175,7 @@ "product_type": { "allOf": [ { - "$ref": "#/components/schemas/api_enums.MerchantProductType" + "$ref": "#/components/schemas/MerchantProductType" } ], "nullable": true @@ -15089,6 +15090,17 @@ }, "additionalProperties": false }, + "MerchantProductType": { + "type": "string", + "enum": [ + "orchestration", + "vault", + "recon", + "recovery", + "cost_observability", + "dynamic_routing" + ] + }, "MerchantRecipientData": { "oneOf": [ { @@ -24881,6 +24893,7 @@ "prophetpay", "rapyd", "razorpay", + "recurly", "riskified", "shift4", "signifyd", diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index b6f1e0a8b9..b3d21c5a0b 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -113,7 +113,7 @@ pub struct MerchantAccountCreate { pub pm_collect_link_config: Option, /// Product Type of this merchant account - #[schema(value_type = Option)] + #[schema(value_type = Option)] pub product_type: Option, } @@ -198,6 +198,7 @@ pub struct MerchantAccountCreateWithoutOrgId { #[schema(value_type = Option, example = r#"{ "city": "NY", "unit": "245" }"#)] pub metadata: Option, + #[schema(value_type = Option)] pub product_type: Option, } @@ -560,7 +561,7 @@ pub struct MerchantAccountResponse { pub pm_collect_link_config: Option, /// Product Type of this merchant account - #[schema(value_type = Option)] + #[schema(value_type = Option)] pub product_type: Option, } @@ -596,7 +597,7 @@ pub struct MerchantAccountResponse { pub recon_status: api_enums::ReconStatus, /// Product Type of this merchant account - #[schema(value_type = Option)] + #[schema(value_type = Option)] pub product_type: Option, } diff --git a/crates/api_models/src/payment_methods.rs b/crates/api_models/src/payment_methods.rs index 6b9b35ac2c..d665337fda 100644 --- a/crates/api_models/src/payment_methods.rs +++ b/crates/api_models/src/payment_methods.rs @@ -980,16 +980,21 @@ pub struct CardDetailsPaymentMethod { pub saved_to_locker: bool, } -#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] pub struct NetworkTokenDetailsPaymentMethod { pub last4_digits: Option, pub issuer_country: Option, + #[schema(value_type = Option)] pub network_token_expiry_month: Option>, + #[schema(value_type = Option)] pub network_token_expiry_year: Option>, + #[schema(value_type = Option)] pub nick_name: Option>, + #[schema(value_type = Option)] pub card_holder_name: Option>, pub card_isin: Option, pub card_issuer: Option, + #[schema(value_type = Option)] pub card_network: Option, pub card_type: Option, #[serde(default = "saved_in_locker_default")] @@ -2019,6 +2024,10 @@ pub struct CustomerPaymentMethod { ///The network token details for the payment method pub network_tokenization: Option, + + /// Whether psp_tokenization is enabled for the payment_method, this will be true when at least + /// one multi-use token with status `Active` is available for the payment method + pub psp_tokenization_enabled: bool, } #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 1109c0ca75..20d1aa6474 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -320,6 +320,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::enums::PaymentLinkDetailsLayout, api_models::enums::PaymentMethodStatus, api_models::enums::UIWidgetFormLayout, + api_models::enums::MerchantProductType, api_models::enums::PaymentConnectorCategory, api_models::enums::CardDiscovery, api_models::enums::FeatureStatus, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 8a122b5fe8..5bbd8dee4b 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -259,6 +259,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::enums::PaymentMethod, api_models::enums::PaymentMethodIssuerCode, api_models::enums::MandateStatus, + api_models::enums::MerchantProductType, api_models::enums::PaymentExperience, api_models::enums::BankNames, api_models::enums::BankType, @@ -527,6 +528,8 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payment_methods::PaymentMethodSessionRequest, api_models::payment_methods::PaymentMethodSessionResponse, api_models::payment_methods::PaymentMethodsSessionUpdateRequest, + api_models::payment_methods::NetworkTokenResponse, + api_models::payment_methods::NetworkTokenDetailsPaymentMethod, api_models::payment_methods::TokenizeCardRequest, api_models::payment_methods::TokenizeDataRequest, api_models::payment_methods::TokenizePaymentMethodRequest, diff --git a/crates/openapi/src/routes/payment_method.rs b/crates/openapi/src/routes/payment_method.rs index 9304afc69d..cf1cd15346 100644 --- a/crates/openapi/src/routes/payment_method.rs +++ b/crates/openapi/src/routes/payment_method.rs @@ -326,7 +326,7 @@ pub async fn payment_method_delete_api() {} /// /// List the payment methods saved for a customer #[utoipa::path( - delete, + get, path = "/v2/customers/{id}/saved-payment-methods", params ( ("id" = String, Path, description = "The unique identifier for the customer"), diff --git a/crates/router/src/core/payment_methods/transformers.rs b/crates/router/src/core/payment_methods/transformers.rs index 87f7e38c93..a781732960 100644 --- a/crates/router/src/core/payment_methods/transformers.rs +++ b/crates/router/src/core/payment_methods/transformers.rs @@ -985,6 +985,15 @@ impl transformers::ForeignTryFrom for api::CustomerPaymen // TODO: check how we can get this field let recurring_enabled = true; + let psp_tokenization_enabled = item.connector_mandate_details.and_then(|details| { + details.payments.map(|payments| { + payments.values().any(|connector_token_reference| { + connector_token_reference.connector_token_status + == api_enums::ConnectorTokenStatus::Active + }) + }) + }); + Ok(Self { id: item.id, customer_id: item.customer_id, @@ -999,6 +1008,7 @@ impl transformers::ForeignTryFrom for api::CustomerPaymen is_default: false, billing: payment_method_billing, network_tokenization: network_token_resp, + psp_tokenization_enabled: psp_tokenization_enabled.unwrap_or(false), }) } }