def fromStripeCharge()

in support-payment-api/src/main/scala/model/db/ContributionData.scala [47:122]


  def fromStripeCharge(
      identityId: Option[String],
      charge: Charge,
      countrySubdivisionCode: Option[String],
      postalCode: Option[String],
      paymentProvider: PaymentProvider,
  ): ContributionData =
    // TODO: error handling
    ContributionData(
      paymentProvider = paymentProvider,
      paymentStatus = PaymentStatus.Paid,
      paymentId = charge.getId,
      identityId = identityId,
      email = charge.getReceiptEmail,
      // From the Stripe documentation for charge.created
      // Time at which the object was created. Measured in seconds since the Unix epoch.
      created = LocalDateTime.ofEpochSecond(charge.getCreated, 0, ZoneOffset.UTC),
      // Stripe can return currency in lower case
      currency = Currency.withNameInsensitive(charge.getCurrency),
      amount = BigDecimal(charge.getAmount, 2),
      countryCode = StripeCharge.getCountryCode(charge),
      countrySubdivisionCode = countrySubdivisionCode,
      postalCode = postalCode,
    )

  import scala.jdk.CollectionConverters._

  // Couple of notes:
  // - using (deprecated) shipping address as unable to get state from billing address
  // - on event of not being able to get state from shipping address,
  //   don't fallback to region header set by Fastly,
  //   since currently the only client of the payment API is support-frontend
  //   and this service makes the request to execute the payment server side,
  //   resulting in the region header always being Dublin i.e. where the server is hosted.
  private def getPaypalCountrySubdivisionCode(payment: Payment): Option[String] =
    Try(payment.getPayer.getPayerInfo.getShippingAddress.getState).toOption.flatMap(Option(_))

  def fromPaypalCharge(
      payment: Payment,
      email: String,
      identityId: Option[String],
      countrySubdivisionCode: Option[String],
      postalCode: Option[String],
  ): Either[PaypalApiError, ContributionData] = {
    for {
      transactions <- Either.fromOption(
        payment.getTransactions.asScala.headOption,
        PaypalApiError
          .fromString(s"Invalid Paypal transactions content."),
      )
      currency <- Either
        .catchNonFatal(Currency.withNameInsensitive(transactions.getAmount.getCurrency))
        .leftMap(PaypalApiError.fromThrowable)
      amount <- Either
        .catchNonFatal(BigDecimal(payment.getTransactions.asScala.head.getAmount.getTotal))
        .leftMap(PaypalApiError.fromThrowable)
      created <- Either
        .catchNonFatal(paypalDateToLocalDateTime(payment.getCreateTime))
        .leftMap(PaypalApiError.fromThrowable)
      countryCode <- Either
        .catchNonFatal(payment.getPayer.getPayerInfo.getCountryCode)
        .leftMap(PaypalApiError.fromThrowable)
    } yield ContributionData(
      paymentProvider = PaymentProvider.Paypal,
      paymentStatus = PaymentStatus.Paid,
      paymentId = payment.getId,
      identityId = identityId,
      email = email,
      created = created,
      currency = currency,
      amount = amount,
      countryCode = Some(countryCode),
      countrySubdivisionCode = getPaypalCountrySubdivisionCode(payment),
      postalCode = postalCode,
    )
  }