[Huawei Developers] Mayism:
PHP — Signature Verification for HUAWEI IAP

Background

If you integrate the HMS SDK 3.x, and after a successful purchase, you can obtain the purchase data InAppPurchaseData and its signature data from the PurchaseResultInfo object. You need to use the public key allocated by AppGallery Connect to verify the signature.

For details, check this document:

https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/dev-guide-0000001050130254#EN-US_TOPIC_0000001050130254__section183174113342

Code Development

I wrote the sample code to verify the obtained purchase data, its signature and the public key for your reference. Hope it can help you with problem locating.

Sample code:

<?php
// Actual payment callback result. Copy the original data without any processing.
// Here, I replaced some personal information with xxxx.

$content = '{"autoRenewing":false,"orderId":"201912250949586652ebf220c1.10xxxx75","packageName":"com.example.xxxxxxexample_netease.huawei","applicationId":10xxxx75,"kind":0,"productId":"3","productName":"test33333","purchaseTime":1577238608000,"purchaseTimeMillis":1577238608000,"purchaseState":0,"developerPayload":"09815772385983110000000191996123","purchaseToken":"0000016f3abf3a78a4ef7b217523ea5a346825ab632c152b864c2e5251433c9d599c5986ab8c89b1.1.10xxxx75","consumptionState":0,"acknowledged":0,"currency":"CNY","price":100,"country":"CN","payOrderId":"Aed0f1fbd9929f803d9d23b523b14575","payType":"4"}';
// The sign value must be the original value in the callback. Do not urlencode or urldecode the value.

$sign = 'IuCnJI3bCDr92uomUbxamp6VeC8vN+o3GTtB7aVwTGpkk9QgeR9KdUjDya1tJXKX8HZgTTLpj7v4A1lP8xrOq3+knykn32Tup6STnn4qpee8J3sS9kjpIHmhIbh3QfnsHksCaT4ib9BurIWnH7yEtNlwqmOOibJw8FgFXofrfPsDwjuCy4/X9rlbimjmyAiFZLXCTNQoGollqUVEjqabhjh/a+VY89A6Z02F2bJkes39a7lQMer42egha86w65L3UYYSLOyxQPIfIZ1BG5yirZN4JgcD17CMk+vQvtVDXhC+e4xN//txWlG/qIgviZbmhLFGjA/gfP0o8LpY7booiA==';
// The payment public key type needs to be RSA. A link break is added to every 64 characters in the intermediate content.

$pubKey = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq7iOD9qLMxMCEsY+l+IE
6kdI9HKHQoDG29ebPZFD+U1pdDewmkEcQzv/k0NmE9oeNIcxUqhg7ZwRrQ0g9xje
BCkiLTg4DOygOPOcZykuKZXDv/9aFn6FR5BVCrrOzmeR+/aEYcZZp86iWX+W4BdJ
L41i8qYonVRD6sDNuidAdg0UkNMPVRiHd5EYBgRHpPma7oeRVqfX4Iq/rL4DFOpu
uLiaLKmWSMOCLnIH+EXjjw3ttJOrB4Rq2fq6KrORgc8JMq2TPf/kK6r8NW9eWRWa
zmFvAZ8bUA7Idu4W8Z4SENwEO+ZeyWQx5I/piYEmBvmn3dy2l2bP3cZMUBVACkAE
jwIDAQAB

-----END PUBLIC KEY-----';

$openssl_public_key = @openssl_get_publickey($pubKey);
// Whether to use the SHA-256 algorithm depends on the value of signType in the callback result. Add the following code when signType is set to RSA256. In other situations, the signature algorithm needs to be SHA1.

$ok = @openssl_verify($content, base64_decode($sign), $openssl_public_key,'SHA256');
@openssl_free_key($openssl_public_key);
$result = "";
if($ok)
{
$result = "0";// success
}
else
{
$result = "1";// failure
}
$res = "{ \"result\": $result} ";
echo $res;
?>

Running the Code

Search for an online code runner that supports PHP. For example:

https://tool.lu/en_US/coderunner/

If the value 0 is returned, everything is normal.