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

feat(router): add db interface for /relay #6879

Merged
merged 22 commits into from
Dec 22, 2024
Merged

Conversation

ShankarSinghC
Copy link
Contributor

@ShankarSinghC ShankarSinghC commented Dec 18, 2024

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

/relay is a api that will be used to just forward the request sent by merchant without performing any application logic on it. In this pr the changes is particular to support the refunds for the payments that was directly performed with the connector (example stripe) with out hyperswitch involved during the payment flow.

Flow

  1. Merchant performs payment directly with processor and stores the payment reference id associated with it.
  2. Merchant tiggers the refund through hyperswitch using the processor reference id for the payment.

Additional Changes

  • This PR modifies the API contract
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

How did you test it?

-> Create a merchant connector account
-> Make a refund request with invalid connector_resource_id

curl --location 'http://localhost:8080/relay' \
--header 'Content-Type: application/json' \
--header 'X-Profile-Id: pro_Pwvl4mcL0CmLR1YbIXnq' \
--header 'api-key: dev_y6s7DJZguBHxS66AneCCoJUgO3aTjcdafjJ5x1JiBtOJFofp5AchFIC4oxTxd8oa' \
--data '{
  "connector_id": "mca_M3pxBGmzJeOPHBhBxOoH",
  "connector_resource_id": "X445D84NZ22WQT65",
  "data": {
    "amount": 50,
    "currency": "USD"
  },
  "type": "refund"
}'
{
    "id": "relay_XiAMJo3ifbyhYaQ7AyW9",
    "status": "failure",
    "connector_resource_id": "X445D84NZ22WQT65",
    "error": {
        "code": "resource_missing",
        "message": "resource_missing"
    },
    "connector_reference_id": null,
    "connector_id": "mca_M3pxBGmzJeOPHBhBxOoH",
    "profile_id": "pro_Pwvl4mcL0CmLR1YbIXnq",
    "type": "refund",
    "data": {
        "amount": 50,
        "currency": "USD",
        "reason": null
    }
}

-> Make a refund request with valid connector_resource_id

curl --location 'http://localhost:8080/relay' \
--header 'Content-Type: application/json' \
--header 'X-Profile-Id: pro_vb2ZGypHwTIhL1xpi7cV' \
--header 'api-key: dev_yOa9A8G8VyF3rDcy8KUylUsSZxXwGYIQOVo10YEPFhVvouztwHhVmpOkqsbPVKKJ' \
--data '{
  "connector_id": "mca_qjU8mTdWzr7uKhm99WON",
  "connector_resource_id": "7348595224296247904953",
  "data": {
      "refund": {
    "amount": 50,
    "currency": "USD"
  }},
  "type": "refund"
}'
{
    "id": "relay_5sEV785aXJs1ZQwpMmO5",
    "status": "pending",
    "connector_resource_id": "7348595224296247904953",
    "error": null,
    "connector_reference_id": "7348601752236522904951",
    "connector_id": "mca_qjU8mTdWzr7uKhm99WON",
    "profile_id": "pro_vb2ZGypHwTIhL1xpi7cV",
    "type": "refund",
    "data": {
        "refund": {
            "amount": 50,
            "currency": "USD",
            "reason": null
        }
    }
}

Checklist

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

@ShankarSinghC ShankarSinghC added A-core Area: Core flows M-database-changes Metadata: This PR involves database schema changes labels Dec 18, 2024
@ShankarSinghC ShankarSinghC self-assigned this Dec 18, 2024
@ShankarSinghC ShankarSinghC requested review from a team as code owners December 18, 2024 13:02
Copy link

semanticdiff-com bot commented Dec 18, 2024

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/lib.rs  75% smaller
  crates/openapi/src/openapi.rs  67% smaller
  crates/diesel_models/src/enums.rs  57% smaller
  api-reference/openapi_spec.json  33% smaller
  crates/api_models/src/relay.rs  19% smaller
  crates/hyperswitch_domain_models/src/merchant_connector_account.rs  12% smaller
  crates/router/src/db.rs  12% smaller
  crates/router/src/routes.rs  2% smaller
  crates/router/src/routes/app.rs  1% smaller
  crates/common_enums/src/enums.rs  0% smaller
  crates/common_utils/src/id_type/relay.rs  0% smaller
  crates/diesel_models/src/lib.rs  0% smaller
  crates/diesel_models/src/query.rs  0% smaller
  crates/diesel_models/src/query/relay.rs  0% smaller
  crates/diesel_models/src/relay.rs  0% smaller
  crates/diesel_models/src/schema.rs  0% smaller
  crates/diesel_models/src/schema_v2.rs  0% smaller
  crates/hyperswitch_domain_models/src/lib.rs  0% smaller
  crates/hyperswitch_domain_models/src/relay.rs  0% smaller
  crates/router/src/core.rs  0% smaller
  crates/router/src/core/relay.rs  0% smaller
  crates/router/src/core/relay/utils.rs  0% smaller
  crates/router/src/db/relay.rs  0% smaller
  crates/router/src/routes/lock_utils.rs  0% smaller
  crates/router/src/routes/relay.rs  0% smaller
  crates/router/src/services/authentication.rs  0% smaller
  crates/router_env/src/logger/types.rs  0% smaller
  migrations/2024-12-17-141811_add_relay_table/down.sql Unsupported file format
  migrations/2024-12-17-141811_add_relay_table/up.sql Unsupported file format

@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 18, 2024
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 19, 2024
Base automatically changed from relay/api-contract to main December 20, 2024 14:34
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 20, 2024
@ShankarSinghC ShankarSinghC requested review from a team as code owners December 21, 2024 13:52
api-reference/api-reference/relay/relay-retrieve.mdx Outdated Show resolved Hide resolved
crates/common_enums/src/enums.rs Outdated Show resolved Hide resolved
crates/common_utils/src/id_type/relay.rs Outdated Show resolved Hide resolved
crates/diesel_models/src/query/relay.rs Outdated Show resolved Hide resolved
crates/hyperswitch_domain_models/src/relay.rs Outdated Show resolved Hide resolved
_merchant_key_store: &domain::MerchantKeyStore,
_new: hyperswitch_domain_models::relay::Relay,
) -> CustomResult<hyperswitch_domain_models::relay::Relay, errors::StorageError> {
Err(errors::StorageError::MockDbError)?
Copy link
Contributor

Choose a reason for hiding this comment

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

Do no throw error here, and call diesel store implementations from here

crates/router/src/routes/app.rs Outdated Show resolved Hide resolved
crates/router/src/routes/lock_utils.rs Outdated Show resolved Hide resolved
crates/router/src/routes/relay.rs Outdated Show resolved Hide resolved
migrations/2024-12-17-141811_add_relay_table/up.sql Outdated Show resolved Hide resolved
@ShankarSinghC ShankarSinghC requested review from sai-harsha-vardhan and removed request for a team December 22, 2024 09:20
crates/router/src/core/relay.rs Outdated Show resolved Hide resolved
.await
.to_refund_failed_response()?;

let relay_response = match router_data_res.response {
Copy link
Member

Choose a reason for hiding this comment

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

+1

crates/router/src/core/relay.rs Show resolved Hide resolved
crates/router/src/core/relay.rs Outdated Show resolved Hide resolved
crates/router/src/core/relay.rs Outdated Show resolved Hide resolved
crates/router/src/core/relay.rs Show resolved Hide resolved
jarnura
jarnura previously approved these changes Dec 22, 2024
Copy link
Contributor

@sai-harsha-vardhan sai-harsha-vardhan left a comment

Choose a reason for hiding this comment

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

api-reference/api-reference/relay/relay-retrieve.mdx

Renaming this would require changes in mint.json, Can you please revert this change? @ShankarSinghC

Comment on lines +90 to +92
impl common_utils::events::ApiEventMetric for RelayRequest {}

impl common_utils::events::ApiEventMetric for RelayResponse {}
Copy link
Member

Choose a reason for hiding this comment

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

Why are we not raising any API events here?

pub profile_id: common_utils::id_type::ProfileId,
pub merchant_id: common_utils::id_type::MerchantId,
pub relay_type: storage_enums::RelayType,
pub request_data: Option<pii::SecretSerdeValue>,
Copy link
Member

Choose a reason for hiding this comment

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

Do we have an option to store structured data (serialized as JSON) in the request_data and response_data fields?

Comment on lines +17 to +18
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Relay {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need the Serialize and Deserialize derives as of today?

) -> Self {
let relay_id = id_type::RelayId::generate();
Self {
id: relay_id.clone(),
Copy link
Member

Choose a reason for hiding this comment

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

Why the clone, looks like we aren't using the relay_id variable anywhere else?

.request_data
.map(|data| {
serde_json::to_value(data).change_context(ValidationError::InvalidValue {
message: "Failed while decrypting business profile data".to_string(),
Copy link
Member

Choose a reason for hiding this comment

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

If we're still going to use serde_json::Value on the diesel model, then update the error message. Otherwise, update the code as required.

.map(|data| {
serde_json::from_value(data.expose()).change_context(
ValidationError::InvalidValue {
message: "Failed while decrypting business profile data".to_string(),
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

.request_data
.map(|data| {
serde_json::to_value(data).change_context(ValidationError::InvalidValue {
message: "Failed while decrypting business profile data".to_string(),
Copy link
Member

Choose a reason for hiding this comment

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

And here.

Comment on lines +32 to +36
let webhook_url = Some(payments::helpers::create_webhook_url(
&state.base_url.clone(),
merchant_id,
connector_name,
));
Copy link
Member

Choose a reason for hiding this comment

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

We should consider using merchant connector account ID instead of connector name.
We can take this change up in a separate PR.

Comment on lines +18 to +19
created_at TIMESTAMP NOT NULL DEFAULT now()::TIMESTAMP,
modified_at TIMESTAMP NOT NULL DEFAULT now()::TIMESTAMP,
Copy link
Member

Choose a reason for hiding this comment

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

Remove the defaults here.

-- Your SQL goes here
CREATE TYPE "RelayStatus" AS ENUM ('created', 'pending', 'failure', 'success');

CREATE TYPE "RelayType" AS ENUM ('refund');
Copy link
Member

Choose a reason for hiding this comment

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

Should we consider using a string instead of enum for the relay_type field? This is considering that adding support for new relay types would involve database migrations to add enum variants each time.

This is open for discussion, we need not take it up now.

Copy link
Contributor Author

@ShankarSinghC ShankarSinghC left a comment

Choose a reason for hiding this comment

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

@SanchithHegde as this is a priority pr, can I address all of your comments in my next pr ?

@likhinbopanna likhinbopanna added this pull request to the merge queue Dec 22, 2024
Merged via the queue into main with commit 0f8b0b3 Dec 22, 2024
17 of 19 checks passed
@likhinbopanna likhinbopanna deleted the relay/db-interface branch December 22, 2024 17:37
pixincreate added a commit that referenced this pull request Dec 23, 2024
…ete-pm

* 'main' of github.com:juspay/hyperswitch:
  chore(version): 2024.12.23.0
  feat(connector): [JPMORGAN] add Payment flows for cards (#6668)
  refactor(grpc): send `x-tenant-id` and `x-request-id` in grpc headers (#6904)
  feat(payment_methods_v2): Added Ephemeral auth for v2 (#6813)
  chore(cypress): payout - fix test cases for adyenplatform bank (#6887)
  refactor(connector): [Airwallex] add device_data in payment request (#6881)
  feat(router): add db interface for `/relay` (#6879)
  feat(payments_v2): implement payments capture v2 (#6722)
  feat(router): add /relay endpoint (#6870)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-core Area: Core flows M-api-contract-changes Metadata: This PR involves API contract changes M-database-changes Metadata: This PR involves database schema changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add api model changes for /relay endpoint
6 participants