Skip to content
New issue

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

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

Already on GitHub? # to your account

feat(connector): [DEUTSCHEBANK] Implement SEPA recurring payments #5925

Merged
merged 12 commits into from
Sep 20, 2024

Conversation

deepanshu-iiitu
Copy link
Contributor

@deepanshu-iiitu deepanshu-iiitu commented Sep 17, 2024

Type of Change

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

Description

Implement SEPA mandate payments for Deutschebank.
These mandate details will be stored in the payment_methods table in the connector_mandate_details.

Additional Changes

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

Motivation and Context

#5924

How did you test it?

  1. Payments Intent Create:

Request:

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_2QpEeK0ByPRkb2DPBxHfad4i1WxQO3hZSuVzlFcg9mTrLFUHRpGfE0SCuQwZjGEb' \
--data '{
    "amount": 1650,
    "currency": "EUR",
    "confirm": false,
    "customer_id": "customer123",
    "setup_future_usage": "off_session"
}'

Response:

{
    "payment_id": "pay_u8nPxFlL3ZUW94kkzrI1",
    "merchant_id": "merchant_1725539597",
    "status": "requires_payment_method",
    "amount": 1650,
    "net_amount": 1650,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": null,
    "client_secret": "pay_u8nPxFlL3ZUW94kkzrI1_secret_npQbKdQHon2g7tthKxeB",
    "created": "2024-09-17T12:59:17.770Z",
    "currency": "EUR",
    "customer_id": "customer123",
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "something@example.com",
        "phone": "9999999999",
        "phone_country_code": "+1"
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": "off_session",
    "off_session": null,
    "capture_on": null,
    "capture_method": null,
    "payment_method": null,
    "payment_method_data": null,
    "payment_token": null,
    "shipping": null,
    "billing": null,
    "order_details": null,
    "email": "something@example.com",
    "name": "John Doe",
    "phone": "9999999999",
    "return_url": null,
    "authentication_type": null,
    "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": "customer123",
        "created_at": 1726577957,
        "expires": 1726581557,
        "secret": "epk_46a85e0e97b645a1bb2f838483b3bf70"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": null,
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_EuXuxP2KVO0m1tlDWSau",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": null,
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-09-17T13:14:17.769Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-09-17T12:59:17.902Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null
}
  1. Payments Confirm:

Request:

curl --location 'http://localhost:8080/payments/pay_u8nPxFlL3ZUW94kkzrI1/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_2QpEeK0ByPRkb2DPBxHfad4i1WxQO3hZSuVzlFcg9mTrLFUHRpGfE0SCuQwZjGEb' \
--data-raw '{
    "profile_id": "pro_EuXuxP2KVO0m1tlDWSau",
    "customer_id": "customer123",
    "payment_method": "bank_debit",
    "payment_method_type": "sepa",
    "payment_method_data": {
        "bank_debit": {
            "sepa_bank_debit": {
                "iban": "DE87123456781234567890"
            }
        }
    },
    "billing": {
        "address": {
            "first_name": "joseph",
            "last_name": "Doe"
        }
    },
    "email": "something@example.com",
    "customer_acceptance": {
        "acceptance_type": "offline"
    }
}'

Response:

{
    "payment_id": "pay_u8nPxFlL3ZUW94kkzrI1",
    "merchant_id": "merchant_1725539597",
    "status": "requires_customer_action",
    "amount": 1650,
    "net_amount": 1650,
    "amount_capturable": 1650,
    "amount_received": null,
    "connector": "deutschebank",
    "client_secret": "pay_u8nPxFlL3ZUW94kkzrI1_secret_npQbKdQHon2g7tthKxeB",
    "created": "2024-09-17T12:59:17.770Z",
    "currency": "EUR",
    "customer_id": "customer123",
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "something@example.com",
        "phone": "9999999999",
        "phone_country_code": "+1"
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": "off_session",
    "off_session": null,
    "capture_on": null,
    "capture_method": null,
    "payment_method": "bank_debit",
    "payment_method_data": {
        "bank_debit": {
            "sepa": {
                "iban": "DE871************67890",
                "bank_account_holder_name": null
            }
        },
        "billing": null
    },
    "payment_token": "token_K3jaclrwRSo2guy2kfn1",
    "shipping": null,
    "billing": {
        "address": {
            "city": null,
            "country": null,
            "line1": null,
            "line2": null,
            "line3": null,
            "zip": null,
            "state": null,
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "something@example.com",
    "name": "John Doe",
    "phone": "9999999999",
    "return_url": null,
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_u8nPxFlL3ZUW94kkzrI1/merchant_1725539597/pay_u8nPxFlL3ZUW94kkzrI1_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "sepa",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": null,
    "connector_transaction_id": null,
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_EuXuxP2KVO0m1tlDWSau",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_MZAsrTowXuzpeXl4DMj2",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-09-17T13:14:17.769Z",
    "fingerprint": null,
    "browser_info": {
        "language": null,
        "time_zone": null,
        "ip_address": "::1",
        "user_agent": null,
        "color_depth": null,
        "java_enabled": null,
        "screen_width": null,
        "accept_header": null,
        "screen_height": null,
        "java_script_enabled": null
    },
    "payment_method_id": "pm_8qqABCQOMAznGanjmLhz",
    "payment_method_status": null,
    "updated": "2024-09-17T12:59:36.782Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null
}
  1. Creating payment using payment_method_id:
    Request:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_2QpEeK0ByPRkb2DPBxHfad4i1WxQO3hZSuVzlFcg9mTrLFUHRpGfE0SCuQwZjGEb' \
--data '{
    "amount": 179,
    "currency": "EUR",
    "confirm": true,
    "customer_id": "customer123",
    "recurring_details": {
        "type": "payment_method_id",
        "data": "pm_8qqABCQOMAznGanjmLhz"
    },
    "off_session": true
}'

Response:

{
    "payment_id": "pay_zeindrGrgMlzJscKZdAC",
    "merchant_id": "merchant_1725539597",
    "status": "succeeded",
    "amount": 179,
    "net_amount": 179,
    "amount_capturable": 0,
    "amount_received": 179,
    "connector": "deutschebank",
    "client_secret": "pay_zeindrGrgMlzJscKZdAC_secret_W4q8bNJWw2yH7MVaC70L",
    "created": "2024-09-17T13:24:07.080Z",
    "currency": "EUR",
    "customer_id": "customer123",
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "something@example.com",
        "phone": "9999999999",
        "phone_country_code": "+1"
    },
    "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": "bank_debit",
    "payment_method_data": null,
    "payment_token": null,
    "shipping": null,
    "billing": null,
    "order_details": null,
    "email": "something@example.com",
    "name": "John Doe",
    "phone": "9999999999",
    "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": "sepa",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "customer123",
        "created_at": 1726579447,
        "expires": 1726583047,
        "secret": "epk_d80c49dcbeb1431cadf357b9c6d64ad9"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "nz17xcQ3x7q7kecPExgV0s",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_EuXuxP2KVO0m1tlDWSau",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_MZAsrTowXuzpeXl4DMj2",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-09-17T13:39:07.079Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": "pm_8qqABCQOMAznGanjmLhz",
    "payment_method_status": "active",
    "updated": "2024-09-17T13:24:08.282Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null
}

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

@deepanshu-iiitu deepanshu-iiitu added A-connector-integration Area: Connector integration C-feature Category: Feature request or enhancement labels Sep 17, 2024
@deepanshu-iiitu deepanshu-iiitu self-assigned this Sep 17, 2024
@deepanshu-iiitu deepanshu-iiitu requested review from a team as code owners September 17, 2024 11:42
Copy link

semanticdiff-com bot commented Sep 17, 2024

Review changes with SemanticDiff.

Analyzed 34 of 34 files.

Overall, the semantic diff is 28% smaller than the GitHub diff.

File Information
Filename Status
✔️ crates/router/src/types/storage/payment_method.rs Analyzed
✔️ crates/router/src/core/payments.rs Analyzed
✔️ crates/router/src/core/payments/helpers.rs Analyzed
✔️ crates/router/src/core/payments/tokenization.rs 17.21% smaller
✔️ crates/router/src/core/payments/operations/payment_confirm.rs Analyzed
✔️ crates/router/src/core/payments/operations/payment_create.rs 50.0% smaller
✔️ crates/router/src/core/payments/operations/payment_response.rs 41.95% smaller
✔️ crates/router/src/core/payments/operations/payment_update.rs Analyzed
✔️ crates/router/src/core/errors/utils.rs 14.98% smaller
✔️ crates/router/src/connector/wellsfargo/transformers.rs Analyzed
✔️ crates/router/src/connector/stripe/transformers.rs Analyzed
✔️ crates/router/src/connector/payme/transformers.rs Analyzed
✔️ crates/router/src/connector/payeezy/transformers.rs Analyzed
✔️ crates/router/src/connector/nuvei/transformers.rs Analyzed
✔️ crates/router/src/connector/noon/transformers.rs Analyzed
✔️ crates/router/src/connector/nexinets/transformers.rs Analyzed
✔️ crates/router/src/connector/multisafepay/transformers.rs Analyzed
✔️ crates/router/src/connector/gocardless/transformers.rs Analyzed
✔️ crates/router/src/connector/globalpay/transformers.rs Analyzed
✔️ crates/router/src/connector/cybersource/transformers.rs Analyzed
✔️ crates/router/src/connector/braintree/transformers.rs Analyzed
✔️ crates/router/src/connector/bankofamerica/transformers.rs Analyzed
✔️ crates/router/src/connector/bamboraapac/transformers.rs Analyzed
✔️ crates/router/src/connector/authorizedotnet/transformers.rs Analyzed
✔️ crates/router/src/connector/adyen/transformers.rs Analyzed
✔️ crates/router/src/connector/aci/transformers.rs Analyzed
✔️ crates/hyperswitch_interfaces/src/errors.rs Analyzed
✔️ crates/hyperswitch_domain_models/src/router_data.rs Analyzed
✔️ crates/hyperswitch_domain_models/src/router_response_types.rs Analyzed
✔️ crates/hyperswitch_connectors/src/connectors/deutschebank.rs 47.65% smaller
✔️ crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs Analyzed
✔️ crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs Analyzed
✔️ crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs 28.05% smaller
✔️ crates/api_models/src/payments.rs Analyzed

@deepanshu-iiitu deepanshu-iiitu linked an issue Sep 17, 2024 that may be closed by this pull request
2 tasks
@@ -1042,6 +1042,7 @@ pub struct ConnectorMandateReferenceId {
pub connector_mandate_id: Option<String>,
pub payment_method_id: Option<String>,
pub update_history: Option<Vec<UpdateHistory>>,
pub mandate_metadata: Option<pii::SecretSerdeValue>,
Copy link
Contributor

Choose a reason for hiding this comment

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

keep it as a serde_json::Value for now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Aprabhat19
Aprabhat19 previously approved these changes Sep 19, 2024
@SamraatBansal SamraatBansal changed the title feat(connector): [DEUTSCHEBANK] Implement SEPA mandate payments feat(connector): [DEUTSCHEBANK] Implement SEPA recurring payments Sep 19, 2024
SamraatBansal
SamraatBansal previously approved these changes Sep 19, 2024
Aprabhat19
Aprabhat19 previously approved these changes Sep 19, 2024
SanchithHegde
SanchithHegde previously approved these changes Sep 19, 2024
Aprabhat19
Aprabhat19 previously approved these changes Sep 20, 2024
@likhinbopanna likhinbopanna added this pull request to the merge queue Sep 20, 2024
Merged via the queue into main with commit 00e913c Sep 20, 2024
14 checks passed
@likhinbopanna likhinbopanna deleted the mandate-sepa-deutsche branch September 20, 2024 11:41
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-connector-integration Area: Connector integration C-feature Category: Feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] [DEUTSCHEBANK] Implement subsequent mandate payments via SEPA
6 participants