Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion obp-api/src/main/resources/props/sample.props.template
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ jwt.use.ssl=false
# berlin_group_expired_consents_interval_in_seconds =


## Expire OBP consents with status "ACCEPTED"
# obp_expired_consents_interval_in_seconds =


## Enable writing API metrics (which APIs are called) to RDBMS
write_metrics=true
## Enable writing connector metrics (which methods are called)to RDBMS
Expand Down Expand Up @@ -1124,7 +1128,7 @@ default_auth_context_update_request_key=CUSTOMER_NUMBER
#featured_api_collection_ids=

# the alias prefix path for BerlinGroupV1.3 (OBP built-in is berlin-group/v1.3), the format must be xxx/yyy, eg: 0.6/v1
#berlin_group_v1.3_alias.path=
#berlin_group_v1_3_alias_path=

# Show the path inside of Berlin Group error message
#berlin_group_error_message_show_path = true
Expand Down
1 change: 1 addition & 0 deletions obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ class Boot extends MdcLoggable {
Menu.i("confirm-user-auth-context-update-request") / "confirm-user-auth-context-update-request",
Menu.i("confirm-bg-consent-request") / "confirm-bg-consent-request" >> AuthUser.loginFirst,//OAuth consent page,
Menu.i("confirm-bg-consent-request-sca") / "confirm-bg-consent-request-sca" >> AuthUser.loginFirst,//OAuth consent page,
Menu.i("confirm-bg-consent-request-redirect-uri") / "confirm-bg-consent-request-redirect-uri" >> AuthUser.loginFirst,//OAuth consent page,
Menu.i("confirm-vrp-consent-request") / "confirm-vrp-consent-request" >> AuthUser.loginFirst,//OAuth consent page,
Menu.i("confirm-vrp-consent") / "confirm-vrp-consent" >> AuthUser.loginFirst //OAuth consent page
) ++ accountCreation ++ Admin.menus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,19 @@ recurringIndicator:
consentJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
json.extract[PostConsentJson]
}
_ <- Helper.booleanToFuture(failMsg = BerlinGroupConsentAccessIsEmpty, cc=callContext) {
consentJson.access.accounts.isDefined ||
consentJson.access.balances.isDefined ||
consentJson.access.transactions.isDefined
}
upperLimit = APIUtil.getPropsAsIntValue("berlin_group_frequency_per_day_upper_limit", 4)
_ <- Helper.booleanToFuture(failMsg = FrequencyPerDayError, cc=callContext) {
consentJson.frequencyPerDay > 0 && consentJson.frequencyPerDay <= upperLimit
}

_ <- Helper.booleanToFuture(failMsg = FrequencyPerDayMustBeOneError, cc=callContext) {
consentJson.recurringIndicator == true ||
(consentJson.recurringIndicator == false && consentJson.frequencyPerDay == 1)
consentJson.recurringIndicator ||
!consentJson.recurringIndicator && consentJson.frequencyPerDay == 1
}

failMsg = BgSpecValidation.getErrorMessage(consentJson.validUntil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ object BgSpecValidation {
}
}

def formatToISODate(date: Date): String = {
if (date == null) ""
else {
val localDate: LocalDate = date.toInstant.atZone(ZoneId.systemDefault()).toLocalDate
localDate.format(DateTimeFormatter.ISO_LOCAL_DATE)
}
}

// Example usage
def main(args: Array[String]): Unit = {
val testDates = Seq(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package code.api.berlin.group.v1_3

import java.text.SimpleDateFormat
import java.util.Date
import code.api.berlin.group.v1_3.model.TransactionStatus.mapTransactionStatus
import code.api.berlin.group.v1_3.model._
import code.api.util.APIUtil._
import code.api.util.ErrorMessages.MissingPropsValueAtThisInstance
import code.api.util.{APIUtil, ConsentJWT, CustomJsonFormats, JwtUtil}
import code.bankconnectors.Connector
import code.consent.ConsentTrait
import code.model.ModeratedTransaction
import com.openbankproject.commons.model.enums.AccountRoutingScheme
import com.openbankproject.commons.model.{BankAccount, TransactionRequest, User, _}
import com.openbankproject.commons.model._
import net.liftweb.common.Box.tryo
import net.liftweb.common.{Box, Full}
import net.liftweb.json
import net.liftweb.json.{JValue, parse}

import scala.collection.immutable.List
import java.text.SimpleDateFormat
import java.util.Date

case class JvalueCaseClass(jvalueToCaseclass: JValue)

Expand Down Expand Up @@ -136,14 +134,15 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
)
case class CreditorAccountJson(
iban: String,
currency : Option[String] = None,
)
case class TransactionJsonV13(
transactionId: String,
creditorName: String,
creditorAccount: CreditorAccountJson,
transactionAmount: AmountOfMoneyV13,
bookingDate: Date,
valueDate: Date,
bookingDate: String,
valueDate: String,
remittanceInformationUnstructured: String,
)
case class SingleTransactionJsonV13(
Expand Down Expand Up @@ -415,9 +414,9 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
transactionId = transaction.id.value,
creditorName = creditorName,
creditorAccount = creditorAccount,
transactionAmount = AmountOfMoneyV13(APIUtil.stringOptionOrNull(transaction.currency), transaction.amount.get.toString()),
bookingDate = bookingDate,
valueDate = valueDate,
transactionAmount = AmountOfMoneyV13(APIUtil.stringOptionOrNull(transaction.currency), transaction.amount.get.toString().trim.stripPrefix("-")),
bookingDate = BgSpecValidation.formatToISODate(bookingDate) ,
valueDate = BgSpecValidation.formatToISODate(valueDate),
remittanceInformationUnstructured = APIUtil.stringOptionOrNull(transaction.description)
)
}
Expand Down Expand Up @@ -450,9 +449,9 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
transactionId = transactionRequest.id.value,
creditorName = creditorName,
creditorAccount = creditorAccount,
transactionAmount = AmountOfMoneyV13(transactionRequest.charge.value.currency, transactionRequest.charge.value.amount),
bookingDate = transactionRequest.start_date,
valueDate = transactionRequest.end_date,
transactionAmount = AmountOfMoneyV13(transactionRequest.charge.value.currency, transactionRequest.charge.value.amount.trim.stripPrefix("-")),
bookingDate = BgSpecValidation.formatToISODate(transactionRequest.start_date),
valueDate = BgSpecValidation.formatToISODate(transactionRequest.end_date),
remittanceInformationUnstructured = remittanceInformationUnstructured
)
}
Expand All @@ -463,6 +462,7 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {

val creditorAccount = CreditorAccountJson(
iban = iban,
currency = Some(bankAccount.currency)
)
TransactionsJsonV13(
FromAccount(
Expand Down Expand Up @@ -647,10 +647,7 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
val scaRedirectUrl = getPropsValue("psu_make_payment_sca_redirect_url")
.openOr(MissingPropsValueAtThisInstance + "psu_make_payment_sca_redirect_url")
InitiatePaymentResponseJson(
transactionStatus = transactionRequest.status match {
case "COMPLETED" => "ACCP"
case "INITIATED" => "RCVD"
},
transactionStatus = mapTransactionStatus(transactionRequest.status),
paymentId = paymentId,
_links = InitiatePaymentResponseLinks(
scaRedirect = LinkHrefJson(s"$scaRedirectUrl/$paymentId"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,31 @@
package code.api.builder.PaymentInitiationServicePISApi

import code.api.Constant
import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{CancelPaymentResponseJson, CancelPaymentResponseLinks, LinkHrefJson, UpdatePaymentPsuDataJson, checkAuthorisationConfirmation, checkSelectPsuAuthenticationMethod, checkTransactionAuthorisation, checkUpdatePsuAuthentication, createCancellationTransactionRequestJson}
import code.api.berlin.group.v1_3.{JSONFactory_BERLIN_GROUP_1_3, JvalueCaseClass, OBP_BERLIN_GROUP_1_3}
import code.api.berlin.group.v1_3.model.TransactionStatus.mapTransactionStatus
import code.api.berlin.group.v1_3.model._
import code.api.berlin.group.v1_3.{JSONFactory_BERLIN_GROUP_1_3, JvalueCaseClass}
import code.api.util.APIUtil._
import code.api.util.ApiTag._
import code.api.util.ErrorMessages._
import code.api.util.NewStyle.HttpCode
import code.api.util.{ApiRole, ApiTag, CallContext, NewStyle}
import code.api.berlin.group.v1_3.model._
import code.bankconnectors.Connector
import code.api.util.{ApiTag, CallContext, NewStyle}
import code.fx.fx
import code.api.Constant._
import code.util.Helper
import code.views.Views
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.ExecutionContext.Implicits.global
import com.openbankproject.commons.model._
import com.openbankproject.commons.model.enums.ChallengeType.BERLIN_GROUP_PAYMENT_CHALLENGE
import com.openbankproject.commons.model.enums.TransactionRequestStatus._
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthenticationStatus, SuppliedAnswerType, TransactionRequestStatus,TransactionRequestTypes,PaymentServiceTypes}
import com.openbankproject.commons.model.enums.TransactionRequestTypes._
import com.openbankproject.commons.model.enums.PaymentServiceTypes._
import com.openbankproject.commons.model.enums.{TransactionRequestStatus, _}
import com.openbankproject.commons.util.ApiVersion
import net.liftweb
import net.liftweb.common.Box.tryo
import net.liftweb.common.Full
import net.liftweb.http.js.JE.JsRaw
import net.liftweb.http.rest.RestHelper
import net.liftweb.json
import net.liftweb.json.Serialization.write
import net.liftweb.json._

import scala.collection.immutable.Nil
import scala.collection.mutable.ArrayBuffer
import scala.concurrent.Future

Expand Down Expand Up @@ -136,7 +129,7 @@ or * access method is generally applicable, but further authorisation processes
(canBeCancelled, _, startSca) <- transactionRequestTypes match {
case TransactionRequestTypes.SEPA_CREDIT_TRANSFERS => {
transactionRequest.status.toUpperCase() match {
case "COMPLETED" =>
case TransactionStatus.ACCP.code =>
NewStyle.function.cancelPaymentV400(TransactionId(transactionRequest.transaction_ids), callContext) map {
x => x._1 match {
case CancelPayment(true, Some(startSca)) if startSca == true =>
Expand Down Expand Up @@ -399,8 +392,8 @@ This method returns the SCA status of a payment initiation's authorisation sub-r
s"""${mockedDataText(false)}
Check the transaction status of a payment initiation.""",
EmptyBody,
json.parse("""{
"transactionStatus": "ACCP"
json.parse(s"""{
"transactionStatus": "${TransactionStatus.ACCP.code}"
}"""),
List(UserNotLoggedIn, UnknownError),
ApiTag("Payment Initiation Service (PIS)") :: apiTagBerlinGroupM :: Nil
Expand All @@ -420,12 +413,9 @@ Check the transaction status of a payment initiation.""",
}
(transactionRequest, callContext) <- NewStyle.function.getTransactionRequestImpl(TransactionRequestId(paymentId), callContext)

transactionRequestStatus = transactionRequest.status match {
case "COMPLETED" => "ACCP"
case "INITIATED" => "RCVD"
}
transactionRequestStatus = mapTransactionStatus(transactionRequest.status)

transactionRequestAmount <- NewStyle.function.tryons(s"${UnknownError} transction request amount can not convert to a Decimal",400, callContext) {
transactionRequestAmount <- NewStyle.function.tryons(s"${UnknownError} transaction request amount can not convert to a Decimal",400, callContext) {
BigDecimal(transactionRequest.body.to_sepa_credit_transfers.get.instructedAmount.amount)
}
transactionRequestCurrency <- NewStyle.function.tryons(s"${UnknownError} can not get currency from this paymentId(${paymentId})",400, callContext) {
Expand All @@ -450,7 +440,7 @@ Check the transaction status of a payment initiation.""",

fundsAvailable = (fromAccountBalance >= requestChangedCurrencyAmount)

transactionRequestStatusChekedFunds = if(fundsAvailable) transactionRequestStatus else "RCVD"
transactionRequestStatusChekedFunds = if(fundsAvailable) transactionRequestStatus else TransactionStatus.RCVD.code

} yield {
(json.parse(s"""{
Expand Down Expand Up @@ -534,7 +524,7 @@ Check the transaction status of a payment initiation.""",
}

//Berlin Group PaymentProduct is OBP transaction request type
transacitonRequestType <- NewStyle.function.tryons(checkPaymentProductError(paymentProduct), 400, callContext) {
transactionRequestType <- NewStyle.function.tryons(checkPaymentProductError(paymentProduct), 400, callContext) {
TransactionRequestTypes.withName(paymentProduct.replaceAll("-", "_").toUpperCase)
}

Expand Down Expand Up @@ -565,13 +555,13 @@ Check the transaction status of a payment initiation.""",
_ <- NewStyle.function.isEnabledTransactionRequests(callContext)


(createdTransactionRequest, callContext) <- transacitonRequestType match {
(createdTransactionRequest, callContext) <- transactionRequestType match {
case TransactionRequestTypes.SEPA_CREDIT_TRANSFERS => {
for {
(createdTransactionRequest, callContext) <- NewStyle.function.createTransactionRequestBGV1(
initiator = u,
paymentServiceType,
transacitonRequestType,
transactionRequestType,
transactionRequestBody = sepaCreditTransfersBerlinGroupV13,
callContext
)
Expand Down Expand Up @@ -606,7 +596,7 @@ Check the transaction status of a payment initiation.""",
"creditorName": "70charname"
}"""),
json.parse(s"""{
"transactionStatus": "RCVD",
"transactionStatus": "${TransactionStatus.RCVD.code}",
"paymentId": "1234-wertiq-983",
"_links":
{
Expand Down Expand Up @@ -655,7 +645,7 @@ Check the transaction status of a payment initiation.""",
"dayOfExecution": "01"
}"""),
json.parse(s"""{
"transactionStatus": "RCVD",
"transactionStatus": "${TransactionStatus.RCVD.code}",
"paymentId": "1234-wertiq-983",
"_links":
{
Expand Down Expand Up @@ -717,7 +707,7 @@ Check the transaction status of a payment initiation.""",
]
}"""),
json.parse(s"""{
"transactionStatus": "RCVD",
"transactionStatus": "${TransactionStatus.RCVD.code}",
"paymentId": "1234-wertiq-983",
"_links":
{
Expand Down Expand Up @@ -1449,7 +1439,7 @@ There are the following request types on this access path:
transactionRequestId = TransactionRequestId(paymentId)
(existingTransactionRequest, callContext) <- NewStyle.function.getTransactionRequestImpl(transactionRequestId, callContext)
_ <- Helper.booleanToFuture(failMsg= CannotUpdatePSUData, cc=callContext) {
existingTransactionRequest.status == TransactionRequestStatus.INITIATED.toString
existingTransactionRequest.status == TransactionStatus.RCVD.code
}
(_, callContext) <- NewStyle.function.getChallenge(authorisationId, callContext)
(challenge, callContext) <- NewStyle.function.validateChallengeAnswerC4(
Expand Down
Loading