Skip to content

Commit ab7fc23

Browse files
fix(stripe): add setup intent sync for stripe (#953)
Co-authored-by: Arun Raj M <[email protected]>
1 parent 1318599 commit ab7fc23

File tree

3 files changed

+90
-13
lines changed

3 files changed

+90
-13
lines changed

crates/router/src/connector/stripe.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -334,13 +334,22 @@ impl
334334
connectors: &settings::Connectors,
335335
) -> CustomResult<String, errors::ConnectorError> {
336336
let id = req.request.connector_transaction_id.clone();
337-
Ok(format!(
338-
"{}{}/{}",
339-
self.base_url(connectors),
340-
"v1/payment_intents",
341-
id.get_connector_transaction_id()
342-
.change_context(errors::ConnectorError::MissingConnectorTransactionID)?
343-
))
337+
338+
match id.get_connector_transaction_id() {
339+
Ok(x) if x.starts_with("set") => Ok(format!(
340+
"{}{}/{}",
341+
self.base_url(connectors),
342+
"v1/setup_intents",
343+
x
344+
)),
345+
Ok(x) => Ok(format!(
346+
"{}{}/{}",
347+
self.base_url(connectors),
348+
"v1/payment_intents",
349+
x
350+
)),
351+
x => x.change_context(errors::ConnectorError::MissingConnectorTransactionID),
352+
}
344353
}
345354

346355
fn build_request(
@@ -368,10 +377,22 @@ impl
368377
types::PaymentsAuthorizeData: Clone,
369378
types::PaymentsResponseData: Clone,
370379
{
371-
let response: stripe::PaymentIntentSyncResponse = res
372-
.response
373-
.parse_struct("PaymentIntentSyncResponse")
374-
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
380+
let id = data.request.connector_transaction_id.clone();
381+
let response: transformers::PaymentIntentSyncResponse =
382+
match id.get_connector_transaction_id() {
383+
Ok(x) if x.starts_with("set") => res
384+
.response
385+
.parse_struct("SetupIntentSyncResponse")
386+
.change_context(errors::ConnectorError::ResponseDeserializationFailed),
387+
Ok(_) => res
388+
.response
389+
.parse_struct("PaymentIntentSyncResponse")
390+
.change_context(errors::ConnectorError::ResponseDeserializationFailed),
391+
Err(err) => {
392+
Err(err).change_context(errors::ConnectorError::MissingConnectorTransactionID)
393+
}
394+
}?;
395+
375396
types::RouterData::try_from(types::ResponseRouterData {
376397
response,
377398
data: data.clone(),

crates/router/src/connector/stripe/transformers.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ pub struct SetupIntentRequest {
116116
pub confirm: bool,
117117
pub usage: Option<enums::FutureUsage>,
118118
pub off_session: Option<bool>,
119+
pub return_url: Option<String>,
119120
#[serde(flatten)]
120121
pub payment_data: StripePaymentMethodData,
121122
}
@@ -920,6 +921,7 @@ impl TryFrom<&types::VerifyRouterData> for SetupIntentRequest {
920921
metadata_txn_id,
921922
metadata_txn_uuid,
922923
payment_data,
924+
return_url: item.return_url.clone(),
923925
off_session: item.request.off_session,
924926
usage: item.request.setup_future_usage,
925927
})
@@ -1039,6 +1041,50 @@ impl std::ops::Deref for PaymentIntentSyncResponse {
10391041
}
10401042
}
10411043

1044+
#[derive(Deserialize)]
1045+
pub struct SetupIntentSyncResponse {
1046+
#[serde(flatten)]
1047+
setup_intent_fields: SetupIntentResponse,
1048+
pub last_payment_error: Option<LastPaymentError>,
1049+
}
1050+
1051+
impl std::ops::Deref for SetupIntentSyncResponse {
1052+
type Target = SetupIntentResponse;
1053+
1054+
fn deref(&self) -> &Self::Target {
1055+
&self.setup_intent_fields
1056+
}
1057+
}
1058+
1059+
impl From<SetupIntentSyncResponse> for PaymentIntentSyncResponse {
1060+
fn from(value: SetupIntentSyncResponse) -> Self {
1061+
Self {
1062+
payment_intent_fields: value.setup_intent_fields.into(),
1063+
last_payment_error: value.last_payment_error,
1064+
}
1065+
}
1066+
}
1067+
1068+
impl From<SetupIntentResponse> for PaymentIntentResponse {
1069+
fn from(value: SetupIntentResponse) -> Self {
1070+
Self {
1071+
id: value.id,
1072+
object: value.object,
1073+
status: value.status,
1074+
client_secret: value.client_secret,
1075+
customer: value.customer,
1076+
description: None,
1077+
statement_descriptor: value.statement_descriptor,
1078+
statement_descriptor_suffix: value.statement_descriptor_suffix,
1079+
metadata: value.metadata,
1080+
next_action: value.next_action,
1081+
payment_method_options: value.payment_method_options,
1082+
last_payment_error: None,
1083+
..Default::default()
1084+
}
1085+
}
1086+
}
1087+
10421088
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize)]
10431089
pub struct SetupIntentResponse {
10441090
pub id: String,

crates/router/src/core/payments/flows/verfiy_flow.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use async_trait::async_trait;
22

3-
use super::{ConstructFlowSpecificData, Feature};
3+
use super::{authorize_flow, ConstructFlowSpecificData, Feature};
44
use crate::{
55
core::{
66
errors::{ConnectorErrorExt, RouterResult},
@@ -89,7 +89,17 @@ impl types::VerifyRouterData {
8989
)
9090
.await
9191
.map_err(|err| err.to_verify_failed_response())?;
92-
Ok(mandate::mandate_procedure(state, resp, maybe_customer, None).await?)
92+
93+
let pm_id = authorize_flow::save_payment_method(
94+
state,
95+
connector,
96+
resp.to_owned(),
97+
maybe_customer,
98+
_merchant_account,
99+
)
100+
.await?;
101+
102+
Ok(mandate::mandate_procedure(state, resp, maybe_customer, pm_id).await?)
93103
}
94104
_ => Ok(self.clone()),
95105
}

0 commit comments

Comments
 (0)