diff --git a/Deployment/nginx.conf b/Deployment/nginx.conf index 00e39ffc4..ef1e81ebe 100644 --- a/Deployment/nginx.conf +++ b/Deployment/nginx.conf @@ -59,6 +59,10 @@ http { return 403; } + location /wallet/payment/internal { + return 403; + } + location /wallet { proxy_pass http://docker-wallet; rewrite ^/wallet(.*)$ $1 break; diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/config/SecurityConfig.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/config/SecurityConfig.kt index 0273e6734..a92bc17ab 100644 --- a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/config/SecurityConfig.kt +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/config/SecurityConfig.kt @@ -37,6 +37,7 @@ class SecurityConfig(private val webClient: WebClient) { AuthorizationDecision(granted) } } + .pathMatchers("/payment/internal/**").permitAll() .pathMatchers("/**").permitAll() .anyExchange().authenticated() .and() diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/PaymentGatewayController.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/PaymentGatewayController.kt new file mode 100644 index 000000000..8676c15c6 --- /dev/null +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/controller/PaymentGatewayController.kt @@ -0,0 +1,72 @@ +package co.nilin.opex.wallet.app.controller + +import co.nilin.opex.utility.error.data.OpexError +import co.nilin.opex.utility.error.data.OpexException +import co.nilin.opex.wallet.app.dto.PaymentCurrency +import co.nilin.opex.wallet.app.dto.PaymentDepositRequest +import co.nilin.opex.wallet.app.dto.PaymentDepositResponse +import co.nilin.opex.wallet.core.inout.TransferCommand +import co.nilin.opex.wallet.core.model.Amount +import co.nilin.opex.wallet.core.service.TransferService +import co.nilin.opex.wallet.core.spi.CurrencyService +import co.nilin.opex.wallet.core.spi.WalletManager +import co.nilin.opex.wallet.core.spi.WalletOwnerManager +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import java.math.BigDecimal + +@RestController +@RequestMapping("/payment") +class PaymentGatewayController( + val transferService: TransferService, + val currencyService: CurrencyService, + val walletManager: WalletManager, + val walletOwnerManager: WalletOwnerManager +) { + + @PostMapping("/internal/deposit") + suspend fun paymentDeposit(@RequestBody request: PaymentDepositRequest): PaymentDepositResponse { + val systemUuid = "1" + val receiverWalletType = "main" + val convertedAmount = when (request.currency) { + PaymentCurrency.RIALS -> (request.amount / 10).toLong() + PaymentCurrency.TOMAN -> request.amount.toLong() + } + + val currency = currencyService.getCurrency("IRT") ?: throw OpexException(OpexError.CurrencyNotFound) + val sourceOwner = walletOwnerManager.findWalletOwner(systemUuid) + ?: throw OpexException(OpexError.WalletOwnerNotFound) + val sourceWallet = walletManager.findWalletByOwnerAndCurrencyAndType(sourceOwner, "main", currency) + ?: walletManager.createWallet(sourceOwner, Amount(currency, BigDecimal.ZERO), currency, "main") + + val receiverOwner = walletOwnerManager.findWalletOwner(request.userId) + ?: walletOwnerManager.createWalletOwner(request.userId, "not set", "") + + val receiverWallet = walletManager.findWalletByOwnerAndCurrencyAndType( + receiverOwner, + receiverWalletType, + currency + ) ?: walletManager.createWallet( + receiverOwner, + Amount(currency, BigDecimal.ZERO), + currency, + receiverWalletType + ) + + val command = transferService.transfer( + TransferCommand( + sourceWallet, + receiverWallet, + Amount(sourceWallet.currency(), convertedAmount.toBigDecimal()), + request.description, + request.reference, + emptyMap() + ) + ) + + return PaymentDepositResponse(true) + } + +} \ No newline at end of file diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentCurrency.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentCurrency.kt new file mode 100644 index 000000000..91f76f21c --- /dev/null +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentCurrency.kt @@ -0,0 +1,5 @@ +package co.nilin.opex.wallet.app.dto + +enum class PaymentCurrency { + RIALS, TOMAN +} \ No newline at end of file diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentDepositRequest.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentDepositRequest.kt new file mode 100644 index 000000000..0b9b871a0 --- /dev/null +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentDepositRequest.kt @@ -0,0 +1,9 @@ +package co.nilin.opex.wallet.app.dto + +data class PaymentDepositRequest( + val userId: String, // user uuid + val amount: Double, + val currency: PaymentCurrency, + val reference: String, + val description: String? +) \ No newline at end of file diff --git a/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentDepositResponse.kt b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentDepositResponse.kt new file mode 100644 index 000000000..61438d55a --- /dev/null +++ b/wallet/wallet-app/src/main/kotlin/co/nilin/opex/wallet/app/dto/PaymentDepositResponse.kt @@ -0,0 +1,3 @@ +package co.nilin.opex.wallet.app.dto + +data class PaymentDepositResponse(val success: Boolean) \ No newline at end of file diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/resources/schema.sql b/wallet/wallet-ports/wallet-persister-postgres/src/main/resources/schema.sql index 019fef299..a2750ca74 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/resources/schema.sql +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/resources/schema.sql @@ -37,7 +37,7 @@ CREATE TABLE IF NOT EXISTS transaction ( source_amount DECIMAL NOT NULL, dest_amount DECIMAL NOT NULL, description TEXT, - transfer_ref TEXT, + transfer_ref TEXT UNIQUE, transaction_date TIMESTAMP NOT NULL DEFAULT CURRENT_DATE );