Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -1047,20 +1047,31 @@ impl UnifiedConnectorServiceClient {
}

/// Performs Create Access Token Granular
///
/// When `is_payout` is set, the payout connector header (`x-payout-connector`) is
/// attached so the merchant-authentication flow resolves the payout connector
/// variant; otherwise the payment connector header (`x-connector`) is used.
pub async fn create_access_token(
&self,
create_access_token_request: payments_grpc::MerchantAuthenticationServiceCreateServerAuthenticationTokenRequest,
connector_auth_metadata: ConnectorAuthMetadata,
grpc_headers: GrpcHeadersUcs,
is_payout: bool,
) -> UnifiedConnectorServiceResult<
tonic::Response<
payments_grpc::MerchantAuthenticationServiceCreateServerAuthenticationTokenResponse,
>,
> {
let mut request = tonic::Request::new(create_access_token_request);
let connector_name = connector_auth_metadata.connector_name.clone();
let metadata =
build_unified_connector_service_grpc_headers(connector_auth_metadata, grpc_headers)?;
let metadata = if is_payout {
build_unified_connector_service_grpc_headers_for_payouts(
connector_auth_metadata,
grpc_headers,
)?
} else {
build_unified_connector_service_grpc_headers(connector_auth_metadata, grpc_headers)?
};
*request.metadata_mut() = metadata;

self.merchant_authentication_service_client
Expand Down
2 changes: 1 addition & 1 deletion crates/router/src/core/payments/access_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ async fn fetch_access_token_from_ucs(
};

let response = client
.create_access_token(create_request, connector_auth_metadata, grpc_headers)
.create_access_token(create_request, connector_auth_metadata, grpc_headers, false)
.await
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("UCS create_access_token gRPC call failed")?;
Expand Down
58 changes: 45 additions & 13 deletions crates/router/src/core/payments/gateway/access_token_gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,51 @@ where
)
.change_context(ConnectorError::RequestEncodingFailed)
.attach_printable("Failed to construct request metadata")?;
let merchant_reference_id = unified_connector_service::parse_merchant_reference_id(
header_payload
.x_reference_id
.as_deref()
.unwrap_or(router_data.payment_id.as_str()),
)
.map(ucs_types::UcsReferenceId::Payment);

let resource_id = id_type::PaymentResourceId::from_str(router_data.attempt_id.as_str())
.inspect_err(
|err| logger::warn!(error=?err, "Invalid Payment AttemptId for UCS resource id"),
// A merchant-authentication (access-token) call can originate from either a
// payment or a payout. When it is a payout, attach the payout reference/resource
// ids so the downstream call carries the real payout reference and (via the
// payout gRPC client) resolves the payout connector variant.
let is_payout = router_data.payout_id.is_some();

let (merchant_reference_id, resource_id) = if let Some(payout_id) =
router_data.payout_id.as_deref()
{
let merchant_reference_id =
unified_connector_service::parse_merchant_payout_reference_id(
header_payload
.x_reference_id
.as_deref()
.unwrap_or(payout_id),
)
.map(ucs_types::UcsReferenceId::Payout);

let resource_id = id_type::PayoutResourceId::from_str(router_data.attempt_id.as_str())
.inspect_err(
|err| logger::warn!(error=?err, "Invalid Payout AttemptId for UCS resource id"),
)
.ok()
.map(ucs_types::UcsResourceId::PayoutAttempt);

(merchant_reference_id, resource_id)
} else {
let merchant_reference_id = unified_connector_service::parse_merchant_reference_id(
header_payload
.x_reference_id
.as_deref()
.unwrap_or(router_data.payment_id.as_str()),
)
.ok()
.map(ucs_types::UcsResourceId::PaymentAttempt);
.map(ucs_types::UcsReferenceId::Payment);

let resource_id =
id_type::PaymentResourceId::from_str(router_data.attempt_id.as_str())
.inspect_err(|err| {
logger::warn!(error=?err, "Invalid Payment AttemptId for UCS resource id")
})
.ok()
.map(ucs_types::UcsResourceId::PaymentAttempt);

(merchant_reference_id, resource_id)
};

let header_payload = state
.get_grpc_headers_ucs(unified_connector_service_execution_mode)
Expand All @@ -136,6 +167,7 @@ where
create_access_token_request,
connector_auth_metadata,
grpc_headers,
is_payout,
)
.await
.attach_printable("Failed to create access token")?;
Expand Down
Loading