Ошибка проверки Stripe Webhook с Play Framework - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь настроить полосовой платеж с помощью приложения Play Framework. У меня проблемы с настройкой webhook.

com.stripe.exception.SignatureVerificationException: No signatures found matching the expected signature for payload

Это ошибка, которую я получаю, когда пытаюсь создать событие, отправленное с полосы. Я распечатываю значения для тела и подписи, и они выглядят так, как будто они должны быть правильными. Это код, который я использую для сбора веб-крюка.

 def webhook = Action { implicit request: Request[AnyContent] =>
println(request.headers.toMap)
val bodyOp:Option[JsValue] = request.body.asJson
val sigOp:Option[String] = request.headers.get("Stripe-Signature")
var event: Event = null
if (bodyOp.isEmpty || sigOp.isEmpty) {
  WebhookController.logger.write("EMPTY BODY OR SIG body-"+bodyOp+"   sig-"+sigOp,Logger.RED)
  BadRequest
} else {
  val body = bodyOp.get.toString
  val sig = sigOp.get
  println(body)
  println(sig)
  try {
    event = Webhook.constructEvent(body, sig, "whsec_5XwS8yCNOcq1CKfhh2Dtvm8RaoaE3p7b")
    val eventType: String = event.getType
    eventType match {
      case "customer.subscription.deleted" => deleteCustomer(event)
      case "invoice.payment.succeeded" => successPayment(event)
      case "invoice.payment.failed" => failedPayment(event)
      case _ => WebhookController.logger.write("UNKNOWN " + event, Logger.RED)
    }

    Ok("")
  } catch {
    case e: JsonSyntaxException =>
      e.printStackTrace()
      WebhookController.logger.write("ERROR" + e.getMessage +" "+exceptionToString(e), Logger.RED)
      BadRequest
    case e: SignatureVerificationException =>
      e.printStackTrace()
      WebhookController.logger.write("ERROR" + e.getMessage + " "+exceptionToString(e), Logger.RED)
      WebhookController.logger.write("SIG ERROR header-"+e.getSigHeader+" status code-"+e.getStatusCode,Logger.RED )
      BadRequest
  }
}
}

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Карллекко был на правильном пути.Play framework автоматически разбирает его как json, что вызвало ошибку.request.body.asText не работал, потому что значение заголовка типа содержимого было установлено в json.Tolarant Text сработал бы, если бы полоса отправляла их веб-хуки с utf-8, а tolarant text не анализирует с utf-8.Поэтому мне пришлось использовать RawBuffer и превратить его в строку (https://www.playframework.com/documentation/2.6.x/ScalaBodyParsers)

class WebhookController @Inject()(parsers: PlayBodyParsers) extends Controller() {

def webhook = Action(parsers.raw) { implicit request: Request[RawBuffer] =>
  val bodyOp =  request.body.asBytes()
  val sigOp:Option[String] = request.headers.get("Stripe-Signature")
  var event: Event = null
  if (bodyOp.isEmpty || sigOp.isEmpty) {
    BadRequest
  } else {
    val body = bodyOp.get.utf8String
    val sig = sigOp.get
    try {
      event = Webhook.constructEvent(body, sig, secret)
      ...
      ...
0 голосов
/ 16 мая 2018

Вам необходимо передать необработанное тело запроса точно в том виде, в котором оно было получено, в constructEvent, а не в разобранной версии JSON.

Я считаю, что должно быть

event = Webhook.constructEvent(request.body.asText, sig, "whsec_5XwS8yCNOcq1CKfhh2Dtvm8RaoaE3p7b")

в этом случае?

Вы также можете посмотреть примеры из Stripe [0].Но основная проблема заключается в том, что вы должны подписать точную строку, отправленную Stripe, без какого-либо вмешательства вашего кода или фреймворка посередине.

[0] - https://github.com/stripe/stripe-java/blob/master/src/test/java/com/stripe/net/WebhookTest.java

...