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
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ThisBuild / organization := "app.softnetwork"

name := "payment"

ThisBuild / version := "0.9.0"
ThisBuild / version := "0.9.1"

ThisBuild / scalaVersion := scala212

Expand Down
1 change: 1 addition & 0 deletions client/src/main/protobuf/api/payment.proto
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ message RegisterRecurringPaymentRequest {
google.protobuf.StringValue statementDescriptor = 12;
google.protobuf.StringValue externalReference = 13;
string clientId = 14;
map<string, string> metadata = 15;
}

message RegisterRecurringPaymentResponse {
Expand Down
1 change: 1 addition & 0 deletions client/src/main/protobuf/model/payment/paymentUser.proto
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,5 @@ message RecurringPayment {
optional string cardId = 22;
optional string statementDescriptor = 23;
optional string externalReference = 24;
map<string, string> metadata = 25;
}
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ trait PaymentClient extends GrpcClient {
nextFeesAmount: Option[Int],
statementDescriptor: Option[String],
externalReference: Option[String],
metadata: Map[String, String] = Map.empty,
token: Option[String] = None
): Future[Option[String]] = {
val t = token.getOrElse(generatedToken)
Expand Down Expand Up @@ -306,7 +307,8 @@ trait PaymentClient extends GrpcClient {
nextFeesAmount,
statementDescriptor,
externalReference,
clientId.getOrElse(settings.clientId)
clientId.getOrElse(settings.clientId),
metadata
)
) map (_.recurringPaymentRegistrationId)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ object PaymentMessages {
nextFeesAmount: Option[Int] = None,
statementDescriptor: Option[String] = None,
externalReference: Option[String] = None,
metadata: Map[String, String] = Map.empty,
clientId: Option[String] = None
) extends PaymentCommandWithKey
with RecurringPaymentCommand {
Expand Down Expand Up @@ -580,12 +581,13 @@ object PaymentMessages {
* - transaction payIn id
*/
@InternalApi
private[payment] case class FirstRecurringPaymentCallback(
private[payment] case class RecurringPaymentCallback(
recurringPayInRegistrationId: String,
transactionId: String
transactionId: String,
debitedAccount: Option[String] = None
) extends PaymentCommandWithKey
with RecurringPaymentCommand {
lazy val key: String = transactionId
lazy val key: String = debitedAccount.getOrElse(transactionId)
}

/** @param recurringPaymentRegistrationId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ trait PaymentServer extends PaymentServiceApi with PaymentDao {
nextFeesAmount,
statementDescriptor,
externalReference,
metadata.toMap,
Some(clientId)
) map {
case Right(r: RecurringPaymentRegistered) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ trait PaymentDao extends PaymentHandler {
nextFeesAmount: Option[Int] = None,
statementDescriptor: Option[String] = None,
externalReference: Option[String] = None,
metadata: Map[String, String] = Map.empty,
clientId: Option[String] = None
)(implicit
system: ActorSystem[_]
Expand All @@ -505,6 +506,7 @@ trait PaymentDao extends PaymentHandler {
nextFeesAmount,
statementDescriptor,
externalReference,
metadata,
Some(clientId)
)
) map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import app.softnetwork.payment.message.PaymentMessages.{
ExecuteNextRecurringPayment,
FirstRecurringCardPaymentFailed,
FirstRecurringPaidIn,
FirstRecurringPaymentCallback,
IllegalMandateStatus,
LoadRecurringPayment,
MandateNotFound,
Expand All @@ -27,6 +26,7 @@ import app.softnetwork.payment.message.PaymentMessages.{
PaymentResult,
RecurringCardPaymentRegistrationNotUpdated,
RecurringCardPaymentRegistrationUpdated,
RecurringPaymentCallback,
RecurringPaymentCommand,
RecurringPaymentLoaded,
RecurringPaymentNotFound,
Expand Down Expand Up @@ -122,7 +122,8 @@ trait RecurringPaymentCommandHandler
frequency = cmd.frequency,
fixedNextAmount = cmd.fixedNextAmount,
nextDebitedAmount = cmd.nextDebitedAmount,
nextFeesAmount = cmd.nextFeesAmount
nextFeesAmount = cmd.nextFeesAmount,
metadata = cmd.metadata
)
val clientId = paymentAccount.clientId
.orElse(cmd.clientId)
Expand Down Expand Up @@ -202,7 +203,8 @@ trait RecurringPaymentCommandHandler
frequency = cmd.frequency,
fixedNextAmount = cmd.fixedNextAmount,
nextDebitedAmount = cmd.nextDebitedAmount,
nextFeesAmount = cmd.nextFeesAmount
nextFeesAmount = cmd.nextFeesAmount,
metadata = cmd.metadata
)
import app.softnetwork.time._
val nextDirectDebit: List[ExternalEntityToSchedulerEvent] =
Expand Down Expand Up @@ -391,7 +393,7 @@ trait RecurringPaymentCommandHandler
case _ => Effect.none.thenRun(_ => PaymentAccountNotFound ~> replyTo)
}

case cmd: FirstRecurringPaymentCallback =>
case cmd: RecurringPaymentCallback =>
state match {
case Some(paymentAccount) =>
import cmd._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ trait CheckoutEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
.description("Execute first recurring payment for 3D secure")
.serverLogic { case (recurringPayInRegistrationId, transactionId) =>
run(
FirstRecurringPaymentCallback(recurringPayInRegistrationId, transactionId)
RecurringPaymentCallback(recurringPayInRegistrationId, transactionId)
).map {
case result: PaidIn => Right(result)
case result: PaymentRedirection => Right(result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ trait PaymentService[SD <: SessionData with SessionDataDecorator[SD]]
pathPrefix(Segment) { recurringPayInRegistrationId =>
parameter("transactionId") { transactionId =>
run(
FirstRecurringPaymentCallback(recurringPayInRegistrationId, transactionId)
RecurringPaymentCallback(recurringPayInRegistrationId, transactionId)
) completeWith {
case r: PaidIn =>
complete(
Expand Down
2 changes: 1 addition & 1 deletion stripe/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ name := "stripe-core"

libraryDependencies ++= Seq(
// stripe
"com.stripe" % "stripe-java" % "26.12.0"
"com.stripe" % "stripe-java" % "26.12.0" // TODO upgrade to v31.4.1
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import com.stripe.param.{
WebhookEndpointUpdateParams
}

import org.slf4j.{Logger, LoggerFactory}

import java.nio.file.Paths
import scala.util.{Failure, Success, Try}

Expand Down Expand Up @@ -73,12 +75,15 @@ object StripeApi {
this.copy(paymentConfig = paymentConfig)
}

private[this] lazy val log: Logger = LoggerFactory.getLogger(getClass)

private[this] var stripeApis: Map[String, StripeApi] = Map.empty

private[this] var stripeWebHooks: Map[String, String] = Map.empty

private[this] lazy val STRIPE_SECRETS_DIR: String = s"${SoftPayClientSettings.SP_SECRETS}/stripe"

// TODO migrate webhook secrets to encrypted storage (Sealed Secrets / Vault)
private[this] def addSecret(hash: String, secret: String): Unit = {
val dir = s"$STRIPE_SECRETS_DIR/$hash"
Paths.get(dir).toFile.mkdirs()
Expand All @@ -93,7 +98,7 @@ object StripeApi {
private[StripeApi] def loadSecret(hash: String): Option[String] = {
val dir = s"$STRIPE_SECRETS_DIR/$hash"
val file = Paths.get(dir, "webhook-secret").toFile
Console.println(s"Loading secret from: ${file.getAbsolutePath}")
log.debug(s"Loading secret from: ${file.getAbsolutePath}")
if (file.exists()) {
import scala.io.Source
val source = Source.fromFile(file)
Expand Down Expand Up @@ -142,7 +147,7 @@ object StripeApi {
None
}) match {
case Some(webhookEndpoint) =>
Console.println(s"Webhook endpoint found: ${webhookEndpoint.getId}")
log.info(s"Webhook endpoint found: ${webhookEndpoint.getId}")
loadSecret(hash) match {
case None =>
Try(webhookEndpoint.delete(requestOptions))
Expand All @@ -159,6 +164,18 @@ object StripeApi {
.addEnabledEvent(
WebhookEndpointUpdateParams.EnabledEvent.PERSON__UPDATED
)
.addEnabledEvent(
WebhookEndpointUpdateParams.EnabledEvent.INVOICE__PAYMENT_SUCCEEDED
)
.addEnabledEvent(
WebhookEndpointUpdateParams.EnabledEvent.INVOICE__PAYMENT_FAILED
)
.addEnabledEvent(
WebhookEndpointUpdateParams.EnabledEvent.CUSTOMER__SUBSCRIPTION__DELETED
)
.addEnabledEvent(
WebhookEndpointUpdateParams.EnabledEvent.CUSTOMER__SUBSCRIPTION__UPDATED
)
.setUrl(url)
.build(),
requestOptions
Expand All @@ -179,6 +196,18 @@ object StripeApi {
.addEnabledEvent(
WebhookEndpointCreateParams.EnabledEvent.PERSON__UPDATED
)
.addEnabledEvent(
WebhookEndpointCreateParams.EnabledEvent.INVOICE__PAYMENT_SUCCEEDED
)
.addEnabledEvent(
WebhookEndpointCreateParams.EnabledEvent.INVOICE__PAYMENT_FAILED
)
.addEnabledEvent(
WebhookEndpointCreateParams.EnabledEvent.CUSTOMER__SUBSCRIPTION__DELETED
)
.addEnabledEvent(
WebhookEndpointCreateParams.EnabledEvent.CUSTOMER__SUBSCRIPTION__UPDATED
)
.setUrl(url)
.setApiVersion(WebhookEndpointCreateParams.ApiVersion.VERSION_2024_06_20)
.setConnect(true)
Expand Down
Loading
Loading