mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
455 lines
13 KiB
Rust
455 lines
13 KiB
Rust
pub mod types;
|
|
|
|
use actix_web::{web, HttpRequest, HttpResponse};
|
|
use api_models::payments as payment_types;
|
|
use error_stack::report;
|
|
use router_env::{instrument, tracing, Flow};
|
|
|
|
use crate::{
|
|
compatibility::{stripe::errors, wrap},
|
|
core::payments,
|
|
routes,
|
|
services::{api, authentication as auth},
|
|
types::api::{self as api_types},
|
|
};
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCreate))]
|
|
pub async fn payment_intents_create(
|
|
state: web::Data<routes::AppState>,
|
|
qs_config: web::Data<serde_qs::Config>,
|
|
req: HttpRequest,
|
|
form_payload: web::Bytes,
|
|
) -> HttpResponse {
|
|
let payload: types::StripePaymentIntentRequest = match qs_config
|
|
.deserialize_bytes(&form_payload)
|
|
.map_err(|err| report!(errors::StripeErrorCode::from(err)))
|
|
{
|
|
Ok(p) => p,
|
|
Err(err) => return api::log_and_return_error_response(err),
|
|
};
|
|
|
|
let create_payment_req: payment_types::PaymentsRequest = match payload.try_into() {
|
|
Ok(req) => req,
|
|
Err(err) => return api::log_and_return_error_response(err),
|
|
};
|
|
|
|
let flow = Flow::PaymentsCreate;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
create_payment_req,
|
|
|state, auth, req| {
|
|
payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _>(
|
|
state,
|
|
auth.merchant_account,
|
|
auth.key_store,
|
|
payments::PaymentCreate,
|
|
req,
|
|
api::AuthFlow::Merchant,
|
|
payments::CallConnectorAction::Trigger,
|
|
)
|
|
},
|
|
&auth::ApiKeyAuth,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsRetrieve))]
|
|
pub async fn payment_intents_retrieve(
|
|
state: web::Data<routes::AppState>,
|
|
req: HttpRequest,
|
|
path: web::Path<String>,
|
|
query_payload: web::Query<types::StripePaymentRetrieveBody>,
|
|
) -> HttpResponse {
|
|
let payload = payment_types::PaymentsRetrieveRequest {
|
|
resource_id: api_types::PaymentIdType::PaymentIntentId(path.to_string()),
|
|
merchant_id: None,
|
|
force_sync: true,
|
|
connector: None,
|
|
param: None,
|
|
merchant_connector_details: None,
|
|
client_secret: query_payload.client_secret.clone(),
|
|
};
|
|
|
|
let (auth_type, auth_flow) =
|
|
match auth::check_client_secret_and_get_auth(req.headers(), &payload) {
|
|
Ok(auth) => auth,
|
|
Err(err) => return api::log_and_return_error_response(report!(err)),
|
|
};
|
|
|
|
let flow = Flow::PaymentsRetrieve;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
payload,
|
|
|state, auth, payload| {
|
|
payments::payments_core::<api_types::PSync, api_types::PaymentsResponse, _, _, _>(
|
|
state,
|
|
auth.merchant_account,
|
|
auth.key_store,
|
|
payments::PaymentStatus,
|
|
payload,
|
|
auth_flow,
|
|
payments::CallConnectorAction::Trigger,
|
|
)
|
|
},
|
|
&*auth_type,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsRetrieve))]
|
|
pub async fn payment_intents_retrieve_with_gateway_creds(
|
|
state: web::Data<routes::AppState>,
|
|
qs_config: web::Data<serde_qs::Config>,
|
|
req: HttpRequest,
|
|
form_payload: web::Bytes,
|
|
) -> HttpResponse {
|
|
let json_payload: payment_types::PaymentRetrieveBodyWithCredentials = match qs_config
|
|
.deserialize_bytes(&form_payload)
|
|
.map_err(|err| report!(errors::StripeErrorCode::from(err)))
|
|
{
|
|
Ok(p) => p,
|
|
Err(err) => return api::log_and_return_error_response(err),
|
|
};
|
|
|
|
let payload = payment_types::PaymentsRetrieveRequest {
|
|
resource_id: payment_types::PaymentIdType::PaymentIntentId(
|
|
json_payload.payment_id.to_string(),
|
|
),
|
|
merchant_id: json_payload.merchant_id.clone(),
|
|
force_sync: json_payload.force_sync.unwrap_or(false),
|
|
merchant_connector_details: json_payload.merchant_connector_details.clone(),
|
|
..Default::default()
|
|
};
|
|
let (auth_type, _auth_flow) = match auth::get_auth_type_and_flow(req.headers()) {
|
|
Ok(auth) => auth,
|
|
Err(err) => return api::log_and_return_error_response(report!(err)),
|
|
};
|
|
|
|
let flow = Flow::PaymentsRetrieve;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
payload,
|
|
|state, auth, req| {
|
|
payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _>(
|
|
state,
|
|
auth.merchant_account,
|
|
auth.key_store,
|
|
payments::PaymentStatus,
|
|
req,
|
|
api::AuthFlow::Merchant,
|
|
payments::CallConnectorAction::Trigger,
|
|
)
|
|
},
|
|
&*auth_type,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsUpdate))]
|
|
pub async fn payment_intents_update(
|
|
state: web::Data<routes::AppState>,
|
|
qs_config: web::Data<serde_qs::Config>,
|
|
req: HttpRequest,
|
|
form_payload: web::Bytes,
|
|
path: web::Path<String>,
|
|
) -> HttpResponse {
|
|
let payment_id = path.into_inner();
|
|
let stripe_payload: types::StripePaymentIntentRequest = match qs_config
|
|
.deserialize_bytes(&form_payload)
|
|
{
|
|
Ok(p) => p,
|
|
Err(err) => {
|
|
return api::log_and_return_error_response(report!(errors::StripeErrorCode::from(err)))
|
|
}
|
|
};
|
|
|
|
let mut payload: payment_types::PaymentsRequest = match stripe_payload.try_into() {
|
|
Ok(req) => req,
|
|
Err(err) => return api::log_and_return_error_response(err),
|
|
};
|
|
|
|
payload.payment_id = Some(api_types::PaymentIdType::PaymentIntentId(payment_id));
|
|
|
|
let (auth_type, auth_flow) = match auth::get_auth_type_and_flow(req.headers()) {
|
|
Ok(auth) => auth,
|
|
Err(err) => return api::log_and_return_error_response(report!(err)),
|
|
};
|
|
|
|
let flow = Flow::PaymentsUpdate;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
payload,
|
|
|state, auth, req| {
|
|
payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _>(
|
|
state,
|
|
auth.merchant_account,
|
|
auth.key_store,
|
|
payments::PaymentUpdate,
|
|
req,
|
|
auth_flow,
|
|
payments::CallConnectorAction::Trigger,
|
|
)
|
|
},
|
|
&*auth_type,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsConfirm))]
|
|
pub async fn payment_intents_confirm(
|
|
state: web::Data<routes::AppState>,
|
|
qs_config: web::Data<serde_qs::Config>,
|
|
req: HttpRequest,
|
|
form_payload: web::Bytes,
|
|
path: web::Path<String>,
|
|
) -> HttpResponse {
|
|
let payment_id = path.into_inner();
|
|
let stripe_payload: types::StripePaymentIntentRequest = match qs_config
|
|
.deserialize_bytes(&form_payload)
|
|
{
|
|
Ok(p) => p,
|
|
Err(err) => {
|
|
return api::log_and_return_error_response(report!(errors::StripeErrorCode::from(err)))
|
|
}
|
|
};
|
|
|
|
let mut payload: payment_types::PaymentsRequest = match stripe_payload.try_into() {
|
|
Ok(req) => req,
|
|
Err(err) => return api::log_and_return_error_response(err),
|
|
};
|
|
|
|
payload.payment_id = Some(api_types::PaymentIdType::PaymentIntentId(payment_id));
|
|
payload.confirm = Some(true);
|
|
|
|
let (auth_type, auth_flow) =
|
|
match auth::check_client_secret_and_get_auth(req.headers(), &payload) {
|
|
Ok(auth) => auth,
|
|
Err(err) => return api::log_and_return_error_response(err),
|
|
};
|
|
|
|
let flow = Flow::PaymentsConfirm;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
payload,
|
|
|state, auth, req| {
|
|
payments::payments_core::<api_types::Authorize, api_types::PaymentsResponse, _, _, _>(
|
|
state,
|
|
auth.merchant_account,
|
|
auth.key_store,
|
|
payments::PaymentConfirm,
|
|
req,
|
|
auth_flow,
|
|
payments::CallConnectorAction::Trigger,
|
|
)
|
|
},
|
|
&*auth_type,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCapture))]
|
|
pub async fn payment_intents_capture(
|
|
state: web::Data<routes::AppState>,
|
|
qs_config: web::Data<serde_qs::Config>,
|
|
req: HttpRequest,
|
|
form_payload: web::Bytes,
|
|
path: web::Path<String>,
|
|
) -> HttpResponse {
|
|
let stripe_payload: payment_types::PaymentsCaptureRequest = match qs_config
|
|
.deserialize_bytes(&form_payload)
|
|
{
|
|
Ok(p) => p,
|
|
Err(err) => {
|
|
return api::log_and_return_error_response(report!(errors::StripeErrorCode::from(err)))
|
|
}
|
|
};
|
|
|
|
let capture_payload = payment_types::PaymentsCaptureRequest {
|
|
payment_id: Some(path.into_inner()),
|
|
..stripe_payload
|
|
};
|
|
|
|
let flow = Flow::PaymentsCapture;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
capture_payload,
|
|
|state, auth, payload| {
|
|
payments::payments_core::<api_types::Capture, api_types::PaymentsResponse, _, _, _>(
|
|
state,
|
|
auth.merchant_account,
|
|
auth.key_store,
|
|
payments::PaymentCapture,
|
|
payload,
|
|
api::AuthFlow::Merchant,
|
|
payments::CallConnectorAction::Trigger,
|
|
)
|
|
},
|
|
&auth::ApiKeyAuth,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCancel))]
|
|
pub async fn payment_intents_cancel(
|
|
state: web::Data<routes::AppState>,
|
|
qs_config: web::Data<serde_qs::Config>,
|
|
req: HttpRequest,
|
|
form_payload: web::Bytes,
|
|
path: web::Path<String>,
|
|
) -> HttpResponse {
|
|
let payment_id = path.into_inner();
|
|
let stripe_payload: types::StripePaymentCancelRequest = match qs_config
|
|
.deserialize_bytes(&form_payload)
|
|
{
|
|
Ok(p) => p,
|
|
Err(err) => {
|
|
return api::log_and_return_error_response(report!(errors::StripeErrorCode::from(err)))
|
|
}
|
|
};
|
|
|
|
let mut payload: payment_types::PaymentsCancelRequest = stripe_payload.into();
|
|
payload.payment_id = payment_id;
|
|
|
|
let (auth_type, auth_flow) = match auth::get_auth_type_and_flow(req.headers()) {
|
|
Ok(auth) => auth,
|
|
Err(err) => return api::log_and_return_error_response(report!(err)),
|
|
};
|
|
|
|
let flow = Flow::PaymentsCancel;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
payload,
|
|
|state, auth, req| {
|
|
payments::payments_core::<api_types::Void, api_types::PaymentsResponse, _, _, _>(
|
|
state,
|
|
auth.merchant_account,
|
|
auth.key_store,
|
|
payments::PaymentCancel,
|
|
req,
|
|
auth_flow,
|
|
payments::CallConnectorAction::Trigger,
|
|
)
|
|
},
|
|
&*auth_type,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[instrument(skip_all, fields(flow = ?Flow::PaymentsList))]
|
|
#[cfg(feature = "olap")]
|
|
pub async fn payment_intent_list(
|
|
state: web::Data<routes::AppState>,
|
|
req: HttpRequest,
|
|
payload: web::Query<types::StripePaymentListConstraints>,
|
|
) -> HttpResponse {
|
|
let payload = match payment_types::PaymentListConstraints::try_from(payload.into_inner()) {
|
|
Ok(p) => p,
|
|
Err(err) => return api::log_and_return_error_response(err),
|
|
};
|
|
|
|
let flow = Flow::PaymentsList;
|
|
|
|
wrap::compatibility_api_wrap::<
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
_,
|
|
types::StripePaymentIntentListResponse,
|
|
errors::StripeErrorCode,
|
|
>(
|
|
flow,
|
|
state.get_ref(),
|
|
&req,
|
|
payload,
|
|
|state, auth, req| payments::list_payments(&*state.store, auth.merchant_account, req),
|
|
&auth::ApiKeyAuth,
|
|
)
|
|
.await
|
|
}
|