vapor-community / stripe-kit

A Swift on Server SDK for the Stripe API
MIT License
128 stars 46 forks source link

Failing to decode StripeEvent #159

Closed lorenalexm closed 1 year ago

lorenalexm commented 1 year ago

Environment: Xcode 14.2 Swift 5.7.2 vapor 4.69.2 stripe-kit 17.0.0


When responding to a webhook from Stripe, currently coming from the CLI for testing, I find an issue when attempting to decode to a StripeEvent. The Vapor console outputs the following warnings:

Value of type 'Dictionary<String, Any>' required for key 'request'. (This happens twice) Cannot initialize StripePaymentIntentStatus from invalid String value requires_source for key data.object.status

When wrapping the decoding in a do catch block it outputs the following from error.localizedDescription

The data couldn’t be read because it isn’t in the correct format.

The data received from the Stripe web hook is below:

{
  "id": "evt_REMOVED",
  "object": "event",
  "api_version": "2016-07-06",
  "created": 1675287370,
  "data": {
    "object": {
      "id": "pi_REMOVED",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_details": {
        "tip": {
        }
      },
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "automatic_payment_methods": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_REMOVED"
      },
      "client_secret": "pi_REMOVED_secret_REMOVED",
      "confirmation_method": "automatic",
      "created": 1675287370,
      "currency": "usd",
      "customer": null,
      "description": "(created by Stripe CLI)",
      "invoice": null,
      "last_payment_error": null,
      "latest_charge": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "mandate_options": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "processing": null,
      "receipt_email": null,
      "review": null,
      "setup_future_usage": null,
      "shipping": {
        "address": {
          "city": "San Francisco",
          "country": "US",
          "line1": "510 Townsend St",
          "line2": null,
          "postal_code": "94103",
          "state": "CA"
        },
        "carrier": null,
        "name": "Jenny Rosen",
        "phone": null,
        "tracking_number": null
      },
      "source": null,
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_source",
      "transfer_data": null,
      "transfer_group": null
    }
  },
  "livemode": false,
  "pending_webhooks": 2,
  "request": "req_REMOVED", 
  "type": "payment_intent.created"
}

The code in my project is hardly anything but the basic Vapor template; just trying to hack together a better understanding of how everything comes together between the code and Stripe. The controller used to respond to webhooks can be found below: Screenshot 2023-02-01 at 2 04 28 PM

Is there something blatant that I am overlooking in my code, or has Stripe recently changed something on their end? I greatly appreciate any insight on this issue of mine, thank you!

Andrewangeta commented 1 year ago

StripeKit currently only supports API version 2020-08-27 you're likely using an API version higher than that. A future version with full async await support will be updated to support the latest version of 2022-11-15 https://github.com/vapor-community/stripe-kit/pull/152

lorenalexm commented 1 year ago

I appreciate your timely reply! Looking over the Stripe Dashboard, I am only seeing the ability to use the 2016-07-06 or 2022-11-15 API versions, nothing in between.

My current use only makes use of signature verification and models to extract customer information from the intent. I would assume this would rule out the usage of the Stripe-Version: XXXX-XX-XX header. Is there a known way to specify an exact version for webhooks?

Andrewangeta commented 1 year ago

@lorenalexm I don't think so, what I can recommend for now is forking the current branch and add the new enum type of requires_source to the status property of the StripePaymentIntent type until the new version is ready to go.

lorenalexm commented 1 year ago

Thanks for the suggestion. I will run with that and keep plugging away for now. Quite grateful for your time, thanks!

lorenalexm commented 1 year ago

@Andrewangeta I just wanted to say thank you again. I was able to get webhook processing taken care of by adding the requires_source to the StripePaymentIntentStatus and also by changing public var request: StripeEventRequest? within the StripeEvent struct to a optional String type.