google play 支付签名验证

编辑于 2022-07-12 15:13:44 阅读 1771

app端支付成功会有一个Purchase对象,里面有购买令牌(purchaseToken)和其他参数,如下

JSONObject jsonObject=new JSONObject();
try {
    jsonObject.put("packageName", purchase.getPackageName());
    jsonObject.put("purchaseToken", purchase.getPurchaseToken());
    jsonObject.put("signature", purchase.getSignature());
    jsonObject.put("purchaseTime", purchase.getPurchaseTime());
    jsonObject.put("purchaseState", purchase.getPurchaseState());
    jsonObject.put("developerPayload", purchase.getDeveloperPayload());
//  jsonObject.put("accountIdentifiers", purchase.getAccountIdentifiers());
    jsonObject.put("orderId", purchase.getOrderId());
    jsonObject.put("originalJson", purchase.getOriginalJson());
    jsonObject.put("products", StringUtils.join(purchase.getProducts(), ","));
    jsonObject.put("quantity", purchase.getQuantity());
    jsonObject.put("isAutoRenewing", purchase.isAutoRenewing());
    jsonObject.put("isAcknowledged", purchase.isAcknowledged());
    Log.e("TAG", jsonObject.toString());
} catch (JSONException e) {
    e.printStackTrace();
}

得到的json,如下

{
	"packageName": "net.cuiwei.voice",
	"purchaseToken": "mjnmdjeccbcmeagmnfieahnd.AO-J1Oza5K7ZQVA。。",
	"signature": "BjEqq1T4NYMlIC\/SXXNgtX2UQRBh0kN。。",
	"purchaseTime": 1657271487378,
	"purchaseState": 1,
	"developerPayload": "",
	"orderId": "GPA.3349-0595-6867-76089",
	"originalJson": "{\"orderId\":\"GPA.3349-0595-6867-76089\",\"packageName\":\"net.cuiwei.voice\",\"productId\":\"voice_0\",\"purchaseTime\":1657271487378,\"purchaseState\":0,\"purchaseToken\":\"mjnmdjeccbcmeagmnfieahnd.AO-J1Oza5K7ZQVA。。",\"quantity\":1,\"acknowledged\":false}",
	"products": "voice_0",
	"quantity": 1,
	"isAutoRenewing": false,
	"isAcknowledged": false
}

建议这些参数都上传给服务器。

作为服务端,我们知道客户端传过来的数据是可以伪造的,那么我们需要有一个验证签名的步骤

验证签名

验证签名需要三个参数

  • originalJson
  • signature
  • google公钥

WX202207081646222x.jpg

如上图可以取得Google公钥

下面是PHP代码

echo googlePayVerify('original_json...', 'signature...', 'google_public_key...').PHP_EOL;

/**
 * 谷歌支付签名验证
 * @param string $original_json
 * @param string $signature
 * @param string $google_public_key
 * @return bool
 */
function googlePayVerify(string $original_json, string $signature, string $google_public_key):bool {
    $public_key_handle = openssl_pkey_get_public($google_public_key);
    if($public_key_handle===false){
        $public_key = "-----BEGIN PUBLIC KEY-----" . PHP_EOL .
            chunk_split($google_public_key, 64, PHP_EOL) .
            "-----END PUBLIC KEY-----";
        $public_key_handle = openssl_pkey_get_public($public_key);
        if($public_key_handle===false) return false;
    }
    $result = openssl_verify($original_json, base64_decode($signature), $public_key_handle, OPENSSL_ALGO_SHA1);
    openssl_free_key($public_key_handle);
    return $result;
}

Google Play Developer API

验证完签名,如果觉得不够,还可以通过Google Play Developer API查询购买详情,里面有购买状态,是否消耗,是否确认等更多信息,详见:http://www.cuiwei.net/p/1370199631/

广而告之,我的新作品《语音助手》上架Google Play了,欢迎下载体验