Bug: [chore] add cardholder name to payment required fields



Add cardholder name to payment required fields for Worldpay card payments.
diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay.rs b/crates/hyperswitch_connectors/src/connectors/worldpay.rs
index 4628eaf116e..645502b267d 100644
--- a/crates/hyperswitch_connectors/src/connectors/worldpay.rs
+++ b/crates/hyperswitch_connectors/src/connectors/worldpay.rs
@@ -285,6 +285,7 @@ impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsRespons
                 http_code: res.status_code,
             },
             optional_correlation_id,
+            data.request.amount.unwrap_or(0),
         ))
         .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
@@ -759,6 +760,7 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
                 http_code: res.status_code,
             },
             optional_correlation_id,
+            data.request.amount,
         ))
         .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
@@ -870,6 +872,7 @@ impl ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResp
                 http_code: res.status_code,
             },
             optional_correlation_id,
+            data.request.amount,
         ))
         .change_context(errors::ConnectorError::ResponseHandlingFailed)
     }
diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs
index 8fd41ea2031..adee7fb2891 100644
--- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs
+++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs
@@ -86,34 +86,24 @@ fn fetch_payment_instrument(
             },
             cvc: card.card_cvc,
             card_holder_name: billing_address.and_then(|address| address.get_optional_full_name()),
-            billing_address: if let Some(address) =
-                billing_address.and_then(|addr| addr.address.clone())
-            {
-                Some(BillingAddress {
-                    address1: address.line1.get_required_value("line1").change_context(
-                        errors::ConnectorError::MissingRequiredField {
-                            field_name: "line1",
-                        },
-                    )?,
-                    address2: address.line2,
-                    address3: address.line3,
-                    city: address.city.get_required_value("city").change_context(
-                        errors::ConnectorError::MissingRequiredField { field_name: "city" },
-                    )?,
-                    state: address.state,
-                    postal_code: address.zip.get_required_value("zip").change_context(
-                        errors::ConnectorError::MissingRequiredField { field_name: "zip" },
-                    )?,
-                    country_code: address
-                        .country
-                        .get_required_value("country_code")
-                        .change_context(errors::ConnectorError::MissingRequiredField {
-                            field_name: "country_code",
-                        })?,
-                })
-            } else {
-                None
-            },
+            billing_address: billing_address
+                .and_then(|addr| addr.address.clone())
+                .and_then(|address| {
+                    match (address.line1, address.city, address.zip, address.country) {
+                        (Some(address1), Some(city), Some(postal_code), Some(country_code)) => {
+                            Some(BillingAddress {
+                                address1,
+                                address2: address.line2,
+                                address3: address.line3,
+                                city,
+                                state: address.state,
+                                postal_code,
+                                country_code,
+                            })
+                        }
+                        _ => None,
+                    }
+                }),
         })),
         PaymentMethodData::CardDetailsForNetworkTransactionId(raw_card_details) => {
             Ok(PaymentInstrument::RawCardForNTI(RawCardDetails {
@@ -264,7 +254,7 @@ impl WorldpayPaymentsRequestData
     for RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
 {
     fn get_return_url(&self) -> Result<String, error_stack::Report<errors::ConnectorError>> {
-        self.request.get_router_return_url()
+        self.request.get_complete_authorize_url()
     }
 
     fn get_auth_type(&self) -> &enums::AuthenticationType {
@@ -681,6 +671,7 @@ impl<F, T>
     ForeignTryFrom<(
         ResponseRouterData<F, WorldpayPaymentsResponse, T, PaymentsResponseData>,
         Option<String>,
+        i64,
     )> for RouterData<F, T, PaymentsResponseData>
 {
     type Error = error_stack::Report<errors::ConnectorError>;
@@ -688,9 +679,10 @@ impl<F, T>
         item: (
             ResponseRouterData<F, WorldpayPaymentsResponse, T, PaymentsResponseData>,
             Option<String>,
+            i64,
         ),
     ) -> Result<Self, Self::Error> {
-        let (router_data, optional_correlation_id) = item;
+        let (router_data, optional_correlation_id, amount) = item;
         let (description, redirection_data, mandate_reference, network_txn_id, error) = router_data
             .response
             .other_fields
@@ -770,7 +762,11 @@ impl<F, T>
             PaymentOutcome::FraudHighRisk => Some("Transaction marked as high risk".to_string()),
             _ => None,
         };
-        let status = enums::AttemptStatus::from(worldpay_status.clone());
+        let status = if amount == 0 && worldpay_status == PaymentOutcome::Authorized {
+            enums::AttemptStatus::Charged
+        } else {
+            enums::AttemptStatus::from(worldpay_status.clone())
+        };
         let response = match (optional_error_message, error) {
             (None, None) => Ok(PaymentsResponseData::TransactionResponse {
                 resource_id: ResponseId::foreign_try_from((
diff --git a/crates/payment_methods/src/configs/payment_connector_required_fields.rs b/crates/payment_methods/src/configs/payment_connector_required_fields.rs
index 192d45c8fce..69cb4b97de4 100644
--- a/crates/payment_methods/src/configs/payment_connector_required_fields.rs
+++ b/crates/payment_methods/src/configs/payment_connector_required_fields.rs
@@ -1473,6 +1473,7 @@ fn get_cards_required_fields() -> HashMap<Connector, RequiredFieldFinal> {
                     RequiredField::CardNumber,
                     RequiredField::CardExpMonth,
                     RequiredField::CardExpYear,
+                    RequiredField::BillingUserFirstName,
                 ],
             ),
         ),

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

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

## Description
This PR adds below changes
- Add required field for Worldpay card transactions - card holder name.
- Fix 3DS SetupMandate flows for Worldpay card transactions

### Additional Changes

- [ ] 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
Card holder name is a mandatory field which is required by WP during card transactions.
Fixing the 3DS SetupMandate flow for Worldpay allows merchants to consume the functionality.

## How did you test it?
<details>
    <summary>1. [No3DS] Create zero amount off_session payment</summary>

cURL

    curl --location --request POST 'http://localhost:8080/payments' \
        --header 'Content-Type: application/json' \
        --header 'Accept: application/json' \
        --header 'api-key: dev_W87tjiH2egf7KXq7k4Z3Kr4b0DjNZKUqv7MgUxzaAaLa3RC2jREfBOzomE4DsAD7' \
        --data-raw '{"amount":0,"currency":"SGD","confirm":true,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","capture_method":"automatic","capture_on":"2022-09-10T10:11:12Z","setup_future_usage":"off_session","customer_id":"cus_GPjGfsYpA50dZpSocrbd","email":"abc@example.com","return_url":"https://google.com","payment_method":"card","payment_method_type":"debit","payment_method_data":{"card":{"card_number":"4000000000002503","card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","card_cvc":"737"}},"metadata":{"Force-PSP":"Adyen","udf1":"value1","new_customer":"true","login_date":"2019-09-10T10:11:12Z"},"browser_info":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","language":"en-US","color_depth":32,"screen_height":1117,"screen_width":1728,"time_zone":-330,"java_enabled":true,"java_script_enabled":true,"ip_address":"127.0.0.1"},"customer_acceptance":{"acceptance_type":"online","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"127.0.0.1","user_agent":"amet irure esse"}},"connector_metadata":{"adyen":{"testing":{}}},"session_expiry":60}'

Response

    {"payment_id":"pay_wfFMLqmemSnqwZVHT3kM","merchant_id":"merchant_1745484169","status":"succeeded","amount":0,"net_amount":0,"shipping_cost":null,"amount_capturable":0,"amount_received":0,"connector":"worldpay","client_secret":"pay_wfFMLqmemSnqwZVHT3kM_secret_eeoF2tNW0wRyvp2pU3WP","created":"2025-04-24T13:31:24.448Z","currency":"SGD","customer_id":"cus_GPjGfsYpA50dZpSocrbd","customer":{"id":"cus_GPjGfsYpA50dZpSocrbd","name":"John Doe","email":"abc@example.com","phone":"999999999","phone_country_code":"+65"},"description":null,"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":"card","payment_method_data":{"card":{"last4":"2503","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"400000","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":null,"order_details":null,"email":"abc@example.com","name":"John Doe","phone":"999999999","return_url":"https://google.com/","authentication_type":"no_three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":null,"cancellation_reason":null,"error_code":null,"error_message":null,"unified_code":null,"unified_message":null,"payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"cus_GPjGfsYpA50dZpSocrbd","created_at":1745501484,"expires":1745505084,"secret":"epk_a62a7064a7e34ccd8305d605ae359881"},"manual_retry_allowed":false,"connector_transaction_id":"23fbb1ff-43c0-4fc4-b27d-072e23683f97","frm_message":null,"metadata":{"udf1":"value1","Force-PSP":"Adyen","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null},"feature_metadata":null,"reference_id":"23fbb1ff-43c0-4fc4-b27d-072e23683f97","payment_link":null,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_3YM2a6Tn1oMvHSLqrGSD","incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-24T13:32:24.448Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","color_depth":32,"java_enabled":true,"screen_width":1728,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":1117,"java_script_enabled":true},"payment_method_id":"pm_yg0qfrNde4WjKQH8Gi3h","payment_method_status":"active","updated":"2025-04-24T13:31:26.513Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":"https://try.access.worldpay.com/tokens/eyJrIjoxLCJkIjoidFlEWFFxbDNSUDNZZDg4T0VoWVVxbkdlaFB0RUlvVjFQcEs5TU9KRk9TQT0ifQ","card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null}

</details>

<details>
    <summary>2. [No3DS] Create non zero amount off_session payment</summary>

cURL

    curl --location --request POST 'http://localhost:8080/payments' \
        --header 'Content-Type: application/json' \
        --header 'Accept: application/json' \
        --header 'api-key: dev_W87tjiH2egf7KXq7k4Z3Kr4b0DjNZKUqv7MgUxzaAaLa3RC2jREfBOzomE4DsAD7' \
        --data-raw '{"amount":1000,"currency":"SGD","confirm":true,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","capture_method":"automatic","capture_on":"2022-09-10T10:11:12Z","setup_future_usage":"off_session","customer_id":"cus_GPjGfsYpA50dZpSocrbd","email":"abc@example.com","return_url":"https://google.com","payment_method":"card","payment_method_type":"debit","payment_method_data":{"card":{"card_number":"4000000000002503","card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","card_cvc":"737"}},"metadata":{"Force-PSP":"Adyen","udf1":"value1","new_customer":"true","login_date":"2019-09-10T10:11:12Z"},"browser_info":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","language":"en-US","color_depth":32,"screen_height":1117,"screen_width":1728,"time_zone":-330,"java_enabled":true,"java_script_enabled":true,"ip_address":"127.0.0.1"},"customer_acceptance":{"acceptance_type":"online","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"127.0.0.1","user_agent":"amet irure esse"}},"connector_metadata":{"adyen":{"testing":{}}},"session_expiry":60}'

Response

    {"payment_id":"pay_OmaRK9FIhoOR0opBCA5q","merchant_id":"merchant_1745484169","status":"succeeded","amount":1000,"net_amount":1000,"shipping_cost":null,"amount_capturable":0,"amount_received":1000,"connector":"worldpay","client_secret":"pay_OmaRK9FIhoOR0opBCA5q_secret_BZ0tzOif151DIaYSqUWl","created":"2025-04-24T13:32:05.834Z","currency":"SGD","customer_id":"cus_GPjGfsYpA50dZpSocrbd","customer":{"id":"cus_GPjGfsYpA50dZpSocrbd","name":"John Doe","email":"abc@example.com","phone":"999999999","phone_country_code":"+65"},"description":null,"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":"card","payment_method_data":{"card":{"last4":"2503","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"400000","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":null,"order_details":null,"email":"abc@example.com","name":"John Doe","phone":"999999999","return_url":"https://google.com/","authentication_type":"no_three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":null,"cancellation_reason":null,"error_code":null,"error_message":null,"unified_code":null,"unified_message":null,"payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"cus_GPjGfsYpA50dZpSocrbd","created_at":1745501525,"expires":1745505125,"secret":"epk_f3c123ca19364af294602e915a89a659"},"manual_retry_allowed":false,"connector_transaction_id":"eyJrIjoiazNhYjYzMiIsImxpbmtWZXJzaW9uIjoiNi4wLjAifQ==.sN:g8wd64bwkbrp0md+bPxcanBnk2zLdsIqSa1pR99HBj426bdlJXCgTskLhNY5Ml0rXtEPNSyl2cbsnj4b2DZrMdENEzIjocoy3lSG96aYlW4Z+fnZKMutoUGX3m1:mDK4Giru8JHLS90mSN+Z+gkVKRI3EE1MXDv7dp+h3RhHFHGaPn9ksCvhYk:a:cH+e81VQ0:KjdVX14V+Q12mM8f8UUuVrb1pWfdmRX0ol0w4rW66yFNGsWi87tzkRENLR8ix3NBfHPU2KlzlyTrmR0mwasA4zRNlfY:bG7Aaa:GaUgn8jvCNhmdUlN6uDEfAu3+Gpx8cadeYO0VLI6Wl9In2xgejGQ0ri:BU5HlAn:UMGwtz7wDtU06VN+Rkfa60cHqFXxXOGsvxbfcVlSe:hmS+WwXVvDoxGmrxlJztOw0ZEV8g:Qgoe7iLzyfbMA1TfZNrYIkRNlWpYaVeOJiIYYCBgREKSZGhVAzktTueU3oo=","frm_message":null,"metadata":{"udf1":"value1","Force-PSP":"Adyen","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null},"feature_metadata":null,"reference_id":"929b66d4-df1d-4660-a4a1-ec4c14136cea","payment_link":null,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_3YM2a6Tn1oMvHSLqrGSD","incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-24T13:33:05.834Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","color_depth":32,"java_enabled":true,"screen_width":1728,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":1117,"java_script_enabled":true},"payment_method_id":"pm_BMicZubaUj8L5mP3dk5M","payment_method_status":"active","updated":"2025-04-24T13:32:07.354Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":"https://try.access.worldpay.com/tokens/eyJrIjoxLCJkIjoidFlEWFFxbDNSUDNZZDg4T0VoWVVxbkdlaFB0RUlvVjFQcEs5TU9KRk9TQT0ifQ","card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null}

</details>

<details>
    <summary>3. [3DS] Create non zero amount off_session payment</summary>

cURL

    curl --location --request POST 'http://localhost:8080/payments' \
        --header 'Content-Type: application/json' \
        --header 'Accept: application/json' \
        --header 'api-key: dev_W87tjiH2egf7KXq7k4Z3Kr4b0DjNZKUqv7MgUxzaAaLa3RC2jREfBOzomE4DsAD7' \
        --data-raw '{"amount":1000,"currency":"SGD","confirm":true,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","capture_method":"automatic","capture_on":"2022-09-10T10:11:12Z","authentication_type":"three_ds","setup_future_usage":"off_session","customer_id":"cus_GPjGfsYpA50dZpSocrbd","email":"abc@example.com","return_url":"https://google.com","payment_method":"card","payment_method_type":"debit","payment_method_data":{"card":{"card_number":"4000000000002503","card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","card_cvc":"737"}},"metadata":{"Force-PSP":"Adyen","udf1":"value1","new_customer":"true","login_date":"2019-09-10T10:11:12Z"},"browser_info":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","language":"en-US","color_depth":32,"screen_height":1117,"screen_width":1728,"time_zone":-330,"java_enabled":true,"java_script_enabled":true,"ip_address":"127.0.0.1"},"customer_acceptance":{"acceptance_type":"online","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"127.0.0.1","user_agent":"amet irure esse"}},"connector_metadata":{"adyen":{"testing":{}}},"session_expiry":60}'

Response

    {"payment_id":"pay_V52ZUSmwZcawWT6SmhK9","merchant_id":"merchant_1745484169","status":"requires_customer_action","amount":1000,"net_amount":1000,"shipping_cost":null,"amount_capturable":1000,"amount_received":null,"connector":"worldpay","client_secret":"pay_V52ZUSmwZcawWT6SmhK9_secret_xkcz8525E884zswbTF90","created":"2025-04-24T13:32:54.875Z","currency":"SGD","customer_id":"cus_GPjGfsYpA50dZpSocrbd","customer":{"id":"cus_GPjGfsYpA50dZpSocrbd","name":"John Doe","email":"abc@example.com","phone":"999999999","phone_country_code":"+65"},"description":null,"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":"card","payment_method_data":{"card":{"last4":"2503","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"400000","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":null,"order_details":null,"email":"abc@example.com","name":"John Doe","phone":"999999999","return_url":"https://google.com/","authentication_type":"three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":{"type":"redirect_to_url","redirect_to_url":"http://localhost:8080/payments/redirect/pay_V52ZUSmwZcawWT6SmhK9/merchant_1745484169/pay_V52ZUSmwZcawWT6SmhK9_1"},"cancellation_reason":null,"error_code":null,"error_message":null,"unified_code":null,"unified_message":null,"payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"cus_GPjGfsYpA50dZpSocrbd","created_at":1745501574,"expires":1745505174,"secret":"epk_79da3389a5d349a2a060f8ef6377ad7a"},"manual_retry_allowed":null,"connector_transaction_id":"eyJrIjoxLCJkIjoiZnFyaU40UENQRnQzVHRndEtDdDg0bHZkVGsyMlNGZkpHRmV3Q3UxRHVwSUxvQVZFYmcwR3Q5NHkrN0xNNitQMiJ9_2","frm_message":null,"metadata":{"udf1":"value1","Force-PSP":"Adyen","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null},"feature_metadata":null,"reference_id":"0b390991-6688-40b9-8b95-950a65af5678","payment_link":null,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_3YM2a6Tn1oMvHSLqrGSD","incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-24T13:33:54.875Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","color_depth":32,"java_enabled":true,"screen_width":1728,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":1117,"java_script_enabled":true},"payment_method_id":"pm_1NL54rrmq8DE3vQ9VgZX","payment_method_status":"inactive","updated":"2025-04-24T13:32:55.282Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null}

Complete the payment by clicking the link

cURL (retrieve)

    curl --location --request GET 'http://localhost:8080/payments/pay_V52ZUSmwZcawWT6SmhK9' \
        --header 'Accept: application/json' \
        --header 'api-key: dev_W87tjiH2egf7KXq7k4Z3Kr4b0DjNZKUqv7MgUxzaAaLa3RC2jREfBOzomE4DsAD7'

Response

    {"payment_id":"pay_V52ZUSmwZcawWT6SmhK9","merchant_id":"merchant_1745484169","status":"succeeded","amount":1000,"net_amount":1000,"shipping_cost":null,"amount_capturable":0,"amount_received":1000,"connector":"worldpay","client_secret":"pay_V52ZUSmwZcawWT6SmhK9_secret_xkcz8525E884zswbTF90","created":"2025-04-24T13:32:54.875Z","currency":"SGD","customer_id":"cus_GPjGfsYpA50dZpSocrbd","customer":{"id":"cus_GPjGfsYpA50dZpSocrbd","name":"John Doe","email":"abc@example.com","phone":"999999999","phone_country_code":"+65"},"description":null,"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":"card","payment_method_data":{"card":{"last4":"2503","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"400000","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":null,"order_details":null,"email":"abc@example.com","name":"John Doe","phone":"999999999","return_url":"https://google.com/","authentication_type":"three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":null,"cancellation_reason":null,"error_code":null,"error_message":null,"unified_code":null,"unified_message":null,"payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":null,"manual_retry_allowed":false,"connector_transaction_id":"eyJrIjoiazNhYjYzMiIsImxpbmtWZXJzaW9uIjoiNi4wLjAifQ==.sN:g8wd64bwkbrp0md+bPxcanBnk2zLdsIqSa1pR99HBj426bdlJXCgTskLhNY5Ml0rXtEPNSyl2cbsnj4b2DZrMdENEzIjocoy3lSG96aYlW4Z+fnZKMutoUGX3m1:mmJTlkRKFQu2PsVe3y+vegKDX5ZP4XxijGSq2aIDDwI7FHGaPn9ksCvhYk:a:cH+e81VQ0:KjdVX14V+Q12mM8f8UUuVrb1pWfdmRX0ol0w4rW66yFNGsWi87tzkRENLR8ix3NBfHPU2KlzlyTrmR0mwasA4zRNlfY:bG7Aaa:GaUgn8jvCNhmdUlN6uDEfAu3+Gpx8cadeYO0VLI6Wl9IlLyMVREoNqKOzGKAWbV6MGEiI1GbjFu2YIwRaZQDXnodMGaowTzH8y6H4OLwV6Mey+WwXVvDoxGmrxlJztOw0ZEV8g:Qgoe7iLzyfbMA1TfZNrYIkRNlWpYaVeOJiIYYCBgREKSZGhVAzktTueU3oo=","frm_message":null,"metadata":{"udf1":"value1","Force-PSP":"Adyen","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null},"feature_metadata":null,"reference_id":"69586da7-7ba1-4154-844c-35a4dddc9b86","payment_link":null,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_3YM2a6Tn1oMvHSLqrGSD","incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-24T13:33:54.875Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","color_depth":32,"java_enabled":true,"screen_width":1728,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":1117,"java_script_enabled":true},"payment_method_id":"pm_1NL54rrmq8DE3vQ9VgZX","payment_method_status":"active","updated":"2025-04-24T13:33:09.920Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null}

</details>

<details>
    <summary>4. [3DS] Create zero amount off_session payment</summary>

cURL

    curl --location --request POST 'http://localhost:8080/payments' \
        --header 'Content-Type: application/json' \
        --header 'Accept: application/json' \
        --header 'api-key: dev_W87tjiH2egf7KXq7k4Z3Kr4b0DjNZKUqv7MgUxzaAaLa3RC2jREfBOzomE4DsAD7' \
        --data-raw '{"amount":0,"currency":"SGD","confirm":true,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","capture_method":"automatic","capture_on":"2022-09-10T10:11:12Z","authentication_type":"three_ds","setup_future_usage":"off_session","customer_id":"cus_GPjGfsYpA50dZpSocrbd","email":"abc@example.com","return_url":"https://google.com","payment_method":"card","payment_method_type":"debit","payment_method_data":{"card":{"card_number":"4000000000002503","card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","card_cvc":"737"}},"metadata":{"Force-PSP":"Adyen","udf1":"value1","new_customer":"true","login_date":"2019-09-10T10:11:12Z"},"browser_info":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","language":"en-US","color_depth":32,"screen_height":1117,"screen_width":1728,"time_zone":-330,"java_enabled":true,"java_script_enabled":true,"ip_address":"127.0.0.1"},"customer_acceptance":{"acceptance_type":"online","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"127.0.0.1","user_agent":"amet irure esse"}},"connector_metadata":{"adyen":{"testing":{}}},"session_expiry":60}'

Response

    {"payment_id":"pay_i87Xb0hGyY0UmG1yhrpH","merchant_id":"merchant_1745484169","status":"requires_customer_action","amount":0,"net_amount":0,"shipping_cost":null,"amount_capturable":0,"amount_received":null,"connector":"worldpay","client_secret":"pay_i87Xb0hGyY0UmG1yhrpH_secret_sjCsGpNDs2T8YVZEjaid","created":"2025-04-24T13:35:09.354Z","currency":"SGD","customer_id":"cus_GPjGfsYpA50dZpSocrbd","customer":{"id":"cus_GPjGfsYpA50dZpSocrbd","name":"John Doe","email":"abc@example.com","phone":"999999999","phone_country_code":"+65"},"description":null,"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":"card","payment_method_data":{"card":{"last4":"2503","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"400000","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":null,"order_details":null,"email":"abc@example.com","name":"John Doe","phone":"999999999","return_url":"https://google.com/","authentication_type":"three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":{"type":"redirect_to_url","redirect_to_url":"http://localhost:8080/payments/redirect/pay_i87Xb0hGyY0UmG1yhrpH/merchant_1745484169/pay_i87Xb0hGyY0UmG1yhrpH_1"},"cancellation_reason":null,"error_code":null,"error_message":null,"unified_code":null,"unified_message":null,"payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"cus_GPjGfsYpA50dZpSocrbd","created_at":1745501709,"expires":1745505309,"secret":"epk_f1b950bdde6d4989a336c8322ef732a6"},"manual_retry_allowed":null,"connector_transaction_id":"eyJrIjoxLCJkIjoiY1d2OGxEdTVBbEF4M1VSNVIwK0FnTGpKakl1cVhVWWpZQ3laVHpxdm5WTUxvQVZFYmcwR3Q5NHkrN0xNNitQMiJ9_2","frm_message":null,"metadata":{"udf1":"value1","Force-PSP":"Adyen","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null},"feature_metadata":null,"reference_id":"43da3943-2049-4e20-95fc-172a1b763dde","payment_link":null,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_3YM2a6Tn1oMvHSLqrGSD","incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-24T13:36:09.354Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","color_depth":32,"java_enabled":true,"screen_width":1728,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":1117,"java_script_enabled":true},"payment_method_id":"pm_Lih5KP2o2m4mcGBnlgWF","payment_method_status":"inactive","updated":"2025-04-24T13:35:10.457Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null}

cURL (retrieve)

    curl --location --request GET 'http://localhost:8080/payments/pay_i87Xb0hGyY0UmG1yhrpH' \
        --header 'Accept: application/json' \
        --header 'api-key: dev_W87tjiH2egf7KXq7k4Z3Kr4b0DjNZKUqv7MgUxzaAaLa3RC2jREfBOzomE4DsAD7'

Response

    {"payment_id":"pay_i87Xb0hGyY0UmG1yhrpH","merchant_id":"merchant_1745484169","status":"succeeded","amount":0,"net_amount":0,"shipping_cost":null,"amount_capturable":0,"amount_received":0,"connector":"worldpay","client_secret":"pay_i87Xb0hGyY0UmG1yhrpH_secret_sjCsGpNDs2T8YVZEjaid","created":"2025-04-24T13:35:09.354Z","currency":"SGD","customer_id":"cus_GPjGfsYpA50dZpSocrbd","customer":{"id":"cus_GPjGfsYpA50dZpSocrbd","name":"John Doe","email":"abc@example.com","phone":"999999999","phone_country_code":"+65"},"description":null,"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":"card","payment_method_data":{"card":{"last4":"2503","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"400000","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"John Doe","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":null,"order_details":null,"email":"abc@example.com","name":"John Doe","phone":"999999999","return_url":"https://google.com/","authentication_type":"three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":null,"cancellation_reason":null,"error_code":null,"error_message":null,"unified_code":null,"unified_message":null,"payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":null,"manual_retry_allowed":false,"connector_transaction_id":"1142f6b3-364b-4988-a508-14b17c18b523","frm_message":null,"metadata":{"udf1":"value1","Force-PSP":"Adyen","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null},"feature_metadata":null,"reference_id":"1142f6b3-364b-4988-a508-14b17c18b523","payment_link":null,"profile_id":"pro_5CNWfwHVvSY4jegnpzco","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_3YM2a6Tn1oMvHSLqrGSD","incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-24T13:36:09.354Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","color_depth":32,"java_enabled":true,"screen_width":1728,"accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","screen_height":1117,"java_script_enabled":true},"payment_method_id":"pm_Lih5KP2o2m4mcGBnlgWF","payment_method_status":"active","updated":"2025-04-24T13:36:35.533Z","split_payments":null,"frm_metadata":null,"extended_authorization_applied":null,"capture_before":null,"merchant_order_reference_id":null,"order_tax_amount":null,"connector_mandate_id":null,"card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null}

</details>


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

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