Skip to content

feat(core): Update PaymentsMethod Table based on IncomingWebhooks#9453

Merged
Gnanasundari24 merged 22 commits intomainfrom
pmTable/pmdUpdate
Nov 7, 2025
Merged

feat(core): Update PaymentsMethod Table based on IncomingWebhooks#9453
Gnanasundari24 merged 22 commits intomainfrom
pmTable/pmdUpdate

Conversation

@bsayak03
Copy link
Contributor

@bsayak03 bsayak03 commented Sep 19, 2025

Type of Change

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

Description

Let's say a CIT has been executed and the future MIT's have been going through pretty well but the customer's card has expired now and only the Bank knows about it. Our locker still has the expired card details and is attempting to execute the MIT based on that. However, when the MIT fails - Bank informs Adyen about this failed card and also passes on the new card details info's like last4 digits, expiry month and year etc. We need to consume this from webhooks and store it in our payment methods table in payment_method_data column.

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?

Make a CIT call

cURL:

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_gmKkRQ15YEFLuQUElQJPKSKBw9OEyIm24J0xmRb08NYY2LlJJJx3lTgN3dDC7aEb' \
--data-raw '{
    "amount": 2500,
    "currency": "USD",
    "connector": [
        "adyen"
    ],
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "customer_id": "customflmwmfler123",
    "setup_future_usage": "off_session",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    },
    "amount_to_capture": 2500,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "2222 4000 7000 0005",
            "card_exp_month": "03",
            "card_exp_year": "2030",
            "card_cvc": "737",
            "card_holder_name": "joseph Doe"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "9123456789",
            "country_code": "+91"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "9123456789",
            "country_code": "+91"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
        "browser_info": {
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "language": "en-US",
        "color_depth": 32,
        "screen_height": 1117,
        "screen_width": 1728,
        "time_zone": -330,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "127.0.0.1"
    }
}'

Response:

{
    "payment_id": "pay_AZdv4ytFuXbBWfATF6FW",
    "merchant_id": "merchant_1760504526",
    "status": "succeeded",
    "amount": 2500,
    "net_amount": 2500,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 2500,
    "connector": "adyen",
    "client_secret": "pay_AZdv4ytFuXbBWfATF6FW_secret_sd7X2sOW5NljKUl2CqB6",
    "created": "2025-10-15T15:03:25.450Z",
    "currency": "USD",
    "customer_id": "customflmwmfler123",
    "customer": {
        "id": "customflmwmfler123",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": "off_session",
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0005",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "222240",
            "card_extended_bin": null,
            "card_exp_month": "03",
            "card_exp_year": "2030",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe",
            "origin_zip": null
        },
        "phone": {
            "number": "9123456789",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe",
            "origin_zip": null
        },
        "phone": {
            "number": "9123456789",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "customflmwmfler123",
        "created_at": 1760540605,
        "expires": 1760544205,
        "secret": "epk_0c0606b82ba24695859c95e017dcb927"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "C7S8TPNWKHWMSR65",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "direct"
    },
    "reference_id": "pay_AZdv4ytFuXbBWfATF6FW_1",
    "payment_link": null,
    "profile_id": "pro_hSjZOTbEWLlJbnY4fEct",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_cdDVH5OHE9nhL4VdpZtF",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-10-15T15:18:25.450Z",
    "fingerprint": null,
    "browser_info": {
        "language": "en-US",
        "time_zone": -330,
        "ip_address": "127.0.0.1",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        "color_depth": 32,
        "java_enabled": true,
        "screen_width": 1728,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 1117,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": "pm_GGCYE5xRH4OCEN2kebdv",
    "network_transaction_id": "UKKFQA2MN1015",
    "payment_method_status": "active",
    "updated": "2025-10-15T15:03:27.442Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "request_extended_authorization": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": "RRPCFHFPQSJ2PF75",
    "card_discovery": "manual",
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": null,
    "enable_partial_authorization": null,
    "enable_overcapture": null,
    "is_overcapture_enabled": null,
    "network_details": null,
    "is_stored_credential": null,
    "mit_category": null
}

Make a POST callback From Postman:

cURL:

curl --location 'https://8f7ded6a5078.ngrok-free.app/webhooks/merchant_1760504526/mca_cdDVH5OHE9nhL4VdpZtF' \
--header 'Content-Type: application/json' \
--data '{
    "live": "false",
    "notificationItems": [
        {
            "NotificationRequestItem": {
                "additionalData": {
                    "expiryDate": "12/2033",
                    "authCode": "1234",
                    "cardBin": "976543",
                    "cardSummary": "7777",
                    "cardHolderName": "J. De Tester",
                    "paymentMethodVariant": "visa",
                    "totalFraudScore": "10",
                    "hmacSignature": "HMAC_SIGNATURE",
                    "NAME2": "VALUE2",
                    "NAME1": "VALUE1",
                    "fraudCheck-6-ShopperIpUsage": "10"
                },
                "amount": {
                    "currency": "EUR",
                    "value": 10100
                },
                "eventCode": "AUTHORISATION",
                "eventDate": "2025-10-15T07:09:14+02:00",
                "merchantAccountCode": "JuspayDEECOM",
                "merchantReference": "pay_AZdv4ytFuXbBWfATF6FW_1",
                "pspReference": "C7S8TPNWKHWMSR65",
                "reason": "1234:7777:12/2012",
                "success": "true"
            }
        }
    ]
}'

Payment Method Retrieve call:

cURL:

curl --location 'http://localhost:8080/payment_methods/pm_GGCYE5xRH4OCEN2kebdv' \
--header 'api-key: dev_gmKkRQ15YEFLuQUElQJPKSKBw9OEyIm24J0xmRb08NYY2LlJJJx3lTgN3dDC7aEb'

Response:

{
    "merchant_id": "merchant_1760504526",
    "customer_id": "customflmwmfler123",
    "payment_method_id": "pm_GGCYE5xRH4OCEN2kebdv",
    "payment_method": "card",
    "payment_method_type": "credit",
    "card": {
        "scheme": null,
        "issuer_country": null,
        "last4_digits": "0005",
        "expiry_month": "12",
        "expiry_year": "37",
        "card_token": null,
        "card_holder_name": "joseph Doe",
        "card_fingerprint": null,
        "nick_name": null,
        "card_network": null,
        "card_isin": null,
        "card_issuer": null,
        "card_type": null,
        "saved_to_locker": true
    },
    "recurring_enabled": false,
    "installment_payment_enabled": false,
    "payment_experience": [
        "redirect_to_url"
    ],
    "metadata": null,
    "created": "2025-10-15T14:04:03.957Z",
    "last_used_at": "2025-10-16T08:07:30.604Z",
    "client_secret": "pm_GGCYE5xRH4OCEN2kebdv_secret_g2TNDXdk2qUvzmrAv0gN"
}

DB Update query in logs:
Screenshot 2025-10-15 at 8 35 20 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

@bsayak03 bsayak03 self-assigned this Sep 19, 2025
@bsayak03 bsayak03 requested review from a team as code owners September 19, 2025 10:50
@semanticdiff-com
Copy link

semanticdiff-com bot commented Sep 19, 2025

@bsayak03 bsayak03 changed the title feat(core): Update PaymentMethodData in PaymentsMethod Table when Connector sends new Card Info's in Webhooks feat(core): Update PaymentMethodData in PaymentsMethod Table based on IncomingWebhooks Sep 19, 2025
@bsayak03 bsayak03 changed the title feat(core): Update PaymentMethodData in PaymentsMethod Table based on IncomingWebhooks feat(core): Update PaymentsMethod Table based on IncomingWebhooks Sep 19, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Sep 19, 2025
kashif-m
kashif-m previously approved these changes Oct 6, 2025
Copy link
Contributor

@kashif-m kashif-m left a comment

Choose a reason for hiding this comment

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

added a nitpick, looks good otherwise

@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 0% with 120 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@ed436b2). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...ch_connectors/src/connectors/adyen/transformers.rs 0.00% 100 Missing ⚠️
..._interfaces/src/connector_integration_interface.rs 0.00% 11 Missing ⚠️
crates/hyperswitch_interfaces/src/webhooks.rs 0.00% 9 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9453   +/-   ##
=======================================
  Coverage        ?    3.89%           
=======================================
  Files           ?     1224           
  Lines           ?   303236           
  Branches        ?        0           
=======================================
  Hits            ?    11804           
  Misses          ?   291432           
  Partials        ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

hrithikesh026
hrithikesh026 previously approved these changes Oct 30, 2025
jagan-jaya
jagan-jaya previously approved these changes Oct 30, 2025
kashif-m
kashif-m previously approved these changes Oct 31, 2025
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue Nov 7, 2025
Merged via the queue into main with commit f0d753f Nov 7, 2025
36 of 48 checks passed
@Gnanasundari24 Gnanasundari24 deleted the pmTable/pmdUpdate branch November 7, 2025 07:24
aadityaguptaa pushed a commit that referenced this pull request Nov 10, 2025
)

Co-authored-by: Sayak Bhattacharya <sayak.b@Sayak-Bhattacharya-G092THXJ34.local>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

M-api-contract-changes Metadata: This PR involves API contract changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants