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): [Placetopay] Implement Card 3ds #6834

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

Conversation

swangi-kumari
Copy link
Contributor

@swangi-kumari swangi-kumari commented Dec 13, 2024

Type of Change

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

Description

  • Implement Card 3ds for Placetopay
  • Add cypess test

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 Palcetopay connector
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_WeyuU18WAcC1A1eZdwLgYeseCxIXdjd1EKPl6kwGU7TuOJTSXnADv6HK9ihnTdt8' \
--data '{
    "amount":320320,
    "currency": "COP",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "customer_id": "deepanshu",
    "description": "Its my first payment request",
    "authentication_type": "three_ds",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": { 
        "card": {
            "card_number": "5292594382060745",
            "card_exp_month": "05",
            "card_exp_year": "25",
            "card_holder_name": "joseph",
            "card_cvc": "123"
        }
    },
    "return_url": "https://www.google.com/",
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "ip_address": "127.2.2.0"
    }
}'

Response

{
    "payment_id": "pay_qPIZkp7gtJ7FQySYwkvw",
    "merchant_id": "merchant_1734340438",
    "status": "requires_customer_action",
    "amount": 320320,
    "net_amount": 320320,
    "shipping_cost": null,
    "amount_capturable": 320320,
    "amount_received": null,
    "connector": "placetopay",
    "client_secret": "pay_qPIZkp7gtJ7FQySYwkvw_secret_yIKITy4TBbFJEJrwIrOu",
    "created": "2024-12-16T11:03:49.978Z",
    "currency": "COP",
    "customer_id": "deepanshu",
    "customer": {
        "id": "deepanshu",
        "name": null,
        "email": null,
        "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": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0745",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "529259",
            "card_extended_bin": null,
            "card_exp_month": "05",
            "card_exp_year": "25",
            "card_holder_name": "joseph",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": "token_GHvF1fAfROgMyBDjP07p",
    "shipping": null,
    "billing": null,
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": "https://www.google.com/",
    "authentication_type": "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_qPIZkp7gtJ7FQySYwkvw/merchant_1734340438/pay_qPIZkp7gtJ7FQySYwkvw_1"
    },
    "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": "deepanshu",
        "created_at": 1734347029,
        "expires": 1734350629,
        "secret": "epk_071566bc94d94ec29e62c784a2db42f8"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "263423",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_BAjOZ9EktLxLMBgVACoU",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_J1wN9t53lGx4un8XUQSY",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-12-16T11:18:49.978Z",
    "fingerprint": null,
    "browser_info": {
        "ip_address": "127.2.2.0",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-12-16T11:03:52.114Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}

Complete Payment using redirection link.

  1. Create Psync
curl --location 'http://localhost:8080/payments/pay_qPIZkp7gtJ7FQySYwkvw?force_sync=true' \
--header 'Accept: application/json' \
--header 'api-key: _'

Response

{
    "payment_id": "pay_qPIZkp7gtJ7FQySYwkvw",
    "merchant_id": "merchant_1734340438",
    "status": "succeeded",
    "amount": 320320,
    "net_amount": 320320,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 320320,
    "connector": "placetopay",
    "client_secret": "pay_qPIZkp7gtJ7FQySYwkvw_secret_yIKITy4TBbFJEJrwIrOu",
    "created": "2024-12-16T11:03:49.978Z",
    "currency": "COP",
    "customer_id": "deepanshu",
    "customer": {
        "id": "deepanshu",
        "name": null,
        "email": null,
        "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": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0745",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "529259",
            "card_extended_bin": null,
            "card_exp_month": "05",
            "card_exp_year": "25",
            "card_holder_name": "joseph",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": "token_GHvF1fAfROgMyBDjP07p",
    "shipping": null,
    "billing": null,
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": "https://www.google.com/",
    "authentication_type": "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": "credit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "263423",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_BAjOZ9EktLxLMBgVACoU",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_J1wN9t53lGx4un8XUQSY",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-12-16T11:18:49.978Z",
    "fingerprint": null,
    "browser_info": {
        "ip_address": "127.2.2.0",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-12-16T11:04:18.002Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null
}

Cypress Test
Screenshot 2024-12-17 at 4 47 44 PM

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

@swangi-kumari swangi-kumari added the A-connector-integration Area: Connector integration label Dec 13, 2024
@swangi-kumari swangi-kumari self-assigned this Dec 13, 2024
@swangi-kumari swangi-kumari requested review from a team as code owners December 13, 2024 08:13
Copy link

semanticdiff-com bot commented Dec 13, 2024

Review changes with  SemanticDiff

Changed Files
File Status
  crates/hyperswitch_connectors/src/connectors/placetopay.rs  12% smaller
  crates/hyperswitch_connectors/src/default_implementations.rs  5% smaller
  crates/hyperswitch_connectors/src/connectors/placetopay/transformers.rs  5% smaller
  config/config.example.toml Unsupported file format
  config/deployments/integration_test.toml Unsupported file format
  config/deployments/production.toml Unsupported file format
  config/deployments/sandbox.toml Unsupported file format
  config/development.toml Unsupported file format
  config/docker_compose.toml Unsupported file format
  cypress-tests/cypress/e2e/PaymentUtils/Commons.js  0% smaller
  cypress-tests/cypress/e2e/PaymentUtils/Placetopay.js  0% smaller
  cypress-tests/cypress/e2e/PaymentUtils/Utils.js  0% smaller

@swangi-kumari swangi-kumari added the C-feature Category: Feature request or enhancement label Dec 16, 2024
@@ -125,6 +126,7 @@ impl TryFrom<&PlacetopayRouterData<&types::PaymentsAuthorizeRouterData>>
.get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned())?,
cvv: req_card.card_cvc.clone(),
};
let return_url = item.router_data.request.complete_authorize_url.clone();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the request body same for 3ds and non-3ds request?
Should we pass complete_authorize_url in case of non-3ds payments?

Self::Charged
}
PlacetopayTransactionStatus::Approved => Self::Charged,
PlacetopayTransactionStatus::Ok => Self::AuthenticationPending,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we map ok to AuthenticationPending for non-3ds payments?

@swangi-kumari swangi-kumari requested a review from a team as a code owner December 17, 2024 14:18
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-feature Category: Feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants