mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	fix(compatibility): fix AddressDetails in the customers flow (#1654)
This commit is contained in:
		| @ -3,6 +3,8 @@ use masking::Secret; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use utoipa::ToSchema; | ||||
|  | ||||
| use crate::payments; | ||||
|  | ||||
| /// The customer details | ||||
| #[derive(Debug, Default, Clone, Deserialize, Serialize, ToSchema)] | ||||
| pub struct CustomerRequest { | ||||
| @ -30,18 +32,8 @@ pub struct CustomerRequest { | ||||
|     #[schema(max_length = 255, example = "+65")] | ||||
|     pub phone_country_code: Option<String>, | ||||
|     /// The address for the customer | ||||
|     #[schema(value_type = Option<Object>,example = json!({ | ||||
|     "city": "Bangalore", | ||||
|     "country": "IN", | ||||
|     "line1": "Hyperswitch router", | ||||
|     "line2": "Koramangala", | ||||
|     "line3": "Stallion", | ||||
|     "state": "Karnataka", | ||||
|     "zip": "560095", | ||||
|     "first_name": "John", | ||||
|     "last_name": "Doe" | ||||
|   }))] | ||||
|     pub address: Option<pii::SecretSerdeValue>, | ||||
|     #[schema(value_type = Option<AddressDetails>)] | ||||
|     pub address: Option<payments::AddressDetails>, | ||||
|     /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 | ||||
|     /// characters long. Metadata is useful for storing additional, structured information on an | ||||
|     /// object. | ||||
| @ -70,18 +62,8 @@ pub struct CustomerResponse { | ||||
|     #[schema(max_length = 255, example = "First Customer")] | ||||
|     pub description: Option<String>, | ||||
|     /// The address for the customer | ||||
|     #[schema(value_type = Option<Object>,example = json!({ | ||||
|     "city": "Bangalore", | ||||
|     "country": "IN", | ||||
|     "line1": "Hyperswitch router", | ||||
|     "line2": "Koramangala", | ||||
|     "line3": "Stallion", | ||||
|     "state": "Karnataka", | ||||
|     "zip": "560095", | ||||
|     "first_name": "John", | ||||
|     "last_name": "Doe" | ||||
|   }))] | ||||
|     pub address: Option<Secret<serde_json::Value>>, | ||||
|     #[schema(value_type = Option<AddressDetails>)] | ||||
|     pub address: Option<payments::AddressDetails>, | ||||
|     ///  A timestamp (ISO 8601 code) that determines when the customer was created | ||||
|     #[schema(value_type = PrimitiveDateTime,example = "2023-01-18T11:04:09.922Z")] | ||||
|     #[serde(with = "custom_serde::iso8601")] | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use std::{convert::From, default::Default}; | ||||
|  | ||||
| use api_models::payment_methods as api_types; | ||||
| use api_models::{payment_methods as api_types, payments}; | ||||
| use common_utils::{ | ||||
|     crypto::Encryptable, | ||||
|     date_time, | ||||
| @ -8,7 +8,29 @@ use common_utils::{ | ||||
| }; | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use crate::{logger, types::api}; | ||||
| use crate::{ | ||||
|     logger, | ||||
|     types::{api, api::enums as api_enums}, | ||||
| }; | ||||
|  | ||||
| #[derive(Default, Serialize, PartialEq, Eq, Deserialize, Clone)] | ||||
| pub struct Shipping { | ||||
|     pub address: StripeAddressDetails, | ||||
|     pub name: Option<masking::Secret<String>>, | ||||
|     pub carrier: Option<String>, | ||||
|     pub phone: Option<masking::Secret<String>>, | ||||
|     pub tracking_number: Option<masking::Secret<String>>, | ||||
| } | ||||
|  | ||||
| #[derive(Default, Serialize, PartialEq, Eq, Deserialize, Clone)] | ||||
| pub struct StripeAddressDetails { | ||||
|     pub city: Option<String>, | ||||
|     pub country: Option<api_enums::CountryAlpha2>, | ||||
|     pub line1: Option<masking::Secret<String>>, | ||||
|     pub line2: Option<masking::Secret<String>>, | ||||
|     pub postal_code: Option<masking::Secret<String>>, | ||||
|     pub state: Option<masking::Secret<String>>, | ||||
| } | ||||
|  | ||||
| #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)] | ||||
| pub struct CreateCustomerRequest { | ||||
| @ -16,9 +38,23 @@ pub struct CreateCustomerRequest { | ||||
|     pub invoice_prefix: Option<String>, | ||||
|     pub name: Option<masking::Secret<String>>, | ||||
|     pub phone: Option<masking::Secret<String>>, | ||||
|     pub address: Option<masking::Secret<serde_json::Value>>, | ||||
|     pub address: Option<StripeAddressDetails>, | ||||
|     pub metadata: Option<pii::SecretSerdeValue>, | ||||
|     pub description: Option<String>, | ||||
|     pub shipping: Option<Shipping>, | ||||
|     pub payment_method: Option<String>,              // not used | ||||
|     pub balance: Option<i64>,                        // not used | ||||
|     pub cash_balance: Option<pii::SecretSerdeValue>, // not used | ||||
|     pub coupon: Option<String>,                      // not used | ||||
|     pub invoice_settings: Option<pii::SecretSerdeValue>, // not used | ||||
|     pub next_invoice_sequence: Option<String>,       // not used | ||||
|     pub preferred_locales: Option<String>,           // not used | ||||
|     pub promotion_code: Option<String>,              // not used | ||||
|     pub source: Option<String>,                      // not used | ||||
|     pub tax: Option<pii::SecretSerdeValue>,          // not used | ||||
|     pub tax_exempt: Option<String>,                  // not used | ||||
|     pub tax_id_data: Option<String>,                 // not used | ||||
|     pub test_clock: Option<String>,                  // not used | ||||
| } | ||||
|  | ||||
| #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)] | ||||
| @ -27,8 +63,21 @@ pub struct CustomerUpdateRequest { | ||||
|     pub email: Option<Email>, | ||||
|     pub phone: Option<masking::Secret<String, masking::WithType>>, | ||||
|     pub name: Option<masking::Secret<String>>, | ||||
|     pub address: Option<masking::Secret<serde_json::Value>>, | ||||
|     pub address: Option<StripeAddressDetails>, | ||||
|     pub metadata: Option<pii::SecretSerdeValue>, | ||||
|     pub shipping: Option<Shipping>, | ||||
|     pub payment_method: Option<String>,              // not used | ||||
|     pub balance: Option<i64>,                        // not used | ||||
|     pub cash_balance: Option<pii::SecretSerdeValue>, // not used | ||||
|     pub coupon: Option<String>,                      // not used | ||||
|     pub default_source: Option<String>,              // not used | ||||
|     pub invoice_settings: Option<pii::SecretSerdeValue>, // not used | ||||
|     pub next_invoice_sequence: Option<String>,       // not used | ||||
|     pub preferred_locales: Option<String>,           // not used | ||||
|     pub promotion_code: Option<String>,              // not used | ||||
|     pub source: Option<String>,                      // not used | ||||
|     pub tax: Option<pii::SecretSerdeValue>,          // not used | ||||
|     pub tax_exempt: Option<String>,                  // not used | ||||
| } | ||||
|  | ||||
| #[derive(Default, Serialize, PartialEq, Eq)] | ||||
| @ -52,6 +101,22 @@ pub struct CustomerDeleteResponse { | ||||
|     pub deleted: bool, | ||||
| } | ||||
|  | ||||
| impl From<StripeAddressDetails> for payments::AddressDetails { | ||||
|     fn from(address: StripeAddressDetails) -> Self { | ||||
|         Self { | ||||
|             city: address.city, | ||||
|             country: address.country, | ||||
|             line1: address.line1, | ||||
|             line2: address.line2, | ||||
|             zip: address.postal_code, | ||||
|             state: address.state, | ||||
|             first_name: None, | ||||
|             line3: None, | ||||
|             last_name: None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<CreateCustomerRequest> for api::CustomerRequest { | ||||
|     fn from(req: CreateCustomerRequest) -> Self { | ||||
|         Self { | ||||
| @ -61,7 +126,7 @@ impl From<CreateCustomerRequest> for api::CustomerRequest { | ||||
|             email: req.email, | ||||
|             description: req.description, | ||||
|             metadata: req.metadata, | ||||
|             address: req.address, | ||||
|             address: req.address.map(|s| s.into()), | ||||
|             ..Default::default() | ||||
|         } | ||||
|     } | ||||
| @ -75,6 +140,7 @@ impl From<CustomerUpdateRequest> for api::CustomerRequest { | ||||
|             email: req.email, | ||||
|             description: req.description, | ||||
|             metadata: req.metadata, | ||||
|             address: req.address.map(|s| s.into()), | ||||
|             ..Default::default() | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -1,7 +1,4 @@ | ||||
| use common_utils::{ | ||||
|     crypto::{Encryptable, GcmAes256}, | ||||
|     ext_traits::ValueExt, | ||||
| }; | ||||
| use common_utils::crypto::{Encryptable, GcmAes256}; | ||||
| use error_stack::ResultExt; | ||||
| use masking::ExposeInterface; | ||||
| use router_env::{instrument, tracing}; | ||||
| @ -42,11 +39,7 @@ pub async fn create_customer( | ||||
|  | ||||
|     let key = key_store.key.get_inner().peek(); | ||||
|     if let Some(addr) = &customer_data.address { | ||||
|         let customer_address: api_models::payments::AddressDetails = addr | ||||
|             .peek() | ||||
|             .clone() | ||||
|             .parse_value("AddressDetails") | ||||
|             .change_context(errors::ApiErrorResponse::AddressNotFound)?; | ||||
|         let customer_address: api_models::payments::AddressDetails = addr.clone(); | ||||
|  | ||||
|         let address = async { | ||||
|             Ok(domain::Address { | ||||
| @ -333,11 +326,7 @@ pub async fn update_customer( | ||||
|     let key = key_store.key.get_inner().peek(); | ||||
|  | ||||
|     if let Some(addr) = &update_customer.address { | ||||
|         let customer_address: api_models::payments::AddressDetails = addr | ||||
|             .peek() | ||||
|             .clone() | ||||
|             .parse_value("AddressDetails") | ||||
|             .change_context(errors::ApiErrorResponse::AddressNotFound)?; | ||||
|         let customer_address: api_models::payments::AddressDetails = addr.clone(); | ||||
|         let update_address = async { | ||||
|             Ok(storage::AddressUpdate::Update { | ||||
|                 city: customer_address.city, | ||||
|  | ||||
| @ -3700,8 +3700,11 @@ | ||||
|             "maxLength": 255 | ||||
|           }, | ||||
|           "address": { | ||||
|             "type": "object", | ||||
|             "description": "The address for the customer", | ||||
|             "allOf": [ | ||||
|               { | ||||
|                 "$ref": "#/components/schemas/AddressDetails" | ||||
|               } | ||||
|             ], | ||||
|             "nullable": true | ||||
|           }, | ||||
|           "metadata": { | ||||
| @ -3760,8 +3763,11 @@ | ||||
|             "maxLength": 255 | ||||
|           }, | ||||
|           "address": { | ||||
|             "type": "object", | ||||
|             "description": "The address for the customer", | ||||
|             "allOf": [ | ||||
|               { | ||||
|                 "$ref": "#/components/schemas/AddressDetails" | ||||
|               } | ||||
|             ], | ||||
|             "nullable": true | ||||
|           }, | ||||
|           "created_at": { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Kritik Modi
					Kritik Modi