因为apple签名优惠算法官方模糊不清,这里直接上一段可以直接签名的代码以java为例,已经验证可以通过apple的优惠内购,希望能帮到你
1、参数准备
| 字段名 | 定义 | 获取方法 |
|---|---|---|
| appBundleID | 应用的包名 | apple后台 |
| keyIdentifier | 密钥标识 | apple后台 |
| productIdentifier | 商品Id | 客户端 |
| offerIdentifier | 促销Id | 客户端 |
| applicationUsername | 自定义参数 | 客户端 |
| nonce | 注意必须是小写 | 服务端生成 |
| timestamp | 时间戳毫秒 | 服务端生成 |
2、组合参数
这里需要注意,苹果官方文档原文必须得加上“\u2063”的空字符按照参数顺序拼接起来
Combine the parameters into a UTF-8 string with an invisible separator ('\u2063') between them, in the order shown in the following code listing.
appBundleId + '\u2063' + keyIdentifier + '\u2063' + productIdentifier + '\u2063' + offerIdentifier + '\u2063' + appAccountToken + '\u2063' + nonce + '\u2063' + timestamp
3、开始签名
这里说下iosPrivateKey是我定义的apple密钥文件解析出来的字符这个需要跟keyIdentifier参数进行配合是一对组合需要在apple后台获取,下面提供一个简单的签名后的demo,其他自行调整
public static Map<String, String> appleSign(AppleSignDTO appleSignDTO) throws Exception {
String timestamp = String.valueOf(System.currentTimeMillis());
String nonce = IdUtil.randomUUID();
String payload = appleSignDTO.getAppBundleID() + "\u2063" +
appleSignDTO.getKeyIdentifier() + "\u2063" +
appleSignDTO.getProductIdentifier() + "\u2063" +
appleSignDTO.getOfferIdentifier() + "\u2063" +
appleSignDTO.getApplicationUsername() + "\u2063" +
nonce + "\u2063" +
timestamp;
String key = iosPrivateKey
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\s+", "");
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(key));
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(privateKey);
signature.update(payload.getBytes(StandardCharsets.UTF_8));
byte[] sign = signature.sign();
Map map = new HashMap();
map.put("sign", Base64.getEncoder().encodeToString(sign));
map.put("nonce", nonce);
map.put("timestamp", timestamp);
map.put("keyIdentifier", "xxxx");
return map;
}