#Sarim-webhook-signature
1 messages ยท Page 1 of 1 (latest)
Java with spring framework ๐
Gotcha, well the same issue that pops up with Node is likely occurring, just in a different way most likely. Basically, to verify the signature, you have to have the raw request body. Anything that manipulates the body at all will make the signature verification fail.
How are you reading the event data?
exactly even the payload is ok but still exception occur
I have a stripe signature key for related account so when ever i create any customer in stripe the webhook events called and I test it locally by using stripe CLI
I am searching for the solution but unable to find any proper answer
Can you provide your webhook code?
Oh wait
You are using CLI
CLI should have its own secret if I remember correctly
Let me double check on that
public String postWebhook(Event event, WebhookEnum webhookEnum) throws StripeException {
LOGGER.debug("Entering postWebhook() with event: {}, webhookEnum: {}", event, webhookEnum);
LOGGER.debug(String.valueOf(Collections.list(request.getHeaderNames())));
String headerStripeSignature = CommonUtility.getReqHeaderValueByName(request, Constants.STRIPE_SIGNATURE_HEADER_NAME);
if (headerStripeSignature != null) {
try {
event = Webhook.constructEvent(
event.toJson(), headerStripeSignature, stripeConfigProperties.getDirectSignature());
} catch (SignatureVerificationException e) {
// Invalid signature
LOGGER.error("โ ๏ธ Webhook error while validating signature. SignatureVerificationException: {}", e);
//TODO: Stripe API doesn't seem to require any specific response. Subject to change with a HttpResponse 400
return "Error";
}
}
//handle the Stripe webhook event
webhookService.handleEvent(event);
//TODO: Stripe API doesn't seem to require any specific response. Subject to change with a HttpResponse 200
return "";
}
here is the code
yes i am using cli just for port forwarding to received events on localhost
Thanks for the code. I think that toJson may be part of the issue. The first parameter is expecting a string that exactly matches the body that we sent you. toJson sounds like some conversion is happening that may be changing the payload a bit
Like if the payload is missing spaces or a different order of json elements will cause the signature verification to fail
.toJson is basically return the string
{
"account": null,
"api_version": null,
"created": 1649420642,
"data": {
"previous_attributes": null,
"object": {}
},
"id": "evt_1KmGr8FFtXgxo67Xyg5glWL0",
"livemode": false,
"object": "event",
"pending_webhooks": null,
"request": {
"id": "req_zH9bnYe6baVBk4",
"idempotency_key": null
},
"type": "customer.created"
}
this is the object the Event class is basically a builtin class comes up with stripe sdk
That does not look like the raw json body of the event that we send.
The body for that event looks like this { "id": "evt_1KmGr8FFtXgxo67Xyg5glWL0", "object": "event", "api_version": "2020-08-27", "created": 1649420642, "data": { "object": { "id": "cus_LTDH6AFsioCuge", "object": "customer", "address": null, "balance": 0, "created": 1649420642, "currency": null, "default_source": null, "delinquent": false, "description": null, "discount": null, "email": "customer905@example.com", "invoice_prefix": "0FDDB73E", "invoice_settings": { "custom_fields": null, "default_payment_method": null, "footer": null }, "livemode": false, "metadata": { }, "name": null, "phone": null, "preferred_locales": [ "de" ], "shipping": null, "tax_exempt": "none", "test_clock": null } }, "livemode": false, "pending_webhooks": 3, "request": { "id": "req_zH9bnYe6baVBk4", "idempotency_key": "abf1abbf-56d7-4842-b9d3-93d5d1582d14" }, "type": "customer.created" }
ok then which type of json we need to send ?
Just pass along the raw string that we send you.
Don't try to do any conversion on it. Just use your java library's way of getting the string for the POST request's body
yes I just see but i am unable to received this data from stripe side
And pass that string in to the constructEvent call
You will after the constructEvent call
That call will return an event object that you can extract data from
ok you mean instead of Event class I get data directly from request object
ok thanks for the clearification let me try again ๐
@hardy belfry just checking in. Have you had any luck testing this?
trying with request now able to received proper json format but still facing same error
No signatures found matching the expected signature for payload
Can you show me your updated code? Unfortunately it can be pretty tricky to get the exact raw body sometimes.
public String postWebhook(String json, WebhookEnum webhookEnum) throws StripeException {
LOGGER.debug("Entering postWebhook() with event: {}, webhookEnum: {}", json, webhookEnum);
LOGGER.debug(String.valueOf(Collections.list(request.getHeaderNames())));
String headerStripeSignature = CommonUtility.getReqHeaderValueByName(request, Constants.STRIPE_SIGNATURE_HEADER_NAME);
Event event = null;
if (headerStripeSignature != null) {
try {
event = webhookEnum.equals(WebhookEnum.CONNECT) ? Webhook.constructEvent(
json, headerStripeSignature, stripeConfigProperties.getConnectSignature()) :
Webhook.constructEvent(
json, headerStripeSignature, stripeConfigProperties.getDirectSignature());
} catch (SignatureVerificationException e) {
// Invalid signature
LOGGER.error("โ ๏ธ Webhook error while validating signature. SignatureVerificationException: {}", e);
//TODO: Stripe API doesn't seem to require any specific response. Subject to change with a HttpResponse 400
return "Error";
}
}
Can you show me the code where you get the body string from our POST request? And I assume you have debugged to check that headerStripeSignature and that the secret string that you are expecting is being retrieved?
{
"id": "evt_1KmO6ZFFtXgxo67XePifSGwE",
"object": "event",
"api_version": "2020-08-27",
"created": 1649448507,
"data": {
"object": {
"id": "cus_LTKmSuG6JFSxj8",
"object": "customer",
"address": null,
"balance": 0,
"created": 1649448507,
"currency": null,
"default_source": null,
"delinquent": false,
"description": null,
"discount": null,
"email": "customer905@example.com",
"invoice_prefix": "6E987B9D",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": null,
"footer": null
},
"livemode": false,
"metadata": {
},
"name": null,
"phone": null,
"preferred_locales": [
"de"
],
"shipping": null,
"tax_exempt": "none",
"test_clock": null
}
},
"livemode": false,
"pending_webhooks": 3,
"request": {
"id": "req_tvhhkfNW9uffNq",
"idempotency_key": "f9179fb9-d402-48ce-99f4-db77af462069"
},
"type": "customer.created"
}
here is the request json
t=1649448507,v1=a64a5a378603f87c8b67839ce908cda3ff0cd8b6bf691a5d1204d88c006ddeb0,v0=da6396d3743e27f6197fcfc757a924e92f8f4c6204729b2bced7266cbc77d4d1
this is the headerStripeSignature
@RequestMapping("/webhook")
public interface WebhookApi {
@PostMapping(
value = "/connect",
produces = {"application/json"},
consumes = {"application/json"}
)
String postConnectWebhook(@Valid @RequestBody String webhookRequestBody) throws StripeException;
@PostMapping(
value = "/direct",
produces = {"application/json"},
consumes = {"application/json"}
)
String postDirectWebhook(@Valid @RequestBody String webhookRequestBody) throws StripeException;
}
here is api endpoint where i received the body string from webhook event
does that make sense ?
@thorn magnet are you there ??
That makes sense. Looking all of that over now.
ok mate thanks
Interesting. That does look like it should get the raw request body in Spring
And the webhook secret key is what the CLI printed out after you ran stripe listen?
It really sounds like there is some small error in the secret or body param that is being passed in
sorry didn't understand what you need ? signature.key or stripe secret-key ?
?
hope it helps ๐ฆ
Whoops sorry, I did not meant to ask for your actual secret. That should not be shared publically if it can be helped. Thanks for the info though. Let me see if I can see which parameter is not working here.
sorry for that I shared here because you are offical stripe devs but correct I'll be very carefull next time
yes sure it will be helpfull for me if you found because i am block now
hey @hardy belfry I'm taking over for @thorn magnet but there has been a ton of words and back and forth, still trying to grasp what you're asking but re-stating the overall potential root cause
1/ You're not using the right secret
2/ You're not getting the raw original JSON we're sending you
We can't really check the secret for you. You seem to use both the CLI and a direct webhook. Which one are you debugging right now?
I use cli for getting request in my local so i am able to debug in my intellij and i test direct webhook i already shared the request json and stripe-header as well
okay so are you properly using the webhook secret from the CLI?
yes
Unfortunately those can be really tricky to debug and it's almost always a secret issue or a raw JSON issue
do you mean direct/connect secret-key ??
no
the webhook endpoint's secret. It's different between what you see in the Dashboard for the endpoint and what the CLI generates
alright got it its resolved now i made the mistake I actually used old one that dashboard provides me thanks alot team stay blessed ๐
yes finally a issue resolved its small but bigger for me thank you all guys for support really appriciated ๐
Thank you @fair lava
Have a great week end ๐
you too