#reni

1 messages · Page 1 of 1 (latest)

restive sierraBOT
hasty ivy
#

Why are you unable to use the signing verification? This is exactly what it was intended for

#

Otherwise, I guess something in your integration is malforming the payload. How does it get from A to B? Your endpoint receives the event payload, then what?

shut juniper
#

As I understand it, the signing verification uses the payload and your signing secret to create a hash value (with a timestamp added at the start). That value must then be compared with a value that I generate on my end, using the same method. But in order to get the same hash value, the payload has to be identical in every way.

#

First we used ngrok to redirect the webhook's endpoint to my local machine. But we've also used the same json request from postman

hasty ivy
#

You don't need to 'compare' payloads, you just need to verify that the initial event received was from Stripe. What you do after that is per your requirements

#

The API shape should always remain consistent (the fields are ordered alphabetically). Maybe I'm misunderstanding your use case but it seems a little off piste

shut juniper
#

Step 4 of your "Check the webhook signature" docs page reads "Compare the signatures"

#

The signature is determined by using the payload

hasty ivy
#

Sorry I interpreted it as comparing payloads. And you're unable to using the signature verification? It fails?

#

Is there a visual breakdown of the flow you're describing? But yes I imagine the signatures won't match after you've sent the payload elsewhere in your application as at that point its malformed (we require the raw payload)

#

Why can you not do verification at point A before sending to point B?

shut juniper
#

The payload, and thus our only way of generating a signature, is already malformed at point A

hasty ivy
#

Can you share the code used in the webhook handler? I suspect something there is malforming it

shut juniper
#

Our best guess is that it has something to do with the Grails framework, reordering the payload as soon as it gets it.

hasty ivy
#

Is there a way in Grails to control how it parses request data

#

(sorry, not familiar with it at all)

shut juniper
#

import com.google.gson.JsonSyntaxException
import grails.rest.*
import grails.converters.*
import com.stripe.Stripe;
import com.stripe.model.StripeObject;
import com.stripe.net.ApiResource;
import com.stripe.net.Webhook
import com.stripe.model.Event;
import com.stripe.model.EventDataObjectDeserializer;
import com.stripe.model.PaymentIntent;
import com.stripe.exception.SignatureVerificationException
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper;
import groovy.util.logging.Slf4j

@Slf4j
class PaymentWebhooksController {
def springSecurityService
static responseFormats = ['json', 'xml']
String endpointSecret = ""

def sendSuccessfulPaymentEmail() {
    println request.JSON //The payload is already malformed at this point
    def msg = [success: false, status: 500]
    PaymentWebhooksService paymentWebhooksService = new PaymentWebhooksService()

// def json = request.XML
String payload = new JsonBuilder(request.JSON).toPrettyString()
String sigHeader = request.getHeader("Stripe-Signature");
Event event = null

#

Due to company regulations, I cannot share more than this

#

We use the same try catch system as shown in your documents. Along with one for general exceptions.
But we keep getting a SignatureVerificationException

hasty ivy
#

Could be that, println request.JSON, actually malforms the request object

#

By calling that JSON method

shut juniper
#

It is possible. But the only way we are able to access the payload's data is throught the JSON method. Or possibly an XML.

hasty ivy
#

And you're using the correct signing secret?

shut juniper
#

Coppied and pasted it straight off of the webhook, on the stripe website

hasty ivy
#

I see. At this point I'd recommend writing in to our team so we can take some time to investigate this, and hopefully somebody with Grails familiarity can pinpoint the issue: https://support.stripe.com/contact

shut juniper
#

Alright, I'll give them a try. Thanks for the assistance.

shut juniper
hasty ivy
#

The fields returned in the JSON payload and their ordering

shut juniper
#

I see. And I should see that alphabetical ordering when looking at the request on the Stripe website's Developers section, on the webhooks tab?

#

When I'm on the actual webhooks page, I can see a list of instances where that webhook ran. When I click on one of those instances, it displays the response and request. Should that request be displaying alphabetically?

hasty ivy
#

And I believe in most (all?) instances the fields are alphabetical

shut juniper
#

And just to confirm, does that mean that the payload should also be alphabetically ordered?

rich oracle
#

Hi there 👋 jumping in as my teammate needed to step away. I wanted to point out that even on the dashboard, the structure of those events does not follow an alphabetical order as more important fields (like id and object) are provided first.

Can you help me understand the importance of the order of fields in this scenario?

shut juniper
#

Hey toby. I hope if you go throught our chat, you'll understand why I'm asking this.

If I use an alphabetical ordering function on the request json, in my controller, will that JSON then match the JSON Stripe sends over, as a payload?

#

I am trying to match the payload exactly, so that when I use the SHA256 hash function. My signature will match the signature sent over by Stripe

rich oracle
#

Ah I see, the framework you're using is rearranging request contents, and you're trying to rebuild that structure.

shut juniper
#

Yes

rich oracle
#

Other than id and object, the contents that I'm seeing in an event that I just sent to my endpoint are being listed in alphabetical order.

shut juniper
#

So in the payload Stripe sends, ID and object are always listed first (in every nested json they appear in) and the rest of the data is in alphabetical order?

rich oracle
#

Yes, that aligns with what I'm seeing.

shut juniper
#

And the dashboard structure matches the actual payload structure perfectly?

rich oracle
#

I believe so, but I haven't done a strict validation of that. Are you seeing them misalign? I saw you mentioned that you confirmed the structure of our events is preserved when using other languages, are you using one of those to compare what we're sending with what you're seeing in the dashboard?

shut juniper
#

Yes, thank you for reminding me. I used a node js app to receive the webhook and it matched the request that the dashboard is displaying.

#

Thank you for your help Toby. I have a better idea of what I need to do.

rich oracle
#

Happy to help, and best of luck! That sounds like a gnarly problem to have to code your way out of.