feat(core): Add record attempt operation for revenue recovery webhooks

## Type of Change
<!-- Put an `x` in the boxes that apply -->

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

## Description
<!-- Describe your changes in detail -->
**Revenue record operation** 
In revenue recovery webhook flow,  we mainly consume 3 types of events
1) PaymentFailure
2) PaymentSuccess
3) InvoiceCancel

For PaymentFailure or PaymentSuccess scenario we need to record the attempt and update the payment intent fields. This PR adds support for this operations.

**Why do we need to record the payment attempts ?**
To predict the next schedule time of mit transaction we need previous attempts information like error message, code and billing info, mandate details etc. So we store this info in payment_attempt against intent(invoice).

**Why do we need to update payment intent ?** 
Intent Status should be altered based on attempt status. Apart from this info like no of retries, payment method token details needs to be update in update trackers of record attempt operation.


### Additional Changes

- [x] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
Testcase 1: 
create payment connector mca : 
```
curl --location 'http://localhost:8080/v2/connector-accounts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-merchant-id: cloth_seller_FFzEuYGiJhp3SfL7AXoZ' \
--header 'x-profile-id: pro_gj36mgkfbJuFw2ZVvzX8' \
--header 'api-key: test_admin' \
--data '{
  "connector_type": "payment_processor",
  "connector_name": "stripe",
  "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "stripe apikey"
    },
  "connector_webhook_details": {
    "merchant_secret": ""
  },
  "profile_id": "pro_gj36mgkfbJuFw2ZVvzX8"
}'
```

response : 
```
{
    "connector_type": "payment_processor",
    "connector_name": "stripe",
    "connector_label": "stripe_business",
    "id": "mca_oAXqVf3BZs7bOS0iNhV7",
    "profile_id": "pro_gj36mgkfbJuFw2ZVvzX8",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "sk*******************************************************************************************************5b"
    },
    "payment_methods_enabled": null,
    "connector_webhook_details": {
        "merchant_secret": "",
        "additional_secret": null
    },
    "metadata": null,
    "disabled": false,
    "frm_configs": null,
    "applepay_verified_domains": null,
    "pm_auth_config": null,
    "status": "active",
    "additional_merchant_data": null,
    "connector_wallets_details": null,
    "feature_metadata": null
}
```
get the payment connector mca and create billing connector mca 

Create billing connector mca 

```
curl --location 'http://localhost:8080/v2/connector-accounts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-merchant-id: cloth_seller_FFzEuYGiJhp3SfL7AXoZ' \
--header 'x-profile-id: pro_gj36mgkfbJuFw2ZVvzX8' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "billing_processor",
    "connector_name": "chargebee",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "chargebee apikey"
    },
    "connector_webhook_details": {
        "merchant_secret": "chargebee",
        "additional_secret" : "password"
    },
       "feature_metadata" : {
        "revenue_recovery" : {
            "max_retry_count" : 27,
            "billing_connector_retry_threshold" : 16,
            "billing_account_reference" :{
                "mca_oAXqVf3BZs7bOS0iNhV7" : "gw_16BlyOUaPA0eq12MZ"
            }
        }
    },
    "profile_id": "pro_gj36mgkfbJuFw2ZVvzX8"
}'
```
response : 
```
{
    "connector_type": "payment_processor",
    "connector_name": "chargebee",
    "connector_label": "chargebee_business",
    "id": "mca_1WvloGjsk5KcxOZ6fBPd",
    "profile_id": "pro_gj36mgkfbJuFw2ZVvzX8",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "sk*******************************************************************************************************5b"
    },
    "payment_methods_enabled": null,
    "connector_webhook_details": {
        "merchant_secret": "chargebee",
        "additional_secret": "password"
    },
    "metadata": null,
    "disabled": false,
    "frm_configs": null,
    "applepay_verified_domains": null,
    "pm_auth_config": null,
    "status": "active",
    "additional_merchant_data": null,
    "connector_wallets_details": null,
    "feature_metadata": {
        "revenue_recovery": {
            "max_retry_count": 27,
            "billing_connector_retry_threshold": 16,
            "billing_account_reference": {
                "mca_oAXqVf3BZs7bOS0iNhV7": "gw_16BlyOUaPA0eq12MZ"
            }
        }
    }
}
```
Send chargebee simulated webhook either from dashboard or postman

request : 
```
curl --location 'http://localhost:8080/v2/webhooks/cloth_seller_FFzEuYGiJhp3SfL7AXoZ/pro_gj36mgkfbJuFw2ZVvzX8/mca_1WvloGjsk5KcxOZ6fBPd' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data-raw '{
  "id": "ev_169vy3UaPFn4L4mf",
  "occurred_at": 1737361021,
  "source": "admin_console",
  "user": "ns22eem1r18@student.nitw.ac.in",
  "object": "event",
  "api_version": "v2",
  "content": {
    "transaction": {
      "id": "txn_169vy3UaPFmC44me",
      "customer_id": "Azq8o5UaLqWWvyGd",
      "subscription_id": "Azq8o5UaLr2WnyHG",
      "gateway_account_id": "gw_16BlyOUaPA0eq12MZ",
      "payment_source_id": "pm_169vy3UaPDo0t4hL",
      "payment_method": "card",
      "gateway": "stripe",
      "type": "payment",
      "date": 1737361019,
      "exchange_rate": 1,
      "amount": 5,
      "id_at_gateway": "ch_3QjGAJSHworDX2hs0B120C0A",
      "status": "failure",
      "updated_at": 1737361021,
      "fraud_reason": "Payment complete.",
      "resource_version": 1737361021397,
      "deleted": false,
      "object": "transaction",
      "masked_card_number": "************4242",
      "currency_code": "INR",
      "base_currency_code": "INR",
      "amount_unused": 0,
      "linked_invoices": [
        {
          "invoice_id": "9",
          "applied_amount": 500000,
          "applied_at": 1737361021,
          "invoice_date": 1737361018,
          "invoice_total": 500000,
          "invoice_status": "paid"
        }
      ],
      "linked_refunds": [],
      "initiator_type": "merchant",
      "three_d_secure": false,
      "payment_method_details": "{\"card\":{\"first_name\":\"test2\",\"last_name\":\"name2\",\"iin\":\"424242\",\"last4\":\"4242\",\"funding_type\":\"credit\",\"expiry_month\":12,\"expiry_year\":2026,\"billing_addr1\":\"asdf\",\"billing_addr2\":\"asd\",\"billing_city\":\"asdf\",\"billing_state\":\"asdfaf\",\"billing_country\":\"AF\",\"billing_zip\":\"12345\",\"masked_number\":\"************4242\",\"object\":\"card\",\"brand\":\"visa\"}}"
    },
    "invoice": {
      "id": "invoice_1234",
      "customer_id": "Azq8o5UaLqWWvyGd",
      "subscription_id": "Azq8o5UaLr2WnyHG",
      "recurring": false,
      "status": "paid",
      "price_type": "tax_exclusive",
      "date": 1737361018,
      "due_date": 1737361018,
      "net_term_days": 0,
      "exchange_rate": 1,
      "total": 5,
      "amount_paid": 0,
      "amount_adjusted": 0,
      "write_off_amount": 0,
      "credits_applied": 0,
      "amount_due": 0,
      "paid_at": 1737361019,
      "updated_at": 1737361021,
      "resource_version": 1737361021401,
      "deleted": false,
      "object": "invoice",
      "first_invoice": false,
      "amount_to_collect": 0,
      "round_off_amount": 0,
      "has_advance_charges": false,
      "currency_code": "INR",
      "base_currency_code": "INR",
      "generated_at": 1737361018,
      "is_gifted": false,
      "term_finalized": true,
      "channel": "web",
      "tax": 0,
      "line_items": [
        {
          "id": "li_169vy3UaPFmBR4md",
          "date_from": 1737361004,
          "date_to": 1737361004,
          "unit_amount": 500000,
          "quantity": 1,
          "amount": 500000,
          "pricing_model": "flat_fee",
          "is_taxed": false,
          "tax_amount": 0,
          "object": "line_item",
          "subscription_id": "Azq8o5UaLr2WnyHG",
          "customer_id": "Azq8o5UaLqWWvyGd",
          "description": "Implementation Charge",
          "entity_type": "charge_item_price",
          "entity_id": "cbdemo_implementation-charge-INR",
          "tax_exempt_reason": "tax_not_configured",
          "discount_amount": 0,
          "item_level_discount_amount": 0
        }
      ],
      "sub_total": 500000,
      "linked_payments": [
        {
          "txn_id": "txn_169vy3UaPFmC44me",
          "applied_amount": 500000,
          "applied_at": 1737361021,
          "txn_status": "success",
          "txn_date": 1737361019,
          "txn_amount": 500000
        }
      ],
      "applied_credits": [],
      "adjustment_credit_notes": [],
      "issued_credit_notes": [],
      "linked_orders": [],
      "dunning_attempts": [],
      "billing_address": {
        "first_name": "test1",
        "last_name": "name",
        "email": "johndoe@gmail.com",
        "company": "johndoe",
        "phone": "+91 83 17 575848",
        "line1": "asdf",
        "line2": "asd",
        "line3": "ahjkd",
        "city": "asdf",
        "state_code": "TG",
        "state": "Telangana",
        "country": "IN",
        "zip": "561432",
        "validation_status": "not_validated",
        "object": "billing_address"
      },
      "site_details_at_creation": {
        "timezone": "Asia/Calcutta"
      }
    },
    "customer": {
      "id": "Azq8o5UaLqWWvyGd",
      "first_name": "john",
      "last_name": "doe",
      "email": "john@gmail.com",
      "phone": "831 757 5848",
      "company": "johndoe",
      "auto_collection": "on",
      "net_term_days": 0,
      "allow_direct_debit": false,
      "created_at": 1737310670,
      "created_from_ip": "205.254.163.189",
      "taxability": "taxable",
      "updated_at": 1737360899,
      "pii_cleared": "active",
      "channel": "web",
      "resource_version": 1737360899990,
      "deleted": false,
      "object": "customer",
      "billing_address": {
        "first_name": "test1",
        "last_name": "name",
        "email": "johndoe@gmail.com",
        "company": "johndoe",
        "phone": "+91 83 17 575848",
        "line1": "asdf",
        "line2": "asd",
        "line3": "ahjkd",
        "city": "asdf",
        "state_code": "TG",
        "state": "Telangana",
        "country": "IN",
        "zip": "561432",
        "validation_status": "not_validated",
        "object": "billing_address"
      },
      "card_status": "valid",
      "promotional_credits": 0,
      "refundable_credits": 0,
      "excess_payments": 0,
      "unbilled_charges": 0,
      "preferred_currency_code": "INR",
      "mrr": 0,
      "primary_payment_source_id": "pm_169vy3UaPDo0t4hL",
      "payment_method": {
        "object": "payment_method",
        "type": "card",
        "reference_id": "cus_RcUo8xTwe0sHP7/card_1QjG2dSHworDX2hs6YIjKdML",
        "gateway": "stripe",
        "gateway_account_id": "gw_16BlyOUaPA0eq12MZ",
        "status": "valid"
      }
    },
    "subscription": {
      "id": "Azq8o5UaLr2WnyHG",
      "billing_period": 1,
      "billing_period_unit": "month",
      "customer_id": "Azq8o5UaLqWWvyGd",
      "status": "active",
      "current_term_start": 1737310793,
      "current_term_end": 1739989193,
      "next_billing_at": 1739989193,
      "created_at": 1737310793,
      "started_at": 1737310793,
      "activated_at": 1737310793,
      "created_from_ip": "205.254.163.189",
      "updated_at": 1737310799,
      "has_scheduled_changes": false,
      "channel": "web",
      "resource_version": 1737310799688,
      "deleted": false,
      "object": "subscription",
      "currency_code": "INR",
      "subscription_items": [
        {
          "item_price_id": "cbdemo_premium-INR-monthly",
          "item_type": "plan",
          "quantity": 1,
          "unit_price": 100000,
          "amount": 0,
          "free_quantity": 3,
          "object": "subscription_item"
        }
      ],
      "shipping_address": {
        "first_name": "test1",
        "last_name": "name",
        "email": "johndoe@gmail.com",
        "company": "johndoe",
        "phone": "+91 83 17 575848",
        "line1": "asdf",
        "line2": "asd",
        "line3": "ahjkd",
        "city": "asdf",
        "state_code": "TG",
        "state": "Telangana",
        "country": "IN",
        "zip": "561432",
        "validation_status": "not_validated",
        "object": "shipping_address"
      },
      "due_invoices_count": 0,
      "mrr": 0,
      "exchange_rate": 1,
      "base_currency_code": "INR",
      "has_scheduled_advance_invoices": false
    }
  },
  "event_type": "payment_failed",
  "webhook_status": "scheduled",
  "webhooks": [
    {
      "id": "whv2_6oZfZUaLmtchA5Bl",
      "webhook_status": "scheduled",
      "object": "webhook"
    }
  ]
}'
```
This should create Payment intent, payment attempt in our system with right values in DB 

Payment intent details in DB 
![Screenshot 2025-03-05 at 12 43 36 PM](https://github.com/user-attachments/assets/a584e694-3c44-48ed-862f-eea8d756ecc3)

Payment attempt details in DB
![Screenshot 2025-03-05 at 12 41 02 PM](https://github.com/user-attachments/assets/3b9762b2-9c60-43c5-be93-646f74cacd38)


Test case 2 : 
change the transaction id in above simulated webhooks and hit the request again, it should create new payment attempt but update the payment intent feature metadata. 
![Screenshot 2025-03-05 at 1 20 35 PM](https://github.com/user-attachments/assets/f1926c83-d670-4c52-ae38-01cd39fb43e6)

Test case 3 : 
After passing succeded  transaction, we should not allow to record further transactions 
![Screenshot 2025-03-05 at 1 25 47 PM](https://github.com/user-attachments/assets/dd9b3540-9289-497d-8b8d-014b7b93b82d)


Note: This above webhook will still not recieve api response it will only create objects in our system .

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [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

<think>
PR Context:
- Title: feat(connector): Add support for chargebee recovery webhooks
- Merged: 2025-02-27T13:32:06Z
- Files changed: 16 files
- Commits: 30 commits

Implementation approach:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

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

## Description
<!-- Describe your changes in detail -->
Add support for chargebee passive churn recovery webhooks. This Pr also adds billing_processor as connector type.

### Additional Changes

- [x] This PR modifies the API contract
- [x] This PR modifies the database schema
- [ ] This PR m
</think>

To implement this, you'll need to modify:


**Detailed Implementation:**


**Commit 1:** feat(connector): Add support for chargebee recovery webhooks (#7110)
Co-authored-by: Chikke Srujan <
Files to modify:


**crates/api_models/src/enums.rs**
  Add:
    - function: pub::convert_billing_connector
    - enum: pub::BillingConnectors

**crates/common_enums/src/connector_enums.rs**
  Modify existing code

**crates/common_enums/src/enums.rs**
  Modify existing code

**crates/common_utils/src/id_type/payment.rs**
  Add:
    - function: private::from_str
    - impl: impl std::str::FromStr for PaymentReferenceId

**crates/connector_configs/src/connector.rs**
  Modify existing code

**crates/hyperswitch_connectors/src/connectors/chargebee.rs**
  Add:
    - function: private::get_webhook_source_verification_signature
    - function: private::verify_webhook_source
    - function: private::get_webhook_object_reference_id
    - function: private::get_webhook_event_type
    - function: private::get_revenue_recovery_attempt_details

**crates/hyperswitch_connectors/src/connectors/chargebee/transformers.rs**
  Add:
    - function: pub::get_webhook_object_from_body
    - function: pub::get_invoice_webhook_data_from_body
    - function: pub::find_connector_ids
    - function: private::try_from
    - function: private::from
    - function: private::from
    - function: private::from
    - function: private::from
    - function: private::try_from
    - struct: pub::ChargebeeWebhookBody
    - struct: pub::ChargebeeInvoiceBody
    - struct: pub::ChargebeeInvoiceContent
    - struct: pub::ChargebeeWebhookContent
    - struct: pub::ChargebeeInvoiceData
    - struct: pub::ChargebeeTransactionData
    - struct: pub::ChargebeePaymentMethodDetails
    - struct: pub::ChargebeeCardDetails
    - struct: pub::ChargebeeCustomer
    - struct: pub::ChargebeePaymentMethod
    - enum: pub::ChargebeeEventType
    - enum: pub::ChargebeeTransactionPaymentMethod
    - enum: pub::ChargebeeFundingType
    - enum: pub::ChargebeeTranasactionStatus
    - enum: pub::ChargebeeGateway
    - impl: impl ChargebeeWebhookBody
    - impl: impl ChargebeeInvoiceBody
    - impl: impl ChargebeeCustomer
    - impl: impl TryFrom<ChargebeeWebhookBody> for revenue_recovery::RevenueRecoveryAttemptData
    - impl: impl From<ChargebeeTranasactionStatus> for enums::AttemptStatus
    - impl: impl From<ChargebeeTransactionPaymentMethod> for enums::PaymentMethod
    - impl: impl From<ChargebeeFundingType> for enums::PaymentMethodType
    - impl: impl From<ChargebeeEventType> for api_models::webhooks::IncomingWebhookEvent
    - impl: impl TryFrom<ChargebeeInvoiceBody> for revenue_recovery::RevenueRecoveryInvoiceData

**crates/router/src/core/admin.rs**
  Modify existing code

**crates/router/src/types/api.rs**
  Modify existing code

**crates/router/src/types/transformers.rs**
  Modify existing code
{"issue_number": 7236, "pr_number": 7110, "commits_count": 1, "files_changed": 16, "response_length": 3587, "file_count": 12, "needs_breakdown": false}