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

feat(connector): [INESPAY] Integrate Sepa Bank Debit #6755

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

ImSagnik007
Copy link
Contributor

@ImSagnik007 ImSagnik007 commented Dec 5, 2024

Type of Change

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

Description

Added payment flows (Auth, PSync, Refund, RSync, and Webhooks) for Inespay Sepa Bank Debit.

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. Merchant Account Create
  2. API Key Create
    3.Inespay Connector Create:
curl --location 'http://localhost:8080/account/merchant_1736331946/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "inespay",
    "connector_account_details": {
        "auth_type": "BodyKey",
        "api_key": "abc",
        "key1": "abc"
    },
    "test_mode": false,
    "disabled": false,
    "payment_methods_enabled": [
        {
                "payment_method": "bank_debit",
                "payment_method_types": [
                    {
                        "payment_method_type": "sepa",
                        "payment_experience": "redirect_to_url",
                        "card_networks": null,
                        "accepted_currencies": null,
                        "accepted_countries": null,
                        "minimum_amount": 0,
                        "maximum_amount": 68607706,
                        "recurring_enabled": true,
                        "installment_payment_enabled": false
                    }
                ]
            }
    ],
    "connector_webhook_details": {
        "merchant_secret": "abc",
        "additional_secret": null
    }
}'
  1. Payments Create:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_t54RQO5Ci3L3J3sV0GFUeySuR0d3zPe66OxpRV8qKD3Th7Pyquxxro6afDNCapom' \
--data '{
  "amount": 6540,
  "currency": "USD",
  "confirm": true,
  "amount_to_capture": 6540,
  "customer_id": "StripbmnxeCustomer",
  "description": "Its my first payment request",
  "return_url": "https://google.com",
  "payment_method": "bank_debit",
  "payment_method_type": "sepa",
  "payment_method_data": {
    "bank_debit": {
      "sepa_bank_debit": {
        "iban": "ES5031831357110123456789"
      }
    }
  }
}'

Response:

{
    "payment_id": "pay_2hUGMfU0Wv31Gn3unXgG",
    "merchant_id": "merchant_1736331946",
    "status": "requires_customer_action",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "inespay",
    "client_secret": "pay_2hUGMfU0Wv31Gn3unXgG_secret_iYsSbpRHSGd4bEJ3OBET",
    "created": "2025-01-09T08:55:12.497Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": "John Doe",
        "email": "[email protected]",
        "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": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "bank_debit",
    "payment_method_data": {
        "bank_debit": {
            "sepa": {
                "iban": "ES503**************56789",
                "bank_account_holder_name": 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"
        },
        "phone": {
            "number": "8056594427",
            "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"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": "[email protected]",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_2hUGMfU0Wv31Gn3unXgG/merchant_1736331946/pay_2hUGMfU0Wv31Gn3unXgG_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": {
        "customer_id": "StripeCustomer",
        "created_at": 1736412912,
        "expires": 1736416512,
        "secret": "epk_a8553335e63d4417ba67bfe8301b8799"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "PMWC9HMC-E37E-I83G-FZWOCP9S2GDVX8ZD",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_oPMGl04eyRD2pY0laexI",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_RTX0eIQOVWNhcTAeKXQQ",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-01-09T09:10:12.497Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-01-09T08:55:13.385Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
  1. Payments Retrieve:
curl --location 'http://localhost:8080/payments/pay_xoODE5mPdtuN8tr5xyMz?force_sync=true' \
--header 'Accept: application/json' \
--header 'api-key: dev_t54RQO5Ci3L3J3sV0GFUeySuR0d3zPe66OxpRV8qKD3Th7Pyquxxro6afDNCapom'

Response:

{
    "payment_id": "pay_TcadxZAWM2P3PjWJ7PRC",
    "merchant_id": "merchant_1736331946",
    "status": "requires_customer_action",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "inespay",
    "client_secret": "pay_TcadxZAWM2P3PjWJ7PRC_secret_xpi5fQgZ7uqbr42h1uxt",
    "created": "2025-01-09T08:44:46.048Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "name": "John Doe",
        "email": "[email protected]",
        "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": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "bank_debit",
    "payment_method_data": {
        "bank_debit": {
            "sepa": {
                "iban": "ES113**************40674",
                "bank_account_holder_name": 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"
        },
        "phone": {
            "number": "8056594427",
            "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"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": "[email protected]",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_TcadxZAWM2P3PjWJ7PRC/merchant_1736331946/pay_TcadxZAWM2P3PjWJ7PRC_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": "BKBBNZ68-17K5-B4SL-LTC0545XW13LKIBK",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_oPMGl04eyRD2pY0laexI",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_RTX0eIQOVWNhcTAeKXQQ",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-01-09T08:59:46.047Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-01-09T08:45:37.239Z",
    "split_payments": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}
  1. Refunds:
curl --location 'http://localhost:8080/refunds' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_J5g19W9vemKtoeyfLV5hBEovbKns39FLpAxqj8SnuDnFdLCJcIHJX928eOVl8nkd' \
--data '{
  "payment_id": "pay_2hUGMfU0Wv31Gn3unXgG",
  "amount": 600,
  "reason": "Customer returned product",
  "refund_type": "instant",
  "metadata": {
    "udf1": "value1",
    "new_customer": "true",
    "login_date": "2019-09-10T10:11:12Z"
  }
}'
  1. Refunds Retrieve:
curl --location 'http://localhost:8080/refunds/' \
--header 'Accept: application/json' \
--header 'api-key: dev_J5g19W9vemKtoeyfLV5hBEovbKns39FLpAxqj8SnuDnFdLCJcIHJX928eOVl8nkd'

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

@ImSagnik007 ImSagnik007 self-assigned this Dec 5, 2024
@ImSagnik007 ImSagnik007 requested review from a team as code owners December 5, 2024 08:14
Copy link

semanticdiff-com bot commented Dec 5, 2024

@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 5, 2024
@ImSagnik007 ImSagnik007 linked an issue Dec 5, 2024 that may be closed by this pull request
2 tasks
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 6, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 7, 2025
crates/hyperswitch_connectors/src/connectors/inespay.rs Outdated Show resolved Hide resolved
Comment on lines 114 to 119
let redirection_url = Url::parse(item.response.single_payin_link.as_str())
.change_context(errors::ConnectorError::FailedToObtainIntegrationUrl)?;
let redirection_data = RedirectForm::from((redirection_url, Method::Get));
let status = match item.response.status_desc.as_str() {
"Success" => common_enums::AttemptStatus::AuthenticationPending,
_ => common_enums::AttemptStatus::Failure,
};
Copy link
Contributor

Choose a reason for hiding this comment

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

In this case the payment fails, we will throw FailedToObtainIntegrationUrl error which is not expected. When it is a failed payment, construct a ErrorResponse, instead TransactionResponse. Do the same for Psync

Instead of FailedToObtainIntegrationUrl error, throw a ParsingFailed error

Copy link
Contributor

Choose a reason for hiding this comment

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

What are the possible values for item.response.status_desc according to the connector doc

Comment on lines 334 to 335
pub debtor_name: String,
pub debtor_account: String,
Copy link
Contributor

Choose a reason for hiding this comment

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

Make these a secret value

Comment on lines 649 to 646
let signed_message = hmac::sign(&signing_key, &message);
println!("{:?}<<>>101", signed_message);
let computed_signature = hex::encode(signed_message.as_ref());
println!("{:?}<<>>102", computed_signature);
println!("{:?}<<>>102", computed_signature.to_lowercase());
let payload_sign = BASE64_ENGINE.encode(computed_signature);
println!("{:?}<<>>10", payload_sign);
println!("{:?}<<>>11", BASE64_ENGINE.decode(signature.to_owned()));
Ok(payload_sign.as_bytes().eq(&signature))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove all the loggers

@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 8, 2025
@ImSagnik007 ImSagnik007 changed the title feat(connector): [INESPAY] Sepa Bank Debit Auth and PSync Flow feat(connector): [INESPAY] Integrate Sepa Bank Debit Jan 9, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 9, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 9, 2025
AkshayaFoiger
AkshayaFoiger previously approved these changes Jan 13, 2025
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Jan 14, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Jan 15, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 15, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 15, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 16, 2025
@deepanshu-iiitu deepanshu-iiitu added the A-connector-integration Area: Connector integration label Jan 16, 2025
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Jan 20, 2025
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Jan 20, 2025
Copy link
Contributor

@ShankarSinghC ShankarSinghC left a comment

Choose a reason for hiding this comment

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

Add pr description.

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 M-api-contract-changes Metadata: This PR involves API contract changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] [INESPAY] Implement Sepa Bank Debit Flow
5 participants