#Jinliang
1 messages · Page 1 of 1 (latest)
com.stripe.exception.SignatureVerificationException: No signatures found matching the expected signature for payload
The payload of event:
You mean this is another question now? you managed to fetch the PaymentIntent ?
I want to implement scenario: Accept the payment, then split the funds and transfer them to another connected account.
Here is the payload of event
Ok, and now you are facing an excpetion when verifying the signature of the event ?
There is two possible causes for this, you are using an incorrect webhook secret or your backend is updating/modifying the raw body of the event
Yes
what programming language are you using for your webhook endpoint ?
Java, but without remove the Stripe Account Id, the verifying works
Hi! I'm taking over my colleague. Please, give me a moment to catch up.
but without remove the Stripe Account Id
You remove it from the original PI call?
SessionCreateParams params =
SessionCreateParams
.builder()
.setMode(SessionCreateParams.Mode.PAYMENT)
.addLineItem(
SessionCreateParams.LineItem
.builder()
.setPrice("{{PRICE_ID}}")
.setQuantity(1L)
.build()
)
.setSuccessUrl("https://example.com/success")
.setCancelUrl("https://example.com/cancel")
.build();
Session session = Session.create(params, null);
After "charge.succeeded" event is received, transfer funds:
TransferCreateParams params =
TransferCreateParams
.builder()
.setAmount(1000L)
.setCurrency("usd")
.setSourceTransaction("{{CHARGE_ID}}")
.setDestination("{{CONNECTED_ACCOUNT_ID}}")
.build();
Transfer transfer = Transfer.create(params)
Because the PaymentIntent object does not contain charge after creating the session, so I prepare to receive the charge object in event callback.
By "event callback" you mean webhook?
Yes, the tranfer needs charge id, I don't known how to get the charge id, so i tried the webhook.
But, the question is the webhook works before removed the Stripe Account Id, so the webhook secret is correct.
Which call has the Stripe-Account header?
SessionCreateParams params =
SessionCreateParams
.builder()
.setMode(SessionCreateParams.Mode.PAYMENT)
.addLineItem(
SessionCreateParams.LineItem
.builder()
.setPrice("{{PRICE_ID}}")
.setQuantity(1L)
.build()
)
.setPaymentIntentData(
SessionCreateParams.PaymentIntentData
.builder()
.setApplicationFeeAmount(123L)
.build()
)
.setSuccessUrl("https://example.com/success")
.setCancelUrl("https://example.com/cancel")
.build();
RequestOptions requestOptions =
RequestOptions.builder().setStripeAccount("{{CONNECTED_ACCOUNT_ID}}").build();
Session session = Session.create(params, requestOptions);
This way you create the Session object on another account. So you will only get a webhook notification about the event on your connect webhook endpoint: https://stripe.com/docs/connect/webhooks
I want to implement scenario: Accept the payment, then split the funds and transfer them to another connected account.
Then you need this: https://stripe.com/docs/connect/charges-transfers
And you don't need to use the Stripe-Account header
Yes, I faced Transfer Availability issue, there is insufficient available balance sometimes.
So refer to Transfer Availablity section, I need charge Id:
TransferCreateParams params =
TransferCreateParams
.builder()
.setAmount(1000L)
.setCurrency("usd")
.setSourceTransaction("{{CHARGE_ID}}")
.setDestination("{{CONNECTED_ACCOUNT_ID}}")
.build();
You can use the transfer_group as well
Yes, I've implement using transfer_group solution, but faced Transfer Availability issue, there is insufficient available balance sometimes.
Refer this document, I need the CHARGE_ID, the original charge paid by customer
Okay, I see. Are you able to get the charge from the webhook endpoint if you don't use the Stripe-Account header?
The payload of event include the charge object. But there is a exception of calling Webhook.constructEvent()
Don't use the Stripe-Account header, you mean remove Stripe.apiKey = xxx ?
No, don't use .setStripeAccount("{{CONNECTED_ACCOUNT_ID}}")
Yes, I removed this.
I understand. Can you make sure you pass the raw request body to the .constructEvent() call?
Yes, before remove the Stripe-Account , constructEvent() works
Maybe you are using Stripe API Secret Key from your Connected account?
You need to use the Secret Key and Webhook secret from your Platform account.
Yes, I use our platform account, I confirm the webhook secret is correct.
We can place different order type, one order don't use setStripeAccount("{{CONNECTED_ACCOUNT_ID}}")
, the constructEvent() work, and the other type of order don't use setStripeAccount, then there is a exception at constructEvent() . The same code.
Could you please share what your webhook code looks like?
Could you please share both PaymentIntent IDs? pi_xxx
the account: pi_3MrepxIbtRg3bgk61cJd3Gso
Don't set the account: pi_3MrerSFCRvzb7CqW1ybkWEi0
Sorry, but you said both don't use the setStripeAccount?
You should never use it in your use case.
Yes, I know, the same code support different secenario.
I just want to confirm webhook secret is correct, and the parameter of constructEvent is correct.
But for your connect webhook you should use a different webhook secret
We use our platform webhook, I don't understand, any docs?
There are regular Account Webhooks: https://stripe.com/docs/webhooks
And Connect Webhooks: https://stripe.com/docs/connect/webhooks
And they use different webhooks secrets.
You can see the type and the secret of the webhook in your Dashboard: https://dashboard.stripe.com/test/webhooks
Ok, I will try, thank you very much.
Happy to help. Please, let me know if you have any other questions.