Ho voy a compartir una función que nos permitirá verificar las compras que realicemos en Apple con Apple Store Kit 2 y JWT usando Python.

Lo primero que haremos es crear una función utils que nos permitira validar el jwsRepresentation de la compra de Apple.
Para ello usaremos estas funciones:
import base64
import requests
import jwt
from cryptography.x509 import load_der_x509_certificate
def get_public_key_from_jws(jws_token):
# Decodificar solo el header (sin verificar)
header_b64 = jws_token.split('.')[0]
header_json = base64.urlsafe_b64decode(pad_base64(header_b64))
import json
header = json.loads(header_json)
# Extraer x5c
if "x5c" not in header:
raise ValueError("El JWS no contiene el header x5c")
cert_b64 = header["x5c"][0]
cert_der = base64.b64decode(cert_b64)
cert = load_der_x509_certificate(cert_der)
return cert.public_key()
def verify_jws(jws_token):
try:
public_key = get_public_key_from_jws(jws_token)
payload = jwt.decode(
jws_token,
public_key,
algorithms=["ES256"],
options={"verify_aud": False} # cambiar a True si verificas 'aud'
)
return payload
except jwt.exceptions.InvalidSignatureError:
raise ValueError("Firma inválida")
except jwt.exceptions.ExpiredSignatureError:
raise ValueError("Token expirado")
except Exception as e:
raise ValueError(f"Error verificando JWS: {str(e)}")
def pad_base64(b64_string):
return b64_string + "=" * (-len(b64_string) % 4)
Y la forma de utilizarse es esta:
try:
payload = verify_jws(jwsRepresentation)
print("Compra verificada, payload:")
print(payload)
except ValueError as e:
print("Error:", e)
raise HTTPException(status_code=400, detail=f"Compra no válida Apple: {str(e)}")
Nota: si utilizas Expo IAP, puedes usar
jwsRepresentation
O
purchase.purchaseToken;

Ingeniero en Informática, Investigador, me encanta crear cosas o arreglarlas y darles una nueva vida. Escritor y poeta. Más de 20 APPs publicadas y un libro en Amazon.