fix: resolve TODO/FIXME from router.routes (#283)

This commit is contained in:
Nishant Joshi
2023-01-05 11:54:40 +05:30
committed by GitHub
parent def94eff2f
commit 09c745f92f
3 changed files with 127 additions and 115 deletions

View File

@ -115,7 +115,6 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
) )
.await?; .await?;
// TODO: get payment method data for response
Ok(( Ok((
Box::new(self), Box::new(self),
payments::PaymentData { payments::PaymentData {

View File

@ -1,5 +1,3 @@
// TODO: Move this to router_env https://juspay.atlassian.net/browse/ORCA-345
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use router_env::opentelemetry::{ use router_env::opentelemetry::{
global, global,

View File

@ -1,38 +1,26 @@
use std::borrow::Cow; use std::borrow::Cow;
use actix_web::{ use actix_web::{web, Responder};
body::{BoxBody, MessageBody},
web, HttpRequest, HttpResponse, Responder,
};
use error_stack::report; use error_stack::report;
use router_env::{ use router_env::{
tracing::{self, instrument}, tracing::{self, instrument},
Flow, Flow,
}; };
use super::app::AppState;
use crate::{ use crate::{
self as app,
core::{errors::http_not_implemented, payments}, core::{errors::http_not_implemented, payments},
services::api, services::api,
types::api::{ types::api::{self as api_types, enums as api_enums, payments as payment_types},
self as api_types, enums as api_enums,
payments::{
PaymentIdType, PaymentListConstraints, PaymentsCancelRequest, PaymentsCaptureRequest,
PaymentsRequest, PaymentsResponse, PaymentsRetrieveRequest,
},
Authorize, Capture, PSync, PaymentRetrieveBody, PaymentsSessionRequest,
PaymentsSessionResponse, PaymentsStartRequest, Session, Verify, Void,
},
//FIXME: remove specific imports
}; };
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCreate))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsCreate))]
// #[post("")] // #[post("")]
pub async fn payments_create( pub async fn payments_create(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
json_payload: web::Json<PaymentsRequest>, json_payload: web::Json<payment_types::PaymentsRequest>,
) -> HttpResponse { ) -> impl Responder {
let payload = json_payload.into_inner(); let payload = json_payload.into_inner();
if let Some(api_enums::CaptureMethod::Scheduled) = payload.capture_method { if let Some(api_enums::CaptureMethod::Scheduled) = payload.capture_method {
@ -44,37 +32,13 @@ pub async fn payments_create(
&req, &req,
payload, payload,
|state, merchant_account, req| { |state, merchant_account, req| {
// TODO: Change for making it possible for the flow to be inferred internally or through validation layer authorize_verify_select(
async { payments::PaymentCreate,
let connector = req.connector;
match req.amount.as_ref() {
Some(api_types::Amount::Value(_)) | None => {
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>(
state, state,
merchant_account, merchant_account,
payments::PaymentCreate,
req, req,
api::AuthFlow::Merchant, api::AuthFlow::Merchant,
connector,
payments::CallConnectorAction::Trigger,
) )
.await
}
Some(api_types::Amount::Zero) => {
payments::payments_core::<Verify, PaymentsResponse, _, _, _>(
state,
merchant_account,
payments::PaymentCreate,
req,
api::AuthFlow::Merchant,
connector,
payments::CallConnectorAction::Trigger,
)
.await
}
}
}
}, },
api::MerchantAuthentication::ApiKey, api::MerchantAuthentication::ApiKey,
) )
@ -83,12 +47,12 @@ pub async fn payments_create(
#[instrument(skip(state), fields(flow = ?Flow::PaymentsStart))] #[instrument(skip(state), fields(flow = ?Flow::PaymentsStart))]
pub async fn payments_start( pub async fn payments_start(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
path: web::Path<(String, String, String)>, path: web::Path<(String, String, String)>,
) -> HttpResponse { ) -> impl Responder {
let (payment_id, merchant_id, attempt_id) = path.into_inner(); let (payment_id, merchant_id, attempt_id) = path.into_inner();
let payload = PaymentsStartRequest { let payload = payment_types::PaymentsStartRequest {
payment_id: payment_id.clone(), payment_id: payment_id.clone(),
merchant_id: merchant_id.clone(), merchant_id: merchant_id.clone(),
txn_id: attempt_id.clone(), txn_id: attempt_id.clone(),
@ -98,7 +62,7 @@ pub async fn payments_start(
&req, &req,
payload, payload,
|state, merchant_account, req| { |state, merchant_account, req| {
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>( payments::payments_core::<api_types::Authorize, payment_types::PaymentsResponse, _, _, _>(
state, state,
merchant_account, merchant_account,
payments::operations::PaymentStart, payments::operations::PaymentStart,
@ -116,13 +80,13 @@ pub async fn payments_start(
#[instrument(skip(state), fields(flow = ?Flow::PaymentsRetrieve))] #[instrument(skip(state), fields(flow = ?Flow::PaymentsRetrieve))]
// #[get("/{payment_id}")] // #[get("/{payment_id}")]
pub async fn payments_retrieve( pub async fn payments_retrieve(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
path: web::Path<String>, path: web::Path<String>,
json_payload: web::Query<PaymentRetrieveBody>, json_payload: web::Query<payment_types::PaymentRetrieveBody>,
) -> HttpResponse { ) -> impl Responder {
let payload = PaymentsRetrieveRequest { let payload = payment_types::PaymentsRetrieveRequest {
resource_id: PaymentIdType::PaymentIntentId(path.to_string()), resource_id: payment_types::PaymentIdType::PaymentIntentId(path.to_string()),
merchant_id: json_payload.merchant_id.clone(), merchant_id: json_payload.merchant_id.clone(),
force_sync: json_payload.force_sync.unwrap_or(false), force_sync: json_payload.force_sync.unwrap_or(false),
param: None, param: None,
@ -139,7 +103,7 @@ pub async fn payments_retrieve(
&req, &req,
payload, payload,
|state, merchant_account, req| { |state, merchant_account, req| {
payments::payments_core::<PSync, PaymentsResponse, _, _, _>( payments::payments_core::<api_types::PSync, payment_types::PaymentsResponse, _, _, _>(
state, state,
merchant_account, merchant_account,
payments::PaymentStatus, payments::PaymentStatus,
@ -157,11 +121,11 @@ pub async fn payments_retrieve(
#[instrument(skip_all, fields(flow = ?Flow::PaymentsUpdate))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsUpdate))]
// #[post("/{payment_id}")] // #[post("/{payment_id}")]
pub async fn payments_update( pub async fn payments_update(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
json_payload: web::Json<PaymentsRequest>, json_payload: web::Json<payment_types::PaymentsRequest>,
path: web::Path<String>, path: web::Path<String>,
) -> HttpResponse { ) -> impl Responder {
let mut payload = json_payload.into_inner(); let mut payload = json_payload.into_inner();
if let Some(api_enums::CaptureMethod::Scheduled) = payload.capture_method { if let Some(api_enums::CaptureMethod::Scheduled) = payload.capture_method {
@ -170,7 +134,7 @@ pub async fn payments_update(
let payment_id = path.into_inner(); let payment_id = path.into_inner();
payload.payment_id = Some(PaymentIdType::PaymentIntentId(payment_id)); payload.payment_id = Some(payment_types::PaymentIdType::PaymentIntentId(payment_id));
let auth_type; let auth_type;
(payload, auth_type) = match api::get_auth_type_and_check_client_secret(&req, payload) { (payload, auth_type) = match api::get_auth_type_and_check_client_secret(&req, payload) {
@ -185,15 +149,12 @@ pub async fn payments_update(
&req, &req,
payload, payload,
|state, merchant_account, req| { |state, merchant_account, req| {
let connector = req.connector; authorize_verify_select(
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>( payments::PaymentUpdate,
state, state,
merchant_account, merchant_account,
payments::PaymentUpdate,
req, req,
auth_flow, auth_flow,
connector,
payments::CallConnectorAction::Trigger,
) )
}, },
auth_type, auth_type,
@ -204,11 +165,11 @@ pub async fn payments_update(
#[instrument(skip_all, fields(flow = ?Flow::PaymentsConfirm))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsConfirm))]
// #[post("/{payment_id}/confirm")] // #[post("/{payment_id}/confirm")]
pub async fn payments_confirm( pub async fn payments_confirm(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
json_payload: web::Json<PaymentsRequest>, json_payload: web::Json<payment_types::PaymentsRequest>,
path: web::Path<String>, path: web::Path<String>,
) -> HttpResponse { ) -> impl Responder {
let mut payload = json_payload.into_inner(); let mut payload = json_payload.into_inner();
if let Some(api_enums::CaptureMethod::Scheduled) = payload.capture_method { if let Some(api_enums::CaptureMethod::Scheduled) = payload.capture_method {
@ -216,7 +177,7 @@ pub async fn payments_confirm(
}; };
let payment_id = path.into_inner(); let payment_id = path.into_inner();
payload.payment_id = Some(PaymentIdType::PaymentIntentId(payment_id)); payload.payment_id = Some(payment_types::PaymentIdType::PaymentIntentId(payment_id));
payload.confirm = Some(true); payload.confirm = Some(true);
let auth_type; let auth_type;
@ -231,15 +192,12 @@ pub async fn payments_confirm(
&req, &req,
payload, payload,
|state, merchant_account, req| { |state, merchant_account, req| {
let connector = req.connector; authorize_verify_select(
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>( payments::PaymentConfirm,
state, state,
merchant_account, merchant_account,
payments::PaymentConfirm,
req, req,
auth_flow, auth_flow,
connector,
payments::CallConnectorAction::Trigger,
) )
}, },
auth_type, auth_type,
@ -250,12 +208,12 @@ pub async fn payments_confirm(
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCapture))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsCapture))]
// #[post("/{payment_id}/capture")] // #[post("/{payment_id}/capture")]
pub async fn payments_capture( pub async fn payments_capture(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
json_payload: web::Json<PaymentsCaptureRequest>, json_payload: web::Json<payment_types::PaymentsCaptureRequest>,
path: web::Path<String>, path: web::Path<String>,
) -> HttpResponse { ) -> impl Responder {
let capture_payload = PaymentsCaptureRequest { let capture_payload = payment_types::PaymentsCaptureRequest {
payment_id: Some(path.into_inner()), payment_id: Some(path.into_inner()),
..json_payload.into_inner() ..json_payload.into_inner()
}; };
@ -265,7 +223,7 @@ pub async fn payments_capture(
&req, &req,
capture_payload, capture_payload,
|state, merchant_account, payload| { |state, merchant_account, payload| {
payments::payments_core::<Capture, PaymentsResponse, _, _, _>( payments::payments_core::<api_types::Capture, payment_types::PaymentsResponse, _, _, _>(
state, state,
merchant_account, merchant_account,
payments::PaymentCapture, payments::PaymentCapture,
@ -282,10 +240,10 @@ pub async fn payments_capture(
#[instrument(skip_all, fields(flow = ?Flow::PaymentsSessionToken))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsSessionToken))]
pub async fn payments_connector_session( pub async fn payments_connector_session(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
json_payload: web::Json<PaymentsSessionRequest>, json_payload: web::Json<payment_types::PaymentsSessionRequest>,
) -> HttpResponse { ) -> impl Responder {
let sessions_payload = json_payload.into_inner(); let sessions_payload = json_payload.into_inner();
api::server_wrap( api::server_wrap(
@ -293,7 +251,13 @@ pub async fn payments_connector_session(
&req, &req,
sessions_payload, sessions_payload,
|state, merchant_account, payload| { |state, merchant_account, payload| {
payments::payments_core::<Session, PaymentsSessionResponse, _, _, _>( payments::payments_core::<
api_types::Session,
payment_types::PaymentsSessionResponse,
_,
_,
_,
>(
state, state,
merchant_account, merchant_account,
payments::PaymentSession, payments::PaymentSession,
@ -310,15 +274,15 @@ pub async fn payments_connector_session(
#[instrument(skip_all)] #[instrument(skip_all)]
pub async fn payments_response( pub async fn payments_response(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
path: web::Path<(String, String, String)>, path: web::Path<(String, String, String)>,
) -> HttpResponse { ) -> impl Responder {
let (payment_id, merchant_id, connector) = path.into_inner(); let (payment_id, merchant_id, connector) = path.into_inner();
let param_string = req.query_string(); let param_string = req.query_string();
let payload = PaymentsRetrieveRequest { let payload = payment_types::PaymentsRetrieveRequest {
resource_id: PaymentIdType::PaymentIntentId(payment_id), resource_id: payment_types::PaymentIdType::PaymentIntentId(payment_id),
merchant_id: Some(merchant_id.clone()), merchant_id: Some(merchant_id.clone()),
force_sync: true, force_sync: true,
param: Some(param_string.to_string()), param: Some(param_string.to_string()),
@ -329,7 +293,11 @@ pub async fn payments_response(
&req, &req,
payload, payload,
|state, merchant_account, req| { |state, merchant_account, req| {
payments::handle_payments_redirect_response::<PSync>(state, merchant_account, req) payments::handle_payments_redirect_response::<api_types::PSync>(
state,
merchant_account,
req,
)
}, },
api::MerchantAuthentication::MerchantId(Cow::Borrowed(&merchant_id)), api::MerchantAuthentication::MerchantId(Cow::Borrowed(&merchant_id)),
) )
@ -339,9 +307,9 @@ pub async fn payments_response(
#[instrument(skip_all, fields(flow = ?Flow::PaymentsCancel))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsCancel))]
// #[post("/{payment_id}/cancel")] // #[post("/{payment_id}/cancel")]
pub async fn payments_cancel( pub async fn payments_cancel(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
json_payload: web::Json<PaymentsCancelRequest>, json_payload: web::Json<payment_types::PaymentsCancelRequest>,
path: web::Path<String>, path: web::Path<String>,
) -> impl Responder { ) -> impl Responder {
let mut payload = json_payload.into_inner(); let mut payload = json_payload.into_inner();
@ -353,7 +321,7 @@ pub async fn payments_cancel(
&req, &req,
payload, payload,
|state, merchant_account, req| { |state, merchant_account, req| {
payments::payments_core::<Void, PaymentsResponse, _, _, _>( payments::payments_core::<api_types::Void, payment_types::PaymentsResponse, _, _, _>(
state, state,
merchant_account, merchant_account,
payments::PaymentCancel, payments::PaymentCancel,
@ -371,10 +339,10 @@ pub async fn payments_cancel(
#[instrument(skip_all, fields(flow = ?Flow::PaymentsList))] #[instrument(skip_all, fields(flow = ?Flow::PaymentsList))]
// #[get("/list")] // #[get("/list")]
pub async fn payments_list( pub async fn payments_list(
state: web::Data<AppState>, state: web::Data<app::AppState>,
req: HttpRequest, req: actix_web::HttpRequest,
payload: web::Query<PaymentListConstraints>, payload: web::Query<payment_types::PaymentListConstraints>,
) -> HttpResponse { ) -> impl Responder {
let payload = payload.into_inner(); let payload = payload.into_inner();
api::server_wrap( api::server_wrap(
&state, &state,
@ -388,9 +356,56 @@ pub async fn payments_list(
.await .await
} }
fn _http_response<T: MessageBody + 'static>(response: T) -> HttpResponse<BoxBody> { async fn authorize_verify_select<Op>(
HttpResponse::Ok() operation: Op,
.content_type("application/json") state: &app::AppState,
.append_header(("Via", "Juspay_router")) merchant_account: storage_models::merchant_account::MerchantAccount,
.body(response) req: api_models::payments::PaymentsRequest,
auth_flow: api::AuthFlow,
) -> app::core::errors::RouterResponse<api_models::payments::PaymentsResponse>
where
Op: Sync
+ Clone
+ std::fmt::Debug
+ payments::operations::Operation<api_types::Authorize, api_models::payments::PaymentsRequest>
+ payments::operations::Operation<api_types::Verify, api_models::payments::PaymentsRequest>,
{
// TODO: Change for making it possible for the flow to be inferred internally or through validation layer
// This is a temporary fix.
// After analyzing the code structure,
// the operation are flow agnostic, and the flow is only required in the post_update_tracker
// Thus the flow can be generated just before calling the connector instead of explicitly passing it here.
let connector = req.connector;
match req.amount.as_ref() {
Some(api_types::Amount::Value(_)) | None => payments::payments_core::<
api_types::Authorize,
payment_types::PaymentsResponse,
_,
_,
_,
>(
state,
merchant_account,
operation,
req,
auth_flow,
connector,
payments::CallConnectorAction::Trigger,
)
.await,
Some(api_types::Amount::Zero) => {
payments::payments_core::<api_types::Verify, payment_types::PaymentsResponse, _, _, _>(
state,
merchant_account,
operation,
req,
auth_flow,
connector,
payments::CallConnectorAction::Trigger,
)
.await
}
}
} }