more stripe stuff

pull/1979/head
Thibault Duplessis 2016-06-06 20:18:40 +02:00
parent 5b9e66d094
commit 124182748b
6 changed files with 47 additions and 7 deletions

View File

@ -44,7 +44,19 @@ object Plan extends LilaController {
def switch = AuthBody { implicit ctx =>
me =>
Redirect(routes.Plan.index()).fuccess
implicit val req = ctx.body
lila.stripe.Switch.form.bindFromRequest.fold(
err => Redirect(routes.Plan.index).fuccess,
data => (data.plan.flatMap(lila.stripe.LichessPlan.byId) match {
case Some(plan) => Env.stripe.api.switch(me, plan)
case _ if data.cancel.isDefined => Env.stripe.api.cancel(me)
case _ => fufail("Invalid switch")
}) recover {
case e: Exception =>
lila.log("stripe").error("Plan.switch", e)
Redirect(routes.Plan.index)
} inject Redirect(routes.Plan.index())
)
}
def charge = AuthBody { implicit ctx =>
@ -54,7 +66,7 @@ object Plan extends LilaController {
lila.stripe.Checkout.form.bindFromRequest.fold(
err => BadRequest(html.plan.badCheckout(err.toString)).fuccess,
data => Env.stripe.api.checkout(me, data) map { res =>
Redirect(routes.Plan.thanks())
Redirect(routes.Plan.index() + "?thanks=1")
} recover {
case e: StripeException =>
lila.log("stripe").error("Plan.charge", e)

View File

@ -26,12 +26,12 @@ description = "All of lichess features are free for all and forever. We do it fo
<th>Change plan</th>
<td>
<form action="@routes.Plan.switch" method="POST">
<button type="submit" class="button">$0 (Cancel)</button>
<button type="submit" class="button" name="cancel" value="1">$0 (Cancel)</button>
@lila.stripe.LichessPlan.all.map { p =>
@if(p == info.currentPlan) {
<button class="button" disabled>@p.usd (Current)</button>
} else {
<button type="submit" class="button">
<button type="submit" class="button" name="plan" value="@p.id">
<span
data-icon="@if(p.usd > info.currentPlan.usd){N}else{M}"
class="switch text @if(p.usd > info.currentPlan.usd){up}else{down}">@p.usd</span>

View File

@ -17,3 +17,13 @@ object Checkout {
"amount" -> number(min = 500)
)(Checkout.apply)(Checkout.unapply))
}
case class Switch(plan: Option[String], cancel: Option[Int])
object Switch {
val form = Form(mapping(
"plan" -> optional(text.verifying("Invalid plan", LichessPlan.exists _)),
"cancel" -> optional(number)
)(Switch.apply)(Switch.unapply))
}

View File

@ -18,4 +18,8 @@ object LichessPlan {
def findUnder(cents: Cents): Option[LichessPlan] = all.reverse.find(_.cents <= cents)
def byStripePlan(plan: StripePlan) = findUnder(plan.cents)
def byId(id: String) = all.find(_.id == id)
def exists(id: String) = all.exists(_.id == id)
}

View File

@ -17,16 +17,27 @@ final class StripeApi(
case Some(plan) => setUserPlan(user, plan.stripePlan, data.source)
}
def upgrade(user: User, plan: LichessPlan): Fu[StripeSubscription] =
def switch(user: User, plan: LichessPlan): Fu[StripeSubscription] =
userCustomer(user) flatMap {
case None => fufail(s"Can't upgrade non-existent customer ${user.id}")
case None => fufail(s"Can't switch non-existent customer ${user.id}")
case Some(customer) =>
customer.firstSubscription match {
case None => fufail(s"Can't upgrade non-existent subscription of ${user.id}")
case None => fufail(s"Can't switch non-existent subscription of ${user.id}")
case Some(sub) => client.updateSubscription(sub, plan.stripePlan, none)
}
}
def cancel(user: User): Funit =
userCustomer(user) flatMap {
case None => fufail(s"Can't cancel non-existent customer ${user.id}")
case Some(customer) =>
customer.firstSubscription match {
case None => fufail(s"Can't cancel non-existent subscription of ${user.id}")
case Some(sub) => client.cancelSubscription(sub) >>
UserRepo.setPlan(user, user.plan.disable)
}
}
def onCharge(charge: StripeCharge): Funit =
customerColl.uno[Customer]($id(charge.customer)).flatMap {
case None => fufail(s"Charged unknown customer $charge")

View File

@ -36,6 +36,9 @@ private final class StripeClient(config: StripeClient.Config) {
'source -> source.map(_.value),
'prorate -> false)
def cancelSubscription(sub: StripeSubscription): Funit =
deleteOne(s"subscriptions/${sub.id}")
def getEvent(id: String): Fu[Option[JsObject]] =
getOne[JsObject](s"events/$id")