in membership-attribute-service/app/controllers/PaymentUpdateController.scala [42:91]
def updateCard(subscriptionName: String) =
AuthorizeForRecentLoginAndScopes(Return401IfNotSignedInRecently, requiredScopes = List(readSelf, updateSelf)).async { implicit request =>
import request.logPrefix
metrics.measureDuration("POST /user-attributes/me/update-card/:subscriptionName") {
// TODO - refactor to use the Zuora-only based lookup, like in AttributeController.pickAttributes - https://trello.com/c/RlESb8jG
val legacyForm = Form {
tuple("stripeToken" -> nonEmptyText, "publicKey" -> nonEmptyText)
}.bindFromRequest().value
val updateForm = Form {
tuple("stripePaymentMethodID" -> nonEmptyText, "stripePublicKey" -> nonEmptyText)
}.bindFromRequest().value
val services = request.touchpoint
val useStripePaymentMethod = updateForm.isDefined
val user = request.user
val userId = user.identityId
logger.info(s"Attempting to update card for $userId")
(for {
stripeDetails <- EitherT.fromEither(
Future.successful(updateForm.orElse(legacyForm).toRight("no 'stripePaymentMethodID' and 'stripePublicKey' submitted with request")),
)
contact <- EitherT.fromEither(services.contactRepository.get(userId).map(_.toEither).map(_.flatMap(_.toRight(s"no SF user $userId"))))
subscription <- EitherT.fromEither(
services.subscriptionService
.current(contact)
.map(subs => subscriptionSelector(memsub.Subscription.SubscriptionNumber(subscriptionName), s"the sfUser $contact", subs)),
)
(stripeCardIdentifier, stripePublicKey) = stripeDetails
updateResult <- services
.setPaymentCard(stripePublicKey)
.setPaymentCard(useStripePaymentMethod, subscription.accountId, stripeCardIdentifier)
catalog <- SimpleEitherT.rightT(services.futureCatalog)
productType = subscription.plan(catalog).productType(catalog)
_ <- sendPaymentMethodChangedEmail(user.primaryEmailAddress, contact, Card, productType)
} yield updateResult match {
case success: CardUpdateSuccess => {
logger.info(s"Successfully updated card for identity user: $user")
Ok(Json.toJson(success))
}
case failure: CardUpdateFailure => {
logger.error(scrub"Failed to update card for identity user: $user due to $failure")
Forbidden(Json.toJson(failure))
}
}).run.map(_.toEither).map {
case Left(message) =>
logger.warn(s"Failed to update card for user $userId, due to $message")
InternalServerError(s"Failed to update card for user $userId")
case Right(result) => result
}
}
}