#reni
1 messages · Page 1 of 1 (latest)
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?
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
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
Step 4 of your "Check the webhook signature" docs page reads "Compare the signatures"
The signature is determined by using the payload
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?
The payload, and thus our only way of generating a signature, is already malformed at point A
Can you share the code used in the webhook handler? I suspect something there is malforming it
Our best guess is that it has something to do with the Grails framework, reordering the payload as soon as it gets it.
Is there a way in Grails to control how it parses request data
(sorry, not familiar with it at all)
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
Could be that, println request.JSON, actually malforms the request object
By calling that JSON method
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.
And you're using the correct signing secret?
Coppied and pasted it straight off of the webhook, on the stripe website
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
Find help and support for Stripe. Our support center provides answers on all types of situations, including account information, charges and refunds, and subscriptions information. Get your questions answered and find international support for Stripe.
Alright, I'll give them a try. Thanks for the assistance.
Could you just explain what you meant by "API shape"?
The fields returned in the JSON payload and their ordering
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?
Well, it'd mirror the API reference for the object: https://stripe.com/docs/api
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
And I believe in most (all?) instances the fields are alphabetical
And just to confirm, does that mean that the payload should also be alphabetically ordered?
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?
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
Ah I see, the framework you're using is rearranging request contents, and you're trying to rebuild that structure.
Yes
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.
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?
Yes, that aligns with what I'm seeing.
And the dashboard structure matches the actual payload structure perfectly?
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?
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.
Happy to help, and best of luck! That sounds like a gnarly problem to have to code your way out of.