fix(compatibility): fix AddressDetails in the customers flow (#1654)

This commit is contained in:
Kritik Modi
2023-07-13 12:30:56 +05:30
committed by GitHub
parent a3ea5dc09c
commit f48d6c4a2b
4 changed files with 90 additions and 47 deletions

View File

@ -3,6 +3,8 @@ use masking::Secret;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use utoipa::ToSchema; use utoipa::ToSchema;
use crate::payments;
/// The customer details /// The customer details
#[derive(Debug, Default, Clone, Deserialize, Serialize, ToSchema)] #[derive(Debug, Default, Clone, Deserialize, Serialize, ToSchema)]
pub struct CustomerRequest { pub struct CustomerRequest {
@ -30,18 +32,8 @@ pub struct CustomerRequest {
#[schema(max_length = 255, example = "+65")] #[schema(max_length = 255, example = "+65")]
pub phone_country_code: Option<String>, pub phone_country_code: Option<String>,
/// The address for the customer /// The address for the customer
#[schema(value_type = Option<Object>,example = json!({ #[schema(value_type = Option<AddressDetails>)]
"city": "Bangalore", pub address: Option<payments::AddressDetails>,
"country": "IN",
"line1": "Hyperswitch router",
"line2": "Koramangala",
"line3": "Stallion",
"state": "Karnataka",
"zip": "560095",
"first_name": "John",
"last_name": "Doe"
}))]
pub address: Option<pii::SecretSerdeValue>,
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 /// 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 /// characters long. Metadata is useful for storing additional, structured information on an
/// object. /// object.
@ -70,18 +62,8 @@ pub struct CustomerResponse {
#[schema(max_length = 255, example = "First Customer")] #[schema(max_length = 255, example = "First Customer")]
pub description: Option<String>, pub description: Option<String>,
/// The address for the customer /// The address for the customer
#[schema(value_type = Option<Object>,example = json!({ #[schema(value_type = Option<AddressDetails>)]
"city": "Bangalore", pub address: Option<payments::AddressDetails>,
"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>>,
/// A timestamp (ISO 8601 code) that determines when the customer was created /// A timestamp (ISO 8601 code) that determines when the customer was created
#[schema(value_type = PrimitiveDateTime,example = "2023-01-18T11:04:09.922Z")] #[schema(value_type = PrimitiveDateTime,example = "2023-01-18T11:04:09.922Z")]
#[serde(with = "custom_serde::iso8601")] #[serde(with = "custom_serde::iso8601")]

View File

@ -1,6 +1,6 @@
use std::{convert::From, default::Default}; 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::{ use common_utils::{
crypto::Encryptable, crypto::Encryptable,
date_time, date_time,
@ -8,7 +8,29 @@ use common_utils::{
}; };
use serde::{Deserialize, Serialize}; 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)] #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct CreateCustomerRequest { pub struct CreateCustomerRequest {
@ -16,9 +38,23 @@ pub struct CreateCustomerRequest {
pub invoice_prefix: Option<String>, pub invoice_prefix: Option<String>,
pub name: Option<masking::Secret<String>>, pub name: Option<masking::Secret<String>>,
pub phone: 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 metadata: Option<pii::SecretSerdeValue>,
pub description: Option<String>, 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)] #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
@ -27,8 +63,21 @@ pub struct CustomerUpdateRequest {
pub email: Option<Email>, pub email: Option<Email>,
pub phone: Option<masking::Secret<String, masking::WithType>>, pub phone: Option<masking::Secret<String, masking::WithType>>,
pub name: Option<masking::Secret<String>>, pub name: Option<masking::Secret<String>>,
pub address: Option<masking::Secret<serde_json::Value>>, pub address: Option<StripeAddressDetails>,
pub metadata: Option<pii::SecretSerdeValue>, 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)] #[derive(Default, Serialize, PartialEq, Eq)]
@ -52,6 +101,22 @@ pub struct CustomerDeleteResponse {
pub deleted: bool, 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 { impl From<CreateCustomerRequest> for api::CustomerRequest {
fn from(req: CreateCustomerRequest) -> Self { fn from(req: CreateCustomerRequest) -> Self {
Self { Self {
@ -61,7 +126,7 @@ impl From<CreateCustomerRequest> for api::CustomerRequest {
email: req.email, email: req.email,
description: req.description, description: req.description,
metadata: req.metadata, metadata: req.metadata,
address: req.address, address: req.address.map(|s| s.into()),
..Default::default() ..Default::default()
} }
} }
@ -75,6 +140,7 @@ impl From<CustomerUpdateRequest> for api::CustomerRequest {
email: req.email, email: req.email,
description: req.description, description: req.description,
metadata: req.metadata, metadata: req.metadata,
address: req.address.map(|s| s.into()),
..Default::default() ..Default::default()
} }
} }

View File

@ -1,7 +1,4 @@
use common_utils::{ use common_utils::crypto::{Encryptable, GcmAes256};
crypto::{Encryptable, GcmAes256},
ext_traits::ValueExt,
};
use error_stack::ResultExt; use error_stack::ResultExt;
use masking::ExposeInterface; use masking::ExposeInterface;
use router_env::{instrument, tracing}; use router_env::{instrument, tracing};
@ -42,11 +39,7 @@ pub async fn create_customer(
let key = key_store.key.get_inner().peek(); let key = key_store.key.get_inner().peek();
if let Some(addr) = &customer_data.address { if let Some(addr) = &customer_data.address {
let customer_address: api_models::payments::AddressDetails = addr let customer_address: api_models::payments::AddressDetails = addr.clone();
.peek()
.clone()
.parse_value("AddressDetails")
.change_context(errors::ApiErrorResponse::AddressNotFound)?;
let address = async { let address = async {
Ok(domain::Address { Ok(domain::Address {
@ -333,11 +326,7 @@ pub async fn update_customer(
let key = key_store.key.get_inner().peek(); let key = key_store.key.get_inner().peek();
if let Some(addr) = &update_customer.address { if let Some(addr) = &update_customer.address {
let customer_address: api_models::payments::AddressDetails = addr let customer_address: api_models::payments::AddressDetails = addr.clone();
.peek()
.clone()
.parse_value("AddressDetails")
.change_context(errors::ApiErrorResponse::AddressNotFound)?;
let update_address = async { let update_address = async {
Ok(storage::AddressUpdate::Update { Ok(storage::AddressUpdate::Update {
city: customer_address.city, city: customer_address.city,

View File

@ -3700,8 +3700,11 @@
"maxLength": 255 "maxLength": 255
}, },
"address": { "address": {
"type": "object", "allOf": [
"description": "The address for the customer", {
"$ref": "#/components/schemas/AddressDetails"
}
],
"nullable": true "nullable": true
}, },
"metadata": { "metadata": {
@ -3760,8 +3763,11 @@
"maxLength": 255 "maxLength": 255
}, },
"address": { "address": {
"type": "object", "allOf": [
"description": "The address for the customer", {
"$ref": "#/components/schemas/AddressDetails"
}
],
"nullable": true "nullable": true
}, },
"created_at": { "created_at": {