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): Integrate PAZE Wallet #6030

Merged
merged 22 commits into from
Oct 8, 2024
Merged

feat(connector): Integrate PAZE Wallet #6030

merged 22 commits into from
Oct 8, 2024

Conversation

deepanshu-iiitu
Copy link
Contributor

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

Type of Change

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

Description

New wallet Paze is integrated in Hyperswitch with Cybserource as the supported payment processor.

Additional Changes

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

Motivation and Context

#6028

How did you test it?

Paze Payments need to be tested via Cybersource:

  1. Payments Connector - Create:
    Request:
curl --location 'http://localhost:8080/account/merchant_1727784802/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "cybersource",
    "connector_account_details": {
        "auth_type": "SignatureKey",
        "api_secret": "Hidden",
        "api_key": "Hidden",
        "key1": "Hidden"
    },
    "test_mode": true,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "paze",
                    "payment_experience": "invoke_sdk_client",
                    "card_networks": null,
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ],
    "connector_wallets_details": {
        "paze": {
            "client_id": "Hidden",
            "client_name": "Hidden",
            "client_profile_id": "Hidden"
        }
    },
    "connector_webhook_details": {
        "merchant_secret": "MyWebhookSecret"
    },
    "metadata": {
        "city": "NY",
        "unit": "245"
    },
    "business_country": "US",
    "business_label": "default"
}'

Response:

{
    "connector_type": "payment_processor",
    "connector_name": "cybersource",
    "connector_label": "cybersource_US_default_default",
    "merchant_connector_id": "mca_LaFobeWWU3nzVfEQnMid",
    "profile_id": "pro_3BNSt57cBpRKDJzhCxfA",
    "connector_account_details": {
        "auth_type": "SignatureKey",
        "api_key": "********************************",
        "key1": "*************",
        "api_secret": "****************************************"
    },
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "payment_experience": null,
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "payment_experience": null,
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "paze",
                    "payment_experience": "invoke_sdk_client",
                    "card_networks": null,
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ],
    "connector_webhook_details": {
        "merchant_secret": "MyWebhookSecret",
        "additional_secret": null
    },
    "metadata": {
        "city": "NY",
        "unit": "245"
    },
    "test_mode": true,
    "disabled": false,
    "frm_configs": null,
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "applepay_verified_domains": null,
    "pm_auth_config": null,
    "status": "active",
    "additional_merchant_data": null,
    "connector_wallets_details": {
        "paze": {
            "client_id": "Hidden",
            "client_name": "Hidden",
            "client_profile_id": "Hidden"
        }
    }
}
  1. Sessions Call:
    Request:
curl --location 'http://localhost:8080/payments/session_tokens' \
--header 'Content-Type: application/json' \
--header 'api-key: pk_dev_1140ed2282ae444f83e6f632b93494c6' \
--data '{
    "payment_id": "pay_pu2Qby7cIiVAwj83fN6i",
    "wallets": [],
    "client_secret": "pay_pu2Qby7cIiVAwj83fN6i_secret_CP7BwLCIUk5SEMsyWxvq"
}'

Response:

{
    "payment_id": "pay_pu2Qby7cIiVAwj83fN6i",
    "client_secret": "pay_pu2Qby7cIiVAwj83fN6i_secret_CP7BwLCIUk5SEMsyWxvq",
    "session_token": [
        {
            "wallet_name": "paze",
            "client_id": "Hidden",
            "client_name": "Hidden",
            "client_profile_id": "Hidden"
        }
    ]
}
  1. Authorize Call:
    Request:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_QgqEI16yUU6qP3jOiSA3j2jbMhRbGL9JWvfXEwtTJuNgRESEP3sT8ERvUr0zfQlw' \
--data-raw '{
    "amount": 1234,
    "currency": "USD",
    "confirm": true,
    "customer_id": "customer123",
    "email": "guest@example.com",
    "payment_method": "wallet",
    "payment_method_type": "paze",
    "payment_method_data": {
        "wallet": {
            "paze": {
                "complete_response": "hidden"
            }
        }
    },
    "billing": {
        "address": {
            "first_name": "joseph",
            "last_name": "Doe"
        }
    }
}'

Response:

{
    "payment_id": "pay_zdsQ2IvNNzTzlXqRxcVf",
    "merchant_id": "merchant_1727784802",
    "status": "succeeded",
    "amount": 1234,
    "net_amount": 1234,
    "amount_capturable": 0,
    "amount_received": 1234,
    "connector": "cybersource",
    "client_secret": "pay_zdsQ2IvNNzTzlXqRxcVf_secret_7KXFE67dATn1TB5tystW",
    "created": "2024-10-02T19:01:05.077Z",
    "currency": "USD",
    "customer_id": "customer123",
    "customer": {
        "id": "customer123",
        "name": null,
        "email": "guest@example.com",
        "phone": null,
        "phone_country_code": null
    },
    "description": null,
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": null,
    "payment_method": "wallet",
    "payment_method_data": {
        "wallet": {},
        "billing": null
    },
    "payment_token": null,
    "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": "guest@example.com",
    "name": null,
    "phone": null,
    "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": "paze",
    "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": 1727895665,
        "expires": 1727899265,
        "secret": "epk_b224eba38d6043489989317e299307db"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "7278956668186980703954",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_zdsQ2IvNNzTzlXqRxcVf_1",
    "payment_link": null,
    "profile_id": "pro_3BNSt57cBpRKDJzhCxfA",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_Y57pUeM64cR6N1yMkABh",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-10-02T19:16:05.076Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-10-02T19:01:08.367Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": 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 25, 2024
@deepanshu-iiitu deepanshu-iiitu self-assigned this Sep 25, 2024
@deepanshu-iiitu deepanshu-iiitu requested review from a team as code owners September 25, 2024 13:09
Copy link

semanticdiff-com bot commented Sep 25, 2024

Review changes with SemanticDiff.

Analyzed 60 of 67 files.

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

File Information
Filename Status
✔️ crates/router/src/types/api.rs Analyzed
✔️ crates/router/src/types/transformers.rs 29.17% smaller
✔️ crates/router/src/core/errors.rs Analyzed
✔️ crates/router/src/core/payments.rs 42.37% smaller
✔️ crates/router/src/core/payments/helpers.rs Analyzed
✔️ crates/router/src/core/payments/tokenization.rs Analyzed
✔️ crates/router/src/core/payments/operations/payment_session.rs Analyzed
✔️ crates/router/src/core/payments/flows/session_flow.rs Analyzed
✔️ crates/router/src/connector/adyen.rs 43.9% smaller
✔️ crates/router/src/connector/klarna.rs 41.27% smaller
✔️ crates/router/src/connector/utils.rs Analyzed
✔️ crates/router/src/connector/zen/transformers.rs 34.15% smaller
✔️ crates/router/src/connector/worldpay/transformers.rs 34.15% smaller
✔️ crates/router/src/connector/wellsfargo/transformers.rs 11.13% smaller
✔️ crates/router/src/connector/stripe/transformers.rs 16.69% smaller
✔️ crates/router/src/connector/shift4/transformers.rs 34.15% smaller
✔️ crates/router/src/connector/paypal/transformers.rs 40.0% smaller
✔️ crates/router/src/connector/payme/transformers.rs 10.0% smaller
✔️ crates/router/src/connector/nuvei/transformers.rs 40.0% smaller
✔️ crates/router/src/connector/noon/transformers.rs 49.06% smaller
✔️ crates/router/src/connector/nmi/transformers.rs 40.0% smaller
✔️ crates/router/src/connector/nexinets/transformers.rs 27.03% smaller
✔️ crates/router/src/connector/multisafepay/transformers.rs 40.0% smaller
✔️ crates/router/src/connector/mifinity/transformers.rs 40.0% smaller
✔️ crates/router/src/connector/gocardless/transformers.rs 76.11% smaller
✔️ crates/router/src/connector/cybersource/transformers.rs 0.39% smaller
✔️ crates/router/src/connector/checkout/transformers.rs 10.0% smaller
✔️ crates/router/src/connector/braintree/transformers.rs Analyzed
✔️ crates/router/src/connector/boku/transformers.rs 27.03% smaller
✔️ crates/router/src/connector/bluesnap/transformers.rs 40.0% smaller
✔️ crates/router/src/connector/bankofamerica/transformers.rs 11.13% smaller
✔️ crates/router/src/connector/authorizedotnet/transformers.rs 27.03% smaller
✔️ crates/router/src/connector/airwallex/transformers.rs 27.03% smaller
✔️ crates/router/src/connector/adyen/transformers.rs 34.15% smaller
✔️ crates/router/src/connector/aci/transformers.rs 34.15% smaller
✔️ crates/router/src/configs/secrets_transformers.rs Analyzed
✔️ crates/router/src/configs/settings.rs Analyzed
✔️ crates/router/src/configs/validations.rs Analyzed
✔️ crates/openapi/src/openapi.rs 15.02% smaller
✔️ crates/openapi/src/openapi_v2.rs 15.55% smaller
✔️ crates/kgraph_utils/src/mca.rs Analyzed
✔️ crates/kgraph_utils/src/transformers.rs Analyzed
✔️ crates/hyperswitch_domain_models/src/payment_method_data.rs Analyzed
✔️ crates/hyperswitch_domain_models/src/router_data.rs Analyzed
✔️ crates/hyperswitch_connectors/src/utils.rs Analyzed
✔️ crates/hyperswitch_connectors/src/connectors/stax/transformers.rs Analyzed
✔️ crates/hyperswitch_connectors/src/connectors/square/transformers.rs 10.61% smaller
✔️ crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs Analyzed
✔️ crates/hyperswitch_connectors/src/connectors/globepay/transformers.rs 48.65% smaller
✔️ crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs 12.16% smaller
✔️ crates/euclid/src/frontend/dir/enums.rs Analyzed
✔️ crates/euclid/src/frontend/dir/lowering.rs Analyzed
✔️ crates/euclid/src/frontend/dir/transformers.rs Analyzed
✔️ crates/connector_configs/src/transformer.rs 88.24% smaller
✔️ crates/common_enums/src/enums.rs Analyzed
✔️ crates/common_enums/src/transformers.rs Analyzed
✔️ crates/api_models/src/admin.rs Analyzed
✔️ crates/api_models/src/payments.rs 1.57% smaller
config/config.example.toml Unsupported file format
config/development.toml Unsupported file format
config/docker_compose.toml Unsupported file format
config/deployments/env_specific.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
✔️ api-reference-v2/openapi_spec.json Analyzed
✔️ api-reference/openapi_spec.json Analyzed

@deepanshu-iiitu deepanshu-iiitu linked an issue Sep 25, 2024 that may be closed by this pull request
2 tasks
config/development.toml Show resolved Hide resolved
crates/api_models/src/payments.rs Outdated Show resolved Hide resolved
crates/api_models/src/payments.rs Outdated Show resolved Hide resolved
crates/router/src/configs/settings.rs Outdated Show resolved Hide resolved
crates/router/src/configs/settings.rs Show resolved Hide resolved
Comment on lines 1337 to 1349
let (first_name, last_name) = paze_data
.billing_address
.name
.unwrap_or(
item.router_data
.get_optional_billing()
.and_then(|address| address.get_optional_full_name())
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "billing_address.name",
})?,
)
.peek()
.split_once(' ')
Copy link
Member

Choose a reason for hiding this comment

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

This logic may be incorrect though, splitting on first space to obtain first name and last name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we add an additional check where if first_name or last_name are empty strings then we can throw missing field error?

Copy link
Member

Choose a reason for hiding this comment

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

I was thinking of situations where the beginning of the name contains initials, as in R. K. Narayan for example. There would be multiple edge cases honestly.

Do we have provision to accept first name and last name as two separate fields itself? If that's possible, I'd prefer we opt for it. If that's not possible, we may have to consider other options.

Also looping in @Narayanbhat166.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do have the provision to collect first_name and last_name at hyperswitch which I've fixed.

In case of the billing name coming from paze we only receive full name which is handled by splitting it on the first whitespace for now. Once we start testing on sandbox we can take further decision on how to handle this. This extensive testing is not possible from backend for now because we only have 1 paze payload.

crates/router/src/core/payments.rs Outdated Show resolved Hide resolved
config/config.example.toml Outdated Show resolved Hide resolved
Comment on lines +5015 to +5023
let paze_complete_response: Vec<&str> = paze_wallet_data
.complete_response
.peek()
.split('.')
.collect();
let encrypted_jwe_key = paze_complete_response
.get(1)
.ok_or(errors::PazeDecryptionError::DecryptionFailed)?
.to_string();
Copy link
Member

Choose a reason for hiding this comment

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

If this is handling JWT tokens, should we consider using a library like jsonwebtoken or josekit to decode the JWT token instead?

CC: @ShankarSinghC

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey @SanchithHegde
I am unable to find a function which returns the jwt payload. Can you help here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed we are going ahead with parsing this data without a library because we were unable to find this functionality in any existing library.

Comment on lines 1337 to 1349
let (first_name, last_name) = paze_data
.billing_address
.name
.unwrap_or(
item.router_data
.get_optional_billing()
.and_then(|address| address.get_optional_full_name())
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "billing_address.name",
})?,
)
.peek()
.split_once(' ')
Copy link
Member

Choose a reason for hiding this comment

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

I was thinking of situations where the beginning of the name contains initials, as in R. K. Narayan for example. There would be multiple edge cases honestly.

Do we have provision to accept first name and last name as two separate fields itself? If that's possible, I'd prefer we opt for it. If that's not possible, we may have to consider other options.

Also looping in @Narayanbhat166.

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.

I see that we are implementing Paze decryption flow where the decryption credentials reside in application env. Are we going to implement any other flows for Paze (like connector tokenization or decrypting Paze token with merchant provided key).

If yes, then we would need to check if the Paze metadata will changes in these cases. So that while implementing new flow for Paze we don't have worry about migration of backwards compatibility of connector_wallet_details.

crates/hyperswitch_domain_models/src/router_data.rs Outdated Show resolved Hide resolved
crates/router/src/core/payments.rs Outdated Show resolved Hide resolved
crates/router/src/core/payments.rs Outdated Show resolved Hide resolved
let decoded_paze_private_key = BASE64_ENGINE
.decode(paze_private_key.expose().as_bytes())
.change_context(errors::PazeDecryptionError::Base64DecodingFailed)?;
let decrypted_private_key = openssl::rsa::Rsa::private_key_from_pem_passphrase(
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to use some other library ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am unable to find a library which provides this functionality.
@SanchithHegde Can you please help here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed we are going ahead with using the openssl library because we are unable to find this functionality in other libraries.

crates/router/src/core/payments/helpers.rs Outdated Show resolved Hide resolved
crates/router/src/core/payments/helpers.rs Outdated Show resolved Hide resolved
@ShankarSinghC
Copy link
Contributor

The wallet details needs to populated in the payment attempt and payment response

"payment_method_data": {
        "wallet": {},
        "billing": null
    },

@deepanshu-iiitu
Copy link
Contributor Author

I see that we are implementing Paze decryption flow where the decryption credentials reside in application env. Are we going to implement any other flows for Paze (like connector tokenization or decrypting Paze token with merchant provided key).

If yes, then we would need to check if the Paze metadata will changes in these cases. So that while implementing new flow for Paze we don't have worry about migration of backwards compatibility of connector_wallet_details.

This is the only flow for Paze. In future we might implement connector tokenization flow but even in that connector wallet details won't change.

Copy link
Member

@SanchithHegde SanchithHegde left a comment

Choose a reason for hiding this comment

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

Other than that, looks good to me!

Comment on lines 2769 to 2775
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, utoipa::ToSchema)]
pub struct PazePaymentProcessingDetails {
#[schema(value_type = String)]
pub paze_private_key: Secret<String>,
#[schema(value_type = String)]
pub paze_private_key_passphrase: Secret<String>,
}
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I think we can remove the ToSchema derive?

pub async fn add_decrypted_payment_method_token<F, Req, D>(
tokenization_action: TokenizationAction,
payment_data: &D,
mut router_data: RouterData<F, Req, router_types::PaymentsResponseData>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to refactor the function so that instead of taking mut router_data, it returns only the PaymentMethodToken. Then, you can assign it to router_data.payment_method_token as needed.

Something like

router_data.payment_method_token = add_decrypted_payment_method_token(tokenization_action.clone(), payment_data)
    .await?;

@ShankarSinghC
Copy link
Contributor

The wallet details needs to populated in the payment attempt and payment response

"payment_method_data": {
        "wallet": {},
        "billing": null
    },

We are not getting payment_method_type in paze response and also we are not sure whether it is safe to expose last4 digits of card network token hence payment_method_data.wallet is currently kept None in payments response for paze.

@srujanchikke can you please confirm if this is fine ?

SamraatBansal
SamraatBansal previously approved these changes Oct 8, 2024
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Oct 8, 2024
@srujanchikke
Copy link
Contributor

The wallet details needs to populated in the payment attempt and payment response

"payment_method_data": {
        "wallet": {},
        "billing": null
    },

We are not getting payment_method_type in paze response and also we are not sure whether it is safe to expose last4 digits of card network token hence payment_method_data.wallet is currently kept None in payments response for paze.

@srujanchikke can you please confirm if this is fine ?

@ShankarSinghC Currently we are getting network transaction id from Paze which we are not sure either to display it's last numbers. We can update the payments response after we get clarification from Paze.
cc : @deepanshu-iiitu

chore: generate openapi spec

chore: generate openapi spec

chore: generate openapi spec
@likhinbopanna likhinbopanna added this pull request to the merge queue Oct 8, 2024
Merged via the queue into main with commit 535f2f1 Oct 8, 2024
14 of 17 checks passed
@likhinbopanna likhinbopanna deleted the paze branch October 8, 2024 13:43
@SanchithHegde SanchithHegde added the M-configuration-changes Metadata: This PR involves configuration changes label Oct 8, 2024
# 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 M-api-contract-changes Metadata: This PR involves API contract changes M-configuration-changes Metadata: This PR involves configuration changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] Implement Paze Wallet
6 participants