chore: merging back release v0.3.0 back to main (#636) (#655)

Co-authored-by: Sangamesh Kulkarni <59434228+Sangamesh26@users.noreply.github.com>
Co-authored-by: ItsMeShashank <shashank.attarde@juspay.in>
Co-authored-by: Abhishek <abhishek.marrivagu@juspay.in>
Co-authored-by: Jagan <jaganelavarasan@gmail.com>
Co-authored-by: SamraatBansal <55536657+SamraatBansal@users.noreply.github.com>
Co-authored-by: Sampras Lopes <lsampras@protonmail.com>
This commit is contained in:
Arun Raj M
2023-02-26 13:55:17 +05:30
committed by GitHub
parent 7792de55ef
commit f3224cc4df
74 changed files with 5979 additions and 355 deletions

View File

@ -166,8 +166,20 @@ pub enum StripeErrorCode {
},
#[error(error_type = StripeErrorType::InvalidRequestError, code = "", message = "The mandate information is invalid. {message}")]
PaymentIntentMandateInvalid { message: String },
#[error(error_type = StripeErrorType::InvalidRequestError, code = "", message = "The payment with the specified payment_id '{payment_id}' already exists in our records.")]
DuplicatePayment { payment_id: String },
#[error(error_type = StripeErrorType::ConnectorError, code = "", message = "{code}: {message}")]
ExternalConnectorError {
code: String,
message: String,
connector: String,
status_code: u16,
},
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "The connector provided in the request is incorrect or not available")]
IncorrectConnectorNameGiven,
// [#216]: https://github.com/juspay/hyperswitch/issues/216
// Implement the remaining stripe error codes
@ -323,6 +335,8 @@ pub enum StripeErrorType {
ApiError,
CardError,
InvalidRequestError,
ConnectorError,
HyperswitchError,
}
impl From<errors::ApiErrorResponse> for StripeErrorCode {
@ -369,8 +383,21 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
errors::ApiErrorResponse::RefundFailed { data } => Self::RefundFailed, // Nothing at stripe to map
errors::ApiErrorResponse::InternalServerError => Self::InternalServerError, // not a stripe code
errors::ApiErrorResponse::ExternalConnectorError { .. } => Self::InternalServerError,
errors::ApiErrorResponse::IncorrectConnectorNameGiven => Self::InternalServerError,
errors::ApiErrorResponse::ExternalConnectorError {
code,
message,
connector,
status_code,
..
} => Self::ExternalConnectorError {
code,
message,
connector,
status_code,
},
errors::ApiErrorResponse::IncorrectConnectorNameGiven => {
Self::IncorrectConnectorNameGiven
}
errors::ApiErrorResponse::MandateActive => Self::MandateActive, //not a stripe code
errors::ApiErrorResponse::CustomerRedacted => Self::CustomerRedacted, //not a stripe code
errors::ApiErrorResponse::ConfigNotFound => Self::ConfigNotFound, // not a stripe code
@ -474,12 +501,16 @@ impl actix_web::ResponseError for StripeErrorCode {
| Self::ResourceIdNotFound
| Self::PaymentIntentMandateInvalid { .. }
| Self::PaymentIntentUnexpectedState { .. }
| Self::DuplicatePayment { .. } => StatusCode::BAD_REQUEST,
| Self::DuplicatePayment { .. }
| Self::IncorrectConnectorNameGiven => StatusCode::BAD_REQUEST,
Self::RefundFailed
| Self::InternalServerError
| Self::MandateActive
| Self::CustomerRedacted => StatusCode::INTERNAL_SERVER_ERROR,
Self::ReturnUrlUnavailable => StatusCode::SERVICE_UNAVAILABLE,
Self::ExternalConnectorError { status_code, .. } => {
StatusCode::from_u16(*status_code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
}
}
}

View File

@ -116,7 +116,7 @@ impl From<Shipping> for payments::Address {
#[derive(PartialEq, Eq, Deserialize, Clone)]
pub struct StripePaymentIntentRequest {
pub amount: Option<i64>, //amount in cents, hence passed as integer
pub connector: Option<api_enums::Connector>,
pub connector: Option<Vec<api_enums::Connector>>,
pub currency: Option<String>,
#[serde(rename = "amount_to_capture")]
pub amount_capturable: Option<i64>,
@ -126,7 +126,7 @@ pub struct StripePaymentIntentRequest {
pub description: Option<String>,
pub payment_method_data: Option<StripePaymentMethodData>,
pub receipt_email: Option<pii::Secret<String, pii::Email>>,
pub return_url: Option<String>,
pub return_url: Option<url::Url>,
pub setup_future_usage: Option<api_enums::FutureUsage>,
pub shipping: Option<Shipping>,
pub billing_details: Option<StripeBillingDetails>,
@ -265,40 +265,110 @@ pub struct StripeCaptureRequest {
#[derive(Default, Eq, PartialEq, Serialize)]
pub struct StripePaymentIntentResponse {
pub id: Option<String>,
pub object: String,
pub object: &'static str,
pub amount: i64,
pub amount_received: Option<i64>,
pub amount_capturable: Option<i64>,
pub currency: String,
pub status: StripePaymentStatus,
pub client_secret: Option<masking::Secret<String>>,
#[serde(with = "common_utils::custom_serde::iso8601::option")]
pub created: Option<time::PrimitiveDateTime>,
pub created: Option<i64>,
pub customer: Option<String>,
pub refunds: Option<Vec<refunds::RefundResponse>>,
pub mandate_id: Option<String>,
pub metadata: Option<Value>,
pub charges: Charges,
pub connector: Option<String>,
pub description: Option<String>,
pub mandate_data: Option<payments::MandateData>,
pub setup_future_usage: Option<api_models::enums::FutureUsage>,
pub off_session: Option<bool>,
pub return_url: Option<String>,
pub authentication_type: Option<api_models::enums::AuthenticationType>,
pub next_action: Option<payments::NextAction>,
pub cancellation_reason: Option<String>,
pub payment_method: Option<api_models::enums::PaymentMethodType>,
pub payment_method_data: Option<payments::PaymentMethodDataResponse>,
pub shipping: Option<payments::Address>,
pub billing: Option<payments::Address>,
#[serde(with = "common_utils::custom_serde::iso8601::option")]
pub capture_on: Option<time::PrimitiveDateTime>,
pub payment_token: Option<String>,
pub email: Option<masking::Secret<String, common_utils::pii::Email>>,
pub phone: Option<masking::Secret<String>>,
pub error_code: Option<String>,
pub error_message: Option<String>,
pub statement_descriptor_suffix: Option<String>,
pub statement_descriptor_name: Option<String>,
pub capture_method: Option<api_models::enums::CaptureMethod>,
pub name: Option<masking::Secret<String>>,
}
impl From<payments::PaymentsResponse> for StripePaymentIntentResponse {
fn from(resp: payments::PaymentsResponse) -> Self {
Self {
object: "payment_intent".to_owned(),
amount: resp.amount,
amount_received: resp.amount_received,
amount_capturable: resp.amount_capturable,
currency: resp.currency.to_lowercase(),
status: StripePaymentStatus::from(resp.status),
client_secret: resp.client_secret,
created: resp.created,
customer: resp.customer_id,
object: "payment_intent",
id: resp.payment_id,
status: StripePaymentStatus::from(resp.status),
amount: resp.amount,
amount_capturable: resp.amount_capturable,
amount_received: resp.amount_received,
connector: resp.connector,
client_secret: resp.client_secret,
created: resp.created.map(|t| t.assume_utc().unix_timestamp()),
currency: resp.currency.to_lowercase(),
customer: resp.customer_id,
description: resp.description,
refunds: resp.refunds,
mandate_id: resp.mandate_id,
mandate_data: resp.mandate_data,
setup_future_usage: resp.setup_future_usage,
off_session: resp.off_session,
capture_on: resp.capture_on,
capture_method: resp.capture_method,
payment_method: resp.payment_method,
payment_method_data: resp.payment_method_data,
payment_token: resp.payment_token,
shipping: resp.shipping,
billing: resp.billing,
email: resp.email,
name: resp.name,
phone: resp.phone,
return_url: resp.return_url,
authentication_type: resp.authentication_type,
statement_descriptor_name: resp.statement_descriptor_name,
statement_descriptor_suffix: resp.statement_descriptor_suffix,
next_action: resp.next_action,
cancellation_reason: resp.cancellation_reason,
error_code: resp.error_code,
error_message: resp.error_message,
metadata: resp.metadata,
charges: Charges::new(),
}
}
}
#[derive(Default, Eq, PartialEq, Serialize)]
pub struct Charges {
object: &'static str,
data: Vec<String>,
has_more: bool,
total_count: i32,
url: String,
}
impl Charges {
fn new() -> Self {
Self {
object: "list",
data: vec![],
has_more: false,
total_count: 0,
url: "http://placeholder".to_string(),
}
}
}
#[derive(Clone, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct StripePaymentListConstraints {

View File

@ -2,7 +2,7 @@ use std::{convert::From, default::Default};
use serde::{Deserialize, Serialize};
use crate::types::api::refunds;
use crate::{core::errors, types::api::refunds};
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct StripeCreateRefundRequest {
@ -23,6 +23,8 @@ pub struct StripeCreateRefundResponse {
pub currency: String,
pub payment_intent: String,
pub status: StripeRefundStatus,
pub created: Option<i64>,
pub metadata: serde_json::Value,
}
#[derive(Clone, Serialize, Deserialize, Eq, PartialEq)]
@ -40,6 +42,7 @@ impl From<StripeCreateRefundRequest> for refunds::RefundRequest {
amount: req.amount,
payment_id: req.payment_intent,
reason: req.reason,
refund_type: Some(refunds::RefundType::Instant),
..Default::default()
}
}
@ -65,14 +68,17 @@ impl From<refunds::RefundStatus> for StripeRefundStatus {
}
}
impl From<refunds::RefundResponse> for StripeCreateRefundResponse {
fn from(res: refunds::RefundResponse) -> Self {
Self {
impl TryFrom<refunds::RefundResponse> for StripeCreateRefundResponse {
type Error = error_stack::Report<errors::ApiErrorResponse>;
fn try_from(res: refunds::RefundResponse) -> Result<Self, Self::Error> {
Ok(Self {
id: res.refund_id,
amount: res.amount,
currency: res.currency.to_ascii_lowercase(),
payment_intent: res.payment_id,
status: res.status.into(),
}
created: res.created_at.map(|t| t.assume_utc().unix_timestamp()),
metadata: res.metadata.unwrap_or(serde_json::json!({})),
})
}
}

View File

@ -116,7 +116,7 @@ pub struct StripeSetupIntentRequest {
pub description: Option<String>,
pub payment_method_data: Option<StripePaymentMethodData>,
pub receipt_email: Option<pii::Secret<String, pii::Email>>,
pub return_url: Option<String>,
pub return_url: Option<url::Url>,
pub setup_future_usage: Option<api_enums::FutureUsage>,
pub shipping: Option<Shipping>,
pub billing_details: Option<StripeBillingDetails>,

View File

@ -23,7 +23,7 @@ where
F: Fn(&'b A, U, T) -> Fut,
Fut: Future<Output = RouterResult<api::ApplicationResponse<Q>>>,
Q: Serialize + std::fmt::Debug + 'a,
S: From<Q> + Serialize,
S: TryFrom<Q> + Serialize,
E: Serialize + error_stack::Context + actix_web::ResponseError + Clone,
errors::ApiErrorResponse: ErrorSwitch<E>,
T: std::fmt::Debug,