diff --git a/src/domains/bizevents-app/04_apim_bizevents.tf b/src/domains/bizevents-app/04_apim_bizevents.tf index 2dc9cf04d3..049fb8bdb3 100644 --- a/src/domains/bizevents-app/04_apim_bizevents.tf +++ b/src/domains/bizevents-app/04_apim_bizevents.tf @@ -268,3 +268,45 @@ module "apim_api_bizevents_transactions_api_jwt_v1" { pdv_api_base_path = var.pdv_api_base_path }) } + + +resource "azurerm_api_management_api_version_set" "api_bizevents_transactions_api_apim_v2" { + count = var.env_short == "p" ? 1 : 0 + name = format("%s-bizevents-transaction-service-api", var.env_short) + resource_group_name = local.pagopa_apim_rg + api_management_name = "${local.product}-weu-core-apim-v2" + display_name = local.apim_transaction_service_api.display_name + versioning_scheme = "Segment" +} + + +module "apim_api_bizevents_transactions_api_jwt_v1_apim_v2" { + + count = var.env_short == "p" ? 1 : 0 + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api?ref=v6.4.1" + + name = format("%s-bizevents-transaction-service-api-jwt", local.project) + api_management_name = "${local.product}-weu-core-apim-v2" + resource_group_name = local.pagopa_apim_rg + product_ids = [module.apim_transactions_product.product_id] + # subscription_required = local.apim_transaction_service_api.subscription_required + subscription_required = false # use jwt + version_set_id = azurerm_api_management_api_version_set.api_bizevents_transactions_api_apim_v2[0].id + api_version = "v1" + + description = "${local.apim_transaction_service_api.description} JWT" + display_name = "${local.apim_transaction_service_api.display_name} JWT" + path = "${local.apim_transaction_service_api.path}-jwt" + protocols = ["https"] + service_url = local.apim_transaction_service_api.service_url + + content_format = "openapi" + content_value = templatefile("./api/transaction-service/v1/_openapi-jwt.json.tpl", { + host = local.apim_hostname + }) + + xml_content = templatefile("./api/transaction-service/v1/_base_policy-jwt.xml", { + hostname = local.bizevents_hostname + pdv_api_base_path = var.pdv_api_base_path + }) +} \ No newline at end of file diff --git a/src/domains/bizevents-app/README.md b/src/domains/bizevents-app/README.md index 013310504f..d30dc58066 100644 --- a/src/domains/bizevents-app/README.md +++ b/src/domains/bizevents-app/README.md @@ -17,6 +17,7 @@ | [apim\_api\_bizevents\_api\_v1](#module\_apim\_api\_bizevents\_api\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.4.1 | | [apim\_api\_bizevents\_helpdesk\_api\_v1](#module\_apim\_api\_bizevents\_helpdesk\_api\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.4.1 | | [apim\_api\_bizevents\_transactions\_api\_jwt\_v1](#module\_apim\_api\_bizevents\_transactions\_api\_jwt\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.4.1 | +| [apim\_api\_bizevents\_transactions\_api\_jwt\_v1\_apim\_v2](#module\_apim\_api\_bizevents\_transactions\_api\_jwt\_v1\_apim\_v2) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.4.1 | | [apim\_api\_bizevents\_transactions\_api\_v1](#module\_apim\_api\_bizevents\_transactions\_api\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.4.1 | | [apim\_bizevents\_helpdesk\_product](#module\_apim\_bizevents\_helpdesk\_product) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_product | v6.4.1 | | [apim\_bizevents\_product](#module\_apim\_bizevents\_product) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_product | v6.4.1 | @@ -31,6 +32,7 @@ | [azurerm_api_management_api_version_set.api_bizevents_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.api_bizevents_helpdesk_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.api_bizevents_transactions_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | +| [azurerm_api_management_api_version_set.api_bizevents_transactions_api_apim_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.api_bizevents_transactions_jwt_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_named_value.list_trx_for_io_api_key_secret](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | | [azurerm_api_management_named_value.list_trx_for_io_api_key_secret_apim_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | diff --git a/src/domains/bizevents-app/api/transaction-service/v1/_base_policy-jwt.xml b/src/domains/bizevents-app/api/transaction-service/v1/_base_policy-jwt.xml index 42584ed9ce..1abba51187 100644 --- a/src/domains/bizevents-app/api/transaction-service/v1/_base_policy-jwt.xml +++ b/src/domains/bizevents-app/api/transaction-service/v1/_base_policy-jwt.xml @@ -1,7 +1,6 @@ - @@ -14,10 +13,11 @@ - - + + - + diff --git a/src/domains/ecommerce-app/04_apim_ecommerce_io.tf b/src/domains/ecommerce-app/04_apim_ecommerce_io.tf index 90d377b88c..1360cc7c51 100644 --- a/src/domains/ecommerce-app/04_apim_ecommerce_io.tf +++ b/src/domains/ecommerce-app/04_apim_ecommerce_io.tf @@ -54,7 +54,7 @@ locals { display_name = "eCommerce API for IO App" description = "eCommerce pagoPA API dedicated to IO App for pagoPA payment" path = "ecommerce/io" - subscription_required = var.env_short == "p" + subscription_required = false service_url = null } @@ -243,7 +243,6 @@ resource "azurerm_api_management_api_operation_policy" "io_calculate_fee" { wallet-basepath = local.wallet_hostname } ) - } resource "azurerm_api_management_api_operation_policy" "io_transaction_outcome" { @@ -422,4 +421,13 @@ resource "azurerm_api_management_api_operation_policy" "io_wallets_by_user_v2" { }) } +resource "azurerm_api_management_api_operation_policy" "io_get_all_payment_methods" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + operation_id = "getAllPaymentMethodsForIO" + xml_content = templatefile("./api/ecommerce-io/v2/_get_payment_methods.xml.tpl", { + enabled_payment_wallet_method_ids_pm = var.enabled_payment_wallet_method_ids_pm + }) +} diff --git a/src/domains/ecommerce-app/04_apim_ecommerce_io_v2.tf b/src/domains/ecommerce-app/04_apim_ecommerce_io_v2.tf new file mode 100644 index 0000000000..e83c3bdf98 --- /dev/null +++ b/src/domains/ecommerce-app/04_apim_ecommerce_io_v2.tf @@ -0,0 +1,146 @@ +########################### +### ### +### ECOMMERCE IO V2 ### +### ### +########################### + +resource "azurerm_api_management_api_version_set" "apim_v2_ecommerce_io_api_v1" { + name = "${local.project}-ecommerce-io-api" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + display_name = local.apim_ecommerce_io_api.display_name + versioning_scheme = "Segment" +} + +resource "azurerm_api_management_named_value" "apim_v2_pay_wallet_family_friends_user_ids" { + name = "pay-wallet-family-friends-user-ids" + api_management_name = local.pagopa_apim_v2 + resource_group_name = local.pagopa_apim_rg + display_name = "pay-wallet-family-friends-user-ids" + value = "" + lifecycle { + ignore_changes = [ + value, + ] + } +} + +module "apim_v2_ecommerce_io_api_v2" { + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api?ref=v6.6.0" + + name = "${local.project}-ecommerce-io-api" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + product_ids = [module.apim_ecommerce_io_product.product_id] + subscription_required = local.apim_ecommerce_io_api.subscription_required + version_set_id = azurerm_api_management_api_version_set.apim_v2_ecommerce_io_api_v1.id + api_version = "v2" + service_url = local.apim_ecommerce_io_api.service_url + + description = local.apim_ecommerce_io_api.description + display_name = local.apim_ecommerce_io_api.display_name + path = local.apim_ecommerce_io_api.path + protocols = ["https"] + + content_format = "openapi" + content_value = templatefile("./api/ecommerce-io/v2/_openapi.json.tpl", { + host = local.apim_hostname + }) + + xml_content = templatefile("./api/ecommerce-io/v2/_base_policy.xml.tpl", { + ecommerce_ingress_hostname = local.ecommerce_hostname + wallet_ingress_hostname = local.wallet_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_io_post_wallet_transactions_v2" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "createWalletForTransactionsForIO" + + xml_content = templatefile("./api/ecommerce-io/v2/_wallet_transactions.xml.tpl", { + wallet-basepath = local.wallet_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_io_transaction_authorization_request_v2" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "requestTransactionAuthorizationForIO" + + xml_content = templatefile("./api/ecommerce-io/v2/_auth_request.xml.tpl", { + authurl-basepath = var.env_short == "d" ? local.apim_hostname : "{{wisp2-gov-it}}" + wallet-basepath = local.wallet_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_io_calculate_fee_v2" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "calculateFeesForIO" + + xml_content = templatefile("./api/ecommerce-io/v2/_calculate_fees_policy.xml.tpl", + { + ecommerce-basepath = local.ecommerce_hostname + wallet-basepath = local.wallet_hostname + } + ) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_delete_transactions_v2" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "requestTransactionUserCancellationForIO" + + xml_content = templatefile("./api/ecommerce-io/v2/_delete_transaction.xml.tpl", { + wallet-basepath = local.wallet_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_get_transactions_v2" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "getTransactionInfoForIO" + + xml_content = templatefile("./api/ecommerce-io/v2/get_transaction.xml.tpl", { + wallet-basepath = local.wallet_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_create_transactions_v2" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "newTransactionForIO" + + xml_content = templatefile("./api/ecommerce-io/v2/post_transactions.xml.tpl", { + ecommerce_ingress_hostname = local.ecommerce_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_io_wallets_by_user_v2" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "getWalletsByIdIOUser" + + xml_content = templatefile("./api/ecommerce-io/v2/_get_wallets_by_user_with_pm.xml.tpl", { + ecommerce-hostname = local.ecommerce_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "apim_v2_io_get_all_payment_methods" { + api_name = "${local.project}-ecommerce-io-api-v2" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_v2 + operation_id = "getAllPaymentMethodsForIO" + + xml_content = templatefile("./api/ecommerce-io/v2/_get_payment_methods.xml.tpl", { + enabled_payment_wallet_method_ids_pm = var.enabled_payment_wallet_method_ids_pm + }) +} diff --git a/src/domains/ecommerce-app/99_locals.tf b/src/domains/ecommerce-app/99_locals.tf index b450f52f91..0ddc71678e 100644 --- a/src/domains/ecommerce-app/99_locals.tf +++ b/src/domains/ecommerce-app/99_locals.tf @@ -30,6 +30,7 @@ locals { pagopa_apim_name = "${local.product}-apim" pagopa_apim_rg = "${local.product}-api-rg" pagopa_apim_snet = "${local.product}-apim-snet" + pagopa_apim_v2 = "${local.product}-weu-core-apim-v2" pagopa_vnet_integration = "pagopa-${var.env_short}-vnet-integration" pagopa_vnet_rg = "pagopa-${var.env_short}-vnet-rg" diff --git a/src/domains/ecommerce-app/99_variables.tf b/src/domains/ecommerce-app/99_variables.tf index 9efc83a77e..bc538dbb0b 100644 --- a/src/domains/ecommerce-app/99_variables.tf +++ b/src/domains/ecommerce-app/99_variables.tf @@ -162,4 +162,10 @@ variable "pdv_api_base_path" { type = string default = null description = "Personal data vault api base path" -} \ No newline at end of file +} + +variable "enabled_payment_wallet_method_ids_pm" { + type = string + default = "" + description = "Comma separated list of eCommerce payment method ids that are enabled with PM APIs" +} diff --git a/src/domains/ecommerce-app/README.md b/src/domains/ecommerce-app/README.md index 67c5fcbd25..faa3f0cc37 100644 --- a/src/domains/ecommerce-app/README.md +++ b/src/domains/ecommerce-app/README.md @@ -38,6 +38,7 @@ | [apim\_pagopa\_ecommerce\_helpdesk\_service\_api\_v1](#module\_apim\_pagopa\_ecommerce\_helpdesk\_service\_api\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.6.0 | | [apim\_pagopa\_ecommerce\_technical\_helpdesk\_service\_api\_v1](#module\_apim\_pagopa\_ecommerce\_technical\_helpdesk\_service\_api\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.6.0 | | [apim\_pagopa\_notifications\_service\_api\_v1](#module\_apim\_pagopa\_notifications\_service\_api\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.6.0 | +| [apim\_v2\_ecommerce\_io\_api\_v2](#module\_apim\_v2\_ecommerce\_io\_api\_v2) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.6.0 | | [pod\_identity](#module\_pod\_identity) | git::https://github.com/pagopa/terraform-azurerm-v3.git//kubernetes_pod_identity | v6.6.0 | | [tls\_checker](#module\_tls\_checker) | git::https://github.com/pagopa/terraform-azurerm-v3.git//tls_checker | v6.7.0 | @@ -53,6 +54,14 @@ | [azurerm_api_management_api.apim_ecommerce_npg_mock](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api) | resource | | [azurerm_api_management_api.apim_ecommerce_npg_notifications](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api) | resource | | [azurerm_api_management_api.apim_ecommerce_pdv_mock](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_create_transactions_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_delete_transactions_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_get_transactions_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_io_calculate_fee_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_io_get_all_payment_methods](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_io_post_wallet_transactions_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_io_transaction_authorization_request_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.apim_v2_io_wallets_by_user_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.auth_request_gateway_policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.confirm_payment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.create_session](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | @@ -76,6 +85,7 @@ | [azurerm_api_management_api_operation_policy.io_create_session](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.io_create_transaction](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.io_delete_transaction](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.io_get_all_payment_methods](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.io_get_transaction_info](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.io_post_wallet_transactions](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.io_post_wallet_transactions_v2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | @@ -107,6 +117,7 @@ | [azurerm_api_management_api_version_set.apim_ecommerce_pdv_mock_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.apim_ecommerce_redirect_outcome_api_v1](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.apim_ecommerce_webview_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | +| [azurerm_api_management_api_version_set.apim_v2_ecommerce_io_api_v1](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.ecommerce_checkout_api_v1](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.ecommerce_io_api_v1](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.ecommerce_io_outcomes_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | @@ -120,6 +131,7 @@ | [azurerm_api_management_api_version_set.pagopa_ecommerce_technical_helpdesk_service_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.pagopa_notifications_service_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_group.ecommerce-methods-full-read](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_group) | resource | +| [azurerm_api_management_named_value.apim_v2_pay_wallet_family_friends_user_ids](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | | [azurerm_api_management_named_value.ecommerce-io-jwt-signing-key](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | | [azurerm_api_management_named_value.ecommerce-personal-data-vault-api-key](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | | [azurerm_api_management_named_value.ecommerce-webview-jwt-signing-key](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | @@ -180,6 +192,7 @@ | [ecommerce\_io\_with\_pm\_enabled](#input\_ecommerce\_io\_with\_pm\_enabled) | ecommerce for IO using Payment Manager enabled | `bool` | `false` | no | | [ecommerce\_vpos\_psps\_list](#input\_ecommerce\_vpos\_psps\_list) | psps list using vpos as comma separated value | `string` | `""` | no | | [ecommerce\_xpay\_psps\_list](#input\_ecommerce\_xpay\_psps\_list) | psps list using xpay as comma separated value | `string` | `""` | no | +| [enabled\_payment\_wallet\_method\_ids\_pm](#input\_enabled\_payment\_wallet\_method\_ids\_pm) | Comma separated list of eCommerce payment method ids that are enabled with PM APIs | `string` | `""` | no | | [env](#input\_env) | n/a | `string` | n/a | yes | | [env\_short](#input\_env\_short) | n/a | `string` | n/a | yes | | [external\_domain](#input\_external\_domain) | Domain for delegation | `string` | `null` | no | diff --git a/src/domains/ecommerce-app/api/ecommerce-io/v2/_auth_request.xml.tpl b/src/domains/ecommerce-app/api/ecommerce-io/v2/_auth_request.xml.tpl index 5e8bdf83c2..7eac7ea38f 100644 --- a/src/domains/ecommerce-app/api/ecommerce-io/v2/_auth_request.xml.tpl +++ b/src/domains/ecommerce-app/api/ecommerce-io/v2/_auth_request.xml.tpl @@ -18,9 +18,8 @@ - - + - + @{ JObject inBody = context.Response.Body.As(preserveContent: true); var authorizationUrl = (string)inBody["authorizationUrl"]; diff --git a/src/domains/ecommerce-app/api/ecommerce-io/v2/_base_policy.xml.tpl b/src/domains/ecommerce-app/api/ecommerce-io/v2/_base_policy.xml.tpl index 3ebd65cc00..bd35e67b51 100644 --- a/src/domains/ecommerce-app/api/ecommerce-io/v2/_base_policy.xml.tpl +++ b/src/domains/ecommerce-app/api/ecommerce-io/v2/_base_policy.xml.tpl @@ -12,9 +12,12 @@ + + - + diff --git a/src/domains/ecommerce-app/api/ecommerce-io/v2/_calculate_fees_policy.xml.tpl b/src/domains/ecommerce-app/api/ecommerce-io/v2/_calculate_fees_policy.xml.tpl index db45472422..6b8da79a3f 100644 --- a/src/domains/ecommerce-app/api/ecommerce-io/v2/_calculate_fees_policy.xml.tpl +++ b/src/domains/ecommerce-app/api/ecommerce-io/v2/_calculate_fees_policy.xml.tpl @@ -45,7 +45,7 @@ - + diff --git a/src/domains/ecommerce-app/api/ecommerce-io/v2/_delete_transaction.xml.tpl b/src/domains/ecommerce-app/api/ecommerce-io/v2/_delete_transaction.xml.tpl index 966d1cfa17..5b5e87fc28 100644 --- a/src/domains/ecommerce-app/api/ecommerce-io/v2/_delete_transaction.xml.tpl +++ b/src/domains/ecommerce-app/api/ecommerce-io/v2/_delete_transaction.xml.tpl @@ -2,7 +2,7 @@ - + + + + + + + + + + + + + + @{ + JObject response = context.Response.Body.As(); + + if (context.Response.StatusCode != 200) { + return response.ToString(); + } + + string enabled_payment_wallet_method_ids_pm = "${enabled_payment_wallet_method_ids_pm}"; + string[] values = enabled_payment_wallet_method_ids_pm.Split(','); + HashSet pmEnabledMethods = new HashSet(values); + + foreach (var method in ((JArray) response["paymentMethods"])) { + string id = (string) method["id"]; + if (pmEnabledMethods.Contains(id)) { + method["status"] = "ENABLED"; + method["methodManagement"] = "ONBOARDABLE_ONLY"; + } else { + method["status"] = "DISABLED"; + } + } + + return response.ToString(); + } + + + + + + + + + + + diff --git a/src/domains/ecommerce-app/api/ecommerce-io/v2/_get_wallets_by_user_with_pm.xml.tpl b/src/domains/ecommerce-app/api/ecommerce-io/v2/_get_wallets_by_user_with_pm.xml.tpl index 7bf84c9b46..f875691f13 100644 --- a/src/domains/ecommerce-app/api/ecommerce-io/v2/_get_wallets_by_user_with_pm.xml.tpl +++ b/src/domains/ecommerce-app/api/ecommerce-io/v2/_get_wallets_by_user_with_pm.xml.tpl @@ -2,7 +2,7 @@ - + @@ -14,6 +14,21 @@ + + + + + application/json + + + { + "title": "Unauthorized", + "status": 401, + "detail": "Unauthorized" + } + + + diff --git a/src/domains/ecommerce-app/api/ecommerce-io/v2/get_transaction.xml.tpl b/src/domains/ecommerce-app/api/ecommerce-io/v2/get_transaction.xml.tpl index d96ca36a62..f54f5090d3 100644 --- a/src/domains/ecommerce-app/api/ecommerce-io/v2/get_transaction.xml.tpl +++ b/src/domains/ecommerce-app/api/ecommerce-io/v2/get_transaction.xml.tpl @@ -2,7 +2,7 @@ - + - + @@ -102,7 +102,7 @@ - + @@ -153,7 +153,7 @@ - + { "status": 502, diff --git a/src/domains/ecommerce-app/env/weu-dev/terraform.tfvars b/src/domains/ecommerce-app/env/weu-dev/terraform.tfvars index 88886bb368..20e1559794 100644 --- a/src/domains/ecommerce-app/env/weu-dev/terraform.tfvars +++ b/src/domains/ecommerce-app/env/weu-dev/terraform.tfvars @@ -41,3 +41,5 @@ dns_zone_checkout = "dev.checkout" io_backend_base_path = "http://{{aks-lb-nexi}}/pmmockservice/pmmockserviceapi" ecommerce_io_with_pm_enabled = false pdv_api_base_path = "https://api.uat.tokenizer.pdv.pagopa.it/tokenizer/v1" + +enabled_payment_wallet_method_ids_pm = "9d735400-9450-4f7e-9431-8c1e7fa2a339,148ff003-46a6-4790-9376-b0e057352e45,ab2c39be-91ad-4c87-944a-a08f30e92cad" diff --git a/src/domains/ecommerce-app/env/weu-prod/terraform.tfvars b/src/domains/ecommerce-app/env/weu-prod/terraform.tfvars index b8071112ae..82bca931e2 100644 --- a/src/domains/ecommerce-app/env/weu-prod/terraform.tfvars +++ b/src/domains/ecommerce-app/env/weu-prod/terraform.tfvars @@ -89,3 +89,5 @@ pod_disruption_budgets = { io_backend_base_path = "https://disabled" ecommerce_io_with_pm_enabled = false pdv_api_base_path = "https://disabled" + +enabled_payment_wallet_method_ids_pm = "6920b555-c972-4e2b-980c-b0e0037a111a,0ff153c2-4c5e-49a5-8720-788b6f190264,b63dbc2b-0b89-4431-a196-a5d73ff7ce9c" diff --git a/src/domains/ecommerce-app/env/weu-uat/terraform.tfvars b/src/domains/ecommerce-app/env/weu-uat/terraform.tfvars index 32fa088175..bb1c07ccff 100644 --- a/src/domains/ecommerce-app/env/weu-uat/terraform.tfvars +++ b/src/domains/ecommerce-app/env/weu-uat/terraform.tfvars @@ -41,3 +41,5 @@ dns_zone_checkout = "uat.checkout" io_backend_base_path = "https://api-app.io.pagopa.it" ecommerce_io_with_pm_enabled = false pdv_api_base_path = "https://api.uat.tokenizer.pdv.pagopa.it/tokenizer/v1" + +enabled_payment_wallet_method_ids_pm = "f25399bf-c56f-4bd2-adc9-7aef87410609,0d1450f4-b993-4f89-af5a-1770a45f5d71,5bdc0d63-a5b8-4221-bbb1-3e8b45a1b40f" diff --git a/src/domains/pay-wallet-app-v2/.terraform.lock.hcl b/src/domains/pay-wallet-app-v2/.terraform.lock.hcl new file mode 100644 index 0000000000..6463bb22ff --- /dev/null +++ b/src/domains/pay-wallet-app-v2/.terraform.lock.hcl @@ -0,0 +1,140 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/azure/azapi" { + version = "1.3.0" + constraints = "<= 1.3.0" + hashes = [ + "h1:OWZNYEGEIunmpxEcbGveH+kkdELQfMCUYxLt1b25UOc=", + "h1:h/ZVYAapVQ+W0R4P5IK/Mvsi84jiYTggmgJHZgfVbfg=", + "zh:0923b297c5b71ed584e5f3a0b2393e80244076e85102a90438159833353274b0", + "zh:11fa2922aa98ca55beaf7cc33c7edbde81bbd405fdfea2955276c7f5a8537240", + "zh:14af830fb6091d084bfc2711c8e9c7bf05aa3c56fe8fd8e2fb4eddeb345be88d", + "zh:25258425ecbffbdf09b0c8131d2c680cddd19b504e0036ee5f83972dcae7df0a", + "zh:2922b535fe4d4f0963189548f2f8360a0aaf951fd411354f2269a111d8a0c1ad", + "zh:32c9360305e00c25d0f9d0a84dfbdbad8da2465be769a9c1f11f132c0225358e", + "zh:4ddd3ee23c340d5000839d8d30ba7f94e695476d63075f95cfb041e67d8f6ef6", + "zh:5c1514392a5c3dd51084aa70cb6c4dcc8b027c4508b5e4eb9f8c3990fd403213", + "zh:6b3ecac7099ab86c007b5ad636bd029f5e5f3e9bd06b0f74c82f0451a7995ecc", + "zh:6cb7081745b378e910e0cf09fb5717a2ad35e629ce3e07415d6682c1c1407872", + "zh:7107eda5125c1b983380f1f6418c592fb7fb2eb5b589ad0e08f6c47341f36318", + "zh:c6fa7af32a7a47d23a85e0eea4d4cbb065378ae75aed8c9c628fb625b04bc619", + ] +} + +provider "registry.terraform.io/hashicorp/azuread" { + version = "2.47.0" + constraints = "<= 2.47.0" + hashes = [ + "h1:8J74v92UvtqVNucugAtB+Sd44oTgnhfct+Xf8ObOZug=", + "h1:KB9BNRNStbdsfdRmVXUwXtN77qgX5VjBy2UALcqp218=", + "h1:g8+gBFM4QVOEQFqAEs5pR6iXpbGvgPvcEi1evHwziyw=", + "h1:iRwDQBdXBpVBoYwM9au2RG01RQuJSm3TGQ2kioFVAas=", + "h1:zYMGokLn44KSWir7Nr4t8lEAPMB6JuXd2LlP2Ac2tMY=", + "zh:1372d81eb24ef3b4b00ea350fe87219f22da51691b8e42ce91d662f6c2a8af5e", + "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", + "zh:1e654a74d171d6ff8f9f6f67e3ff1421d4c5e56a18607703626bf12cd23ba001", + "zh:35227fad617a0509c64ab5759a8b703b10d244877f1aa5416bfbcc100c96996f", + "zh:357f553f0d78d46a96c7b2ed06d25ee0fc60fc5be19812ccb5d969fa47d62e17", + "zh:58faa2940065137e3e87d02eba59ab5cd7137d7a18caf225e660d1788f274569", + "zh:7308eda0339620fa24f47cedd22221fc2c02cab9d5be1710c09a783aea84eb3a", + "zh:863eabf7f908a8263e28d8aa2ad1381affd6bb5c67755216781f674ef214100e", + "zh:8b95b595a7c14ed7b56194d03cdec253527e7a146c1c58961be09e6b5c50baee", + "zh:afbca6b4fac9a0a488bc22ff9e51a8f14e986137d25275068fd932f379a51d57", + "zh:c6aadec4c81a44c3ffc22c2d90ffc6706bf5a9a903a395d896477516f4be6cbb", + "zh:e54a59de7d4ef0f3a18f91fed0b54a2bce18257ae2ee1df8a88226e1023c5811", + ] +} + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "3.45.0" + constraints = ">= 3.30.0, ~> 3.30, <= 3.45.0, <= 3.95.0, <= 3.97.1" + hashes = [ + "h1:VQWxV5+qelZeUCjpdLvZ7iAom4RvG+fVVgK6ELvw/cs=", + "h1:gQLNY1I5e9kcle1p/VYEWb0eteQ/t5kUfnqVu2/GBNY=", + "zh:04c5dbb8845366ce5eb0dc2d55e151270cc2c0ace20993867fdae9af43b953ad", + "zh:2589585da615ccae341400d45d672ee3fae413fdd88449b5befeff12a85a44b2", + "zh:603869ed98fff5d9bf841a51afd9e06b628533c59356c8433aef4b15df63f5f7", + "zh:853fecab9c987b6772c8d9aa10362675f6c626b60ebc7118aa33ce91366fcc38", + "zh:979848c45e8e058862c36ba3a661457f7c81ef26ebb6634f479600de9c203d65", + "zh:9b512c8588ecc9c1b803b746a3a8517422561a918f0dfb0faaa707ed53ef1760", + "zh:a9601ffb58043426bcff1220662d6d137f0b2857a24f2dcf180aeac2c9cea688", + "zh:d52d2652328f0ed3ba202561d88cb9f43c174edbfaab1abf69f772125dbfe15e", + "zh:d92d91ca597c47f575bf3ae129f4b723be9b7dcb71b906ec6ec740fac29b1aaa", + "zh:ded73b730e4197b70fda9e83447c119f92f75dc37be3ff2ed45730c8f0348c28", + "zh:ec37ac332d50f8ca5827f97198346b0f8ecbf470e2e3ba1e027bb389d826b902", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/helm" { + version = "2.12.0" + constraints = "<= 2.12.0" + hashes = [ + "h1:8EsvI/hOM9Q9ltVhkQfeK2NF4cr0RxHiUPqdmddcKHI=", + "h1:N29oQNxmZR0tOdpUSeHZCLY/ML0Pa14a+CqDbBApSuw=", + "h1:ZNtHw95EKvgnnU+1B7dLpF0bFvTFJKc4I7RwDCVy7Vs=", + "h1:nk9CCuHkvoJZbbI90ybKiVlU2SUQCIdsmREzOoDtY8Q=", + "h1:q2t74cDvT3Ig4DlkCpk0Rqslc5FUs6I40dRdkMWZX4E=", + "zh:08aa5b177db2603a0ecf9728f867cbccbd663f4a3867251729604692c21cd28f", + "zh:13ce638a3f5f88c9e0da951472619d4449172a3f5cb0332eaba87964456c88ac", + "zh:43e90052d05a4adde7aab9df2d6b807de0bbae550a9b7a76f93d946c30cf9814", + "zh:4451cf0f8bd3a62a72451d0941eb936b2ff5089bf7acf80a28d82f486e19188e", + "zh:490ce970334cf398dc48bf9239854578a4d1ef7227048606ee4bb838a83d231e", + "zh:97c14100faeb8c9e237338925b3f2443489e6099684f8636c966dad05c19a6f6", + "zh:9da8bb2250ff9a160279206563957f25ae4ba0242698dc22181d677a6ff13aba", + "zh:a4bb8fea89baae7bb1a7c0a99d32e4e39c9ad822efa8ad76821cabf3b5f0da5b", + "zh:c006da0cb8e80d37f7386336671018b3e437113a9fd54b32954b454731da6376", + "zh:da8d7c2b7c8256f2c0c968a2e1690ffb7a183a3daa911e98fa15f6d2c0562ea1", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fedf8e76f2d03de84819f0192974433b13dc668f901e98672af05e3d3fd13a03", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.26.0" + constraints = "<= 2.26.0, <= 2.27.0" + hashes = [ + "h1:0MjgW/qkJH4udWwTiSpjqA8AmEjVwrQzpkV2bu8+LhY=", + "h1:LxZk5Vc0TnfeLYnp7HXZui53PEV+gFd+mznBzdNm+po=", + "h1:MMxX/EY9AEGwp5DbGQ+LTd3c9YmjwrnPJHLlyc9u0eU=", + "h1:vTbi/tiJQS8Wto3LLxZ/WWPcptqaMpQlT33s61WTV9Q=", + "h1:wSFDvzim4kD1iieFFuQJ+cd/TqmpHJTomnK4ktj1mrw=", + "zh:3f8ee1bffab1ba4f6ae549daae1648974214880d3606b6821cb0aceb365284a4", + "zh:5596b1248231cc3b8f6a98f5b78df7120cd3153fd2b34b369dc20356a75bf35b", + "zh:64420c9e4aa49c5e443afcd60f3e8d293ea6bd78797d402e21e23605f7757954", + "zh:8327a488854e15f8d7eaf8272c3b9d6d1d9a6e68212a8dcb111d7b4023aac6b5", + "zh:94c1c9b65280847d28a3e90e5046650858ac0bf87feefd2349336444e21e68e8", + "zh:a3fb0b0b4bfd1844bb94011ae80111cedc188085235cf466313ca2151e75c8ca", + "zh:ab5e381928144e0c2a9d9768a48e38797642e5c5fb2184370c7c08df500e5db3", + "zh:da78995e8d6daf3acfd4c455ebbd12f6bf154cadf455f14ef35c0862e58dd2ec", + "zh:e24cdd5b90196df93215f40d821af3a7b4473c53992be4c3038940d117a50eb4", + "zh:e632efb3bce6d089b7c08507660af8b2c5e3f94c34fe401bfa228f154405e26e", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f5aea9da0eba25d35fee49db193c4b44cd3746a5578065092c62a53077e50b84", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.1" + constraints = "<= 3.2.1" + hashes = [ + "h1:FbGfc+muBsC17Ohy5g806iuI1hQc4SIexpYCrQHQd8w=", + "h1:tSj1mL6OQ8ILGqR2mDu7OYYYWf+hoir0pf9KAQ8IzO8=", + "h1:vUW21lLLsKlxtBf0QF7LKJreKxs0CM7YXGzqW1N/ODY=", + "h1:wqgRvlyVIbkCeCQs+5jj6zVuQL0KDxZZtNofGqqlSdI=", + "h1:ydA0/SNRVB1o95btfshvYsmxA+jZFRZcvKzZSB+4S1M=", + "zh:58ed64389620cc7b82f01332e27723856422820cfd302e304b5f6c3436fb9840", + "zh:62a5cc82c3b2ddef7ef3a6f2fedb7b9b3deff4ab7b414938b08e51d6e8be87cb", + "zh:63cff4de03af983175a7e37e52d4bd89d990be256b16b5c7f919aff5ad485aa5", + "zh:74cb22c6700e48486b7cabefa10b33b801dfcab56f1a6ac9b6624531f3d36ea3", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:79e553aff77f1cfa9012a2218b8238dd672ea5e1b2924775ac9ac24d2a75c238", + "zh:a1e06ddda0b5ac48f7e7c7d59e1ab5a4073bbcf876c73c0299e4610ed53859dc", + "zh:c37a97090f1a82222925d45d84483b2aa702ef7ab66532af6cbcfb567818b970", + "zh:e4453fbebf90c53ca3323a92e7ca0f9961427d2f0ce0d2b65523cc04d5d999c2", + "zh:e80a746921946d8b6761e77305b752ad188da60688cfd2059322875d363be5f5", + "zh:fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f", + "zh:fca01a623d90d0cad0843102f9b8b9fe0d3ff8244593bd817f126582b52dd694", + ] +} diff --git a/src/domains/pay-wallet-app-v2/00_azuread.tf b/src/domains/pay-wallet-app-v2/00_azuread.tf new file mode 100644 index 0000000000..14a0893a9f --- /dev/null +++ b/src/domains/pay-wallet-app-v2/00_azuread.tf @@ -0,0 +1,16 @@ +# Azure AD +data "azuread_group" "adgroup_admin" { + display_name = "${local.product}-adgroup-admin" +} + +data "azuread_group" "adgroup_developers" { + display_name = "${local.product}-adgroup-developers" +} + +data "azuread_group" "adgroup_externals" { + display_name = "${local.product}-adgroup-externals" +} + +data "azuread_group" "adgroup_security" { + display_name = "${local.product}-adgroup-security" +} \ No newline at end of file diff --git a/src/domains/pay-wallet-app-v2/00_data.tf b/src/domains/pay-wallet-app-v2/00_data.tf new file mode 100644 index 0000000000..5fabba85b3 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/00_data.tf @@ -0,0 +1,4 @@ +data "azurerm_api_management" "apim" { + name = local.pagopa_apim_name + resource_group_name = local.pagopa_apim_rg +} diff --git a/src/domains/pay-wallet-app-v2/00_monitor.tf b/src/domains/pay-wallet-app-v2/00_monitor.tf new file mode 100644 index 0000000000..4ee72a4a09 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/00_monitor.tf @@ -0,0 +1,29 @@ +# +# 🇮🇹 Monitor Italy +# +data "azurerm_resource_group" "monitor_italy_rg" { + name = var.monitor_italy_resource_group_name +} + +data "azurerm_log_analytics_workspace" "log_analytics_italy" { + name = var.log_analytics_italy_workspace_name + resource_group_name = var.log_analytics_italy_workspace_resource_group_name +} + +data "azurerm_application_insights" "application_insights_italy" { + name = local.monitor_appinsights_italy_name + resource_group_name = data.azurerm_resource_group.monitor_italy_rg.name +} + +# +# Action Groups +# +data "azurerm_monitor_action_group" "slack" { + resource_group_name = data.azurerm_resource_group.monitor_italy_rg.name + name = local.monitor_action_group_slack_name +} + +data "azurerm_monitor_action_group" "email" { + resource_group_name = data.azurerm_resource_group.monitor_italy_rg.name + name = local.monitor_action_group_email_name +} diff --git a/src/domains/pay-wallet-app-v2/00_network.tf b/src/domains/pay-wallet-app-v2/00_network.tf new file mode 100644 index 0000000000..6675cee112 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/00_network.tf @@ -0,0 +1,10 @@ +data "azurerm_virtual_network" "vnet" { + name = local.vnet_name + resource_group_name = local.vnet_resource_group_name +} + +data "azurerm_subnet" "apim_vnet" { + name = local.pagopa_apim_snet + resource_group_name = local.pagopa_vnet_rg + virtual_network_name = local.pagopa_vnet_integration +} diff --git a/src/domains/pay-wallet-app-v2/00_security.tf b/src/domains/pay-wallet-app-v2/00_security.tf new file mode 100644 index 0000000000..31ed9ca522 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/00_security.tf @@ -0,0 +1,4 @@ +data "azurerm_key_vault" "kv" { + name = "${local.product}-${var.domain}-kv" + resource_group_name = "${local.product}-${var.domain}-sec-rg" +} diff --git a/src/domains/pay-wallet-app-v2/04_apim_io_payment_wallet.tf b/src/domains/pay-wallet-app-v2/04_apim_io_payment_wallet.tf new file mode 100644 index 0000000000..4bc4cad560 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/04_apim_io_payment_wallet.tf @@ -0,0 +1,187 @@ +data "azurerm_key_vault_secret" "personal_data_vault_api_key_secret" { + name = "personal-data-vault-api-key" + key_vault_id = data.azurerm_key_vault.kv.id +} + +resource "azurerm_api_management_named_value" "wallet_personal_data_vault_api_key" { + name = "wallet-personal-data-vault-api-key" + api_management_name = local.pagopa_apim_name + resource_group_name = local.pagopa_apim_rg + display_name = "wallet-personal-data-vault-api-key" + value = data.azurerm_key_vault_secret.personal_data_vault_api_key_secret.value + secret = true +} + +############## +## Products ## +############## + +module "apim_io_payment_wallet_product" { + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_product?ref=v6.3.0" + + product_id = "io-payment-wallet" + display_name = "IO payment wallet pagoPA" + description = "Product for IO payment wallet pagoPA" + + api_management_name = local.pagopa_apim_name + resource_group_name = local.pagopa_apim_rg + + published = true + subscription_required = true + approval_required = true + subscriptions_limit = 1000 + + policy_xml = file("./api_product/_base_policy.xml") +} + +################################################# +## API payment wallet for IO ## +################################################# +locals { + apim_io_payment_wallet_api = { + display_name = "pagoPA - payment wallet API only for IO APP" + description = "API to support payment wallet only for IO APP" + path = "io-payment-wallet" + subscription_required = false + service_url = null + } +} + +# Payment wallet service APIs +resource "azurerm_api_management_api_version_set" "io_payment_wallet_api" { + name = "${local.project}-io-payment-wallet-api" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + display_name = local.apim_io_payment_wallet_api.display_name + versioning_scheme = "Segment" +} + +module "apim_io_payment_wallet_api_v1" { + source = "git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api?ref=v6.3.0" + + name = "${local.project}-io-payment-wallet-api" + api_management_name = local.pagopa_apim_name + resource_group_name = local.pagopa_apim_rg + product_ids = [module.apim_io_payment_wallet_product.product_id] + subscription_required = local.apim_io_payment_wallet_api.subscription_required + version_set_id = azurerm_api_management_api_version_set.io_payment_wallet_api.id + api_version = "v1" + + description = local.apim_io_payment_wallet_api.description + display_name = local.apim_io_payment_wallet_api.display_name + path = local.apim_io_payment_wallet_api.path + protocols = ["https"] + service_url = local.apim_io_payment_wallet_api.service_url + + content_format = "openapi" + content_value = templatefile("./api/io-payment-wallet/v1/_openapi.json.tpl", { + hostname = local.apim_hostname + }) + + xml_content = templatefile("./api/io-payment-wallet/v1/_base_policy.xml.tpl", { + hostname = local.payment_wallet_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "delete_io_wallets" { + api_name = "${local.project}-io-payment-wallet-api-v1" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + operation_id = "deleteIOPaymentWalletById" + + xml_content = file("./api/io-payment-wallet/v1/_delete_wallet.xml.tpl") +} + +resource "azurerm_api_management_api_operation_policy" "get_payment_methods_for_io" { + api_name = "${local.project}-io-payment-wallet-api-v1" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + operation_id = "getAllPaymentMethodsForIO" + + xml_content = templatefile("./api/io-payment-wallet/v1/_get_payment_methods.xml.tpl", + { + ecommerce_hostname = local.ecommerce_hostname + enabled_payment_wallet_method_ids_pm = var.enabled_payment_wallet_method_ids_pm + } + ) +} + +resource "azurerm_api_management_api_operation_policy" "get_wallets_by_user_and_walletId_for_io" { + api_name = "${local.project}-io-payment-wallet-api-v1" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + operation_id = "getIOPaymentWalletById" + + xml_content = templatefile("./api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl", { ecommerce_hostname = local.ecommerce_hostname }) +} + +resource "azurerm_api_management_api_operation_policy" "get_wallets_by_user_for_io" { + api_name = "${local.project}-io-payment-wallet-api-v1" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + operation_id = "getIOPaymentWalletsByIdUser" + + xml_content = templatefile("./api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl", { ecommerce_hostname = local.ecommerce_hostname }) +} + +resource "azurerm_api_management_api_operation_policy" "post_io_wallets" { + api_name = "${local.project}-io-payment-wallet-api-v1" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + operation_id = "createIOPaymentWallet" + + xml_content = templatefile("./api/io-payment-wallet/v1/_post_wallets.xml.tpl", { + env = var.env == "prod" ? "" : "${var.env}.", + ecommerce_hostname = local.ecommerce_hostname + }) +} + +resource "azurerm_api_management_api_operation_policy" "update_applications_for_io" { + api_name = "${local.project}-io-payment-wallet-api-v1" + resource_group_name = local.pagopa_apim_rg + api_management_name = local.pagopa_apim_name + operation_id = "updateIOPaymentWalletApplicationsById" + + xml_content = file("./api/io-payment-wallet/v1/_update_applications.xml.tpl") +} + + +resource "azurerm_api_management_named_value" "pay_wallet_family_friends_user_ids" { + name = "pay-wallet-family-friends-user-ids" + api_management_name = local.pagopa_apim_name + resource_group_name = local.pagopa_apim_rg + display_name = "pay-wallet-family-friends-user-ids" + value = "" + lifecycle { + ignore_changes = [ + value, + ] + } +} + + +####################################################################### +## Fragment policy to extract user id from session token ## +####################################################################### + +resource "azapi_resource" "pay_wallet_fragment_user_id_from_session_token" { + + # provider = azapi.apim + type = "Microsoft.ApiManagement/service/policyFragments@2022-04-01-preview" + name = "pay-wallet-user-id-from-session-token" + parent_id = data.azurerm_api_management.apim.id + + body = jsonencode({ + properties = { + description = "Component that extract userId from JWT session token" + format = "rawxml" + value = templatefile("./api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml", { + }) + + } + }) + + lifecycle { + ignore_changes = [output] + } +} diff --git a/src/domains/pay-wallet-app-v2/99_locals.tf b/src/domains/pay-wallet-app-v2/99_locals.tf new file mode 100644 index 0000000000..65b5a4e124 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/99_locals.tf @@ -0,0 +1,47 @@ +locals { + project = "${var.prefix}-${var.env_short}-${var.location_short}-${var.domain}" + product = "${var.prefix}-${var.env_short}" + product_italy = "${var.prefix}-${var.env_short}-${var.location_short}" + + + app_insights_ips_west_europe = [ + "51.144.56.96/28", + "51.144.56.112/28", + "51.144.56.128/28", + "51.144.56.144/28", + "51.144.56.160/28", + "51.144.56.176/28", + ] + + monitor_appinsights_italy_name = "${local.product_italy}-core-appinsights" + monitor_action_group_slack_name = "SlackPagoPA" + monitor_action_group_email_name = "PagoPA" + monitor_appinsights_name = "${local.product}-appinsights" + + vnet_name = "${local.product}-vnet" + vnet_resource_group_name = "${local.product}-vnet-rg" + + acr_name = replace("${local.product}commonacr", "-", "") + acr_resource_group_name = "${local.product}-container-registry-rg" + + aks_name = "${local.product}-${var.location_short}-${var.instance}-aks" + aks_resource_group_name = "${local.product}-${var.location_short}-${var.instance}-aks-rg" + + ingress_hostname = "${var.location_short}${var.instance}.${var.domain}" + internal_dns_zone_name = "${var.dns_zone_internal_prefix}.${var.external_domain}" + + #pagopa_apim_name = "${local.product}-apim" + pagopa_apim_name = "${local.product}-weu-core-apim-v2" + pagopa_apim_rg = "${local.product}-api-rg" + pagopa_apim_snet = "${local.product}-apim-snet" + + #pagopa_apim_v2_name = "${local.product}-weu-core-apim-v2" + + pagopa_vnet_integration = "pagopa-${var.env_short}-vnet-integration" + pagopa_vnet_rg = "pagopa-${var.env_short}-vnet-rg" + + apim_hostname = "api.${var.apim_dns_zone_prefix}.${var.external_domain}" + payment_wallet_hostname = var.env_short != "p" ? "${var.location_short}${var.env}.pay-wallet.internal.${var.env}.platform.pagopa.it" : "${var.location_short}${var.env}.pay-wallet.internal.platform.pagopa.it" + ecommerce_hostname = var.env_short == "p" ? "weu${var.env}.ecommerce.internal.platform.pagopa.it" : "weu${var.env}.ecommerce.internal.${var.env}.platform.pagopa.it" + wallet_service_hostname = var.env_short != "p" ? "weu${var.env}.wallet.internal.${var.env}.platform.pagopa.it" : "${var.location_short}${var.env}.pay-wallet.internal.platform.pagopa.it" +} diff --git a/src/domains/pay-wallet-app-v2/99_main.tf b/src/domains/pay-wallet-app-v2/99_main.tf new file mode 100644 index 0000000000..5faabf1825 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/99_main.tf @@ -0,0 +1,52 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "<= 3.95.0" + } + azuread = { + source = "hashicorp/azuread" + version = "<= 2.47.0" + } + null = { + source = "hashicorp/null" + version = "<= 3.2.1" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "<= 2.26.0" + } + helm = { + source = "hashicorp/helm" + version = "<= 2.12.0" + } + azapi = { + source = "azure/azapi" + version = "<= 1.3.0" + } + } + + backend "azurerm" {} +} + +provider "azurerm" { + features { + key_vault { + purge_soft_delete_on_destroy = false + } + } +} + +data "azurerm_subscription" "current" {} + +data "azurerm_client_config" "current" {} + +provider "kubernetes" { + config_path = "${var.k8s_kube_config_path_prefix}/config-${local.aks_name}" +} + +provider "helm" { + kubernetes { + config_path = "${var.k8s_kube_config_path_prefix}/config-${local.aks_name}" + } +} diff --git a/src/domains/pay-wallet-app-v2/99_variables.tf b/src/domains/pay-wallet-app-v2/99_variables.tf new file mode 100644 index 0000000000..95e6f85798 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/99_variables.tf @@ -0,0 +1,157 @@ +# general + +variable "prefix" { + type = string + validation { + condition = ( + length(var.prefix) <= 6 + ) + error_message = "Max length is 6 chars." + } +} + +variable "env" { + type = string +} + +variable "env_short" { + type = string + validation { + condition = ( + length(var.env_short) == 1 + ) + error_message = "Length must be 1 chars." + } +} + +variable "domain" { + type = string + validation { + condition = ( + length(var.domain) <= 12 + ) + error_message = "Max length is 12 chars." + } +} + +variable "location" { + type = string + description = "One of westeurope, northeurope" +} + +variable "location_short" { + type = string + validation { + condition = ( + length(var.location_short) == 3 + ) + error_message = "Length must be 3 chars." + } + description = "One of wue, neu" +} + +variable "location_string" { + type = string + description = "One of West Europe, North Europe" +} + +variable "instance" { + type = string + description = "One of beta, prod01, prod02" +} + +variable "tags" { + type = map(any) + default = { + CreatedBy = "Terraform" + } +} + +### External resources + +variable "monitor_italy_resource_group_name" { + type = string + description = "Monitor Italy resource group name" +} + +variable "log_analytics_italy_workspace_name" { + type = string + description = "Specifies the name of the Log Analytics Workspace Italy." +} + +variable "log_analytics_italy_workspace_resource_group_name" { + type = string + description = "The name of the resource group in which the Log Analytics workspace Italy is located in." +} + +### Aks + +variable "k8s_kube_config_path_prefix" { + type = string + default = "~/.kube" +} + +variable "external_domain" { + type = string + default = null + description = "Domain for delegation" +} + +variable "dns_zone_internal_prefix" { + type = string + default = null + description = "The dns subdomain." +} + +variable "apim_dns_zone_prefix" { + type = string + default = null + description = "The dns subdomain for apim." +} + +variable "tls_cert_check_helm" { + type = object({ + chart_version = string, + image_name = string, + image_tag = string + }) + description = "tls cert helm chart configuration" +} + +variable "payment_wallet_with_pm_enabled" { + type = bool + default = false + description = "payment wallet using Payment Manager" +} + +variable "pdv_api_base_path" { + type = string + default = null + description = "Personal data vault api base path" +} + +variable "io_backend_base_path" { + type = string + default = null + description = "io backend api base path" +} + +# DNS + +variable "dns_zone_prefix" { + type = string + default = null + description = "The wallet dns subdomain." +} + +variable "payment_wallet_migrations_enabled" { + type = bool + default = false + description = "Payment wallet migrations enabled" +} + +variable "enabled_payment_wallet_method_ids_pm" { + type = string + default = "" + description = "Comma separated list of eCommerce payment method ids that are enabled with PM APIs" +} diff --git a/src/domains/pay-wallet-app-v2/README.md b/src/domains/pay-wallet-app-v2/README.md new file mode 100644 index 0000000000..0434b0d118 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/README.md @@ -0,0 +1,85 @@ +# payment-wallet-app + + + +## Requirements + +| Name | Version | +|------|---------| +| [azapi](#requirement\_azapi) | <= 1.3.0 | +| [azuread](#requirement\_azuread) | <= 2.47.0 | +| [azurerm](#requirement\_azurerm) | <= 3.95.0 | +| [helm](#requirement\_helm) | <= 2.12.0 | +| [kubernetes](#requirement\_kubernetes) | <= 2.26.0 | +| [null](#requirement\_null) | <= 3.2.1 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [apim\_io\_payment\_wallet\_api\_v1](#module\_apim\_io\_payment\_wallet\_api\_v1) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_api | v6.3.0 | +| [apim\_io\_payment\_wallet\_product](#module\_apim\_io\_payment\_wallet\_product) | git::https://github.com/pagopa/terraform-azurerm-v3.git//api_management_product | v6.3.0 | + +## Resources + +| Name | Type | +|------|------| +| [azapi_resource.pay_wallet_fragment_user_id_from_session_token](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource) | resource | +| [azurerm_api_management_api_operation_policy.delete_io_wallets](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.get_payment_methods_for_io](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.get_wallets_by_user_and_walletId_for_io](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.get_wallets_by_user_for_io](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.post_io_wallets](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_operation_policy.update_applications_for_io](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | +| [azurerm_api_management_api_version_set.io_payment_wallet_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | +| [azurerm_api_management_named_value.pay_wallet_family_friends_user_ids](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | +| [azurerm_api_management_named_value.wallet_personal_data_vault_api_key](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | +| [azuread_group.adgroup_admin](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | +| [azuread_group.adgroup_developers](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | +| [azuread_group.adgroup_externals](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | +| [azuread_group.adgroup_security](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | +| [azurerm_api_management.apim](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/api_management) | data source | +| [azurerm_application_insights.application_insights_italy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/application_insights) | data source | +| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source | +| [azurerm_key_vault.kv](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault) | data source | +| [azurerm_key_vault_secret.personal_data_vault_api_key_secret](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_secret) | data source | +| [azurerm_log_analytics_workspace.log_analytics_italy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/log_analytics_workspace) | data source | +| [azurerm_monitor_action_group.email](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/monitor_action_group) | data source | +| [azurerm_monitor_action_group.slack](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/monitor_action_group) | data source | +| [azurerm_resource_group.monitor_italy_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | +| [azurerm_subnet.apim_vnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subnet) | data source | +| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | +| [azurerm_virtual_network.vnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [apim\_dns\_zone\_prefix](#input\_apim\_dns\_zone\_prefix) | The dns subdomain for apim. | `string` | `null` | no | +| [dns\_zone\_internal\_prefix](#input\_dns\_zone\_internal\_prefix) | The dns subdomain. | `string` | `null` | no | +| [dns\_zone\_prefix](#input\_dns\_zone\_prefix) | The wallet dns subdomain. | `string` | `null` | no | +| [domain](#input\_domain) | n/a | `string` | n/a | yes | +| [enabled\_payment\_wallet\_method\_ids\_pm](#input\_enabled\_payment\_wallet\_method\_ids\_pm) | Comma separated list of eCommerce payment method ids that are enabled with PM APIs | `string` | `""` | no | +| [env](#input\_env) | n/a | `string` | n/a | yes | +| [env\_short](#input\_env\_short) | n/a | `string` | n/a | yes | +| [external\_domain](#input\_external\_domain) | Domain for delegation | `string` | `null` | no | +| [instance](#input\_instance) | One of beta, prod01, prod02 | `string` | n/a | yes | +| [io\_backend\_base\_path](#input\_io\_backend\_base\_path) | io backend api base path | `string` | `null` | no | +| [k8s\_kube\_config\_path\_prefix](#input\_k8s\_kube\_config\_path\_prefix) | n/a | `string` | `"~/.kube"` | no | +| [location](#input\_location) | One of westeurope, northeurope | `string` | n/a | yes | +| [location\_short](#input\_location\_short) | One of wue, neu | `string` | n/a | yes | +| [location\_string](#input\_location\_string) | One of West Europe, North Europe | `string` | n/a | yes | +| [log\_analytics\_italy\_workspace\_name](#input\_log\_analytics\_italy\_workspace\_name) | Specifies the name of the Log Analytics Workspace Italy. | `string` | n/a | yes | +| [log\_analytics\_italy\_workspace\_resource\_group\_name](#input\_log\_analytics\_italy\_workspace\_resource\_group\_name) | The name of the resource group in which the Log Analytics workspace Italy is located in. | `string` | n/a | yes | +| [monitor\_italy\_resource\_group\_name](#input\_monitor\_italy\_resource\_group\_name) | Monitor Italy resource group name | `string` | n/a | yes | +| [payment\_wallet\_migrations\_enabled](#input\_payment\_wallet\_migrations\_enabled) | Payment wallet migrations enabled | `bool` | `false` | no | +| [payment\_wallet\_with\_pm\_enabled](#input\_payment\_wallet\_with\_pm\_enabled) | payment wallet using Payment Manager | `bool` | `false` | no | +| [pdv\_api\_base\_path](#input\_pdv\_api\_base\_path) | Personal data vault api base path | `string` | `null` | no | +| [prefix](#input\_prefix) | n/a | `string` | n/a | yes | +| [tags](#input\_tags) | n/a | `map(any)` |
{
"CreatedBy": "Terraform"
}
| no | +| [tls\_cert\_check\_helm](#input\_tls\_cert\_check\_helm) | tls cert helm chart configuration |
object({
chart_version = string,
image_name = string,
image_tag = string
})
| n/a | yes | + +## Outputs + +No outputs. + diff --git a/src/domains/pay-wallet-app-v2/api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml b/src/domains/pay-wallet-app-v2/api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml new file mode 100644 index 0000000000..39eefad065 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml @@ -0,0 +1,21 @@ + + + + 1 ? sessionTokenParts[1] : ""; + int reminder = sessionTokenBody.Length % 4; + int toPad = reminder > 1 ? (4-reminder) : 0; + string padded = string.Concat(sessionTokenBody,string.Concat(Enumerable.Repeat("=", toPad))); + byte[] data = Convert.FromBase64String(padded); + string decodedString = System.Text.Encoding.UTF8.GetString(data); + Dictionary parsed = JsonConvert.DeserializeObject>(decodedString); + string userId = (string)parsed?["userId"]; + return String.IsNullOrEmpty(userId) ? "user-id-not-found" : userId; + } catch(Exception){ + return "user-id-not-found"; + } + }" /> + \ No newline at end of file diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_base_policy.xml.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_base_policy.xml.tpl new file mode 100644 index 0000000000..f755c4d77b --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_base_policy.xml.tpl @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + @((string)context.Variables.GetValueOrDefault("xUserId","")) + + + + + + + IO + + + + + + + + + + + + diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_delete_wallet.xml.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_delete_wallet.xml.tpl new file mode 100644 index 0000000000..1c57d097b0 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_delete_wallet.xml.tpl @@ -0,0 +1,84 @@ + + + + + + + + + @($"{{pm-host}}/pp-restapi-CD/v1/wallet/{(string)context.Variables["idWalletPM"]}") + DELETE + + @($"Bearer {((String)context.Variables["sessionToken"])}") + + + + + + + + + + + + + + + application/json + + + { + "title": "Unauthorized", + "status": 401, + "detail": "Unauthorized" + } + + + + + + + + application/json + + + { + "title": "Not Found", + "status": 404, + "detail": "Wallet not found" + } + + + + + + + + application/json + + + { + "title": "Error deleting wallet", + "status": 502, + "detail": "There was an error deleting wallet" + } + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_payment_methods.xml.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_payment_methods.xml.tpl new file mode 100644 index 0000000000..372a549889 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_payment_methods.xml.tpl @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + @{ + JObject response = context.Response.Body.As(); + + if (context.Response.StatusCode != 200) { + return response.ToString(); + } + + string enabled_payment_wallet_method_ids_pm = "${enabled_payment_wallet_method_ids_pm}"; + string[] values = enabled_payment_wallet_method_ids_pm.Split(','); + HashSet pmEnabledMethods = new HashSet(values); + + foreach (var method in ((JArray) response["paymentMethods"])) { + string id = (string) method["id"]; + if (pmEnabledMethods.Contains(id)) { + method["status"] = "ENABLED"; + method["methodManagement"] = "ONBOARDABLE_ONLY"; + } else { + method["status"] = "DISABLED"; + } + } + + return response.ToString(); + } + + + + + + + + + + + diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl new file mode 100644 index 0000000000..39fa423c1c --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl @@ -0,0 +1,207 @@ + + + + + + + + {{pm-host}}/pp-restapi-CD/v3/wallet + GET + + @($"Bearer {((String)context.Variables["sessionToken"])}") + + + + + + + + application/json + + { + "title": "Unauthorized", + "status": 401, + "detail": "Unauthorized" + } + + + + + + + application/json + + + { + "title": "Error retrieving user wallet data", + "status": 502, + "detail": "There was an error retrieving user wallet data" + } + + + + + ())" /> + + + + + + + application/json + + + { + "title": "Wallet not found", + "status": 404, + "detail": "No wallet found for input wallet token" + } + + + + + + + + https://${ecommerce_hostname}/pagopa-ecommerce-payment-methods-service/payment-methods + GET + + IO + + + + + + + + application/json + + + { + "title": "Error retrieving eCommerce payment methods", + "status": 502, + "detail": "There was an error retrieving eCommerce payment methods" + } + + + + + ())" /> + + + + + application/json + + + @{ + JObject pmWalletResponse = (JObject)context.Variables["pmUserWalletResponseBody"]; + var walletApplications = new List{"PAGOPA"}; + var eCommerceWalletTypes = new Dictionary + { + { "Card", "CARDS" }, + { "BPay", "BANCOMATPAY" }, + { "PayPal", "PAYPAL" } + }; + var eCommercePaymentMethodIds = new Dictionary(); + JObject paymentMethods = (JObject)context.Variables["paymentMethodsResponseBody"]; + foreach(JObject paymentMethod in (JArray)paymentMethods["paymentMethods"]){ + eCommercePaymentMethodIds[paymentMethod["name"].ToString()] = paymentMethod["id"].ToString(); + } + Object[] wallets = pmWalletResponse["data"] + .Where(wallet =>{ + return eCommerceWalletTypes.ContainsKey((string) wallet["walletType"]); + }) + .Select(wallet =>{ + JObject result = new JObject(); + //convert wallet id (long) to UUID v4 with all bit set to 0 (except for the version). + //wallet id long value is stored into UUID latest 8 byte + string walletIdHex = ((long)wallet["idWallet"]).ToString("X").PadLeft(16,'0'); + string walletIdToUuid = "00000000-0000-4000-"+walletIdHex.Substring(0,4)+"-"+walletIdHex.Substring(4); + result["walletId"] = walletIdToUuid; + string pmWalletType = (string) wallet["walletType"]; + string eCommerceWalletType = eCommerceWalletTypes[pmWalletType]; + result["paymentMethodId"] = eCommercePaymentMethodIds[eCommerceWalletType]; + result["status"] = "VALIDATED"; + + TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"); + + DateTime creationDateTime = DateTime.Parse(((string)wallet["createDate"]).Replace(" ","T")); + DateTime utcCreationDateTime = TimeZoneInfo.ConvertTimeToUtc(creationDateTime, zone); + DateTimeOffset creationDateTimeOffset = new DateTimeOffset(utcCreationDateTime); + result["creationDate"] = creationDateTimeOffset.ToString("o"); + result["updateDate"] = result["creationDate"]; + + var convertedApplications = new List(); + foreach(JValue application in wallet["enableableFunctions"]){ + string applicationName = application.ToString().ToUpper(); + if(walletApplications.Contains(applicationName) && wallet[application.ToString()] != null){ + JObject converted = new JObject(); + converted["name"] = applicationName; + converted["status"] = Convert.ToBoolean(wallet[application.ToString()]) == true ? "ENABLED" : "DISABLED"; + converted["updateDate"] = result["creationDate"]; + convertedApplications.Add(converted); + } + } + result["applications"] = JArray.FromObject(convertedApplications); + JObject details = new JObject(); + details["type"] = eCommerceWalletType; + string paymentMethodAsset = null; + if (eCommerceWalletType == "CARDS") { + details["lastFourDigits"] = $"{wallet["info"]["blurredNumber"]}"; + details["expiryDate"] = $"{(string)wallet["info"]["expireYear"]}{(string)wallet["info"]["expireMonth"]}"; + details["brand"] = wallet["info"]["brand"]; + paymentMethodAsset = (string)wallet["info"]["brandLogo"]; + } + if (eCommerceWalletType == "PAYPAL") { + var info = (JObject)(wallet["info"]); + var pspArray = (JArray)(info["pspInfo"]); + var pspInfo = (JObject)(pspArray[0]); + details["pspId"] = pspInfo["abi"]; + details["maskedEmail"] = pspInfo["email"]; + details["pspBusinessName"] = pspInfo["ragioneSociale"]; + paymentMethodAsset = "https://assets.cdn.platform.pagopa.it/apm/paypal.png"; + } + if (eCommerceWalletType == "BANCOMATPAY") { + details["maskedNumber"] = wallet["info"]["numberObfuscated"]; + details["instituteCode"] = wallet["info"]["instituteCode"]; + details["bankName"] = wallet["info"]["bankName"]; + paymentMethodAsset = (string)wallet["info"]["brandLogo"]; + } + result["details"] = details; + result["paymentMethodAsset"] = paymentMethodAsset; + + Boolean favourite = (Boolean) wallet["favourite"]; + JObject clients = new JObject(); + JObject clientIO = new JObject(); + clientIO["status"] = "ENABLED"; + if(favourite == true) { + DateTime localDateUtc = DateTime.UtcNow; + DateTimeOffset lastUsageDateTimeOffset = new DateTimeOffset(localDateUtc); + clientIO["lastUsage"] = lastUsageDateTimeOffset.ToString("o"); + } + clients["IO"] = clientIO; + result["clients"] = clients; + + return result; + }).ToArray(); + + JObject response = new JObject(); + response["wallets"] = JArray.FromObject(wallets); + return response.ToString(); + } + + + + + + + + + + + + + + + diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl new file mode 100644 index 0000000000..b03ec92afa --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl @@ -0,0 +1,221 @@ + + + + + + + + + {{pm-host}}/pp-restapi-CD/v3/wallet + GET + + @($"Bearer {((String)context.Variables["sessionToken"])}") + + + + + + + + application/json + + { + "title": "Unauthorized", + "status": 401, + "detail": "Unauthorized" + } + + + + + + + application/json + + { + "title": "Error retrieving user wallet data", + "status": 502, + "detail": "There was an error retrieving user wallet data" + } + + + + ())" /> + + + + + + + application/json + + { + "title": "Wallet not found", + "status": 404, + "detail": "No wallet found for input wallet token" + } + + + + + + + https://${ecommerce_hostname}/pagopa-ecommerce-payment-methods-service/payment-methods + GET + + IO + + + + + + + + application/json + + { + "title": "Error retrieving eCommerce payment methods", + "status": 502, + "detail": "There was an error retrieving eCommerce payment methods" + } + + + + ())" /> + + {"PAGOPA"}; + var eCommerceWalletTypes = new Dictionary + { + { "Card", "CARDS" }, + { "BPay", "BANCOMATPAY" }, + { "PayPal", "PAYPAL" } + }; + var eCommercePaymentMethodIds = new Dictionary(); + JObject paymentMethods = (JObject)context.Variables["paymentMethodsResponseBody"]; + foreach(JObject paymentMethod in (JArray)paymentMethods["paymentMethods"]){ + eCommercePaymentMethodIds[paymentMethod["name"].ToString()] = paymentMethod["id"].ToString(); + } + JObject walletResult = (JObject) pmWalletResponse["data"] + .Where(wallet =>{ + return eCommerceWalletTypes.ContainsKey((string) wallet["walletType"]) && (((string)context.Variables["walletId"]).Equals((string)wallet["idWallet"])); + }) + .Select(wallet =>{ + + JObject result = new JObject(); + //convert wallet id (long) to UUID v4 with all bit set to 0 (except for the version). + //wallet id long value is stored into UUID latest 8 byte + string walletIdHex = ((long)wallet["idWallet"]).ToString("X").PadLeft(16,'0'); + string walletIdToUuid = "00000000-0000-4000-"+walletIdHex.Substring(0,4)+"-"+walletIdHex.Substring(4); + result["walletId"] = walletIdToUuid; + string pmWalletType = (string) wallet["walletType"]; + string eCommerceWalletType = eCommerceWalletTypes[pmWalletType]; + result["paymentMethodId"] = eCommercePaymentMethodIds[eCommerceWalletType]; + result["status"] = "VALIDATED"; + + TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"); + + DateTime creationDateTime = DateTime.Parse(((string)wallet["createDate"]).Replace(" ","T")); + DateTime utcCreationDateTime = TimeZoneInfo.ConvertTimeToUtc(creationDateTime, zone); + DateTimeOffset creationDateTimeOffset = new DateTimeOffset(utcCreationDateTime); + result["creationDate"] = creationDateTimeOffset.ToString("o"); + result["updateDate"] = result["creationDate"]; + + string paymentMethodAsset=null; + var convertedApplications = new List(); + foreach(JValue application in wallet["enableableFunctions"]){ + string applicationName = application.ToString().ToUpper(); + if(walletApplications.Contains(applicationName) && wallet[application.ToString()] != null){ + JObject converted = new JObject(); + converted["name"] = applicationName; + converted["status"] = Convert.ToBoolean(wallet[application.ToString()]) == true ? "ENABLED" : "DISABLED"; + converted["updateDate"] = result["creationDate"]; + convertedApplications.Add(converted); + } + } + result["applications"] = JArray.FromObject(convertedApplications); + JObject details = new JObject(); + details["type"] = eCommerceWalletType; + if (eCommerceWalletType == "CARDS") { + details["lastFourDigits"] = $"{wallet["info"]["blurredNumber"]}"; + details["expiryDate"] = $"{(string)wallet["info"]["expireYear"]}{(string)wallet["info"]["expireMonth"]}"; + details["brand"] = wallet["info"]["brand"]; + paymentMethodAsset = (string)wallet["info"]["brandLogo"]; + } + if (eCommerceWalletType == "PAYPAL") { + var info = (JObject)(wallet["info"]); + var pspArray = (JArray)(info["pspInfo"]); + var pspInfo = (JObject)(pspArray[0]); + details["pspId"] = pspInfo["abi"]; + details["maskedEmail"] = pspInfo["email"]; + details["pspBusinessName"] = pspInfo["ragioneSociale"]; + paymentMethodAsset = "https://assets.cdn.platform.pagopa.it/apm/paypal.png"; + } + if (eCommerceWalletType == "BANCOMATPAY") { + details["maskedNumber"] = wallet["info"]["numberObfuscated"]; + details["instituteCode"] = wallet["info"]["instituteCode"]; + details["bankName"] = wallet["info"]["bankName"]; + paymentMethodAsset = (string)wallet["info"]["brandLogo"]; + } + result["details"] = details; + result["paymentMethodAsset"] = paymentMethodAsset; + + Boolean favourite = (Boolean) wallet["favourite"]; + JObject clients = new JObject(); + JObject clientIO = new JObject(); + clientIO["status"] = "ENABLED"; + if(favourite == true) { + DateTime localDateUtc = DateTime.UtcNow; + DateTimeOffset lastUsageDateTimeOffset = new DateTimeOffset(localDateUtc); + clientIO["lastUsage"] = lastUsageDateTimeOffset.ToString("o"); + } + clients["IO"] = clientIO; + result["clients"] = clients; + + return result; + + }).SingleOrDefault(); + return walletResult; + }" /> + + + + + + application/json + + @(((JObject)context.Variables["walletResponseBody"]).ToString()) + + + + + + + application/json + + { + "title": "Wallet not found", + "status": 404, + "detail": "Wallet not found" + } + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_openapi.json.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_openapi.json.tpl new file mode 100644 index 0000000000..a7a42b02c5 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_openapi.json.tpl @@ -0,0 +1,973 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "pagoPA IO Payment Wallet API", + "version": "0.0.1", + "description": "API to handle payment wallets PagoPA for App IO, where a wallet is triple between user identifier, payment instrument and applications (i.e pagoPA, bpd).\n\nThe wallet onboarding outcome and walletId are returned as query params to the app IO, for example \n/wallets/{walletId}/outcomes?outcome=0&walletId=123. The possible outcome are:\n- SUCCESS(0)\n- GENERIC_ERROR(1)\n- AUTH_ERROR(2)\n- TIMEOUT(4)\n- CANCELED_BY_USER(8)\n- INVALID_SESSION(14)", + "termsOfService": "https://pagopa.it/terms/" + }, + "tags": [ + { + "name": "paymentMethods", + "description": "Api's to retrive payment methods", + "externalDocs": { + "url": "https://pagopa.atlassian.net/wiki/spaces/WA/overview?homepageId=622658099", + "description": "Documentation" + } + }, + { + "name": "wallets", + "description": "Api's to handle a wallet", + "externalDocs": { + "url": "https://pagopa.atlassian.net/wiki/spaces/WA/overview?homepageId=622658099", + "description": "Documentation" + } + } + ], + "servers": [ + { + "url": "https://${hostname}" + } + ], + "paths": { + "/payment-methods": { + "get": { + "tags": [ + "paymentMethods" + ], + "operationId": "getAllPaymentMethodsForIO", + "security": [ + { + "pagoPAPlatformSessionToken": [] + } + ], + "summary": "Retrieve all Payment Methods for IO", + "parameters": [ + { + "name": "amount", + "in": "query", + "description": "Payment Amount expressed in eurocents", + "required": false, + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Payment method successfully retrieved", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaymentMethodsResponse" + } + } + } + }, + "400": { + "description": "Formally invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "401": { + "description": "Unauthorized: the provided token is not valid or expired.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "404": { + "description": "Payment methods not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "500": { + "description": "Internal server error serving request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "502": { + "description": "Gateway error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "504": { + "description": "Timeout serving request" + } + } + } + }, + "/wallets": { + "post": { + "tags": [ + "wallets" + ], + "summary": "Create a new wallet for IO", + "description": "Creates a new wallet for IO", + "operationId": "createIOPaymentWallet", + "security": [ + { + "pagoPAPlatformSessionToken": [] + } + ], + "requestBody": { + "description": "Create a new wallet for IO", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletCreateRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Wallet created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletCreateResponse" + } + } + } + }, + "400": { + "description": "Formally invalid input", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "401": { + "description": "Unauthorized: the provided token is not valid or expired.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "500": { + "description": "Internal server error serving request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "502": { + "description": "Gateway error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "504": { + "description": "Timeout serving request" + } + } + }, + "get": { + "tags": [ + "wallets" + ], + "summary": "Get wallet by user identifier", + "description": "Returns a of wallets related to user", + "operationId": "getIOPaymentWalletsByIdUser", + "security": [ + { + "pagoPAPlatformSessionToken": [] + } + ], + "responses": { + "200": { + "description": "Wallet retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Wallets" + } + } + } + }, + "400": { + "description": "Invalid input id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "401": { + "description": "Unauthorized: the provided token is not valid or expired.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "404": { + "description": "Wallet not found" + }, + "502": { + "description": "Bad gateway" + }, + "504": { + "description": "Timeout serving request" + } + } + } + }, + "/wallets/{walletId}": { + "get": { + "tags": [ + "wallets" + ], + "summary": "Get wallet by id", + "description": "Returns a single wallet", + "operationId": "getIOPaymentWalletById", + "security": [ + { + "pagoPAPlatformSessionToken": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "description": "ID of wallet to return", + "required": true, + "schema": { + "$ref": "#/components/schemas/WalletId" + } + } + ], + "responses": { + "200": { + "description": "Wallet retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletInfo" + } + } + } + }, + "400": { + "description": "Invalid input id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "401": { + "description": "Unauthorized: the provided token is not valid or expired.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "404": { + "description": "Wallet not found" + }, + "504": { + "description": "Timeout serving request" + } + } + }, + "delete": { + "tags": [ + "wallets" + ], + "summary": "Delete wallet by id", + "description": "Returns a single wallet", + "operationId": "deleteIOPaymentWalletById", + "security": [ + { + "pagoPAPlatformSessionToken": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "description": "ID of wallet to return", + "required": true, + "schema": { + "$ref": "#/components/schemas/WalletId" + } + } + ], + "responses": { + "204": { + "description": "Wallet deleted successfully" + }, + "400": { + "description": "Invalid input id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "401": { + "description": "Unauthorized: the provided token is not valid or expired.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "404": { + "description": "Wallet not found" + }, + "504": { + "description": "Timeout serving request" + } + } + } + }, + "/wallets/{walletId}/applications": { + "put": { + "tags": [ + "wallets" + ], + "summary": "Update wallet applications and their status", + "description": "Update wallet applications", + "operationId": "updateIOPaymentWalletApplicationsById", + "requestBody": { + "description": "Update wallet applications for the specified wallet", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletApplicationUpdateRequest" + } + } + } + }, + "security": [ + { + "pagoPAPlatformSessionToken": [] + } + ], + "parameters": [ + { + "name": "walletId", + "in": "path", + "description": "ID of wallet to return", + "required": true, + "schema": { + "$ref": "#/components/schemas/WalletId" + } + } + ], + "responses": { + "204": { + "description": "Wallet updated successfully" + }, + "400": { + "description": "Invalid input id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemJson" + } + } + } + }, + "404": { + "description": "Wallet not found" + }, + "409": { + "description": "Wallet request is inconsistent with global application status (e.g. the user requested a application to be enabled but the application has a global status of disabled)", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WalletApplicationsPartialUpdate" + } + } + } + }, + "504": { + "description": "Timeout serving request" + } + } + } + } + }, + "components": { + "schemas": { + "WalletId": { + "description": "Wallet identifier", + "type": "string", + "format": "uuid" + }, + "ApplicationId": { + "type": "string", + "description": "Id of applications" + }, + "Application": { + "type": "object", + "properties": { + "name": { + "$ref": "#/components/schemas/ApplicationId" + }, + "status": { + "$ref": "#/components/schemas/ApplicationStatus" + }, + "updateDate": { + "description": "Application last update date", + "type": "string", + "format": "date-time" + } + } + }, + "ApplicationStatus": { + "type": "string", + "description": "Enumeration of wallet statuses", + "enum": [ + "ENABLED", + "DISABLED", + "INCOMING" + ] + }, + "WalletStatus": { + "type": "string", + "description": "Enumeration of wallet statuses", + "enum": [ + "CREATED", + "INITIALIZED", + "VALIDATED", + "DELETED", + "ERROR" + ] + }, + "WalletCreateRequest": { + "type": "object", + "description": "Wallet creation request", + "properties": { + "applications": { + "type": "array", + "description": "List of applications for which wallet is enabled", + "items": { + "$ref": "#/components/schemas/WalletApplicationId" + } + }, + "useDiagnosticTracing": { + "type": "boolean" + }, + "paymentMethodId": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "paymentMethodId", + "applications", + "useDiagnosticTracing" + ] + }, + "WalletCreateResponse": { + "type": "object", + "description": "Wallet creation response", + "properties": { + "redirectUrl": { + "type": "string", + "format": "url", + "description": "Redirection URL to a payment gateway page where the user can input a payment instrument information", + "example": "http://localhost/inputPage" + } + }, + "required": [ + "walletId", + "redirectUrl" + ] + }, + "WalletApplication": { + "type": "object", + "properties": { + "name": { + "$ref": "#/components/schemas/WalletApplicationId" + }, + "status": { + "$ref": "#/components/schemas/WalletApplicationStatus" + } + } + }, + "WalletApplicationId": { + "type": "string", + "description": "Id of wallet application" + }, + "WalletApplicationStatus": { + "type": "string", + "description": "Enumeration of wallet statuses", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "WalletApplicationUpdateRequest": { + "type": "object", + "description": "Wallet update request", + "properties": { + "applications": { + "type": "array", + "description": "List of applications to update", + "items": { + "$ref": "#/components/schemas/WalletApplication" + } + } + } + }, + "WalletApplicationsPartialUpdate": { + "type": "object", + "description": "Response for wallet applications partial update due to status conflicts", + "properties": { + "updatedApplications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WalletApplication" + } + }, + "failedApplications": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WalletApplication" + } + } + }, + "example": { + "updatedApplications": [ + { + "name": "PAGOPA", + "status": "ENABLED" + } + ], + "failedApplications": [ + { + "name": "PARI", + "status": "DISABLED" + } + ] + } + }, + "WalletApplicationInfo": { + "type": "object", + "properties": { + "name": { + "$ref": "#/components/schemas/WalletApplicationId" + }, + "status": { + "$ref": "#/components/schemas/WalletApplicationStatus" + } + }, + "required": [ + "name", + "status" + ] + }, + "WalletClientStatus": { + "type": "string", + "description": "Enumeration of wallet client statuses", + "enum": [ + "ENABLED", + "DISABLED" + ] + }, + "WalletClient": { + "type": "object", + "properties": { + "status": { + "$ref": "#/components/schemas/WalletClientStatus" + }, + "lastUsage": { + "type": "string", + "description": "Time of last usage of this wallet by the client", + "format": "date-time" + } + }, + "required": [ + "status" + ] + }, + "WalletInfo": { + "type": "object", + "description": "Wallet information", + "properties": { + "walletId": { + "$ref": "#/components/schemas/WalletId" + }, + "paymentMethodId": { + "description": "Payment method identifier", + "type": "string" + }, + "status": { + "$ref": "#/components/schemas/WalletStatus" + }, + "creationDate": { + "description": "Wallet creation date", + "type": "string", + "format": "date-time" + }, + "updateDate": { + "description": "Wallet update date", + "type": "string", + "format": "date-time" + }, + "applications": { + "description": "list of applications for which this wallet is created for", + "type": "array", + "items": { + "$ref": "#/components/schemas/WalletApplicationInfo" + } + }, + "clients": { + "description": "Client-specific state (e.g. last usage) and configuration (enabled/disabled)", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/WalletClient" + } + }, + "details": { + "$ref": "#/components/schemas/WalletInfoDetails" + }, + "paymentMethodAsset": { + "description": "Payment method asset", + "type": "string", + "format": "uri", + "example": "http://logo.cdn/brandLogo" + } + }, + "required": [ + "walletId", + "paymentMethodId", + "status", + "creationDate", + "updateDate", + "applications", + "clients", + "paymentMethodAsset" + ] + }, + "WalletInfoDetails": { + "description": "details for the specific payment instrument. This field is disciminated by the type field", + "oneOf": [ + { + "type": "object", + "description": "Card payment instrument details", + "properties": { + "type": { + "type": "string", + "description": "Wallet details discriminator field. Fixed valued 'CARDS'" + }, + "lastFourDigits": { + "description": "Card last 4 digits", + "type": "string", + "example": "9876" + }, + "expiryDate": { + "type": "string", + "description": "Credit card expiry date. The date format is `YYYYMM`", + "pattern": "^[0-9]{6}$", + "example": "203012" + }, + "brand": { + "description": "Payment instrument brand", + "type": "string" + } + }, + "required": [ + "type", + "lastFourDigits", + "expiryDate", + "brand" + ] + }, + { + "type": "object", + "description": "Paypal instrument details", + "properties": { + "type": { + "type": "string", + "description": "Wallet details discriminator field. Fixed valued 'PAYPAL'" + }, + "pspId": { + "description": "bank identifier", + "type": "string" + }, + "pspBusinessName": { + "description": "PSP business name", + "type": "string" + }, + "maskedEmail": { + "description": "email masked pan", + "type": "string", + "example": "test***@***test.it" + } + }, + "required": [ + "type", + "pspId", + "pspBusinessName" + ] + }, + { + "type": "object", + "description": "Bancomat pay instrument details", + "properties": { + "type": { + "type": "string", + "description": "Wallet details discriminator field. Fixed valued 'BANCOMATPAY'" + }, + "maskedNumber": { + "description": "masked number", + "type": "string", + "minLength": 1, + "maxLength": 20, + "example": "+3938*******202" + }, + "instituteCode": { + "description": "institute code", + "type": "string", + "minLength": 1, + "maxLength": 5, + "example": "12345" + }, + "bankName": { + "description": "bank name", + "type": "string", + "example": "banca di banca" + } + }, + "required": [ + "type", + "maskedNumber", + "instituteCode", + "bankName" + ] + } + ] + }, + "Wallets": { + "type": "object", + "description": "Wallets information", + "properties": { + "wallets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WalletInfo" + } + } + } + }, + "ProblemJson": { + "description": "Body definition for error responses containing failure details", + "type": "object", + "properties": { + "type": { + "type": "string", + "format": "uri", + "description": "An absolute URI that identifies the problem type. When dereferenced,\nit SHOULD provide human-readable documentation for the problem type\n(e.g., using HTML).", + "default": "about:blank", + "example": "https://example.com/problem/constraint-violation" + }, + "title": { + "type": "string", + "description": "A short, summary of the problem type. Written in english and readable\nfor engineers (usually not suited for non technical stakeholders and\nnot localized); example: Application Unavailable" + }, + "status": { + "$ref": "#/components/schemas/HttpStatusCode" + }, + "detail": { + "type": "string", + "description": "A human readable explanation specific to this occurrence of the\nproblem.", + "example": "There was an error processing the request" + }, + "instance": { + "type": "string", + "format": "uri", + "description": "An absolute URI that identifies the specific occurrence of the problem.\nIt may or may not yield further information if dereferenced." + } + } + }, + "HttpStatusCode": { + "type": "integer", + "format": "int32", + "description": "The HTTP status code generated by the origin server for this occurrence\nof the problem.", + "minimum": 100, + "maximum": 600, + "exclusiveMaximum": true, + "example": 502 + }, + "PaymentMethodsResponse": { + "type": "object", + "description": "Payment methods response", + "properties": { + "paymentMethods": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentMethodResponse" + } + } + } + }, + "PaymentMethodResponse": { + "type": "object", + "description": "Payment method Response", + "properties": { + "id": { + "type": "string", + "description": "Payment method ID" + }, + "name": { + "type": "string", + "description": "Payment method name" + }, + "description": { + "type": "string", + "description": "Payment method description" + }, + "asset": { + "type": "string", + "description": "Payment method asset name" + }, + "status": { + "$ref": "#/components/schemas/PaymentMethodStatus" + }, + "paymentTypeCode": { + "type": "string", + "description": "Payment method type code" + }, + "methodManagement": { + "$ref": "#/components/schemas/PaymentMethodManagementType" + }, + "ranges": { + "description": "Payment amount range in eurocents", + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/Range" + } + }, + "brandAssets": { + "description": "Brand assets map associated to the selected payment method", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "id", + "name", + "description", + "status", + "paymentTypeCode", + "ranges", + "methodManagement" + ] + }, + "PaymentMethodStatus": { + "type": "string", + "description": "Payment method status", + "enum": [ + "ENABLED", + "DISABLED", + "INCOMING" + ] + }, + "PaymentMethodManagementType": { + "type": "string", + "description": "Describes how to manage the payment method authorization flow in wallet and eCommerce domain:\n- REDIRECT if it must be managed with a redirect flow;\n- ONBOARDABLE if it must be managed with NPG and it is possible to save the payment method in the wallet, but also guest payment is accepted;\n- NOT_ONBOARDABLE if it must be managed with NPG but the method cannot be saved, only guest payment is accepted;\n- ONBOARDABLE_ONLY if it must be managed with NPG and it is mandatory to save the payment method in the wallet to use it. Guest payment isn't accepted;\n- ONBORDABLE_WITH_PAYMENT if it must be managed with NPG and it is possible to save it, to use it as guest payment, and to onboard it during the payment;", + "enum": [ + "ONBOARDABLE", + "NOT_ONBOARDABLE", + "REDIRECT", + "ONBOARDABLE_ONLY", + "ONBOARDABLE_WITH_PAYMENT" + ] + }, + "Range": { + "type": "object", + "description": "Payment amount range in cents", + "properties": { + "min": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Range min amount" + }, + "max": { + "type": "integer", + "format": "int64", + "minimum": 0 + } + } + } + }, + "securitySchemes": { + "pagoPAPlatformSessionToken": { + "type": "http", + "scheme": "bearer", + "description": "session token according to pagoPA platform for IO" + } + } + } +} \ No newline at end of file diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_post_wallets.xml.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_post_wallets.xml.tpl new file mode 100644 index 0000000000..4806956069 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_post_wallets.xml.tpl @@ -0,0 +1,128 @@ + + + + + + + + + + @("https://${ecommerce_hostname}/pagopa-ecommerce-payment-methods-service/payment-methods/" + context.Variables["paymentMethodId"]) + GET + + IO + + + + + + + + application/json + + + { + "title": "Error retrieving eCommerce payment methods", + "status": 502, + "detail": "There was an error retrieving eCommerce payment methods" + } + + + + + ())" /> + + + { + { "CP", "pm-onboarding/creditcard" }, + { "BPAY", "pm-onboarding/bpay" }, + { "PPAL", "pm-onboarding/paypal" } + }; + + string redirectUrlPrefix; + paymentMethodTypeCodes.TryGetValue(returnedPaymentMethodTypeCode, out redirectUrlPrefix); + return redirectUrlPrefix; + }" /> + + + + + + application/json + + + { + "title": "Error retrieving eCommerce payment methods", + "status": 502, + "detail": "Invalid payment method name" + } + + + + + + + + + application/json + + @{ + return new JObject( + new JProperty("redirectUrl", $"https://${env}payment-wallet.pagopa.it/{(string)context.Variables["redirectUrlPrefix"]}#sessionToken={((string) context.Variables["sessionToken"])}") + ).ToString(); + } + + + + + + + + + + + + + + + + @{ + JObject inBody = context.Response.Body.As(preserveContent: true); + var redirectUrl = inBody["redirectUrl"]; + inBody["redirectUrl"] = redirectUrl + "&sessionToken=" + ((string)context.Variables.GetValueOrDefault("x-jwt-token","")); + inBody.Remove("walletId"); + return inBody.ToString(); + } + + + + + + + + + + diff --git a/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_update_applications.xml.tpl b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_update_applications.xml.tpl new file mode 100644 index 0000000000..1d05867878 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api/io-payment-wallet/v1/_update_applications.xml.tpl @@ -0,0 +1,119 @@ + + + + + + + + + + @($"{{pm-host}}/pp-restapi-CD/v2/wallet/{(string)context.Variables["idWalletPM"]}/payment-status") + PUT + + application/json + + + @($"Bearer {((String)context.Variables["sessionToken"])}") + + @{ + JObject requestBody = (JObject)context.Variables["requestBody"]; + JArray applications = (JArray)requestBody["applications"]; + foreach(JObject application in applications){ + String name = application["name"].ToString(); + String status = application["status"].ToString(); + if(name.Equals("PAGOPA")) { + return new JObject( + new JProperty("data", new JObject( + new JProperty("pagoPA", status.Equals("ENABLED")) + )) + ).ToString(); + } + } + return new JObject().ToString(); + } + + + + + + + + + + + + + + application/json + + + { + "title": "Unauthorized", + "status": 401, + "detail": "Unauthorized" + } + + + + + + + + application/json + + + { + "title": "Forbidden", + "status": 403, + "detail": "Forbidden" + } + + + + + + + + application/json + + + { + "title": "Not Found", + "status": 404, + "detail": "Wallet not found" + } + + + + + + + + application/json + + + { + "title": "Error changing wallet status", + "status": 502, + "detail": "There was an error changing wallet status" + } + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/domains/pay-wallet-app-v2/api_product/_base_policy.xml b/src/domains/pay-wallet-app-v2/api_product/_base_policy.xml new file mode 100644 index 0000000000..ce18a37436 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/api_product/_base_policy.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/domains/pay-wallet-app-v2/env/itn-prod/backend.ini b/src/domains/pay-wallet-app-v2/env/itn-prod/backend.ini new file mode 100644 index 0000000000..ddda4bb50f --- /dev/null +++ b/src/domains/pay-wallet-app-v2/env/itn-prod/backend.ini @@ -0,0 +1 @@ +subscription=prod-pagoPA diff --git a/src/domains/pay-wallet-app-v2/env/itn-prod/backend.tfvars b/src/domains/pay-wallet-app-v2/env/itn-prod/backend.tfvars new file mode 100644 index 0000000000..c2c27f7775 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/env/itn-prod/backend.tfvars @@ -0,0 +1,4 @@ +resource_group_name = "terraform-state-rg" +storage_account_name = "tfinfprodpagopa" +container_name = "terraform-state" +key = "pay-wallet-app-prod-v2.terraform.tfstate" diff --git a/src/domains/pay-wallet-app-v2/env/itn-prod/terraform.tfvars b/src/domains/pay-wallet-app-v2/env/itn-prod/terraform.tfvars new file mode 100644 index 0000000000..811ae181fa --- /dev/null +++ b/src/domains/pay-wallet-app-v2/env/itn-prod/terraform.tfvars @@ -0,0 +1,47 @@ +prefix = "pagopa" +env_short = "p" +env = "prod" +domain = "pay-wallet" +location = "italynorth" +location_short = "itn" +location_string = "Italy North" +instance = "prod" + +tags = { + CreatedBy = "Terraform" + Environment = "prod" + Owner = "pagoPA" + Source = "https://github.com/pagopa/pagopa-infra/tree/main/src/domains/pay-wallet-app" + CostCenter = "TS310 - PAGAMENTI & SERVIZI" +} + +### External resources + +monitor_italy_resource_group_name = "pagopa-p-itn-core-monitor-rg" +log_analytics_italy_workspace_name = "pagopa-p-itn-core-law" +log_analytics_italy_workspace_resource_group_name = "pagopa-p-itn-core-monitor-rg" + +external_domain = "pagopa.it" +dns_zone_internal_prefix = "internal.platform" +dns_zone_prefix = "payment-wallet" +apim_dns_zone_prefix = "platform" + +### Aks + +ingress_load_balancer_ip = "10.3.2.250" + +# chart releases: https://github.com/pagopa/aks-microservice-chart-blueprint/releases +# image tags: https://github.com/pagopa/infra-ssl-check/releases +tls_cert_check_helm = { + chart_version = "2.0.0" + image_name = "ghcr.io/pagopa/infra-ssl-check" + image_tag = "v1.3.4@sha256:c3d45736706c981493b6216451fc65e99a69d5d64409ccb1c4ca93fef57c921d" +} + +pdv_api_base_path = "https://api.tokenizer.pdv.pagopa.it/tokenizer/v1" +io_backend_base_path = "https://api-app.io.pagopa.it" + +payment_wallet_with_pm_enabled = true + +payment_wallet_migrations_enabled = true +enabled_payment_wallet_method_ids_pm = "6920b555-c972-4e2b-980c-b0e0037a111a,0ff153c2-4c5e-49a5-8720-788b6f190264,b63dbc2b-0b89-4431-a196-a5d73ff7ce9c" diff --git a/src/domains/pay-wallet-app-v2/helm/cert-mounter.yaml.tpl b/src/domains/pay-wallet-app-v2/helm/cert-mounter.yaml.tpl new file mode 100644 index 0000000000..224cb4f111 --- /dev/null +++ b/src/domains/pay-wallet-app-v2/helm/cert-mounter.yaml.tpl @@ -0,0 +1,13 @@ +namespace: ${NAMESPACE} +nameOverride: "" +fullnameOverride: "" + +deployment: + create: true + +kvCertificatesName: + - ${CERTIFICATE_NAME} + +keyvault: + name: "pagopa-${ENV_SHORT}-${DOMAIN}-kv" + tenantId: "7788edaf-0346-4068-9d79-c868aed15b3d" diff --git a/src/domains/pay-wallet-app-v2/terraform.sh b/src/domains/pay-wallet-app-v2/terraform.sh new file mode 100755 index 0000000000..c19455653f --- /dev/null +++ b/src/domains/pay-wallet-app-v2/terraform.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -e + +action=$1 +env=$2 +shift 2 +other=$@ + +if [ -z "$action" ]; then + echo "Missed action: init, apply, plan" + exit 0 +fi + +if [ -z "$env" ]; then + echo "env should be: dev, uat or prod." + exit 0 +fi + +source "./env/$env/backend.ini" +az account set -s "${subscription}" + +if echo "init plan apply refresh import output state taint destroy" | grep -w $action > /dev/null; then + if [ $action = "init" ]; then + terraform $action -reconfigure -backend-config="./env/$env/backend.tfvars" $other + elif [ $action = "output" ] || [ $action = "state" ] || [ $action = "taint" ]; then + # init terraform backend + terraform init -reconfigure -backend-config="./env/$env/backend.tfvars" + terraform $action $other + else + # init terraform backend + terraform init -reconfigure -backend-config="./env/$env/backend.tfvars" + terraform $action -var-file="./env/$env/terraform.tfvars" $other + fi +else + echo "Action not allowed." + exit 1 +fi diff --git a/src/domains/pay-wallet-app/.terraform.lock.hcl b/src/domains/pay-wallet-app/.terraform.lock.hcl index 80fe8f2b7e..792c4b3f64 100644 --- a/src/domains/pay-wallet-app/.terraform.lock.hcl +++ b/src/domains/pay-wallet-app/.terraform.lock.hcl @@ -1,6 +1,26 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/azure/azapi" { + version = "1.3.0" + constraints = "<= 1.3.0" + hashes = [ + "h1:OWZNYEGEIunmpxEcbGveH+kkdELQfMCUYxLt1b25UOc=", + "zh:0923b297c5b71ed584e5f3a0b2393e80244076e85102a90438159833353274b0", + "zh:11fa2922aa98ca55beaf7cc33c7edbde81bbd405fdfea2955276c7f5a8537240", + "zh:14af830fb6091d084bfc2711c8e9c7bf05aa3c56fe8fd8e2fb4eddeb345be88d", + "zh:25258425ecbffbdf09b0c8131d2c680cddd19b504e0036ee5f83972dcae7df0a", + "zh:2922b535fe4d4f0963189548f2f8360a0aaf951fd411354f2269a111d8a0c1ad", + "zh:32c9360305e00c25d0f9d0a84dfbdbad8da2465be769a9c1f11f132c0225358e", + "zh:4ddd3ee23c340d5000839d8d30ba7f94e695476d63075f95cfb041e67d8f6ef6", + "zh:5c1514392a5c3dd51084aa70cb6c4dcc8b027c4508b5e4eb9f8c3990fd403213", + "zh:6b3ecac7099ab86c007b5ad636bd029f5e5f3e9bd06b0f74c82f0451a7995ecc", + "zh:6cb7081745b378e910e0cf09fb5717a2ad35e629ce3e07415d6682c1c1407872", + "zh:7107eda5125c1b983380f1f6418c592fb7fb2eb5b589ad0e08f6c47341f36318", + "zh:c6fa7af32a7a47d23a85e0eea4d4cbb065378ae75aed8c9c628fb625b04bc619", + ] +} + provider "registry.terraform.io/hashicorp/azuread" { version = "2.47.0" constraints = "<= 2.47.0" @@ -29,6 +49,7 @@ provider "registry.terraform.io/hashicorp/azurerm" { version = "3.45.0" constraints = ">= 3.30.0, ~> 3.30, <= 3.45.0, <= 3.95.0, <= 3.97.1" hashes = [ + "h1:VQWxV5+qelZeUCjpdLvZ7iAom4RvG+fVVgK6ELvw/cs=", "h1:gQLNY1I5e9kcle1p/VYEWb0eteQ/t5kUfnqVu2/GBNY=", "zh:04c5dbb8845366ce5eb0dc2d55e151270cc2c0ace20993867fdae9af43b953ad", "zh:2589585da615ccae341400d45d672ee3fae413fdd88449b5befeff12a85a44b2", diff --git a/src/domains/pay-wallet-app/00_data.tf b/src/domains/pay-wallet-app/00_data.tf new file mode 100644 index 0000000000..ae7bbf3b32 --- /dev/null +++ b/src/domains/pay-wallet-app/00_data.tf @@ -0,0 +1,4 @@ +data "azurerm_api_management" "apim" { + name = "${local.product}-apim" + resource_group_name = "${local.product}-api-rg" +} diff --git a/src/domains/pay-wallet-app/04_apim_io_payment_wallet.tf b/src/domains/pay-wallet-app/04_apim_io_payment_wallet.tf index cac0ca577e..9ce11f35f0 100644 --- a/src/domains/pay-wallet-app/04_apim_io_payment_wallet.tf +++ b/src/domains/pay-wallet-app/04_apim_io_payment_wallet.tf @@ -84,7 +84,11 @@ resource "azurerm_api_management_api_operation_policy" "get_payment_methods_for_ api_management_name = local.pagopa_apim_name operation_id = "getAllPaymentMethodsForIO" - xml_content = templatefile("./api/io-payment-wallet/v1/_get_payment_methods.xml.tpl", { ecommerce_hostname = local.ecommerce_hostname } + xml_content = templatefile("./api/io-payment-wallet/v1/_get_payment_methods.xml.tpl", + { + ecommerce_hostname = local.ecommerce_hostname + enabled_payment_wallet_method_ids_pm = var.enabled_payment_wallet_method_ids_pm + } ) } @@ -113,7 +117,7 @@ resource "azurerm_api_management_api_operation_policy" "post_io_wallets" { operation_id = "createIOPaymentWallet" xml_content = templatefile("./api/io-payment-wallet/v1/_post_wallets.xml.tpl", { - env = var.env, + env = var.env == "prod" ? "" : "${var.env}.", ecommerce_hostname = local.ecommerce_hostname }) } @@ -126,3 +130,44 @@ resource "azurerm_api_management_api_operation_policy" "update_applications_for_ xml_content = file("./api/io-payment-wallet/v1/_update_applications.xml.tpl") } + + +resource "azurerm_api_management_named_value" "pay_wallet_family_friends_user_ids" { + name = "pay-wallet-family-friends-user-ids" + api_management_name = local.pagopa_apim_name + resource_group_name = local.pagopa_apim_rg + display_name = "pay-wallet-family-friends-user-ids" + value = "" + lifecycle { + ignore_changes = [ + value, + ] + } +} + + +####################################################################### +## Fragment policy to extract user id from session token ## +####################################################################### + +resource "azapi_resource" "pay_wallet_fragment_user_id_from_session_token" { + + # provider = azapi.apim + type = "Microsoft.ApiManagement/service/policyFragments@2022-04-01-preview" + name = "pay-wallet-user-id-from-session-token" + parent_id = data.azurerm_api_management.apim.id + + body = jsonencode({ + properties = { + description = "Component that extract userId from JWT session token" + format = "rawxml" + value = templatefile("./api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml", { + }) + + } + }) + + lifecycle { + ignore_changes = [output] + } +} diff --git a/src/domains/pay-wallet-app/99_main.tf b/src/domains/pay-wallet-app/99_main.tf index 2835595f8a..5faabf1825 100644 --- a/src/domains/pay-wallet-app/99_main.tf +++ b/src/domains/pay-wallet-app/99_main.tf @@ -20,6 +20,10 @@ terraform { source = "hashicorp/helm" version = "<= 2.12.0" } + azapi = { + source = "azure/azapi" + version = "<= 1.3.0" + } } backend "azurerm" {} diff --git a/src/domains/pay-wallet-app/99_variables.tf b/src/domains/pay-wallet-app/99_variables.tf index 4970525d7a..95e6f85798 100644 --- a/src/domains/pay-wallet-app/99_variables.tf +++ b/src/domains/pay-wallet-app/99_variables.tf @@ -149,3 +149,9 @@ variable "payment_wallet_migrations_enabled" { default = false description = "Payment wallet migrations enabled" } + +variable "enabled_payment_wallet_method_ids_pm" { + type = string + default = "" + description = "Comma separated list of eCommerce payment method ids that are enabled with PM APIs" +} diff --git a/src/domains/pay-wallet-app/README.md b/src/domains/pay-wallet-app/README.md index 5ad6966bd4..17bcf749d3 100644 --- a/src/domains/pay-wallet-app/README.md +++ b/src/domains/pay-wallet-app/README.md @@ -6,6 +6,7 @@ | Name | Version | |------|---------| +| [azapi](#requirement\_azapi) | <= 1.3.0 | | [azuread](#requirement\_azuread) | <= 2.47.0 | | [azurerm](#requirement\_azurerm) | <= 3.95.0 | | [helm](#requirement\_helm) | <= 2.12.0 | @@ -34,6 +35,7 @@ | Name | Type | |------|------| +| [azapi_resource.pay_wallet_fragment_user_id_from_session_token](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource) | resource | | [azurerm_api_management_api_operation_policy.create_wallet_pm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.delete_io_wallets](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | | [azurerm_api_management_api_operation_policy.delete_wallet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_operation_policy) | resource | @@ -57,6 +59,7 @@ | [azurerm_api_management_api_version_set.wallet_outcomes_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_api_version_set.wallet_webview_api](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_api_version_set) | resource | | [azurerm_api_management_group.payment-wallet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_group) | resource | +| [azurerm_api_management_named_value.pay_wallet_family_friends_user_ids](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | | [azurerm_api_management_named_value.wallet-jwt-signing-key](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | | [azurerm_api_management_named_value.wallet_personal_data_vault_api_key](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management_named_value) | resource | | [azurerm_key_vault_secret.aks_apiserver_url](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource | @@ -72,6 +75,7 @@ | [azuread_group.adgroup_developers](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | | [azuread_group.adgroup_externals](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | | [azuread_group.adgroup_security](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source | +| [azurerm_api_management.apim](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/api_management) | data source | | [azurerm_application_insights.application_insights_italy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/application_insights) | data source | | [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source | | [azurerm_key_vault.kv](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault) | data source | @@ -94,6 +98,7 @@ | [dns\_zone\_internal\_prefix](#input\_dns\_zone\_internal\_prefix) | The dns subdomain. | `string` | `null` | no | | [dns\_zone\_prefix](#input\_dns\_zone\_prefix) | The wallet dns subdomain. | `string` | `null` | no | | [domain](#input\_domain) | n/a | `string` | n/a | yes | +| [enabled\_payment\_wallet\_method\_ids\_pm](#input\_enabled\_payment\_wallet\_method\_ids\_pm) | Comma separated list of eCommerce payment method ids that are enabled with PM APIs | `string` | `""` | no | | [env](#input\_env) | n/a | `string` | n/a | yes | | [env\_short](#input\_env\_short) | n/a | `string` | n/a | yes | | [external\_domain](#input\_external\_domain) | Domain for delegation | `string` | `null` | no | diff --git a/src/domains/pay-wallet-app/api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml b/src/domains/pay-wallet-app/api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml new file mode 100644 index 0000000000..39eefad065 --- /dev/null +++ b/src/domains/pay-wallet-app/api/fragments/_fragment_policy_user_id_from_session_token.tpl.xml @@ -0,0 +1,21 @@ + + + + 1 ? sessionTokenParts[1] : ""; + int reminder = sessionTokenBody.Length % 4; + int toPad = reminder > 1 ? (4-reminder) : 0; + string padded = string.Concat(sessionTokenBody,string.Concat(Enumerable.Repeat("=", toPad))); + byte[] data = Convert.FromBase64String(padded); + string decodedString = System.Text.Encoding.UTF8.GetString(data); + Dictionary parsed = JsonConvert.DeserializeObject>(decodedString); + string userId = (string)parsed?["userId"]; + return String.IsNullOrEmpty(userId) ? "user-id-not-found" : userId; + } catch(Exception){ + return "user-id-not-found"; + } + }" /> + \ No newline at end of file diff --git a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_base_policy.xml.tpl b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_base_policy.xml.tpl index a4ca40dcb8..f755c4d77b 100644 --- a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_base_policy.xml.tpl +++ b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_base_policy.xml.tpl @@ -1,8 +1,11 @@ + + - + diff --git a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_delete_wallet.xml.tpl b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_delete_wallet.xml.tpl index 488077b9ce..1c57d097b0 100644 --- a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_delete_wallet.xml.tpl +++ b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_delete_wallet.xml.tpl @@ -2,7 +2,7 @@ - + - + @@ -10,6 +10,34 @@ + + + @{ + JObject response = context.Response.Body.As(); + + if (context.Response.StatusCode != 200) { + return response.ToString(); + } + + string enabled_payment_wallet_method_ids_pm = "${enabled_payment_wallet_method_ids_pm}"; + string[] values = enabled_payment_wallet_method_ids_pm.Split(','); + HashSet pmEnabledMethods = new HashSet(values); + + foreach (var method in ((JArray) response["paymentMethods"])) { + string id = (string) method["id"]; + if (pmEnabledMethods.Contains(id)) { + method["status"] = "ENABLED"; + method["methodManagement"] = "ONBOARDABLE_ONLY"; + } else { + method["status"] = "DISABLED"; + } + } + + return response.ToString(); + } + + + diff --git a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl index 36d7663de0..39fa423c1c 100644 --- a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl +++ b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user.xml.tpl @@ -2,7 +2,7 @@ - + {{pm-host}}/pp-restapi-CD/v3/wallet @@ -12,6 +12,19 @@ + + + + + application/json + + { + "title": "Unauthorized", + "status": 401, + "detail": "Unauthorized" + } + + diff --git a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl index f0c845082b..b03ec92afa 100644 --- a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl +++ b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_get_wallets_by_user_and_walletId.xml.tpl @@ -1,8 +1,8 @@ - + - + + + + + + application/json + + { + "title": "Unauthorized", + "status": 401, + "detail": "Unauthorized" + } + + application/json - - { + { "title": "Error retrieving user wallet data", "status": 502, "detail": "There was an error retrieving user wallet data" - } - + } @@ -42,13 +53,11 @@ application/json - - { + { "title": "Wallet not found", "status": 404, "detail": "No wallet found for input wallet token" - } - + } @@ -64,29 +73,21 @@ - - - application/json - - - { + + + application/json + + { "title": "Error retrieving eCommerce payment methods", "status": 502, "detail": "There was an error retrieving eCommerce payment methods" - } - + } ())" /> - - - - application/json - - - @{ + {"PAGOPA"}; var eCommerceWalletTypes = new Dictionary @@ -178,12 +179,33 @@ return result; - }).Single(); - - return walletResult.ToString(); - } - - + }).SingleOrDefault(); + return walletResult; + }" /> + + + + + + application/json + + @(((JObject)context.Variables["walletResponseBody"]).ToString()) + + + + + + + application/json + + { + "title": "Wallet not found", + "status": 404, + "detail": "Wallet not found" + } + + + @@ -196,4 +218,4 @@ - + \ No newline at end of file diff --git a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_post_wallets.xml.tpl b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_post_wallets.xml.tpl index 5919cc24d8..4806956069 100644 --- a/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_post_wallets.xml.tpl +++ b/src/domains/pay-wallet-app/api/io-payment-wallet/v1/_post_wallets.xml.tpl @@ -2,7 +2,7 @@ - + @@ -70,7 +70,7 @@ @{ return new JObject( - new JProperty("redirectUrl", $"https://${env}.payment-wallet.pagopa.it/{(string)context.Variables["redirectUrlPrefix"]}#sessionToken={((string) context.Variables["sessionToken"])}") + new JProperty("redirectUrl", $"https://${env}payment-wallet.pagopa.it/{(string)context.Variables["redirectUrlPrefix"]}#sessionToken={((string) context.Variables["sessionToken"])}") ).ToString(); }
@@ -83,7 +83,7 @@ - + + - + + + + @($"{{pm-host}}/pp-restapi-CD/v1/users/actions/start-session?token={(string)context.Variables["walletToken"]}") + GET + - - - - @($"{{pm-host}}/pp-restapi-CD/v1/users/actions/start-session?token={(string)context.Variables["walletToken"]}") - GET - - - - - - - application/json - - - { - "title": "Unauthorized", - "status": 401, - "detail": "Invalid session token" - } - - - - + + + + + application/json + + + { + "title": "Unauthorized", + "status": 401, + "detail": "Invalid session token" + } + + + + + + + + application/json + + + { + "title": "Error starting session", + "status": 502, + "detail": "There was an error starting session for input wallet token" + } + + + + + ())" /> + + + + + + + + + application/json + + + { + "title": "Error starting session", + "status": 502, + "detail": "Cannot tokenize user fiscal code: PM start-session fiscalCode is null" + } + + + + + + + ${pdv_api_base_path}/tokens + PUT + + {{wallet-session-personal-data-vault-api-key}} + + @{ + return new JObject( + new JProperty("pii", (string)context.Variables["userFiscalCode"]) + ).ToString(); + } + + + - - - application/json - - - { - "title": "Error starting session", - "status": 502, - "detail": "There was an error starting session for input wallet token" - } - + + + { + "title": "Error starting session", + "status": 502, + "detail": "Error during fiscal code tokenization" + } + - - - ())" /> - + + + + ())" /> + + + + + + + + application/json + + @{ + return new JObject( + new JProperty("title", "Bad gateway - Invalid PDV response"), + new JProperty("status", 502), + new JProperty("detail", "Cannot tokenize fiscal code") + ).ToString(); + } + + + + + + + + + @@ -94,50 +173,6 @@ ())" /> - - - ${pdv_api_base_path}/tokens - PUT - - {{wallet-session-personal-data-vault-api-key}} - - @{ - JObject requestBody = (JObject)context.Variables["userAuthBody"]; - return new JObject( - new JProperty("pii", (string)requestBody["fiscal_code"]) - ).ToString(); - } - - - - - - - - - - ())" /> - - - - - - - - application/json - - @{ - return new JObject( - new JProperty("title", "Bad gateway - Invalid PDV response"), - new JProperty("status", 502), - new JProperty("detail", "Cannot tokenize fiscal code") - ).ToString(); - } - - - - -