Skip to content

fix(core): moved merchant fingerprint secret from superposition to merchant account table#13346

Open
sahkal wants to merge 2 commits into
mainfrom
21567-move-merchant-finger-print-from-superposition-to-merchant-account-table
Open

fix(core): moved merchant fingerprint secret from superposition to merchant account table#13346
sahkal wants to merge 2 commits into
mainfrom
21567-move-merchant-finger-print-from-superposition-to-merchant-account-table

Conversation

@sahkal

@sahkal sahkal commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • Refactoring

Description

moved merchant fingerprint secret from superposition to merchant account table

Additional Changes

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

Overview

The PR moves the fingerprint_secret for merchants from the dynamic configuration service (Superposition) into the primary database as a direct column on the merchant_account table. This simplifies data retrieval and reduces the dependency on external config services for fingerprinting payments (used in blocklists).

Key Changes

  1. Database Schema & Migrations

    • Added a new database migration (2026-07-16-000001_add_fingerprint_secret_to_merchant_account) to ADD COLUMN IF NOT EXISTS fingerprint_secret VARCHAR(128) to the merchant_account table.
    • Updated schema.rs and schema_v2.rs in diesel_models to reflect the new column.
  2. Model Updates

    • Modified the MerchantAccount, MerchantAccountSetter, and MerchantAccountNew structs in both diesel_models and hyperswitch_domain_models to include the fingerprint_secret: Option<Secret<String>> field.
    • Updated the mapping and conversion logic between domain and database models to account for this new field.
  3. Core Logic Refactoring (Blocklist & Routing)

    • Removed Superposition Usage: Removed insert_merchant_configs_with_superposition from crates/router/src/core/admin.rs.
    • Account Creation: Instead of making a separate API call to Superposition when creating a merchant account, a securely generated fingerprint_secret is now immediately embedded and saved with the new MerchantAccount record.
    • Blocklist & Fingerprinting: Refactored get_merchant_fingerprint_secret and generate_payment_fingerprint in crates/router/src/core/blocklist/utils.rs. They no longer require Superposition dimensions/state to fetch the secret; they simply extract it directly from the passed MerchantAccount object.
  4. Configuration & Cleanup

    • Removed the FINGERPRINT_SECRET entry from config/superposition_seed.toml.
    • Removed FINGERPRINT_SECRET macros and writable config implementations in dimension_config.rs.
    • Removed related constants and helper methods (get_merchant_fingerprint_secret_key) across consts.rs and merchant.rs.

Motivation and Context

Currently we are pushing merchant fingerprint to superposition and then fetching from superposition for further usecase, But merchant fingerprint is a merchant account property and not superposition property so we are moving back merchant fingerprint to merchant account table from superposition.

How did you test it?

Create merchant account

curl --location 'localhost:8080/accounts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data-raw '{
"merchant_id": "new_sahkal",
  "locker_id": "m0010",
  "merchant_name": "NewAge Retailer",
  "merchant_details": {
    "primary_contact_person": "John Test",
    "primary_email": "JohnTest@test.com",
    "primary_phone": "sunt laborum",
    "secondary_contact_person": "John Test2",
    "secondary_email": "JohnTest2@test.com",
    "secondary_phone": "cillum do dolor id",
    "website": "www.example.com",
    "about_business": "Online Retail with a wide selection of organic products for North America",
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US"
    }
  },
  "return_url": "https://google.com/success",
  "webhook_details": {
    "webhook_version": "1.0.1",
    "webhook_username": "ekart_retail",
    "webhook_password": "password_ekart@123",
    "payment_created_enabled": true,
    "payment_succeeded_enabled": true,
    "payment_failed_enabled": true
  },
  "sub_merchants_enabled": false,
  "metadata": {
    "city": "NY",
    "unit": "245"
  },
  "primary_business_details": [
    {
      "country": "US",
      "business": "default"
    }
  ]
}'

Checked if fingerprint secret is set in the table or not

Screenshot 2026-07-16 at 3 29 10 PM

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

@sahkal sahkal self-assigned this Jul 16, 2026
@sahkal
sahkal requested review from a team as code owners July 16, 2026 09:49
@semanticdiff-com

semanticdiff-com Bot commented Jul 16, 2026

Copy link
Copy Markdown

@hyperswitch-bot hyperswitch-bot Bot added the M-database-changes Metadata: This PR involves database schema changes label Jul 16, 2026
@sahkal sahkal added the S-test-ready Status: This PR is ready for cypress-tests label Jul 16, 2026
@sahkal sahkal added the C-refactor Category: Refactor label Jul 16, 2026
@sahkal
sahkal enabled auto-merge July 16, 2026 11:34
true => Err(errors::ApiErrorResponse::InternalServerError)
.attach_printable("fingerprint_secret not found in Superposition for merchant"),
}
merchant_account

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should have superposition as a fallback for now if the value is not found. We already have several fingerprint_secrets stored in superposition. We will need to migrate them to the merchant table before we can deploy this change.

This is easy enough for us, but this will also impact the self hosted merchants who are using superposition. If they miss the migration before the new deployment they might start experiencing transaction failures.

Ideally migrations like this should be automatically done in the background on application startup or as a background job and should be transparent to the self hosted merchant.

@XyneSpaces

Copy link
Copy Markdown
Contributor

[blocking] Please add a migration/backfill or a read fallback for existing merchants before switching fingerprint generation to merchant_account.fingerprint_secret. The new column is nullable and the migration only adds it, so existing merchant rows will keep NULL; get_merchant_fingerprint_secret now returns InternalServerError for those merchants, breaking blocklist/fingerprint generation paths until every row is populated.

@XyneSpaces

Copy link
Copy Markdown
Contributor

[blocking] The merchant-account migration adds fingerprint_secret as nullable but does not backfill existing merchants, while the new blocklist/fingerprint path now errors when that field is None. Existing merchants that run card fingerprinting can start receiving internal server errors until each row gets a secret.

Please either backfill merchant_account.fingerprint_secret in the migration, or add a lazy generation/update path for None before removing the Superposition fallback.

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

Labels

C-refactor Category: Refactor M-database-changes Metadata: This PR involves database schema changes S-test-ready Status: This PR is ready for cypress-tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants