Skip to content

feat(core): Add support for updating metadata after payment has been authorized#7776

Merged
likhinbopanna merged 15 commits intomainfrom
update
Apr 15, 2025
Merged

feat(core): Add support for updating metadata after payment has been authorized#7776
likhinbopanna merged 15 commits intomainfrom
update

Conversation

@swangi-kumari
Copy link
Contributor

@swangi-kumari swangi-kumari commented Apr 9, 2025

Type of Change

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

Description

  • Add support where merchant can update the payment metadata after the payment has been authorized.
  • Introduce a new api \payments:id\update_metadata
  • Only the metadata field can be updated, which is a key value pair.
  • This api can do a connector call just using the metadata field.
  • After this call is successful, metadata will be updated, it will have the intent_metadata along with the metadata passed in this new api request.

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?

  1. Create Merchant Account
  2. Create API Key
  3. Create Stripe MCA
  4. Create a Stripe Payment
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: _' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "StripeCustomer",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "setup_future_usage": "off_session",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "123"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "routing": {
        "type": "single",
        "data": "stripe"
    }
}'

Response

{
    "payment_id": "pay_MxPTKHNcJwOOoL8FDtPN",
    "merchant_id": "postman_merchant_GHAction_da04b367-690b-4bde-ad7c-3cfbf62e4e84",
    "status": "succeeded",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 6540,
    "connector": "stripe",
    "client_secret": "pay_MxPTKHNcJwOOoL8FDtPN_secret_025WQHlpbdojP0rBFWMj",
    "created": "2025-04-10T11:35:49.375Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "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": "4242",
            "card_type": "CREDIT",
            "card_network": "Visa",
            "card_issuer": "STRIPE PAYMENTS UK LIMITED",
            "card_issuing_country": "UNITEDKINGDOM",
            "card_isin": "424242",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "payment_checks": {
                "cvc_check": "pass",
                "address_line1_check": "pass",
                "address_postal_code_check": "pass"
            },
            "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": "sundari",
            "last_name": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": null
        },
        "phone": null,
        "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": "StripeCustomer",
        "created_at": 1744284949,
        "expires": 1744288549,
        "secret": "epk_6468c3c1c40a4364b195d2cc5c02f9a0"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "pi_3RCJObD5R7gDAGff0xK5cBVw",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pi_3RCJObD5R7gDAGff0xK5cBVw",
    "payment_link": null,
    "profile_id": "pro_2DPhFg35OVObpgXxYyB3",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_i5a4IRbcJtPyI9WCzMxz",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-04-10T11:50:49.375Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-04-10T11:35:51.031Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null
}

MetaData in DB after confirm call

Screenshot 2025-04-10 at 5 06 08 PM
  1. Update metadata
curl --location 'http://localhost:8080/payments/pay_MxPTKHNcJwOOoL8FDtPN/update_metadata' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_bSPrVP5RULlFD83TafFu8lTKXxRpdotKpvkCXWzH4Qz1YIPwq32452dcqdE7T1p6' \
--data '{
    "metadata": {
        "order_id": "999999897989"
    }
}'

Response

{
    "payment_id": "pay_MxPTKHNcJwOOoL8FDtPN",
    "metadata": {
        "udf1": "value1",
        "order_id": "999999897989",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    }
}

Metadata in DB after UpdateMetadata call
Screenshot 2025-04-10 at 5 07 13 PM

  • Here Metadata is updated with order_id

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

@semanticdiff-com
Copy link

semanticdiff-com bot commented Apr 9, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/types/api/payments_v2.rs  95% smaller
  crates/router/src/types/api/payments.rs  91% smaller
  crates/hyperswitch_domain_models/src/router_data.rs  87% smaller
  crates/router/src/types.rs  78% smaller
  api-reference/mint.json  67% smaller
  crates/hyperswitch_interfaces/src/types.rs  65% smaller
  crates/hyperswitch_connectors/src/default_implementations_v2.rs  53% smaller
  crates/router/src/routes/lock_utils.rs  34% smaller
  crates/hyperswitch_domain_models/src/types.rs  30% smaller
  crates/router_derive/src/macros/operation.rs  17% smaller
  crates/hyperswitch_connectors/src/default_implementations.rs  6% smaller
  crates/router/src/core/payments/operations/payment_response.rs  3% smaller
  crates/router/src/core/payments.rs  1% smaller
  crates/hyperswitch_interfaces/src/api/payments.rs  1% smaller
  crates/hyperswitch_interfaces/src/api/payments_v2.rs  1% smaller
  crates/api_models/src/events/payment.rs  1% smaller
  api-reference/api-reference/payments/payments--update-metadata.mdx Unsupported file format
  api-reference/openapi_spec.json  0% smaller
  crates/api_models/src/payments.rs  0% smaller
  crates/common_enums/src/enums.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/paypal.rs  0% smaller
  crates/hyperswitch_domain_models/src/payments.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_flow_types/payments.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_request_types.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_response_types.rs  0% smaller
  crates/openapi/src/openapi.rs  0% smaller
  crates/openapi/src/routes/payments.rs  0% smaller
  crates/router/src/connector/stripe.rs  0% smaller
  crates/router/src/connector/stripe/transformers.rs  0% smaller
  crates/router/src/core/payments/flows.rs  0% smaller
  crates/router/src/core/payments/flows/update_metadata_flow.rs  0% smaller
  crates/router/src/core/payments/operations.rs  0% smaller
  crates/router/src/core/payments/operations/payment_update_metadata.rs  0% smaller
  crates/router/src/core/payments/transformers.rs  0% smaller
  crates/router/src/routes/app.rs  0% smaller
  crates/router/src/routes/payments.rs  0% smaller
  crates/router/src/services/api.rs  0% smaller
  crates/router/tests/connectors/utils.rs  0% smaller
  crates/router_env/src/logger/types.rs  0% smaller

@swangi-kumari swangi-kumari self-assigned this Apr 9, 2025
@swangi-kumari swangi-kumari added A-connector-integration Area: Connector integration A-core Area: Core flows C-feature Category: Feature request or enhancement labels Apr 9, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Apr 9, 2025
@swangi-kumari swangi-kumari marked this pull request as ready for review April 10, 2025 11:41
@swangi-kumari swangi-kumari requested review from a team as code owners April 10, 2025 11:41
@swangi-kumari swangi-kumari added this to the April 2025 Release milestone Apr 10, 2025
@swangi-kumari swangi-kumari changed the title feat(core): Create Update Metadata Endpoint feat(core): Add support for updating metadata after payment has been authorized Apr 10, 2025
tsdk02
tsdk02 previously approved these changes Apr 11, 2025
tsdk02
tsdk02 previously approved these changes Apr 11, 2025
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum SessionUpdateStatus {
pub enum PaymentResourceUpdateStatus {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: This type can derive Copy.

@likhinbopanna likhinbopanna added this pull request to the merge queue Apr 15, 2025
Merged via the queue into main with commit 92f6821 Apr 15, 2025
16 of 20 checks passed
@likhinbopanna likhinbopanna deleted the update branch April 15, 2025 07:39
swangi-kumari added a commit that referenced this pull request Apr 15, 2025
…authorized (#7776)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
pixincreate added a commit that referenced this pull request Apr 15, 2025
…acilitapay-pix-pmt

* 'main' of github.com:juspay/hyperswitch:
  feat(docker): add webhook notifiers for installation tracking (#7653)
  refactor(customer): refactor customer db with storage utils and move trait to domain_models and impl to storage_model (#7538)
  feat(core): Add support for updating metadata after payment has been authorized (#7776)
  chore(version): 2025.04.14.0
  fix: script for one click docker setup (#7762)
  fix(payment_link): add validation for return_url during payment link creation (#7802)
  chore: address Rust 1.86.0 clippy lints (#7735)
  fix(connector): Add network error message support for payment connectors (#7760)
  feat(webhook): add filter by event class and type (#7275)
  ci(cypress): verify if card fields are populated on updating card info (#7743)
  chore(version): 2025.04.11.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-connector-integration Area: Connector integration 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.

6 participants