Skip to content

Commit

Permalink
Merge branch 'main' into pd/landing-page-abtest-benefit-reset
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-daniel-dempsey authored Jan 22, 2025
2 parents a5d8704 + de60a81 commit cc6e0fc
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 341 deletions.
58 changes: 0 additions & 58 deletions cdk/lib/__snapshots__/payment-api.test.ts.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 0 additions & 20 deletions cdk/lib/payment-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,26 +399,6 @@ export class PaymentApi extends GuStack {
snsTopicName: `alarms-handler-topic-${this.stage}`,
});

new GuAlarm(this, "AmazonPayPaymentError", {
app,
alarmName: `[CDK] ${app} ${this.stage} Amazon Pay payment error for one-off contribution via the payment-api`,
actionsEnabled: props.stage === "PROD",
threshold: 1,
evaluationPeriods: 1,
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
metric: new Metric({
metricName: "payment-error",
namespace: `support-payment-api-${this.stage}`,
dimensionsMap: {
"payment-provider": "AmazonPay",
},
statistic: "Sum",
period: Duration.seconds(60),
}),
treatMissingData: TreatMissingData.NOT_BREACHING,
snsTopicName: `alarms-handler-topic-${this.stage}`,
});

new GuAlarm(this, "PostPaymentError", {
app,
alarmName: `[CDK] ${app} ${this.stage} Failed post-payment task for one-off contribution via the payment-api`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import io.circe.syntax._
import lib.PlayImplicits._
import models.identity.responses.IdentityErrorResponse._
import org.apache.pekko.actor.{ActorSystem, Scheduler}
import org.joda.time.DateTime
import play.api.http.Writeable
import play.api.libs.circe.Circe
import play.api.mvc._
Expand Down Expand Up @@ -343,56 +342,9 @@ class CreateSubscriptionController(
}

private def cookies(product: ProductType, userEmail: String): Future[List[Cookie]] = {
// Setting the user attributes cookies used by frontend. See:
// https://github.com/guardian/dotcom-rendering/blob/3c4700cae532993ace6f40c3b59c337f3efe2247/dotcom-rendering/src/client/userFeatures/user-features.ts
val standardCookies = List(
"gu_user_features_expiry" -> DateTime.now.plusDays(1).getMillis.toString,
"gu_hide_support_messaging" -> true.toString,
)
val productCookies = product match {
case Contribution(_, _, billingPeriod) =>
List(
s"gu.contributions.recurring.contrib-timestamp.$billingPeriod" -> DateTime.now.getMillis.toString,
"gu_recurring_contributor" -> true.toString,
)
case _: SupporterPlus =>
List(
"gu_digital_subscriber" -> true.toString,
// "gu_supporter_plus" -> true.toString, // TODO: add this and remove the digisub one now that the CMP cookie list has been updated
"GU_AF1" -> DateTime.now().plusDays(1).getMillis.toString,
)
case _: TierThree =>
List(
"gu_digital_subscriber" -> true.toString,
// "gu_supporter_plus" -> true.toString, // TODO: add this and remove the digisub one now that the CMP cookie list has been updated
"GU_AF1" -> DateTime.now().plusDays(1).getMillis.toString,
)
case _: DigitalPack =>
List(
"gu_digital_subscriber" -> true.toString,
"GU_AF1" -> DateTime.now().plusDays(1).getMillis.toString,
)
case p: Paper if p.productOptions.hasDigitalSubscription =>
List(
"gu_digital_subscriber" -> true.toString,
"GU_AF1" -> DateTime.now().plusDays(1).getMillis.toString,
)
case _: Paper => List.empty
case _: GuardianWeekly => List.empty
case _: GuardianAdLite => List("gu_allow_reject_all" -> true.toString)
}

val standardAndProductCookies = (standardCookies ++ productCookies).map { case (name, value) =>
Cookie(
name = name,
value = value,
secure = true,
httpOnly = false,
domain = Some(guardianDomain.value),
)
}

checkoutCompleteCookies(product, userEmail).map(_ ++ standardAndProductCookies)
val productCookiesCreator = SubscriptionProductCookiesCreator(guardianDomain)
val productCookies = productCookiesCreator.createCookiesForProduct(product)
checkoutCompleteCookies(product, userEmail).map(_ ++ productCookies)
}

private def buildSupportWorkersUser(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package controllers

import com.gu.support.workers.ProductType
import config.Configuration.GuardianDomain
import org.joda.time.DateTime
import play.api.mvc.Cookie
import com.gu.support.workers._

case class SubscriptionProductCookiesCreator(domain: GuardianDomain) {
sealed trait SupportCookie {
def toPlayCookie: Cookie
}

case class SessionCookie(name: String, value: String) extends SupportCookie {
def toPlayCookie: Cookie = Cookie(
name = name,
value = value,
secure = true,
httpOnly = false,
domain = Some(domain.value),
)
}

case class PersistentCookie(name: String, value: String, maxAge: Int) extends SupportCookie {
def toPlayCookie: Cookie = Cookie(
name = name,
value = value,
maxAge = Some(maxAge),
secure = true,
httpOnly = false,
domain = Some(domain.value),
)
}

def createCookiesForProduct(product: ProductType): List[Cookie] = {
// Setting the user attributes cookies used by frontend. See:
// https://github.com/guardian/dotcom-rendering/blob/3c4700cae532993ace6f40c3b59c337f3efe2247/dotcom-rendering/src/client/userFeatures/user-features.ts
val standardCookies: List[SupportCookie] = List(
SessionCookie("gu_user_features_expiry", DateTime.now.plusDays(1).getMillis.toString),
SessionCookie("gu_hide_support_messaging", true.toString),
)
val oneWeekInSeconds = 604800
val productCookies: List[SupportCookie] = product match {
case Contribution(_, _, billingPeriod) =>
List(
SessionCookie(
s"gu.contributions.recurring.contrib-timestamp.$billingPeriod",
DateTime.now.getMillis.toString,
),
SessionCookie("gu_recurring_contributor", true.toString),
)
case _: SupporterPlus =>
List(
SessionCookie("gu_digital_subscriber", true.toString),
// "gu_supporter_plus" -> true.toString, // TODO: add this and remove the digisub one now that the CMP cookie list has been updated
SessionCookie("GU_AF1", DateTime.now().plusDays(1).getMillis.toString),
)
case _: TierThree =>
List(
SessionCookie("gu_digital_subscriber", true.toString),
// SessionCookie("gu_supporter_plus", true.toString), // TODO: add this and remove the digisub one now that the CMP cookie list has been updated
SessionCookie("GU_AF1", DateTime.now().plusDays(1).getMillis.toString),
)
case _: DigitalPack =>
List(
SessionCookie("gu_digital_subscriber", true.toString),
SessionCookie("GU_AF1", DateTime.now().plusDays(1).getMillis.toString),
)
case p: Paper if p.productOptions.hasDigitalSubscription =>
List(
SessionCookie("gu_digital_subscriber", true.toString),
SessionCookie("GU_AF1", DateTime.now().plusDays(1).getMillis.toString),
)
case _: Paper => List.empty
case _: GuardianWeekly => List.empty
case _: GuardianAdLite => List(PersistentCookie("gu_allow_reject_all", true.toString, oneWeekInSeconds))
}

(standardCookies ++ productCookies).map(_.toPlayCookie)
}
}
10 changes: 0 additions & 10 deletions support-frontend/assets/helpers/forms/errorReasons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ const errorReasons = [
'internal_error',
'card_authentication_error',
'incomplete_payment_request_details',
'amazon_pay_try_other_card',
'amazon_pay_try_again',
'amazon_pay_fatal',
'email_provider_rejected',
'invalid_email_address',
'recaptcha_validation_failed',
Expand All @@ -38,25 +35,18 @@ function appropriateErrorMessage(errorReason: string): string {
case 'payment_details_incorrect':
return 'An error occurred while trying to process your payment. Please double check your card details and try again. Alternatively, try another card or payment method.';

case 'amazon_pay_try_again':
return 'An error occurred while trying to process your payment. You have not been charged. Please try entering your payment details again.';

case 'personal_details_incorrect':
return 'Please double check the name and contact details you provided and try again.';

case 'payment_method_temporarily_declined':
return 'The transaction was temporarily declined. Please try entering your payment details again. Alternatively, try another payment method.';

case 'payment_method_unacceptable':
case 'amazon_pay_try_other_card':
return 'The transaction was unsuccessful and you have not been charged. Please use a different card or choose another payment method.';

case 'payment_provider_unavailable':
return 'The transaction was unsuccessful. This does not mean there’s anything wrong with your card, and you have not been charged. Please try using an alternative payment method.';

case 'amazon_pay_fatal':
return 'The transaction was unsuccessful and you have not been charged. Please try using an alternative payment method.';

case 'all_payment_methods_unavailable':
return 'Sorry, our payment methods are unavailable at this time. We are working hard to fix the problem and hope to be back up and running soon. Please come back later to complete your contribution or consider another type of contribution from the tabs above. Thank you.';

Expand Down
3 changes: 0 additions & 3 deletions support-frontend/conf/CODE.public.conf
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ _src=${_src} "metric-push-api-code.support.guardianapis.com"
_src=${_src} "www.paypal.com"
_src=${_src} "www.sandbox.paypal.com"
_src=${_src} "js.stripe.com"
_src=${_src} "https://payments-sandbox.amazon.com"
_src=${_src} "https://api-cdn.amazon.com"
_src=${_src} "static-na.payments-amazon.com"
_src=${_src} "ophan.theguardian.com"
_src=${_src} "j.ophan.co.uk"
_src=${_src} "media.guim.co.uk"
Expand Down
3 changes: 0 additions & 3 deletions support-frontend/conf/DEV.public.conf
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ _src=${_src} "www.paypal.com"
_src=${_src} "t.paypal.com"
_src=${_src} "www.sandbox.paypal.com"
_src=${_src} "js.stripe.com"
_src=${_src} "https://payments-sandbox.amazon.com"
_src=${_src} "https://api-cdn.amazon.com"
_src=${_src} "static-na.payments-amazon.com"
_src=${_src} "ophan.theguardian.com"
_src=${_src} "j.ophan.co.uk"
_src=${_src} "media.guim.co.uk"
Expand Down
5 changes: 0 additions & 5 deletions support-frontend/conf/PROD.public.conf
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ _src=${_src} "www.paypal.com"
_src=${_src} "t.paypal.com"
_src=${_src} "www.sandbox.paypal.com"
_src=${_src} "js.stripe.com"
_src=${_src} "https://payments.amazon.com"
_src=${_src} "https://payments-sandbox.amazon.com"
_src=${_src} "https://coin.amazonpay.com"
_src=${_src} "https://api-cdn.amazon.com"
_src=${_src} "static-na.payments-amazon.com"
_src=${_src} "ophan.theguardian.com"
_src=${_src} "j.ophan.co.uk"
_src=${_src} "media.guim.co.uk"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package controllers

import com.gu.i18n.Currency.GBP
import com.gu.support.workers.{GuardianAdLite, Monthly, SupporterPlus}
import config.Configuration.GuardianDomain
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import play.api.mvc.Cookie

class SubscriptionProductCookiesCreatorTest extends AnyFlatSpec with Matchers {
"createCookiesForProduct" should "set the gu_allow_reject_all cookie for GuardianAdLite" in {
val guardianAdLite = GuardianAdLite(GBP)
val creator = SubscriptionProductCookiesCreator(GuardianDomain("thegulocal.com"))

val cookies = creator.createCookiesForProduct(guardianAdLite)

val expectedCookie = Cookie(
name = "gu_allow_reject_all",
value = "true",
maxAge = Some(604800),
secure = true,
httpOnly = false,
domain = Some("thegulocal.com"),
)
cookies should contain(expectedCookie)
}

it should "set the gu_digital_subscriber cookie for SupporterPlus" in {
val supporterPlus = SupporterPlus(BigDecimal(12), GBP, Monthly)
val creator = SubscriptionProductCookiesCreator(GuardianDomain("thegulocal.com"))

val cookies = creator.createCookiesForProduct(supporterPlus)

val expectedCookie = Cookie(
name = "gu_digital_subscriber",
value = "true",
secure = true,
httpOnly = false,
domain = Some("thegulocal.com"),
)
cookies should contain(expectedCookie)
}
}
Loading

0 comments on commit cc6e0fc

Please sign in to comment.