Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(connector): fix incorrect mapping of attempt status in NMI connector #7200

Merged
merged 2 commits into from
Feb 10, 2025

Conversation

Anurag-05-prog
Copy link
Contributor

@Anurag-05-prog Anurag-05-prog commented Feb 5, 2025

Type of Change

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

Description

After making a capture call following the Payments-Create call, the backend was returning an incorrect error message, incorrectly indicating an issue with the capture_method. This is because, after the Payments-Create call, the payment status was being set to processing instead of requires_capture due to an incorrect mapping of an attempt status in the NMI connector. This fix ensures that the correct payment status is displayed.

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?

Postman Test

  1. Payments Connector - Create (NMI)

Request -

curl --location 'http://localhost:8080/account/:merchant_id/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: {{api-key}}' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "nmi",
    "connector_account_details": {
        "auth_type": "BodyKey",
        "api_key": "API KEY",
        "key1": "KEY1"
    },
    "test_mode": true,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "accepted_countries": {
                        "type": "disable_only",
                        "list": [
                            "HK"
                        ]
                    },
                    "accepted_currencies": {
                        "type": "enable_only",
                        "list": [
                            "USD",
                            "GBP",
                            "INR"
                        ]
                    }
                },
                {
                    "payment_method_type": "debit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "accepted_countries": {
                        "type": "disable_only",
                        "list": [
                            "HK"
                        ]
                    },
                    "accepted_currencies": {
                        "type": "enable_only",
                        "list": [
                            "USD",
                            "GBP",
                            "INR"
                        ]
                    }
                }
            ]
        }
    ],
    "metadata": {
        "city": "NY",
        "unit": "245"
    },
    "connector_webhook_details": {
        "merchant_secret": "MyWebhookSecret"
    },
    "business_country": "US",
    "business_label": "default"
}'

Response -

{
    "connector_type": "payment_processor",
    "connector_name": "nmi",
    "connector_label": "nmi_US_default",
    "merchant_connector_id": "mca_lSdgOhqb7xkLIwFG5RmF",
    "profile_id": "pro_8TCRT4W0cFxSiwrX6UZX",
    "connector_account_details": {
        "auth_type": "BodyKey",
        "api_key": "8Y****************************Sm",
        "key1": "ch********************************************59"
    },
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "payment_experience": null,
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "accepted_currencies": {
                        "type": "enable_only",
                        "list": [
                            "USD",
                            "GBP",
                            "INR"
                        ]
                    },
                    "accepted_countries": {
                        "type": "disable_only",
                        "list": [
                            "HK"
                        ]
                    },
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "payment_experience": null,
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "accepted_currencies": {
                        "type": "enable_only",
                        "list": [
                            "USD",
                            "GBP",
                            "INR"
                        ]
                    },
                    "accepted_countries": {
                        "type": "disable_only",
                        "list": [
                            "HK"
                        ]
                    },
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ],
    "connector_webhook_details": {
        "merchant_secret": "MyWebhookSecret",
        "additional_secret": null
    },
    "metadata": {
        "city": "NY",
        "unit": "245"
    },
    "test_mode": true,
    "disabled": false,
    "frm_configs": null,
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "applepay_verified_domains": null,
    "pm_auth_config": null,
    "status": "active",
    "additional_merchant_data": null,
    "connector_wallets_details": null
}
  1. Payments - Create

Request -

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: {{api-key}}' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "capture_method": "manual",
    "customer_id": "StripeCustomer",
    "email": "guest@example.com",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4012000033330026",
            "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": "joseph",
            "last_name": "Doe"
        }
    },
    "shipping": {
        "address": {
            "line1": "123",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country":"US",
            "first_name": "PiX"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'

Response -

{
    "payment_id": "pay_nbmtZ5WEPRqu5YrSFf1c",
    "merchant_id": "merchant_1738782997",
    "status": "requires_capture",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "nmi",
    "client_secret": "pay_nbmtZ5WEPRqu5YrSFf1c_secret_q4r6QTPpGIfAFzq1pTSQ",
    "created": "2025-02-05T19:16:45.353Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": null,
        "email": "guest@example.com",
        "phone": null,
        "phone_country_code": null
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0026",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "401200",
            "card_extended_bin": null,
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": "token_E4a0G0TyXfI9zRhUKhdt",
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "123",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "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": "joseph",
            "last_name": "Doe"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": null,
    "phone": null,
    "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": null,
    "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": 1738783005,
        "expires": 1738786605,
        "secret": "epk_9e27e24364464098900da2a7c078d441"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "10384074477",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_nbmtZ5WEPRqu5YrSFf1c_1",
    "payment_link": null,
    "profile_id": "pro_8TCRT4W0cFxSiwrX6UZX",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_lSdgOhqb7xkLIwFG5RmF",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-02-05T19:31:45.353Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-02-05T19:16:49.957Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
  1. Payments - Capture

Request -

curl --location 'http://localhost:8080/payments/pay_WjH16MusMwAlPgWjbkqt/capture' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: {{api-key}}' \
--data '{
  "amount_to_capture": 65400
}'

Response -

{
    "error": {
        "type": "invalid_request",
        "message": "amount_to_capture is greater than amount",
        "code": "IR_06"
    }
}

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

@Anurag-05-prog Anurag-05-prog requested a review from a team as a code owner February 5, 2025 21:11
Copy link

semanticdiff-com bot commented Feb 5, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/connector/nmi/transformers.rs  0% smaller

@Anurag-05-prog Anurag-05-prog self-assigned this Feb 5, 2025
@Anurag-05-prog Anurag-05-prog linked an issue Feb 5, 2025 that may be closed by this pull request
2 tasks
@Anurag-05-prog Anurag-05-prog added the C-bug Category: Bug label Feb 5, 2025
@@ -2582,30 +2582,30 @@ pub(crate) fn validate_status_with_capture_method(
status: storage_enums::IntentStatus,
capture_method: storage_enums::CaptureMethod,
) -> RouterResult<()> {
if status == storage_enums::IntentStatus::Processing
&& !(capture_method == storage_enums::CaptureMethod::ManualMultiple)
if capture_method == storage_enums::CaptureMethod::ManualMultiple
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if capture_method == storage_enums::CaptureMethod::ManualMultiple
let allowed_status_for_manual_multiple = vec![IntentStatus::RequiresCapture,IntentStatus::PartiallyCapturedAndCapturable, IntentStatus::Processing ]
match capture_method

@Anurag-05-prog Anurag-05-prog requested a review from a team as a code owner February 6, 2025 09:19
@Anurag-05-prog Anurag-05-prog changed the title fix(core): fix incorrect error message during status validation check in capture call fix(connector): fix incorrect mapping of attempt status in NMI connector Feb 6, 2025
@deepanshu-iiitu deepanshu-iiitu requested review from hrithikesh026 and AkshayaFoiger and removed request for hrithikesh026 February 6, 2025 10:21
@deepanshu-iiitu deepanshu-iiitu added the A-connector-integration Area: Connector integration label Feb 7, 2025
@likhinbopanna likhinbopanna added this pull request to the merge queue Feb 10, 2025
Merged via the queue into main with commit 76c3459 Feb 10, 2025
21 of 24 checks passed
@likhinbopanna likhinbopanna deleted the nmi-connector-bug-fix branch February 10, 2025 13:04
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 C-bug Category: Bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Incorrect mapping of attempt status in NMI connector
5 participants