Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: separate DB queries and HTML creation for payout links #4967

Merged
merged 101 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
b23edb3
feat(collect_link): basic setup for collect_links - app structs / enu…
kashif-m Apr 18, 2024
cc48b06
wip: feat(collect_link): add render pm collect link flow
kashif-m Apr 21, 2024
dcfa4bb
feat(collect_link): add basic initiate + status + expiry templates
kashif-m Apr 22, 2024
58e5e78
feat(collect_link): store pm_collect_link_config in merchant account
kashif-m Apr 23, 2024
89277ce
refactor(collect_link): cargo hack fixes
kashif-m Apr 23, 2024
843c2c8
feat(collect_link): inject enabled_payment_methods
kashif-m Apr 30, 2024
a2daf17
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m Apr 30, 2024
97b40ed
refactor(collect_link): update styles
kashif-m May 2, 2024
7cc75ac
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m May 2, 2024
7057338
feat(collect_link): add widget options
kashif-m May 6, 2024
5bafcd1
feat(payment_methods): enable client secret auth for CREATE payment_m…
kashif-m May 8, 2024
e0f7fac
feat(collect_link): read enabled_payment_methods in /admin and collec…
kashif-m May 9, 2024
f02b526
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m May 23, 2024
6ce91c5
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m May 23, 2024
3913d46
add payout link support
srujanchikke Jun 3, 2024
84ab2d9
add confirm api
srujanchikke Jun 6, 2024
7411a56
remove comments
srujanchikke Jun 6, 2024
3bdffff
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m Jun 7, 2024
85da820
add slash to payout_link scope
Jun 10, 2024
51e7ad7
Merge branch 'pm_collect_link' of https://github.com/juspay/hyperswit…
srujanchikke Jun 10, 2024
acea448
Merge branch 'payout_link' of https://github.com/juspay/hyperswitch i…
srujanchikke Jun 10, 2024
ab5d140
resolve merge conflicts
srujanchikke Jun 11, 2024
8d1e34e
chore: run formatter
hyperswitch-bot[bot] Jun 11, 2024
f7a341a
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m Jun 11, 2024
26c9ecf
remove schema.rs
srujanchikke Jun 11, 2024
1dee131
Merge branch 'payout_link' of https://github.com/juspay/hyperswitch i…
srujanchikke Jun 11, 2024
38f94e8
resolve schema.rs file conflict
srujanchikke Jun 11, 2024
cf25247
refactor: add openapi changes
kashif-m Jun 11, 2024
7cec5c0
chore: run formatter
hyperswitch-bot[bot] Jun 11, 2024
f6cfde2
merge branch
srujanchikke Jun 11, 2024
3c9a3a2
clippy fix
srujanchikke Jun 11, 2024
6be0325
fix validate openapi spec
srujanchikke Jun 11, 2024
85e64dd
clippy fix
srujanchikke Jun 11, 2024
3791ebb
chore: run formatter
hyperswitch-bot[bot] Jun 11, 2024
cc0b09d
fix schema
srujanchikke Jun 12, 2024
762a24b
refactor: separate DB queries and HTML creation for payout links
kashif-m Jun 12, 2024
691082e
add enabled payout method in payout_link
srujanchikke Jun 13, 2024
52d8dd8
fix enabled payment methods
srujanchikke Jun 13, 2024
acbea09
make enabled payment methods optional for payout links
srujanchikke Jun 13, 2024
8b28952
chore: run formatter
hyperswitch-bot[bot] Jun 13, 2024
f7e52ea
open api check fix
srujanchikke Jun 13, 2024
9c9a3c6
open api fix
srujanchikke Jun 13, 2024
e5dc100
refactor: separate queries for payout links
kashif-m Jun 13, 2024
02c2763
openapi fix
srujanchikke Jun 13, 2024
f5b7cbf
ci check fix
srujanchikke Jun 13, 2024
dcb32db
chore: run formatter
hyperswitch-bot[bot] Jun 13, 2024
5d09e85
feat(payout_link): add expired and status pages
kashif-m Jun 13, 2024
073a5ce
Merge remote-tracking branch 'origin/main' into payout_link_ref
kashif-m Jun 13, 2024
d1507c7
ci check fix
srujanchikke Jun 14, 2024
ead64a9
Merge branch 'payout_link' of github.com:juspay/hyperswitch into payo…
srujanchikke Jun 14, 2024
6e0d116
chore: run formatter
hyperswitch-bot[bot] Jun 14, 2024
13e011b
minor refactor
srujanchikke Jun 14, 2024
b616451
Merge branch 'payout_link' of github.com:juspay/hyperswitch into payo…
srujanchikke Jun 14, 2024
cb10520
refactor: cargo fix
kashif-m Jun 14, 2024
eef38fa
Merge remote-tracking branch 'origin/payout_link' into payout_link_ref
kashif-m Jun 14, 2024
bc1dd6d
chore: run formatter
hyperswitch-bot[bot] Jun 14, 2024
571824b
refactor: re-generate openAPI spec
kashif-m Jun 14, 2024
3d9f1ad
Merge branch 'main' into pm_collect_link
kashif-m Jun 19, 2024
1d8af46
Merge branch 'pm_collect_link' into payout_link
kashif-m Jun 19, 2024
fd7c412
Merge remote-tracking branch 'origin/payout_link' into payout_link_ref
kashif-m Jun 19, 2024
4e06034
resolve comments
srujanchikke Jun 19, 2024
b218946
chore: run formatter
hyperswitch-bot[bot] Jun 19, 2024
0b0dfd1
refactor(generic_links): move payout_link_config to business_profile
kashif-m Jun 19, 2024
aabf12b
refactor: inject flow type for pm_collect_link
kashif-m Jun 19, 2024
d668130
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] Jun 19, 2024
4e5ac76
resolve comments
Jun 20, 2024
a41ee95
remove unnecessary logs
Jun 20, 2024
026ad06
chore: run formatter
hyperswitch-bot[bot] Jun 20, 2024
b9dcceb
clippy fix
Jun 20, 2024
00bc65e
refactor(payout_links): map domain name to the payout link and add a …
kashif-m Jun 21, 2024
2ee89eb
Merge remote-tracking branch 'origin/main' into payout_link_ref
kashif-m Jun 23, 2024
a939970
refactor: missing import
kashif-m Jun 23, 2024
b889d33
refactor: clippy fix
kashif-m Jun 23, 2024
9c7258e
update payouts in confirm
Jun 24, 2024
982d4b5
chore: run formatter
hyperswitch-bot[bot] Jun 24, 2024
0eb0136
update payout_type in PayoutUpdate
Jun 24, 2024
e958839
refactor: revert client_secret auth in POST /payment_methods
kashif-m Jun 24, 2024
de2434a
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m Jun 24, 2024
ba9880d
refactor: missing import
kashif-m Jun 24, 2024
f3f1bfc
Merge remote-tracking branch 'origin/pm_collect_link' into payout_link
kashif-m Jun 24, 2024
a285679
Merge remote-tracking branch 'origin/payout_link' into payout_link_ref
kashif-m Jun 24, 2024
2c62a96
refactor: clippy fixes
kashif-m Jun 24, 2024
4717b07
Merge remote-tracking branch 'origin/pm_collect_link' into payout_link
kashif-m Jun 24, 2024
8bc98ef
refactor: revert payouts insert query
kashif-m Jun 24, 2024
e3da8fc
refactor: add default env configs in docker_compose.toml and update m…
kashif-m Jun 24, 2024
ce0f155
feat: attach payout_id to Payout events
kashif-m Jun 24, 2024
4c5496b
Merge remote-tracking branch 'origin/main' into pm_collect_link
kashif-m Jun 24, 2024
1797a83
Merge remote-tracking branch 'origin/main' into payout_link_ref
kashif-m Jun 24, 2024
6a47a27
clippy fix
Jun 24, 2024
d0543e7
Merge branch 'pm_collect_link' into payout_link
srujanchikke Jun 24, 2024
d301039
refactor: resolve comments
kashif-m Jun 24, 2024
e62b354
Merge remote-tracking branch 'origin/payout_link' into payout_link_ref
kashif-m Jun 24, 2024
1602734
refactor: clippy fixes
kashif-m Jun 24, 2024
baca310
refactor: clippy fixes
kashif-m Jun 24, 2024
21ebf13
refactor: resolve comments
kashif-m Jun 25, 2024
5a65b3d
refactor: migration update
kashif-m Jun 25, 2024
6c35e7e
refactor: add comments
kashif-m Jun 25, 2024
cedb025
chore: missing validations
kashif-m Jun 25, 2024
91c269b
refactor: update generic link_status
kashif-m Jun 25, 2024
6a34bb7
chore: comments
kashif-m Jun 25, 2024
d99c3f7
chore: updated env configs
kashif-m Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add payout link support
  • Loading branch information
srujanchikke committed Jun 3, 2024
commit 3913d46f6e051b9a465c2a83fcfb06b471dab0b9
36 changes: 36 additions & 0 deletions crates/api_models/src/payouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,33 @@ pub struct PayoutCreateRequest {
/// The business profile to use for this payment, if not passed the default business profile
/// associated with the merchant account will be used.
pub profile_id: Option<String>,

/// Whether to get the payment link (if applicable)
#[schema(default = false, example = true)]
pub payout_link: Option<bool>,

/// custom payment link config for the particular payment
#[schema(value_type = Option<PayoutCreatePayoutLinkConfig>)]
pub payout_link_config: Option<PayoutCreatePayoutLinkConfig>,
}

#[derive(Default, Debug, Deserialize, Serialize, Clone, ToSchema)]
pub struct PayoutCreatePayoutLinkConfig {
/// The unique identifier for the collect link.
#[schema(value_type = Option<String>, example = "pm_collect_link_2bdacf398vwzq5n422S1")]
pub payout_link_id: Option<String>,

#[serde(flatten)]
pub ui_config: Option<api_enums::CollectLinkConfig>,
kashif-m marked this conversation as resolved.
Show resolved Hide resolved

/// Will be used to expire client secret after certain amount of time to be supplied in seconds
/// (900) for 15 mins
#[schema(value_type = Option<u32>, example = 900)]
pub session_expiry: Option<u32>,
kashif-m marked this conversation as resolved.
Show resolved Hide resolved

/// List of payment methods shown on collect UI
#[schema(value_type = Option<Vec<EnabledPaymentMethod>>, example = r#"[{"payment_method": "bank_transfer", "payment_method_types": ["ach", "bacs"]}]"#)]
pub enabled_payment_methods: Option<Vec<api_enums::EnabledPaymentMethod>>,
}

#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
Expand Down Expand Up @@ -445,6 +472,9 @@ pub struct PayoutCreateResponse {
#[schema(value_type = Option<Vec<PayoutAttemptResponse>>)]
#[serde(skip_serializing_if = "Option::is_none")]
pub attempts: Option<Vec<PayoutAttemptResponse>>,

// If payout link is request, this represents response on
pub payout_link: Option<PayoutLinkResponse>,
}

#[derive(
Expand Down Expand Up @@ -652,3 +682,9 @@ pub struct PayoutListFilters {
/// The list of available payment method filters
pub payout_method: Vec<common_enums::PayoutType>,
}

#[derive(Clone, Debug, serde::Serialize, ToSchema)]
pub struct PayoutLinkResponse {
pub link: Secret<String>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this can also be a URL?

pub payout_link_id: String,
}
2 changes: 2 additions & 0 deletions crates/diesel_models/src/payouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct Payouts {
pub profile_id: String,
pub status: storage_enums::PayoutStatus,
pub confirm: Option<bool>,
pub payout_link_id: Option<String>,
}

#[derive(
Expand Down Expand Up @@ -72,6 +73,7 @@ pub struct PayoutsNew {
pub profile_id: String,
pub status: storage_enums::PayoutStatus,
pub confirm: Option<bool>,
pub payout_link_id: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
2 changes: 2 additions & 0 deletions crates/diesel_models/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,8 @@ diesel::table! {
profile_id -> Varchar,
status -> PayoutStatus,
confirm -> Nullable<Bool>,
#[max_length = 255]
payout_link_id -> Nullable<Varchar>,
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/hyperswitch_domain_models/src/payouts/payouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub struct Payouts {
pub profile_id: String,
pub status: storage_enums::PayoutStatus,
pub confirm: Option<bool>,
pub payout_link_id: Option<String>,
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand All @@ -115,6 +116,7 @@ pub struct PayoutsNew {
pub profile_id: String,
pub status: storage_enums::PayoutStatus,
pub confirm: Option<bool>,
pub payout_link_id: Option<String>,
}

impl Default for PayoutsNew {
Expand Down Expand Up @@ -143,6 +145,7 @@ impl Default for PayoutsNew {
profile_id: String::default(),
status: storage_enums::PayoutStatus::default(),
confirm: None,
payout_link_id: Option::default(),
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions crates/router/src/core/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,13 @@ pub async fn initiate_pm_collect_link(
.await?;

// Create DB entries
let pm_collect_link =
create_pm_collect_db_entry(&state, &merchant_account, &pm_collect_link_data, &req).await?;
let pm_collect_link = create_pm_collect_db_entry(
&state,
&merchant_account,
&pm_collect_link_data,
req.return_url.clone(),
)
.await?;

// Return response
let response = payment_methods::PaymentMethodCollectLinkResponse {
Expand All @@ -141,7 +146,7 @@ pub async fn create_pm_collect_db_entry(
state: &AppState,
merchant_account: &domain::MerchantAccount,
pm_collect_link_data: &PaymentMethodCollectLinkData,
req: &payment_methods::PaymentMethodCollectLinkRequest,
return_url: Option<String>,
) -> RouterResult<PaymentMethodCollectLink> {
let db: &dyn StorageInterface = &*state.store;

Expand All @@ -156,7 +161,7 @@ pub async fn create_pm_collect_db_entry(
link_type: common_enums::GenericLinkType::PaymentMethodCollect,
link_data,
url: pm_collect_link_data.link.clone(),
return_url: req.return_url.clone(),
return_url,
expiry: common_utils::date_time::now()
+ Duration::seconds(pm_collect_link_data.session_expiry.into()),
..Default::default()
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/core/payments/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,7 @@ impl ForeignFrom<(storage::Payouts, storage::PayoutAttempt, domain::Customer)>
attempts: Some(attempts),
billing: None,
client_secret: None,
payout_link: None
}
}
}
Expand Down
38 changes: 36 additions & 2 deletions crates/router/src/core/payouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod retry;
pub mod validator;
use std::vec::IntoIter;

use api_models::enums as api_enums;
use api_models::{self, enums as api_enums, payouts::PayoutLinkResponse};
use common_utils::{consts, crypto::Encryptable, ext_traits::ValueExt, pii, types::MinorUnit};
use diesel_models::enums as storage_enums;
use error_stack::{report, ResultExt};
Expand Down Expand Up @@ -57,6 +57,7 @@ pub struct PayoutData {
pub payout_method_data: Option<payouts::PayoutMethodData>,
pub profile_id: String,
pub should_terminate: bool,
pub payout_link_data: Option<PayoutLinkResponse>,
}

// ********************************************** CORE FLOWS **********************************************
Expand Down Expand Up @@ -1890,6 +1891,7 @@ pub async fn response_handler(
profile_id: payout_attempt.profile_id,
created: Some(payouts.created_at),
attempts: None,
payout_link: payout_data.payout_link_data.to_owned(),
};
Ok(services::ApplicationResponse::Json(response))
}
Expand Down Expand Up @@ -1931,7 +1933,36 @@ pub async fn payout_create_db_entries(
})
})?
.customer_id;
let payout_link = if let Some(payout_link_create) = req.payout_link {
if payout_link_create {
let payout_link_config = req.payout_link_config.as_ref().ok_or_else(|| {
report!(errors::ApiErrorResponse::MissingRequiredField {
field_name: "payout_link_config",
})
})?;
validator::intiate_payout_link(
state,
merchant_account,
payout_link_config,
&customer_id,
req.return_url.to_owned(),
)
.await?
} else {
None
}
} else {
None
};

let payout_link_data = payout_link.as_ref().map(|link_data| PayoutLinkResponse {
link: link_data.link.clone(),
payout_link_id: link_data.pm_collect_link_id.clone(),
});

let payout_link_id = payout_link_data
.clone()
.map(|link_data| link_data.payout_link_id);
// Get or create address
let billing_address = payment_helpers::create_or_find_address_for_payment_by_request(
db,
Expand Down Expand Up @@ -1985,6 +2016,7 @@ pub async fn payout_create_db_entries(
attempt_count: 1,
metadata: req.metadata.clone(),
confirm: req.confirm,
payout_link_id: payout_link_id.clone(),
..Default::default()
};
let payouts = db
Expand All @@ -1994,7 +2026,7 @@ pub async fn payout_create_db_entries(
payout_id: payout_id.to_owned(),
})
.attach_printable("Error inserting payouts in db")?;

logger::debug!("{:?}", payout_link_id.clone());
// Make payout_attempt entry
let status = if req.payout_method_data.is_some()
|| req.payout_token.is_some()
Expand Down Expand Up @@ -2050,6 +2082,7 @@ pub async fn payout_create_db_entries(
.or(stored_payout_method_data.cloned()),
should_terminate: false,
profile_id: profile_id.to_owned(),
payout_link_data,
})
}

Expand Down Expand Up @@ -2125,6 +2158,7 @@ pub async fn make_payout_data(
merchant_connector_account: None,
should_terminate: false,
profile_id,
payout_link_data: None, // Should be changed
})
}

Expand Down
124 changes: 124 additions & 0 deletions crates/router/src/core/payouts/validator.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
use api_models::admin;
#[cfg(feature = "olap")]
use common_utils::errors::CustomResult;
use common_utils::ext_traits::ValueExt;
use diesel_models::{enums::CollectLinkConfig, generic_link::PaymentMethodCollectLinkData};
use error_stack::{report, ResultExt};
pub use hyperswitch_domain_models::errors::StorageError;
use masking::Secret;
use router_env::{instrument, tracing};

use super::helpers;
use crate::{
consts,
core::{
errors::{self, RouterResult},
payment_methods::create_pm_collect_db_entry,
utils as core_utils,
},
db::StorageInterface,
Expand Down Expand Up @@ -52,6 +58,12 @@ pub async fn validate_create_request(
) -> RouterResult<(String, Option<payouts::PayoutMethodData>, String)> {
let merchant_id = &merchant_account.merchant_id;

if let Some(payout_link) = &req.payout_link {
if *payout_link {
validate_payout_link_request(req.confirm)?;
}
};

// Merchant ID
let predicate = req.merchant_id.as_ref().map(|mid| mid != merchant_id);
utils::when(predicate.unwrap_or(false), || {
Expand Down Expand Up @@ -119,6 +131,19 @@ pub async fn validate_create_request(
Ok((payout_id, payout_method_data, profile_id))
}

pub fn validate_payout_link_request(confirm: Option<bool>) -> Result<(), errors::ApiErrorResponse> {
if let Some(cnf) = confirm {
if !cnf {
return Ok(());
} else {
return Err(errors::ApiErrorResponse::InvalidRequestData {
message: "cannot confirm a payout while creating a payout link".to_string(),
});
}
}
kashif-m marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
}

#[cfg(feature = "olap")]
pub(super) fn validate_payout_list_request(
req: &payouts::PayoutListConstraints,
Expand Down Expand Up @@ -155,3 +180,102 @@ pub(super) fn validate_payout_list_request_for_joins(
})?;
Ok(())
}

pub async fn intiate_payout_link(
state: &AppState,
merchant_account: &domain::MerchantAccount,
req: &api_models::payouts::PayoutCreatePayoutLinkConfig,
customer_id: &String,
return_url: Option<String>,
) -> RouterResult<Option<PaymentMethodCollectLinkData>> {
// Create payment method collect link ID
let payout_link_id =
core_utils::get_or_generate_id("payout_link_id", &req.payout_link_id, "payout_link")?;

// Fetch all configs
let default_config = &state.conf.generic_link.payment_method_collect;
let merchant_config = merchant_account
.pm_collect_link_config
.clone()
.map(|config| {
config.parse_value::<admin::MerchantCollectLinkConfig>("MerchantCollectLinkConfig")
})
.transpose()
.change_context(errors::ApiErrorResponse::InvalidDataValue {
field_name: "pm_collect_link_config in merchant_account",
})?;
let ui_config = &req.ui_config;
// Create client secret
let client_secret = utils::generate_id(consts::ID_LENGTH, "payout_link_secret");

let fallback_ui_config = match &merchant_account.pm_collect_link_config {
Some(config) => {
config
.clone()
.parse_value::<admin::MerchantCollectLinkConfig>("MerchantCollectLinkConfig")
.change_context(errors::ApiErrorResponse::InvalidDataValue {
field_name: "pm_collect_link_config in merchant_account",
})?
.ui_config
}
None => default_config.ui_config.clone(),
};

// Form data to be injected in HTML
let sdk_host = default_config.sdk_url.clone();

let domain = merchant_config
.clone()
.and_then(|c| c.domain_name.clone())
.unwrap_or_else(|| state.conf.server.base_url.clone());

let (collector_name, logo, theme) = match ui_config {
Some(config) => (
config.collector_name.clone(),
config.logo.clone(),
config.theme.clone(),
),
None => (
fallback_ui_config.collector_name.clone(),
fallback_ui_config.logo.clone(),
fallback_ui_config.theme.clone(),
),
};

let session_expiry = match req.session_expiry {
Some(expiry) => expiry,
None => default_config.expiry,
};
let merchant_id = merchant_account.merchant_id.clone();
let link = Secret::new(format!(
"{domain}/payout_link/initiate/{merchant_id}/{payout_link_id}"
));

let payout_link_config = CollectLinkConfig {
theme,
logo,
collector_name,
};

let enabled_payment_methods = match (&req.enabled_payment_methods, &merchant_config) {
(Some(enabled_payment_methods), _) => enabled_payment_methods.clone(),
(None, Some(config)) => config.enabled_payment_methods.clone(),
_ => default_config.enabled_payment_methods.clone(),
};

let data = PaymentMethodCollectLinkData {
pm_collect_link_id: payout_link_id.clone(),
customer_id: customer_id.to_string(),
link,
sdk_host,
client_secret: Secret::new(client_secret),
session_expiry,
ui_config: payout_link_config,
enabled_payment_methods,
};

let _db_link_data =
create_pm_collect_db_entry(state, merchant_account, &data, return_url).await?;

Ok(Some(data))
}
Loading