iOS 자동 구독의 문제점 업그레이드 패키지 | | 강등 패키지

8385 단어

거래 절차의 처리


주로 자동 구독 개발은 내부 구매에서 비교적 번거롭고 세부적인 문제가 많으며 많은 문제가 확정되어야 한다.예를 들어 증빙서류의 업로드, 누락 문제 처리, 백그라운드에서 주문서의 유효기간을 어떻게 판단하는지, 주문서의 유형 등을 확보해야 한다.
  • 증명서 업로드, 누락 처리 문제.내부 구매의 전체 절차는 3자, 클라이언트, 애플 서버와 백엔드와 관련되기 때문에 이 3자의 내부 구매 행위를 원자 거래로 만드는 것은 비교적 번거롭다.
  • 일반적인 절차: 애플 서버 요청 -> 거래 성공 리셋 -> 로컬 증명서 얻기 업로드 백엔드 -> 백엔드 검사 (백엔드 원격 애플 서비스 호출) -> 검사 성공 후 리셋 클라이언트 -> 클라이언트 권한 얻기.그중에 몇 가지 발생할 수 있는 문제가 있다.백그라운드에 자격 증명 업로드 실패 2.백그라운드 요청 애플의 실패나 인터넷 등 일련의 원인으로 인해 클라이언트 리셋 실패가 발생했다.내구 절차의 폐쇄를 위해서는 반드시 백그라운드의 리셋 결과를 받아야 완성된다.따라서 1, 2시에 대응하여 증명서를 통해 로컬에 저장한 후에 다시 업로드하여 서버가 리셋될 때까지 결과를 얻을 수 있다.이 점은 많은 글에서 말했지만 세부적인 문제는 말하지 않은 것 같다. 증빙서류는 저장하지 않아도 다시 로컬 증빙서류를 얻을 수 있다. 증빙서류에 모든 거래 기록이 저장되어 있지만 애플 ID를 바꾸면 로컬 증빙서류를 다시 가져와 이전의 거래를 완성할 수 없기 때문이다.따라서 타당하게 말하자면 증명서를 저장하는 동시에 키체인에 저장하여 앱의 마운트 해제로 인한 증명서 분실 문제를 피할 수 있다. (키체인의 용량 문제를 고려하면 수량적으로 제한이 있어야 하고 하나의 대기열을 실현하는 처리가 비교적 좋을 수 있다.)

  • 클라이언트 디버깅


    클라이언트가 서버 측에 협조하는 것은 비교적 번거롭다.클라이언트는 증거를 통해 애플 서버에 정보 검증 영수증을 받을 수 있다.
    문서의 지침:
    - (void)query:(NSString *)receipt {
    # ifdef DEBUG
    //    NSData *receipt; // Sent to the server by the device
        // Create the JSON object that describes the request
        NSError *error;
        NSDictionary *requestContents = @{
        @"receipt-data": receipt,
        @"password" : @"xxxxxxxxxxxxxxxxxxxxxx",// 
        @"exclude-old-transactions":@(YES)
        };
        NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
        options:0
        error:&error];
        if (!requestData) { /* ... Handle error ... */ }
        // Create a POST request with the receipt data.
        NSURL *storeURL = [NSURL
        URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
        NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
        [storeRequest setHTTPMethod:@"POST"];
        [storeRequest setHTTPBody:requestData];
        // Make a connection to the iTunes Store on a background queue.
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        ///NSURLConnection  , api
        [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
                               completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
            if (connectionError) {
                
            } else {
                NSError *error;
                NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
                options:0 error:&error];
                if (!jsonResponse) { /* ... Handle error ...*/ } else {
                    
                }
                /* ... Send a response back to the device ... */
                }
        }];
    # endif
    }
    

    만약 테스트에서만 사용한다면, 접속하기 전에 코드를 차단하는 것을 기억하세요.

    같은 구독 그룹에서 구독 xxx_ 교체2 xxx_로 업그레이드삼


    이 구독을 바꾸면 현재 두 가지 상황을 발견할 수 있습니다. 두 가지 상황은 공통점이 있습니다. 바로pending_renewal_info 필드, 이 필드는 구독의 변경 등 자동 갱신 대기 정보를 기록합니다.
    참조:https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info
  • 같은 구독 그룹 업그레이드 구독pending_renewal_info형예
  •  "pending_renewal_info" =     (
                    {
                "auto_renew_product_id" = "xxxx_3";// 
                "auto_renew_status" = 1;
                "original_transaction_id" = 1000000xxxxxx;
                "product_id" = "xxx_2";// 
            }
        );
    

    저렴한 구독에서 비싼 구독으로 업그레이드합니다. 다음 구독은 현재 구독이 끝나야 구체적으로 변경됩니다.그래서 만약 이때 마지막 거래 정보를 얻게 된다면, 대응하는 제품_id는 여전히 현재입니다. 예를 들어 "product_id"= "xx_2"입니다.이 때 마지막 기록은
    "latest_receipt_info" =     (
                    {
                "expires_date" = "2020-03-26 03:43:20 Etc/GMT";
                "expires_date_ms" = 1585194200000;
                "expires_date_pst" = "2020-03-25 20:43:20 America/Los_Angeles";
                "is_in_intro_offer_period" = false;
                "is_trial_period" = false;
                "original_purchase_date" = "2020-03-26 02:54:07 Etc/GMT";
                "original_purchase_date_ms" = 1585191247000;
                "original_purchase_date_pst" = "2020-03-25 19:54:07 America/Los_Angeles";
                "original_transaction_id" = 1000000643447076;
                "product_id" = "xxx_2";
                "purchase_date" = "2020-03-26 03:28:20 Etc/GMT";
                "purchase_date_ms" = 1585193300000;
                "purchase_date_pst" = "2020-03-25 20:28:20 America/Los_Angeles";
                quantity = 1;
            .... 
            }
        );
    

    현재 제품의 효력 여부만 판단하면 latest_receipt_info -> expires_date_ms면 됩니다.
    ............그리고 어느 날 만기가 되면 목표 구독으로 변경됩니다. 이때 자동 갱신을 받고 정보를 얻습니다.latest_receipt_info 및 pending_renewal_info는 다음과 같이 변경됩니다.
    /// auto_renew_product_id    product_id    。
     "pending_renewal_info" =     (
                    {
                "auto_renew_product_id" = "xxx_3";
                "auto_renew_status" = 1;
                "original_transaction_id" = 1000000643xxxx;
                "product_id" = "xxx_3";
            }
        );
        
        // , 
          "latest_receipt_info" =     (
                    {
                "expires_date" = "2020-03-26 04:43:20 Etc/GMT";
                "expires_date_ms" = 1585197800000;
                "expires_date_pst" = "2020-03-25 21:43:20 America/Los_Angeles";
                "is_in_intro_offer_period" = false;
                "is_trial_period" = false;
                "original_purchase_date" = "2020-03-26 02:54:07 Etc/GMT";
                "original_purchase_date_ms" = 1585191247000;
                "original_purchase_date_pst" = "2020-03-25 19:54:07 America/Los_Angeles";
                "original_transaction_id" = 1000000643447076;
                "product_id" = "xxx_3";
                "purchase_date" = "2020-03-26 03:43:20 Etc/GMT";
                "purchase_date_ms" = 1585194200000;
                "purchase_date_pst" = "2020-03-25 20:43:20 America/Los_Angeles";
                quantity = 1;
              .... 
            }
        );
    
    

    이런 방식은 애플의 내부 구매 알림에 따라 모두 일치한다. "현재 xxx 구독이 만료되면 새로운 구독 비용을 지불한다."당장 돈을 보충하는 것도 아니고 바로 전환하는 것도 아니라 다음에 구독을 변경하는 동시에 비용을 변경한다는 뜻이다.
  • 같은 구독 그룹 강등 패키지 xx_3 xxx로 다운그레이드_2 강등 구독은 업그레이드 구독과 달리 즉시 효력이 발생하고 일정한 계산 방식에 따라 환불됩니다(미사용 시간에 따라 환산할 수 있음). 이런 뜻은 이 강등 구독이 즉시 기록을 생성하고pending_renewal_info 안에 있는 product_id 및 auto_renew_product_id가 일치합니다.구체적으로 다음과 같다.
  • "latest_receipt_info" =     (
                    {
                "expires_date" = "2020-03-26 04:23:23 Etc/GMT";
                "expires_date_ms" = 1585196603000;
                "expires_date_pst" = "2020-03-25 21:23:23 America/Los_Angeles";
                "is_in_intro_offer_period" = false;
                "is_trial_period" = false;
                "original_purchase_date" = "2020-03-26 02:54:07 Etc/GMT";
                "original_purchase_date_ms" = 1585191247000;
                "original_purchase_date_pst" = "2020-03-25 19:54:07 America/Los_Angeles";
                "original_transaction_id" = 1000000643447076;
                "product_id" = "xxx_2";
                "purchase_date" = "2020-03-26 04:08:23 Etc/GMT";
                "purchase_date_ms" = 1585195703000;
                "purchase_date_pst" = "2020-03-25 21:08:23 America/Los_Angeles";
                quantity = 1;
             ...... 
            }
        );
        "pending_renewal_info" =     (
                    {
                "auto_renew_product_id" = "xxx_2";
                "auto_renew_status" = 1;
                "original_transaction_id" = 100000064344xxxx;
                "product_id" = "xxxx_2";
            }
        );
    

    이 과정에서 이런 의혹이 있을 수 있기 때문에 구독을 업그레이드하는데 왜 새로운 기록이 나오지 않습니까?그리고 latest_receipt_info의 기록은 오래된 production_id, 이해하기 어렵다. 실제로 변화하는 과정은 위와 같다.이 기록은 정확합니다. 또한 기록이 효력이 발생하면 expires_date_ms 만료 시간도 정확합니다.
    그래서 구독 효력이 확정된 상황에서 latest_receipt_info의 데이터로 기한이 지났는지 계산하면 됩니다.
    이상 설명, 테스트 개발 중의 분석 공유, 참고만 제공, 반드시 정확하지 않습니다!!!
    참조 링크: 공식 필드 설명 중국어 문서 참조

    좋은 웹페이지 즐겨찾기