Skip to content

fix(payment-methods): fetch customer using merchant_id#11261

Open
kashif-m wants to merge 1 commit intomainfrom
fix-pm-cust-v2
Open

fix(payment-methods): fetch customer using merchant_id#11261
kashif-m wants to merge 1 commit intomainfrom
fix-pm-cust-v2

Conversation

@kashif-m
Copy link
Contributor

Type of Change

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

Description

This PR adds a new DB query to fetch customers using global_id and merchant_id.

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?

Pre-requisites

  1. Create merchant account (M1)
  2. Create API key for M1
  3. Create merchant account (M2)
  4. Create API key for M2

Steps to validate

1. Create a customer in v2 service using M1

cURL

curl --location --request POST 'http://localhost:8081/v2/customers' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Authorization: api-key=dev_8zaM32gm9uzbK4GtlCrAyaknfX0sjkk9UTNfTlnGGBhQoiIUR23Zrm85poJTzw7u' \
    --header 'x-profile-id: pro_g1okzluC0dulMQpXZRXX' \
    --data-raw '{
        "name": "Albert Klaassen",
        "phone": "6168205362",
        "email": "albert@gmail.com",
        "phone_country_code": "+1"
    }'

Response

{
    "id": "12345_cus_019c57c4f35e7322948ccc0163484eb8",
    "merchant_reference_id": null,
    "connector_customer_ids": null,
    "name": "Albert Klaassen",
    "email": "albert@gmail.com",
    "phone": "6168205362",
    "phone_country_code": "+1",
    "description": null,
    "default_billing_address": null,
    "default_shipping_address": null,
    "created_at": "2026-02-13T16:10:51.103Z",
    "metadata": null,
    "default_payment_method_id": null,
    "tax_registration_id": null,
    "document_details": null
}
2. Try to create a PM for this customer using M1 creds (should pass)

cURL

curl --location --request POST 'http://localhost:8081/v2/payment-methods' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Authorization: api-key=dev_XbrflQ0iE1eRKaz6TFVYBEjuKUfGEkhPCsOBL3dRbvmLtvfc3SqDzUjg5kfenz2x' \
    --header 'X-Profile-Id: pro_tOycY9MpPvOokzi5hvmT' \
    --data '{
        "payment_method_type": "card",
        "customer_id": "12345_cus_019c57c4f35e7322948ccc0163484eb8",
        "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "11",
            "card_exp_year": "35",
            "card_holder_name": "John Test",
            "card_cvc": "123"
        }
        },
        "storage_type": "persistent"
    }'

Response

{
    "id": "12345_pm_019c57c7a3057500a12323948157498f",
    "merchant_id": "merchant_1770998553",
    "customer_id": "12345_cus_019c57c4f35e7322948ccc0163484eb8",
    "payment_method_type": "card",
    "payment_method_subtype": null,
    "recurring_enabled": false,
    "created": "2026-02-13T16:13:47.274Z",
    "last_used_at": "2026-02-13T16:13:47.274Z",
    "payment_method_data": {
        "card": {
            "issuer_country": null,
            "last4_digits": "4242",
            "expiry_month": "11",
            "expiry_year": "35",
            "card_holder_name": "John Test",
            "card_fingerprint": null,
            "nick_name": null,
            "card_network": null,
            "card_isin": null,
            "card_issuer": null,
            "card_type": null,
            "saved_to_locker": true
        }
    },
    "connector_tokens": null,
    "network_token": null,
    "storage_type": "persistent",
    "card_cvc_token_storage": {
        "is_stored": true,
        "expires_at": "2026-02-13T16:28:47.291Z"
    },
    "network_transaction_id": null,
    "raw_payment_method_data": null
}
2. Try to create a PM for this customer using M2 creds (should fail)

cURL

curl --location --request POST 'http://localhost:8081/v2/payment-methods' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Authorization: api-key=dev_XbrflQ0iE1eRKaz6TFVYBEjuKUfGEkhPCsOBL3dRbvmLtvfc3SqDzUjg5kfenz2x' \
    --header 'X-Profile-Id: pro_tOycY9MpPvOokzi5hvmT' \
    --data '{
        "payment_method_type": "card",
        "customer_id": "12345_cus_019c57c4f35e7322948ccc0163484eb8",
        "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "11",
            "card_exp_year": "35",
            "card_holder_name": "John Test",
            "card_cvc": "123"
        }
        },
        "storage_type": "persistent"
    }'

Response

{
    "error": {
        "type": "invalid_request",
        "message": "Customer does not exist in our records",
        "code": "HE_02"
    }
}

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

@kashif-m kashif-m self-assigned this Feb 13, 2026
@kashif-m kashif-m requested review from a team as code owners February 13, 2026 16:20
@semanticdiff-com
Copy link

semanticdiff-com bot commented Feb 13, 2026

Review changes with  SemanticDiff

Changed Files
File Status
  crates/diesel_models/src/query/customers.rs  0% smaller
  crates/hyperswitch_domain_models/src/customer.rs  0% smaller
  crates/router/src/core/payment_methods.rs  0% smaller
  crates/router/src/db/kafka_store.rs  0% smaller
  crates/storage_impl/src/customers.rs  0% smaller

@kashif-m kashif-m added the S-test-ready Status: This PR is ready for cypress-tests label Feb 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-test-ready Status: This PR is ready for cypress-tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Prevent cross-merchant customer access via global customer lookup in Payment Methods flows

1 participant