Skip to content

Conversation

sai-harsha-vardhan
Copy link
Contributor

@sai-harsha-vardhan sai-harsha-vardhan commented Oct 9, 2025

Type of Change

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

Description

Payments Eligibility API

This PR introduces the Payments Eligibility API, which is invoked by the SDK after the payment method data filled event. The API pre-processes the submitted payment method data to determine the appropriate next action and checks eligibility based on various parameters.

As part of this change, blocklist checks have been added to the eligibility flow to ensure that ineligible or restricted payment methods are identified early in the process.

image

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?

Tested Manually

  1. Create a blocklist rule for a card_bin (424242)
    CURL
curl --location '{{BASE_URL}}/blocklist' \
--header 'Content-Type: application/json' \
--header 'api-key: {{API_KEY}}' \
--data '{
    "type": "card_bin",
    "data": "424242"
}'

Response

{
    "fingerprint_id": "424242",
    "data_kind": "card_bin",
    "created_at": "2025-10-09T13:52:38.914Z"
}
  1. Call the Eligibility API with blocklisted bin to see next_action being Deny in the response
    CURL
curl --location '{{BASE_URL}}/payments/{{PAYMENT_ID}}/eligibility' \
--header 'Content-Type: application/json' \
--header 'api-key: {{PUBLISHABLE_KEY}}' \
--data '{
    "client_secret": "pay_UvTqxnVPNNChhe1vKk1W_secret_AF9avGOwxxvcwqHhmYv0",
    "payment_method_type": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "01",
            "card_exp_year": "2050",
            "card_holder_name": "John Smith",
            "card_cvc": "349",
            "card_network": "Visa"
        },
        "billing": {
            "address": {
                "line1": "1467",
                "line2": "Harrison Street",
                "line3": "Harrison Street",
                "city": "San Fransico",
                "state": "CA",
                "zip": "94122",
                "country": "US",
                "first_name": "John",
                "last_name": "Doe"
            },
            "phone": {
                "number": "8056594427",
                "country_code": "+91"
            }
        }
    }
}'

Response

{
    "payment_id": "pay_UvTqxnVPNNChhe1vKk1W",
    "sdk_next_action": {
        "next_action": {
            "deny": {
                "message": "Card number is blocklisted"
            }
        }
    }
}
  1. Call the Eligibility API with non-blocklisted bin to see next_action being Confirm in the response
    CURL
curl --location '{{BASE_URL}}/payments/{{PAYMENT_ID}}/eligibility' \
--header 'Content-Type: application/json' \
--header 'api-key: {{PUBLISHABLE_KEY}}' \
--data '{
    "client_secret": "pay_UvTqxnVPNNChhe1vKk1W_secret_AF9avGOwxxvcwqHhmYv0",
    "payment_method_type": "card",
    "payment_method_data": {
        "card": {
            "card_number": "411111111111111",
            "card_exp_month": "01",
            "card_exp_year": "2050",
            "card_holder_name": "John Smith",
            "card_cvc": "349",
            "card_network": "Visa"
        },
        "billing": {
            "address": {
                "line1": "1467",
                "line2": "Harrison Street",
                "line3": "Harrison Street",
                "city": "San Fransico",
                "state": "CA",
                "zip": "94122",
                "country": "US",
                "first_name": "John",
                "last_name": "Doe"
            },
            "phone": {
                "number": "8056594427",
                "country_code": "+91"
            }
        }
    }
}'

Response

{
    "payment_id": "pay_UvTqxnVPNNChhe1vKk1W",
    "sdk_next_action": {
        "next_action": "confirm"
    }
}

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

@sai-harsha-vardhan sai-harsha-vardhan added this to the July 2025 Release milestone Oct 9, 2025
@sai-harsha-vardhan sai-harsha-vardhan self-assigned this Oct 9, 2025
@sai-harsha-vardhan sai-harsha-vardhan requested review from a team as code owners October 9, 2025 14:39
@sai-harsha-vardhan sai-harsha-vardhan added A-core Area: Core flows C-feature Category: Feature request or enhancement labels Oct 9, 2025
Copy link

semanticdiff-com bot commented Oct 9, 2025

@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Oct 10, 2025
pub struct PaymentsEligibilityRequest {
/// The identifier for the payment
#[serde(skip)]
pub payment_id: id_type::PaymentId,
Copy link
Member

Choose a reason for hiding this comment

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

Why we are adding serde skip and include payment_id field? The path only contains this field and not the payload. Remove this field

// Trait for Eligibility Checks
#[cfg(feature = "v1")]
#[async_trait::async_trait]
trait EligibilityCheck {
Copy link
Member

Choose a reason for hiding this comment

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

How EligibilityCheck is polymorphic?


#[cfg(feature = "v1")]
impl EligibilityPipeline {
pub async fn run(
Copy link
Member

Choose a reason for hiding this comment

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

Use function name respective to domain, these functions represents some kind of framework representation but there is no actual framework around this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-core Area: Core flows C-feature Category: Feature request or enhancement M-api-contract-changes Metadata: This PR involves API contract changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants