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 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")]

View File

@ -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()
}
}

View File

@ -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,

View File

@ -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": {