Skip to content

Conversation

awasthi21
Copy link
Contributor

@awasthi21 awasthi21 commented Oct 21, 2024

Type of Change

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

Description

1)Added Mandate flow for Paybox
2) Added a new field additional_payment_method_data in PaymentsAuthorizeData type
3) Added connector_mandate_request_reference_id in RouterData

Additional Changes

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

Motivation and Context

1)Paybox requires the expiration year, month, and mandate ID in our request, added additional_payment_method to fetch card info.
2)Paybox also needs a unique ID(connector_mandate_request_reference_id) from us during CIT, which they'll return with their own ID for MIT payments.

How did you test it?

CIT Flow

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key:' \
--data-raw '{
    "amount": 501,
    "currency": "EUR",
    "confirm": true,
    "capture_method": "manual",
    "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": "8056594427",
            "country_code": "+91"
        }
    },
    "customer_acceptance": {
          "acceptance_type": "online",
          "accepted_at":"1963-05-03T04:07:52.723Z",
          "online": {
            "ip_address":"127.0.0.1",
            "user_agent": "amet irure esse"
          }
    },
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "5200000000000007",
            "card_exp_month": "01",
            "card_exp_year": "26",
            "card_holder_name": "John T",
            "card_cvc": "123"
        }
    },
    "customer_id":"test_mit1",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "email": "[email protected]",
    "name": "Joseph Doe",
    "phone": "999999999",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "setup_future_usage": "off_session"
}'

Response

{
    "payment_id": "pay_Z5EjX2drsMwJOJW9c4cD",
    "merchant_id": "postman_merchant_GHAction_3a560136-e947-4667-bb84-2f015fcc1196",
    "status": "requires_capture",
    "amount": 501,
    "net_amount": 501,
    "shipping_cost": null,
    "amount_capturable": 501,
    "amount_received": null,
    "connector": "paybox",
    "client_secret": "pay_Z5EjX2drsMwJOJW9c4cD_secret_jRlKLOkmGQDyMJYv5Vos",
    "created": "2024-10-29T17:40:15.214Z",
    "currency": "EUR",
    "customer_id": "test_mit1",
    "customer": {
        "id": "test_mit1",
        "name": "Joseph Doe",
        "email": "[email protected]",
        "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": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0007",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "520000",
            "card_extended_bin": null,
            "card_exp_month": "01",
            "card_exp_year": "26",
            "card_holder_name": null,
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": "token_WtS8M0HJRumgDi8wlOtH",
    "shipping": 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": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": "[email protected]",
    "name": "Joseph Doe",
    "phone": "999999999",
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "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": "test_mit1",
        "created_at": 1730223615,
        "expires": 1730227215,
        "secret": "epk_0d91d25b351049e09b6a554232df82c7"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "0080031896",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_hl5seUYAuPOk5MN8bSGO",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_DsQkwRcnsQVWJ7jbsSZl",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-10-29T17:55:15.214Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": "pm_SFHEomDxVxWQg81PB0KU",
    "payment_method_status": "active",
    "updated": "2024-10-29T17:40:17.064Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": "SM@LpCp@L@C"
}

MIT
Request

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_wmCOQW4LM2BHYugFWaU8crmipDtmGDsq0iozaQhe17CtM59tqCHSAtD8w646AkZU' \
--data-raw '{
    "amount": 7100,
    "currency": "EUR",
    "confirm": true,
    "customer_id": "test_mit1",
    "email": "[email protected]",
    "off_session": true,
    "recurring_details": {
        "type": "payment_method_id",
        "data": "pm_SFHEomDxVxWQg81PB0KU"
    },
    "payment_method": "card",
    "billing": {
        "address": {
            "city": "test",
            "country": "US",
            "line1": "here",
            "line2": "there",
            "line3": "anywhere",
            "zip": "560095",
            "state": "Washington",
            "first_name": "One",
            "last_name": "Two"
        },
        "phone": {
            "number": "1234567890",
            "country_code": "+1"
        },
        "email": "[email protected]"
    }
}'

Response

{
    "payment_id": "pay_i2b2h2D3OygZcX6xhllE",
    "merchant_id": "postman_merchant_GHAction_3a560136-e947-4667-bb84-2f015fcc1196",
    "status": "succeeded",
    "amount": 7100,
    "net_amount": 7100,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 7100,
    "connector": "paybox",
    "client_secret": "pay_i2b2h2D3OygZcX6xhllE_secret_3F2pXPqmDmDl7aOu0zpx",
    "created": "2024-10-29T17:41:52.979Z",
    "currency": "EUR",
    "customer_id": "test_mit1",
    "customer": {
        "id": "test_mit1",
        "name": "Joseph Doe",
        "email": "[email protected]",
        "phone": "999999999",
        "phone_country_code": "+65"
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": true,
    "capture_on": null,
    "capture_method": null,
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0007",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "520000",
            "card_extended_bin": null,
            "card_exp_month": "01",
            "card_exp_year": "26",
            "card_holder_name": "John T",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": null,
    "billing": {
        "address": {
            "city": "test",
            "country": "US",
            "line1": "here",
            "line2": "there",
            "line3": "anywhere",
            "zip": "560095",
            "state": "Washington",
            "first_name": "One",
            "last_name": "Two"
        },
        "phone": {
            "number": "1234567890",
            "country_code": "+1"
        },
        "email": "[email protected]"
    },
    "order_details": null,
    "email": "[email protected]",
    "name": "Joseph Doe",
    "phone": "999999999",
    "return_url": null,
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "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": "test_mit1",
        "created_at": 1730223712,
        "expires": 1730227312,
        "secret": "epk_d5ce670fd4f44281b90228c5f480816a"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "0080031906",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_hl5seUYAuPOk5MN8bSGO",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_DsQkwRcnsQVWJ7jbsSZl",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-10-29T17:56:52.979Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": "pm_SFHEomDxVxWQg81PB0KU",
    "payment_method_status": "active",
    "updated": "2024-10-29T17:41:54.740Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": "SM@LpCp@L@C"
}

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

@awasthi21 awasthi21 added A-connector-integration Area: Connector integration A-core Area: Core flows A-mandates Area: Mandate Flows labels Oct 21, 2024
@awasthi21 awasthi21 self-assigned this Oct 21, 2024
@awasthi21 awasthi21 requested review from a team as code owners October 21, 2024 07:38
Copy link

semanticdiff-com bot commented Oct 21, 2024

Review changes with  SemanticDiff

Changed Files
File Status
  crates/hyperswitch_connectors/src/utils.rs  81% smaller
  crates/router/src/connector/multisafepay/transformers.rs  78% smaller
  crates/router/src/core/payments.rs  73% smaller
  crates/router/src/connector/adyen/transformers.rs  63% smaller
  crates/router/src/core/payments/operations/payment_update.rs  56% smaller
  crates/router/src/core/payments/tokenization.rs  45% smaller
  crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs  37% smaller
  crates/router/src/core/payments/operations/payment_confirm.rs  36% smaller
  crates/router/src/connector/globalpay/transformers.rs  36% smaller
  crates/router/src/core/payments/operations/payment_create.rs  33% smaller
  crates/router/src/core/payments/transformers.rs  22% smaller
  crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs  19% smaller
  crates/router/src/connector/stripe/transformers.rs  17% smaller
  crates/api_models/src/payments.rs  15% smaller
  crates/router/src/connector/paybox/transformers.rs  12% smaller
  crates/router/src/core/payments/operations/payment_response.rs  10% smaller
  crates/router/src/connector/utils.rs  5% smaller
  crates/router/src/connector/paybox.rs  3% smaller
  crates/hyperswitch_domain_models/src/router_request_types.rs  1% smaller
  crates/common_utils/src/lib.rs  0% smaller
  crates/diesel_models/src/payment_attempt.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/nexinets/transformers.rs  0% smaller
  crates/hyperswitch_domain_models/src/payments/payment_attempt.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_data.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_response_types.rs  0% smaller
  crates/router/src/connector/aci/transformers.rs  0% smaller
  crates/router/src/connector/authorizedotnet/transformers.rs  0% smaller
  crates/router/src/connector/bamboraapac/transformers.rs  0% smaller
  crates/router/src/connector/bankofamerica/transformers.rs  0% smaller
  crates/router/src/connector/braintree/transformers.rs  0% smaller
  crates/router/src/connector/cybersource/transformers.rs  0% smaller
  crates/router/src/connector/gocardless/transformers.rs  0% smaller
  crates/router/src/connector/noon/transformers.rs  0% smaller
  crates/router/src/connector/nuvei/transformers.rs  0% smaller
  crates/router/src/connector/payme/transformers.rs  0% smaller
  crates/router/src/connector/wellsfargo/transformers.rs  0% smaller
  crates/router/src/consts.rs  0% smaller
  crates/router/src/core/authentication/transformers.rs  0% smaller
  crates/router/src/core/fraud_check/flows/checkout_flow.rs  0% smaller
  crates/router/src/core/fraud_check/flows/fulfillment_flow.rs  0% smaller
  crates/router/src/core/fraud_check/flows/record_return.rs  0% smaller
  crates/router/src/core/fraud_check/flows/sale_flow.rs  0% smaller
  crates/router/src/core/fraud_check/flows/transaction_flow.rs  0% smaller
  crates/router/src/core/mandate/utils.rs  0% smaller
  crates/router/src/core/payments/helpers.rs  0% smaller
  crates/router/src/core/utils.rs  0% smaller
  crates/router/src/core/webhooks/utils.rs  0% smaller
  crates/router/src/services/conversion_impls.rs  0% smaller
  crates/router/src/types.rs  0% smaller
  crates/router/src/types/api/verify_connector.rs  0% smaller
  crates/router/src/types/storage/payment_method.rs  0% smaller
  crates/router/tests/connectors/aci.rs  0% smaller
  crates/router/tests/connectors/utils.rs  0% smaller

@awasthi21 awasthi21 force-pushed the 7040-featconnector-paybox-implement-mandate-flow branch from cb851dc to 8d4780a Compare October 28, 2024 06:07
connector_mandate_ids.get_connector_mandate_id()?,
connector_mandate_ids
.get_connector_mandate_id()
.ok_or_else(missing_field_err("mandate_id"))?,
Copy link
Member

Choose a reason for hiding this comment

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

Optional change:

There also seems to be a errors::ConnectorError::MissingConnectorMandateID enum variant, confirm with the connector team if that enum variant would have to be raised instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@deepanshu-iiitu Can you verify this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Both can be used

@awasthi21 awasthi21 force-pushed the 7040-featconnector-paybox-implement-mandate-flow branch from 5441e64 to 6feba97 Compare October 29, 2024 11:10
ThisIsMani
ThisIsMani previously approved these changes Oct 29, 2024
apoorvdixit88
apoorvdixit88 previously approved these changes Oct 29, 2024
Copy link
Contributor

@apoorvdixit88 apoorvdixit88 left a comment

Choose a reason for hiding this comment

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

Dashboard specific changes look fine

@sai-harsha-vardhan
Copy link
Contributor

@awasthi21 Can you please add the relevant test cases in the PR description?

let card_detail_from_locker: Option<api::CardDetailFromLocker> = pm
.payment_method_data
.clone()
.map(|x| x.into_inner().expose())
Copy link
Contributor

Choose a reason for hiding this comment

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

nit : Can you give a better naming for the inner variables?

.clone()
.map(|x| x.into_inner().expose())
.and_then(|v| {
v.parse_value("PaymentMethodsData")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: here as well

connector_mandate_ids.get_connector_mandate_id()?,
connector_mandate_ids
.get_connector_mandate_id()
.ok_or_else(missing_field_err("mandate_id"))?,
Copy link
Contributor

Choose a reason for hiding this comment

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

Both can be used

@awasthi21 awasthi21 removed the request for review from ThisIsMani October 30, 2024 08:02
@likhinbopanna likhinbopanna added this pull request to the merge queue Oct 30, 2024
Merged via the queue into main with commit 37513e0 Oct 30, 2024
20 of 21 checks passed
@likhinbopanna likhinbopanna deleted the 7040-featconnector-paybox-implement-mandate-flow branch October 30, 2024 16:38
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 A-mandates Area: Mandate Flows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants