jophenna avatar image
jophenna asked

Digital Signatures for APIs - Steps to Completion


I'm hoping that somebody may be able to help us with this.

We clearly have an issue as we're getting 215120 - 'Signature validation failed' for every request we are making. It feels like we've tried every combination of tweak. I'm hoping that if I post our steps below someone who's successfully integrated may be able to spot our issue.

FYI - We're using PHP and cURL.

Initially,. we're requesting our keyset using the following call:

$connection = curl_init();

curl_setopt($connection, CURLOPT_URL, $this->API_URL_Z_VERSION . "/developer/key_management/v1/signing_key");

curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, 0);

curl_setopt($connection, CURLOPT_SSL_VERIFYHOST, 0);

curl_setopt($connection, CURLOPT_CONNECTTIMEOUT, 0);

curl_setopt($connection, CURLOPT_TIMEOUT, 1200);

curl_setopt($connection, CURLOPT_HTTPHEADER,

array (

'Authorization: Bearer ' . $this->oauth_user_access_token,

'Content-Type: application/json',



curl_setopt($connection, CURLOPT_POST, 1);

curl_setopt($connection, CURLOPT_POSTFIELDS, '{"signingKeyCipher" : "RSA"}');

curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($connection);

This works successfully and we receive our public key, private key and JWE.

We're then calling 'issue_refund' with the following code:

// Build the path

$path = "/sell/fulfillment/v1/order/" . $order_id . "/issue_refund";

// The POST data

$data_arr = [ 'reasonForRefund' => $reason_for_refund, orderLevelRefundAmount' => [ 'value' => $refund_value, 'currency' => $currency] ];

// Start building the new required headers

$extra_security_headers = [

'x-ebay-signature-key: ' . $this->extra_security_jwe,

'x-ebay-enforce-signature: true'


// json encode post data, then ensure our string is UTF-8 encoded

$string_to_digest = json_encode($data_arr);

if (!mb_check_encoding($string_to_digest, 'UTF-8')) {

$string_to_digest = mb_convert_encoding($string_to_digest, 'UTF-8');


// content digest header

$contentDigest = hash( 'sha256', $string_to_digest, true );

$extra_security_headers[] = 'Content-Digest: sha-256=:' . base64_encode($contentDigest) . ':';

// signature-input header

$signature_input_txt = '( "content-digest" "x-ebay-signature-key" "@method" "@path" "@authority");created=' . time();

$extra_security_headers[] = "Signature-Input: sig1=" . $signature_input_txt;

// generate signature base ready for signing

$signature_base = '"content-digest": sha-256=:' . base64_encode($contentDigest) . ":\n";

$signature_base .= '"x-ebay-signature-key": ' . $this->extra_security_jwe . "\n";

$signature_base .= '"@method": POST' . "\n";

$signature_base .= '"@path": ' . $path . "\n";

$signature_base .= '"@authority": ' . "" . "\n";

$signature_base .= '"@signature-params": ' . $signature_input_txt . "";

// ensure signature_base is UTF-8

if (!mb_check_encoding($signature_base, 'UTF-8')) {

$signature_base = mb_convert_encoding($signature_base, 'UTF-8');


// base 64 encode our signature_base

$signature_base_base64_encoded = base64_encode( $signature_base );

// format the private key as required

$formatted_private_key = "-----BEGIN RSA PRIVATE KEY-----".PHP_EOL . $this->extra_security_priv_key . PHP_EOL."-----END RSA PRIVATE KEY-----";

// sign
openssl_sign( $signature_base_base64_encoded, $signed_signature, $formatted_private_key, "sha256WithRSAEncryption");

// add the signature header to the array

$extra_security_headers[] = 'Signature: ' . base64_encode($signed_signature);

.... cURL call here ...

It would be amazing if anybody is able to spot a logic error or point us in the right direction as to where our issue may lie.

Thanks for any assistance!

digital signatures for apis
10 |600

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

yolooffers avatar image
yolooffers answered

This is the closest thing to a working example I've found, but it does not quite work !
Did you ever manage to get this working? I've been at this for days.

· 7
10 |600

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jophenna avatar image jophenna commented ·

Unfortunately we're not quite there yet. We've in the belief that we've tried everything but theres obviously something missing.

Our eBay account manager reached out to us to see how we're getting on and we've relayed that we're struggling so we're being put in touch with an integration team who will point us in the right direction. I'll post any updates here.

0 Likes 0 ·
yolooffers avatar image yolooffers jophenna commented ·

Thank you very much !

Quick question, are you getting a similar error :
"errorId":32100,"domain":"API_FULFILLMENT" ?
Invalid Order Id

Im trying to call the "sell/fulfillment/v1/order/{orderId}" endpoint, my code is working 100% for US website, and now it's broken for the UK version because of signing. Yet the message indicates I have the wrong order id which is impossible, Im not getting any validation on the actual "digital signatures" part... are you ?

0 Likes 0 ·
jophenna avatar image jophenna yolooffers commented ·

No problem at all. No, we've not seen that error message (yet!). We're constantly seeing "215120 Signature validation failed".

However we've just been issued some guidance from the eBay dev team, which we're due to look into tomorrow morning in detail (I'm in GMT timezone). I suspect that we will be able to get it working successfully with this extra assistance. When I get a fully working code sample I'll post it here :)

0 Likes 0 ·
Show more comments

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.