iOS 자동 구독의 문제점 업그레이드 패키지 | | 강등 패키지
거래 절차의 처리
주로 자동 구독 개발은 내부 구매에서 비교적 번거롭고 세부적인 문제가 많으며 많은 문제가 확정되어야 한다.예를 들어 증빙서류의 업로드, 누락 문제 처리, 백그라운드에서 주문서의 유효기간을 어떻게 판단하는지, 주문서의 유형 등을 확보해야 한다.
클라이언트 디버깅
클라이언트가 서버 측에 협조하는 것은 비교적 번거롭다.클라이언트는 증거를 통해 애플 서버에 정보 검증 영수증을 받을 수 있다.
문서의 지침:
- (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" = (
{
"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 구독이 만료되면 새로운 구독 비용을 지불한다."당장 돈을 보충하는 것도 아니고 바로 전환하는 것도 아니라 다음에 구독을 변경하는 동시에 비용을 변경한다는 뜻이다.
"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의 데이터로 기한이 지났는지 계산하면 됩니다.
이상 설명, 테스트 개발 중의 분석 공유, 참고만 제공, 반드시 정확하지 않습니다!!!
참조 링크: 공식 필드 설명 중국어 문서 참조
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.