From 457a386262b1b5af2ad933c3eda780b6cd9e7df2 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 2 Nov 2023 15:47:06 +0530 Subject: [PATCH 01/26] feat(connector): [BANKOFAMERICA] Add Connector Template Code --- config/config.example.toml | 1 + config/development.toml | 2 + config/docker_compose.toml | 2 + crates/api_models/src/enums.rs | 2 + crates/router/src/configs/settings.rs | 1 + crates/router/src/connector.rs | 20 +- crates/router/src/connector/bankofamerica.rs | 539 ++++++++++++++++++ .../connector/bankofamerica/transformers.rs | 250 ++++++++ crates/router/src/core/admin.rs | 4 + crates/router/src/core/payments/flows.rs | 19 + crates/router/src/types/api.rs | 1 + .../router/tests/connectors/bankofamerica.rs | 420 ++++++++++++++ crates/router/tests/connectors/main.rs | 1 + .../router/tests/connectors/sample_auth.toml | 7 +- crates/test_utils/src/connector_auth.rs | 1 + loadtest/config/development.toml | 2 + scripts/add_connector.sh | 2 +- 17 files changed, 1263 insertions(+), 11 deletions(-) create mode 100644 crates/router/src/connector/bankofamerica.rs create mode 100644 crates/router/src/connector/bankofamerica/transformers.rs create mode 100644 crates/router/tests/connectors/bankofamerica.rs diff --git a/config/config.example.toml b/config/config.example.toml index 59083d6c71d3..ed9cf9698984 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -163,6 +163,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/" applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" +bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" diff --git a/config/development.toml b/config/development.toml index 5e74eafcb467..34fbdbc9e078 100644 --- a/config/development.toml +++ b/config/development.toml @@ -71,6 +71,7 @@ cards = [ "airwallex", "authorizedotnet", "bambora", + "bankofamerica", "bitpay", "bluesnap", "boku", @@ -136,6 +137,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/" applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" +bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" diff --git a/config/docker_compose.toml b/config/docker_compose.toml index 20ca175ceb84..282894b56d43 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -78,6 +78,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/" applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" +bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" @@ -145,6 +146,7 @@ cards = [ "airwallex", "authorizedotnet", "bambora", + "bankofamerica", "bitpay", "bluesnap", "boku", diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index ee67c1187e6b..177dc73d2bff 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -75,6 +75,7 @@ pub enum Connector { Adyen, Airwallex, Authorizedotnet, + // Bankofamerica, Added as template code for future usage Bitpay, Bambora, Bluesnap, @@ -195,6 +196,7 @@ pub enum RoutableConnectors { Adyen, Airwallex, Authorizedotnet, + // Bankofamerica, Added as template code for future usage Bitpay, Bambora, Bluesnap, diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs index 204060b37aa0..df87c8a460ac 100644 --- a/crates/router/src/configs/settings.rs +++ b/crates/router/src/configs/settings.rs @@ -531,6 +531,7 @@ pub struct Connectors { pub applepay: ConnectorParams, pub authorizedotnet: ConnectorParams, pub bambora: ConnectorParams, + pub bankofamerica: ConnectorParams, pub bitpay: ConnectorParams, pub bluesnap: ConnectorParamsWithSecondaryBaseUrl, pub boku: ConnectorParams, diff --git a/crates/router/src/connector.rs b/crates/router/src/connector.rs index 7849fd98a4d1..3a83fea0d910 100644 --- a/crates/router/src/connector.rs +++ b/crates/router/src/connector.rs @@ -3,6 +3,7 @@ pub mod adyen; pub mod airwallex; pub mod authorizedotnet; pub mod bambora; +pub mod bankofamerica; pub mod bitpay; pub mod bluesnap; pub mod boku; @@ -55,13 +56,14 @@ pub mod zen; pub use self::dummyconnector::DummyConnector; pub use self::{ aci::Aci, adyen::Adyen, airwallex::Airwallex, authorizedotnet::Authorizedotnet, - bambora::Bambora, bitpay::Bitpay, bluesnap::Bluesnap, boku::Boku, braintree::Braintree, - cashtocode::Cashtocode, checkout::Checkout, coinbase::Coinbase, cryptopay::Cryptopay, - cybersource::Cybersource, dlocal::Dlocal, fiserv::Fiserv, forte::Forte, globalpay::Globalpay, - globepay::Globepay, gocardless::Gocardless, helcim::Helcim, iatapay::Iatapay, klarna::Klarna, - mollie::Mollie, multisafepay::Multisafepay, nexinets::Nexinets, nmi::Nmi, noon::Noon, - nuvei::Nuvei, opayo::Opayo, opennode::Opennode, payeezy::Payeezy, payme::Payme, paypal::Paypal, - payu::Payu, powertranz::Powertranz, prophetpay::Prophetpay, rapyd::Rapyd, shift4::Shift4, - square::Square, stax::Stax, stripe::Stripe, trustpay::Trustpay, tsys::Tsys, volt::Volt, - wise::Wise, worldline::Worldline, worldpay::Worldpay, zen::Zen, + bambora::Bambora, bankofamerica::Bankofamerica, bitpay::Bitpay, bluesnap::Bluesnap, boku::Boku, + braintree::Braintree, cashtocode::Cashtocode, checkout::Checkout, coinbase::Coinbase, + cryptopay::Cryptopay, cybersource::Cybersource, dlocal::Dlocal, fiserv::Fiserv, forte::Forte, + globalpay::Globalpay, globepay::Globepay, gocardless::Gocardless, helcim::Helcim, + iatapay::Iatapay, klarna::Klarna, mollie::Mollie, multisafepay::Multisafepay, + nexinets::Nexinets, nmi::Nmi, noon::Noon, nuvei::Nuvei, opayo::Opayo, opennode::Opennode, + payeezy::Payeezy, payme::Payme, paypal::Paypal, payu::Payu, powertranz::Powertranz, + prophetpay::Prophetpay, rapyd::Rapyd, shift4::Shift4, square::Square, stax::Stax, + stripe::Stripe, trustpay::Trustpay, tsys::Tsys, volt::Volt, wise::Wise, worldline::Worldline, + worldpay::Worldpay, zen::Zen, }; diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs new file mode 100644 index 000000000000..ef37411c8b25 --- /dev/null +++ b/crates/router/src/connector/bankofamerica.rs @@ -0,0 +1,539 @@ +pub mod transformers; + +use std::fmt::Debug; + +use error_stack::{IntoReport, ResultExt}; +use masking::ExposeInterface; +use transformers as bankofamerica; + +use crate::{ + configs::settings, + core::errors::{self, CustomResult}, + headers, + services::{ + self, + request::{self, Mask}, + ConnectorIntegration, ConnectorValidation, + }, + types::{ + self, + api::{self, ConnectorCommon, ConnectorCommonExt}, + ErrorResponse, Response, + }, + utils::{self, BytesExt}, +}; + +#[derive(Debug, Clone)] +pub struct Bankofamerica; + +impl api::Payment for Bankofamerica {} +impl api::PaymentSession for Bankofamerica {} +impl api::ConnectorAccessToken for Bankofamerica {} +impl api::MandateSetup for Bankofamerica {} +impl api::PaymentAuthorize for Bankofamerica {} +impl api::PaymentSync for Bankofamerica {} +impl api::PaymentCapture for Bankofamerica {} +impl api::PaymentVoid for Bankofamerica {} +impl api::Refund for Bankofamerica {} +impl api::RefundExecute for Bankofamerica {} +impl api::RefundSync for Bankofamerica {} +impl api::PaymentToken for Bankofamerica {} + +impl + ConnectorIntegration< + api::PaymentMethodToken, + types::PaymentMethodTokenizationData, + types::PaymentsResponseData, + > for Bankofamerica +{ + // Not Implemented (R) +} + +impl ConnectorCommonExt for Bankofamerica +where + Self: ConnectorIntegration, +{ + fn build_headers( + &self, + req: &types::RouterData, + _connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + let mut header = vec![( + headers::CONTENT_TYPE.to_string(), + self.get_content_type().to_string().into(), + )]; + let mut api_key = self.get_auth_header(&req.connector_auth_type)?; + header.append(&mut api_key); + Ok(header) + } +} + +impl ConnectorCommon for Bankofamerica { + fn id(&self) -> &'static str { + "bankofamerica" + } + + fn get_currency_unit(&self) -> api::CurrencyUnit { + todo!() + // TODO! Check connector documentation, on which unit they are processing the currency. + // If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor, + // if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base + } + + fn common_get_content_type(&self) -> &'static str { + "application/json" + } + + fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { + connectors.bankofamerica.base_url.as_ref() + } + + fn get_auth_header( + &self, + auth_type: &types::ConnectorAuthType, + ) -> CustomResult)>, errors::ConnectorError> { + let auth = bankofamerica::BankofamericaAuthType::try_from(auth_type) + .change_context(errors::ConnectorError::FailedToObtainAuthType)?; + Ok(vec![( + headers::AUTHORIZATION.to_string(), + auth.api_key.expose().into_masked(), + )]) + } + + fn build_error_response( + &self, + res: Response, + ) -> CustomResult { + let response: bankofamerica::BankofamericaErrorResponse = res + .response + .parse_struct("BankofamericaErrorResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + + Ok(ErrorResponse { + status_code: res.status_code, + code: response.code, + message: response.message, + reason: response.reason, + }) + } +} + +impl ConnectorValidation for Bankofamerica { + //TODO: implement functions when support enabled +} + +impl ConnectorIntegration + for Bankofamerica +{ + //TODO: implement sessions flow +} + +impl ConnectorIntegration + for Bankofamerica +{ +} + +impl + ConnectorIntegration< + api::SetupMandate, + types::SetupMandateRequestData, + types::PaymentsResponseData, + > for Bankofamerica +{ +} + +impl ConnectorIntegration + for Bankofamerica +{ + fn get_headers( + &self, + req: &types::PaymentsAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::PaymentsAuthorizeRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + req: &types::PaymentsAuthorizeRouterData, + ) -> CustomResult, errors::ConnectorError> { + let connector_router_data = bankofamerica::BankofamericaRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.amount, + req, + ))?; + let req_obj = + bankofamerica::BankofamericaPaymentsRequest::try_from(&connector_router_data)?; + let bankofamerica_req = types::RequestBody::log_and_get_request_body( + &req_obj, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(bankofamerica_req)) + } + + fn build_request( + &self, + req: &types::PaymentsAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::PaymentsAuthorizeType::get_url( + self, req, connectors, + )?) + .attach_default_headers() + .headers(types::PaymentsAuthorizeType::get_headers( + self, req, connectors, + )?) + .body(types::PaymentsAuthorizeType::get_request_body(self, req)?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsAuthorizeRouterData, + res: Response, + ) -> CustomResult { + let response: bankofamerica::BankofamericaPaymentsResponse = res + .response + .parse_struct("Bankofamerica PaymentsAuthorizeResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + ) -> CustomResult { + self.build_error_response(res) + } +} + +impl ConnectorIntegration + for Bankofamerica +{ + fn get_headers( + &self, + req: &types::PaymentsSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::PaymentsSyncRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn build_request( + &self, + req: &types::PaymentsSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Get) + .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsSyncRouterData, + res: Response, + ) -> CustomResult { + let response: bankofamerica::BankofamericaPaymentsResponse = res + .response + .parse_struct("bankofamerica PaymentsSyncResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + ) -> CustomResult { + self.build_error_response(res) + } +} + +impl ConnectorIntegration + for Bankofamerica +{ + fn get_headers( + &self, + req: &types::PaymentsCaptureRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::PaymentsCaptureRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + _req: &types::PaymentsCaptureRouterData, + ) -> CustomResult, errors::ConnectorError> { + Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) + } + + fn build_request( + &self, + req: &types::PaymentsCaptureRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::PaymentsCaptureType::get_headers( + self, req, connectors, + )?) + .body(types::PaymentsCaptureType::get_request_body(self, req)?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsCaptureRouterData, + res: Response, + ) -> CustomResult { + let response: bankofamerica::BankofamericaPaymentsResponse = res + .response + .parse_struct("Bankofamerica PaymentsCaptureResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + ) -> CustomResult { + self.build_error_response(res) + } +} + +impl ConnectorIntegration + for Bankofamerica +{ +} + +impl ConnectorIntegration + for Bankofamerica +{ + fn get_headers( + &self, + req: &types::RefundsRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::RefundsRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + req: &types::RefundsRouterData, + ) -> CustomResult, errors::ConnectorError> { + let connector_router_data = bankofamerica::BankofamericaRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.refund_amount, + req, + ))?; + let req_obj = bankofamerica::BankofamericaRefundRequest::try_from(&connector_router_data)?; + let bankofamerica_req = types::RequestBody::log_and_get_request_body( + &req_obj, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(bankofamerica_req)) + } + + fn build_request( + &self, + req: &types::RefundsRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + let request = services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::RefundExecuteType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::RefundExecuteType::get_headers( + self, req, connectors, + )?) + .body(types::RefundExecuteType::get_request_body(self, req)?) + .build(); + Ok(Some(request)) + } + + fn handle_response( + &self, + data: &types::RefundsRouterData, + res: Response, + ) -> CustomResult, errors::ConnectorError> { + let response: bankofamerica::RefundResponse = res + .response + .parse_struct("bankofamerica RefundResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + ) -> CustomResult { + self.build_error_response(res) + } +} + +impl ConnectorIntegration + for Bankofamerica +{ + fn get_headers( + &self, + req: &types::RefundSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::RefundSyncRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn build_request( + &self, + req: &types::RefundSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Get) + .url(&types::RefundSyncType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::RefundSyncType::get_headers(self, req, connectors)?) + .body(types::RefundSyncType::get_request_body(self, req)?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::RefundSyncRouterData, + res: Response, + ) -> CustomResult { + let response: bankofamerica::RefundResponse = res + .response + .parse_struct("bankofamerica RefundSyncResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + ) -> CustomResult { + self.build_error_response(res) + } +} + +#[async_trait::async_trait] +impl api::IncomingWebhook for Bankofamerica { + fn get_webhook_object_reference_id( + &self, + _request: &api::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { + Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + } + + fn get_webhook_event_type( + &self, + _request: &api::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { + Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + } + + fn get_webhook_resource_object( + &self, + _request: &api::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { + Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + } +} diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs new file mode 100644 index 000000000000..a396c47a4ced --- /dev/null +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -0,0 +1,250 @@ +use masking::Secret; +use serde::{Deserialize, Serialize}; + +use crate::{ + connector::utils::PaymentsAuthorizeRequestData, + core::errors, + types::{self, api, storage::enums}, +}; + +//TODO: Fill the struct with respective fields +pub struct BankofamericaRouterData { + pub amount: i64, // The type of amount that a connector accepts, for example, String, i64, f64, etc. + pub router_data: T, +} + +impl + TryFrom<( + &types::api::CurrencyUnit, + types::storage::enums::Currency, + i64, + T, + )> for BankofamericaRouterData +{ + type Error = error_stack::Report; + fn try_from( + (_currency_unit, _currency, amount, item): ( + &types::api::CurrencyUnit, + types::storage::enums::Currency, + i64, + T, + ), + ) -> Result { + //Todo : use utils to convert the amount to the type of amount that a connector accepts + Ok(Self { + amount, + router_data: item, + }) + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +pub struct BankofamericaPaymentsRequest { + amount: i64, + card: BankofamericaCard, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +pub struct BankofamericaCard { + name: Secret, + number: cards::CardNumber, + expiry_month: Secret, + expiry_year: Secret, + cvc: Secret, + complete: bool, +} + +impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> + for BankofamericaPaymentsRequest +{ + type Error = error_stack::Report; + fn try_from( + item: &BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>, + ) -> Result { + match item.router_data.request.payment_method_data.clone() { + api::PaymentMethodData::Card(req_card) => { + let card = BankofamericaCard { + name: req_card.card_holder_name, + number: req_card.card_number, + expiry_month: req_card.card_exp_month, + expiry_year: req_card.card_exp_year, + cvc: req_card.card_cvc, + complete: item.router_data.request.is_auto_capture()?, + }; + Ok(Self { + amount: item.amount.to_owned(), + card, + }) + } + _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + } + } +} + +//TODO: Fill the struct with respective fields +// Auth Struct +pub struct BankofamericaAuthType { + pub(super) api_key: Secret, +} + +impl TryFrom<&types::ConnectorAuthType> for BankofamericaAuthType { + type Error = error_stack::Report; + fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + match auth_type { + types::ConnectorAuthType::HeaderKey { api_key } => Ok(Self { + api_key: api_key.to_owned(), + }), + _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), + } + } +} +// PaymentsResponse +//TODO: Append the remaining status flags +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum BankofamericaPaymentStatus { + Succeeded, + Failed, + #[default] + Processing, +} + +impl From for enums::AttemptStatus { + fn from(item: BankofamericaPaymentStatus) -> Self { + match item { + BankofamericaPaymentStatus::Succeeded => Self::Charged, + BankofamericaPaymentStatus::Failed => Self::Failure, + BankofamericaPaymentStatus::Processing => Self::Authorizing, + } + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct BankofamericaPaymentsResponse { + status: BankofamericaPaymentStatus, + id: String, +} + +impl + TryFrom< + types::ResponseRouterData, + > for types::RouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + T, + types::PaymentsResponseData, + >, + ) -> Result { + Ok(Self { + status: enums::AttemptStatus::from(item.response.status), + response: Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::ConnectorTransactionId(item.response.id), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: None, + }), + ..item.data + }) + } +} + +//TODO: Fill the struct with respective fields +// REFUND : +// Type definition for RefundRequest +#[derive(Default, Debug, Serialize)] +pub struct BankofamericaRefundRequest { + pub amount: i64, +} + +impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> + for BankofamericaRefundRequest +{ + type Error = error_stack::Report; + fn try_from( + item: &BankofamericaRouterData<&types::RefundsRouterData>, + ) -> Result { + Ok(Self { + amount: item.amount.to_owned(), + }) + } +} + +// Type definition for Refund Response + +#[allow(dead_code)] +#[derive(Debug, Serialize, Default, Deserialize, Clone)] +pub enum RefundStatus { + Succeeded, + Failed, + #[default] + Processing, +} + +impl From for enums::RefundStatus { + fn from(item: RefundStatus) -> Self { + match item { + RefundStatus::Succeeded => Self::Success, + RefundStatus::Failed => Self::Failure, + RefundStatus::Processing => Self::Pending, + //TODO: Review mapping + } + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct RefundResponse { + id: String, + status: RefundStatus, +} + +impl TryFrom> + for types::RefundsRouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::RefundsResponseRouterData, + ) -> Result { + Ok(Self { + response: Ok(types::RefundsResponseData { + connector_refund_id: item.response.id.to_string(), + refund_status: enums::RefundStatus::from(item.response.status), + }), + ..item.data + }) + } +} + +impl TryFrom> + for types::RefundsRouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::RefundsResponseRouterData, + ) -> Result { + Ok(Self { + response: Ok(types::RefundsResponseData { + connector_refund_id: item.response.id.to_string(), + refund_status: enums::RefundStatus::from(item.response.status), + }), + ..item.data + }) + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Serialize, Deserialize, PartialEq)] +pub struct BankofamericaErrorResponse { + pub status_code: u16, + pub code: String, + pub message: String, + pub reason: Option, +} diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index cd1243dd3688..853a573bc64c 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1434,6 +1434,10 @@ pub(crate) fn validate_auth_and_metadata_type( authorizedotnet::transformers::AuthorizedotnetAuthType::try_from(val)?; Ok(()) } + // api_enums::Connector::Bankofamerica => { + // bankofamerica::transformers::BankofamericaAuthType::try_from(val)?; + // Ok(()) + // } Added as template code for future usage api_enums::Connector::Bitpay => { bitpay::transformers::BitpayAuthType::try_from(val)?; Ok(()) diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index c55df8e35d6e..0b253cdc6079 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -144,6 +144,7 @@ impl default_imp_for_complete_authorize!( connector::Aci, connector::Adyen, + connector::Bankofamerica, connector::Bitpay, connector::Boku, connector::Cashtocode, @@ -212,6 +213,7 @@ default_imp_for_webhook_source_verification!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Braintree, @@ -290,6 +292,7 @@ default_imp_for_create_customer!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -366,6 +369,7 @@ default_imp_for_connector_redirect_response!( connector::Aci, connector::Adyen, connector::Bitpay, + connector::Bankofamerica, connector::Boku, connector::Cashtocode, connector::Coinbase, @@ -416,6 +420,7 @@ default_imp_for_connector_request_id!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -496,6 +501,7 @@ default_imp_for_accept_dispute!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -596,6 +602,7 @@ default_imp_for_file_upload!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -673,6 +680,7 @@ default_imp_for_submit_evidence!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -750,6 +758,7 @@ default_imp_for_defend_dispute!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -828,6 +837,7 @@ default_imp_for_pre_processing_steps!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -886,6 +896,7 @@ default_imp_for_payouts!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -964,6 +975,7 @@ default_imp_for_payouts_create!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1045,6 +1057,7 @@ default_imp_for_payouts_eligibility!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1123,6 +1136,7 @@ default_imp_for_payouts_fulfill!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1201,6 +1215,7 @@ default_imp_for_payouts_cancel!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1280,6 +1295,7 @@ default_imp_for_payouts_quote!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1359,6 +1375,7 @@ default_imp_for_payouts_recipient!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1437,6 +1454,7 @@ default_imp_for_approve!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1516,6 +1534,7 @@ default_imp_for_reject!( connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Bankofamerica, connector::Bitpay, connector::Bluesnap, connector::Boku, diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index 8f5a0f8a59f2..5eecdb389e52 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -307,6 +307,7 @@ impl ConnectorData { enums::Connector::Airwallex => Ok(Box::new(&connector::Airwallex)), enums::Connector::Authorizedotnet => Ok(Box::new(&connector::Authorizedotnet)), enums::Connector::Bambora => Ok(Box::new(&connector::Bambora)), + // enums::Connector::Bankofamerica => Ok(Box::new(&connector::Bankofamerica)), Added as template code for future usage enums::Connector::Bitpay => Ok(Box::new(&connector::Bitpay)), enums::Connector::Bluesnap => Ok(Box::new(&connector::Bluesnap)), enums::Connector::Boku => Ok(Box::new(&connector::Boku)), diff --git a/crates/router/tests/connectors/bankofamerica.rs b/crates/router/tests/connectors/bankofamerica.rs new file mode 100644 index 000000000000..ce264cbccc86 --- /dev/null +++ b/crates/router/tests/connectors/bankofamerica.rs @@ -0,0 +1,420 @@ +use masking::Secret; +use router::types::{self, api, storage::enums}; +use test_utils::connector_auth; + +use crate::utils::{self, ConnectorActions}; + +#[derive(Clone, Copy)] +struct BankofamericaTest; +impl ConnectorActions for BankofamericaTest {} +impl utils::Connector for BankofamericaTest { + fn get_data(&self) -> types::api::ConnectorData { + use router::connector::Bankofamerica; + types::api::ConnectorData { + connector: Box::new(&Bankofamerica), + connector_name: types::Connector::DummyConnector1, + get_token: types::api::GetToken::Connector, + merchant_connector_id: None, + } + } + + fn get_auth_token(&self) -> types::ConnectorAuthType { + utils::to_connector_auth_type( + connector_auth::ConnectorAuthentication::new() + .bankofamerica + .expect("Missing connector authentication configuration") + .into(), + ) + } + + fn get_name(&self) -> String { + "bankofamerica".to_string() + } +} + +static CONNECTOR: BankofamericaTest = BankofamericaTest {}; + +fn get_default_payment_info() -> Option { + None +} + +fn payment_method_details() -> Option { + None +} + +// Cards Positive Tests +// Creates a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_only_authorize_payment() { + let response = CONNECTOR + .authorize_payment(payment_method_details(), get_default_payment_info()) + .await + .expect("Authorize payment response"); + assert_eq!(response.status, enums::AttemptStatus::Authorized); +} + +// Captures a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_capture_authorized_payment() { + let response = CONNECTOR + .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info()) + .await + .expect("Capture payment response"); + assert_eq!(response.status, enums::AttemptStatus::Charged); +} + +// Partially captures a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_capture_authorized_payment() { + let response = CONNECTOR + .authorize_and_capture_payment( + payment_method_details(), + Some(types::PaymentsCaptureData { + amount_to_capture: 50, + ..utils::PaymentCaptureType::default().0 + }), + get_default_payment_info(), + ) + .await + .expect("Capture payment response"); + assert_eq!(response.status, enums::AttemptStatus::Charged); +} + +// Synchronizes a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_authorized_payment() { + let authorize_response = CONNECTOR + .authorize_payment(payment_method_details(), get_default_payment_info()) + .await + .expect("Authorize payment response"); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + let response = CONNECTOR + .psync_retry_till_status_matches( + enums::AttemptStatus::Authorized, + Some(types::PaymentsSyncData { + connector_transaction_id: router::types::ResponseId::ConnectorTransactionId( + txn_id.unwrap(), + ), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .expect("PSync response"); + assert_eq!(response.status, enums::AttemptStatus::Authorized,); +} + +// Voids a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_void_authorized_payment() { + let response = CONNECTOR + .authorize_and_void_payment( + payment_method_details(), + Some(types::PaymentsCancelData { + connector_transaction_id: String::from(""), + cancellation_reason: Some("requested_by_customer".to_string()), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .expect("Void payment response"); + assert_eq!(response.status, enums::AttemptStatus::Voided); +} + +// Refunds a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_manually_captured_payment() { + let response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Partially refunds a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_refund_manually_captured_payment() { + let response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Synchronizes a refund using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_manually_captured_refund() { + let refund_response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + let response = CONNECTOR + .rsync_retry_till_status_matches( + enums::RefundStatus::Success, + refund_response.response.unwrap().connector_refund_id, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Creates a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_make_payment() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); +} + +// Synchronizes a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_auto_captured_payment() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + assert_ne!(txn_id, None, "Empty connector transaction id"); + let response = CONNECTOR + .psync_retry_till_status_matches( + enums::AttemptStatus::Charged, + Some(types::PaymentsSyncData { + connector_transaction_id: router::types::ResponseId::ConnectorTransactionId( + txn_id.unwrap(), + ), + capture_method: Some(enums::CaptureMethod::Automatic), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!(response.status, enums::AttemptStatus::Charged,); +} + +// Refunds a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_auto_captured_payment() { + let response = CONNECTOR + .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Partially refunds a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_refund_succeeded_payment() { + let refund_response = CONNECTOR + .make_payment_and_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + refund_response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_succeeded_payment_multiple_times() { + CONNECTOR + .make_payment_and_multiple_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await; +} + +// Synchronizes a refund using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_refund() { + let refund_response = CONNECTOR + .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) + .await + .unwrap(); + let response = CONNECTOR + .rsync_retry_till_status_matches( + enums::RefundStatus::Success, + refund_response.response.unwrap().connector_refund_id, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Cards Negative scenerios +// Creates a payment with incorrect CVC. +#[actix_web::test] +async fn should_fail_payment_for_incorrect_cvc() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: types::api::PaymentMethodData::Card(api::Card { + card_cvc: Secret::new("12345".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's security code is invalid.".to_string(), + ); +} + +// Creates a payment with incorrect expiry month. +#[actix_web::test] +async fn should_fail_payment_for_invalid_exp_month() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: types::api::PaymentMethodData::Card(api::Card { + card_exp_month: Secret::new("20".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's expiration month is invalid.".to_string(), + ); +} + +// Creates a payment with incorrect expiry year. +#[actix_web::test] +async fn should_fail_payment_for_incorrect_expiry_year() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: types::api::PaymentMethodData::Card(api::Card { + card_exp_year: Secret::new("2000".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's expiration year is invalid.".to_string(), + ); +} + +// Voids a payment using automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_fail_void_payment_for_auto_capture() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + assert_ne!(txn_id, None, "Empty connector transaction id"); + let void_response = CONNECTOR + .void_payment(txn_id.unwrap(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + void_response.response.unwrap_err().message, + "You cannot cancel this PaymentIntent because it has a status of succeeded." + ); +} + +// Captures a payment using invalid connector payment id. +#[actix_web::test] +async fn should_fail_capture_for_invalid_payment() { + let capture_response = CONNECTOR + .capture_payment("123456789".to_string(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + capture_response.response.unwrap_err().message, + String::from("No such payment_intent: '123456789'") + ); +} + +// Refunds a payment with refund amount higher than payment amount. +#[actix_web::test] +async fn should_fail_for_refund_amount_higher_than_payment_amount() { + let response = CONNECTOR + .make_payment_and_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 150, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Refund amount (₹1.50) is greater than charge amount (₹1.00)", + ); +} + +// Connector dependent test cases goes here + +// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests diff --git a/crates/router/tests/connectors/main.rs b/crates/router/tests/connectors/main.rs index ed06312b77ac..03b6181b8a89 100644 --- a/crates/router/tests/connectors/main.rs +++ b/crates/router/tests/connectors/main.rs @@ -11,6 +11,7 @@ mod adyen; mod airwallex; mod authorizedotnet; mod bambora; +mod bankofamerica; mod bitpay; mod bluesnap; mod boku; diff --git a/crates/router/tests/connectors/sample_auth.toml b/crates/router/tests/connectors/sample_auth.toml index 0966db95a42f..4968dfb8ff03 100644 --- a/crates/router/tests/connectors/sample_auth.toml +++ b/crates/router/tests/connectors/sample_auth.toml @@ -183,4 +183,9 @@ api_key="API Key" api_key="API Key" [prophetpay] -api_key="API Key" \ No newline at end of file +api_key="API Key" + +[bankofamerica] +api_key = "Bearer MyApiKey" +key1 = "Merchant id" +api_secret = "Secret key" diff --git a/crates/test_utils/src/connector_auth.rs b/crates/test_utils/src/connector_auth.rs index d774e2530e9d..9562972c126e 100644 --- a/crates/test_utils/src/connector_auth.rs +++ b/crates/test_utils/src/connector_auth.rs @@ -17,6 +17,7 @@ pub struct ConnectorAuthentication { pub airwallex: Option, pub authorizedotnet: Option, pub bambora: Option, + pub bankofamerica: Option, pub bitpay: Option, pub bluesnap: Option, pub boku: Option, diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml index 7cdbc8dd6fdd..352c4ff551bc 100644 --- a/loadtest/config/development.toml +++ b/loadtest/config/development.toml @@ -64,6 +64,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/" applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" +bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" @@ -130,6 +131,7 @@ cards = [ "airwallex", "authorizedotnet", "bambora", + "bankofamerica", "bitpay", "bluesnap", "boku", diff --git a/scripts/add_connector.sh b/scripts/add_connector.sh index bcd02f6cbd68..9fdc57bf3c81 100755 --- a/scripts/add_connector.sh +++ b/scripts/add_connector.sh @@ -6,7 +6,7 @@ function find_prev_connector() { git checkout $self cp $self $self.tmp # Add new connector to existing list and sort it - connectors=(aci adyen airwallex applepay authorizedotnet bambora bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource dlocal dummyconnector fiserv forte globalpay globepay gocardless helcim iatapay klarna mollie multisafepay nexinets noon nuvei opayo opennode payeezy payme paypal payu powertranz prophetpay rapyd shift4 square stax stripe trustpay tsys volt wise worldline worldpay "$1") + connectors=(aci adyen airwallex applepay authorizedotnet bambora bankofamerica bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource dlocal dummyconnector fiserv forte globalpay globepay gocardless helcim iatapay klarna mollie multisafepay nexinets noon nuvei opayo opennode payeezy payme paypal payu powertranz prophetpay rapyd shift4 square stax stripe trustpay tsys volt wise worldline worldpay "$1") IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS res=`echo ${sorted[@]}` sed -i'' -e "s/^ connectors=.*/ connectors=($res \"\$1\")/" $self.tmp From 4b545aa7d948ef63257edb0e1c8becdde330b9a4 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 2 Nov 2023 16:44:29 +0530 Subject: [PATCH 02/26] feat(connector): [BANKOFAMERICA] Address PR comments --- crates/api_models/src/enums.rs | 2 +- crates/router/tests/connectors/sample_auth.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index 177dc73d2bff..b27e71b9e8f5 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -75,9 +75,9 @@ pub enum Connector { Adyen, Airwallex, Authorizedotnet, + Bambora, // Bankofamerica, Added as template code for future usage Bitpay, - Bambora, Bluesnap, Boku, Braintree, diff --git a/crates/router/tests/connectors/sample_auth.toml b/crates/router/tests/connectors/sample_auth.toml index 4968dfb8ff03..f8f6039d6d36 100644 --- a/crates/router/tests/connectors/sample_auth.toml +++ b/crates/router/tests/connectors/sample_auth.toml @@ -186,6 +186,6 @@ api_key="API Key" api_key="API Key" [bankofamerica] -api_key = "Bearer MyApiKey" +api_key = "MyApiKey" key1 = "Merchant id" api_secret = "Secret key" From 668b78f865fe2877d13423b9c42dda085b2b6d19 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 11:28:55 +0000 Subject: [PATCH 03/26] docs(openapi): re-generate OpenAPI specification --- openapi/openapi_spec.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 45d0bde9d323..822b1aacee96 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -3898,8 +3898,8 @@ "adyen", "airwallex", "authorizedotnet", - "bitpay", "bambora", + "bitpay", "bluesnap", "boku", "braintree", From c06a93c97b5a31af87d858d011d959e3e73c6bfa Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 2 Nov 2023 17:23:23 +0530 Subject: [PATCH 04/26] feat(connector): [BANKOFAMERICA] Activate Bank of America --- crates/api_models/src/enums.rs | 4 +- crates/router/src/connector/bankofamerica.rs | 144 ++++++++++++++++-- .../connector/bankofamerica/transformers.rs | 18 ++- crates/router/src/core/admin.rs | 8 +- crates/router/src/types/api.rs | 2 +- 5 files changed, 150 insertions(+), 26 deletions(-) diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index b27e71b9e8f5..d564097c965c 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -76,7 +76,7 @@ pub enum Connector { Airwallex, Authorizedotnet, Bambora, - // Bankofamerica, Added as template code for future usage + Bankofamerica, Bitpay, Bluesnap, Boku, @@ -196,7 +196,7 @@ pub enum RoutableConnectors { Adyen, Airwallex, Authorizedotnet, - // Bankofamerica, Added as template code for future usage + Bankofamerica, Bitpay, Bambora, Bluesnap, diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index ef37411c8b25..0be0e30649e2 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -2,12 +2,19 @@ pub mod transformers; use std::fmt::Debug; +use base64::Engine; +use diesel_models::enums; use error_stack::{IntoReport, ResultExt}; -use masking::ExposeInterface; +use masking::{ExposeInterface, PeekInterface}; +use ring::{digest, hmac}; +use time::OffsetDateTime; use transformers as bankofamerica; +use url::Url; use crate::{ configs::settings, + connector::{utils as connector_utils, utils::RefundsRequestData}, + consts, core::errors::{self, CustomResult}, headers, services::{ @@ -39,6 +46,54 @@ impl api::RefundExecute for Bankofamerica {} impl api::RefundSync for Bankofamerica {} impl api::PaymentToken for Bankofamerica {} +impl Bankofamerica { + pub fn generate_digest(&self, payload: &[u8]) -> String { + let payload_digest = digest::digest(&digest::SHA256, payload); + consts::BASE64_ENGINE.encode(payload_digest) + } + + pub fn generate_signature( + &self, + auth: bankofamerica::BankofamericaAuthType, + host: String, + resource: &str, + payload: &String, + date: OffsetDateTime, + http_method: services::Method, + ) -> CustomResult { + let bankofamerica::BankofamericaAuthType { + api_key, + merchant_account, + api_secret, + } = auth; + let is_post_method = matches!(http_method, services::Method::Post); + let digest_str = if is_post_method { "digest " } else { "" }; + let headers = format!("host date (request-target) {digest_str}v-c-merchant-id"); + let request_target = if is_post_method { + format!("(request-target): post {resource}\ndigest: SHA-256={payload}\n") + } else { + format!("(request-target): get {resource}\n") + }; + let signature_string = format!( + "host: {host}\ndate: {date}\n{request_target}v-c-merchant-id: {}", + merchant_account.peek() + ); + let key_value = consts::BASE64_ENGINE + .decode(api_secret.expose()) + .into_report() + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + let key = hmac::Key::new(hmac::HMAC_SHA256, &key_value); + let signature_value = + consts::BASE64_ENGINE.encode(hmac::sign(&key, signature_string.as_bytes()).as_ref()); + let signature_header = format!( + r#"keyid="{}", algorithm="HmacSHA256", headers="{headers}", signature="{signature_value}""#, + api_key.peek() + ); + + Ok(signature_header) + } +} + impl ConnectorIntegration< api::PaymentMethodToken, @@ -56,15 +111,66 @@ where fn build_headers( &self, req: &types::RouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { - let mut header = vec![( - headers::CONTENT_TYPE.to_string(), - self.get_content_type().to_string().into(), - )]; - let mut api_key = self.get_auth_header(&req.connector_auth_type)?; - header.append(&mut api_key); - Ok(header) + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> + { + let date = OffsetDateTime::now_utc(); + let boa_req = self.get_request_body(req)?; + let auth = bankofamerica::BankofamericaAuthType::try_from(&req.connector_auth_type)?; + let merchant_account = auth.merchant_account.clone(); + let base_url = connectors.bankofamerica.base_url.as_str(); + let boa_host = Url::parse(base_url) + .into_report() + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + let host = boa_host + .host_str() + .ok_or(errors::ConnectorError::RequestEncodingFailed)?; + let path: String = self + .get_url(req, connectors)? + .chars() + .skip(base_url.len() - 1) + .collect(); + let sha256 = self.generate_digest( + boa_req + .map_or("{}".to_string(), |s| { + types::RequestBody::get_inner_value(s).expose() + }) + .as_bytes(), + ); + let http_method = self.get_http_method(); + let signature = self.generate_signature( + auth, + host.to_string(), + path.as_str(), + &sha256, + date, + http_method, + )?; + + let mut headers = vec![ + ( + headers::CONTENT_TYPE.to_string(), + self.get_content_type().to_string().into(), + ), + ( + headers::ACCEPT.to_string(), + "application/hal+json;charset=utf-8".to_string().into(), + ), + ( + "v-c-merchant-id".to_string(), + merchant_account.into_masked(), + ), + ("Date".to_string(), date.to_string().into()), + ("Host".to_string(), host.to_string().into()), + ("Signature".to_string(), signature.into_masked()), + ]; + if matches!(http_method, services::Method::Post | services::Method::Put) { + headers.push(( + "Digest".to_string(), + format!("SHA-256={sha256}").into_masked(), + )); + } + Ok(headers) } } @@ -74,10 +180,7 @@ impl ConnectorCommon for Bankofamerica { } fn get_currency_unit(&self) -> api::CurrencyUnit { - todo!() - // TODO! Check connector documentation, on which unit they are processing the currency. - // If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor, - // if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base + api::CurrencyUnit::Minor } fn common_get_content_type(&self) -> &'static str { @@ -119,7 +222,18 @@ impl ConnectorCommon for Bankofamerica { } impl ConnectorValidation for Bankofamerica { - //TODO: implement functions when support enabled + fn validate_capture_method( + &self, + capture_method: Option, + ) -> CustomResult<(), errors::ConnectorError> { + let capture_method = capture_method.unwrap_or_default(); + match capture_method { + enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), + enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( + connector_utils::construct_not_implemented_error_report(capture_method, self.id()), + ), + } + } } impl ConnectorIntegration diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index a396c47a4ced..59c91ca0aad9 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -86,16 +86,26 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> // Auth Struct pub struct BankofamericaAuthType { pub(super) api_key: Secret, + pub(super) merchant_account: Secret, + pub(super) api_secret: Secret, } impl TryFrom<&types::ConnectorAuthType> for BankofamericaAuthType { type Error = error_stack::Report; fn try_from(auth_type: &types::ConnectorAuthType) -> Result { - match auth_type { - types::ConnectorAuthType::HeaderKey { api_key } => Ok(Self { + if let types::ConnectorAuthType::SignatureKey { + api_key, + key1, + api_secret, + } = auth_type + { + Ok(Self { api_key: api_key.to_owned(), - }), - _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), + merchant_account: key1.to_owned(), + api_secret: api_secret.to_owned(), + }) + } else { + Err(errors::ConnectorError::FailedToObtainAuthType)? } } } diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 853a573bc64c..a6e861ce35e7 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1434,10 +1434,10 @@ pub(crate) fn validate_auth_and_metadata_type( authorizedotnet::transformers::AuthorizedotnetAuthType::try_from(val)?; Ok(()) } - // api_enums::Connector::Bankofamerica => { - // bankofamerica::transformers::BankofamericaAuthType::try_from(val)?; - // Ok(()) - // } Added as template code for future usage + api_enums::Connector::Bankofamerica => { + bankofamerica::transformers::BankofamericaAuthType::try_from(val)?; + Ok(()) + } api_enums::Connector::Bitpay => { bitpay::transformers::BitpayAuthType::try_from(val)?; Ok(()) diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index 5eecdb389e52..bcc1953cb61d 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -307,7 +307,7 @@ impl ConnectorData { enums::Connector::Airwallex => Ok(Box::new(&connector::Airwallex)), enums::Connector::Authorizedotnet => Ok(Box::new(&connector::Authorizedotnet)), enums::Connector::Bambora => Ok(Box::new(&connector::Bambora)), - // enums::Connector::Bankofamerica => Ok(Box::new(&connector::Bankofamerica)), Added as template code for future usage + enums::Connector::Bankofamerica => Ok(Box::new(&connector::Bankofamerica)), enums::Connector::Bitpay => Ok(Box::new(&connector::Bitpay)), enums::Connector::Bluesnap => Ok(Box::new(&connector::Bluesnap)), enums::Connector::Boku => Ok(Box::new(&connector::Boku)), From 85659a29001db62fbdb25cf2ed24dd2933365165 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 2 Nov 2023 17:30:01 +0530 Subject: [PATCH 05/26] feat(connector): [BANKOFAMERICA] Remove TODO --- crates/router/src/connector/bankofamerica.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index ef37411c8b25..e25d99f9af3d 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -74,10 +74,7 @@ impl ConnectorCommon for Bankofamerica { } fn get_currency_unit(&self) -> api::CurrencyUnit { - todo!() - // TODO! Check connector documentation, on which unit they are processing the currency. - // If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor, - // if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base + api::CurrencyUnit::Minor } fn common_get_content_type(&self) -> &'static str { From b4cfbc813e6c09cf5acb78a82e207c7f3879cabd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 12:09:27 +0000 Subject: [PATCH 06/26] docs(openapi): re-generate OpenAPI specification --- openapi/openapi_spec.json | 1 + 1 file changed, 1 insertion(+) diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 822b1aacee96..97d56fd5a3e0 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -3899,6 +3899,7 @@ "airwallex", "authorizedotnet", "bambora", + "bankofamerica", "bitpay", "bluesnap", "boku", From d2c24c849c82a768b48f0674cb21944576c4f854 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 2 Nov 2023 17:50:47 +0530 Subject: [PATCH 07/26] feat(connector): [BANKOFAMERICA] Build Headers --- crates/router/src/connector/bankofamerica.rs | 47 ++++++++++++------- .../connector/bankofamerica/transformers.rs | 44 +++++++++++++++-- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index 0be0e30649e2..accde0316adb 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -184,39 +184,52 @@ impl ConnectorCommon for Bankofamerica { } fn common_get_content_type(&self) -> &'static str { - "application/json" + "application/json;charset=utf-8" } fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { connectors.bankofamerica.base_url.as_ref() } - fn get_auth_header( - &self, - auth_type: &types::ConnectorAuthType, - ) -> CustomResult)>, errors::ConnectorError> { - let auth = bankofamerica::BankofamericaAuthType::try_from(auth_type) - .change_context(errors::ConnectorError::FailedToObtainAuthType)?; - Ok(vec![( - headers::AUTHORIZATION.to_string(), - auth.api_key.expose().into_masked(), - )]) - } - fn build_error_response( &self, res: Response, ) -> CustomResult { let response: bankofamerica::BankofamericaErrorResponse = res .response - .parse_struct("BankofamericaErrorResponse") + .parse_struct("BankOfAmerica ErrorResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + let details = response.details.unwrap_or_default(); + let connector_reason = details + .iter() + .map(|det| format!("{} : {}", det.field, det.reason)) + .collect::>() + .join(", "); + + let error_message = if res.status_code == 401 { + consts::CONNECTOR_UNAUTHORIZED_ERROR + } else { + consts::NO_ERROR_MESSAGE + }; + let (code, message) = match response.error_information { + Some(ref error_info) => (error_info.reason.clone(), error_info.message.clone()), + None => ( + response + .reason + .map_or(consts::NO_ERROR_CODE.to_string(), |reason| { + reason.to_string() + }), + response + .message + .map_or(error_message.to_string(), |message| message), + ), + }; Ok(ErrorResponse { status_code: res.status_code, - code: response.code, - message: response.message, - reason: response.reason, + code, + message, + reason: Some(connector_reason), }) } } diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 59c91ca0aad9..175d4e4bed53 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -250,11 +250,45 @@ impl TryFrom> } } -//TODO: Fill the struct with respective fields -#[derive(Default, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct BankofamericaErrorResponse { - pub status_code: u16, - pub code: String, + pub error_information: Option, + pub status: Option, + pub message: Option, + pub reason: Option, + pub details: Option>, +} + +#[derive(Debug, Deserialize, strum::Display)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum Reason { + MissingField, + InvalidData, + DuplicateRequest, + InvalidCard, + AuthAlreadyReversed, + CardTypeNotAccepted, + InvalidMerchantConfiguration, + ProcessorUnavailable, + InvalidAmount, + InvalidCardType, + InvalidPaymentId, + NotSupported, + SystemError, + ServerTimeout, + ServiceTimeout, +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Details { + pub field: String, + pub reason: String, +} + +#[derive(Debug, Default, Deserialize)] +pub struct ErrorInformation { pub message: String, - pub reason: Option, + pub reason: String, } From c80cc1252f0e5bfedc9963f663efae33baa3e9a5 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Fri, 3 Nov 2023 16:28:54 +0530 Subject: [PATCH 08/26] feat(connector): [BANKOFAMERICA] Add Auth, PSYNC, Capture & Void --- crates/router/src/connector/bankofamerica.rs | 187 ++++++-- .../connector/bankofamerica/transformers.rs | 421 +++++++++++++++--- 2 files changed, 505 insertions(+), 103 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index accde0316adb..ce3dfcfa5727 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -287,9 +287,12 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + Ok(format!( + "{}pts/v2/payments/", + api::ConnectorCommon::base_url(self, connectors) + )) } fn get_request_body( @@ -302,14 +305,14 @@ impl ConnectorIntegration::encode_to_string_of_json, ) .change_context(errors::ConnectorError::RequestEncodingFailed)?; - Ok(Some(bankofamerica_req)) + Ok(Some(bankofamerica_payments_request)) } fn build_request( @@ -327,7 +330,7 @@ impl ConnectorIntegration CustomResult { let response: bankofamerica::BankofamericaPaymentsResponse = res .response - .parse_struct("Bankofamerica PaymentsAuthorizeResponse") + .parse_struct("BankOfAmerica PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; - types::RouterData::try_from(types::ResponseRouterData { - response, - data: data.clone(), - http_code: res.status_code, - }) + let is_auto_capture = + data.request.capture_method == Some(diesel_models::enums::CaptureMethod::Automatic); + types::RouterData::try_from(( + types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }, + is_auto_capture, + )) + .change_context(errors::ConnectorError::ResponseHandlingFailed) } fn get_error_response( @@ -373,10 +382,19 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + let connector_payment_id = req + .request + .connector_transaction_id + .get_connector_transaction_id() + .change_context(errors::ConnectorError::MissingConnectorTransactionID)?; + Ok(format!( + "{}tss/v2/transactions/{}", + self.base_url(connectors), + connector_payment_id + )) } fn build_request( @@ -399,15 +417,21 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::BankofamericaPaymentsResponse = res + let response: bankofamerica::BankofamericaTransactionResponse = res .response - .parse_struct("bankofamerica PaymentsSyncResponse") + .parse_struct("BankOfAmerica PaymentSyncResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; - types::RouterData::try_from(types::ResponseRouterData { - response, - data: data.clone(), - http_code: res.status_code, - }) + let is_auto_capture = + data.request.capture_method == Some(diesel_models::enums::CaptureMethod::Automatic); + types::RouterData::try_from(( + types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }, + is_auto_capture, + )) + .change_context(errors::ConnectorError::ResponseHandlingFailed) } fn get_error_response( @@ -435,17 +459,28 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + let connector_payment_id = req.request.connector_transaction_id.clone(); + Ok(format!( + "{}pts/v2/payments/{}/captures", + self.base_url(connectors), + connector_payment_id + )) } fn get_request_body( &self, - _req: &types::PaymentsCaptureRouterData, + req: &types::PaymentsCaptureRouterData, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) + let connector_request = bankofamerica::BankofamericaPaymentsRequest::try_from(req)?; + let bankofamerica_payments_request = types::RequestBody::log_and_get_request_body( + &connector_request, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(bankofamerica_payments_request)) } fn build_request( @@ -473,13 +508,17 @@ impl ConnectorIntegration CustomResult { let response: bankofamerica::BankofamericaPaymentsResponse = res .response - .parse_struct("Bankofamerica PaymentsCaptureResponse") + .parse_struct("BankOfAmerica PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; - types::RouterData::try_from(types::ResponseRouterData { - response, - data: data.clone(), - http_code: res.status_code, - }) + types::RouterData::try_from(( + types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }, + true, + )) + .change_context(errors::ConnectorError::ResponseHandlingFailed) } fn get_error_response( @@ -493,6 +532,86 @@ impl ConnectorIntegration for Bankofamerica { + fn get_headers( + &self, + req: &types::PaymentsCancelRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_url( + &self, + req: &types::PaymentsCancelRouterData, + connectors: &settings::Connectors, + ) -> CustomResult { + let connector_payment_id = req.request.connector_transaction_id.clone(); + Ok(format!( + "{}pts/v2/payments/{}/voids", + self.base_url(connectors), + connector_payment_id + )) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_request_body( + &self, + req: &types::PaymentsCancelRouterData, + ) -> CustomResult, errors::ConnectorError> { + let connector_request = bankofamerica::BankofamericaVoidRequest::try_from(req)?; + let bankofamerica_void_request = types::RequestBody::log_and_get_request_body( + &connector_request, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(bankofamerica_void_request)) + } + + fn build_request( + &self, + req: &types::PaymentsCancelRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::PaymentsVoidType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?) + .body(self.get_request_body(req)?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsCancelRouterData, + res: Response, + ) -> CustomResult { + let response: bankofamerica::BankofamericaPaymentsResponse = res + .response + .parse_struct("BankOfAmerica PaymentResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + types::RouterData::try_from(( + types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }, + false, + )) + .change_context(errors::ConnectorError::ResponseHandlingFailed) + } + + fn get_error_response( + &self, + res: Response, + ) -> CustomResult { + self.build_error_response(res) + } } impl ConnectorIntegration diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 175d4e4bed53..ce32ce75bc20 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -1,15 +1,48 @@ +use api_models::payments; +use common_utils::pii; use masking::Secret; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::PaymentsAuthorizeRequestData, + connector::utils::{self, AddressDetailsData, PhoneDetailsData, RouterData}, + consts, core::errors, - types::{self, api, storage::enums}, + pii::PeekInterface, + types::{ + self, + api::{self, enums as api_enums}, + storage::enums, + }, }; -//TODO: Fill the struct with respective fields +pub struct BankofamericaAuthType { + pub(super) api_key: Secret, + pub(super) merchant_account: Secret, + pub(super) api_secret: Secret, +} + +impl TryFrom<&types::ConnectorAuthType> for BankofamericaAuthType { + type Error = error_stack::Report; + fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + if let types::ConnectorAuthType::SignatureKey { + api_key, + key1, + api_secret, + } = auth_type + { + Ok(Self { + api_key: api_key.to_owned(), + merchant_account: key1.to_owned(), + api_secret: api_secret.to_owned(), + }) + } else { + Err(errors::ConnectorError::FailedToObtainAuthType)? + } + } +} + pub struct BankofamericaRouterData { - pub amount: i64, // The type of amount that a connector accepts, for example, String, i64, f64, etc. + pub amount: String, pub router_data: T, } @@ -23,14 +56,14 @@ impl { type Error = error_stack::Report; fn try_from( - (_currency_unit, _currency, amount, item): ( + (currency_unit, currency, amount, item): ( &types::api::CurrencyUnit, types::storage::enums::Currency, i64, T, ), ) -> Result { - //Todo : use utils to convert the amount to the type of amount that a connector accepts + let amount = utils::get_amount_as_string(currency_unit, amount, currency)?; Ok(Self { amount, router_data: item, @@ -41,18 +74,95 @@ impl //TODO: Fill the struct with respective fields #[derive(Default, Debug, Serialize, Eq, PartialEq)] pub struct BankofamericaPaymentsRequest { - amount: i64, - card: BankofamericaCard, + processing_information: ProcessingInformation, + payment_information: PaymentInformation, + order_information: OrderInformationWithBill, + client_reference_information: ClientReferenceInformation, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct ProcessingInformation { + capture: bool, + capture_options: Option, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct CaptureOptions { + capture_sequence_number: u32, + total_capture_count: u32, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +pub struct PaymentInformation { + card: Card, } #[derive(Default, Debug, Serialize, Eq, PartialEq)] -pub struct BankofamericaCard { - name: Secret, +#[serde(rename_all = "camelCase")] +pub struct Card { number: cards::CardNumber, - expiry_month: Secret, - expiry_year: Secret, - cvc: Secret, - complete: bool, + expiration_month: Secret, + expiration_year: Secret, + security_code: Secret, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct OrderInformationWithBill { + amount_details: Amount, + bill_to: BillTo, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct Amount { + total_amount: String, + currency: String, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct BillTo { + first_name: Secret, + last_name: Secret, + address1: Secret, + locality: String, + administrative_area: Secret, + postal_code: Secret, + country: api_enums::CountryAlpha2, + email: pii::Email, + phone_number: Secret, +} + +// for bankofamerica each item in Billing is mandatory +fn build_bill_to( + address_details: &payments::Address, + email: pii::Email, + phone_number: Secret, +) -> Result> { + let address = address_details + .address + .as_ref() + .ok_or_else(utils::missing_field_err("billing.address"))?; + Ok(BillTo { + first_name: address.get_first_name()?.to_owned(), + last_name: address.get_last_name()?.to_owned(), + address1: address.get_line1()?.to_owned(), + locality: address.get_city()?.to_owned(), + administrative_area: address.to_state_code()?, + postal_code: address.get_zip()?.to_owned(), + country: address.get_country()?.to_owned(), + email, + phone_number, + }) +} + +#[derive(Default, Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct ClientReferenceInformation { + code: Option, } impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> @@ -63,18 +173,55 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> item: &BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>, ) -> Result { match item.router_data.request.payment_method_data.clone() { - api::PaymentMethodData::Card(req_card) => { - let card = BankofamericaCard { - name: req_card.card_holder_name, - number: req_card.card_number, - expiry_month: req_card.card_exp_month, - expiry_year: req_card.card_exp_year, - cvc: req_card.card_cvc, - complete: item.router_data.request.is_auto_capture()?, + api::PaymentMethodData::Card(ccard) => { + let phone = item.router_data.get_billing_phone()?; + let phone_number = phone.get_number()?; + let country_code = phone.get_country_code()?; + let number_with_code = + Secret::new(format!("{}{}", country_code, phone_number.peek())); + let email = item + .router_data + .request + .email + .clone() + .ok_or_else(utils::missing_field_err("email"))?; + let bill_to = + build_bill_to(item.router_data.get_billing()?, email, number_with_code)?; + + let order_information = OrderInformationWithBill { + amount_details: Amount { + total_amount: item.amount.to_owned(), + currency: item.router_data.request.currency.to_string().to_uppercase(), + }, + bill_to, }; + + let payment_information = PaymentInformation { + card: Card { + number: ccard.card_number, + expiration_month: ccard.card_exp_month, + expiration_year: ccard.card_exp_year, + security_code: ccard.card_cvc, + }, + }; + + let processing_information = ProcessingInformation { + capture: matches!( + item.router_data.request.capture_method, + Some(enums::CaptureMethod::Automatic) | None + ), + capture_options: None, + }; + + let client_reference_information = ClientReferenceInformation { + code: Some(item.router_data.connector_request_reference_id.clone()), + }; + Ok(Self { - amount: item.amount.to_owned(), - card, + processing_information, + payment_information, + order_information, + client_reference_information, }) } _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), @@ -82,40 +229,18 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> } } -//TODO: Fill the struct with respective fields -// Auth Struct -pub struct BankofamericaAuthType { - pub(super) api_key: Secret, - pub(super) merchant_account: Secret, - pub(super) api_secret: Secret, -} - -impl TryFrom<&types::ConnectorAuthType> for BankofamericaAuthType { - type Error = error_stack::Report; - fn try_from(auth_type: &types::ConnectorAuthType) -> Result { - if let types::ConnectorAuthType::SignatureKey { - api_key, - key1, - api_secret, - } = auth_type - { - Ok(Self { - api_key: api_key.to_owned(), - merchant_account: key1.to_owned(), - api_secret: api_secret.to_owned(), - }) - } else { - Err(errors::ConnectorError::FailedToObtainAuthType)? - } - } -} -// PaymentsResponse -//TODO: Append the remaining status flags -#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Default, Clone, Deserialize, Eq, PartialEq)] #[serde(rename_all = "lowercase")] pub enum BankofamericaPaymentStatus { + Authorized, Succeeded, Failed, + Voided, + Reversed, + Pending, + Declined, + AuthorizedPendingReview, + Transmitted, #[default] Processing, } @@ -123,55 +248,213 @@ pub enum BankofamericaPaymentStatus { impl From for enums::AttemptStatus { fn from(item: BankofamericaPaymentStatus) -> Self { match item { - BankofamericaPaymentStatus::Succeeded => Self::Charged, - BankofamericaPaymentStatus::Failed => Self::Failure, + BankofamericaPaymentStatus::Authorized + | BankofamericaPaymentStatus::AuthorizedPendingReview => Self::Authorized, + BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { + Self::Charged + } + BankofamericaPaymentStatus::Voided | BankofamericaPaymentStatus::Reversed => { + Self::Voided + } + BankofamericaPaymentStatus::Failed | BankofamericaPaymentStatus::Declined => { + Self::Failure + } BankofamericaPaymentStatus::Processing => Self::Authorizing, + BankofamericaPaymentStatus::Pending => Self::Pending, + } + } +} + +impl From for enums::RefundStatus { + fn from(item: BankofamericaPaymentStatus) -> Self { + match item { + BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { + Self::Success + } + BankofamericaPaymentStatus::Failed => Self::Failure, + _ => Self::Pending, } } } //TODO: Fill the struct with respective fields -#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Default, Debug, Clone, Deserialize, PartialEq)] pub struct BankofamericaPaymentsResponse { - status: BankofamericaPaymentStatus, id: String, + status: BankofamericaPaymentStatus, + error_information: Option, + client_reference_information: Option, +} + +#[derive(Default, Debug, Clone, Deserialize, Eq, PartialEq)] +pub struct BankofamericaErrorInformation { + reason: String, + message: String, +} + +fn get_payment_status(is_capture: bool, status: enums::AttemptStatus) -> enums::AttemptStatus { + let is_authorized = matches!(status, enums::AttemptStatus::Authorized); + if is_capture && is_authorized { + return enums::AttemptStatus::Pending; + } + status } impl - TryFrom< + TryFrom<( types::ResponseRouterData, - > for types::RouterData + bool, + )> for types::RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + data: ( + types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + T, + types::PaymentsResponseData, + >, + bool, + ), + ) -> Result { + let item = data.0; + let is_capture = data.1; + Ok(Self { + status: get_payment_status(is_capture, item.response.status.into()), + response: match item.response.error_information { + Some(error) => Err(types::ErrorResponse { + code: consts::NO_ERROR_CODE.to_string(), + message: error.message, + reason: Some(error.reason), + status_code: item.http_code, + }), + _ => Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::ConnectorTransactionId( + item.response.id.clone(), + ), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: item + .response + .client_reference_information + .map(|cref| cref.code) + .unwrap_or(Some(item.response.id)), + }), + }, + ..item.data + }) + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BankofamericaTransactionResponse { + id: String, + application_information: ApplicationInformation, + client_reference_information: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ApplicationInformation { + status: BankofamericaPaymentStatus, +} + +impl + TryFrom<( + types::ResponseRouterData< F, - BankofamericaPaymentsResponse, + BankofamericaTransactionResponse, T, types::PaymentsResponseData, >, + bool, + )> for types::RouterData +{ + type Error = error_stack::Report; + fn try_from( + data: ( + types::ResponseRouterData< + F, + BankofamericaTransactionResponse, + T, + types::PaymentsResponseData, + >, + bool, + ), ) -> Result { + let item = data.0; + let is_capture = data.1; Ok(Self { - status: enums::AttemptStatus::from(item.response.status), + status: get_payment_status( + is_capture, + item.response.application_information.status.into(), + ), response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId(item.response.id), + resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()), redirection_data: None, mandate_reference: None, connector_metadata: None, network_txn_id: None, - connector_response_reference_id: None, + connector_response_reference_id: item + .response + .client_reference_information + .map(|cref| cref.code) + .unwrap_or(Some(item.response.id)), }), ..item.data }) } } -//TODO: Fill the struct with respective fields -// REFUND : -// Type definition for RefundRequest +impl TryFrom<&types::PaymentsCaptureRouterData> for BankofamericaPaymentsRequest { + type Error = error_stack::Report; + fn try_from(value: &types::PaymentsCaptureRouterData) -> Result { + Ok(Self { + processing_information: ProcessingInformation { + capture_options: Some(CaptureOptions { + capture_sequence_number: 1, + total_capture_count: 1, + }), + ..Default::default() + }, + order_information: OrderInformationWithBill { + amount_details: Amount { + total_amount: value.request.amount_to_capture.to_string(), + ..Default::default() + }, + ..Default::default() + }, + client_reference_information: ClientReferenceInformation { + code: Some(value.connector_request_reference_id.clone()), + }, + ..Default::default() + }) + } +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +pub struct BankofamericaVoidRequest { + client_reference_information: ClientReferenceInformation, +} + +impl TryFrom<&types::PaymentsCancelRouterData> for BankofamericaVoidRequest { + type Error = error_stack::Report; + fn try_from(value: &types::PaymentsCancelRouterData) -> Result { + Ok(Self { + client_reference_information: ClientReferenceInformation { + code: Some(value.connector_request_reference_id.clone()), + }, + }) + } +} + #[derive(Default, Debug, Serialize)] pub struct BankofamericaRefundRequest { - pub amount: i64, + pub amount: String, } impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> From 646a16b9f9ddf21947d2a63a63804e5862fb5c94 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Fri, 3 Nov 2023 18:34:09 +0530 Subject: [PATCH 09/26] feat(connector): [BANKOFAMERICA] Fix Auth, PSYNC, Capture & Void --- crates/router/src/connector/bankofamerica/transformers.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index ce32ce75bc20..e96a7faa7ebf 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -73,6 +73,7 @@ impl //TODO: Fill the struct with respective fields #[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] pub struct BankofamericaPaymentsRequest { processing_information: ProcessingInformation, payment_information: PaymentInformation, @@ -230,7 +231,7 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> } #[derive(Debug, Default, Clone, Deserialize, Eq, PartialEq)] -#[serde(rename_all = "lowercase")] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum BankofamericaPaymentStatus { Authorized, Succeeded, From 1575ba5f0dd6ad3e5e73f839ec5c73baa36b8898 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Fri, 3 Nov 2023 19:04:53 +0530 Subject: [PATCH 10/26] feat(connector): [BANKOFAMERICA] Fix Capture --- .../connector/bankofamerica/transformers.rs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index e96a7faa7ebf..31a49c521d59 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -411,28 +411,32 @@ impl } } -impl TryFrom<&types::PaymentsCaptureRouterData> for BankofamericaPaymentsRequest { +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct OrderInformation { + amount_details: Amount, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct BankofamericaCaptureRequest { + order_information: OrderInformation, + client_reference_information: ClientReferenceInformation, +} + +impl TryFrom<&types::PaymentsCaptureRouterData> for BankofamericaCaptureRequest { type Error = error_stack::Report; fn try_from(value: &types::PaymentsCaptureRouterData) -> Result { Ok(Self { - processing_information: ProcessingInformation { - capture_options: Some(CaptureOptions { - capture_sequence_number: 1, - total_capture_count: 1, - }), - ..Default::default() - }, - order_information: OrderInformationWithBill { + order_information: OrderInformation { amount_details: Amount { total_amount: value.request.amount_to_capture.to_string(), - ..Default::default() + currency: value.request.currency.to_string(), }, - ..Default::default() }, client_reference_information: ClientReferenceInformation { code: Some(value.connector_request_reference_id.clone()), }, - ..Default::default() }) } } From 38fbdb47c9bb131e5614138ecc346ab0fdb6df14 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Mon, 6 Nov 2023 17:59:12 +0530 Subject: [PATCH 11/26] feat(connector):[ BANKOFAMERICA] Fix PSYNC --- crates/router/src/connector/bankofamerica.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index ce3dfcfa5727..3d6c30f6fff5 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -116,6 +116,10 @@ where { let date = OffsetDateTime::now_utc(); let boa_req = self.get_request_body(req)?; + let http_method = match boa_req{ + Some(_) => common_utils::request::Method::Post, + None => common_utils::request::Method::Get, + }; let auth = bankofamerica::BankofamericaAuthType::try_from(&req.connector_auth_type)?; let merchant_account = auth.merchant_account.clone(); let base_url = connectors.bankofamerica.base_url.as_str(); @@ -137,7 +141,6 @@ where }) .as_bytes(), ); - let http_method = self.get_http_method(); let signature = self.generate_signature( auth, host.to_string(), @@ -474,13 +477,13 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_request = bankofamerica::BankofamericaPaymentsRequest::try_from(req)?; - let bankofamerica_payments_request = types::RequestBody::log_and_get_request_body( + let connector_request = bankofamerica::BankofamericaCaptureRequest::try_from(req)?; + let bankofamerica_capture_request = types::RequestBody::log_and_get_request_body( &connector_request, - utils::Encode::::encode_to_string_of_json, + utils::Encode::::encode_to_string_of_json, ) .change_context(errors::ConnectorError::RequestEncodingFailed)?; - Ok(Some(bankofamerica_payments_request)) + Ok(Some(bankofamerica_capture_request)) } fn build_request( From 9b2d837be87f1f2bb3b6c920c461ca4599de84ff Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Mon, 6 Nov 2023 19:58:13 +0530 Subject: [PATCH 12/26] feat(connector): [BANKOFAMERICA] Add Refund, RSYNC Flow --- crates/router/src/connector/bankofamerica.rs | 28 +++++--- .../connector/bankofamerica/transformers.rs | 68 +++++++------------ 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index 3d6c30f6fff5..6d5e4211d9c8 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -116,7 +116,7 @@ where { let date = OffsetDateTime::now_utc(); let boa_req = self.get_request_body(req)?; - let http_method = match boa_req{ + let http_method = match boa_req { Some(_) => common_utils::request::Method::Post, None => common_utils::request::Method::Get, }; @@ -634,10 +634,15 @@ impl ConnectorIntegration, - _connectors: &settings::Connectors, + req: &types::RefundsRouterData, + connectors: &settings::Connectors, ) -> CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + let connector_payment_id = req.request.connector_transaction_id.clone(); + Ok(format!( + "{}pts/v2/payments/{}/refunds", + self.base_url(connectors), + connector_payment_id + )) } fn get_request_body( @@ -681,7 +686,7 @@ impl ConnectorIntegration, res: Response, ) -> CustomResult, errors::ConnectorError> { - let response: bankofamerica::RefundResponse = res + let response: bankofamerica::BankofamericaPaymentsResponse = res .response .parse_struct("bankofamerica RefundResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -717,10 +722,15 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + let refund_id = req.request.get_connector_refund_id()?; + Ok(format!( + "{}tss/v2/transactions/{}", + self.base_url(connectors), + refund_id + )) } fn build_request( @@ -744,7 +754,7 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::RefundResponse = res + let response: bankofamerica::BankofamericaTransactionResponse = res .response .parse_struct("bankofamerica RefundSyncResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 31a49c521d59..9ad50c35f751 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -266,18 +266,6 @@ impl From for enums::AttemptStatus { } } -impl From for enums::RefundStatus { - fn from(item: BankofamericaPaymentStatus) -> Self { - match item { - BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { - Self::Success - } - BankofamericaPaymentStatus::Failed => Self::Failure, - _ => Self::Pending, - } - } -} - //TODO: Fill the struct with respective fields #[derive(Default, Debug, Clone, Deserialize, PartialEq)] pub struct BankofamericaPaymentsResponse { @@ -459,7 +447,7 @@ impl TryFrom<&types::PaymentsCancelRouterData> for BankofamericaVoidRequest { #[derive(Default, Debug, Serialize)] pub struct BankofamericaRefundRequest { - pub amount: String, + order_information: OrderInformation, } impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> @@ -470,50 +458,38 @@ impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> item: &BankofamericaRouterData<&types::RefundsRouterData>, ) -> Result { Ok(Self { - amount: item.amount.to_owned(), + order_information: OrderInformation { + amount_details: Amount { + total_amount: item.router_data.request.refund_amount.to_string(), + currency: item.router_data.request.currency.to_string(), + }, + }, }) } } -// Type definition for Refund Response - -#[allow(dead_code)] -#[derive(Debug, Serialize, Default, Deserialize, Clone)] -pub enum RefundStatus { - Succeeded, - Failed, - #[default] - Processing, -} - -impl From for enums::RefundStatus { - fn from(item: RefundStatus) -> Self { +impl From for enums::RefundStatus { + fn from(item: BankofamericaPaymentStatus) -> Self { match item { - RefundStatus::Succeeded => Self::Success, - RefundStatus::Failed => Self::Failure, - RefundStatus::Processing => Self::Pending, - //TODO: Review mapping + BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { + Self::Success + } + BankofamericaPaymentStatus::Failed => Self::Failure, + _ => Self::Pending, } } } -//TODO: Fill the struct with respective fields -#[derive(Default, Debug, Clone, Serialize, Deserialize)] -pub struct RefundResponse { - id: String, - status: RefundStatus, -} - -impl TryFrom> +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { Ok(Self { response: Ok(types::RefundsResponseData { - connector_refund_id: item.response.id.to_string(), + connector_refund_id: item.response.id, refund_status: enums::RefundStatus::from(item.response.status), }), ..item.data @@ -521,17 +497,19 @@ impl TryFrom> } } -impl TryFrom> +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { Ok(Self { response: Ok(types::RefundsResponseData { - connector_refund_id: item.response.id.to_string(), - refund_status: enums::RefundStatus::from(item.response.status), + connector_refund_id: item.response.id, + refund_status: enums::RefundStatus::from( + item.response.application_information.status, + ), }), ..item.data }) From 7cf3aba368c440c945af07649cb47eeed49aa060 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Mon, 6 Nov 2023 20:16:50 +0530 Subject: [PATCH 13/26] feat(connector): [BANKOFAMERICA] Fix --- crates/api_models/src/routing.rs | 3 ++- crates/euclid/src/enums.rs | 3 ++- crates/router/src/core/payments/routing/transformers.rs | 3 ++- crates/router/src/types/transformers.rs | 6 ++++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs index 95d4c5e10ece..83e264f3bf0b 100644 --- a/crates/api_models/src/routing.rs +++ b/crates/api_models/src/routing.rs @@ -300,8 +300,9 @@ impl From for ast::ConnectorChoice { RoutableConnectors::Adyen => euclid_enums::Connector::Adyen, RoutableConnectors::Airwallex => euclid_enums::Connector::Airwallex, RoutableConnectors::Authorizedotnet => euclid_enums::Connector::Authorizedotnet, - RoutableConnectors::Bitpay => euclid_enums::Connector::Bitpay, RoutableConnectors::Bambora => euclid_enums::Connector::Bambora, + RoutableConnectors::Bankofamerica => euclid_enums::Connector::Bankofamerica, + RoutableConnectors::Bitpay => euclid_enums::Connector::Bitpay, RoutableConnectors::Bluesnap => euclid_enums::Connector::Bluesnap, RoutableConnectors::Boku => euclid_enums::Connector::Boku, RoutableConnectors::Braintree => euclid_enums::Connector::Braintree, diff --git a/crates/euclid/src/enums.rs b/crates/euclid/src/enums.rs index 4188860ab90f..da5c99816715 100644 --- a/crates/euclid/src/enums.rs +++ b/crates/euclid/src/enums.rs @@ -86,8 +86,9 @@ pub enum Connector { Adyen, Airwallex, Authorizedotnet, - Bitpay, Bambora, + Bankofamerica, + Bitpay, Bluesnap, Boku, Braintree, diff --git a/crates/router/src/core/payments/routing/transformers.rs b/crates/router/src/core/payments/routing/transformers.rs index de94a36248ff..d7061a1502de 100644 --- a/crates/router/src/core/payments/routing/transformers.rs +++ b/crates/router/src/core/payments/routing/transformers.rs @@ -74,8 +74,9 @@ impl ForeignFrom for dsl_enums::Connector { api_enums::RoutableConnectors::Adyen => Self::Adyen, api_enums::RoutableConnectors::Airwallex => Self::Airwallex, api_enums::RoutableConnectors::Authorizedotnet => Self::Authorizedotnet, - api_enums::RoutableConnectors::Bitpay => Self::Bitpay, api_enums::RoutableConnectors::Bambora => Self::Bambora, + api_enums::RoutableConnectors::Bankofamerica => Self::Bankofamerica, + api_enums::RoutableConnectors::Bitpay => Self::Bitpay, api_enums::RoutableConnectors::Bluesnap => Self::Bluesnap, api_enums::RoutableConnectors::Boku => Self::Boku, api_enums::RoutableConnectors::Braintree => Self::Braintree, diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 83ca0d014dc8..582a85f7c156 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -193,8 +193,9 @@ impl ForeignTryFrom for api_enums::RoutableConnectors { api_enums::Connector::Adyen => Self::Adyen, api_enums::Connector::Airwallex => Self::Airwallex, api_enums::Connector::Authorizedotnet => Self::Authorizedotnet, - api_enums::Connector::Bitpay => Self::Bitpay, api_enums::Connector::Bambora => Self::Bambora, + api_enums::Connector::Bankofamerica => Self::Bankofamerica, + api_enums::Connector::Bitpay => Self::Bitpay, api_enums::Connector::Bluesnap => Self::Bluesnap, api_enums::Connector::Boku => Self::Boku, api_enums::Connector::Braintree => Self::Braintree, @@ -272,8 +273,9 @@ impl ForeignFrom for api_enums::RoutableConnectors { dsl_enums::Connector::Adyen => Self::Adyen, dsl_enums::Connector::Airwallex => Self::Airwallex, dsl_enums::Connector::Authorizedotnet => Self::Authorizedotnet, - dsl_enums::Connector::Bitpay => Self::Bitpay, dsl_enums::Connector::Bambora => Self::Bambora, + dsl_enums::Connector::Bankofamerica => Self::Bankofamerica, + dsl_enums::Connector::Bitpay => Self::Bitpay, dsl_enums::Connector::Bluesnap => Self::Bluesnap, dsl_enums::Connector::Boku => Self::Boku, dsl_enums::Connector::Braintree => Self::Braintree, From c6d559768df6d0e5793396a44568a705c00bbd38 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Tue, 7 Nov 2023 15:57:06 +0530 Subject: [PATCH 14/26] feat(connector): [BANKOFAMERICA] Fix Base/Minor amount --- crates/router/src/connector/bankofamerica.rs | 11 +++++++++-- .../src/connector/bankofamerica/transformers.rs | 15 ++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index 6d5e4211d9c8..fdc763fff4a8 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -183,7 +183,7 @@ impl ConnectorCommon for Bankofamerica { } fn get_currency_unit(&self) -> api::CurrencyUnit { - api::CurrencyUnit::Minor + api::CurrencyUnit::Base } fn common_get_content_type(&self) -> &'static str { @@ -477,7 +477,14 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_request = bankofamerica::BankofamericaCaptureRequest::try_from(req)?; + let connector_router_data = bankofamerica::BankofamericaRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.amount_to_capture, + req, + ))?; + let connector_request = + bankofamerica::BankofamericaCaptureRequest::try_from(&connector_router_data)?; let bankofamerica_capture_request = types::RequestBody::log_and_get_request_body( &connector_request, utils::Encode::::encode_to_string_of_json, diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 9ad50c35f751..4b67510e787b 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -412,18 +412,22 @@ pub struct BankofamericaCaptureRequest { client_reference_information: ClientReferenceInformation, } -impl TryFrom<&types::PaymentsCaptureRouterData> for BankofamericaCaptureRequest { +impl TryFrom<&BankofamericaRouterData<&types::PaymentsCaptureRouterData>> + for BankofamericaCaptureRequest +{ type Error = error_stack::Report; - fn try_from(value: &types::PaymentsCaptureRouterData) -> Result { + fn try_from( + value: &BankofamericaRouterData<&types::PaymentsCaptureRouterData>, + ) -> Result { Ok(Self { order_information: OrderInformation { amount_details: Amount { - total_amount: value.request.amount_to_capture.to_string(), - currency: value.request.currency.to_string(), + total_amount: value.amount.to_owned(), + currency: value.router_data.request.currency.to_string(), }, }, client_reference_information: ClientReferenceInformation { - code: Some(value.connector_request_reference_id.clone()), + code: Some(value.router_data.connector_request_reference_id.clone()), }, }) } @@ -446,6 +450,7 @@ impl TryFrom<&types::PaymentsCancelRouterData> for BankofamericaVoidRequest { } #[derive(Default, Debug, Serialize)] +#[serde(rename_all = "camelCase")] pub struct BankofamericaRefundRequest { order_information: OrderInformation, } From c75294cdcd9995fd721efc655ffa3b6bd1c01dad Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Wed, 8 Nov 2023 11:07:18 +0530 Subject: [PATCH 15/26] feat(connector): [BANKOFAMERICA] Add card type function --- .../connector/bankofamerica/transformers.rs | 27 +++++++++++++++++-- .../connector/multisafepay/transformers.rs | 12 ++++----- .../src/connector/payeezy/transformers.rs | 13 ++++----- crates/router/src/connector/utils.rs | 2 ++ 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 4b67510e787b..3b386b57b0aa 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -4,7 +4,9 @@ use masking::Secret; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::{self, AddressDetailsData, PhoneDetailsData, RouterData}, + connector::utils::{ + self, AddressDetailsData, CardData, CardIssuer, PhoneDetailsData, RouterData, + }, consts, core::errors, pii::PeekInterface, @@ -107,6 +109,8 @@ pub struct Card { expiration_month: Secret, expiration_year: Secret, security_code: Secret, + #[serde(rename = "type")] + card_type: Option, } #[derive(Default, Debug, Serialize, Eq, PartialEq)] @@ -160,6 +164,20 @@ fn build_bill_to( }) } +fn get_card_type(card_issuer: CardIssuer) -> &'static str { + match card_issuer { + CardIssuer::AmericanExpress => "003", + CardIssuer::Master => "002", + //"042" is the type code for Masetro Cards(International). For Maestro Cards(UK-Domestic) the mapping shoule be "024" + CardIssuer::Maestro => "042", + CardIssuer::Visa => "001", + CardIssuer::Discover => "004", + CardIssuer::DinersClub => "005", + CardIssuer::CarteBlanche => "006", + CardIssuer::JCB => "007", + } +} + #[derive(Default, Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] #[serde(rename_all = "camelCase")] pub struct ClientReferenceInformation { @@ -196,13 +214,18 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> }, bill_to, }; - + let card_issuer = ccard.get_card_issuer(); + let card_type = match card_issuer { + Ok(issuer) => Some(get_card_type(issuer).to_string()), + Err(_) => None, + }; let payment_information = PaymentInformation { card: Card { number: ccard.card_number, expiration_month: ccard.card_exp_month, expiration_year: ccard.card_exp_year, security_code: ccard.card_cvc, + card_type, }, }; diff --git a/crates/router/src/connector/multisafepay/transformers.rs b/crates/router/src/connector/multisafepay/transformers.rs index 3eead97ad863..75d38483c42f 100644 --- a/crates/router/src/connector/multisafepay/transformers.rs +++ b/crates/router/src/connector/multisafepay/transformers.rs @@ -260,13 +260,13 @@ impl TryFrom for Gateway { utils::CardIssuer::Maestro => Ok(Self::Maestro), utils::CardIssuer::Discover => Ok(Self::Discover), utils::CardIssuer::Visa => Ok(Self::Visa), - utils::CardIssuer::DinersClub | utils::CardIssuer::JCB => { - Err(errors::ConnectorError::NotSupported { - message: issuer.to_string(), - connector: "Multisafe pay", - } - .into()) + utils::CardIssuer::DinersClub + | utils::CardIssuer::JCB + | utils::CardIssuer::CarteBlanche => Err(errors::ConnectorError::NotSupported { + message: issuer.to_string(), + connector: "Multisafe pay", } + .into()), } } } diff --git a/crates/router/src/connector/payeezy/transformers.rs b/crates/router/src/connector/payeezy/transformers.rs index 3a859b325300..e2e837929c41 100644 --- a/crates/router/src/connector/payeezy/transformers.rs +++ b/crates/router/src/connector/payeezy/transformers.rs @@ -69,13 +69,14 @@ impl TryFrom for PayeezyCardType { utils::CardIssuer::Discover => Ok(Self::Discover), utils::CardIssuer::Visa => Ok(Self::Visa), - utils::CardIssuer::Maestro | utils::CardIssuer::DinersClub | utils::CardIssuer::JCB => { - Err(errors::ConnectorError::NotSupported { - message: utils::SELECTED_PAYMENT_METHOD.to_string(), - connector: "Payeezy", - } - .into()) + utils::CardIssuer::Maestro + | utils::CardIssuer::DinersClub + | utils::CardIssuer::JCB + | utils::CardIssuer::CarteBlanche => Err(errors::ConnectorError::NotSupported { + message: utils::SELECTED_PAYMENT_METHOD.to_string(), + connector: "Payeezy", } + .into()), } } } diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 3a8cae3a631e..bdc2dd8bd29e 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -626,6 +626,7 @@ static CARD_REGEX: Lazy>> = Lazy CardIssuer::JCB, Regex::new(r"^(3(?:088|096|112|158|337|5(?:2[89]|[3-8][0-9]))\d{12})$"), ); + map.insert(CardIssuer::CarteBlanche, Regex::new(r"^389[0-9]{11}$")); map }); @@ -638,6 +639,7 @@ pub enum CardIssuer { Discover, DinersClub, JCB, + CarteBlanche, } pub trait CardData { From 86a96a9b8ced864e0faa0360f508c53d50cc43a1 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Wed, 8 Nov 2023 17:38:09 +0530 Subject: [PATCH 16/26] feat(connector): [BANKOFAMERICA] Fix PR comments --- crates/router/src/configs/defaults.rs | 132 ++++++++++++++++++ crates/router/src/connector/bankofamerica.rs | 63 ++++----- .../connector/bankofamerica/transformers.rs | 79 +++++------ 3 files changed, 203 insertions(+), 71 deletions(-) diff --git a/crates/router/src/configs/defaults.rs b/crates/router/src/configs/defaults.rs index 8d58037343e0..40cfefe35621 100644 --- a/crates/router/src/configs/defaults.rs +++ b/crates/router/src/configs/defaults.rs @@ -458,6 +458,138 @@ impl Default for super::settings::RequiredFields { common: HashMap::new(), } ), + ( + enums::Connector::Bankofamerica, + RequiredFieldFinal { + mandate: HashMap::new(), + non_mandate: HashMap::from( + [ + ( + "payment_method_data.card.card_number".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_number".to_string(), + display_name: "card_number".to_string(), + field_type: enums::FieldType::UserCardNumber, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_month".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_month".to_string(), + display_name: "card_exp_month".to_string(), + field_type: enums::FieldType::UserCardExpiryMonth, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_year".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_year".to_string(), + display_name: "card_exp_year".to_string(), + field_type: enums::FieldType::UserCardExpiryYear, + value: None, + } + ), + ( + "payment_method_data.card.card_cvc".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_cvc".to_string(), + display_name: "card_cvc".to_string(), + field_type: enums::FieldType::UserCardCvc, + value: None, + } + ), + ( + "payment_method_data.card.card_holder_name".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_holder_name".to_string(), + display_name: "card_holder_name".to_string(), + field_type: enums::FieldType::UserFullName, + value: None, + } + ), + ( + "email".to_string(), + RequiredFieldInfo { + required_field: "email".to_string(), + display_name: "email".to_string(), + field_type: enums::FieldType::UserEmailAddress, + value: None, + } + ), + ( + "billing.address.first_name".to_string(), + RequiredFieldInfo { + required_field: "billing.address.first_name".to_string(), + display_name: "billing_first_name".to_string(), + field_type: enums::FieldType::UserBillingName, + value: None, + } + ), + ( + "billing.address.last_name".to_string(), + RequiredFieldInfo { + required_field: "billing.address.last_name".to_string(), + display_name: "billing_last_name".to_string(), + field_type: enums::FieldType::UserBillingName, + value: None, + } + ), + ( + "billing.address.city".to_string(), + RequiredFieldInfo { + required_field: "billing.address.city".to_string(), + display_name: "city".to_string(), + field_type: enums::FieldType::UserAddressCity, + value: None, + } + ), + ( + "billing.address.state".to_string(), + RequiredFieldInfo { + required_field: "billing.address.state".to_string(), + display_name: "state".to_string(), + field_type: enums::FieldType::UserAddressState, + value: None, + } + ), + ( + "billing.address.zip".to_string(), + RequiredFieldInfo { + required_field: "billing.address.zip".to_string(), + display_name: "zip".to_string(), + field_type: enums::FieldType::UserAddressPincode, + value: None, + } + ), + ( + "billing.address.country".to_string(), + RequiredFieldInfo { + required_field: "billing.address.country".to_string(), + display_name: "country".to_string(), + field_type: enums::FieldType::UserAddressCountry{ + options: vec![ + "ALL".to_string(), + ] + }, + value: None, + } + ), + ( + "billing.address.line1".to_string(), + RequiredFieldInfo { + required_field: "billing.address.line1".to_string(), + display_name: "line1".to_string(), + field_type: enums::FieldType::UserAddressline1, + value: None, + } + ), + ] + ), + common: HashMap::new(), + } + ), ( enums::Connector::Bluesnap, RequiredFieldFinal { diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index fdc763fff4a8..3a32d5745cb2 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -30,6 +30,8 @@ use crate::{ utils::{self, BytesExt}, }; +pub const V_C_MERCHANT_ID: &str = "v-c-merchant-id"; + #[derive(Debug, Clone)] pub struct Bankofamerica; @@ -68,14 +70,14 @@ impl Bankofamerica { } = auth; let is_post_method = matches!(http_method, services::Method::Post); let digest_str = if is_post_method { "digest " } else { "" }; - let headers = format!("host date (request-target) {digest_str}v-c-merchant-id"); + let headers = format!("host date (request-target) {digest_str}{V_C_MERCHANT_ID}"); let request_target = if is_post_method { format!("(request-target): post {resource}\ndigest: SHA-256={payload}\n") } else { format!("(request-target): get {resource}\n") }; let signature_string = format!( - "host: {host}\ndate: {date}\n{request_target}v-c-merchant-id: {}", + "host: {host}\ndate: {date}\n{request_target}{V_C_MERCHANT_ID}: {}", merchant_account.peek() ); let key_value = consts::BASE64_ENGINE @@ -116,10 +118,7 @@ where { let date = OffsetDateTime::now_utc(); let boa_req = self.get_request_body(req)?; - let http_method = match boa_req { - Some(_) => common_utils::request::Method::Post, - None => common_utils::request::Method::Get, - }; + let http_method = self.get_http_method(); let auth = bankofamerica::BankofamericaAuthType::try_from(&req.connector_auth_type)?; let merchant_account = auth.merchant_account.clone(); let base_url = connectors.bankofamerica.base_url.as_str(); @@ -159,10 +158,7 @@ where headers::ACCEPT.to_string(), "application/hal+json;charset=utf-8".to_string().into(), ), - ( - "v-c-merchant-id".to_string(), - merchant_account.into_masked(), - ), + (V_C_MERCHANT_ID.to_string(), merchant_account.into_masked()), ("Date".to_string(), date.to_string().into()), ("Host".to_string(), host.to_string().into()), ("Signature".to_string(), signature.into_masked()), @@ -202,12 +198,6 @@ impl ConnectorCommon for Bankofamerica { .response .parse_struct("BankOfAmerica ErrorResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; - let details = response.details.unwrap_or_default(); - let connector_reason = details - .iter() - .map(|det| format!("{} : {}", det.field, det.reason)) - .collect::>() - .join(", "); let error_message = if res.status_code == 401 { consts::CONNECTOR_UNAUTHORIZED_ERROR @@ -228,6 +218,15 @@ impl ConnectorCommon for Bankofamerica { .map_or(error_message.to_string(), |message| message), ), }; + let connector_reason = match response.details { + Some(details) => details + .iter() + .map(|det| format!("{} : {}", det.field, det.reason)) + .collect::>() + .join(", "), + None => message.clone(), + }; + Ok(ErrorResponse { status_code: res.status_code, code, @@ -357,7 +356,6 @@ impl ConnectorIntegration services::Method { + services::Method::Get + } + fn get_url( &self, req: &types::PaymentsSyncRouterData, @@ -434,7 +436,6 @@ impl ConnectorIntegration CustomResult { let connector_payment_id = req.request.connector_transaction_id.clone(); Ok(format!( - "{}pts/v2/payments/{}/captures", - self.base_url(connectors), - connector_payment_id + "{}pts/v2/payments/{connector_payment_id}/captures", + self.base_url(connectors) )) } @@ -528,7 +528,6 @@ impl ConnectorIntegration CustomResult { let connector_payment_id = req.request.connector_transaction_id.clone(); Ok(format!( - "{}pts/v2/payments/{}/voids", - self.base_url(connectors), - connector_payment_id + "{}pts/v2/payments/{connector_payment_id}/voids", + self.base_url(connectors) )) } @@ -613,7 +611,6 @@ impl ConnectorIntegration CustomResult { let connector_payment_id = req.request.connector_transaction_id.clone(); Ok(format!( - "{}pts/v2/payments/{}/refunds", - self.base_url(connectors), - connector_payment_id + "{}pts/v2/payments/{connector_payment_id}/refunds", + self.base_url(connectors) )) } @@ -727,6 +723,10 @@ impl ConnectorIntegration services::Method { + services::Method::Get + } + fn get_url( &self, req: &types::RefundSyncRouterData, @@ -734,9 +734,8 @@ impl ConnectorIntegration CustomResult { let refund_id = req.request.get_connector_refund_id()?; Ok(format!( - "{}tss/v2/transactions/{}", - self.base_url(connectors), - refund_id + "{}tss/v2/transactions/{refund_id}", + self.base_url(connectors) )) } diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 3b386b57b0aa..48f7f139a08e 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -4,12 +4,9 @@ use masking::Secret; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::{ - self, AddressDetailsData, CardData, CardIssuer, PhoneDetailsData, RouterData, - }, + connector::utils::{self, AddressDetailsData, CardData, CardIssuer, RouterData}, consts, core::errors, - pii::PeekInterface, types::{ self, api::{self, enums as api_enums}, @@ -73,8 +70,7 @@ impl } } -//TODO: Fill the struct with respective fields -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct BankofamericaPaymentsRequest { processing_information: ProcessingInformation, @@ -83,26 +79,26 @@ pub struct BankofamericaPaymentsRequest { client_reference_information: ClientReferenceInformation, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct ProcessingInformation { capture: bool, capture_options: Option, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct CaptureOptions { capture_sequence_number: u32, total_capture_count: u32, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] pub struct PaymentInformation { card: Card, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Card { number: cards::CardNumber, @@ -113,21 +109,21 @@ pub struct Card { card_type: Option, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct OrderInformationWithBill { amount_details: Amount, bill_to: BillTo, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Amount { total_amount: String, currency: String, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct BillTo { first_name: Secret, @@ -138,14 +134,12 @@ pub struct BillTo { postal_code: Secret, country: api_enums::CountryAlpha2, email: pii::Email, - phone_number: Secret, } // for bankofamerica each item in Billing is mandatory fn build_bill_to( address_details: &payments::Address, email: pii::Email, - phone_number: Secret, ) -> Result> { let address = address_details .address @@ -160,7 +154,6 @@ fn build_bill_to( postal_code: address.get_zip()?.to_owned(), country: address.get_country()?.to_owned(), email, - phone_number, }) } @@ -168,7 +161,7 @@ fn get_card_type(card_issuer: CardIssuer) -> &'static str { match card_issuer { CardIssuer::AmericanExpress => "003", CardIssuer::Master => "002", - //"042" is the type code for Masetro Cards(International). For Maestro Cards(UK-Domestic) the mapping shoule be "024" + //"042" is the type code for Masetro Cards(International). For Maestro Cards(UK-Domestic) the mapping should be "024" CardIssuer::Maestro => "042", CardIssuer::Visa => "001", CardIssuer::Discover => "004", @@ -178,7 +171,7 @@ fn get_card_type(card_issuer: CardIssuer) -> &'static str { } } -#[derive(Default, Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +#[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct ClientReferenceInformation { code: Option, @@ -193,19 +186,13 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> ) -> Result { match item.router_data.request.payment_method_data.clone() { api::PaymentMethodData::Card(ccard) => { - let phone = item.router_data.get_billing_phone()?; - let phone_number = phone.get_number()?; - let country_code = phone.get_country_code()?; - let number_with_code = - Secret::new(format!("{}{}", country_code, phone_number.peek())); let email = item .router_data .request .email .clone() .ok_or_else(utils::missing_field_err("email"))?; - let bill_to = - build_bill_to(item.router_data.get_billing()?, email, number_with_code)?; + let bill_to = build_bill_to(item.router_data.get_billing()?, email)?; let order_information = OrderInformationWithBill { amount_details: Amount { @@ -248,12 +235,25 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> client_reference_information, }) } - _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + payments::PaymentMethodData::CardRedirect(_) + | payments::PaymentMethodData::Wallet(_) + | payments::PaymentMethodData::PayLater(_) + | payments::PaymentMethodData::BankRedirect(_) + | payments::PaymentMethodData::BankDebit(_) + | payments::PaymentMethodData::BankTransfer(_) + | payments::PaymentMethodData::Crypto(_) + | payments::PaymentMethodData::MandatePayment + | payments::PaymentMethodData::Reward + | payments::PaymentMethodData::Upi(_) + | payments::PaymentMethodData::Voucher(_) + | payments::PaymentMethodData::GiftCard(_) => { + Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()) + } } } } -#[derive(Debug, Default, Clone, Deserialize, Eq, PartialEq)] +#[derive(Debug, Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum BankofamericaPaymentStatus { Authorized, @@ -265,8 +265,6 @@ pub enum BankofamericaPaymentStatus { Declined, AuthorizedPendingReview, Transmitted, - #[default] - Processing, } impl From for enums::AttemptStatus { @@ -283,14 +281,12 @@ impl From for enums::AttemptStatus { BankofamericaPaymentStatus::Failed | BankofamericaPaymentStatus::Declined => { Self::Failure } - BankofamericaPaymentStatus::Processing => Self::Authorizing, BankofamericaPaymentStatus::Pending => Self::Pending, } } } -//TODO: Fill the struct with respective fields -#[derive(Default, Debug, Clone, Deserialize, PartialEq)] +#[derive(Debug, Deserialize)] pub struct BankofamericaPaymentsResponse { id: String, status: BankofamericaPaymentStatus, @@ -298,7 +294,7 @@ pub struct BankofamericaPaymentsResponse { client_reference_information: Option, } -#[derive(Default, Debug, Clone, Deserialize, Eq, PartialEq)] +#[derive(Debug, Deserialize)] pub struct BankofamericaErrorInformation { reason: String, message: String, @@ -422,13 +418,13 @@ impl } } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct OrderInformation { amount_details: Amount, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct BankofamericaCaptureRequest { order_information: OrderInformation, @@ -456,7 +452,7 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsCaptureRouterData>> } } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] +#[derive(Debug, Serialize)] pub struct BankofamericaVoidRequest { client_reference_information: ClientReferenceInformation, } @@ -472,7 +468,7 @@ impl TryFrom<&types::PaymentsCancelRouterData> for BankofamericaVoidRequest { } } -#[derive(Default, Debug, Serialize)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct BankofamericaRefundRequest { order_information: OrderInformation, @@ -502,8 +498,13 @@ impl From for enums::RefundStatus { BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { Self::Success } - BankofamericaPaymentStatus::Failed => Self::Failure, - _ => Self::Pending, + BankofamericaPaymentStatus::Failed + | BankofamericaPaymentStatus::Authorized + | BankofamericaPaymentStatus::Voided + | BankofamericaPaymentStatus::Reversed + | BankofamericaPaymentStatus::Pending + | BankofamericaPaymentStatus::Declined + | BankofamericaPaymentStatus::AuthorizedPendingReview => Self::Pending, } } } From e31901d7270019125e665c9c6b27bc7d3ebe853e Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Wed, 8 Nov 2023 19:34:47 +0530 Subject: [PATCH 17/26] feat(connector): [BANKOFAMERICA] Address PR comments tryfrom --- crates/router/src/connector/bankofamerica.rs | 41 ++--- .../connector/bankofamerica/transformers.rs | 140 +++++++++++++++--- 2 files changed, 137 insertions(+), 44 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index 3a32d5745cb2..b4e088c85399 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -346,16 +346,11 @@ impl ConnectorIntegration enums:: status } -impl - TryFrom<( - types::ResponseRouterData, - bool, - )> for types::RouterData +impl + TryFrom< + types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + types::PaymentsAuthorizeData, + types::PaymentsResponseData, + >, + > for types::RouterData { type Error = error_stack::Report; fn try_from( - data: ( - types::ResponseRouterData< - F, - BankofamericaPaymentsResponse, - T, - types::PaymentsResponseData, - >, - bool, - ), + item: types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + types::PaymentsAuthorizeData, + types::PaymentsResponseData, + >, ) -> Result { - let item = data.0; - let is_capture = data.1; Ok(Self { - status: get_payment_status(is_capture, item.response.status.into()), + status: get_payment_status( + item.data.request.is_auto_capture()?, + item.response.status.into(), + ), + response: match item.response.error_information { + Some(error) => Err(types::ErrorResponse { + code: consts::NO_ERROR_CODE.to_string(), + message: error.message, + reason: Some(error.reason), + status_code: item.http_code, + }), + _ => Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::ConnectorTransactionId( + item.response.id.clone(), + ), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: item + .response + .client_reference_information + .map(|cref| cref.code) + .unwrap_or(Some(item.response.id)), + }), + }, + ..item.data + }) + } +} + +impl + TryFrom< + types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + types::PaymentsCaptureData, + types::PaymentsResponseData, + >, + > for types::RouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + types::PaymentsCaptureData, + types::PaymentsResponseData, + >, + ) -> Result { + Ok(Self { + status: get_payment_status(true, item.response.status.into()), + response: match item.response.error_information { + Some(error) => Err(types::ErrorResponse { + code: consts::NO_ERROR_CODE.to_string(), + message: error.message, + reason: Some(error.reason), + status_code: item.http_code, + }), + _ => Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::ConnectorTransactionId( + item.response.id.clone(), + ), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: item + .response + .client_reference_information + .map(|cref| cref.code) + .unwrap_or(Some(item.response.id)), + }), + }, + ..item.data + }) + } +} + +impl + TryFrom< + types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + types::PaymentsCancelData, + types::PaymentsResponseData, + >, + > for types::RouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::ResponseRouterData< + F, + BankofamericaPaymentsResponse, + types::PaymentsCancelData, + types::PaymentsResponseData, + >, + ) -> Result { + Ok(Self { + status: item.response.status.into(), response: match item.response.error_information { Some(error) => Err(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), @@ -472,6 +572,7 @@ impl TryFrom<&types::PaymentsCancelRouterData> for BankofamericaVoidRequest { #[serde(rename_all = "camelCase")] pub struct BankofamericaRefundRequest { order_information: OrderInformation, + client_reference_information: ClientReferenceInformation, } impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> @@ -488,6 +589,9 @@ impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> currency: item.router_data.request.currency.to_string(), }, }, + client_reference_information: ClientReferenceInformation { + code: Some(item.router_data.request.refund_id.clone()), + }, }) } } From cd984237971a5a821fbb4d09ba7bc054a218a1a2 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Wed, 8 Nov 2023 20:02:44 +0530 Subject: [PATCH 18/26] feat(connector): Fix --- crates/router/src/connector/bankofamerica.rs | 12 +++++++++--- .../src/connector/bankofamerica/transformers.rs | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index cbd28e7b261b..0152f71d9e3d 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -117,7 +117,7 @@ where ) -> CustomResult)>, errors::ConnectorError> { let date = OffsetDateTime::now_utc(); - let boa_req = self.get_request_body(req)?; + let boa_req = self.get_request_body(req, connectors)?; let http_method = self.get_http_method(); let auth = bankofamerica::BankofamericaAuthType::try_from(&req.connector_auth_type)?; let merchant_account = auth.merchant_account.clone(); @@ -232,6 +232,7 @@ impl ConnectorCommon for Bankofamerica { code, message, reason: Some(connector_reason), + attempt_status: None, }) } } @@ -333,7 +334,9 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { let connector_request = bankofamerica::BankofamericaVoidRequest::try_from(req)?; let bankofamerica_void_request = types::RequestBody::log_and_get_request_body( @@ -585,7 +589,9 @@ impl ConnectorIntegration message: error.message, reason: Some(error.reason), status_code: item.http_code, + attempt_status: None, }), _ => Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( @@ -388,6 +389,7 @@ impl message: error.message, reason: Some(error.reason), status_code: item.http_code, + attempt_status: None, }), _ => Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( @@ -436,6 +438,7 @@ impl message: error.message, reason: Some(error.reason), status_code: item.http_code, + attempt_status: None, }), _ => Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( From 80548e6c975f3ebfe89dfa76696ffb47e58c60c2 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Wed, 8 Nov 2023 21:09:07 +0530 Subject: [PATCH 19/26] feat(connector): [BANKOFAMERICA] Resolve PR Comments Part 3 --- crates/router/src/connector/bankofamerica.rs | 20 ++---- .../connector/bankofamerica/transformers.rs | 72 +++++++++---------- 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index 0152f71d9e3d..2691544b1f70 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -395,9 +395,8 @@ impl ConnectorIntegration for enums::AttemptStatus { - fn from(item: BankofamericaPaymentStatus) -> Self { - match item { +impl ForeignFrom<(BankofamericaPaymentStatus, bool)> for enums::AttemptStatus { + fn foreign_from(item: (BankofamericaPaymentStatus, bool)) -> Self { + let status = match item.0 { BankofamericaPaymentStatus::Authorized | BankofamericaPaymentStatus::AuthorizedPendingReview => Self::Authorized, BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { @@ -284,7 +286,11 @@ impl From for enums::AttemptStatus { Self::Failure } BankofamericaPaymentStatus::Pending => Self::Pending, + }; + if item.1 && status == Self::Authorized { + return enums::AttemptStatus::Pending; } + status } } @@ -302,14 +308,6 @@ pub struct BankofamericaErrorInformation { message: String, } -fn get_payment_status(is_capture: bool, status: enums::AttemptStatus) -> enums::AttemptStatus { - let is_authorized = matches!(status, enums::AttemptStatus::Authorized); - if is_capture && is_authorized { - return enums::AttemptStatus::Pending; - } - status -} - impl TryFrom< types::ResponseRouterData< @@ -330,10 +328,10 @@ impl >, ) -> Result { Ok(Self { - status: get_payment_status( + status: enums::AttemptStatus::foreign_from(( + item.response.status, item.data.request.is_auto_capture()?, - item.response.status.into(), - ), + )), response: match item.response.error_information { Some(error) => Err(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), @@ -382,7 +380,7 @@ impl >, ) -> Result { Ok(Self { - status: get_payment_status(true, item.response.status.into()), + status: enums::AttemptStatus::foreign_from((item.response.status, true)), response: match item.response.error_information { Some(error) => Err(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), @@ -431,7 +429,7 @@ impl >, ) -> Result { Ok(Self { - status: item.response.status.into(), + status: enums::AttemptStatus::foreign_from((item.response.status, false)), response: match item.response.error_information { Some(error) => Err(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), @@ -474,36 +472,30 @@ pub struct ApplicationInformation { status: BankofamericaPaymentStatus, } -impl - TryFrom<( +impl + TryFrom< types::ResponseRouterData< F, BankofamericaTransactionResponse, - T, + types::PaymentsSyncData, types::PaymentsResponseData, >, - bool, - )> for types::RouterData + > for types::RouterData { type Error = error_stack::Report; fn try_from( - data: ( - types::ResponseRouterData< - F, - BankofamericaTransactionResponse, - T, - types::PaymentsResponseData, - >, - bool, - ), + item: types::ResponseRouterData< + F, + BankofamericaTransactionResponse, + types::PaymentsSyncData, + types::PaymentsResponseData, + >, ) -> Result { - let item = data.0; - let is_capture = data.1; Ok(Self { - status: get_payment_status( - is_capture, - item.response.application_information.status.into(), - ), + status: enums::AttemptStatus::foreign_from(( + item.response.application_information.status, + item.data.request.is_auto_capture()?, + )), response: Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()), redirection_data: None, @@ -588,7 +580,7 @@ impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> Ok(Self { order_information: OrderInformation { amount_details: Amount { - total_amount: item.router_data.request.refund_amount.to_string(), + total_amount: item.amount.clone(), currency: item.router_data.request.currency.to_string(), }, }, @@ -605,8 +597,8 @@ impl From for enums::RefundStatus { BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { Self::Success } - BankofamericaPaymentStatus::Failed - | BankofamericaPaymentStatus::Authorized + BankofamericaPaymentStatus::Failed => Self::Failure, + BankofamericaPaymentStatus::Authorized | BankofamericaPaymentStatus::Voided | BankofamericaPaymentStatus::Reversed | BankofamericaPaymentStatus::Pending From f5fd67c1c9120cc8e93ec8e8a56c472408be45a9 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 9 Nov 2023 18:30:43 +0530 Subject: [PATCH 20/26] feat(connector): [BANKOFAMERICA] Resolve PR Comments Part 4 --- crates/router/src/connector/bankofamerica.rs | 42 +++--- .../connector/bankofamerica/transformers.rs | 121 +++++++++--------- crates/router/src/core/admin.rs | 2 +- 3 files changed, 82 insertions(+), 83 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index 2691544b1f70..a77d865ae89b 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -56,14 +56,14 @@ impl Bankofamerica { pub fn generate_signature( &self, - auth: bankofamerica::BankofamericaAuthType, + auth: bankofamerica::BankOfAmericaAuthType, host: String, resource: &str, payload: &String, date: OffsetDateTime, http_method: services::Method, ) -> CustomResult { - let bankofamerica::BankofamericaAuthType { + let bankofamerica::BankOfAmericaAuthType { api_key, merchant_account, api_secret, @@ -119,7 +119,7 @@ where let date = OffsetDateTime::now_utc(); let boa_req = self.get_request_body(req, connectors)?; let http_method = self.get_http_method(); - let auth = bankofamerica::BankofamericaAuthType::try_from(&req.connector_auth_type)?; + let auth = bankofamerica::BankOfAmericaAuthType::try_from(&req.connector_auth_type)?; let merchant_account = auth.merchant_account.clone(); let base_url = connectors.bankofamerica.base_url.as_str(); let boa_host = Url::parse(base_url) @@ -194,7 +194,7 @@ impl ConnectorCommon for Bankofamerica { &self, res: Response, ) -> CustomResult { - let response: bankofamerica::BankofamericaErrorResponse = res + let response: bankofamerica::BankOfAmericaErrorResponse = res .response .parse_struct("BankOfAmerica ErrorResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -303,17 +303,17 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_router_data = bankofamerica::BankofamericaRouterData::try_from(( + let connector_router_data = bankofamerica::BankOfAmericaRouterData::try_from(( &self.get_currency_unit(), req.request.currency, req.request.amount, req, ))?; let connector_request = - bankofamerica::BankofamericaPaymentsRequest::try_from(&connector_router_data)?; + bankofamerica::BankOfAmericaPaymentsRequest::try_from(&connector_router_data)?; let bankofamerica_payments_request = types::RequestBody::log_and_get_request_body( &connector_request, - utils::Encode::::encode_to_string_of_json, + utils::Encode::::encode_to_string_of_json, ) .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Some(bankofamerica_payments_request)) @@ -346,7 +346,7 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::BankofamericaPaymentsResponse = res + let response: bankofamerica::BankOfAmericaPaymentsResponse = res .response .parse_struct("BankOfAmerica PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -420,7 +420,7 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::BankofamericaTransactionResponse = res + let response: bankofamerica::BankOfAmericaTransactionResponse = res .response .parse_struct("BankOfAmerica PaymentSyncResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -471,17 +471,17 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_router_data = bankofamerica::BankofamericaRouterData::try_from(( + let connector_router_data = bankofamerica::BankOfAmericaRouterData::try_from(( &self.get_currency_unit(), req.request.currency, req.request.amount_to_capture, req, ))?; let connector_request = - bankofamerica::BankofamericaCaptureRequest::try_from(&connector_router_data)?; + bankofamerica::BankOfAmericaCaptureRequest::try_from(&connector_router_data)?; let bankofamerica_capture_request = types::RequestBody::log_and_get_request_body( &connector_request, - utils::Encode::::encode_to_string_of_json, + utils::Encode::::encode_to_string_of_json, ) .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Some(bankofamerica_capture_request)) @@ -512,7 +512,7 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::BankofamericaPaymentsResponse = res + let response: bankofamerica::BankOfAmericaPaymentsResponse = res .response .parse_struct("BankOfAmerica PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -563,10 +563,10 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_request = bankofamerica::BankofamericaVoidRequest::try_from(req)?; + let connector_request = bankofamerica::BankOfAmericaVoidRequest::try_from(req)?; let bankofamerica_void_request = types::RequestBody::log_and_get_request_body( &connector_request, - utils::Encode::::encode_to_string_of_json, + utils::Encode::::encode_to_string_of_json, ) .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Some(bankofamerica_void_request)) @@ -595,7 +595,7 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::BankofamericaPaymentsResponse = res + let response: bankofamerica::BankOfAmericaPaymentsResponse = res .response .parse_struct("BankOfAmerica PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -646,16 +646,16 @@ impl ConnectorIntegration, _connectors: &settings::Connectors, ) -> CustomResult, errors::ConnectorError> { - let connector_router_data = bankofamerica::BankofamericaRouterData::try_from(( + let connector_router_data = bankofamerica::BankOfAmericaRouterData::try_from(( &self.get_currency_unit(), req.request.currency, req.request.refund_amount, req, ))?; - let req_obj = bankofamerica::BankofamericaRefundRequest::try_from(&connector_router_data)?; + let req_obj = bankofamerica::BankOfAmericaRefundRequest::try_from(&connector_router_data)?; let bankofamerica_req = types::RequestBody::log_and_get_request_body( &req_obj, - utils::Encode::::encode_to_string_of_json, + utils::Encode::::encode_to_string_of_json, ) .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Some(bankofamerica_req)) @@ -685,7 +685,7 @@ impl ConnectorIntegration, res: Response, ) -> CustomResult, errors::ConnectorError> { - let response: bankofamerica::BankofamericaPaymentsResponse = res + let response: bankofamerica::BankOfAmericaPaymentsResponse = res .response .parse_struct("bankofamerica RefundResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -758,7 +758,7 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::BankofamericaTransactionResponse = res + let response: bankofamerica::BankOfAmericaTransactionResponse = res .response .parse_struct("bankofamerica RefundSyncResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 43919d6cd4f1..c91777a1ee8e 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -18,13 +18,13 @@ use crate::{ }, }; -pub struct BankofamericaAuthType { +pub struct BankOfAmericaAuthType { pub(super) api_key: Secret, pub(super) merchant_account: Secret, pub(super) api_secret: Secret, } -impl TryFrom<&types::ConnectorAuthType> for BankofamericaAuthType { +impl TryFrom<&types::ConnectorAuthType> for BankOfAmericaAuthType { type Error = error_stack::Report; fn try_from(auth_type: &types::ConnectorAuthType) -> Result { if let types::ConnectorAuthType::SignatureKey { @@ -44,7 +44,7 @@ impl TryFrom<&types::ConnectorAuthType> for BankofamericaAuthType { } } -pub struct BankofamericaRouterData { +pub struct BankOfAmericaRouterData { pub amount: String, pub router_data: T, } @@ -55,7 +55,7 @@ impl types::storage::enums::Currency, i64, T, - )> for BankofamericaRouterData + )> for BankOfAmericaRouterData { type Error = error_stack::Report; fn try_from( @@ -76,7 +76,7 @@ impl #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] -pub struct BankofamericaPaymentsRequest { +pub struct BankOfAmericaPaymentsRequest { processing_information: ProcessingInformation, payment_information: PaymentInformation, order_information: OrderInformationWithBill, @@ -87,7 +87,6 @@ pub struct BankofamericaPaymentsRequest { #[serde(rename_all = "camelCase")] pub struct ProcessingInformation { capture: bool, - capture_options: Option, } #[derive(Debug, Serialize)] @@ -124,7 +123,7 @@ pub struct OrderInformationWithBill { #[serde(rename_all = "camelCase")] pub struct Amount { total_amount: String, - currency: String, + currency: api_models::enums::Currency, } #[derive(Debug, Serialize)] @@ -161,17 +160,20 @@ fn build_bill_to( }) } -fn get_card_type(card_issuer: CardIssuer) -> &'static str { - match card_issuer { - CardIssuer::AmericanExpress => "003", - CardIssuer::Master => "002", - //"042" is the type code for Masetro Cards(International). For Maestro Cards(UK-Domestic) the mapping should be "024" - CardIssuer::Maestro => "042", - CardIssuer::Visa => "001", - CardIssuer::Discover => "004", - CardIssuer::DinersClub => "005", - CardIssuer::CarteBlanche => "006", - CardIssuer::JCB => "007", +impl From for String { + fn from(card_issuer: CardIssuer) -> Self { + let card_type = match card_issuer { + CardIssuer::AmericanExpress => "003", + CardIssuer::Master => "002", + //"042" is the type code for Masetro Cards(International). For Maestro Cards(UK-Domestic) the mapping should be "024" + CardIssuer::Maestro => "042", + CardIssuer::Visa => "001", + CardIssuer::Discover => "004", + CardIssuer::DinersClub => "005", + CardIssuer::CarteBlanche => "006", + CardIssuer::JCB => "007", + }; + return card_type.to_string(); } } @@ -181,33 +183,28 @@ pub struct ClientReferenceInformation { code: Option, } -impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> - for BankofamericaPaymentsRequest +impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>> + for BankOfAmericaPaymentsRequest { type Error = error_stack::Report; fn try_from( - item: &BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>, + item: &BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, ) -> Result { match item.router_data.request.payment_method_data.clone() { api::PaymentMethodData::Card(ccard) => { - let email = item - .router_data - .request - .email - .clone() - .ok_or_else(utils::missing_field_err("email"))?; + let email = item.router_data.request.get_email()?; let bill_to = build_bill_to(item.router_data.get_billing()?, email)?; let order_information = OrderInformationWithBill { amount_details: Amount { total_amount: item.amount.to_owned(), - currency: item.router_data.request.currency.to_string().to_uppercase(), + currency: item.router_data.request.currency, }, bill_to, }; let card_issuer = ccard.get_card_issuer(); let card_type = match card_issuer { - Ok(issuer) => Some(get_card_type(issuer).to_string()), + Ok(issuer) => Some(String::from(issuer)), Err(_) => None, }; let payment_information = PaymentInformation { @@ -225,7 +222,6 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> item.router_data.request.capture_method, Some(enums::CaptureMethod::Automatic) | None ), - capture_options: None, }; let client_reference_information = ClientReferenceInformation { @@ -251,7 +247,10 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsAuthorizeRouterData>> | payments::PaymentMethodData::Upi(_) | payments::PaymentMethodData::Voucher(_) | payments::PaymentMethodData::GiftCard(_) => { - Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()) + Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("Bank of America"), + ) + .into()) } } } @@ -288,22 +287,22 @@ impl ForeignFrom<(BankofamericaPaymentStatus, bool)> for enums::AttemptStatus { BankofamericaPaymentStatus::Pending => Self::Pending, }; if item.1 && status == Self::Authorized { - return enums::AttemptStatus::Pending; + return Self::Pending; } status } } #[derive(Debug, Deserialize)] -pub struct BankofamericaPaymentsResponse { +pub struct BankOfAmericaPaymentsResponse { id: String, status: BankofamericaPaymentStatus, - error_information: Option, + error_information: Option, client_reference_information: Option, } #[derive(Debug, Deserialize)] -pub struct BankofamericaErrorInformation { +pub struct BankOfAmericaErrorInformation { reason: String, message: String, } @@ -312,7 +311,7 @@ impl TryFrom< types::ResponseRouterData< F, - BankofamericaPaymentsResponse, + BankOfAmericaPaymentsResponse, types::PaymentsAuthorizeData, types::PaymentsResponseData, >, @@ -322,7 +321,7 @@ impl fn try_from( item: types::ResponseRouterData< F, - BankofamericaPaymentsResponse, + BankOfAmericaPaymentsResponse, types::PaymentsAuthorizeData, types::PaymentsResponseData, >, @@ -364,7 +363,7 @@ impl TryFrom< types::ResponseRouterData< F, - BankofamericaPaymentsResponse, + BankOfAmericaPaymentsResponse, types::PaymentsCaptureData, types::PaymentsResponseData, >, @@ -374,7 +373,7 @@ impl fn try_from( item: types::ResponseRouterData< F, - BankofamericaPaymentsResponse, + BankOfAmericaPaymentsResponse, types::PaymentsCaptureData, types::PaymentsResponseData, >, @@ -413,7 +412,7 @@ impl TryFrom< types::ResponseRouterData< F, - BankofamericaPaymentsResponse, + BankOfAmericaPaymentsResponse, types::PaymentsCancelData, types::PaymentsResponseData, >, @@ -423,7 +422,7 @@ impl fn try_from( item: types::ResponseRouterData< F, - BankofamericaPaymentsResponse, + BankOfAmericaPaymentsResponse, types::PaymentsCancelData, types::PaymentsResponseData, >, @@ -460,7 +459,7 @@ impl #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct BankofamericaTransactionResponse { +pub struct BankOfAmericaTransactionResponse { id: String, application_information: ApplicationInformation, client_reference_information: Option, @@ -476,7 +475,7 @@ impl TryFrom< types::ResponseRouterData< F, - BankofamericaTransactionResponse, + BankOfAmericaTransactionResponse, types::PaymentsSyncData, types::PaymentsResponseData, >, @@ -486,7 +485,7 @@ impl fn try_from( item: types::ResponseRouterData< F, - BankofamericaTransactionResponse, + BankOfAmericaTransactionResponse, types::PaymentsSyncData, types::PaymentsResponseData, >, @@ -521,23 +520,23 @@ pub struct OrderInformation { #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] -pub struct BankofamericaCaptureRequest { +pub struct BankOfAmericaCaptureRequest { order_information: OrderInformation, client_reference_information: ClientReferenceInformation, } -impl TryFrom<&BankofamericaRouterData<&types::PaymentsCaptureRouterData>> - for BankofamericaCaptureRequest +impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsCaptureRouterData>> + for BankOfAmericaCaptureRequest { type Error = error_stack::Report; fn try_from( - value: &BankofamericaRouterData<&types::PaymentsCaptureRouterData>, + value: &BankOfAmericaRouterData<&types::PaymentsCaptureRouterData>, ) -> Result { Ok(Self { order_information: OrderInformation { amount_details: Amount { total_amount: value.amount.to_owned(), - currency: value.router_data.request.currency.to_string(), + currency: value.router_data.request.currency, }, }, client_reference_information: ClientReferenceInformation { @@ -548,11 +547,11 @@ impl TryFrom<&BankofamericaRouterData<&types::PaymentsCaptureRouterData>> } #[derive(Debug, Serialize)] -pub struct BankofamericaVoidRequest { +pub struct BankOfAmericaVoidRequest { client_reference_information: ClientReferenceInformation, } -impl TryFrom<&types::PaymentsCancelRouterData> for BankofamericaVoidRequest { +impl TryFrom<&types::PaymentsCancelRouterData> for BankOfAmericaVoidRequest { type Error = error_stack::Report; fn try_from(value: &types::PaymentsCancelRouterData) -> Result { Ok(Self { @@ -565,23 +564,23 @@ impl TryFrom<&types::PaymentsCancelRouterData> for BankofamericaVoidRequest { #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] -pub struct BankofamericaRefundRequest { +pub struct BankOfAmericaRefundRequest { order_information: OrderInformation, client_reference_information: ClientReferenceInformation, } -impl TryFrom<&BankofamericaRouterData<&types::RefundsRouterData>> - for BankofamericaRefundRequest +impl TryFrom<&BankOfAmericaRouterData<&types::RefundsRouterData>> + for BankOfAmericaRefundRequest { type Error = error_stack::Report; fn try_from( - item: &BankofamericaRouterData<&types::RefundsRouterData>, + item: &BankOfAmericaRouterData<&types::RefundsRouterData>, ) -> Result { Ok(Self { order_information: OrderInformation { amount_details: Amount { total_amount: item.amount.clone(), - currency: item.router_data.request.currency.to_string(), + currency: item.router_data.request.currency, }, }, client_reference_information: ClientReferenceInformation { @@ -608,12 +607,12 @@ impl From for enums::RefundStatus { } } -impl TryFrom> +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { Ok(Self { response: Ok(types::RefundsResponseData { @@ -625,12 +624,12 @@ impl TryFrom> +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { Ok(Self { response: Ok(types::RefundsResponseData { @@ -646,7 +645,7 @@ impl TryFrom, pub status: Option, pub message: Option, diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 3f932f8a15cd..0baa8334b20e 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1500,7 +1500,7 @@ pub(crate) fn validate_auth_and_metadata_type( Ok(()) } api_enums::Connector::Bankofamerica => { - bankofamerica::transformers::BankofamericaAuthType::try_from(val)?; + bankofamerica::transformers::BankOfAmericaAuthType::try_from(val)?; Ok(()) } api_enums::Connector::Bitpay => { From 7c05fa5108cb37a66866fa5b9487463b660429ab Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Fri, 10 Nov 2023 16:19:35 +0530 Subject: [PATCH 21/26] feat(connector): [BANKOFAMERICA] Add Postman Collection --- .../collection-dir/bankofamerica/.auth.json | 22 + .../bankofamerica/.event.meta.json | 6 + .../collection-dir/bankofamerica/.info.json | 9 + .../collection-dir/bankofamerica/.meta.json | 9 + .../bankofamerica/.variable.json | 100 + .../bankofamerica/API Key/.meta.json | 9 + .../API Key/Create API Key/.event.meta.json | 5 + .../API Key/Create API Key/event.test.js | 46 + .../API Key/Create API Key/request.json | 52 + .../API Key/Create API Key/response.json | 1 + .../API Key/Delete API Key/.event.meta.json | 5 + .../API Key/Delete API Key/event.test.js | 17 + .../API Key/Delete API Key/request.json | 49 + .../API Key/Delete API Key/response.json | 1 + .../API Key/List API Keys/.event.meta.json | 5 + .../API Key/List API Keys/event.test.js | 46 + .../API Key/List API Keys/request.json | 45 + .../API Key/List API Keys/response.json | 1 + .../API Key/Retrieve API Key/.event.meta.json | 5 + .../API Key/Retrieve API Key/event.test.js | 49 + .../API Key/Retrieve API Key/request.json | 49 + .../API Key/Retrieve API Key/response.json | 1 + .../API Key/Update API Key/.event.meta.json | 5 + .../API Key/Update API Key/event.test.js | 49 + .../API Key/Update API Key/request.json | 57 + .../API Key/Update API Key/response.json | 1 + .../bankofamerica/Flow Testcases/.meta.json | 6 + .../Flow Testcases/Happy Cases/.meta.json | 9 + .../.meta.json | 6 + .../Payments - Create/.event.meta.json | 5 + .../Payments - Create/event.test.js | 80 + .../Payments - Create/request.json | 98 + .../Payments - Create/response.json | 1 + .../Payments - Retrieve/.event.meta.json | 5 + .../Payments - Retrieve/event.test.js | 80 + .../Payments - Retrieve/request.json | 33 + .../Payments - Retrieve/response.json | 1 + .../.meta.json | 7 + .../Payments - Confirm/.event.meta.json | 6 + .../Payments - Confirm/event.prerequest.js | 0 .../Payments - Confirm/event.test.js | 103 + .../Payments - Confirm/request.json | 63 + .../Payments - Confirm/response.json | 1 + .../Payments - Create/.event.meta.json | 5 + .../Payments - Create/event.test.js | 71 + .../Payments - Create/request.json | 98 + .../Payments - Create/response.json | 1 + .../Payments - Retrieve/.event.meta.json | 5 + .../Payments - Retrieve/event.test.js | 91 + .../Payments - Retrieve/request.json | 33 + .../Payments - Retrieve/response.json | 1 + .../.meta.json | 7 + .../Payments - Confirm/.event.meta.json | 6 + .../Payments - Confirm/event.prerequest.js | 0 .../Payments - Confirm/event.test.js | 73 + .../Payments - Confirm/request.json | 73 + .../Payments - Confirm/response.json | 1 + .../Payments - Create/.event.meta.json | 5 + .../Payments - Create/event.test.js | 71 + .../Payments - Create/request.json | 84 + .../Payments - Create/response.json | 1 + .../Payments - Retrieve/.event.meta.json | 5 + .../Payments - Retrieve/event.test.js | 71 + .../Payments - Retrieve/request.json | 33 + .../Payments - Retrieve/response.json | 1 + .../.meta.json | 7 + .../Payments - Capture/.event.meta.json | 5 + .../Payments - Capture/event.test.js | 94 + .../Payments - Capture/request.json | 45 + .../Payments - Capture/response.json | 1 + .../Payments - Create/.event.meta.json | 5 + .../Payments - Create/event.test.js | 71 + .../Payments - Create/request.json | 98 + .../Payments - Create/response.json | 1 + .../Payments - Retrieve/.event.meta.json | 5 + .../Payments - Retrieve/event.test.js | 71 + .../Payments - Retrieve/request.json | 33 + .../Payments - Retrieve/response.json | 1 + .../Scenario5-Void the payment/.meta.json | 7 + .../Payments - Cancel/.event.meta.json | 5 + .../Payments - Cancel/event.test.js | 61 + .../Payments - Cancel/request.json | 43 + .../Payments - Cancel/response.json | 1 + .../Payments - Create/.event.meta.json | 5 + .../Payments - Create/event.test.js | 71 + .../Payments - Create/request.json | 98 + .../Payments - Create/response.json | 1 + .../Payments - Retrieve/.event.meta.json | 5 + .../Payments - Retrieve/event.test.js | 71 + .../Payments - Retrieve/request.json | 33 + .../Payments - Retrieve/response.json | 1 + .../Flow Testcases/QuickStart/.meta.json | 9 + .../API Key - Create/.event.meta.json | 5 + .../QuickStart/API Key - Create/event.test.js | 46 + .../QuickStart/API Key - Create/request.json | 52 + .../QuickStart/API Key - Create/response.json | 1 + .../.event.meta.json | 5 + .../Merchant Account - Create/event.test.js | 56 + .../Merchant Account - Create/request.json | 95 + .../Merchant Account - Create/response.json | 1 + .../.event.meta.json | 5 + .../Payment Connector - Create/event.test.js | 39 + .../Payment Connector - Create/request.json | 108 + .../Payment Connector - Create/response.json | 1 + .../Payments - Create/.event.meta.json | 5 + .../Payments - Create/event.test.js | 61 + .../QuickStart/Payments - Create/request.json | 103 + .../Payments - Create/response.json | 1 + .../Payments - Retrieve/.event.meta.json | 5 + .../Payments - Retrieve/event.test.js | 61 + .../Payments - Retrieve/request.json | 27 + .../Payments - Retrieve/response.json | 1 + .../bankofamerica/Health check/.meta.json | 5 + .../Health check/New Request/.event.meta.json | 5 + .../Health check/New Request/event.test.js | 4 + .../Health check/New Request/request.json | 20 + .../Health check/New Request/response.json | 1 + .../bankofamerica/MerchantAccounts/.meta.json | 8 + .../.event.meta.json | 6 + .../event.prerequest.js | 0 .../Merchant Account - Create/event.test.js | 77 + .../Merchant Account - Create/request.json | 95 + .../Merchant Account - Create/response.json | 1 + .../Merchant Account - List/.event.meta.json | 5 + .../Merchant Account - List/event.test.js | 43 + .../Merchant Account - List/request.json | 53 + .../Merchant Account - List/response.json | 1 + .../.event.meta.json | 5 + .../Merchant Account - Retrieve/event.test.js | 43 + .../Merchant Account - Retrieve/request.json | 47 + .../Merchant Account - Retrieve/response.json | 1 + .../.event.meta.json | 5 + .../Merchant Account - Update/event.test.js | 46 + .../Merchant Account - Update/request.json | 98 + .../Merchant Account - Update/response.json | 1 + .../PaymentConnectors/.meta.json | 10 + .../List Connectors by MID/.event.meta.json | 5 + .../List Connectors by MID/event.test.js | 17 + .../List Connectors by MID/request.json | 41 + .../List Connectors by MID/response.json | 1 + .../.event.meta.json | 5 + .../Merchant Account - Delete/event.test.js | 42 + .../Merchant Account - Delete/request.json | 47 + .../Merchant Account - Delete/response.json | 1 + .../.event.meta.json | 5 + .../Payment Connector - Create/event.test.js | 47 + .../Payment Connector - Create/request.json | 108 + .../Payment Connector - Create/response.json | 1 + .../.event.meta.json | 5 + .../Payment Connector - Delete/event.test.js | 39 + .../Payment Connector - Delete/request.json | 52 + .../Payment Connector - Delete/response.json | 1 + .../.event.meta.json | 5 + .../event.test.js | 39 + .../Payment Connector - Retrieve/request.json | 54 + .../response.json | 1 + .../.event.meta.json | 5 + .../Payment Connector - Update/event.test.js | 47 + .../Payment Connector - Update/request.json | 109 + .../Payment Connector - Update/response.json | 1 + .../bankofamerica/event.prerequest.js | 0 .../bankofamerica/event.test.js | 13 + .../bankofamerica.postman_collection.json | 4310 +++++++++++++++++ 163 files changed, 8991 insertions(+) create mode 100644 postman/collection-dir/bankofamerica/.auth.json create mode 100644 postman/collection-dir/bankofamerica/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/.info.json create mode 100644 postman/collection-dir/bankofamerica/.meta.json create mode 100644 postman/collection-dir/bankofamerica/.variable.json create mode 100644 postman/collection-dir/bankofamerica/API Key/.meta.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Create API Key/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Create API Key/event.test.js create mode 100644 postman/collection-dir/bankofamerica/API Key/Create API Key/request.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Create API Key/response.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Delete API Key/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Delete API Key/event.test.js create mode 100644 postman/collection-dir/bankofamerica/API Key/Delete API Key/request.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Delete API Key/response.json create mode 100644 postman/collection-dir/bankofamerica/API Key/List API Keys/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/API Key/List API Keys/event.test.js create mode 100644 postman/collection-dir/bankofamerica/API Key/List API Keys/request.json create mode 100644 postman/collection-dir/bankofamerica/API Key/List API Keys/response.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Retrieve API Key/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Retrieve API Key/event.test.js create mode 100644 postman/collection-dir/bankofamerica/API Key/Retrieve API Key/request.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Retrieve API Key/response.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Update API Key/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Update API Key/event.test.js create mode 100644 postman/collection-dir/bankofamerica/API Key/Update API Key/request.json create mode 100644 postman/collection-dir/bankofamerica/API Key/Update API Key/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/event.prerequest.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/event.prerequest.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/Health check/.meta.json create mode 100644 postman/collection-dir/bankofamerica/Health check/New Request/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/Health check/New Request/event.test.js create mode 100644 postman/collection-dir/bankofamerica/Health check/New Request/request.json create mode 100644 postman/collection-dir/bankofamerica/Health check/New Request/response.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/.meta.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/event.prerequest.js create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/event.test.js create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/request.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/response.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/event.test.js create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/request.json create mode 100644 postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/response.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/.meta.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/event.test.js create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/request.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/response.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/event.test.js create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/request.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/response.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/event.test.js create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/request.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/response.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/event.test.js create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/request.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/response.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/event.test.js create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/request.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/response.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/.event.meta.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/event.test.js create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/request.json create mode 100644 postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/response.json create mode 100644 postman/collection-dir/bankofamerica/event.prerequest.js create mode 100644 postman/collection-dir/bankofamerica/event.test.js create mode 100644 postman/collection-json/bankofamerica.postman_collection.json diff --git a/postman/collection-dir/bankofamerica/.auth.json b/postman/collection-dir/bankofamerica/.auth.json new file mode 100644 index 000000000000..915a28357900 --- /dev/null +++ b/postman/collection-dir/bankofamerica/.auth.json @@ -0,0 +1,22 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/.event.meta.json b/postman/collection-dir/bankofamerica/.event.meta.json new file mode 100644 index 000000000000..2df9d47d936d --- /dev/null +++ b/postman/collection-dir/bankofamerica/.event.meta.json @@ -0,0 +1,6 @@ +{ + "eventOrder": [ + "event.prerequest.js", + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/.info.json b/postman/collection-dir/bankofamerica/.info.json new file mode 100644 index 000000000000..2a1b8f809c01 --- /dev/null +++ b/postman/collection-dir/bankofamerica/.info.json @@ -0,0 +1,9 @@ +{ + "info": { + "_postman_id": "646f7167-da26-4a24-adb0-4157fd3a1781", + "name": "bankofamerica", + "description": "## Get started\n\nJuspay Router provides a collection of APIs that enable you to process and manage payments. Our APIs accept and return JSON in the HTTP body, and return standard HTTP response codes. \nYou can consume the APIs directly using your favorite HTTP/REST library. \nWe have a testing environment referred to \"sandbox\", which you can setup to test API calls without affecting production data.\n\n### Base URLs\n\nUse the following base URLs when making requests to the APIs:\n\n| Environment | Base URL |\n| --- | --- |\n| Sandbox | [https://sandbox.hyperswitch.io](https://sandbox.hyperswitch.io) |\n| Production | [https://router.juspay.io](https://router.juspay.io) |\n\n# Authentication\n\nWhen you sign up for an account, you are given a secret key (also referred as api-key). You may authenticate all API requests with Juspay server by providing the appropriate key in the request Authorization header. \nNever share your secret api keys. Keep them guarded and secure.\n\nContact Support: \nName: Juspay Support \nEmail: [support@juspay.in](mailto:support@juspay.in)", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "28305597" + } +} diff --git a/postman/collection-dir/bankofamerica/.meta.json b/postman/collection-dir/bankofamerica/.meta.json new file mode 100644 index 000000000000..e578098f721e --- /dev/null +++ b/postman/collection-dir/bankofamerica/.meta.json @@ -0,0 +1,9 @@ +{ + "childrenOrder": [ + "Health check", + "MerchantAccounts", + "API Key", + "PaymentConnectors", + "Flow Testcases" + ] +} diff --git a/postman/collection-dir/bankofamerica/.variable.json b/postman/collection-dir/bankofamerica/.variable.json new file mode 100644 index 000000000000..492c3b7ed0cb --- /dev/null +++ b/postman/collection-dir/bankofamerica/.variable.json @@ -0,0 +1,100 @@ +{ + "variable": [ + { + "key": "baseUrl", + "value": "", + "type": "string" + }, + { + "key": "admin_api_key", + "value": "", + "type": "string" + }, + { + "key": "api_key", + "value": "", + "type": "string" + }, + { + "key": "merchant_id", + "value": "" + }, + { + "key": "payment_id", + "value": "" + }, + { + "key": "customer_id", + "value": "" + }, + { + "key": "mandate_id", + "value": "" + }, + { + "key": "payment_method_id", + "value": "" + }, + { + "key": "refund_id", + "value": "" + }, + { + "key": "merchant_connector_id", + "value": "" + }, + { + "key": "client_secret", + "value": "", + "type": "string" + }, + { + "key": "connector_api_key", + "value": "", + "type": "string" + }, + { + "key": "publishable_key", + "value": "", + "type": "string" + }, + { + "key": "api_key_id", + "value": "", + "type": "string" + }, + { + "key": "payment_token", + "value": "" + }, + { + "key": "gateway_merchant_id", + "value": "", + "type": "string" + }, + { + "key": "certificate", + "value": "", + "type": "string" + }, + { + "key": "certificate_keys", + "value": "", + "type": "string" + }, + { + "key": "organization_id", + "value": "" + }, + { + "key": "connector_api_secret", + "value": "", + "type": "string" + }, + { + "key": "connector_key1", + "value": "", + "type": "string" + } + ] +} diff --git a/postman/collection-dir/bankofamerica/API Key/.meta.json b/postman/collection-dir/bankofamerica/API Key/.meta.json new file mode 100644 index 000000000000..0388c2d61b4b --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/.meta.json @@ -0,0 +1,9 @@ +{ + "childrenOrder": [ + "Create API Key", + "Update API Key", + "Retrieve API Key", + "List API Keys", + "Delete API Key" + ] +} diff --git a/postman/collection-dir/bankofamerica/API Key/Create API Key/.event.meta.json b/postman/collection-dir/bankofamerica/API Key/Create API Key/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Create API Key/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/API Key/Create API Key/event.test.js b/postman/collection-dir/bankofamerica/API Key/Create API Key/event.test.js new file mode 100644 index 000000000000..4e27c5a50253 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Create API Key/event.test.js @@ -0,0 +1,46 @@ +// Validate status 2xx +pm.test("[POST]::/api_keys/:merchant_id - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/api_keys/:merchant_id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id +if (jsonData?.key_id) { + pm.collectionVariables.set("api_key_id", jsonData.key_id); + console.log( + "- use {{api_key_id}} as collection variable for value", + jsonData.key_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.", + ); +} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/API Key/Create API Key/request.json b/postman/collection-dir/bankofamerica/API Key/Create API Key/request.json new file mode 100644 index 000000000000..4e4c66284978 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Create API Key/request.json @@ -0,0 +1,52 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw_json_formatted": { + "name": "API Key 1", + "description": null, + "expiration": "2069-09-23T01:02:03.000Z" + } + }, + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/API Key/Create API Key/response.json b/postman/collection-dir/bankofamerica/API Key/Create API Key/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Create API Key/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/API Key/Delete API Key/.event.meta.json b/postman/collection-dir/bankofamerica/API Key/Delete API Key/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Delete API Key/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/API Key/Delete API Key/event.test.js b/postman/collection-dir/bankofamerica/API Key/Delete API Key/event.test.js new file mode 100644 index 000000000000..bed2232f1a37 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Delete API Key/event.test.js @@ -0,0 +1,17 @@ +// Validate status 2xx +pm.test( + "[DELETE]::/api_keys/:merchant_id/:api-key - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[DELETE]::/api_keys/:merchant_id/:api-key - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); diff --git a/postman/collection-dir/bankofamerica/API Key/Delete API Key/request.json b/postman/collection-dir/bankofamerica/API Key/Delete API Key/request.json new file mode 100644 index 000000000000..a83d12a2bebc --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Delete API Key/request.json @@ -0,0 +1,49 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/:api-key", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + ":api-key" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + }, + { + "key": "api-key", + "value": "{{api_key_id}}" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/API Key/Delete API Key/response.json b/postman/collection-dir/bankofamerica/API Key/Delete API Key/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Delete API Key/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/API Key/List API Keys/.event.meta.json b/postman/collection-dir/bankofamerica/API Key/List API Keys/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/List API Keys/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/API Key/List API Keys/event.test.js b/postman/collection-dir/bankofamerica/API Key/List API Keys/event.test.js new file mode 100644 index 000000000000..c6cbb8742e2c --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/List API Keys/event.test.js @@ -0,0 +1,46 @@ +// Validate status 2xx +pm.test("[GET]::/api_keys/:merchant_id/list - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[GET]::/api_keys/:merchant_id/list - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id +if (jsonData?.key_id) { + pm.collectionVariables.set("api_key_id", jsonData.key_id); + console.log( + "- use {{api_key_id}} as collection variable for value", + jsonData.key_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.", + ); +} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/API Key/List API Keys/request.json b/postman/collection-dir/bankofamerica/API Key/List API Keys/request.json new file mode 100644 index 000000000000..86d12e8c7418 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/List API Keys/request.json @@ -0,0 +1,45 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/list", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + "list" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/API Key/List API Keys/response.json b/postman/collection-dir/bankofamerica/API Key/List API Keys/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/List API Keys/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/.event.meta.json b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/event.test.js b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/event.test.js new file mode 100644 index 000000000000..bef13cc35779 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/event.test.js @@ -0,0 +1,49 @@ +// Validate status 2xx +pm.test( + "[GET]::/api_keys/:merchant_id/:api_key_id - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[GET]::/api_keys/:merchant_id/:api_key_id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id +if (jsonData?.key_id) { + pm.collectionVariables.set("api_key_id", jsonData.key_id); + console.log( + "- use {{api_key_id}} as collection variable for value", + jsonData.key_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.", + ); +} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/request.json b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/request.json new file mode 100644 index 000000000000..958049e90879 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/request.json @@ -0,0 +1,49 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/:api_key_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + ":api_key_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + }, + { + "key": "api_key_id", + "value": "{{api_key_id}}" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/response.json b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Retrieve API Key/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/API Key/Update API Key/.event.meta.json b/postman/collection-dir/bankofamerica/API Key/Update API Key/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Update API Key/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/API Key/Update API Key/event.test.js b/postman/collection-dir/bankofamerica/API Key/Update API Key/event.test.js new file mode 100644 index 000000000000..fd6ed957bdff --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Update API Key/event.test.js @@ -0,0 +1,49 @@ +// Validate status 2xx +pm.test( + "[POST]::/api_keys/:merchant_id/:api_key_id - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/api_keys/:merchant_id/:api_key_id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id +if (jsonData?.key_id) { + pm.collectionVariables.set("api_key_id", jsonData.key_id); + console.log( + "- use {{api_key_id}} as collection variable for value", + jsonData.key_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.", + ); +} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/API Key/Update API Key/request.json b/postman/collection-dir/bankofamerica/API Key/Update API Key/request.json new file mode 100644 index 000000000000..af2f450969b6 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Update API Key/request.json @@ -0,0 +1,57 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw_json_formatted": { + "name": null, + "description": "My very awesome API key", + "expiration": null + } + }, + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/:api_key_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + ":api_key_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + }, + { + "key": "api_key_id", + "value": "{{api_key_id}}" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/API Key/Update API Key/response.json b/postman/collection-dir/bankofamerica/API Key/Update API Key/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/API Key/Update API Key/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/.meta.json new file mode 100644 index 000000000000..bd972090b19e --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/.meta.json @@ -0,0 +1,6 @@ +{ + "childrenOrder": [ + "QuickStart", + "Happy Cases" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/.meta.json new file mode 100644 index 000000000000..d85baac8fbe6 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/.meta.json @@ -0,0 +1,9 @@ +{ + "childrenOrder": [ + "Scenario1-Create payment with confirm true", + "Scenario2-Create payment with confirm false", + "Scenario3-Create payment without PMD", + "Scenario4-Create payment with Manual capture", + "Scenario5-Void the payment" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/.meta.json new file mode 100644 index 000000000000..60051ecca220 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/.meta.json @@ -0,0 +1,6 @@ +{ + "childrenOrder": [ + "Payments - Create", + "Payments - Retrieve" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/event.test.js new file mode 100644 index 000000000000..ac3f862e43f4 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/event.test.js @@ -0,0 +1,80 @@ +// Validate status 2xx +pm.test("[POST]::/payments - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/payments - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[POST]::/payments - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "processing" for "status" because payment gets succeeded after one day. +if (jsonData?.status) { + pm.test( + "[POST]::/payments - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} + +// Response body should have "connector_transaction_id" +pm.test( + "[POST]::/payments - Content check if 'connector_transaction_id' exists", + function () { + pm.expect(typeof jsonData.connector_transaction_id !== "undefined").to.be + .true; + }, +); diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json new file mode 100644 index 000000000000..21f054843897 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json @@ -0,0 +1,98 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "amount": 6540, + "currency": "USD", + "confirm": true, + "business_country": "US", + "business_label": "default", + "capture_method": "automatic", + "capture_on": "2022-09-10T10:11:12Z", + "amount_to_capture": 1, + "customer_id": "bernard123", + "email": "guest@example.com", + "name": "John Doe", + "phone": "999999999", + "phone_country_code": "+65", + "description": "Its my first payment request", + "authentication_type": "no_three_ds", + "return_url": "https://duck.com", + "setup_future_usage": "on_session", + "payment_method": "card", + "payment_method_type": "debit", + "payment_method_data": { + "card": { + "card_number": "4242424242424242", + "card_exp_month": "01", + "card_exp_year": "24", + "card_holder_name": "joseph Doe", + "card_cvc": "123" + } + }, + "billing": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "shipping": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS", + "metadata": { + "udf1": "value1", + "new_customer": "true", + "login_date": "2019-09-10T10:11:12Z" + }, + "routing": { + "type": "single", + "data": "stripe" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/event.test.js new file mode 100644 index 000000000000..a6976d95f69e --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/event.test.js @@ -0,0 +1,80 @@ +// Validate status 2xx +// pm.test("[GET]::/payments/:id - Status code is 2xx", function () { +// pm.response.to.be.success; +// }); + +// Validate if response header has matching content-type +pm.test("[GET]::/payments/:id - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[GET]::/payments/:id - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "processing" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments/:id - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} + +// Response body should have "connector_transaction_id" +// pm.test( +// "[POST]::/payments - Content check if 'connector_transaction_id' exists", +// function () { +// pm.expect(typeof jsonData.connector_transaction_id !== "undefined").to.be +// .true; +// }, +// ); diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/request.json new file mode 100644 index 000000000000..b9ebc1be4aa3 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/request.json @@ -0,0 +1,33 @@ +{ + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/.meta.json new file mode 100644 index 000000000000..57d3f8e2bc7e --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/.meta.json @@ -0,0 +1,7 @@ +{ + "childrenOrder": [ + "Payments - Create", + "Payments - Confirm", + "Payments - Retrieve" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/.event.meta.json new file mode 100644 index 000000000000..4ac527d834af --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/.event.meta.json @@ -0,0 +1,6 @@ +{ + "eventOrder": [ + "event.test.js", + "event.prerequest.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/event.prerequest.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/event.prerequest.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/event.test.js new file mode 100644 index 000000000000..b160ad9dc04b --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/event.test.js @@ -0,0 +1,103 @@ +// Validate status 2xx +pm.test("[POST]::/payments/:id/confirm - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/payments/:id/confirm - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Validate if response has JSON Body +pm.test("[POST]::/payments/:id/confirm - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "6540" for "amount" +if (jsonData?.amount) { + pm.test( + "[post]:://payments/:id/capture - Content check if value for 'amount' matches '6540'", + function () { + pm.expect(jsonData.amount).to.eql(6540); + }, + ); +} + +// Response body should have value "6540" for "amount_capturable" +if (jsonData?.amount) { + pm.test( + "[post]:://payments/:id/capture - Content check if value for 'amount_capturable' matches 'amount - 0'", + function () { + pm.expect(jsonData.amount_capturable).to.eql(0); + }, + ); +} + +// Response body should have value "processing" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments/:id/confirm - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} + +// Response body should have "connector_transaction_id" +pm.test( + "[POST]::/payments - Content check if 'connector_transaction_id' exists", + function () { + pm.expect(typeof jsonData.connector_transaction_id !== "undefined").to.be + .true; + }, +); diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/request.json new file mode 100644 index 000000000000..16f6e13983f8 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/request.json @@ -0,0 +1,63 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{publishable_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "client_secret": "{{client_secret}}" + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/confirm", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "confirm" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "This API is to confirm the payment request and forward payment to the payment processor. This API provides more granular control upon when the API is forwarded to the payment processor. Alternatively you can confirm the payment within the Payments-Create API" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Confirm/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/event.test.js new file mode 100644 index 000000000000..55dc35b91280 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/event.test.js @@ -0,0 +1,71 @@ +// Validate status 2xx +pm.test("[POST]::/payments - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/payments - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[POST]::/payments - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "requires_confirmation" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments - Content check if value for 'status' matches 'requires_confirmation'", + function () { + pm.expect(jsonData.status).to.eql("requires_confirmation"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/request.json new file mode 100644 index 000000000000..b1d5ad5ebbf8 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/request.json @@ -0,0 +1,98 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "amount": 6540, + "currency": "USD", + "confirm": false, + "business_country": "US", + "business_label": "default", + "capture_method": "automatic", + "capture_on": "2022-09-10T10:11:12Z", + "amount_to_capture": 1, + "customer_id": "bernard123", + "email": "guest@example.com", + "name": "John Doe", + "phone": "999999999", + "phone_country_code": "+65", + "description": "Its my first payment request", + "authentication_type": "no_three_ds", + "return_url": "https://duck.com", + "setup_future_usage": "on_session", + "payment_method": "card", + "payment_method_type": "debit", + "payment_method_data": { + "card": { + "card_number": "4242424242424242", + "card_exp_month": "01", + "card_exp_year": "24", + "card_holder_name": "joseph Doe", + "card_cvc": "123" + } + }, + "billing": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "shipping": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS", + "metadata": { + "udf1": "value1", + "new_customer": "true", + "login_date": "2019-09-10T10:11:12Z" + }, + "routing": { + "type": "single", + "data": "stripe" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/event.test.js new file mode 100644 index 000000000000..f87069589f0a --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/event.test.js @@ -0,0 +1,91 @@ +// Validate status 2xx +// pm.test("[GET]::/payments/:id - Status code is 2xx", function () { +// pm.response.to.be.success; +// }); + +// Validate if response header has matching content-type +pm.test("[GET]::/payments/:id - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[GET]::/payments/:id - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "processing" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments:id - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} + +// Response body should have value "6540" for "amount" +if (jsonData?.amount) { + pm.test( + "[post]:://payments/:id/capture - Content check if value for 'amount' matches '6540'", + function () { + pm.expect(jsonData.amount).to.eql(6540); + }, + ); +} + +// Response body should have value "6540" for "amount_capturable" +if (jsonData?.amount) { + pm.test( + "[post]:://payments/:id/capture - Content check if value for 'amount_capturable' matches 'amount - 0'", + function () { + pm.expect(jsonData.amount_capturable).to.eql(0); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/request.json new file mode 100644 index 000000000000..b9ebc1be4aa3 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/request.json @@ -0,0 +1,33 @@ +{ + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario2-Create payment with confirm false/Payments - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/.meta.json new file mode 100644 index 000000000000..57d3f8e2bc7e --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/.meta.json @@ -0,0 +1,7 @@ +{ + "childrenOrder": [ + "Payments - Create", + "Payments - Confirm", + "Payments - Retrieve" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/.event.meta.json new file mode 100644 index 000000000000..4ac527d834af --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/.event.meta.json @@ -0,0 +1,6 @@ +{ + "eventOrder": [ + "event.test.js", + "event.prerequest.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/event.prerequest.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/event.prerequest.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/event.test.js new file mode 100644 index 000000000000..255743af78c7 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/event.test.js @@ -0,0 +1,73 @@ +// Validate status 2xx +pm.test("[POST]::/payments/:id/confirm - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/payments/:id/confirm - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Validate if response has JSON Body +pm.test("[POST]::/payments/:id/confirm - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} +// Response body should have value "processing" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments:id/confirm - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json new file mode 100644 index 000000000000..8ac0a623f77d --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json @@ -0,0 +1,73 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{publishable_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "payment_method": "card", + "payment_method_data": { + "card": { + "card_number": "4242424242424242", + "card_exp_month": "10", + "card_exp_year": "25", + "card_holder_name": "joseph Doe", + "card_cvc": "123" + } + }, + "client_secret": "{{client_secret}}" + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/confirm", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "confirm" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "This API is to confirm the payment request and forward payment to the payment processor. This API provides more granular control upon when the API is forwarded to the payment processor. Alternatively you can confirm the payment within the Payments-Create API" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/event.test.js new file mode 100644 index 000000000000..0444324000a6 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/event.test.js @@ -0,0 +1,71 @@ +// Validate status 2xx +pm.test("[POST]::/payments - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/payments - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[POST]::/payments - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "requires_payment_method" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments - Content check if value for 'status' matches 'requires_payment_method'", + function () { + pm.expect(jsonData.status).to.eql("requires_payment_method"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/request.json new file mode 100644 index 000000000000..71cc91069581 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/request.json @@ -0,0 +1,84 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "amount": 6540, + "currency": "USD", + "confirm": false, + "capture_method": "automatic", + "capture_on": "2022-09-10T10:11:12Z", + "amount_to_capture": 6540, + "customer_id": "StripeCustomer", + "email": "guest@example.com", + "name": "John Doe", + "phone": "999999999", + "phone_country_code": "+65", + "description": "Its my first payment request", + "authentication_type": "no_three_ds", + "return_url": "https://duck.com", + "billing": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "abcd" + } + }, + "shipping": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "abcd" + } + }, + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS", + "metadata": { + "udf1": "value1", + "new_customer": "true", + "login_date": "2019-09-10T10:11:12Z" + }, + "routing": { + "type": "single", + "data": "bankofamerica" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/event.test.js new file mode 100644 index 000000000000..4fbefdb8494a --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/event.test.js @@ -0,0 +1,71 @@ +// Validate status 2xx +// pm.test("[GET]::/payments/:id - Status code is 2xx", function () { +// pm.response.to.be.success; +// }); + +// Validate if response header has matching content-type +pm.test("[GET]::/payments/:id - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[GET]::/payments/:id - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "processing" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments:id - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/request.json new file mode 100644 index 000000000000..b9ebc1be4aa3 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/request.json @@ -0,0 +1,33 @@ +{ + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/.meta.json new file mode 100644 index 000000000000..e4ef30e39e8d --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/.meta.json @@ -0,0 +1,7 @@ +{ + "childrenOrder": [ + "Payments - Create", + "Payments - Capture", + "Payments - Retrieve" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/event.test.js new file mode 100644 index 000000000000..fa6deebe16a8 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/event.test.js @@ -0,0 +1,94 @@ +// Validate status 2xx +pm.test("[POST]::/payments/:id/capture - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/payments/:id/capture - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Validate if response has JSON Body +pm.test("[POST]::/payments/:id/capture - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "processing" for "status" +if (jsonData?.status) { + pm.test( + "[POST]:://payments/:id/capture - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} + +// Response body should have value "6540" for "amount" +if (jsonData?.amount) { + pm.test( + "[post]:://payments/:id/capture - Content check if value for 'amount' matches '6540'", + function () { + pm.expect(jsonData.amount).to.eql(6540); + }, + ); +} + +// Response body should have value "6000" for "amount_received" +if (jsonData?.amount_received) { + pm.test( + "[POST]::/payments:id/capture - Content check if value for 'amount_received' matches '6000'", + function () { + pm.expect(jsonData.amount_received).to.eql(6000); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/request.json new file mode 100644 index 000000000000..8975575ca40e --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/request.json @@ -0,0 +1,45 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "amount_to_capture": 6000, + "statement_descriptor_name": "Joseph", + "statement_descriptor_suffix": "JS" + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/capture", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "capture" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To capture the funds for an uncaptured payment" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Capture/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/event.test.js new file mode 100644 index 000000000000..d683186aa007 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/event.test.js @@ -0,0 +1,71 @@ +// Validate status 2xx +pm.test("[POST]::/payments - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/payments - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[POST]::/payments - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "requires_capture" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments - Content check if value for 'status' matches 'requires_capture'", + function () { + pm.expect(jsonData.status).to.eql("requires_capture"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json new file mode 100644 index 000000000000..5e3ff0e70ad2 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json @@ -0,0 +1,98 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "amount": 6540, + "currency": "USD", + "confirm": true, + "business_country": "US", + "business_label": "default", + "capture_method": "manual", + "capture_on": "2022-09-10T10:11:12Z", + "amount_to_capture": 1, + "customer_id": "bernard123", + "email": "guest@example.com", + "name": "John Doe", + "phone": "999999999", + "phone_country_code": "+65", + "description": "Its my first payment request", + "authentication_type": "no_three_ds", + "return_url": "https://duck.com", + "setup_future_usage": "on_session", + "payment_method": "card", + "payment_method_type": "debit", + "payment_method_data": { + "card": { + "card_number": "3566111111111113", + "card_exp_month": "12", + "card_exp_year": "30", + "card_holder_name": "joseph Doe", + "card_cvc": "123" + } + }, + "billing": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "shipping": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS", + "metadata": { + "udf1": "value1", + "new_customer": "true", + "login_date": "2019-09-10T10:11:12Z" + }, + "routing": { + "type": "single", + "data": "stripe" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/event.test.js new file mode 100644 index 000000000000..b1b53a360e32 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/event.test.js @@ -0,0 +1,71 @@ +// Validate status 2xx +// pm.test("[GET]::/payments/:id - Status code is 2xx", function () { +// pm.response.to.be.success; +// }); + +// Validate if response header has matching content-type +pm.test("[GET]::/payments/:id - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[GET]::/payments/:id - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "processing" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments - Content check if value for 'status' matches 'processing'", + function () { + pm.expect(jsonData.status).to.eql("processing"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/request.json new file mode 100644 index 000000000000..b9ebc1be4aa3 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/request.json @@ -0,0 +1,33 @@ +{ + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/.meta.json new file mode 100644 index 000000000000..14bab2fbd260 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/.meta.json @@ -0,0 +1,7 @@ +{ + "childrenOrder": [ + "Payments - Create", + "Payments - Cancel", + "Payments - Retrieve" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/event.test.js new file mode 100644 index 000000000000..dcf3f1916430 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/event.test.js @@ -0,0 +1,61 @@ +// Validate status 2xx +pm.test("[POST]::/payments/:id/cancel - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/payments/:id/cancel - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Validate if response has JSON Body +pm.test("[POST]::/payments/:id/cancel - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "cancelled" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments/:id/cancel - Content check if value for 'status' matches 'cancelled'", + function () { + pm.expect(jsonData.status).to.eql("cancelled"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/request.json new file mode 100644 index 000000000000..f64e37a125a2 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/request.json @@ -0,0 +1,43 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "cancellation_reason": "requested_by_customer" + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/cancel", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "cancel" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "A Payment could can be cancelled when it is in one of these statuses: requires_payment_method, requires_capture, requires_confirmation, requires_customer_action" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Cancel/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/event.test.js new file mode 100644 index 000000000000..d683186aa007 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/event.test.js @@ -0,0 +1,71 @@ +// Validate status 2xx +pm.test("[POST]::/payments - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/payments - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[POST]::/payments - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "requires_capture" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments - Content check if value for 'status' matches 'requires_capture'", + function () { + pm.expect(jsonData.status).to.eql("requires_capture"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json new file mode 100644 index 000000000000..5e3ff0e70ad2 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json @@ -0,0 +1,98 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "amount": 6540, + "currency": "USD", + "confirm": true, + "business_country": "US", + "business_label": "default", + "capture_method": "manual", + "capture_on": "2022-09-10T10:11:12Z", + "amount_to_capture": 1, + "customer_id": "bernard123", + "email": "guest@example.com", + "name": "John Doe", + "phone": "999999999", + "phone_country_code": "+65", + "description": "Its my first payment request", + "authentication_type": "no_three_ds", + "return_url": "https://duck.com", + "setup_future_usage": "on_session", + "payment_method": "card", + "payment_method_type": "debit", + "payment_method_data": { + "card": { + "card_number": "3566111111111113", + "card_exp_month": "12", + "card_exp_year": "30", + "card_holder_name": "joseph Doe", + "card_cvc": "123" + } + }, + "billing": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "shipping": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "sundari", + "last_name": "sundari" + } + }, + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS", + "metadata": { + "udf1": "value1", + "new_customer": "true", + "login_date": "2019-09-10T10:11:12Z" + }, + "routing": { + "type": "single", + "data": "stripe" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/event.test.js new file mode 100644 index 000000000000..5e52e13a59e1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/event.test.js @@ -0,0 +1,71 @@ +// Validate status 2xx +pm.test("[GET]::/payments/:id - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[GET]::/payments/:id - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[GET]::/payments/:id - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} + +// Response body should have value "cancelled" for "status" +if (jsonData?.status) { + pm.test( + "[POST]::/payments/:id - Content check if value for 'status' matches 'cancelled'", + function () { + pm.expect(jsonData.status).to.eql("cancelled"); + }, + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/request.json new file mode 100644 index 000000000000..b9ebc1be4aa3 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/request.json @@ -0,0 +1,33 @@ +{ + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/.meta.json new file mode 100644 index 000000000000..e3596ba357bc --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/.meta.json @@ -0,0 +1,9 @@ +{ + "childrenOrder": [ + "Merchant Account - Create", + "API Key - Create", + "Payment Connector - Create", + "Payments - Create", + "Payments - Retrieve" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/event.test.js new file mode 100644 index 000000000000..4e27c5a50253 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/event.test.js @@ -0,0 +1,46 @@ +// Validate status 2xx +pm.test("[POST]::/api_keys/:merchant_id - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/api_keys/:merchant_id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id +if (jsonData?.key_id) { + pm.collectionVariables.set("api_key_id", jsonData.key_id); + console.log( + "- use {{api_key_id}} as collection variable for value", + jsonData.key_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.", + ); +} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/request.json new file mode 100644 index 000000000000..4e4c66284978 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/request.json @@ -0,0 +1,52 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw_json_formatted": { + "name": "API Key 1", + "description": null, + "expiration": "2069-09-23T01:02:03.000Z" + } + }, + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/API Key - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/event.test.js new file mode 100644 index 000000000000..7de0d5beb316 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/event.test.js @@ -0,0 +1,56 @@ +// Validate status 2xx +pm.test("[POST]::/accounts - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/accounts - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set merchant_id as variable for jsonData.merchant_id +if (jsonData?.merchant_id) { + pm.collectionVariables.set("merchant_id", jsonData.merchant_id); + console.log( + "- use {{merchant_id}} as collection variable for value", + jsonData.merchant_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{merchant_id}}, as jsonData.merchant_id is undefined.", + ); +} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} + +// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key +if (jsonData?.publishable_key) { + pm.collectionVariables.set("publishable_key", jsonData.publishable_key); + console.log( + "- use {{publishable_key}} as collection variable for value", + jsonData.publishable_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/request.json new file mode 100644 index 000000000000..5313e3e6b486 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/request.json @@ -0,0 +1,95 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "merchant_id": "postman_merchant_GHAction_{{$guid}}", + "locker_id": "m0010", + "merchant_name": "NewAge Retailer", + "merchant_details": { + "primary_contact_person": "John Test", + "primary_email": "JohnTest@test.com", + "primary_phone": "sunt laborum", + "secondary_contact_person": "John Test2", + "secondary_email": "JohnTest2@test.com", + "secondary_phone": "cillum do dolor id", + "website": "www.example.com", + "about_business": "Online Retail with a wide selection of organic products for North America", + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US" + } + }, + "return_url": "https://duck.com/success", + "webhook_details": { + "webhook_version": "1.0.1", + "webhook_username": "ekart_retail", + "webhook_password": "password_ekart@123", + "payment_created_enabled": true, + "payment_succeeded_enabled": true, + "payment_failed_enabled": true + }, + "sub_merchants_enabled": false, + "metadata": { + "city": "NY", + "unit": "245" + }, + "primary_business_details": [ + { + "country": "US", + "business": "default" + } + ] + } + }, + "url": { + "raw": "{{baseUrl}}/accounts", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts" + ] + }, + "description": "Create a new account for a merchant. The merchant could be a seller or retailer or client who likes to receive and send payments." +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Merchant Account - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/event.test.js new file mode 100644 index 000000000000..88e92d8d84a2 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/event.test.js @@ -0,0 +1,39 @@ +// Validate status 2xx +pm.test( + "[POST]::/account/:account_id/connectors - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/account/:account_id/connectors - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id +if (jsonData?.merchant_connector_id) { + pm.collectionVariables.set( + "merchant_connector_id", + jsonData.merchant_connector_id, + ); + console.log( + "- use {{merchant_connector_id}} as collection variable for value", + jsonData.merchant_connector_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/request.json new file mode 100644 index 000000000000..8ab41d88236e --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/request.json @@ -0,0 +1,108 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "connector_type": "fiz_operations", + "connector_name": "bankofamerica", + "business_country": "US", + "business_label": "default", + "connector_label": "first_boa_connector", + "connector_account_details": { + "auth_type": "SignatureKey", + "api_key": "{{connector_api_key}}", + "api_secret": "{{connector_api_secret}}", + "key1": "{{connector_key1}}" + }, + "test_mode": false, + "disabled": false, + "payment_methods_enabled": [ + { + "payment_method": "card", + "payment_method_types": [ + { + "payment_method_type": "credit", + "card_networks": [ + "Visa", + "Mastercard" + ], + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + }, + { + "payment_method_type": "debit", + "card_networks": [ + "Visa", + "Mastercard" + ], + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + } + ] + } + ], + "metadata": { + "city": "NY", + "unit": "245" + } + } + }, + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Create a new Payment Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialised services like Fraud / Accounting etc." +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payment Connector - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/event.test.js new file mode 100644 index 000000000000..a6947db94c0b --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/event.test.js @@ -0,0 +1,61 @@ +// Validate status 2xx +pm.test("[POST]::/payments - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/payments - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Validate if response has JSON Body +pm.test("[POST]::/payments - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/request.json new file mode 100644 index 000000000000..6af4c897162c --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/request.json @@ -0,0 +1,103 @@ +{ + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "amount": 6540, + "currency": "USD", + "confirm": true, + "capture_method": "automatic", + "capture_on": "2022-09-10T10:11:12Z", + "amount_to_capture": 6540, + "customer_id": "StripeCustomer", + "email": "guest@example.com", + "name": "John Doe", + "phone": "999999999", + "phone_country_code": "+1", + "description": "Its my first payment request", + "authentication_type": "no_three_ds", + "return_url": "https://duck.com", + "payment_method": "card", + "payment_method_type": "credit", + "payment_method_data": { + "card": { + "card_number": "4111111111111111", + "card_exp_month": "12", + "card_exp_year": "30", + "card_holder_name": "joseph Doe", + "card_cvc": "123" + } + }, + "billing": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "joseph", + "last_name": "Doe" + }, + "phone": { + "number": "8056594427", + "country_code": "+91" + } + }, + "shipping": { + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US", + "first_name": "joseph", + "last_name": "Doe" + }, + "phone": { + "number": "8056594427", + "country_code": "+91" + } + }, + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS", + "metadata": { + "udf1": "value1", + "new_customer": "true", + "login_date": "2019-09-10T10:11:12Z" + }, + "routing": { + "type": "single", + "data": "bankofamerica" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/event.test.js new file mode 100644 index 000000000000..d0a02af74367 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/event.test.js @@ -0,0 +1,61 @@ +// Validate status 2xx +pm.test("[GET]::/payments/:id - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[GET]::/payments/:id - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// Validate if response has JSON Body +pm.test("[GET]::/payments/:id - Response has JSON Body", function () { + pm.response.to.have.jsonBody(); +}); + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log( + "- use {{payment_id}} as collection variable for value", + jsonData.payment_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.", + ); +} + +// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id +if (jsonData?.mandate_id) { + pm.collectionVariables.set("mandate_id", jsonData.mandate_id); + console.log( + "- use {{mandate_id}} as collection variable for value", + jsonData.mandate_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.", + ); +} + +// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret +if (jsonData?.client_secret) { + pm.collectionVariables.set("client_secret", jsonData.client_secret); + console.log( + "- use {{client_secret}} as collection variable for value", + jsonData.client_secret, + ); +} else { + console.log( + "INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/request.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/request.json new file mode 100644 index 000000000000..c71774083b2c --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/request.json @@ -0,0 +1,27 @@ +{ + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" +} diff --git a/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/response.json b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Flow Testcases/QuickStart/Payments - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/Health check/.meta.json b/postman/collection-dir/bankofamerica/Health check/.meta.json new file mode 100644 index 000000000000..66ee7e50cab8 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Health check/.meta.json @@ -0,0 +1,5 @@ +{ + "childrenOrder": [ + "New Request" + ] +} diff --git a/postman/collection-dir/bankofamerica/Health check/New Request/.event.meta.json b/postman/collection-dir/bankofamerica/Health check/New Request/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Health check/New Request/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/Health check/New Request/event.test.js b/postman/collection-dir/bankofamerica/Health check/New Request/event.test.js new file mode 100644 index 000000000000..b490b8be090f --- /dev/null +++ b/postman/collection-dir/bankofamerica/Health check/New Request/event.test.js @@ -0,0 +1,4 @@ +// Validate status 2xx +pm.test("[POST]::/accounts - Status code is 2xx", function () { + pm.response.to.be.success; +}); diff --git a/postman/collection-dir/bankofamerica/Health check/New Request/request.json b/postman/collection-dir/bankofamerica/Health check/New Request/request.json new file mode 100644 index 000000000000..4cc8d4b1a966 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Health check/New Request/request.json @@ -0,0 +1,20 @@ +{ + "method": "GET", + "header": [ + { + "key": "x-feature", + "value": "router-custom", + "type": "text", + "disabled": true + } + ], + "url": { + "raw": "{{baseUrl}}/health", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "health" + ] + } +} diff --git a/postman/collection-dir/bankofamerica/Health check/New Request/response.json b/postman/collection-dir/bankofamerica/Health check/New Request/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/Health check/New Request/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/.meta.json b/postman/collection-dir/bankofamerica/MerchantAccounts/.meta.json new file mode 100644 index 000000000000..02ea600d2eb8 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/.meta.json @@ -0,0 +1,8 @@ +{ + "childrenOrder": [ + "Merchant Account - Create", + "Merchant Account - Retrieve", + "Merchant Account - List", + "Merchant Account - Update" + ] +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/.event.meta.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/.event.meta.json new file mode 100644 index 000000000000..4ac527d834af --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/.event.meta.json @@ -0,0 +1,6 @@ +{ + "eventOrder": [ + "event.test.js", + "event.prerequest.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/event.prerequest.js b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/event.prerequest.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/event.test.js b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/event.test.js new file mode 100644 index 000000000000..41eecccf83fc --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/event.test.js @@ -0,0 +1,77 @@ +// Validate status 2xx +pm.test("[POST]::/accounts - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[POST]::/accounts - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) { } + +// pm.collectionVariables - Set merchant_id as variable for jsonData.merchant_id +if (jsonData?.merchant_id) { + pm.collectionVariables.set("merchant_id", jsonData.merchant_id); + console.log( + "- use {{merchant_id}} as collection variable for value", + jsonData.merchant_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{merchant_id}}, as jsonData.merchant_id is undefined.", + ); +} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} + +// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key +if (jsonData?.publishable_key) { + pm.collectionVariables.set("publishable_key", jsonData.publishable_key); + console.log( + "- use {{publishable_key}} as collection variable for value", + jsonData.publishable_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.", + ); +} + +// pm.collectionVariables - Set merchant_id as variable for jsonData.merchant_id +if (jsonData?.merchant_id) { + pm.collectionVariables.set("organization_id", jsonData.organization_id); + console.log( + "- use {{organization_id}} as collection variable for value", + jsonData.organization_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{organization_id}}, as jsonData.organization_id is undefined.", + ); +} + +// Response body should have "mandate_id" +pm.test( + "[POST]::/accounts - Organization id is generated", + function () { + pm.expect(typeof jsonData.organization_id !== "undefined").to.be.true; + }, +); diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/request.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/request.json new file mode 100644 index 000000000000..5313e3e6b486 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/request.json @@ -0,0 +1,95 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "merchant_id": "postman_merchant_GHAction_{{$guid}}", + "locker_id": "m0010", + "merchant_name": "NewAge Retailer", + "merchant_details": { + "primary_contact_person": "John Test", + "primary_email": "JohnTest@test.com", + "primary_phone": "sunt laborum", + "secondary_contact_person": "John Test2", + "secondary_email": "JohnTest2@test.com", + "secondary_phone": "cillum do dolor id", + "website": "www.example.com", + "about_business": "Online Retail with a wide selection of organic products for North America", + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US" + } + }, + "return_url": "https://duck.com/success", + "webhook_details": { + "webhook_version": "1.0.1", + "webhook_username": "ekart_retail", + "webhook_password": "password_ekart@123", + "payment_created_enabled": true, + "payment_succeeded_enabled": true, + "payment_failed_enabled": true + }, + "sub_merchants_enabled": false, + "metadata": { + "city": "NY", + "unit": "245" + }, + "primary_business_details": [ + { + "country": "US", + "business": "default" + } + ] + } + }, + "url": { + "raw": "{{baseUrl}}/accounts", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts" + ] + }, + "description": "Create a new account for a merchant. The merchant could be a seller or retailer or client who likes to receive and send payments." +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/response.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/.event.meta.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/event.test.js b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/event.test.js new file mode 100644 index 000000000000..0ba15a15ee6a --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/event.test.js @@ -0,0 +1,43 @@ +// Validate status 2xx +pm.test("[GET]::/accounts/list - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[GET]::/accounts/list - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) { } + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} + +// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key +if (jsonData?.publishable_key) { + pm.collectionVariables.set("publishable_key", jsonData.publishable_key); + console.log( + "- use {{publishable_key}} as collection variable for value", + jsonData.publishable_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/request.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/request.json new file mode 100644 index 000000000000..ed2324e03082 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/request.json @@ -0,0 +1,53 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/accounts/list?organization_id={{organization_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "list" + ], + "query": [ + { + "key": "organization_id", + "value": "{{organization_id}}" + } + ], + "variable": [ + { + "key": "organization_id", + "value": "{{organization_id}}", + "description": "(Required) - Organization id" + } + ] + }, + "description": "List merchant accounts for an organization" +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/response.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - List/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/event.test.js new file mode 100644 index 000000000000..7694684a1770 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/event.test.js @@ -0,0 +1,43 @@ +// Validate status 2xx +pm.test("[GET]::/accounts/:id - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test("[GET]::/accounts/:id - Content-Type is application/json", function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); +}); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} + +// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key +if (jsonData?.publishable_key) { + pm.collectionVariables.set("publishable_key", jsonData.publishable_key); + console.log( + "- use {{publishable_key}} as collection variable for value", + jsonData.publishable_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/request.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/request.json new file mode 100644 index 000000000000..536ad17268f5 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/request.json @@ -0,0 +1,47 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/accounts/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Retrieve a merchant account details." +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/response.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/.event.meta.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/event.test.js b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/event.test.js new file mode 100644 index 000000000000..ecd9d862b3f9 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/event.test.js @@ -0,0 +1,46 @@ +// Validate status 2xx +pm.test("[POST]::/accounts/:id - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/accounts/:id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set api_key as variable for jsonData.api_key +if (jsonData?.api_key) { + pm.collectionVariables.set("api_key", jsonData.api_key); + console.log( + "- use {{api_key}} as collection variable for value", + jsonData.api_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.", + ); +} + +// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key +if (jsonData?.publishable_key) { + pm.collectionVariables.set("publishable_key", jsonData.publishable_key); + console.log( + "- use {{publishable_key}} as collection variable for value", + jsonData.publishable_key, + ); +} else { + console.log( + "INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/request.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/request.json new file mode 100644 index 000000000000..c58b1202d111 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/request.json @@ -0,0 +1,98 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "merchant_id": "{{merchant_id}}", + "merchant_name": "NewAge Retailer", + "locker_id": "m0010", + "merchant_details": { + "primary_contact_person": "joseph Test", + "primary_email": "josephTest@test.com", + "primary_phone": "veniam aute officia ullamco esse", + "secondary_contact_person": "joseph Test2", + "secondary_email": "josephTest2@test.com", + "secondary_phone": "proident adipisicing officia nulla", + "website": "www.example.com", + "about_business": "Online Retail with a wide selection of organic products for North America", + "address": { + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US" + } + }, + "return_url": "https://duck.com", + "webhook_details": { + "webhook_version": "1.0.1", + "webhook_username": "ekart_retail", + "webhook_password": "password_ekart@123", + "payment_created_enabled": true, + "payment_succeeded_enabled": true, + "payment_failed_enabled": true + }, + "sub_merchants_enabled": false, + "parent_merchant_id": "xkkdf909012sdjki2dkh5sdf", + "metadata": { + "city": "NY", + "unit": "245" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "To update an existing merchant account. Helpful in updating merchant details such as email, contact deteails, or other configuration details like webhook, routing algorithm etc" +} diff --git a/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/response.json b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/MerchantAccounts/Merchant Account - Update/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/.meta.json b/postman/collection-dir/bankofamerica/PaymentConnectors/.meta.json new file mode 100644 index 000000000000..3f8bc360dd41 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/.meta.json @@ -0,0 +1,10 @@ +{ + "childrenOrder": [ + "Payment Connector - Create", + "Payment Connector - Retrieve", + "Payment Connector - Update", + "List Connectors by MID", + "Payment Connector - Delete", + "Merchant Account - Delete" + ] +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/.event.meta.json b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/event.test.js b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/event.test.js new file mode 100644 index 000000000000..c685ff160bf9 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/event.test.js @@ -0,0 +1,17 @@ +// Validate status 2xx +pm.test( + "[GET]::/account/:account_id/connectors - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[GET]::/account/:account_id/connectors - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/request.json b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/request.json new file mode 100644 index 000000000000..89aa4e594064 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/request.json @@ -0,0 +1,41 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}" + } + ] + } +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/response.json b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/List Connectors by MID/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/.event.meta.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/event.test.js b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/event.test.js new file mode 100644 index 000000000000..596c14630df9 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/event.test.js @@ -0,0 +1,42 @@ +// Validate status 2xx +pm.test("[DELETE]::/accounts/:id - Status code is 2xx", function () { + pm.response.to.be.success; +}); + +// Validate if response header has matching content-type +pm.test( + "[DELETE]::/accounts/:id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Response Validation +const schema = { + type: "object", + description: "Merchant Account", + required: ["merchant_id", "deleted"], + properties: { + merchant_id: { + type: "string", + description: "The identifier for the MerchantAccount object.", + maxLength: 255, + example: "y3oqhf46pyzuxjbcn2giaqnb44", + }, + deleted: { + type: "boolean", + description: + "Indicates the deletion status of the Merchant Account object.", + example: true, + }, + }, +}; + +// Validate if response matches JSON schema +pm.test("[DELETE]::/accounts/:id - Schema is valid", function () { + pm.response.to.have.jsonSchema(schema, { + unknownFormats: ["int32", "int64", "float", "double"], + }); +}); diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/request.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/request.json new file mode 100644 index 000000000000..17d56a57ea45 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/request.json @@ -0,0 +1,47 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/accounts/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Delete a Merchant Account" +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/response.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Merchant Account - Delete/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/.event.meta.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/event.test.js b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/event.test.js new file mode 100644 index 000000000000..679a01ff33ed --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/event.test.js @@ -0,0 +1,47 @@ +// Validate status 2xx +pm.test( + "[POST]::/accounts/:account_id/connectors - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/accounts/:account_id/connectors - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) { } + +// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id +if (jsonData?.merchant_connector_id) { + pm.collectionVariables.set( + "merchant_connector_id", + jsonData.merchant_connector_id, + ); + console.log( + "- use {{merchant_connector_id}} as collection variable for value", + jsonData.merchant_connector_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.", + ); +} + +// Validate if the connector label is the one that is passed in the request +pm.test( + "[POST]::/accounts/:account_id/connectors - connector_label is not autogenerated", + function () { + pm.expect(jsonData.connector_label).to.eql("first_boa_connector") + }, +); \ No newline at end of file diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/request.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/request.json new file mode 100644 index 000000000000..8ab41d88236e --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/request.json @@ -0,0 +1,108 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "connector_type": "fiz_operations", + "connector_name": "bankofamerica", + "business_country": "US", + "business_label": "default", + "connector_label": "first_boa_connector", + "connector_account_details": { + "auth_type": "SignatureKey", + "api_key": "{{connector_api_key}}", + "api_secret": "{{connector_api_secret}}", + "key1": "{{connector_key1}}" + }, + "test_mode": false, + "disabled": false, + "payment_methods_enabled": [ + { + "payment_method": "card", + "payment_method_types": [ + { + "payment_method_type": "credit", + "card_networks": [ + "Visa", + "Mastercard" + ], + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + }, + { + "payment_method_type": "debit", + "card_networks": [ + "Visa", + "Mastercard" + ], + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + } + ] + } + ], + "metadata": { + "city": "NY", + "unit": "245" + } + } + }, + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Create a new Payment Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialised services like Fraud / Accounting etc." +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/response.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Create/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/.event.meta.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/event.test.js b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/event.test.js new file mode 100644 index 000000000000..a8f03ce767fd --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/event.test.js @@ -0,0 +1,39 @@ +// Validate status 2xx +pm.test( + "[DELETE]::/account/:account_id/connectors/:connector_id - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[DELETE]::/account/:account_id/connectors/:connector_id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id +if (jsonData?.merchant_connector_id) { + pm.collectionVariables.set( + "merchant_connector_id", + jsonData.merchant_connector_id, + ); + console.log( + "- use {{merchant_connector_id}} as collection variable for value", + jsonData.merchant_connector_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/request.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/request.json new file mode 100644 index 000000000000..6d7939d6762a --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/request.json @@ -0,0 +1,52 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors/:connector_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors", + ":connector_id" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}" + }, + { + "key": "connector_id", + "value": "{{merchant_connector_id}}" + } + ] + }, + "description": "Delete or Detach a Payment Connector from Merchant Account" +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/response.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Delete/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/.event.meta.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/event.test.js b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/event.test.js new file mode 100644 index 000000000000..8125c4e1bb73 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/event.test.js @@ -0,0 +1,39 @@ +// Validate status 2xx +pm.test( + "[GET]::/accounts/:account_id/connectors/:connector_id - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[GET]::/accounts/:account_id/connectors/:connector_id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id +if (jsonData?.merchant_connector_id) { + pm.collectionVariables.set( + "merchant_connector_id", + jsonData.merchant_connector_id, + ); + console.log( + "- use {{merchant_connector_id}} as collection variable for value", + jsonData.merchant_connector_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.", + ); +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/request.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/request.json new file mode 100644 index 000000000000..b87e65381250 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/request.json @@ -0,0 +1,54 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors/:connector_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors", + ":connector_id" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + }, + { + "key": "connector_id", + "value": "{{merchant_connector_id}}", + "description": "(Required) The unique identifier for the payment connector" + } + ] + }, + "description": "Retrieve Payment Connector details." +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/response.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Retrieve/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/.event.meta.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/.event.meta.json new file mode 100644 index 000000000000..688c85746ef1 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/.event.meta.json @@ -0,0 +1,5 @@ +{ + "eventOrder": [ + "event.test.js" + ] +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/event.test.js b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/event.test.js new file mode 100644 index 000000000000..98f405d8bb85 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/event.test.js @@ -0,0 +1,47 @@ +// Validate status 2xx +pm.test( + "[POST]::/account/:account_id/connectors/:connector_id - Status code is 2xx", + function () { + pm.response.to.be.success; + }, +); + +// Validate if response header has matching content-type +pm.test( + "[POST]::/account/:account_id/connectors/:connector_id - Content-Type is application/json", + function () { + pm.expect(pm.response.headers.get("Content-Type")).to.include( + "application/json", + ); + }, +); + +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) { } + +// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id +if (jsonData?.merchant_connector_id) { + pm.collectionVariables.set( + "merchant_connector_id", + jsonData.merchant_connector_id, + ); + console.log( + "- use {{merchant_connector_id}} as collection variable for value", + jsonData.merchant_connector_id, + ); +} else { + console.log( + "INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.", + ); +} + +// Validate if the connector label is the one that is passed in the request +pm.test( + "[POST]::/accounts/:account_id/connectors - connector_label is not autogenerated", + function () { + pm.expect(jsonData.connector_label).to.eql("updated_stripe_connector") + }, +); \ No newline at end of file diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/request.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/request.json new file mode 100644 index 000000000000..3cb7be2537ad --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/request.json @@ -0,0 +1,109 @@ +{ + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw_json_formatted": { + "connector_type": "fiz_operations", + "connector_account_details": { + "auth_type": "SignatureKey", + "api_key": "{{connector_api_key}}", + "api_secret": "{{connector_api_secret}}", + "key1": "{{connector_key1}}" + }, + "connector_label": "updated_stripe_connector", + "test_mode": false, + "disabled": false, + "payment_methods_enabled": [ + { + "payment_method": "card", + "payment_method_types": [ + { + "payment_method_type": "credit", + "card_networks": [ + "Visa", + "Mastercard" + ], + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + }, + { + "payment_method_type": "debit", + "card_networks": [ + "Visa", + "Mastercard" + ], + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + } + ] + } + ], + "metadata": { + "city": "NY", + "unit": "245" + } + } + }, + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors/:connector_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors", + ":connector_id" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}" + }, + { + "key": "connector_id", + "value": "{{merchant_connector_id}}" + } + ] + }, + "description": "To update an existing Payment Connector. Helpful in enabling / disabling different payment methods and other settings for the connector etc" +} diff --git a/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/response.json b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/response.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/postman/collection-dir/bankofamerica/PaymentConnectors/Payment Connector - Update/response.json @@ -0,0 +1 @@ +[] diff --git a/postman/collection-dir/bankofamerica/event.prerequest.js b/postman/collection-dir/bankofamerica/event.prerequest.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/postman/collection-dir/bankofamerica/event.test.js b/postman/collection-dir/bankofamerica/event.test.js new file mode 100644 index 000000000000..fb52caec30fc --- /dev/null +++ b/postman/collection-dir/bankofamerica/event.test.js @@ -0,0 +1,13 @@ +// Set response object as internal variable +let jsonData = {}; +try { + jsonData = pm.response.json(); +} catch (e) {} + +// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id +if (jsonData?.payment_id) { + pm.collectionVariables.set("payment_id", jsonData.payment_id); + console.log("[LOG]::payment_id - " + jsonData.payment_id); +} + +console.log("[LOG]::x-request-id - " + pm.response.headers.get("x-request-id")); diff --git a/postman/collection-json/bankofamerica.postman_collection.json b/postman/collection-json/bankofamerica.postman_collection.json new file mode 100644 index 000000000000..2b1a8fdc4704 --- /dev/null +++ b/postman/collection-json/bankofamerica.postman_collection.json @@ -0,0 +1,4310 @@ +{ + "info": { + "_postman_id": "646f7167-da26-4a24-adb0-4157fd3a1781", + "name": "bankofamerica", + "description": "## Get started\n\nJuspay Router provides a collection of APIs that enable you to process and manage payments. Our APIs accept and return JSON in the HTTP body, and return standard HTTP response codes. \nYou can consume the APIs directly using your favorite HTTP/REST library. \nWe have a testing environment referred to \"sandbox\", which you can setup to test API calls without affecting production data.\n\n### Base URLs\n\nUse the following base URLs when making requests to the APIs:\n\n| Environment | Base URL |\n| --- | --- |\n| Sandbox | [https://sandbox.hyperswitch.io](https://sandbox.hyperswitch.io) |\n| Production | [https://router.juspay.io](https://router.juspay.io) |\n\n# Authentication\n\nWhen you sign up for an account, you are given a secret key (also referred as api-key). You may authenticate all API requests with Juspay server by providing the appropriate key in the request Authorization header. \nNever share your secret api keys. Keep them guarded and secure.\n\nContact Support: \nName: Juspay Support \nEmail: [support@juspay.in](mailto:support@juspay.in)", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "28305597" + }, + "item": [ + { + "name": "Health check", + "item": [ + { + "name": "New Request", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/accounts - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "x-feature", + "value": "router-custom", + "type": "text", + "disabled": true + } + ], + "url": { + "raw": "{{baseUrl}}/health", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "health" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "MerchantAccounts", + "item": [ + { + "name": "Merchant Account - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/accounts - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/accounts - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) { }", + "", + "// pm.collectionVariables - Set merchant_id as variable for jsonData.merchant_id", + "if (jsonData?.merchant_id) {", + " pm.collectionVariables.set(\"merchant_id\", jsonData.merchant_id);", + " console.log(", + " \"- use {{merchant_id}} as collection variable for value\",", + " jsonData.merchant_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{merchant_id}}, as jsonData.merchant_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key", + "if (jsonData?.publishable_key) {", + " pm.collectionVariables.set(\"publishable_key\", jsonData.publishable_key);", + " console.log(", + " \"- use {{publishable_key}} as collection variable for value\",", + " jsonData.publishable_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set merchant_id as variable for jsonData.merchant_id", + "if (jsonData?.merchant_id) {", + " pm.collectionVariables.set(\"organization_id\", jsonData.organization_id);", + " console.log(", + " \"- use {{organization_id}} as collection variable for value\",", + " jsonData.organization_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{organization_id}}, as jsonData.organization_id is undefined.\",", + " );", + "}", + "", + "// Response body should have \"mandate_id\"", + "pm.test(", + " \"[POST]::/accounts - Organization id is generated\",", + " function () {", + " pm.expect(typeof jsonData.organization_id !== \"undefined\").to.be.true;", + " },", + ");", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"merchant_id\": \"postman_merchant_GHAction_{{$guid}}\",\n \"locker_id\": \"m0010\",\n \"merchant_name\": \"NewAge Retailer\",\n \"merchant_details\": {\n \"primary_contact_person\": \"John Test\",\n \"primary_email\": \"JohnTest@test.com\",\n \"primary_phone\": \"sunt laborum\",\n \"secondary_contact_person\": \"John Test2\",\n \"secondary_email\": \"JohnTest2@test.com\",\n \"secondary_phone\": \"cillum do dolor id\",\n \"website\": \"www.example.com\",\n \"about_business\": \"Online Retail with a wide selection of organic products for North America\",\n \"address\": {\n \"line1\": \"1467\",\n \"line2\": \"Harrison Street\",\n \"line3\": \"Harrison Street\",\n \"city\": \"San Fransico\",\n \"state\": \"California\",\n \"zip\": \"94122\",\n \"country\": \"US\"\n }\n },\n \"return_url\": \"https://duck.com/success\",\n \"webhook_details\": {\n \"webhook_version\": \"1.0.1\",\n \"webhook_username\": \"ekart_retail\",\n \"webhook_password\": \"password_ekart@123\",\n \"payment_created_enabled\": true,\n \"payment_succeeded_enabled\": true,\n \"payment_failed_enabled\": true\n },\n \"sub_merchants_enabled\": false,\n \"metadata\": {\n \"city\": \"NY\",\n \"unit\": \"245\"\n },\n \"primary_business_details\": [\n {\n \"country\": \"US\",\n \"business\": \"default\"\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts" + ] + }, + "description": "Create a new account for a merchant. The merchant could be a seller or retailer or client who likes to receive and send payments." + }, + "response": [] + }, + { + "name": "Merchant Account - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[GET]::/accounts/:id - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/accounts/:id - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key", + "if (jsonData?.publishable_key) {", + " pm.collectionVariables.set(\"publishable_key\", jsonData.publishable_key);", + " console.log(", + " \"- use {{publishable_key}} as collection variable for value\",", + " jsonData.publishable_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/accounts/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Retrieve a merchant account details." + }, + "response": [] + }, + { + "name": "Merchant Account - List", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[GET]::/accounts/list - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/accounts/list - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) { }", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key", + "if (jsonData?.publishable_key) {", + " pm.collectionVariables.set(\"publishable_key\", jsonData.publishable_key);", + " console.log(", + " \"- use {{publishable_key}} as collection variable for value\",", + " jsonData.publishable_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/accounts/list?organization_id={{organization_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "list" + ], + "query": [ + { + "key": "organization_id", + "value": "{{organization_id}}" + } + ], + "variable": [ + { + "key": "organization_id", + "value": "{{organization_id}}", + "description": "(Required) - Organization id" + } + ] + }, + "description": "List merchant accounts for an organization" + }, + "response": [] + }, + { + "name": "Merchant Account - Update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/accounts/:id - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/accounts/:id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key", + "if (jsonData?.publishable_key) {", + " pm.collectionVariables.set(\"publishable_key\", jsonData.publishable_key);", + " console.log(", + " \"- use {{publishable_key}} as collection variable for value\",", + " jsonData.publishable_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"merchant_id\":\"{{merchant_id}}\",\"merchant_name\":\"NewAge Retailer\",\"locker_id\":\"m0010\",\"merchant_details\":{\"primary_contact_person\":\"joseph Test\",\"primary_email\":\"josephTest@test.com\",\"primary_phone\":\"veniam aute officia ullamco esse\",\"secondary_contact_person\":\"joseph Test2\",\"secondary_email\":\"josephTest2@test.com\",\"secondary_phone\":\"proident adipisicing officia nulla\",\"website\":\"www.example.com\",\"about_business\":\"Online Retail with a wide selection of organic products for North America\",\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\"}},\"return_url\":\"https://duck.com\",\"webhook_details\":{\"webhook_version\":\"1.0.1\",\"webhook_username\":\"ekart_retail\",\"webhook_password\":\"password_ekart@123\",\"payment_created_enabled\":true,\"payment_succeeded_enabled\":true,\"payment_failed_enabled\":true},\"sub_merchants_enabled\":false,\"parent_merchant_id\":\"xkkdf909012sdjki2dkh5sdf\",\"metadata\":{\"city\":\"NY\",\"unit\":\"245\"}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "To update an existing merchant account. Helpful in updating merchant details such as email, contact deteails, or other configuration details like webhook, routing algorithm etc" + }, + "response": [] + } + ] + }, + { + "name": "API Key", + "item": [ + { + "name": "Create API Key", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/api_keys/:merchant_id - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/api_keys/:merchant_id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id", + "if (jsonData?.key_id) {", + " pm.collectionVariables.set(\"api_key_id\", jsonData.key_id);", + " console.log(", + " \"- use {{api_key_id}} as collection variable for value\",", + " jsonData.key_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"API Key 1\",\n \"description\": null,\n \"expiration\": \"2069-09-23T01:02:03.000Z\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Update API Key", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[POST]::/api_keys/:merchant_id/:api_key_id - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/api_keys/:merchant_id/:api_key_id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id", + "if (jsonData?.key_id) {", + " pm.collectionVariables.set(\"api_key_id\", jsonData.key_id);", + " console.log(", + " \"- use {{api_key_id}} as collection variable for value\",", + " jsonData.key_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":null,\"description\":\"My very awesome API key\",\"expiration\":null}" + }, + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/:api_key_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + ":api_key_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + }, + { + "key": "api_key_id", + "value": "{{api_key_id}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Retrieve API Key", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[GET]::/api_keys/:merchant_id/:api_key_id - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[GET]::/api_keys/:merchant_id/:api_key_id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id", + "if (jsonData?.key_id) {", + " pm.collectionVariables.set(\"api_key_id\", jsonData.key_id);", + " console.log(", + " \"- use {{api_key_id}} as collection variable for value\",", + " jsonData.key_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/:api_key_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + ":api_key_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + }, + { + "key": "api_key_id", + "value": "{{api_key_id}}" + } + ] + } + }, + "response": [] + }, + { + "name": "List API Keys", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[GET]::/api_keys/:merchant_id/list - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[GET]::/api_keys/:merchant_id/list - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id", + "if (jsonData?.key_id) {", + " pm.collectionVariables.set(\"api_key_id\", jsonData.key_id);", + " console.log(", + " \"- use {{api_key_id}} as collection variable for value\",", + " jsonData.key_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/list", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + "list" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete API Key", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[DELETE]::/api_keys/:merchant_id/:api-key - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[DELETE]::/api_keys/:merchant_id/:api-key - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id/:api-key", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id", + ":api-key" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + }, + { + "key": "api-key", + "value": "{{api_key_id}}" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "PaymentConnectors", + "item": [ + { + "name": "Payment Connector - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[POST]::/accounts/:account_id/connectors - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/accounts/:account_id/connectors - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) { }", + "", + "// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id", + "if (jsonData?.merchant_connector_id) {", + " pm.collectionVariables.set(", + " \"merchant_connector_id\",", + " jsonData.merchant_connector_id,", + " );", + " console.log(", + " \"- use {{merchant_connector_id}} as collection variable for value\",", + " jsonData.merchant_connector_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.\",", + " );", + "}", + "", + "// Validate if the connector label is the one that is passed in the request", + "pm.test(", + " \"[POST]::/accounts/:account_id/connectors - connector_label is not autogenerated\",", + " function () {", + " pm.expect(jsonData.connector_label).to.eql(\"first_boa_connector\")", + " },", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connector_type\": \"fiz_operations\",\n \"connector_name\": \"bankofamerica\",\n \"business_country\": \"US\",\n \"business_label\": \"default\",\n \"connector_label\": \"first_boa_connector\",\n \"connector_account_details\": {\n \"auth_type\": \"SignatureKey\",\n \"api_key\": \"{{connector_api_key}}\",\n \"api_secret\": \"{{connector_api_secret}}\",\n \"key1\": \"{{connector_key1}}\"\n },\n \"test_mode\": false,\n \"disabled\": false,\n \"payment_methods_enabled\": [\n {\n \"payment_method\": \"card\",\n \"payment_method_types\": [\n {\n \"payment_method_type\": \"credit\",\n \"card_networks\": [\n \"Visa\",\n \"Mastercard\"\n ],\n \"minimum_amount\": 1,\n \"maximum_amount\": 68607706,\n \"recurring_enabled\": true,\n \"installment_payment_enabled\": true\n },\n {\n \"payment_method_type\": \"debit\",\n \"card_networks\": [\n \"Visa\",\n \"Mastercard\"\n ],\n \"minimum_amount\": 1,\n \"maximum_amount\": 68607706,\n \"recurring_enabled\": true,\n \"installment_payment_enabled\": true\n }\n ]\n }\n ],\n \"metadata\": {\n \"city\": \"NY\",\n \"unit\": \"245\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Create a new Payment Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialised services like Fraud / Accounting etc." + }, + "response": [] + }, + { + "name": "Payment Connector - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[GET]::/accounts/:account_id/connectors/:connector_id - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[GET]::/accounts/:account_id/connectors/:connector_id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id", + "if (jsonData?.merchant_connector_id) {", + " pm.collectionVariables.set(", + " \"merchant_connector_id\",", + " jsonData.merchant_connector_id,", + " );", + " console.log(", + " \"- use {{merchant_connector_id}} as collection variable for value\",", + " jsonData.merchant_connector_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors/:connector_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors", + ":connector_id" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + }, + { + "key": "connector_id", + "value": "{{merchant_connector_id}}", + "description": "(Required) The unique identifier for the payment connector" + } + ] + }, + "description": "Retrieve Payment Connector details." + }, + "response": [] + }, + { + "name": "Payment Connector - Update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[POST]::/account/:account_id/connectors/:connector_id - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/account/:account_id/connectors/:connector_id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) { }", + "", + "// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id", + "if (jsonData?.merchant_connector_id) {", + " pm.collectionVariables.set(", + " \"merchant_connector_id\",", + " jsonData.merchant_connector_id,", + " );", + " console.log(", + " \"- use {{merchant_connector_id}} as collection variable for value\",", + " jsonData.merchant_connector_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.\",", + " );", + "}", + "", + "// Validate if the connector label is the one that is passed in the request", + "pm.test(", + " \"[POST]::/accounts/:account_id/connectors - connector_label is not autogenerated\",", + " function () {", + " pm.expect(jsonData.connector_label).to.eql(\"updated_stripe_connector\")", + " },", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connector_type\": \"fiz_operations\",\n \"connector_account_details\": {\n \"auth_type\": \"SignatureKey\",\n \"api_key\": \"{{connector_api_key}}\",\n \"api_secret\": \"{{connector_api_secret}}\",\n \"key1\": \"{{connector_key1}}\"\n },\n \"connector_label\": \"updated_stripe_connector\",\n \"test_mode\": false,\n \"disabled\": false,\n \"payment_methods_enabled\": [\n {\n \"payment_method\": \"card\",\n \"payment_method_types\": [\n {\n \"payment_method_type\": \"credit\",\n \"card_networks\": [\n \"Visa\",\n \"Mastercard\"\n ],\n \"minimum_amount\": 1,\n \"maximum_amount\": 68607706,\n \"recurring_enabled\": true,\n \"installment_payment_enabled\": true\n },\n {\n \"payment_method_type\": \"debit\",\n \"card_networks\": [\n \"Visa\",\n \"Mastercard\"\n ],\n \"minimum_amount\": 1,\n \"maximum_amount\": 68607706,\n \"recurring_enabled\": true,\n \"installment_payment_enabled\": true\n }\n ]\n }\n ],\n \"metadata\": {\n \"city\": \"NY\",\n \"unit\": \"245\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors/:connector_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors", + ":connector_id" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}" + }, + { + "key": "connector_id", + "value": "{{merchant_connector_id}}" + } + ] + }, + "description": "To update an existing Payment Connector. Helpful in enabling / disabling different payment methods and other settings for the connector etc" + }, + "response": [] + }, + { + "name": "List Connectors by MID", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[GET]::/account/:account_id/connectors - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[GET]::/account/:account_id/connectors - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Payment Connector - Delete", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[DELETE]::/account/:account_id/connectors/:connector_id - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[DELETE]::/account/:account_id/connectors/:connector_id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id", + "if (jsonData?.merchant_connector_id) {", + " pm.collectionVariables.set(", + " \"merchant_connector_id\",", + " jsonData.merchant_connector_id,", + " );", + " console.log(", + " \"- use {{merchant_connector_id}} as collection variable for value\",", + " jsonData.merchant_connector_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors/:connector_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors", + ":connector_id" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}" + }, + { + "key": "connector_id", + "value": "{{merchant_connector_id}}" + } + ] + }, + "description": "Delete or Detach a Payment Connector from Merchant Account" + }, + "response": [] + }, + { + "name": "Merchant Account - Delete", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[DELETE]::/accounts/:id - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[DELETE]::/accounts/:id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Response Validation", + "const schema = {", + " type: \"object\",", + " description: \"Merchant Account\",", + " required: [\"merchant_id\", \"deleted\"],", + " properties: {", + " merchant_id: {", + " type: \"string\",", + " description: \"The identifier for the MerchantAccount object.\",", + " maxLength: 255,", + " example: \"y3oqhf46pyzuxjbcn2giaqnb44\",", + " },", + " deleted: {", + " type: \"boolean\",", + " description:", + " \"Indicates the deletion status of the Merchant Account object.\",", + " example: true,", + " },", + " },", + "};", + "", + "// Validate if response matches JSON schema", + "pm.test(\"[DELETE]::/accounts/:id - Schema is valid\", function () {", + " pm.response.to.have.jsonSchema(schema, {", + " unknownFormats: [\"int32\", \"int64\", \"float\", \"double\"],", + " });", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/accounts/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Delete a Merchant Account" + }, + "response": [] + } + ] + }, + { + "name": "Flow Testcases", + "item": [ + { + "name": "QuickStart", + "item": [ + { + "name": "Merchant Account - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/accounts - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/accounts - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set merchant_id as variable for jsonData.merchant_id", + "if (jsonData?.merchant_id) {", + " pm.collectionVariables.set(\"merchant_id\", jsonData.merchant_id);", + " console.log(", + " \"- use {{merchant_id}} as collection variable for value\",", + " jsonData.merchant_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{merchant_id}}, as jsonData.merchant_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set publishable_key as variable for jsonData.publishable_key", + "if (jsonData?.publishable_key) {", + " pm.collectionVariables.set(\"publishable_key\", jsonData.publishable_key);", + " console.log(", + " \"- use {{publishable_key}} as collection variable for value\",", + " jsonData.publishable_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{publishable_key}}, as jsonData.publishable_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"merchant_id\": \"postman_merchant_GHAction_{{$guid}}\",\n \"locker_id\": \"m0010\",\n \"merchant_name\": \"NewAge Retailer\",\n \"merchant_details\": {\n \"primary_contact_person\": \"John Test\",\n \"primary_email\": \"JohnTest@test.com\",\n \"primary_phone\": \"sunt laborum\",\n \"secondary_contact_person\": \"John Test2\",\n \"secondary_email\": \"JohnTest2@test.com\",\n \"secondary_phone\": \"cillum do dolor id\",\n \"website\": \"www.example.com\",\n \"about_business\": \"Online Retail with a wide selection of organic products for North America\",\n \"address\": {\n \"line1\": \"1467\",\n \"line2\": \"Harrison Street\",\n \"line3\": \"Harrison Street\",\n \"city\": \"San Fransico\",\n \"state\": \"California\",\n \"zip\": \"94122\",\n \"country\": \"US\"\n }\n },\n \"return_url\": \"https://duck.com/success\",\n \"webhook_details\": {\n \"webhook_version\": \"1.0.1\",\n \"webhook_username\": \"ekart_retail\",\n \"webhook_password\": \"password_ekart@123\",\n \"payment_created_enabled\": true,\n \"payment_succeeded_enabled\": true,\n \"payment_failed_enabled\": true\n },\n \"sub_merchants_enabled\": false,\n \"metadata\": {\n \"city\": \"NY\",\n \"unit\": \"245\"\n },\n \"primary_business_details\": [\n {\n \"country\": \"US\",\n \"business\": \"default\"\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts" + ] + }, + "description": "Create a new account for a merchant. The merchant could be a seller or retailer or client who likes to receive and send payments." + }, + "response": [] + }, + { + "name": "API Key - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/api_keys/:merchant_id - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/api_keys/:merchant_id - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set api_key_id as variable for jsonData.key_id", + "if (jsonData?.key_id) {", + " pm.collectionVariables.set(\"api_key_id\", jsonData.key_id);", + " console.log(", + " \"- use {{api_key_id}} as collection variable for value\",", + " jsonData.key_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key_id}}, as jsonData.key_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set api_key as variable for jsonData.api_key", + "if (jsonData?.api_key) {", + " pm.collectionVariables.set(\"api_key\", jsonData.api_key);", + " console.log(", + " \"- use {{api_key}} as collection variable for value\",", + " jsonData.api_key,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{api_key}}, as jsonData.api_key is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"name\":\"API Key 1\",\"description\":null,\"expiration\":\"2069-09-23T01:02:03.000Z\"}" + }, + "url": { + "raw": "{{baseUrl}}/api_keys/:merchant_id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api_keys", + ":merchant_id" + ], + "variable": [ + { + "key": "merchant_id", + "value": "{{merchant_id}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Payment Connector - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(", + " \"[POST]::/account/:account_id/connectors - Status code is 2xx\",", + " function () {", + " pm.response.to.be.success;", + " },", + ");", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/account/:account_id/connectors - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set merchant_connector_id as variable for jsonData.merchant_connector_id", + "if (jsonData?.merchant_connector_id) {", + " pm.collectionVariables.set(", + " \"merchant_connector_id\",", + " jsonData.merchant_connector_id,", + " );", + " console.log(", + " \"- use {{merchant_connector_id}} as collection variable for value\",", + " jsonData.merchant_connector_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{merchant_connector_id}}, as jsonData.merchant_connector_id is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{admin_api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connector_type\": \"fiz_operations\",\n \"connector_name\": \"bankofamerica\",\n \"business_country\": \"US\",\n \"business_label\": \"default\",\n \"connector_label\": \"first_boa_connector\",\n \"connector_account_details\": {\n \"auth_type\": \"SignatureKey\",\n \"api_key\": \"{{connector_api_key}}\",\n \"api_secret\": \"{{connector_api_secret}}\",\n \"key1\": \"{{connector_key1}}\"\n },\n \"test_mode\": false,\n \"disabled\": false,\n \"payment_methods_enabled\": [\n {\n \"payment_method\": \"card\",\n \"payment_method_types\": [\n {\n \"payment_method_type\": \"credit\",\n \"card_networks\": [\n \"Visa\",\n \"Mastercard\"\n ],\n \"minimum_amount\": 1,\n \"maximum_amount\": 68607706,\n \"recurring_enabled\": true,\n \"installment_payment_enabled\": true\n },\n {\n \"payment_method_type\": \"debit\",\n \"card_networks\": [\n \"Visa\",\n \"Mastercard\"\n ],\n \"minimum_amount\": 1,\n \"maximum_amount\": 68607706,\n \"recurring_enabled\": true,\n \"installment_payment_enabled\": true\n }\n ]\n }\n ],\n \"metadata\": {\n \"city\": \"NY\",\n \"unit\": \"245\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/account/:account_id/connectors", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "account", + ":account_id", + "connectors" + ], + "variable": [ + { + "key": "account_id", + "value": "{{merchant_id}}", + "description": "(Required) The unique identifier for the merchant account" + } + ] + }, + "description": "Create a new Payment Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialised services like Fraud / Accounting etc." + }, + "response": [] + }, + { + "name": "Payments - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/payments - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"amount\": 6540,\n \"currency\": \"USD\",\n \"confirm\": true,\n \"capture_method\": \"automatic\",\n \"capture_on\": \"2022-09-10T10:11:12Z\",\n \"amount_to_capture\": 6540,\n \"customer_id\": \"StripeCustomer\",\n \"email\": \"guest@example.com\",\n \"name\": \"John Doe\",\n \"phone\": \"999999999\",\n \"phone_country_code\": \"+1\",\n \"description\": \"Its my first payment request\",\n \"authentication_type\": \"no_three_ds\",\n \"return_url\": \"https://duck.com\",\n \"payment_method\": \"card\",\n \"payment_method_type\": \"credit\",\n \"payment_method_data\": {\n \"card\": {\n \"card_number\": \"4111111111111111\",\n \"card_exp_month\": \"12\",\n \"card_exp_year\": \"30\",\n \"card_holder_name\": \"joseph Doe\",\n \"card_cvc\": \"123\"\n }\n },\n \"billing\": {\n \"address\": {\n \"line1\": \"1467\",\n \"line2\": \"Harrison Street\",\n \"line3\": \"Harrison Street\",\n \"city\": \"San Fransico\",\n \"state\": \"California\",\n \"zip\": \"94122\",\n \"country\": \"US\",\n \"first_name\": \"joseph\",\n \"last_name\": \"Doe\"\n },\n \"phone\": {\n \"number\": \"8056594427\",\n \"country_code\": \"+91\"\n }\n },\n \"shipping\": {\n \"address\": {\n \"line1\": \"1467\",\n \"line2\": \"Harrison Street\",\n \"line3\": \"Harrison Street\",\n \"city\": \"San Fransico\",\n \"state\": \"California\",\n \"zip\": \"94122\",\n \"country\": \"US\",\n \"first_name\": \"joseph\",\n \"last_name\": \"Doe\"\n },\n \"phone\": {\n \"number\": \"8056594427\",\n \"country_code\": \"+91\"\n }\n },\n \"statement_descriptor_name\": \"joseph\",\n \"statement_descriptor_suffix\": \"JS\",\n \"metadata\": {\n \"udf1\": \"value1\",\n \"new_customer\": \"true\",\n \"login_date\": \"2019-09-10T10:11:12Z\"\n },\n \"routing\": {\n \"type\": \"single\",\n \"data\": \"bankofamerica\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" + }, + "response": [] + }, + { + "name": "Payments - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[GET]::/payments/:id - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/payments/:id - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// Validate if response has JSON Body", + "pm.test(\"[GET]::/payments/:id - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" + }, + "response": [] + } + ] + }, + { + "name": "Happy Cases", + "item": [ + { + "name": "Scenario1-Create payment with confirm true", + "item": [ + { + "name": "Payments - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/payments - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"processing\" for \"status\" because payment gets succeeded after one day.", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "", + "// Response body should have \"connector_transaction_id\"", + "pm.test(", + " \"[POST]::/payments - Content check if 'connector_transaction_id' exists\",", + " function () {", + " pm.expect(typeof jsonData.connector_transaction_id !== \"undefined\").to.be", + " .true;", + " },", + ");", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":1,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"01\",\"card_exp_year\":\"24\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":\"stripe\"}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" + }, + "response": [] + }, + { + "name": "Payments - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "// pm.test(\"[GET]::/payments/:id - Status code is 2xx\", function () {", + "// pm.response.to.be.success;", + "// });", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/payments/:id - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[GET]::/payments/:id - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"processing\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments/:id - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "", + "// Response body should have \"connector_transaction_id\"", + "// pm.test(", + "// \"[POST]::/payments - Content check if 'connector_transaction_id' exists\",", + "// function () {", + "// pm.expect(typeof jsonData.connector_transaction_id !== \"undefined\").to.be", + "// .true;", + "// },", + "// );", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" + }, + "response": [] + } + ] + }, + { + "name": "Scenario2-Create payment with confirm false", + "item": [ + { + "name": "Payments - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/payments - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"requires_confirmation\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments - Content check if value for 'status' matches 'requires_confirmation'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"requires_confirmation\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":false,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":1,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"01\",\"card_exp_year\":\"24\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":\"stripe\"}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" + }, + "response": [] + }, + { + "name": "Payments - Confirm", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments/:id/confirm - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/payments/:id/confirm - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments/:id/confirm - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"6540\" for \"amount\"", + "if (jsonData?.amount) {", + " pm.test(", + " \"[post]:://payments/:id/capture - Content check if value for 'amount' matches '6540'\",", + " function () {", + " pm.expect(jsonData.amount).to.eql(6540);", + " },", + " );", + "}", + "", + "// Response body should have value \"6540\" for \"amount_capturable\"", + "if (jsonData?.amount) {", + " pm.test(", + " \"[post]:://payments/:id/capture - Content check if value for 'amount_capturable' matches 'amount - 0'\",", + " function () {", + " pm.expect(jsonData.amount_capturable).to.eql(0);", + " },", + " );", + "}", + "", + "// Response body should have value \"processing\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments/:id/confirm - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "", + "// Response body should have \"connector_transaction_id\"", + "pm.test(", + " \"[POST]::/payments - Content check if 'connector_transaction_id' exists\",", + " function () {", + " pm.expect(typeof jsonData.connector_transaction_id !== \"undefined\").to.be", + " .true;", + " },", + ");", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{publishable_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"client_secret\":\"{{client_secret}}\"}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/confirm", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "confirm" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "This API is to confirm the payment request and forward payment to the payment processor. This API provides more granular control upon when the API is forwarded to the payment processor. Alternatively you can confirm the payment within the Payments-Create API" + }, + "response": [] + }, + { + "name": "Payments - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "// pm.test(\"[GET]::/payments/:id - Status code is 2xx\", function () {", + "// pm.response.to.be.success;", + "// });", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/payments/:id - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[GET]::/payments/:id - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"processing\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments:id - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "", + "// Response body should have value \"6540\" for \"amount\"", + "if (jsonData?.amount) {", + " pm.test(", + " \"[post]:://payments/:id/capture - Content check if value for 'amount' matches '6540'\",", + " function () {", + " pm.expect(jsonData.amount).to.eql(6540);", + " },", + " );", + "}", + "", + "// Response body should have value \"6540\" for \"amount_capturable\"", + "if (jsonData?.amount) {", + " pm.test(", + " \"[post]:://payments/:id/capture - Content check if value for 'amount_capturable' matches 'amount - 0'\",", + " function () {", + " pm.expect(jsonData.amount_capturable).to.eql(0);", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" + }, + "response": [] + } + ] + }, + { + "name": "Scenario3-Create payment without PMD", + "item": [ + { + "name": "Payments - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/payments - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"requires_payment_method\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments - Content check if value for 'status' matches 'requires_payment_method'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"requires_payment_method\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"amount\": 6540,\n \"currency\": \"USD\",\n \"confirm\": false,\n \"capture_method\": \"automatic\",\n \"capture_on\": \"2022-09-10T10:11:12Z\",\n \"amount_to_capture\": 6540,\n \"customer_id\": \"StripeCustomer\",\n \"email\": \"guest@example.com\",\n \"name\": \"John Doe\",\n \"phone\": \"999999999\",\n \"phone_country_code\": \"+65\",\n \"description\": \"Its my first payment request\",\n \"authentication_type\": \"no_three_ds\",\n \"return_url\": \"https://duck.com\",\n \"billing\": {\n \"address\": {\n \"line1\": \"1467\",\n \"line2\": \"Harrison Street\",\n \"line3\": \"Harrison Street\",\n \"city\": \"San Fransico\",\n \"state\": \"California\",\n \"zip\": \"94122\",\n \"country\": \"US\",\n \"first_name\": \"sundari\",\n \"last_name\": \"abcd\"\n }\n },\n \"shipping\": {\n \"address\": {\n \"line1\": \"1467\",\n \"line2\": \"Harrison Street\",\n \"line3\": \"Harrison Street\",\n \"city\": \"San Fransico\",\n \"state\": \"California\",\n \"zip\": \"94122\",\n \"country\": \"US\",\n \"first_name\": \"sundari\",\n \"last_name\": \"abcd\"\n }\n },\n \"statement_descriptor_name\": \"joseph\",\n \"statement_descriptor_suffix\": \"JS\",\n \"metadata\": {\n \"udf1\": \"value1\",\n \"new_customer\": \"true\",\n \"login_date\": \"2019-09-10T10:11:12Z\"\n },\n \"routing\": {\n \"type\": \"single\",\n \"data\": \"bankofamerica\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" + }, + "response": [] + }, + { + "name": "Payments - Confirm", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments/:id/confirm - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/payments/:id/confirm - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments/:id/confirm - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "// Response body should have value \"processing\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments:id/confirm - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{publishable_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\"}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/confirm", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "confirm" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "This API is to confirm the payment request and forward payment to the payment processor. This API provides more granular control upon when the API is forwarded to the payment processor. Alternatively you can confirm the payment within the Payments-Create API" + }, + "response": [] + }, + { + "name": "Payments - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "// pm.test(\"[GET]::/payments/:id - Status code is 2xx\", function () {", + "// pm.response.to.be.success;", + "// });", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/payments/:id - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[GET]::/payments/:id - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"processing\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments:id - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" + }, + "response": [] + } + ] + }, + { + "name": "Scenario4-Create payment with Manual capture", + "item": [ + { + "name": "Payments - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/payments - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"requires_capture\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments - Content check if value for 'status' matches 'requires_capture'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"requires_capture\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":1,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"3566111111111113\",\"card_exp_month\":\"12\",\"card_exp_year\":\"30\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":\"stripe\"}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" + }, + "response": [] + }, + { + "name": "Payments - Capture", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments/:id/capture - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/payments/:id/capture - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments/:id/capture - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"processing\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]:://payments/:id/capture - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "", + "// Response body should have value \"6540\" for \"amount\"", + "if (jsonData?.amount) {", + " pm.test(", + " \"[post]:://payments/:id/capture - Content check if value for 'amount' matches '6540'\",", + " function () {", + " pm.expect(jsonData.amount).to.eql(6540);", + " },", + " );", + "}", + "", + "// Response body should have value \"6000\" for \"amount_received\"", + "if (jsonData?.amount_received) {", + " pm.test(", + " \"[POST]::/payments:id/capture - Content check if value for 'amount_received' matches '6000'\",", + " function () {", + " pm.expect(jsonData.amount_received).to.eql(6000);", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"amount_to_capture\":6000,\"statement_descriptor_name\":\"Joseph\",\"statement_descriptor_suffix\":\"JS\"}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/capture", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "capture" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To capture the funds for an uncaptured payment" + }, + "response": [] + }, + { + "name": "Payments - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "// pm.test(\"[GET]::/payments/:id - Status code is 2xx\", function () {", + "// pm.response.to.be.success;", + "// });", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/payments/:id - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[GET]::/payments/:id - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"processing\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments - Content check if value for 'status' matches 'processing'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"processing\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" + }, + "response": [] + } + ] + }, + { + "name": "Scenario5-Void the payment", + "item": [ + { + "name": "Payments - Create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[POST]::/payments - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"requires_capture\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments - Content check if value for 'status' matches 'requires_capture'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"requires_capture\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":1,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"3566111111111113\",\"card_exp_month\":\"12\",\"card_exp_year\":\"30\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":\"stripe\"}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments" + ] + }, + "description": "To process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture" + }, + "response": [] + }, + { + "name": "Payments - Cancel", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[POST]::/payments/:id/cancel - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(", + " \"[POST]::/payments/:id/cancel - Content-Type is application/json\",", + " function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + " },", + ");", + "", + "// Validate if response has JSON Body", + "pm.test(\"[POST]::/payments/:id/cancel - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"cancelled\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments/:id/cancel - Content check if value for 'status' matches 'cancelled'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"cancelled\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"cancellation_reason\":\"requested_by_customer\"}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/payments/:id/cancel", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id", + "cancel" + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "A Payment could can be cancelled when it is in one of these statuses: requires_payment_method, requires_capture, requires_confirmation, requires_customer_action" + }, + "response": [] + }, + { + "name": "Payments - Retrieve", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Validate status 2xx", + "pm.test(\"[GET]::/payments/:id - Status code is 2xx\", function () {", + " pm.response.to.be.success;", + "});", + "", + "// Validate if response header has matching content-type", + "pm.test(\"[GET]::/payments/:id - Content-Type is application/json\", function () {", + " pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(", + " \"application/json\",", + " );", + "});", + "", + "// Validate if response has JSON Body", + "pm.test(\"[GET]::/payments/:id - Response has JSON Body\", function () {", + " pm.response.to.have.jsonBody();", + "});", + "", + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(", + " \"- use {{payment_id}} as collection variable for value\",", + " jsonData.payment_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{payment_id}}, as jsonData.payment_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set mandate_id as variable for jsonData.mandate_id", + "if (jsonData?.mandate_id) {", + " pm.collectionVariables.set(\"mandate_id\", jsonData.mandate_id);", + " console.log(", + " \"- use {{mandate_id}} as collection variable for value\",", + " jsonData.mandate_id,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{mandate_id}}, as jsonData.mandate_id is undefined.\",", + " );", + "}", + "", + "// pm.collectionVariables - Set client_secret as variable for jsonData.client_secret", + "if (jsonData?.client_secret) {", + " pm.collectionVariables.set(\"client_secret\", jsonData.client_secret);", + " console.log(", + " \"- use {{client_secret}} as collection variable for value\",", + " jsonData.client_secret,", + " );", + "} else {", + " console.log(", + " \"INFO - Unable to assign variable {{client_secret}}, as jsonData.client_secret is undefined.\",", + " );", + "}", + "", + "// Response body should have value \"cancelled\" for \"status\"", + "if (jsonData?.status) {", + " pm.test(", + " \"[POST]::/payments/:id - Content check if value for 'status' matches 'cancelled'\",", + " function () {", + " pm.expect(jsonData.status).to.eql(\"cancelled\");", + " },", + " );", + "}", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/payments/:id?force_sync=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "payments", + ":id" + ], + "query": [ + { + "key": "force_sync", + "value": "true" + } + ], + "variable": [ + { + "key": "id", + "value": "{{payment_id}}", + "description": "(Required) unique payment id" + } + ] + }, + "description": "To retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment" + }, + "response": [] + } + ] + } + ] + } + ] + } + ], + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "{{api_key}}", + "type": "string" + }, + { + "key": "key", + "value": "api-key", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Set response object as internal variable", + "let jsonData = {};", + "try {", + " jsonData = pm.response.json();", + "} catch (e) {}", + "", + "// pm.collectionVariables - Set payment_id as variable for jsonData.payment_id", + "if (jsonData?.payment_id) {", + " pm.collectionVariables.set(\"payment_id\", jsonData.payment_id);", + " console.log(\"[LOG]::payment_id - \" + jsonData.payment_id);", + "}", + "", + "console.log(\"[LOG]::x-request-id - \" + pm.response.headers.get(\"x-request-id\"));", + "" + ] + } + } + ], + "variable": [ + { + "key": "baseUrl", + "value": "", + "type": "string" + }, + { + "key": "admin_api_key", + "value": "", + "type": "string" + }, + { + "key": "api_key", + "value": "", + "type": "string" + }, + { + "key": "merchant_id", + "value": "" + }, + { + "key": "payment_id", + "value": "" + }, + { + "key": "customer_id", + "value": "" + }, + { + "key": "mandate_id", + "value": "" + }, + { + "key": "payment_method_id", + "value": "" + }, + { + "key": "refund_id", + "value": "" + }, + { + "key": "merchant_connector_id", + "value": "" + }, + { + "key": "client_secret", + "value": "", + "type": "string" + }, + { + "key": "connector_api_key", + "value": "", + "type": "string" + }, + { + "key": "publishable_key", + "value": "", + "type": "string" + }, + { + "key": "api_key_id", + "value": "", + "type": "string" + }, + { + "key": "payment_token", + "value": "" + }, + { + "key": "gateway_merchant_id", + "value": "", + "type": "string" + }, + { + "key": "certificate", + "value": "", + "type": "string" + }, + { + "key": "certificate_keys", + "value": "", + "type": "string" + }, + { + "key": "organization_id", + "value": "" + }, + { + "key": "connector_api_secret", + "value": "", + "type": "string" + }, + { + "key": "connector_key1", + "value": "", + "type": "string" + } + ] +} \ No newline at end of file From d205fd6959bd985ca75be06d1b5d889d45b4c554 Mon Sep 17 00:00:00 2001 From: swangi-kumari Date: Fri, 10 Nov 2023 16:36:41 +0530 Subject: [PATCH 22/26] feat: updated credentials for boa connector --- .github/secrets/connector_auth.toml.gpg | Bin 3310 -> 3395 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/.github/secrets/connector_auth.toml.gpg b/.github/secrets/connector_auth.toml.gpg index 487e436df4638117aa49684ae4f7f45f682e44cd..7da9189ade58a1bab00649a724f5f1c4f26fee7f 100644 GIT binary patch literal 3395 zcmV-J4ZQM<4Fm}T2wG4r!^LpaX8Y3W0ZVS|^j)3kaW~$@Z$|xD!@3GwP4w$K(<2$o zlLY+w3CK|D-v1@*z~Nt?WUP&Oa<(o4+SzXZ)*ohBhM2ZyUF@mN(rQI)6cr!D0I08w zJyGIrA!kTvq+d)F(8rYwe`tLxM5cOeg)}^oBL35%EzZ3spBjd+!H2e=CGEc9R@=C3V|2FX$Z!O^hTkoXi?43BglJB@!04mGa zD{6PoP8C084R{b-JbtG9HM>LkUE*EoUjvc}PC1J+{Z{iaUIOJGe^n7nxit^|TWs$! zhONQbNDGu!J8db7-5{K+&ZZ7H(ip*>MZbfWlfWCnpp$44?dfveKX0oT&xo#qHquCl z`SB1jSC3XWYmruA=Nr5<+2_Y!Y>DPJL~0BgWc6`ku9iF6?$+5xYhA&YaTdvI!y?GE z*7#`)g7rjVD7*g2w#r66Qn2-55hTef`x&Jm?L! z4qT*@$qdaT=N<{pY7g(^pa5%w^6XU?5S-cGAVISe@SCrCRliGUXXpIkzLC)a*(2!W zzQ+oskf;2^XztBe$?wbDo`dW?z`5Ofy)5x=YY5}m(x~J5Nd+Ue2s8$TK@$qf@z6hF zLPGqpP^Vj_^gYi{{?%m+5ZVoHRZ+r;DRb&GHzu#2Y3IF7!Z2J{?!$mbSq!(Md-b_Q zzKZY#p*a>yBA{lFC5H~?cy^L@@t;)$TIBFA_?uwRzNR(k?m@-YpD@t;jno(ZGpp~O zbYTFokT;F++Rqlez6NvuAnI=q!d+ut_dwml3_urda4+1-zKtPjj296FEU8$!{bMT_ zVpinv!(|$IbAKf9W(_AHN6|@mF>5s1>6_K)dC^XvgP9*^9TI^FJbwZ+-w0xJ6)}_F z%0d4Y7eH`kIejTb&ZKWd2Rs9reYUc=@_Z>K`8hu-4@4x;2}hR}_WGcLn#5>X?tQ4ysEyeqowUv>=;{0e^9Y~qca}dP?92* z@vA3vD4(ef(z85wN21@_3IT?GJm?epi~Ok+?4#Pc&`Mxu(_V-RE;4=C?k(ZvG+&az zvOzM=1b)rJ33GJ^OChdxG1@(Nyp9Fxowkie|VFAo0l?k1ro5_TK9c^eyGsE1EdF zuN%Bu@qMiMHBo_8eIxVu$OYrX18Rztr2yY-=q^|@g{LS<+y1ZBb5`>i(ie~CX5(mb zkrY|I4h^*B?QED9+1-(;143Qn)^1w+TwrDZUDaSf^ETS9^><-GIk+mW;nd<*0yD4uGsZ7K)#^-exjTEIrHwrcFpl0`sc1;$h(MGiG5>}`=HW54HE zKRZ1UgE^%ElFTBqMq37#HtwG(ZxlmD2QQoYMlXfERNE%+G3C^@K*(zWGTaxS&NxVn z7`Wd$4+r)h1&=gFnD~Z;O@EG5T$GQ{rnAL@zAW#l2epnAn7D@77B8qt6l=F^_b`R42#5x);0z*k^C=e{E%Xr&ku2?8YosLpkkd%5_V?^CCa3P zs?km+8CfI0`Js4RN3HWi=3Rm3bBWVIa|3<+_^u(Quug{2M|rE9FMW;oB9(s37{S)5{M> z<<$(rkm84zZw~8Xc}_H_J-i6^_}c0ySMB2eb_*i|q$;Nns;c1l@p@)&fXbZ;`YekX zLCpLAQ0@ll!ZO@>YrA`o&-HN6udHTtVxOfqJqG}v`FsYZyL&L!-(9wn)R%2)EhG=w zZ5fQGBs2~h>&o9OBo6QGiP!QX!gH{$D_w;}!y-vuSZ(LtlFy0*U{C zB_$8y`Y@0dj)$P9euGyi0YnD~E7}9XOQQNseGKE++#iAW(Nu4x+s-f8yPT09*sdK# zg6Xf(_W(cowMo;CXq>=g^=_|Ecc@=UYszI0z%&`>c^pLuNP&#XOH}B18Y#C?I15AL z|F)nk`U$z^en?1yD3Kgi%ubN748*1sN6~GN>>$sbdL=wpV<|d&wq8lrUQgn%$KjBY zWCE)TkPZXGSU&BjaI$pRjcSW*Pul;syCrAkXjfxb1uUZ~OR0Kfc7RS!m#lPB$iy>5 zi(Q4U@a18vN+v;R%v0C@hu?H{+<>R6Km#H6L~h-s20{C=OC^7hz0vr`OpJpl9YmE$ z7D(}Jjp|b$jwd&I zVAPpIfy~GrD69t{3O2NG7oE`55<#jb7NeQj{C_Det~kejavM*j7qz79jAGLTH zB9-qgu+c}$?%6eCc2rWM-6GlikG0)Q9wQG@MN$ENr37}LGs9>i;$0xI?k&VGr>k2_ zM(LeaUC!wWVcZz`Q7xirQLYQhec(ANOtEt^Qe9Zrq*dP}A{mAKzjV%L;7;+(@wpaW zi`Q&c+IY3}1lq2(;d|w*cF6_SnP_pp8(Rg-CG}SN5C$Yus&c%#*(3R$c_X3xJ|6kP z0)3g@ZOicSoB7}tTWAo<7&Oj6|JF2c@-Z!by{FAIsnCDZa_y^}eM;52{vN?|7P!oZ zJ-X_tXa*3Q!wv&=bPXk9a(%zj4S}tF!VlX|`2oeO!OR zDg%e$R`E{u5+r@pzs6v+m`C%87n4MQvR*IZ%4woK@bE{CrGMhoU~)}Y9#~0AS0Bcz zK#!_BC=7xjOP`}q0NQJ$Acb!yXdveKebb=3kyUQRx`tbfdzb`qgZyIlauzd+3l`Q% zNMkh0_y^jFe+~OTaMaa-{|JEtW$AJkew1rb=m(zf^lCiGIJ5l!2v!n&WDAR35df>N zTS0&@V&Ms7-h0qNVRw#j zZy4%FW?WwO%@pw)^{cL~I-%l+)?n7G;CaNSJ($CvJju+aJ;Gj$8*BR|aJ3eq(E5z|e3z=%RK{(KuS043{Hx2ATPP0<-Ek$q=TO`N+p}HW=*Xl=B9>-Sj zHrDTZP})=44LShDA_DmVPFHm~lPW^odOb0IE zGoj>8;tnBkz%~X;IPKg<8NX;r@h8fZQSHGm8$JdH>5J{{fzTp@L(WGp5}X+2h0 z`Xsj?vj>b`ao+EX)R7>a3B%}kl(TR>=8n^;kTp)VY!2;SlltlhrG~1?-DjU4_w1dhkr78!r$I*tnlqV z7|{_nCtsV@8Dw5ce`W@;B%KBa$P&J!;1-5u%^PJj`3>d??XXVGeW*0u z6NPl?R#V;%mgcBuxukxrSr<(AYLs$A=C*tpGp@jHFACCbppAIj4Dc9#nr{#ad<59| zIuE$VgAX{LkKZ%@W_7SrB5`1l-)W%}Rx0v68j7pAKL=Zfiv1&`UDGAh;~6a(UdW)k zKOXj1A(1NdDnW9e(j#coreBj|4(rvi_f4K;v-)^t*(x+#1sz=`>8a7jUZs)X@^j z?Sb&uy#On^RBnZ*k@YxvAvf_8Tj&1(+ipUGLtD?antwuh9_SeCj1`=DK_1IzpJRjA zHsd%NR`3TKf`_-)k2qe(x~xju7NiLYxi(PW@ml~^7BXp_a(XDHFk}W+P!0Dc5+if% zWV{~Tq_E?tqa`Nt+2W#U-#%2~y#>WRhW!L7xInUJdTR++nI0`pe))dejx2EHh2NMG zu*N;@T^tM4TT%^w@K9e`FnB_YV!ov_j8?bNnNSu-_)X&n&V;^g%tE>tkH0#(P!mPo zB{L=%1AiX#yi!lJ9|bSGF1ZG)`Ar#?HS^fS%`I>f0Pw0+(Q5+`Ha{kcoh935ry^?G zIJ|$pEP>kt{kw6%{WjNS=OkO2xSLG^Y4}D8?|~<8r%VB zBG&q|`=WEi2Sk}ALR@A0klZA#CahoP(<}v|#*WLIypVZbA*OEZY|mg^@U?7F1l|rNPB-iXiLh9z>Buea z_dYTWN4%qsu=4R^OIsJ;#3s5DYa9W&;HE-%z%CBU@4qD$a_psbkY4^XoW1)N)9p%%KWyk738qTYaW3p5dgA$uX*2ey|hX|)d`NtJSA zVF@fNe79(6UIrEOdWxMZ`kRA-PfteihO$GAziL@CB@I`Zv8Hq*am!D{)XP_s^e7`B~}H*dTnX&YjGjiLx+=YE|lX zHQ{|zj|{C{n3ocGTbmtVbv3$_*OarX!q51gNMXkh-XxaC9^hRpJ^aGx^9O?fQ#Dwt zh5FimU_@qE>KLZ8aNOo4gRZ@-tMESHtY@3IQLxOKSaQURw}dSdz~M)OB)F?VnE*U0 z96%(gI1_8QFcp=VIvg?PB$&uJjNr3} zj@=0uUU*SM1Ool(YpF>XND(hcgGWcqIFb)l9ATT^6VW@?@l5>4W zZ>F>Z?vuvHBeiD0nL6}rC+t?BF+QeQ;dwBG0!Nj?K~8n3V!gnKZIZtOa8`wue*6SW zviRFz)G{8EqU3VvVYqwkGz@)XhK-<_77M2zuGC!jLc{He+sStL1zok920(YA11h_6 z2_DY_EU;Aoc2R%J*5xl@J!(H}H2Sq|4=)MXI*?N5Zw{wrRE($5g^PQjbVGkiu9;6q zu;d6)G=h!$`%j{IE$q#3cX{qFYC|&VlAr$!TFXe>`k@!_6-7Gtsp>z*n)54b6t~Bv zYBFeE8YAW4SFiRw@rqWCC|!PfYJfpBT**Da9{~1dp9E_!dh!XPztIsfX;G2daxIeX zmz8S*l6{$X^Z#;A|6EQ#A4srsx^>yj1WTBui!mQ#93YK^`c8D`8t?LJ#I-XAj7l4W z65?$HTe~(>h6oVpbH>nFIrE0y%+U5<@4J*KQ*#1K$D>sKM{M&$g2(71*$v}mmh7-n z^7=sbc$r3mYvL2K@>xBWJTIWo00(q{c?#5$Es*=hGVnO9;X!tj9S#O6M)=?4gK>a7 zy<3;>S~NWfeZMm+gzm|+H@5M*%U9hIcU1N6 z^btXKy&*cWH%>jA-@oM(RFuYc5!YIh-Ys)W;qLzi{5#nIU^?AZHGG0-2aG;~P2u25 z&uRS&r!4ys9qj;%$q{c}?2G-%EUBgd?B47_N`x*W(-!HQ#Z^s{rI+@~WWWS*n1CCg z?D}AEU7h$VCSz!Ax>KRz2H_@@e0?nApkCje>CF4&EM-{jN~mTMzb4psNK&kukl@9v8c3DY%$58^T7n0ClzCB~6n*NVP^8Hr3^~pqAvYzZc?eI2UO`|z5^+T_YT;EMZgX&bwuc%0N zsnZVdSP7T!t}SQq5i1rok03<_Ve>$GNn5XA?%xr(NMxgu&yS1GWp_;+pQjKCALhd! z4~Zxmb+!UqthXq4m;(genlz6pQ-8#pa!Uq*^-ZBg^&Di)EgdX#Ai~zdh_pabT{Bs( z1_HM|e@vqw4T{F!M16+p`N}gU)wf=%FO%fgff)#6XTg#yx9djL?3CkmZJ|)bCu{5h zz@o@Y*sR!c9Xo#YI!+fvHcQH;UdD8Q9xFcXQnV5lr@f3lZtjfO28G(G?Zj%7;ps~{ z$^J9)4NpPJZNSXm^|wQpR^_z*pW=F~G`$bR@wBNAIJUuzNzrMgF%dUhDG<~abcdH1=WqD4jIH&So?hDDgRm>(Q-ER<)J#DFb1?M1fYq3LA0GXQ zcG>E6GY`V&x}O*aOmpc-~}K2z}0%LyOs<;=SmB=IzxfC2Cb0nNx?T&)%;Bh?>F zgZz95Df`XDg@gv$+z0~Dr7b`?DeiOPm5BGdq@S8u@t#UYke2XtA*(=9!cWlGor%?P zF}5&(u06+t+pKhsCW&Ao3^m3SoRtK`gy$UPY0G??EiI{CeW0hIF*_`Lm5oHs?*2AR z1jLZM=3IMRXYMm#slc2x4DtZDq;LfdkzHXL{-#8s+9sChpOu@i#VDr=KtmpxeWatp z*5Gvr)2P^Zf2)0+9pIfWL3RlH`r~TBxl*C3XBwhRdv7x{6s*dU){%g-5D(~54Lwk<`-@!??(Z{Lv@sxO@Z7kx?} z3KK1&tt!_h9+kvdqxB$ey5z3)aAcU~IRombAgXImQ2-xofrOBrQ2q2!a}-JN*$Y>@~F0u@M0 z_t}e3-Q$D+KI!|qSHa4w`H-qLKfjuzM82`)S=8}~vxGt8QSrPrA$f+hkZ+_s`1;@G zulMeS$}*k{Ldx`D?RO9tt^Yl~Kn(Wx8)8vW2JtmQmcB)c@et;^Lw?2))byI~f-p?} z_J;4hVQD7_Z7&Q|uEF*z8B&%5_ce%`HRg6TCR!!QT8<2snr|MJ>a2;b&LvE;*t_71 s_Sy+{An_^L*Qbd0DMs*_fFEN)%u3nS3!R@JrnrOXXDHeQgilF&;>e+F8vp Date: Tue, 14 Nov 2023 16:09:16 +0530 Subject: [PATCH 23/26] feat(connector): [BANKOFAMERICA] Add Auth Reversal --- crates/router/src/connector/bankofamerica.rs | 20 +++++++++- .../connector/bankofamerica/transformers.rs | 37 +++++++++++++++++-- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index a77d865ae89b..e42d87e44221 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -549,7 +549,7 @@ impl ConnectorIntegration CustomResult { let connector_payment_id = req.request.connector_transaction_id.clone(); Ok(format!( - "{}pts/v2/payments/{connector_payment_id}/voids", + "{}pts/v2/payments/{connector_payment_id}/reversals", self.base_url(connectors) )) } @@ -563,7 +563,23 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let connector_request = bankofamerica::BankOfAmericaVoidRequest::try_from(req)?; + let connector_router_data = bankofamerica::BankOfAmericaRouterData::try_from(( + &self.get_currency_unit(), + req.request + .currency + .ok_or(errors::ConnectorError::MissingRequiredField { + field_name: "Currency", + })?, + req.request + .amount + .ok_or(errors::ConnectorError::MissingRequiredField { + field_name: "Amount", + })?, + req, + ))?; + let connector_request = + bankofamerica::BankOfAmericaVoidRequest::try_from(&connector_router_data)?; + let bankofamerica_void_request = types::RequestBody::log_and_get_request_body( &connector_request, utils::Encode::::encode_to_string_of_json, diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index c91777a1ee8e..7cc191d96847 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -547,16 +547,47 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsCaptureRouterData>> } #[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] pub struct BankOfAmericaVoidRequest { client_reference_information: ClientReferenceInformation, + reversal_information: ReversalInformation, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ReversalInformation { + amount_details: Amount, + reason: String, } -impl TryFrom<&types::PaymentsCancelRouterData> for BankOfAmericaVoidRequest { +impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsCancelRouterData>> + for BankOfAmericaVoidRequest +{ type Error = error_stack::Report; - fn try_from(value: &types::PaymentsCancelRouterData) -> Result { + fn try_from( + value: &BankOfAmericaRouterData<&types::PaymentsCancelRouterData>, + ) -> Result { Ok(Self { client_reference_information: ClientReferenceInformation { - code: Some(value.connector_request_reference_id.clone()), + code: Some(value.router_data.connector_request_reference_id.clone()), + }, + reversal_information: ReversalInformation { + amount_details: Amount { + total_amount: value.amount.to_owned(), + currency: value.router_data.request.currency.ok_or( + errors::ConnectorError::MissingRequiredField { + field_name: "Currency", + }, + )?, + }, + reason: value + .router_data + .request + .cancellation_reason + .clone() + .ok_or(errors::ConnectorError::MissingRequiredField { + field_name: "Cancellation Reason", + })?, }, }) } From 24bd5fa711d9b7c3aec4f5d4c4e476368cb68ec0 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Tue, 14 Nov 2023 16:26:55 +0530 Subject: [PATCH 24/26] feat(connector): [BANKOFAMERICA] Clippy Check --- crates/router/src/connector/bankofamerica/transformers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 7cc191d96847..d6859ccd11ef 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -173,7 +173,7 @@ impl From for String { CardIssuer::CarteBlanche => "006", CardIssuer::JCB => "007", }; - return card_type.to_string(); + card_type.to_string() } } From 770c09505235d3f79ebb69494f1b25470342cd98 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 16 Nov 2023 13:48:40 +0530 Subject: [PATCH 25/26] feat(connector): [BANKOFAMERICA] Add enum BankOfAmericaPaymentsResponse --- .../connector/bankofamerica/transformers.rs | 181 +++++++++++------- 1 file changed, 109 insertions(+), 72 deletions(-) diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index d6859ccd11ef..fe37dea785c1 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -294,11 +294,24 @@ impl ForeignFrom<(BankofamericaPaymentStatus, bool)> for enums::AttemptStatus { } #[derive(Debug, Deserialize)] -pub struct BankOfAmericaPaymentsResponse { +#[serde(untagged)] +pub enum BankOfAmericaPaymentsResponse { + ClientReferenceInformation(BankOfAmericaClientReferenceResponse), + ErrorInformation(BankOfAmericaErrorInformationResponse), +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BankOfAmericaClientReferenceResponse { id: String, status: BankofamericaPaymentStatus, - error_information: Option, - client_reference_information: Option, + client_reference_information: ClientReferenceInformation, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BankOfAmericaErrorInformationResponse { + error_information: BankOfAmericaErrorInformation, } #[derive(Debug, Deserialize)] @@ -326,36 +339,40 @@ impl types::PaymentsResponseData, >, ) -> Result { - Ok(Self { - status: enums::AttemptStatus::foreign_from(( - item.response.status, - item.data.request.is_auto_capture()?, - )), - response: match item.response.error_information { - Some(error) => Err(types::ErrorResponse { - code: consts::NO_ERROR_CODE.to_string(), - message: error.message, - reason: Some(error.reason), - status_code: item.http_code, - attempt_status: None, - }), - _ => Ok(types::PaymentsResponseData::TransactionResponse { + match item.response { + BankOfAmericaPaymentsResponse::ClientReferenceInformation(info_response) => Ok(Self { + status: enums::AttemptStatus::foreign_from(( + info_response.status, + item.data.request.is_auto_capture()?, + )), + response: Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( - item.response.id.clone(), + info_response.id.clone(), ), redirection_data: None, mandate_reference: None, connector_metadata: None, network_txn_id: None, - connector_response_reference_id: item - .response - .client_reference_information - .map(|cref| cref.code) - .unwrap_or(Some(item.response.id)), + connector_response_reference_id: Some( + info_response + .client_reference_information + .code + .unwrap_or(info_response.id), + ), }), - }, - ..item.data - }) + ..item.data + }), + BankOfAmericaPaymentsResponse::ErrorInformation(error_response) => Ok(Self { + response: Err(types::ErrorResponse { + code: consts::NO_ERROR_CODE.to_string(), + message: error_response.error_information.message, + reason: Some(error_response.error_information.reason), + status_code: item.http_code, + attempt_status: None, + }), + ..item.data + }), + } } } @@ -378,33 +395,37 @@ impl types::PaymentsResponseData, >, ) -> Result { - Ok(Self { - status: enums::AttemptStatus::foreign_from((item.response.status, true)), - response: match item.response.error_information { - Some(error) => Err(types::ErrorResponse { - code: consts::NO_ERROR_CODE.to_string(), - message: error.message, - reason: Some(error.reason), - status_code: item.http_code, - attempt_status: None, - }), - _ => Ok(types::PaymentsResponseData::TransactionResponse { + match item.response { + BankOfAmericaPaymentsResponse::ClientReferenceInformation(info_response) => Ok(Self { + status: enums::AttemptStatus::foreign_from((info_response.status, true)), + response: Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( - item.response.id.clone(), + info_response.id.clone(), ), redirection_data: None, mandate_reference: None, connector_metadata: None, network_txn_id: None, - connector_response_reference_id: item - .response - .client_reference_information - .map(|cref| cref.code) - .unwrap_or(Some(item.response.id)), + connector_response_reference_id: Some( + info_response + .client_reference_information + .code + .unwrap_or(info_response.id), + ), }), - }, - ..item.data - }) + ..item.data + }), + BankOfAmericaPaymentsResponse::ErrorInformation(error_response) => Ok(Self { + response: Err(types::ErrorResponse { + code: consts::NO_ERROR_CODE.to_string(), + message: error_response.error_information.message, + reason: Some(error_response.error_information.reason), + status_code: item.http_code, + attempt_status: None, + }), + ..item.data + }), + } } } @@ -427,33 +448,37 @@ impl types::PaymentsResponseData, >, ) -> Result { - Ok(Self { - status: enums::AttemptStatus::foreign_from((item.response.status, false)), - response: match item.response.error_information { - Some(error) => Err(types::ErrorResponse { - code: consts::NO_ERROR_CODE.to_string(), - message: error.message, - reason: Some(error.reason), - status_code: item.http_code, - attempt_status: None, - }), - _ => Ok(types::PaymentsResponseData::TransactionResponse { + match item.response { + BankOfAmericaPaymentsResponse::ClientReferenceInformation(info_response) => Ok(Self { + status: enums::AttemptStatus::foreign_from((info_response.status, false)), + response: Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId( - item.response.id.clone(), + info_response.id.clone(), ), redirection_data: None, mandate_reference: None, connector_metadata: None, network_txn_id: None, - connector_response_reference_id: item - .response - .client_reference_information - .map(|cref| cref.code) - .unwrap_or(Some(item.response.id)), + connector_response_reference_id: Some( + info_response + .client_reference_information + .code + .unwrap_or(info_response.id), + ), }), - }, - ..item.data - }) + ..item.data + }), + BankOfAmericaPaymentsResponse::ErrorInformation(error_response) => Ok(Self { + response: Err(types::ErrorResponse { + code: consts::NO_ERROR_CODE.to_string(), + message: error_response.error_information.message, + reason: Some(error_response.error_information.reason), + status_code: item.http_code, + attempt_status: None, + }), + ..item.data + }), + } } } @@ -645,13 +670,25 @@ impl TryFrom, ) -> Result { - Ok(Self { - response: Ok(types::RefundsResponseData { - connector_refund_id: item.response.id, - refund_status: enums::RefundStatus::from(item.response.status), + match item.response { + BankOfAmericaPaymentsResponse::ClientReferenceInformation(info_response) => Ok(Self { + response: Ok(types::RefundsResponseData { + connector_refund_id: info_response.id, + refund_status: enums::RefundStatus::from(info_response.status), + }), + ..item.data }), - ..item.data - }) + BankOfAmericaPaymentsResponse::ErrorInformation(error_response) => Ok(Self { + response: Err(types::ErrorResponse { + code: consts::NO_ERROR_CODE.to_string(), + message: error_response.error_information.message, + reason: Some(error_response.error_information.reason), + status_code: item.http_code, + attempt_status: None, + }), + ..item.data + }), + } } } From 1beaaa8fc9d2224c2e77ed4fc61c0e88b78eb759 Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL Date: Thu, 16 Nov 2023 16:28:15 +0530 Subject: [PATCH 26/26] feat(connector): [BANKOFAMERICA] Resolve PR Comments --- crates/router/src/connector/bankofamerica.rs | 4 +- .../connector/bankofamerica/transformers.rs | 164 +++++++++++------- 2 files changed, 103 insertions(+), 65 deletions(-) diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index e42d87e44221..51a1d722dc51 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -701,7 +701,7 @@ impl ConnectorIntegration, res: Response, ) -> CustomResult, errors::ConnectorError> { - let response: bankofamerica::BankOfAmericaPaymentsResponse = res + let response: bankofamerica::BankOfAmericaRefundResponse = res .response .parse_struct("bankofamerica RefundResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -774,7 +774,7 @@ impl ConnectorIntegration CustomResult { - let response: bankofamerica::BankOfAmericaTransactionResponse = res + let response: bankofamerica::BankOfAmericaRsyncResponse = res .response .parse_struct("bankofamerica RefundSyncResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index fe37dea785c1..20b2af48b168 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -271,10 +271,17 @@ pub enum BankofamericaPaymentStatus { } impl ForeignFrom<(BankofamericaPaymentStatus, bool)> for enums::AttemptStatus { - fn foreign_from(item: (BankofamericaPaymentStatus, bool)) -> Self { - let status = match item.0 { - BankofamericaPaymentStatus::Authorized - | BankofamericaPaymentStatus::AuthorizedPendingReview => Self::Authorized, + fn foreign_from((status, auto_capture): (BankofamericaPaymentStatus, bool)) -> Self { + match status { + BankofamericaPaymentStatus::Authorized => { + if auto_capture { + // Because BankOfAmerica will return Payment Status as Authorized even in AutoCapture Payment + Self::Pending + } else { + Self::Authorized + } + } + BankofamericaPaymentStatus::AuthorizedPendingReview => Self::Authorized, BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { Self::Charged } @@ -285,11 +292,7 @@ impl ForeignFrom<(BankofamericaPaymentStatus, bool)> for enums::AttemptStatus { Self::Failure } BankofamericaPaymentStatus::Pending => Self::Pending, - }; - if item.1 && status == Self::Authorized { - return Self::Pending; } - status } } @@ -311,12 +314,13 @@ pub struct BankOfAmericaClientReferenceResponse { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BankOfAmericaErrorInformationResponse { + id: String, error_information: BankOfAmericaErrorInformation, } #[derive(Debug, Deserialize)] pub struct BankOfAmericaErrorInformation { - reason: String, + reason: Option, message: String, } @@ -366,7 +370,7 @@ impl response: Err(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), message: error_response.error_information.message, - reason: Some(error_response.error_information.reason), + reason: error_response.error_information.reason, status_code: item.http_code, attempt_status: None, }), @@ -419,7 +423,7 @@ impl response: Err(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), message: error_response.error_information.message, - reason: Some(error_response.error_information.reason), + reason: error_response.error_information.reason, status_code: item.http_code, attempt_status: None, }), @@ -472,7 +476,7 @@ impl response: Err(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), message: error_response.error_information.message, - reason: Some(error_response.error_information.reason), + reason: error_response.error_information.reason, status_code: item.http_code, attempt_status: None, }), @@ -482,9 +486,16 @@ impl } } +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum BankOfAmericaTransactionResponse { + ApplicationInformation(BankOfAmericaApplicationInfoResponse), + ErrorInformation(BankOfAmericaErrorInformationResponse), +} + #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct BankOfAmericaTransactionResponse { +pub struct BankOfAmericaApplicationInfoResponse { id: String, application_information: ApplicationInformation, client_reference_information: Option, @@ -515,25 +526,40 @@ impl types::PaymentsResponseData, >, ) -> Result { - Ok(Self { - status: enums::AttemptStatus::foreign_from(( - item.response.application_information.status, - item.data.request.is_auto_capture()?, - )), - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()), - redirection_data: None, - mandate_reference: None, - connector_metadata: None, - network_txn_id: None, - connector_response_reference_id: item - .response - .client_reference_information - .map(|cref| cref.code) - .unwrap_or(Some(item.response.id)), + match item.response { + BankOfAmericaTransactionResponse::ApplicationInformation(app_response) => Ok(Self { + status: enums::AttemptStatus::foreign_from(( + app_response.application_information.status, + item.data.request.is_auto_capture()?, + )), + response: Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::ConnectorTransactionId(app_response.id.clone()), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: app_response + .client_reference_information + .map(|cref| cref.code) + .unwrap_or(Some(app_response.id)), + }), + ..item.data }), - ..item.data - }) + BankOfAmericaTransactionResponse::ErrorInformation(error_response) => Ok(Self { + status: item.data.status, + response: Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::ConnectorTransactionId( + error_response.id.clone(), + ), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: Some(error_response.id), + }), + ..item.data + }), + } } } @@ -646,58 +672,70 @@ impl TryFrom<&BankOfAmericaRouterData<&types::RefundsRouterData>> } } -impl From for enums::RefundStatus { - fn from(item: BankofamericaPaymentStatus) -> Self { +impl From for enums::RefundStatus { + fn from(item: BankofamericaRefundStatus) -> Self { match item { - BankofamericaPaymentStatus::Succeeded | BankofamericaPaymentStatus::Transmitted => { + BankofamericaRefundStatus::Succeeded | BankofamericaRefundStatus::Transmitted => { Self::Success } - BankofamericaPaymentStatus::Failed => Self::Failure, - BankofamericaPaymentStatus::Authorized - | BankofamericaPaymentStatus::Voided - | BankofamericaPaymentStatus::Reversed - | BankofamericaPaymentStatus::Pending - | BankofamericaPaymentStatus::Declined - | BankofamericaPaymentStatus::AuthorizedPendingReview => Self::Pending, + BankofamericaRefundStatus::Failed => Self::Failure, + BankofamericaRefundStatus::Pending => Self::Pending, } } } -impl TryFrom> +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BankOfAmericaRefundResponse { + id: String, + status: BankofamericaRefundStatus, +} + +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { - match item.response { - BankOfAmericaPaymentsResponse::ClientReferenceInformation(info_response) => Ok(Self { - response: Ok(types::RefundsResponseData { - connector_refund_id: info_response.id, - refund_status: enums::RefundStatus::from(info_response.status), - }), - ..item.data - }), - BankOfAmericaPaymentsResponse::ErrorInformation(error_response) => Ok(Self { - response: Err(types::ErrorResponse { - code: consts::NO_ERROR_CODE.to_string(), - message: error_response.error_information.message, - reason: Some(error_response.error_information.reason), - status_code: item.http_code, - attempt_status: None, - }), - ..item.data + Ok(Self { + response: Ok(types::RefundsResponseData { + connector_refund_id: item.response.id, + refund_status: enums::RefundStatus::from(item.response.status), }), - } + ..item.data + }) } } -impl TryFrom> +#[derive(Debug, Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum BankofamericaRefundStatus { + Succeeded, + Transmitted, + Failed, + Pending, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RsyncApplicationInformation { + status: BankofamericaRefundStatus, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct BankOfAmericaRsyncResponse { + id: String, + application_information: RsyncApplicationInformation, +} + +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { Ok(Self { response: Ok(types::RefundsResponseData {