From 863e380cf2eb8ace17cad0f1bcbc2a9f4a460983 Mon Sep 17 00:00:00 2001 From: Narayan Bhat <48803246+Narayanbhat166@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:18:27 +0530 Subject: [PATCH] feat(address): add email field to address (#3682) --- crates/api_models/src/payments.rs | 3 +++ crates/diesel_models/src/address.rs | 3 +++ crates/diesel_models/src/schema.rs | 1 + .../compatibility/stripe/payment_intents/types.rs | 2 ++ .../compatibility/stripe/setup_intents/types.rs | 2 ++ crates/router/src/core/customers.rs | 7 +++++++ .../src/core/payments/flows/setup_mandate_flow.rs | 4 ++-- crates/router/src/core/payments/helpers.rs | 14 ++++++++++++++ crates/router/src/core/payouts.rs | 3 ++- crates/router/src/core/utils.rs | 1 + crates/router/src/db/address.rs | 1 + crates/router/src/types/domain/address.rs | 8 ++++++++ crates/router/src/types/transformers.rs | 1 + crates/router/src/utils.rs | 13 +++++++++++++ crates/router/tests/connectors/adyen.rs | 2 ++ crates/router/tests/connectors/bitpay.rs | 1 + crates/router/tests/connectors/bluesnap.rs | 1 + crates/router/tests/connectors/cashtocode.rs | 1 + crates/router/tests/connectors/coinbase.rs | 1 + crates/router/tests/connectors/cryptopay.rs | 1 + crates/router/tests/connectors/cybersource.rs | 1 + crates/router/tests/connectors/dlocal.rs | 1 + crates/router/tests/connectors/forte.rs | 1 + crates/router/tests/connectors/globalpay.rs | 1 + crates/router/tests/connectors/iatapay.rs | 1 + crates/router/tests/connectors/multisafepay.rs | 1 + crates/router/tests/connectors/opennode.rs | 1 + crates/router/tests/connectors/payeezy.rs | 1 + crates/router/tests/connectors/payme.rs | 1 + crates/router/tests/connectors/trustpay.rs | 1 + crates/router/tests/connectors/wise.rs | 1 + crates/router/tests/connectors/worldline.rs | 1 + crates/router/tests/payments.rs | 4 ++++ crates/router/tests/payments2.rs | 8 ++++++++ .../down.sql | 2 ++ .../2024-02-15-133957_add_email_to_address/up.sql | 3 +++ openapi/openapi_spec.json | 4 ++++ .../QuickStart/Payments - Create/event.test.js | 11 ++++++++++- .../QuickStart/Payments - Create/request.json | 3 ++- 39 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 migrations/2024-02-15-133957_add_email_to_address/down.sql create mode 100644 migrations/2024-02-15-133957_add_email_to_address/up.sql diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index b95b74b329..91a289652b 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -1996,6 +1996,9 @@ pub struct Address { pub address: Option, pub phone: Option, + + #[schema(value_type = Option)] + pub email: Option, } // used by customers also, could be moved outside diff --git a/crates/diesel_models/src/address.rs b/crates/diesel_models/src/address.rs index 03dedfd60d..e3d5ed7399 100644 --- a/crates/diesel_models/src/address.rs +++ b/crates/diesel_models/src/address.rs @@ -25,6 +25,7 @@ pub struct AddressNew { pub created_at: PrimitiveDateTime, pub modified_at: PrimitiveDateTime, pub updated_by: String, + pub email: Option, } #[derive(Clone, Debug, Queryable, Identifiable, Serialize, Deserialize)] @@ -49,6 +50,7 @@ pub struct Address { pub merchant_id: String, pub payment_id: Option, pub updated_by: String, + pub email: Option, } #[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay, Serialize, Deserialize)] @@ -67,6 +69,7 @@ pub struct AddressUpdateInternal { pub country_code: Option, pub modified_at: PrimitiveDateTime, pub updated_by: String, + pub email: Option, } impl AddressUpdateInternal { diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index 5093f0df7d..be8c330214 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -31,6 +31,7 @@ diesel::table! { payment_id -> Nullable, #[max_length = 32] updated_by -> Varchar, + email -> Nullable, } } diff --git a/crates/router/src/compatibility/stripe/payment_intents/types.rs b/crates/router/src/compatibility/stripe/payment_intents/types.rs index 9aa84db5fa..ba6bf28679 100644 --- a/crates/router/src/compatibility/stripe/payment_intents/types.rs +++ b/crates/router/src/compatibility/stripe/payment_intents/types.rs @@ -39,6 +39,7 @@ impl From for payments::Address { address.country.as_ref().map(|country| country.to_string()) }), }), + email: details.email, address: details.address.map(|address| payments::AddressDetails { city: address.city, country: address.country, @@ -184,6 +185,7 @@ impl From for payments::Address { number: details.phone, country_code: details.address.country.map(|country| country.to_string()), }), + email: None, address: Some(payments::AddressDetails { city: details.address.city, country: details.address.country, diff --git a/crates/router/src/compatibility/stripe/setup_intents/types.rs b/crates/router/src/compatibility/stripe/setup_intents/types.rs index 5a2c7a0289..4dcea1c4fe 100644 --- a/crates/router/src/compatibility/stripe/setup_intents/types.rs +++ b/crates/router/src/compatibility/stripe/setup_intents/types.rs @@ -37,6 +37,7 @@ impl From for payments::Address { number: details.phone, country_code: None, }), + email: details.email, } } } @@ -143,6 +144,7 @@ impl From for payments::Address { number: details.phone, country_code: None, }), + email: None, } } } diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs index 9442bf2ff3..5686cf4ec6 100644 --- a/crates/router/src/core/customers.rs +++ b/crates/router/src/core/customers.rs @@ -249,6 +249,12 @@ pub async fn delete_customer( .await .switch()?; + let redacted_encrypted_email: Encryptable< + masking::Secret<_, common_utils::pii::EmailStrategy>, + > = Encryptable::encrypt(REDACTED.to_string().into(), key, GcmAes256) + .await + .switch()?; + let update_address = storage::AddressUpdate::Update { city: Some(REDACTED.to_string()), country: None, @@ -262,6 +268,7 @@ pub async fn delete_customer( phone_number: Some(redacted_encrypted_value.clone()), country_code: Some(REDACTED.to_string()), updated_by: merchant_account.storage_scheme.to_string(), + email: Some(redacted_encrypted_email), }; match db diff --git a/crates/router/src/core/payments/flows/setup_mandate_flow.rs b/crates/router/src/core/payments/flows/setup_mandate_flow.rs index 30918b2fe4..3f43204b98 100644 --- a/crates/router/src/core/payments/flows/setup_mandate_flow.rs +++ b/crates/router/src/core/payments/flows/setup_mandate_flow.rs @@ -69,7 +69,7 @@ impl Feature for types::Setup .as_ref() .and_then(|mandate_data| mandate_data.update_mandate_id.clone()) { - self.update_mandate_flow( + Box::pin(self.update_mandate_flow( state, merchant_account, mandate_id, @@ -79,7 +79,7 @@ impl Feature for types::Setup &state.conf.mandates.update_mandate_supported, connector_request, maybe_customer, - ) + )) .await } else { let connector_integration: services::BoxedConnectorIntegration< diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index b3330f82f7..b6e28faa4e 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -181,6 +181,14 @@ pub async fn create_or_update_address_for_payment_by_request( .as_ref() .and_then(|value| value.country_code.clone()), updated_by: storage_scheme.to_string(), + email: address + .email + .as_ref() + .cloned() + .async_lift(|inner| { + types::encrypt_optional(inner.map(|inner| inner.expose()), key) + }) + .await?, }) } .await @@ -370,6 +378,12 @@ pub async fn get_domain_address_for_payments( .await?, payment_id: Some(payment_id.to_owned()), updated_by: storage_scheme.to_string(), + email: address + .email + .as_ref() + .cloned() + .async_lift(|inner| types::encrypt_optional(inner.map(|inner| inner.expose()), key)) + .await?, }) } .await diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs index 8741407d17..ccb6f74c78 100644 --- a/crates/router/src/core/payouts.rs +++ b/crates/router/src/core/payouts.rs @@ -2,7 +2,7 @@ pub mod helpers; pub mod validator; use api_models::enums as api_enums; -use common_utils::{crypto::Encryptable, ext_traits::ValueExt}; +use common_utils::{crypto::Encryptable, ext_traits::ValueExt, pii}; use diesel_models::enums as storage_enums; use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; @@ -1096,6 +1096,7 @@ pub async fn response_handler( api::payments::Address { phone: Some(phone_details), address: Some(address_details), + email: a.email.to_owned().map(pii::Email::from), } }); diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index ef8dddde95..21b10ecd1e 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -108,6 +108,7 @@ pub async fn construct_payout_router_data<'a, F>( api_models::payments::Address { phone: Some(phone_details), address: Some(address_details), + email: a.email.to_owned().map(Email::from), } }), }; diff --git a/crates/router/src/db/address.rs b/crates/router/src/db/address.rs index 99006752f5..311fdc127d 100644 --- a/crates/router/src/db/address.rs +++ b/crates/router/src/db/address.rs @@ -501,6 +501,7 @@ mod storage { merchant_id: address_new.merchant_id.clone(), payment_id: address_new.payment_id.clone(), updated_by: storage_scheme.to_string(), + email: address_new.email.clone(), }; let redis_entry = kv::TypedSql { diff --git a/crates/router/src/types/domain/address.rs b/crates/router/src/types/domain/address.rs index ddf9c2152e..c657aaf97e 100644 --- a/crates/router/src/types/domain/address.rs +++ b/crates/router/src/types/domain/address.rs @@ -39,6 +39,7 @@ pub struct Address { pub merchant_id: String, pub payment_id: Option, pub updated_by: String, + pub email: crypto::OptionalEncryptableEmail, } #[async_trait] @@ -67,6 +68,7 @@ impl behaviour::Conversion for Address { merchant_id: self.merchant_id, payment_id: self.payment_id, updated_by: self.updated_by, + email: self.email.map(Encryption::from), }) } @@ -76,6 +78,7 @@ impl behaviour::Conversion for Address { ) -> CustomResult { async { let inner_decrypt = |inner| types::decrypt(inner, key.peek()); + let inner_decrypt_email = |inner| types::decrypt(inner, key.peek()); Ok(Self { id: other.id, address_id: other.address_id, @@ -96,6 +99,7 @@ impl behaviour::Conversion for Address { merchant_id: other.merchant_id, payment_id: other.payment_id, updated_by: other.updated_by, + email: other.email.async_lift(inner_decrypt_email).await?, }) } .await @@ -125,6 +129,7 @@ impl behaviour::Conversion for Address { created_at: now, modified_at: now, updated_by: self.updated_by, + email: self.email.map(Encryption::from), }) } } @@ -144,6 +149,7 @@ pub enum AddressUpdate { phone_number: crypto::OptionalEncryptableSecretString, country_code: Option, updated_by: String, + email: crypto::OptionalEncryptableEmail, }, } @@ -163,6 +169,7 @@ impl From for AddressUpdateInternal { phone_number, country_code, updated_by, + email, } => Self { city, country, @@ -177,6 +184,7 @@ impl From for AddressUpdateInternal { country_code, modified_at: date_time::convert_to_pdt(OffsetDateTime::now_utc()), updated_by, + email: email.map(Encryption::from), }, } } diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index f9ba7f8e92..e0d608f3cd 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -589,6 +589,7 @@ impl<'a> From<&'a domain::Address> for api_types::Address { number: address.phone_number.clone().map(Encryptable::into_inner), country_code: address.country_code.clone(), }), + email: address.email.clone().map(pii::Email::from), } } } diff --git a/crates/router/src/utils.rs b/crates/router/src/utils.rs index f9511a76d8..f218751204 100644 --- a/crates/router/src/utils.rs +++ b/crates/router/src/utils.rs @@ -26,6 +26,7 @@ pub use common_utils::{ use data_models::payments::PaymentIntent; use error_stack::{IntoReport, ResultExt}; use image::Luma; +use masking::ExposeInterface; use nanoid::nanoid; use qrcode; use serde::de::DeserializeOwned; @@ -564,6 +565,12 @@ impl CustomerAddress for api_models::customers::CustomerRequest { .await?, country_code: self.phone_country_code.clone(), updated_by: storage_scheme.to_string(), + email: self + .email + .as_ref() + .cloned() + .async_lift(|inner| encrypt_optional(inner.map(|inner| inner.expose()), key)) + .await?, }) } .await @@ -623,6 +630,12 @@ impl CustomerAddress for api_models::customers::CustomerRequest { created_at: common_utils::date_time::now(), modified_at: common_utils::date_time::now(), updated_by: storage_scheme.to_string(), + email: self + .email + .as_ref() + .cloned() + .async_lift(|inner| encrypt_optional(inner.map(|inner| inner.expose()), key)) + .await?, }) } .await diff --git a/crates/router/tests/connectors/adyen.rs b/crates/router/tests/connectors/adyen.rs index 76e2a3052a..6f3a309b0f 100644 --- a/crates/router/tests/connectors/adyen.rs +++ b/crates/router/tests/connectors/adyen.rs @@ -62,6 +62,7 @@ impl AdyenTest { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), @@ -88,6 +89,7 @@ impl AdyenTest { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/bitpay.rs b/crates/router/tests/connectors/bitpay.rs index 892d5b1f20..d24e20cd66 100644 --- a/crates/router/tests/connectors/bitpay.rs +++ b/crates/router/tests/connectors/bitpay.rs @@ -55,6 +55,7 @@ fn get_default_payment_info() -> Option { number: Some(Secret::new("1234567890".to_string())), country_code: Some("+91".to_string()), }), + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/bluesnap.rs b/crates/router/tests/connectors/bluesnap.rs index 852b23f022..622d835e83 100644 --- a/crates/router/tests/connectors/bluesnap.rs +++ b/crates/router/tests/connectors/bluesnap.rs @@ -54,6 +54,7 @@ fn get_payment_info() -> Option { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/cashtocode.rs b/crates/router/tests/connectors/cashtocode.rs index 9d08244571..a9d81d2bb6 100644 --- a/crates/router/tests/connectors/cashtocode.rs +++ b/crates/router/tests/connectors/cashtocode.rs @@ -82,6 +82,7 @@ impl CashtocodeTest { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/coinbase.rs b/crates/router/tests/connectors/coinbase.rs index 9a476df7fe..7a872ecb58 100644 --- a/crates/router/tests/connectors/coinbase.rs +++ b/crates/router/tests/connectors/coinbase.rs @@ -56,6 +56,7 @@ fn get_default_payment_info() -> Option { number: Some(Secret::new("1234567890".to_string())), country_code: Some("+91".to_string()), }), + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/cryptopay.rs b/crates/router/tests/connectors/cryptopay.rs index 5e1b3f5ab4..d61a93c8b8 100644 --- a/crates/router/tests/connectors/cryptopay.rs +++ b/crates/router/tests/connectors/cryptopay.rs @@ -55,6 +55,7 @@ fn get_default_payment_info() -> Option { number: Some(Secret::new("1234567890".to_string())), country_code: Some("+91".to_string()), }), + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/cybersource.rs b/crates/router/tests/connectors/cybersource.rs index 70255f68d8..617b184156 100644 --- a/crates/router/tests/connectors/cybersource.rs +++ b/crates/router/tests/connectors/cybersource.rs @@ -54,6 +54,7 @@ fn get_default_payment_info() -> Option { number: Some(Secret::new("1234567890".to_string())), country_code: Some("+91".to_string()), }), + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/dlocal.rs b/crates/router/tests/connectors/dlocal.rs index 92ae9da11d..6b3a2954b6 100644 --- a/crates/router/tests/connectors/dlocal.rs +++ b/crates/router/tests/connectors/dlocal.rs @@ -435,6 +435,7 @@ pub fn get_payment_info() -> PaymentInfo { first_name: None, last_name: None, }), + email: None, }), }), auth_type: None, diff --git a/crates/router/tests/connectors/forte.rs b/crates/router/tests/connectors/forte.rs index fdc6647c86..e017a11ff5 100644 --- a/crates/router/tests/connectors/forte.rs +++ b/crates/router/tests/connectors/forte.rs @@ -67,6 +67,7 @@ fn get_default_payment_info() -> Option { number: Some(Secret::new("1234567890".to_string())), country_code: Some("+91".to_string()), }), + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/globalpay.rs b/crates/router/tests/connectors/globalpay.rs index 8553f2a768..7cfd691c03 100644 --- a/crates/router/tests/connectors/globalpay.rs +++ b/crates/router/tests/connectors/globalpay.rs @@ -64,6 +64,7 @@ impl Globalpay { ..Default::default() }), phone: None, + ..Default::default() }), ..Default::default() }), diff --git a/crates/router/tests/connectors/iatapay.rs b/crates/router/tests/connectors/iatapay.rs index b6469b500c..d138fe8518 100644 --- a/crates/router/tests/connectors/iatapay.rs +++ b/crates/router/tests/connectors/iatapay.rs @@ -71,6 +71,7 @@ fn get_default_payment_info() -> Option { number: Some(Secret::new("1234567890".to_string())), country_code: Some("+91".to_string()), }), + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/multisafepay.rs b/crates/router/tests/connectors/multisafepay.rs index 8502a60b71..ff56239e97 100644 --- a/crates/router/tests/connectors/multisafepay.rs +++ b/crates/router/tests/connectors/multisafepay.rs @@ -53,6 +53,7 @@ fn get_default_payment_info() -> Option { state: Some(Secret::new("Amsterdam".to_string())), }), phone: None, + email: None, }), }); Some(PaymentInfo { diff --git a/crates/router/tests/connectors/opennode.rs b/crates/router/tests/connectors/opennode.rs index 69edec2af2..8415be949a 100644 --- a/crates/router/tests/connectors/opennode.rs +++ b/crates/router/tests/connectors/opennode.rs @@ -55,6 +55,7 @@ fn get_default_payment_info() -> Option { number: Some(Secret::new("1234567890".to_string())), country_code: Some("+91".to_string()), }), + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/payeezy.rs b/crates/router/tests/connectors/payeezy.rs index 1176ad7322..d05d065bcd 100644 --- a/crates/router/tests/connectors/payeezy.rs +++ b/crates/router/tests/connectors/payeezy.rs @@ -62,6 +62,7 @@ impl PayeezyTest { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/payme.rs b/crates/router/tests/connectors/payme.rs index 206694be0e..0ec07f4f72 100644 --- a/crates/router/tests/connectors/payme.rs +++ b/crates/router/tests/connectors/payme.rs @@ -57,6 +57,7 @@ fn get_default_payment_info() -> Option { last_name: Some(Secret::new("Doe".to_string())), }), phone: None, + email: None, }), }), auth_type: None, diff --git a/crates/router/tests/connectors/trustpay.rs b/crates/router/tests/connectors/trustpay.rs index 6dcd78f58a..560b7ba0b5 100644 --- a/crates/router/tests/connectors/trustpay.rs +++ b/crates/router/tests/connectors/trustpay.rs @@ -80,6 +80,7 @@ fn get_default_payment_info() -> Option { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/wise.rs b/crates/router/tests/connectors/wise.rs index de30352304..58fc74ed19 100644 --- a/crates/router/tests/connectors/wise.rs +++ b/crates/router/tests/connectors/wise.rs @@ -66,6 +66,7 @@ impl WiseTest { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/connectors/worldline.rs b/crates/router/tests/connectors/worldline.rs index 8b86578900..c5b12a0b0b 100644 --- a/crates/router/tests/connectors/worldline.rs +++ b/crates/router/tests/connectors/worldline.rs @@ -50,6 +50,7 @@ impl WorldlineTest { ..Default::default() }), phone: None, + email: None, }), ..Default::default() }), diff --git a/crates/router/tests/payments.rs b/crates/router/tests/payments.rs index 8f5ac25736..8ab2779d97 100644 --- a/crates/router/tests/payments.rs +++ b/crates/router/tests/payments.rs @@ -333,10 +333,12 @@ async fn payments_create_core() { shipping: Some(api::Address { address: None, phone: None, + email: None, }), billing: Some(api::Address { address: None, phone: None, + email: None, }), statement_descriptor_name: Some("Hyperswtich".to_string()), statement_descriptor_suffix: Some("Hyperswitch".to_string()), @@ -509,10 +511,12 @@ async fn payments_create_core_adyen_no_redirect() { shipping: Some(api::Address { address: None, phone: None, + email: None, }), billing: Some(api::Address { address: None, phone: None, + email: None, }), statement_descriptor_name: Some("Juspay".to_string()), statement_descriptor_suffix: Some("Router".to_string()), diff --git a/crates/router/tests/payments2.rs b/crates/router/tests/payments2.rs index 89ac522d23..d901da342f 100644 --- a/crates/router/tests/payments2.rs +++ b/crates/router/tests/payments2.rs @@ -93,10 +93,12 @@ async fn payments_create_core() { shipping: Some(api::Address { address: None, phone: None, + email: None, }), billing: Some(api::Address { address: None, phone: None, + email: None, }), statement_descriptor_name: Some("Hyperswitch".to_string()), statement_descriptor_suffix: Some("Hyperswitch".to_string()), @@ -273,9 +275,15 @@ async fn payments_create_core_adyen_no_redirect() { nick_name: Some(masking::Secret::new("nick_name".into())), })), payment_method: Some(api_enums::PaymentMethod::Card), + shipping: Some(api::Address { + address: None, + phone: None, + email: None, + }), billing: Some(api::Address { address: None, phone: None, + email: None, }), statement_descriptor_name: Some("Juspay".to_string()), statement_descriptor_suffix: Some("Router".to_string()), diff --git a/migrations/2024-02-15-133957_add_email_to_address/down.sql b/migrations/2024-02-15-133957_add_email_to_address/down.sql new file mode 100644 index 0000000000..8d3d6bd90a --- /dev/null +++ b/migrations/2024-02-15-133957_add_email_to_address/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE address DROP COLUMN IF EXISTS email; diff --git a/migrations/2024-02-15-133957_add_email_to_address/up.sql b/migrations/2024-02-15-133957_add_email_to_address/up.sql new file mode 100644 index 0000000000..5dce63c4b2 --- /dev/null +++ b/migrations/2024-02-15-133957_add_email_to_address/up.sql @@ -0,0 +1,3 @@ +-- Your SQL goes here +ALTER TABLE address +ADD COLUMN IF NOT EXISTS email BYTEA; diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 9e64f3e9d0..27989e1eae 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -4315,6 +4315,10 @@ } ], "nullable": true + }, + "email": { + "type": "string", + "nullable": true } } }, diff --git a/postman/collection-dir/stripe/QuickStart/Payments - Create/event.test.js b/postman/collection-dir/stripe/QuickStart/Payments - Create/event.test.js index 44aef3e03b..3d51aaa49a 100644 --- a/postman/collection-dir/stripe/QuickStart/Payments - Create/event.test.js +++ b/postman/collection-dir/stripe/QuickStart/Payments - Create/event.test.js @@ -19,7 +19,7 @@ pm.test("[POST]::/payments - Response has JSON Body", function () { let jsonData = {}; try { jsonData = pm.response.json(); -} catch (e) {} +} catch (e) { } // pm.collectionVariables - Set payment_id as variable for jsonData.payment_id if (jsonData?.payment_id) { @@ -88,3 +88,12 @@ pm.test( .true; }, ); + +// Response body should have "billing.email" +pm.test( + "[POST]::/payments - Content check if 'billing.email' exists", + function () { + pm.expect(typeof jsonData.connector_transaction_id !== "undefined").to.be + .true; + }, +); diff --git a/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json b/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json index e149698461..256d7a4209 100644 --- a/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json +++ b/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json @@ -58,7 +58,8 @@ "phone": { "number": "8056594427", "country_code": "+91" - } + }, + "email": "example@example.com" }, "shipping": { "address": {