Implemented transferMoney()
This commit is contained in:
parent
6512f45955
commit
8671bf058d
|
@ -2,10 +2,7 @@ import kotlinx.coroutines.GlobalScope
|
|||
import kotlinx.coroutines.launch
|
||||
import net.dankito.banking.client.model.AccountTransaction
|
||||
import net.dankito.banking.fints.model.TanChallenge
|
||||
import react.RBuilder
|
||||
import react.RComponent
|
||||
import react.Props
|
||||
import react.State
|
||||
import react.*
|
||||
import react.dom.*
|
||||
import styled.styledDiv
|
||||
|
||||
|
@ -13,7 +10,8 @@ external interface AccountTransactionsViewProps : Props {
|
|||
var presenter: Presenter
|
||||
}
|
||||
|
||||
data class AccountTransactionsViewState(val balance: String, val transactions: Collection<AccountTransaction>, val enterTanChallenge: TanChallenge? = null) : State
|
||||
data class AccountTransactionsViewState(val balance: String, val transactions: Collection<AccountTransaction>, var showTransferMoneyView: Boolean = false,
|
||||
val enterTanChallenge: TanChallenge? = null) : State
|
||||
|
||||
@JsExport
|
||||
class AccountTransactionsView(props: AccountTransactionsViewProps) : RComponent<AccountTransactionsViewProps, AccountTransactionsViewState>(props) {
|
||||
|
@ -22,7 +20,7 @@ class AccountTransactionsView(props: AccountTransactionsViewProps) : RComponent<
|
|||
init {
|
||||
state = AccountTransactionsViewState("", listOf())
|
||||
|
||||
props.presenter.enterTanCallback = { setState(AccountTransactionsViewState(state.balance, state.transactions, it)) }
|
||||
props.presenter.enterTanCallback = { setState(AccountTransactionsViewState(state.balance, state.transactions, state.showTransferMoneyView, it)) }
|
||||
|
||||
// due to CORS your bank's servers can not be requested directly from browser -> set a CORS proxy url in main.kt
|
||||
// TODO: set your credentials here
|
||||
|
@ -47,6 +45,21 @@ class AccountTransactionsView(props: AccountTransactionsViewProps) : RComponent<
|
|||
}
|
||||
}
|
||||
|
||||
button {
|
||||
span { +"Transfer Money" }
|
||||
attrs {
|
||||
onMouseUp = { setState { showTransferMoneyView = !showTransferMoneyView } }
|
||||
}
|
||||
}
|
||||
|
||||
if (state.showTransferMoneyView) {
|
||||
child(TransferMoneyView::class) {
|
||||
attrs {
|
||||
presenter = props.presenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
+"Saldo: ${state.balance}"
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@ import kotlinx.coroutines.GlobalScope
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
|
||||
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
|
||||
import net.dankito.banking.client.model.response.GetAccountDataResponse
|
||||
import net.dankito.banking.client.model.response.TransferMoneyResponse
|
||||
import net.dankito.banking.fints.FinTsClient
|
||||
import net.dankito.banking.fints.callback.SimpleFinTsClientCallback
|
||||
import net.dankito.banking.fints.model.TanChallenge
|
||||
import net.dankito.banking.fints.model.TanMethod
|
||||
import net.dankito.banking.fints.model.TanMethodType
|
||||
import net.dankito.banking.fints.model.*
|
||||
import net.dankito.banking.fints.webclient.KtorWebClient
|
||||
import net.dankito.banking.fints.webclient.ProxyingWebClient
|
||||
import net.dankito.utils.multiplatform.log.LoggerFactory
|
||||
|
@ -44,4 +44,23 @@ open class Presenter {
|
|||
}
|
||||
}
|
||||
|
||||
open fun transferMoney(recipientName: String, recipientAccountIdentifier: String, recipientBankIdentifier: String?, reference: String?,
|
||||
amount: String, instantPayment: Boolean = false, response: (TransferMoneyResponse) -> Unit) {
|
||||
GlobalScope.launch(Dispatchers.Unconfined) {
|
||||
// TODO: set your credentials here
|
||||
val transferMoneyResponse = fintsClient.transferMoneyAsync(TransferMoneyParameter("", "", "", null, recipientName,
|
||||
recipientAccountIdentifier, recipientBankIdentifier, Money(Amount(amount), Currency.DefaultCurrencyCode), reference, instantPayment))
|
||||
|
||||
if (transferMoneyResponse.successful) {
|
||||
log.info("Successfully transferred $amount to $recipientName")
|
||||
} else {
|
||||
log.error("Could not transfer $amount to $recipientName: ${transferMoneyResponse.error} ${transferMoneyResponse.errorMessage}")
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
response(transferMoneyResponse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import react.*
|
||||
import react.dom.html.ReactHTML.div
|
||||
import react.dom.html.ReactHTML.input
|
||||
import react.dom.html.ReactHTML.span
|
||||
|
||||
external interface TextInputFieldProps : Props {
|
||||
var label: String
|
||||
var valueChanged: (String) -> Unit
|
||||
}
|
||||
|
||||
|
||||
val TextInputField = FC<TextInputFieldProps> { props ->
|
||||
|
||||
div {
|
||||
span { +"${props.label}: " }
|
||||
|
||||
input {
|
||||
type = react.dom.html.InputType.text
|
||||
onChange = { event ->
|
||||
val enteredValue = event.target.value
|
||||
|
||||
props.valueChanged(enteredValue)}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
import react.*
|
||||
import react.dom.*
|
||||
|
||||
external interface TransferMoneyViewProps : Props {
|
||||
var presenter: Presenter
|
||||
}
|
||||
|
||||
class TransferMoneyViewState(var recipientName: String = "", var recipientAccountIdentifier: String = "", var recipientBankIdentifier: String? = null,
|
||||
var reference: String = "", var amount: String = "", var instantPayment: Boolean = false) : State
|
||||
|
||||
|
||||
@JsExport
|
||||
class TransferMoneyView(props: TransferMoneyViewProps) : RComponent<TransferMoneyViewProps, TransferMoneyViewState>(props) {
|
||||
|
||||
override fun RBuilder.render() {
|
||||
div {
|
||||
TextInputField {
|
||||
attrs {
|
||||
label = "Recipient name"
|
||||
valueChanged = { newValue -> setState { recipientName = newValue } }
|
||||
}
|
||||
}
|
||||
|
||||
TextInputField {
|
||||
attrs {
|
||||
label = "IBAN"
|
||||
valueChanged = { newValue -> setState { recipientAccountIdentifier = newValue } }
|
||||
}
|
||||
}
|
||||
|
||||
TextInputField {
|
||||
attrs {
|
||||
label = "Amount"
|
||||
valueChanged = { newValue -> setState { amount = newValue } }
|
||||
}
|
||||
}
|
||||
|
||||
TextInputField {
|
||||
attrs {
|
||||
label = "Reference"
|
||||
valueChanged = { newValue -> setState { reference = newValue } }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
button {
|
||||
span { +"Transfer" }
|
||||
attrs {
|
||||
onMouseUp = {
|
||||
props.presenter.transferMoney(state.recipientName, state.recipientAccountIdentifier, state.recipientBankIdentifier, state.reference, state.amount, state.instantPayment) { } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
import kotlinx.browser.document
|
||||
import kotlinx.browser.window
|
||||
import net.dankito.banking.fints.FinTsClientDeprecated
|
||||
import net.dankito.banking.fints.callback.SimpleFinTsClientCallback
|
||||
import net.dankito.banking.fints.webclient.KtorWebClient
|
||||
import net.dankito.banking.fints.webclient.ProxyingWebClient
|
||||
import react.dom.render
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package net.dankito.banking.client.model.parameter
|
||||
|
||||
import net.dankito.banking.client.model.BankAccountIdentifier
|
||||
import net.dankito.banking.fints.model.BankData
|
||||
import net.dankito.banking.fints.model.Money
|
||||
import net.dankito.banking.fints.model.TanMethodType
|
||||
|
||||
|
||||
open class TransferMoneyParameter(
|
||||
bankCode: String,
|
||||
loginName: String,
|
||||
password: String,
|
||||
/**
|
||||
* The account from which the money should be withdrawn.
|
||||
* If not specified fints4k retrieves all bank accounts and checks if there is exactly one that supports money transfer.
|
||||
* If no or more than one bank account supports money transfer, the error codes NoAccountSupportsMoneyTransfer or MoreThanOneAccountSupportsMoneyTransfer are returned.
|
||||
*/
|
||||
open val remittanceAccount: BankAccountIdentifier? = null,
|
||||
|
||||
open val recipientName: String,
|
||||
/**
|
||||
* The identifier of recipient's account. In most cases the IBAN.
|
||||
*/
|
||||
open val recipientAccountIdentifier: String,
|
||||
/**
|
||||
* The identifier of recipient's bank. In most cases the BIC.
|
||||
* Can be omitted for German banks as the BIC can be derived from IBAN.
|
||||
*/
|
||||
open val recipientBankIdentifier: String? = null,
|
||||
|
||||
open val amount: Money,
|
||||
open val reference: String? = null,
|
||||
open val instantPayment: Boolean = false,
|
||||
|
||||
preferredTanMethods: List<TanMethodType>? = null,
|
||||
preferredTanMedium: String? = null,
|
||||
abortIfTanIsRequired: Boolean = false,
|
||||
finTsModel: BankData? = null
|
||||
|
||||
) : FinTsClientParameter(bankCode, loginName, password, preferredTanMethods, preferredTanMedium, abortIfTanIsRequired, finTsModel)
|
|
@ -21,6 +21,10 @@ enum class ErrorCode {
|
|||
|
||||
NoneOfTheAccountsSupportsRetrievingData,
|
||||
|
||||
DidNotRetrieveAllAccountData
|
||||
DidNotRetrieveAllAccountData,
|
||||
|
||||
NoAccountSupportsMoneyTransfer,
|
||||
|
||||
MoreThanOneAccountSupportsMoneyTransfer
|
||||
|
||||
}
|
|
@ -15,4 +15,7 @@ open class FinTsClientResponse(
|
|||
open val successful: Boolean
|
||||
get() = error == null
|
||||
|
||||
open val errorCodeAndMessage: String
|
||||
get() = "$error${errorMessage?.let { " $it" }}}"
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package net.dankito.banking.client.model.response
|
||||
|
||||
import net.dankito.banking.fints.model.BankData
|
||||
import net.dankito.banking.fints.model.MessageLogEntry
|
||||
|
||||
|
||||
open class TransferMoneyResponse(
|
||||
error: ErrorCode?,
|
||||
errorMessage: String?,
|
||||
messageLogWithoutSensitiveData: List<MessageLogEntry>,
|
||||
finTsModel: BankData? = null
|
||||
) : FinTsClientResponse(error, errorMessage, messageLogWithoutSensitiveData, finTsModel)
|
|
@ -1,12 +1,15 @@
|
|||
package net.dankito.banking.fints
|
||||
|
||||
import kotlinx.datetime.LocalDate
|
||||
import net.dankito.banking.client.model.parameter.FinTsClientParameter
|
||||
import net.dankito.banking.fints.callback.FinTsClientCallback
|
||||
import net.dankito.banking.fints.model.*
|
||||
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
|
||||
import net.dankito.banking.client.model.parameter.RetrieveTransactions
|
||||
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
|
||||
import net.dankito.banking.client.model.response.ErrorCode
|
||||
import net.dankito.banking.client.model.response.GetAccountDataResponse
|
||||
import net.dankito.banking.client.model.response.TransferMoneyResponse
|
||||
import net.dankito.banking.fints.mapper.FinTsModelMapper
|
||||
import net.dankito.banking.fints.response.client.FinTsClientResponse
|
||||
import net.dankito.banking.fints.response.client.GetAccountInfoResponse
|
||||
|
@ -109,7 +112,52 @@ open class FinTsClient @JvmOverloads constructor(
|
|||
return LocalDate.todayAtEuropeBerlin().minusDays(90)
|
||||
}
|
||||
|
||||
protected open suspend fun getAccountInfo(param: GetAccountDataParameter, bank: BankData): GetAccountInfoResponse {
|
||||
|
||||
open suspend fun transferMoneyAsync(param: TransferMoneyParameter): TransferMoneyResponse {
|
||||
val finTsServerAddress = finTsServerAddressFinder.findFinTsServerAddress(param.bankCode)
|
||||
if (finTsServerAddress.isNullOrBlank()) {
|
||||
return TransferMoneyResponse(ErrorCode.BankDoesNotSupportFinTs3, "Either bank does not FinTS 3.0 or we don't know its FinTS server address", listOf(), null)
|
||||
}
|
||||
|
||||
val bank = BankData(param.bankCode, param.loginName, param.password, finTsServerAddress, "")
|
||||
val remittanceAccount = param.remittanceAccount
|
||||
|
||||
if (remittanceAccount == null) { // then first retrieve customer's bank accounts
|
||||
val getAccountInfoResponse = getAccountInfo(param, bank)
|
||||
|
||||
if (getAccountInfoResponse.successful == false) {
|
||||
return TransferMoneyResponse(mapper.mapErrorCode(getAccountInfoResponse), mapper.mapErrorMessages(getAccountInfoResponse),
|
||||
getAccountInfoResponse.messageLogWithoutSensitiveData, bank)
|
||||
} else {
|
||||
return transferMoneyAsync(param, getAccountInfoResponse.bank, getAccountInfoResponse.bank.accounts, getAccountInfoResponse)
|
||||
}
|
||||
} else {
|
||||
return transferMoneyAsync(param, bank, listOf(mapper.mapToAccountData(remittanceAccount, param)), null)
|
||||
}
|
||||
}
|
||||
|
||||
protected open suspend fun transferMoneyAsync(param: TransferMoneyParameter, bank: BankData, accounts: List<AccountData>, previousJobResponse: FinTsClientResponse?): TransferMoneyResponse {
|
||||
val accountsSupportingTransfer = accounts.filter { it.supportsTransferringMoney }
|
||||
if (accountsSupportingTransfer.isEmpty()) {
|
||||
return TransferMoneyResponse(ErrorCode.NoAccountSupportsMoneyTransfer, "None of the accounts $accounts supports money transfer", previousJobResponse?.messageLogWithoutSensitiveData ?: listOf(), bank)
|
||||
} else if (accountsSupportingTransfer.size > 1) {
|
||||
return TransferMoneyResponse(ErrorCode.MoreThanOneAccountSupportsMoneyTransfer, "More than one of the accounts $accountsSupportingTransfer supports money transfer, so we cannot clearly determine which one to use for this transfer", previousJobResponse?.messageLogWithoutSensitiveData ?: listOf(), bank)
|
||||
}
|
||||
|
||||
val recipientBankIdentifier = param.recipientBankIdentifier ?: "" // TODO: determine BIC from recipientBankCode if it's a German bank
|
||||
val context = JobContext(JobContextType.TransferMoney, this.callback, product, bank, accountsSupportingTransfer.first())
|
||||
|
||||
val response = jobExecutor.transferMoneyAsync(context, BankTransferData(param.recipientName, param.recipientAccountIdentifier, recipientBankIdentifier, param.amount, param.reference, param.instantPayment))
|
||||
|
||||
return TransferMoneyResponse(mapper.mapErrorCode(response), mapper.mapErrorMessages(response), mapper.mergeMessageLog(previousJobResponse, response), bank)
|
||||
}
|
||||
|
||||
protected open suspend fun getAccountInfo(param: FinTsClientParameter, bank: BankData): GetAccountInfoResponse {
|
||||
param.finTsModel?.let {
|
||||
// TODO: implement
|
||||
// return GetAccountInfoResponse(it)
|
||||
}
|
||||
|
||||
val context = JobContext(JobContextType.AddAccount, this.callback, product, bank) // TODO: add / change JobContextType
|
||||
|
||||
/* First dialog: Get user's basic data like BPD, customer system ID and her TAN methods */
|
||||
|
|
|
@ -10,9 +10,7 @@ import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.*
|
|||
import net.dankito.banking.fints.model.*
|
||||
import net.dankito.banking.fints.response.BankResponse
|
||||
import net.dankito.banking.fints.response.client.*
|
||||
import net.dankito.banking.fints.response.segments.*
|
||||
import net.dankito.banking.fints.webclient.IWebClient
|
||||
import kotlin.jvm.JvmOverloads
|
||||
|
||||
|
||||
/**
|
||||
|
@ -166,7 +164,7 @@ open class FinTsClientDeprecated(
|
|||
open suspend fun doBankTransferAsync(bankTransferData: BankTransferData, bank: BankData, account: AccountData): FinTsClientResponse {
|
||||
val context = JobContext(JobContextType.TransferMoney, this.callback, product, bank, account)
|
||||
|
||||
return jobExecutor.doBankTransferAsync(context, bankTransferData)
|
||||
return jobExecutor.transferMoneyAsync(context, bankTransferData)
|
||||
}
|
||||
|
||||
}
|
|
@ -342,7 +342,7 @@ open class FinTsJobExecutor(
|
|||
}
|
||||
|
||||
|
||||
open suspend fun doBankTransferAsync(context: JobContext, bankTransferData: BankTransferData): FinTsClientResponse {
|
||||
open suspend fun transferMoneyAsync(context: JobContext, bankTransferData: BankTransferData): FinTsClientResponse {
|
||||
|
||||
val response = sendMessageInNewDialogAndHandleResponse(context, null, true) {
|
||||
val updatedAccount = getUpdatedAccount(context, context.account!!)
|
||||
|
|
|
@ -2,6 +2,7 @@ package net.dankito.banking.fints.mapper
|
|||
|
||||
import net.dankito.banking.client.model.*
|
||||
import net.dankito.banking.client.model.AccountTransaction
|
||||
import net.dankito.banking.client.model.parameter.FinTsClientParameter
|
||||
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
|
||||
import net.dankito.banking.client.model.response.ErrorCode
|
||||
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Laenderkennzeichen
|
||||
|
@ -13,13 +14,15 @@ import net.dankito.banking.fints.response.segments.AccountType
|
|||
|
||||
open class FinTsModelMapper {
|
||||
|
||||
open fun mapToAccountData(credentials: BankAccountIdentifier, param: GetAccountDataParameter): AccountData {
|
||||
open fun mapToAccountData(credentials: BankAccountIdentifier, param: FinTsClientParameter): AccountData {
|
||||
val accountData = AccountData(credentials.identifier, credentials.subAccountNumber, Laenderkennzeichen.Germany, param.bankCode,
|
||||
credentials.iban, param.loginName, null, null, "", null, null, listOf(), listOf())
|
||||
|
||||
// TODO: where to know from if account supports retrieving balance and transactions?
|
||||
accountData.setSupportsFeature(AccountFeature.RetrieveBalance, true)
|
||||
accountData.setSupportsFeature(AccountFeature.RetrieveAccountTransactions, true)
|
||||
accountData.setSupportsFeature(AccountFeature.TransferMoney, true)
|
||||
accountData.setSupportsFeature(AccountFeature.RealTimeTransfer, true)
|
||||
|
||||
return accountData
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ open class SepaBankTransferBase(
|
|||
"RecipientIban" to data.recipientAccountId.replace(" ", ""),
|
||||
"RecipientBic" to data.recipientBankCode.replace(" ", ""),
|
||||
"Amount" to data.amount.amount.string.replace(',', '.'), // TODO: check if ',' or '.' should be used as decimal separator
|
||||
"Reference" to if (data.reference.isEmpty()) " " else messageCreator.convertDiacriticsAndReservedXmlCharacters(data.reference),
|
||||
"Reference" to if (data.reference.isNullOrBlank()) " " else messageCreator.convertDiacriticsAndReservedXmlCharacters(data.reference),
|
||||
"RequestedExecutionDate" to RequestedExecutionDateValueForNotScheduledTransfers
|
||||
),
|
||||
messageCreator
|
||||
|
|
|
@ -6,6 +6,6 @@ open class BankTransferData(
|
|||
val recipientAccountId: String,
|
||||
val recipientBankCode: String,
|
||||
val amount: Money,
|
||||
val reference: String,
|
||||
val reference: String?,
|
||||
val realTimeTransfer: Boolean = false
|
||||
)
|
|
@ -2,26 +2,29 @@ import kotlinx.datetime.LocalDate
|
|||
import net.dankito.banking.client.model.AccountTransaction
|
||||
import net.dankito.banking.client.model.CustomerAccount
|
||||
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
|
||||
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
|
||||
import net.dankito.banking.fints.FinTsClient
|
||||
import net.dankito.banking.fints.callback.SimpleFinTsClientCallback
|
||||
import net.dankito.banking.fints.getAccountData
|
||||
import net.dankito.banking.fints.model.TanChallenge
|
||||
import net.dankito.banking.fints.transferMoney
|
||||
import net.dankito.utils.multiplatform.extensions.*
|
||||
|
||||
|
||||
class NativeApp {
|
||||
|
||||
private val client = FinTsClient(SimpleFinTsClientCallback { tanChallenge -> enterTan(tanChallenge) })
|
||||
|
||||
|
||||
fun retrieveAccountData(bankCode: String, loginName: String, password: String) {
|
||||
retrieveAccountData(GetAccountDataParameter(bankCode, loginName, password))
|
||||
}
|
||||
|
||||
fun retrieveAccountData(param: GetAccountDataParameter) {
|
||||
val client = FinTsClient(SimpleFinTsClientCallback { tanChallenge -> enterTan(tanChallenge) })
|
||||
|
||||
val response = client.getAccountData(param)
|
||||
|
||||
if (response.error != null) {
|
||||
println("An error occurred: ${response.error}${response.errorMessage?.let { " $it" }}")
|
||||
println("An error occurred: ${response.errorCodeAndMessage}")
|
||||
}
|
||||
|
||||
response.customerAccount?.let { account ->
|
||||
|
@ -32,6 +35,17 @@ class NativeApp {
|
|||
}
|
||||
|
||||
|
||||
fun transferMoney(param: TransferMoneyParameter) {
|
||||
val response = client.transferMoney(param)
|
||||
|
||||
if (response.error != null) {
|
||||
println("Could not transfer ${param.amount} to ${param.recipientName}: ${response.errorCodeAndMessage}")
|
||||
} else {
|
||||
println("Successfully transferred ${param.amount} to ${param.recipientName}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun enterTan(tanChallenge: TanChallenge) {
|
||||
println("A TAN is required:")
|
||||
println(tanChallenge.messageToShowToUser)
|
||||
|
|
|
@ -2,7 +2,9 @@ package net.dankito.banking.fints
|
|||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.dankito.banking.client.model.parameter.GetAccountDataParameter
|
||||
import net.dankito.banking.client.model.parameter.TransferMoneyParameter
|
||||
import net.dankito.banking.client.model.response.GetAccountDataResponse
|
||||
import net.dankito.banking.client.model.response.TransferMoneyResponse
|
||||
|
||||
|
||||
fun FinTsClient.getAccountData(bankCode: String, loginName: String, password: String): GetAccountDataResponse {
|
||||
|
@ -11,4 +13,9 @@ fun FinTsClient.getAccountData(bankCode: String, loginName: String, password: St
|
|||
|
||||
fun FinTsClient.getAccountData(param: GetAccountDataParameter): GetAccountDataResponse {
|
||||
return runBlocking { getAccountDataAsync(param) }
|
||||
}
|
||||
|
||||
|
||||
fun FinTsClient.transferMoney(param: TransferMoneyParameter): TransferMoneyResponse {
|
||||
return runBlocking { transferMoneyAsync(param) }
|
||||
}
|
Loading…
Reference in New Issue