java苹果通知V2新版协议实现订阅退款

1.需要在苹果后台配置通知地址,选v2版本协议

2.相关地址

用来解析调试接收到的signedPayload

JSON Web Tokens - jwt.io

新版通知协议地址 responseBodyV2DecodedPayload​​​​​​https://developer.apple.com/documentation/appstoreservernotifications/responsebodyv2decodedpayload

3.上代码

pom引用,用来解析苹果的jws数据

        
            io.jsonwebtoken
            jjwt
            0.9.1
        

工具类

@Component
public class JwsUtil {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    public Jws verifyJWT(String x5c, String jws){
        try {
            X509Certificate cert = getCert(x5c);
            if (!cert.getSubjectDN().getName().contains("Apple Inc")){
                logger.info("not apple cert . name = {}", cert.getIssuerX500Principal().getName());
                return null;
            }
            return Jwts.parser().setSigningKey(cert.getPublicKey()).parseClaimsJws(jws);
        }catch (JwtException exc){
            logger.info("jws verify failure.", exc);
            return null;
        } catch (Exception exc){
            logger.info("jws verify error.", exc);
            return null;
        }
    }

    public static X509Certificate getCert(String x5c) throws CertificateException {
        String stripped = x5c.replaceAll("-----BEGIN (.*)-----", "");
        stripped = stripped.replaceAll("-----END (.*)----", "");
        stripped = stripped.replaceAll("\r\n", "");
        stripped = stripped.replaceAll("\n", "");
        stripped.trim();
        byte[] keyBytes = Base64.getDecoder().decode(stripped);
        CertificateFactory fact = CertificateFactory.getInstance("X.509");
        return (X509Certificate) fact.generateCertificate(new ByteArrayInputStream(keyBytes));
    }
}

接收参数实体类

@Data
public class RefundIosDto {
   
    private String signedPayload;
}

接口代码

@PostMapping("/notification")
    public BaseResponse notification(@RequestBody RefundIosDto refundIosDto) {
        //记录每次的苹果通知请求
        AppleNotificationInfo appleNotificationInfo=new AppleNotificationInfo();
        appleNotificationInfo.setCreatetime(new Date());
        appleNotificationInfo.setContent(refundIosDto.getSignedPayload());

        appleNotificationService.insert(appleNotificationInfo);
        //解析苹果请求的数据
        String signedPayload=new String(com.google.api.client.util.Base64.decodeBase64(refundIosDto.getSignedPayload().split("\\.")[0]));
//        String result2=java.util.Base64.getUrlDecoder().decode(refundIosDto.getSignedPayload()).toString();
        JSONObject jsonObject=JSONObject.parseObject(signedPayload);
        ;
        Jws result=jwsUtil.verifyJWT(jsonObject.getJSONArray("x5c").get(0).toString(),refundIosDto.getSignedPayload());
        System.out.println(result.toString());

        String notificationType=result.getBody().get("notificationType").toString();
        Claims map=result.getBody();
        HashMap envmap=map.get("data",HashMap.class);
        String env=envmap.get("environment").toString();
        String resulttran=new String(com.google.api.client.util.Base64.decodeBase64(envmap.get("signedTransactionInfo").toString().split("\\.")[0]));
        JSONObject jsonObjecttran=JSONObject.parseObject(resulttran);

        Jws result3=jwsUtil.verifyJWT(jsonObjecttran.getJSONArray("x5c").get(0).toString(),envmap.get("signedTransactionInfo").toString());
        System.out.println(result3.getBody().toString());
//        HashMap orderMap=result3.getBody().("data",HashMap.class);
        logger.info("苹果通知类型:"+notificationType+"环境:"+env);

            if(notificationType.equals("DID_RENEW")) {
//查找原始订单的memberuid

//                VipOrder vipOrderinsert=new VipOrder();


                String transactionId = result3.getBody().get("transactionId").toString();
                String productId = result3.getBody().get("productId").toString();
                String originalTransactionId = result3.getBody().get("originalTransactionId").toString();
                VipOrder vipOrder = vipOrdrService.getOne(originalTransactionId, productId, "ios");
                if (Objects.nonNull(vipOrder)&&StringUtils.isNotBlank(productId) && StringUtils.isNotBlank(transactionId)) {//判重,避免重复分发内购商品。

                    //逻辑代码

                }
            }
            else if(notificationType.equals("REFUND")) {

                String originalTransactionId= result3.getBody().get("originalTransactionId").toString();
                String productId = result3.getBody().get("productId").toString();
               //逻辑代码
            }
            else {
                logger.info("notificationType未处理:" + notificationType);
            }


//        result.toLowerCase();
        return ReturnResponseUtil.Success(ReturnResponseUtil.SUCCESS, "success");

    }

你可能感兴趣的:(apple,大数据,java,后端)