Always occurs "invalid_client" error trying to get refresh token by authorisation code

I have an iOS app which implements sign in with Apple.
A private key was generated for this app on developer portal.
For the first our app server receives identity token and authorization code from iOS app. We use firebase/jwt-php library to verify identitty token with keys here. After comlete we have decoded identity token like this:

header:
Code Block JSON
{
"kid": "eXaunmL",
"alg": "RS256"
}

payload:
Code Block JSON
{
"iss": "https://appleid.apple.com",
"aud": "com.mycompany.myapp",
"exp": 1597336478,
"iat": 1597335878,
"sub": "000138.77a8b51895c943dcbe1ae4c34721a4c3.1312",
"nonce": "1597335873132",
"c_hash": "llDP9yFq6YOQEoi4qDzfDA",
"email": "useremail@gmail.com",
"email_verified": "true",
"auth_time": 1597335878,
"nonce_supported": true
}

Also client app send to our app server authorisation code like this:
Code Block language
c6b4d8ec548014979b7b7e0f4d63a173e.0.mrty.2sZAWSjybSC6MU0PQAxaag


And troubles starts...
I try to obtain refresh token by authorisation code and client secret. I don't use firebase/jwt-php library to create client secret because I read about openSSL issues here.
I've converted my .p8 private key to .pem format to use it for sign.

I got a function to generate signed jwt like this:




To convert openSSL sign I use fromDER function from this library:



And finally my call to https://appleid.apple.com/auth/token endpoint looks like this:
Code Block php
$signed_jwt = opensslFix::generateJWT($my_kid, 'myTeamID', $app);
$send_data = [
'client_id' => $app,
'client_secret' => $signed_jwt,
'grant_type' => 'authorization_code',
'code' => $request->code
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://appleid.apple.com/auth/token');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([$send_data]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6');
$serverOutput = curl_exec($ch);

And I always have "invalid_client" answer from the Apple server :(
What else could go wrong?

Always occurs "invalid_client" error trying to get refresh token by authorisation code
 
 
Q