def updateCard()

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
        }
      }
    }