Signing
TL:DR On signing requests
Why we need signing
For some API calls we want to make sure the content tampered with. For instance making a payment, you would not want anyone to be able to change the amount or receiving party. Adding a signature allows bunq to detect whether the request body has been tampered with.
When do you need signing
Any request that creates or accepts a payment. If you forget to sign it we'll tell you with error 466
What is a signature?
A signature is nothing more than a extra header: X-Bunq-Client-Signature that you add to your API call. You'll need to write some code in your application that takes in the request body and your private key (some examples are mentioned below)
When Do You Need to Sign Requests?
Most API calls don’t need signing, but any request that creates or accepts a payment does. If you forget to sign it, you’ll get a 466
error—so keep an eye out for that!
How It Works
You sign the request body (not the whole request).
We verify the signature on our end.
We sign our response, so you can verify it too.
What You Need
A private key (which you generate when installing your API connection).
The public key we send you, which you’ll use to verify our responses.
Example Curl request
This is a payment to Sugardaddy for €0,10. As you can see in the header we added the X-Bunq-Client-Signature header. This is just a Base64 encoded representation of the request body.
curl --location 'https://public-api.sandbox.bunq.com/v1/user/1800297/monetary-account/1989601/payment' \
--header [other headers]' \
--header 'X-Bunq-Client-Signature: eMymd9ynLx+j5tpcoPMlaJ7vEyxIZAXWInXIRxIOyP24KF7lpvNIwElB/wiQqVXr99pua4+onqvJUNiuceInAtohJnSGDEd58GjeBthz2OHTG5I0GZyJ9S8XAuBJYbqPgFaIk2m0VelPmjAHbiA3WSH0ASMDvcht/p4n60Y1GMVESXFovU2jUWX2X2k5QhowitIBJnsf4fkvYknbispFvUTn4ESU8QQVBgwR9QJ8DpxObGYbsTKQCyTzXoKNLM1mkw3pMwHn1EZ+AmOTx5iR/xXZLvvXWDmj9rEZWms7G1+drmhkK5aV8PuvR6s11mS6laRxyS1eoCaOcqeOZs1EcQ==' \
--data-raw '{
"amount": {
"value": "0.10",
"currency": "EUR"
},
"counterparty_alias": {
"type": "EMAIL",
"value": "[email protected]",
"name": "Sugar Daddy"
},
"description": "My payment description :)"
}'
Request signing example
Consider the following request, a POST
to /v1/user/126/monetary-account/222/payment
(the JSON is formatted with newlines and indentations to make it more readable - be careful to account for that when creating your signature):
Cache-Control:
no-cache
User-Agent:
bunq-TestServer/1.00 sandbox/0.17b3
X-Bunq-Client-Authentication:
f15f1bbe1feba25efb00802fa127042b54101c8ec0a524c36464f5bb143d3b8b
{
"amount": {
"value": "12.50",
"currency": "EUR"
},
"counterparty_alias": {
"type": "EMAIL",
"value": "[email protected]"
},
"description": "Payment for drinks."
}
Let's sign that request. First create a variable $dataToSign
containing the body of the request:
{
"amount": {
"value": "12.50",
"currency": "EUR"
},
"counterparty_alias": {
"type": "EMAIL",
"value": "[email protected]"
},
"description": "Payment for drinks."
}
Next, create the signature of $dataToSign
using the SHA256 algorithm and the private key $privateKey
of the Installation's key pair. In PHP, use the following to create a signature. The signature will be passed by reference into $signature
.
openssl_sign($dataToSign, $signature, $privateKey, OPENSSL_ALGO_SHA256);
Encode the resulting $signature
using base64, and add the resulting value to the request under the X-Bunq-Client-Signature
header. You have just signed your request, and can send it!
Troubleshooting
If you struggle with signing you might want to try our SDK's. They handle signing for you
If you are getting error 466 for invalid signatures then it's best to test these things:
Check list:
If you run into issues, double-check these points—or just use our SDKs, which handle all of this for you.
Standards and formats
To ensure secure and valid request and response signatures, you should use the following standards: First, apply SHA256 as the cryptographic hash function to hash the data (either the request body or response body). For the signing process, use the private key with PKCS #1 v1.5 padding for RSA encryption to generate the signature. Once the signature is created, it must be base64-encoded to ensure proper transmission in HTTP headers. This ensures that the integrity and authenticity of the data are preserved, and the signature can be verified by the recipient using the corresponding public key.
Response Signatures
In some cases you might also want to validate whether responses are actually sent by bunq. Here you can do the same thing. If you stored the public key of the bunq server (you received this during installation) you can verify the response sent by bunq and validate that the response body matches the signature.
Last updated
Was this helpful?