I'm trying to integrate Google Pay in Direct Integration mode. I'm having trouble decrypting the payment data once received.
public static String decryptGooglePayTokenWithTink(
String encryptedMessage,
String privateKeyBase64,
String merchantId,
boolean isTestEnvironment
) throws Exception {
// Per Google documentation:
// - For TEST: Use "merchant:[MERCHANT ID]" format
// - For PRODUCTION: Use "merchant:[MERCHANT ID]" format
// If merchant ID is not configured, use empty string
String recipientId = (merchantId != null && !merchantId.trim().isEmpty())
? "merchant:" + merchantId
: "";
try {
// Build recipient using Tink library exactly as per Google documentation
PaymentMethodTokenRecipient.Builder builder = new PaymentMethodTokenRecipient.Builder();
// Use appropriate Google signing keys manager based on environment
// Keys are prefetched at startup for performance
if (isTestEnvironment) {
builder.fetchSenderVerifyingKeysWith(GooglePaymentsPublicKeysManager.INSTANCE_TEST);
} else {
builder.fetchSenderVerifyingKeysWith(GooglePaymentsPublicKeysManager.INSTANCE_PRODUCTION);
}
// Set recipient ID per Google documentation: "merchant:[MERCHANT ID]"
builder.recipientId(recipientId);
// Set protocol version (ECv2 only)
builder.protocolVersion("ECv2");
// Add private key as Base64-encoded PKCS8 string
// Can add multiple keys for graceful key rotation
builder.addRecipientPrivateKey(privateKeyBase64);
// Build and unseal (decrypt and verify signatures)
PaymentMethodTokenRecipient recipient = builder.build();
return recipient.unseal(encryptedMessage);
} catch (Exception e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
}
This fails. I have added my Public Key on https://pay.google.com/ under the Direct Integration. And I'm trying on TEST mode. The unseal method throws an error.
Error Log:
Caused by: javax.crypto.AEADBadTagException: Tag mismatch! at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMDecrypt.doFinal(GaloisCounterMode.java:1395) at java.base/com.sun.crypto.provider.GaloisCounterMode.engineDoFinal(GaloisCounterMode.java:406) at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2205) at io.apptizer.payments.util.GooglePayECv2Util.decryptGooglePayPayload(GooglePayECv2Util.java:231) ... 73 common frames omitted
What could be causing the issue?
Edit: On the Google Pay Console, my added Public Key is on "Inactive" status. I don't see any option to bring it to Active status.