Bug: [FEATURE]: Add a new endpoint Complete Authorize



### Feature Description

Add a new endpoint Complete Authorize
### Possible Implementation

- This will be used in the cases where we get shipping after confirm call and we need to call the connector 2nd time.
- Collect shipping address in complete authorize call


### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/crates/api_models/src/events/payment.rs b/crates/api_models/src/events/payment.rs
index 59e65c0605f..cd1671b2b8e 100644
--- a/crates/api_models/src/events/payment.rs
+++ b/crates/api_models/src/events/payment.rs
@@ -11,10 +11,10 @@ use crate::{
         ExtendedCardInfoResponse, PaymentIdType, PaymentListConstraints,
         PaymentListFilterConstraints, PaymentListFilters, PaymentListFiltersV2,
         PaymentListResponse, PaymentListResponseV2, PaymentsApproveRequest, PaymentsCancelRequest,
-        PaymentsCaptureRequest, PaymentsExternalAuthenticationRequest,
-        PaymentsExternalAuthenticationResponse, PaymentsIncrementalAuthorizationRequest,
-        PaymentsRejectRequest, PaymentsRequest, PaymentsResponse, PaymentsRetrieveRequest,
-        PaymentsStartRequest, RedirectionResponse,
+        PaymentsCaptureRequest, PaymentsCompleteAuthorizeRequest,
+        PaymentsExternalAuthenticationRequest, PaymentsExternalAuthenticationResponse,
+        PaymentsIncrementalAuthorizationRequest, PaymentsRejectRequest, PaymentsRequest,
+        PaymentsResponse, PaymentsRetrieveRequest, PaymentsStartRequest, RedirectionResponse,
     },
 };
 impl ApiEventMetric for PaymentsRetrieveRequest {
@@ -44,6 +44,14 @@ impl ApiEventMetric for PaymentsCaptureRequest {
     }
 }
 
+impl ApiEventMetric for PaymentsCompleteAuthorizeRequest {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        Some(ApiEventsType::Payment {
+            payment_id: self.payment_id.clone(),
+        })
+    }
+}
+
 impl ApiEventMetric for PaymentsCancelRequest {
     fn get_api_event_type(&self) -> Option<ApiEventsType> {
         Some(ApiEventsType::Payment {
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index f00be78a039..8f4fca59d26 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -4343,6 +4343,18 @@ pub struct PaymentRetrieveBodyWithCredentials {
     pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
 }
 
+#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
+pub struct PaymentsCompleteAuthorizeRequest {
+    /// The unique identifier for the payment
+    #[serde(skip_deserializing)]
+    pub payment_id: String,
+    /// The shipping address for the payment
+    pub shipping: Option<Address>,
+    /// Client Secret
+    #[schema(value_type = String)]
+    pub client_secret: Secret<String>,
+}
+
 #[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
 pub struct PaymentsCancelRequest {
     /// The identifier for the payment
diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs
index d65fa6868b9..660db4d8b8b 100644
--- a/crates/diesel_models/src/payment_intent.rs
+++ b/crates/diesel_models/src/payment_intent.rs
@@ -202,6 +202,9 @@ pub enum PaymentIntentUpdate {
     AuthorizationCountUpdate {
         authorization_count: i32,
     },
+    CompleteAuthorizeUpdate {
+        shipping_address_id: Option<String>,
+    },
 }
 
 #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
@@ -503,6 +506,12 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 authorization_count: Some(authorization_count),
                 ..Default::default()
             },
+            PaymentIntentUpdate::CompleteAuthorizeUpdate {
+                shipping_address_id,
+            } => Self {
+                shipping_address_id,
+                ..Default::default()
+            },
         }
     }
 }
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
index 84dc56403c6..1322e66a149 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
@@ -203,6 +203,9 @@ pub enum PaymentIntentUpdate {
     AuthorizationCountUpdate {
         authorization_count: i32,
     },
+    CompleteAuthorizeUpdate {
+        shipping_address_id: Option<String>,
+    },
 }
 
 #[derive(Clone, Debug, Default)]
@@ -425,6 +428,12 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
                 authorization_count: Some(authorization_count),
                 ..Default::default()
             },
+            PaymentIntentUpdate::CompleteAuthorizeUpdate {
+                shipping_address_id,
+            } => Self {
+                shipping_address_id,
+                ..Default::default()
+            },
         }
     }
 }
diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs
index 5f5597387b1..018ea342099 100644
--- a/crates/openapi/src/openapi.rs
+++ b/crates/openapi/src/openapi.rs
@@ -81,6 +81,7 @@ Never share your secret api keys. Keep them guarded and secure.
         routes::payments::payments_incremental_authorization,
         routes::payment_link::payment_link_retrieve,
         routes::payments::payments_external_authentication,
+        routes::payments::payments_complete_authorize,
 
         // Routes for refunds
         routes::refunds::refunds_create,
@@ -402,6 +403,7 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::payments::CaptureResponse,
         api_models::payments::PaymentsIncrementalAuthorizationRequest,
         api_models::payments::IncrementalAuthorizationResponse,
+        api_models::payments::PaymentsCompleteAuthorizeRequest,
         api_models::payments::PaymentsExternalAuthenticationRequest,
         api_models::payments::PaymentsExternalAuthenticationResponse,
         api_models::payments::SdkInformation,
diff --git a/crates/openapi/src/routes/payments.rs b/crates/openapi/src/routes/payments.rs
index 20d87b91e79..1273bde7a36 100644
--- a/crates/openapi/src/routes/payments.rs
+++ b/crates/openapi/src/routes/payments.rs
@@ -486,3 +486,23 @@ pub fn payments_incremental_authorization() {}
   security(("publishable_key" = []))
 )]
 pub fn payments_external_authentication() {}
+
+/// Payments - Complete Authorize
+///
+///
+#[utoipa::path(
+  post,
+  path = "/{payment_id}/complete_authorize",
+  request_body=PaymentsCompleteAuthorizeRequest,
+  params(
+    ("payment_id" =String, Path, description =  "The identifier for payment")
+  ),
+ responses(
+      (status = 200, description = "Payments Complete Authorize Success", body = PaymentsResponse),
+      (status = 400, description = "Missing mandatory fields")
+  ),
+  tag = "Payments",
+  operation_id = "Complete Authorize a Payment",
+  security(("publishable_key" = []))
+)]
+pub fn payments_complete_authorize() {}
diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs
index a9736516725..3f57ba2830f 100644
--- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs
+++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs
@@ -59,6 +59,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
             .setup_future_usage
             .or(payment_intent.setup_future_usage);
 
+        helpers::authenticate_client_secret(request.client_secret.as_ref(), &payment_intent)?;
+
         helpers::validate_payment_status_against_not_allowed_statuses(
             &payment_intent.status,
             &[
@@ -173,16 +175,22 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
                 .or_else(|| request.customer_id.clone()),
         )?;
 
-        let shipping_address = helpers::get_address_by_id(
+        let shipping_address = helpers::create_or_update_address_for_payment_by_request(
             db,
-            payment_intent.shipping_address_id.clone(),
+            request.shipping.as_ref(),
+            payment_intent.shipping_address_id.clone().as_deref(),
+            merchant_id.as_ref(),
+            payment_intent.customer_id.as_ref(),
             key_store,
-            &payment_intent.payment_id,
-            merchant_id,
-            merchant_account.storage_scheme,
+            payment_id.as_ref(),
+            storage_scheme,
         )
         .await?;
 
+        payment_intent.shipping_address_id = shipping_address
+            .as_ref()
+            .map(|shipping_address| shipping_address.address_id.clone());
+
         let billing_address = helpers::get_address_by_id(
             db,
             payment_intent.billing_address_id.clone(),
@@ -421,11 +429,11 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Comple
     #[instrument(skip_all)]
     async fn update_trackers<'b>(
         &'b self,
-        _state: &'b AppState,
+        state: &'b AppState,
         _req_state: ReqState,
-        payment_data: PaymentData<F>,
+        mut payment_data: PaymentData<F>,
         _customer: Option<domain::Customer>,
-        _storage_scheme: storage_enums::MerchantStorageScheme,
+        storage_scheme: storage_enums::MerchantStorageScheme,
         _updated_customer: Option<storage::CustomerUpdate>,
         _merchant_key_store: &domain::MerchantKeyStore,
         _frm_suggestion: Option<FrmSuggestion>,
@@ -434,6 +442,19 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Comple
     where
         F: 'b + Send,
     {
+        let payment_intent_update = hyperswitch_domain_models::payments::payment_intent::PaymentIntentUpdate::CompleteAuthorizeUpdate {
+            shipping_address_id: payment_data.payment_intent.shipping_address_id.clone()
+        };
+
+        let db = &*state.store;
+        let payment_intent = payment_data.payment_intent.clone();
+
+        let updated_payment_intent = db
+            .update_payment_intent(payment_intent, payment_intent_update, storage_scheme)
+            .await
+            .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
+
+        payment_data.payment_intent = updated_payment_intent;
         Ok((Box::new(self), payment_data))
     }
 }
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 21cc994381e..ba8dd94b332 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -386,7 +386,11 @@ impl Payments {
                 )
                 .service(
                     web::resource("/{payment_id}/{merchant_id}/redirect/complete/{connector}")
-                        .route(web::get().to(payments_complete_authorize))
+                        .route(web::get().to(payments_complete_authorize_redirect))
+                        .route(web::post().to(payments_complete_authorize_redirect)),
+                )
+                .service(
+                    web::resource("/{payment_id}/complete_authorize")
                         .route(web::post().to(payments_complete_authorize)),
                 )
                 .service(
diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs
index 30b582079e3..6a73643ce68 100644
--- a/crates/router/src/routes/lock_utils.rs
+++ b/crates/router/src/routes/lock_utils.rs
@@ -121,7 +121,8 @@ impl From<Flow> for ApiIdentifier {
             | Flow::PaymentsIncrementalAuthorization
             | Flow::PaymentsExternalAuthentication
             | Flow::PaymentsAuthorize
-            | Flow::GetExtendedCardInfo => Self::Payments,
+            | Flow::GetExtendedCardInfo
+            | Flow::PaymentsCompleteAuthorize => Self::Payments,
 
             Flow::PayoutsCreate
             | Flow::PayoutsRetrieve
diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs
index 06bdd3ed05a..f28cad89004 100644
--- a/crates/router/src/routes/payments.rs
+++ b/crates/router/src/routes/payments.rs
@@ -7,6 +7,7 @@ pub mod helpers;
 use actix_web::{web, Responder};
 use api_models::payments::HeaderPayload;
 use error_stack::report;
+use masking::PeekInterface;
 use router_env::{env, instrument, tracing, types, Flow};
 
 use super::app::ReqState;
@@ -749,7 +750,7 @@ pub async fn payments_redirect_response_with_creds_identifier(
     .await
 }
 #[instrument(skip_all, fields(flow =? Flow::PaymentsRedirect, payment_id))]
-pub async fn payments_complete_authorize(
+pub async fn payments_complete_authorize_redirect(
     state: web::Data<app::AppState>,
     req: actix_web::HttpRequest,
     json_payload: Option<web::Form<serde_json::Value>>,
@@ -792,6 +793,70 @@ pub async fn payments_complete_authorize(
     )
     .await
 }
+
+/// Payments - Complete Authorize
+#[instrument(skip_all, fields(flow =? Flow::PaymentsCompleteAuthorize, payment_id))]
+pub async fn payments_complete_authorize(
+    state: web::Data<app::AppState>,
+    req: actix_web::HttpRequest,
+    json_payload: web::Json<payment_types::PaymentsCompleteAuthorizeRequest>,
+    path: web::Path<String>,
+) -> impl Responder {
+    let flow = Flow::PaymentsCompleteAuthorize;
+    let mut payload = json_payload.into_inner();
+
+    let payment_id = path.into_inner();
+    payload.payment_id.clone_from(&payment_id);
+
+    tracing::Span::current().record("payment_id", &payment_id);
+
+    let payment_confirm_req = payment_types::PaymentsRequest {
+        payment_id: Some(payment_types::PaymentIdType::PaymentIntentId(
+            payment_id.clone(),
+        )),
+        shipping: payload.shipping.clone(),
+        client_secret: Some(payload.client_secret.peek().clone()),
+        ..Default::default()
+    };
+
+    let (auth_type, auth_flow) =
+        match auth::check_client_secret_and_get_auth(req.headers(), &payment_confirm_req) {
+            Ok(auth) => auth,
+            Err(err) => return api::log_and_return_error_response(report!(err)),
+        };
+
+    let locking_action = payload.get_locking_input(flow.clone());
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        payload,
+        |state, auth, _req, req_state| {
+            payments::payments_core::<
+                api_types::CompleteAuthorize,
+                payment_types::PaymentsResponse,
+                _,
+                _,
+                _,
+            >(
+                state.clone(),
+                req_state,
+                auth.merchant_account,
+                auth.key_store,
+                payments::operations::payment_complete_authorize::CompleteAuthorize,
+                payment_confirm_req.clone(),
+                auth_flow,
+                payments::CallConnectorAction::Trigger,
+                None,
+                HeaderPayload::default(),
+            )
+        },
+        &*auth_type,
+        locking_action,
+    ))
+    .await
+}
+
 /// Payments - Cancel
 ///
 /// A Payment could can be cancelled when it is in one of these statuses: requires_payment_method, requires_capture, requires_confirmation, requires_customer_action
@@ -1465,6 +1530,22 @@ impl GetLockingInput for payments::PaymentsRedirectResponseData {
     }
 }
 
+impl GetLockingInput for payment_types::PaymentsCompleteAuthorizeRequest {
+    fn get_locking_input<F>(&self, flow: F) -> api_locking::LockAction
+    where
+        F: types::FlowMetric,
+        lock_utils::ApiIdentifier: From<F>,
+    {
+        api_locking::LockAction::Hold {
+            input: api_locking::LockingInput {
+                unique_locking_key: self.payment_id.to_owned(),
+                api_identifier: lock_utils::ApiIdentifier::from(flow),
+                override_lock_retries: None,
+            },
+        }
+    }
+}
+
 impl GetLockingInput for payment_types::PaymentsCancelRequest {
     fn get_locking_input<F>(&self, flow: F) -> api_locking::LockAction
     where
diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs
index 9f68cac98c9..a2201936299 100644
--- a/crates/router/src/types/api/payments.rs
+++ b/crates/router/src/types/api/payments.rs
@@ -6,12 +6,13 @@ pub use api_models::payments::{
     PaymentListFilters, PaymentListFiltersV2, PaymentListResponse, PaymentListResponseV2,
     PaymentMethodData, PaymentMethodDataRequest, PaymentMethodDataResponse, PaymentOp,
     PaymentRetrieveBody, PaymentRetrieveBodyWithCredentials, PaymentsApproveRequest,
-    PaymentsCancelRequest, PaymentsCaptureRequest, PaymentsExternalAuthenticationRequest,
-    PaymentsIncrementalAuthorizationRequest, PaymentsRedirectRequest, PaymentsRedirectionResponse,
-    PaymentsRejectRequest, PaymentsRequest, PaymentsResponse, PaymentsResponseForm,
-    PaymentsRetrieveRequest, PaymentsSessionRequest, PaymentsSessionResponse, PaymentsStartRequest,
-    PgRedirectResponse, PhoneDetails, RedirectionResponse, SessionToken, TimeRange, UrlDetails,
-    VerifyRequest, VerifyResponse, WalletData,
+    PaymentsCancelRequest, PaymentsCaptureRequest, PaymentsCompleteAuthorizeRequest,
+    PaymentsExternalAuthenticationRequest, PaymentsIncrementalAuthorizationRequest,
+    PaymentsRedirectRequest, PaymentsRedirectionResponse, PaymentsRejectRequest, PaymentsRequest,
+    PaymentsResponse, PaymentsResponseForm, PaymentsRetrieveRequest, PaymentsSessionRequest,
+    PaymentsSessionResponse, PaymentsStartRequest, PgRedirectResponse, PhoneDetails,
+    RedirectionResponse, SessionToken, TimeRange, UrlDetails, VerifyRequest, VerifyResponse,
+    WalletData,
 };
 use error_stack::ResultExt;
 
diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs
index ffa492bc60d..07a45f5cdbc 100644
--- a/crates/router_env/src/logger/types.rs
+++ b/crates/router_env/src/logger/types.rs
@@ -180,6 +180,8 @@ pub enum Flow {
     PayoutsAccounts,
     /// Payments Redirect flow.
     PaymentsRedirect,
+    /// Payemnts Complete Authorize Flow
+    PaymentsCompleteAuthorize,
     /// Refunds create flow.
     RefundsCreate,
     /// Refunds retrieve flow.
diff --git a/crates/storage_impl/src/payments/payment_intent.rs b/crates/storage_impl/src/payments/payment_intent.rs
index c7592e48211..720a3b6d024 100644
--- a/crates/storage_impl/src/payments/payment_intent.rs
+++ b/crates/storage_impl/src/payments/payment_intent.rs
@@ -1152,6 +1152,11 @@ impl DataModelExt for PaymentIntentUpdate {
             } => DieselPaymentIntentUpdate::AuthorizationCountUpdate {
                 authorization_count,
             },
+            Self::CompleteAuthorizeUpdate {
+                shipping_address_id,
+            } => DieselPaymentIntentUpdate::CompleteAuthorizeUpdate {
+                shipping_address_id,
+            },
         }
     }
 
diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json
index a3cd88d2ee9..2365f165d65 100644
--- a/openapi/openapi_spec.json
+++ b/openapi/openapi_spec.json
@@ -853,6 +853,57 @@
         ]
       }
     },
+    "/{payment_id}/complete_authorize": {
+      "post": {
+        "tags": [
+          "Payments"
+        ],
+        "summary": "Payments - Complete Authorize",
+        "description": "Payments - Complete Authorize\n\n",
+        "operationId": "Complete Authorize a Payment",
+        "parameters": [
+          {
+            "name": "payment_id",
+            "in": "path",
+            "description": "The identifier for payment",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/PaymentsCompleteAuthorizeRequest"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "200": {
+            "description": "Payments Complete Authorize Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PaymentsResponse"
+                }
+              }
+            }
+          },
+          "400": {
+            "description": "Missing mandatory fields"
+          }
+        },
+        "security": [
+          {
+            "publishable_key": []
+          }
+        ]
+      }
+    },
     "/refunds": {
       "post": {
         "tags": [
@@ -13522,6 +13573,26 @@
           }
         }
       },
+      "PaymentsCompleteAuthorizeRequest": {
+        "type": "object",
+        "required": [
+          "client_secret"
+        ],
+        "properties": {
+          "shipping": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/Address"
+              }
+            ],
+            "nullable": true
+          },
+          "client_secret": {
+            "type": "string",
+            "description": "Client Secret"
+          }
+        }
+      },
       "PaymentsConfirmRequest": {
         "type": "object",
         "properties": {

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
- Add a new end point `/{payment_id}/complete_authorize`. 
- This will be used in the cases where we get shipping after confirm call and we need to call the connector 2nd time.
- Collect shipping address in complete authorize call



### Additional Changes

- [x] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
1. Create a Paypal Payment request via Paypal (without adding shipping in request)
```
{
  "amount": 6540,
  "currency": "USD",
  "confirm": true,
  "capture_method": "automatic",
  "capture_on": "2022-09-10T10:11:12Z",
  "amount_to_capture": 6540,
  "customer_id": "StripeCustomer223",
  "email": "abcdef123@gmail.com",
  "name": "John Doe",
  "phone": "999999999",
  "phone_country_code": "+65",
  "description": "Its my first payment request",
  "authentication_type": "three_ds",
  "return_url": "https://duck.com",
  "setup_future_usage": "off_session",
  "billing": {
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US"
    }
  },
  "browser_info": {
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
    "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "language": "nl-NL",
    "color_depth": 24,
    "screen_height": 723,
    "screen_width": 1536,
    "time_zone": 0,
    "java_enabled": true,
    "java_script_enabled": true,
    "ip_address": "127.0.0.1"
  },
  "statement_descriptor_name": "joseph",
  "statement_descriptor_suffix": "JS",
  "metadata": {
    "udf1": "value1",
    "new_customer": "true",
    "login_date": "2019-09-10T10:11:12Z"
  },
  "payment_method": "wallet",
  "payment_method_type": "paypal",
  "payment_method_data": {
    "wallet": {
      "paypal_redirect": {}
    }
  }
}
```
Response
```
{
    "payment_id": "pay_kgDXnhkYLQ19FfXW5HlC",
    "merchant_id": "merchant_1715932962",
    "status": "requires_customer_action",
    "amount": 6540,
    "net_amount": 6540,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "paypal",
    "client_secret": "pay_kgDXnhkYLQ19FfXW5HlC_secret_cCq0P0y8hP1rOwjjSXQW",
    "created": "2024-05-17T11:54:56.365Z",
    "currency": "USD",
    "customer_id": "StripeCustomer223",
    "customer": {
        "id": "StripeCustomer223",
        "name": "John Doe",
        "email": "abcdef123@gmail.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": "off_session",
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "wallet",
    "payment_method_data": {
        "wallet": {},
        "billing": null
    },
    "payment_token": null,
    "shipping": null,
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": null,
            "last_name": null
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "abcdef123@gmail.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_kgDXnhkYLQ19FfXW5HlC/merchant_1715932962/pay_kgDXnhkYLQ19FfXW5HlC_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "paypal",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "StripeCustomer223",
        "created_at": 1715946896,
        "expires": 1715950496,
        "secret": "epk_1612889c945d4948b4ea7df75aa819ec"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "9LY92988UP8943014",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_kgDXnhkYLQ19FfXW5HlC_1",
    "payment_link": null,
    "profile_id": "pro_o6Rw573Vwz3izj70A7ua",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_hmRahHIqSmAlgOR6UQAu",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-05-17T12:09:56.365Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "127.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-05-17T11:54:58.187Z"
}
```
______________________________________________________________
2. Hit Complete Authorize end point
```
curl --location '{{baseUrl}}/payments/:id/complete_authorize' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: pk_dev_e41911bdeff647c1bb6e3276e5bc621d' \
--data-raw '{
  "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Kormangala",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "PiX"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "client_secret": "{{client_secret}}"
}'
```
Response
In Response we should shipping details.
```
{
    "payment_id": "pay_lxZFT0OfS55HekMEdeJ5",
    "merchant_id": "merchant_1716021280",
    "status": "failed",
    "amount": 6540,
    "net_amount": 6540,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": "paypal",
    "client_secret": "pay_lxZFT0OfS55HekMEdeJ5_secret_oHIG40VJWaJv206oQQmV",
    "created": "2024-05-18T08:34:52.094Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "wallet",
    "payment_method_data": {
        "wallet": {},
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Kormangala",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": "ORDER_NOT_APPROVED",
    "error_message": "description - Payer has not yet approved the Order for payment. Please redirect the payer to the 'rel':'approve' url returned as part of the HATEOAS links within the Create Order call or provide a valid payment_source in the request. ;",
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "paypal",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": true,
    "connector_transaction_id": "4Y3612593C2698259",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_lxZFT0OfS55HekMEdeJ5_1",
    "payment_link": null,
    "profile_id": "pro_p0FqSgqYAfU1Z93fJXDo",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_bjUetR7rWBdXgCjGLrBa",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-05-18T08:49:52.094Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-05-18T08:36:08.387Z",
    "frm_metadata": null
}
```
_________________________________________________________
3. Retrieve Payment with same payment_id
In Response we should shipping details.
```
{
    "payment_id": "pay_lxZFT0OfS55HekMEdeJ5",
    "merchant_id": "merchant_1716021280",
    "status": "failed",
    "amount": 6540,
    "net_amount": 6540,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": "paypal",
    "client_secret": "pay_lxZFT0OfS55HekMEdeJ5_secret_oHIG40VJWaJv206oQQmV",
    "created": "2024-05-18T08:34:52.094Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "wallet",
    "payment_method_data": {
        "wallet": {},
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Kormangala",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "guest@example.com"
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": "ORDER_NOT_APPROVED",
    "error_message": "description - Payer has not yet approved the Order for payment. Please redirect the payer to the 'rel':'approve' url returned as part of the HATEOAS links within the Create Order call or provide a valid payment_source in the request. ;",
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "paypal",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": true,
    "connector_transaction_id": "4Y3612593C2698259",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_lxZFT0OfS55HekMEdeJ5_1",
    "payment_link": null,
    "profile_id": "pro_p0FqSgqYAfU1Z93fJXDo",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_bjUetR7rWBdXgCjGLrBa",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-05-18T08:49:52.094Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-05-18T08:36:08.387Z",
    "frm_metadata": null
}
```


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [ ] I formatted the code `cargo +nightly fmt --all`
- [ ] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
