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 endpoint for listing connector features #6612

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

AkshayaFoiger
Copy link
Contributor

@AkshayaFoiger AkshayaFoiger commented Nov 19, 2024

Type of Change

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

Description

-> Why?
With new features being added, it is becoming increasingly difficult to track all the additions. This information is essential for accurately representing Hyperswitch's offerings. Having this solution will eliminate inconsistencies between the documentation and the actual implementation, ensuring clarity and alignment.

-> What?

Introduce an API endpoint that provides:
-> A list of all connectors.
-> The payment methods supported by each connector.
-> The status of these payment methods.
-> Whether these payment methods support mandates.

-> How?
-> Pre-validation for Payment Methods:
Before invoking a connector to process a payment, this function will check if the specified payment_method is implemented. This ensures developers update the relevant functions during development and testing.

-> Unified API Endpoint:
Build an endpoint that collects information from all connectors and consolidates it into a unified JSON response. This will act as a single source of truth for supported features.

Additional Changes

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

How did you test it?

Test the validation.
Create a Klarna payment with Bambora. It should fail with "payment method not supported" error.

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_JHPIA2kkwO2PZt5kIZtkqGbjUotOyUD9ByNeEHTIVMPeLCqsU3qPIqJQ72Jtbdn5' \
--data-raw '{
    "amount": 6540,
    "currency": "GBP",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "StripeCustomer",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "payment_method": "pay_later",
    "payment_method_type": "klarna",
    "payment_experience": "redirect_to_url",
    "payment_method_data": {
        "pay_later": {
            "klarna_redirect": {}
        },
        "billing": {
            "address": {
                "country": "GB"
            },
            "email": "[email protected]"
        }
    }  
}'

Response

{
    "error": {
        "type": "invalid_request",
        "message": "Payment method type not supported",
        "code": "IR_19",
        "reason": "pay_later is not supported by bambora"
    }
}

The payment intent status will be requires_payment_method

  1. Test the endpoint /feature_matrix
curl --location --request GET 'http://localhost:8080/feature_matrix' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--header 'X-Merchant-Id: postman_merchant_GHAction_e70f1cfe-b545-46a4-bb39-4ceb21392117' \
--data '{
     "connectors" : ["bambora"]   // Provide list of connectors, for which you need to list the features 
                                                      // currently only implemented for bambora and deutsche bank. 
}'

Response

{
    "size": 1,
    "data": [
        {
            "connector": "bambora",
            "payment_method_types": [
                {
                    "payment_method_type": "card",
                    "payment_methods": [
                        {
                            "payment_method": "debit",
                            "availability_status": "Live",
                            "supports_mandates": false
                        },
                        {
                            "payment_method": "credit",
                            "availability_status": "Live",
                            "supports_mandates": false
                        }
                    ]
                }
            ]
        }
    ]
}

List for all connector (that implements this feature)

curl --location --request GET 'http://localhost:8080/feature_matrix' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--header 'X-Merchant-Id: postman_merchant_GHAction_e70f1cfe-b545-46a4-bb39-4ceb21392117' \
--data '{
    
}'

Response

{
    "size": 2,
    "data": [
        {
            "connector": "bambora",
            "payment_method_types": [
                {
                    "payment_method_type": "card",
                    "payment_methods": [
                        {
                            "payment_method": "credit",
                            "availability_status": "Live",
                            "supports_mandates": false
                        },
                        {
                            "payment_method": "debit",
                            "availability_status": "Live",
                            "supports_mandates": false
                        }
                    ]
                }
            ]
        },
        {
            "connector": "deutschebank",
            "payment_method_types": [
                {
                    "payment_method_type": "bank_debit",
                    "payment_methods": [
                        {
                            "payment_method": "sepa",
                            "availability_status": "Live",
                            "supports_mandates": true
                        }
                    ]
                }
            ]
        }
    ]
}

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

@AkshayaFoiger AkshayaFoiger requested review from a team as code owners November 19, 2024 12:35
@AkshayaFoiger AkshayaFoiger self-assigned this Nov 19, 2024
@AkshayaFoiger AkshayaFoiger added C-feature Category: Feature request or enhancement C-refactor Category: Refactor M-api-contract-changes Metadata: This PR involves API contract changes labels Nov 19, 2024
@AkshayaFoiger AkshayaFoiger changed the title feat(router): add an api for listing connector features and add a payment method function feat(router): add endpoint for listing connector features Nov 19, 2024
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Nov 19, 2024
Live,
/// Payment Method available in sandbox
Beta,
/// Payment Method not available
Copy link
Member

Choose a reason for hiding this comment

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

In my opinion this should be the default value. We cannot have Live as the default value.

let feature_matrix_response: Vec<payment_types::FeatureMatrixResponse> = connector_list
.into_iter()
.filter_map(|connector_name| {
api_types::ConnectorData::convert_connector(&connector_name.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.

why do we have so much of nesting here?

Copy link
Member

Choose a reason for hiding this comment

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

if possible try idiomatic approach and reduce the nesting

#[derive(Default, Debug, Deserialize, Serialize, Clone, ToSchema)]
pub struct FeatureMatrixRequest {
// List of connectors for which the feature matrix is requested
pub connectors: Option<Vec<enums::Connector>>,
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 not accept any connector from the request, application will know how many connectors are supported, so this value should be provided by the application

ToSchema,
)]
#[strum(serialize_all = "snake_case")]
pub enum PaymentMethodStage {
Copy link
Member

Choose a reason for hiding this comment

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

rename this to PaymentMethodAvailabilityStage

#[strum(serialize_all = "snake_case")]
pub enum PaymentMethodStage {
/// Payment Method available in production
#[default]
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 default value, we should not infer any default values

Comment on lines +124 to +142
let mut supported_payment_methods = SupportedPaymentMethods::new();
let mut card_payment_method = PaymentMethodTypeMetadata::new();
card_payment_method.insert(
enums::PaymentMethodType::Credit,
PaymentMethodDetails {
availability_status: enums::PaymentMethodStage::Live,
supports_mandates: false,
},
);
card_payment_method.insert(
enums::PaymentMethodType::Debit,
PaymentMethodDetails {
availability_status: enums::PaymentMethodStage::Live,
supports_mandates: false,
},
);
supported_payment_methods.insert(enums::PaymentMethod::Card, card_payment_method);
Some(supported_payment_methods)
}
Copy link
Member

Choose a reason for hiding this comment

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

define a toml file for the config and get these values from that config file. That will be maintainable

/// fn validate_payment_method
fn validate_payment_method(
&self,
payment_method_type: &Option<PaymentMethodType>,
Copy link
Member

Choose a reason for hiding this comment

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

why is this optional in the request, if we want to validate this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature Category: Feature request or enhancement C-refactor Category: Refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants