hyperswitch icon indicating copy to clipboard operation
hyperswitch copied to clipboard

refactor(mandates): add validations for recurring mandates using payment_method_id

Open Chethan-rao opened this issue 11 months ago • 0 comments

Type of Change

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

Description

When a setup mandate is done with customer, when doing recurring payment using payment_method_id, this PR adds following validation

  • to match on customer_id such that they match on setup mandate as well as recurring.
  • to match on merchant_id such that they match on setup mandate as well as recurring.
  • not to pass both mandate_id and recurring_details

This PR also stores payment_method_id and payment_method_data in payment_attempt table when doing recurring payment with payment_method_id

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. Setup mandate with a customer
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: abc' \
--data-raw '{
    "amount": 0,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "customer_id": "test_cus4",
    "email": "[email protected]",
    "setup_future_usage": "off_session",
    "customer_acceptance": {
        "acceptance_type": "online"
    },
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "03",
            "card_exp_year": "2030",
            "card_holder_name": "Test Holder",
            "card_cvc": "737"
        }
    },
    "payment_type": "setup_mandate",
    "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]"
    },
    "authentication_type": "no_three_ds",
    "mandate_data": {
        "customer_acceptance": {
            "acceptance_type": "offline",
            "accepted_at": "1963-05-03T04:07:52.723Z",
            "online": {
                "ip_address": "153.54.53.134",
                "user_agent": "amet irure esse"
            }
        },
        "mandate_type": {
            "multi_use": null
        }
    }
}'
  1. Now try to do recurring payment usingpayment_method_id by passing different customer_id
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: abc' \
--data-raw '{
    "amount": 499,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "customer_id": "test_cus5",
    "email": "[email protected]",
    "off_session": true,
    "recurring_details": {
        "type": "payment_method_id",
        "data": "xyz"
    },
    "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]"
    },
    "authentication_type": "no_three_ds"
}'

image

  1. Now try to pass both mandate_id and recurring_details
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: abc' \
--data-raw '{
    "amount": 499,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "customer_id": "test_cus4",
    "email": "[email protected]",
    "off_session": true,
    "recurring_details": {
        "type": "payment_method_id",
        "data": "pm_7zf8MTSyG3h6grOBwPPc"
    },
    "mandate_id": "abc",
    "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]"
    },
    "authentication_type": "no_three_ds"
}'

image

  1. When recurring payment is done using payment_method_id, both payment_method_id and payment_method_data is getting stored in attempt table

image

Checklist

  • [x] I formatted the code cargo +nightly fmt --all
  • [x] I addressed lints thrown by cargo clippy
  • [x] I reviewed the submitted code
  • [ ] I added unit tests for my changes where possible
  • [ ] I added a CHANGELOG entry if applicable

Chethan-rao avatar Apr 01 '24 11:04 Chethan-rao