Skip to content

Commit

Permalink
feat: add renewal info for Storekit 2
Browse files Browse the repository at this point in the history
  • Loading branch information
cervebar committed Nov 17, 2023
1 parent e294165 commit d6b6233
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 48 deletions.
27 changes: 24 additions & 3 deletions ios/IapSerializationUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func serializeDebug (_ d: Data) -> String? {
#endif
}

func serialize (_ d: Data) -> String? {
return String( decoding: d, as: UTF8.self)
}

func serializeDebug (_ s: String) -> String? {
#if DEBUG
return s
Expand Down Expand Up @@ -75,12 +79,29 @@ func serialize(_ sp: Product.SubscriptionPeriod.Unit?) -> String? {
@available(iOS 15.0, tvOS 15.0, *)
func serialize(_ s: Product.SubscriptionInfo.Status?) -> [String: Any?]? {
guard let s = s else {return nil}
return ["state": serialize( s.state)
// "renewalInfo": serialize(s.renewalInfo),
return ["state": serialize( s.state),
"renewalInfo": serialize(s.renewalInfo),
// "transaction": serialize(s.transaction),
]
}

@available(iOS 15.0, tvOS 15.0, *)
func serialize(_ vri: VerificationResult<Product.SubscriptionInfo.RenewalInfo>?) -> [String: Any?]? {
guard let vri = vri else {return nil}
do {
let ri = try vri.payloadValue
let jsonStringRepresentation = String(data: ri.jsonRepresentation, encoding: .utf8) ?? ""
return [
"jsonRepresentation": jsonStringRepresentation,
"willAutoRenew": ri.willAutoRenew,
"autoRenewPreference": ri.autoRenewPreference
]
} catch {
print("Error in parsing VerificationResult<Product.SubscriptionInfo.RenewalInfo>")
return nil
}
}

@available(iOS 15.0, tvOS 15.0, *)
func serialize(_ rs: Product.SubscriptionInfo.RenewalState?) -> String? {
guard let rs = rs else {return nil}
Expand Down Expand Up @@ -158,7 +179,7 @@ func serialize(_ t: Transaction) -> [String: Any?] {
"environment": environment,
"id": t.id,
"isUpgraded": t.isUpgraded,
"jsonRepresentation": serializeDebug(t.jsonRepresentation),
"jsonRepresentation": serialize(t.jsonRepresentation),
"offerID": t.offerID,
"offerType": serialize(t.offerType),
"originalID": t.originalID,
Expand Down
71 changes: 40 additions & 31 deletions src/types/appleSk2.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {PurchaseError} from '../purchaseError';
import type { PurchaseError } from '../purchaseError';

import type {
ProductIOS,
Expand All @@ -7,7 +7,7 @@ import type {
SubscriptionIosPeriod,
} from '.';
import type * as Apple from './apple';
import {SubscriptionPlatform} from '.';
import { SubscriptionPlatform } from '.';

export type SubscriptionPeriod = {
unit: 'day' | 'week' | 'month' | 'year';
Expand Down Expand Up @@ -47,12 +47,12 @@ export type ProductSk2 = {
type: 'autoRenewable' | 'consumable' | 'nonConsumable' | 'nonRenewable';
};
export const productSk2Map = ({
id,
description,
displayName,
price,
displayPrice,
}: ProductSk2): ProductIOS => {
id,
description,
displayName,
price,
displayPrice,
}: ProductSk2): ProductIOS => {
const prod: ProductIOS = {
title: displayName,
productId: String(id),
Expand All @@ -66,13 +66,13 @@ export const productSk2Map = ({
};

export const subscriptionSk2Map = ({
id,
description,
displayName,
price,
displayPrice,
subscription,
}: ProductSk2): SubscriptionIOS => {
id,
description,
displayName,
price,
displayPrice,
subscription,
}: ProductSk2): SubscriptionIOS => {
const prod: SubscriptionIOS = {
platform: SubscriptionPlatform.ios,
title: displayName,
Expand All @@ -84,7 +84,7 @@ export const subscriptionSk2Map = ({
currency: '', // Not available on new API, use localizedPrice instead
subscriptionPeriodNumberIOS: `${subscription?.subscriptionPeriod?.value}`,
subscriptionPeriodUnitIOS:
subscription?.subscriptionPeriod?.unit.toUpperCase() as SubscriptionIosPeriod,
subscription?.subscriptionPeriod?.unit.toUpperCase() as SubscriptionIosPeriod,
};
return prod;
};
Expand Down Expand Up @@ -128,26 +128,34 @@ export type TransactionEvent = {
};

export type SubscriptionStatus =
| 'expired'
| 'inBillingRetryPeriod'
| 'inGracePeriod'
| 'revoked'
| 'subscribed';
| 'expired'
| 'inBillingRetryPeriod'
| 'inGracePeriod'
| 'revoked'
| 'subscribed';

export type ProductStatus = {
state: SubscriptionStatus;
};

export const transactionSk2ToPurchaseMap = ({
id,
originalPurchaseDate,
productID,
purchaseDate,
purchasedQuantity,
originalID,
verificationResult,
appAccountToken
}: TransactionSk2): Purchase => {
id,
originalPurchaseDate,
productID,
purchaseDate,
purchasedQuantity,
originalID,
verificationResult,
appAccountToken,
jsonRepresentation,
}: TransactionSk2): Purchase => {
let transactionReasonIOS
try {
const transactionData = JSON.parse(jsonRepresentation);
transactionReasonIOS = transactionData.transactionReason;
} catch (e) {
console.log('AppleSK2.ts react-native-iap: Error parsing jsonRepresentation', e);
}
const purchase: Purchase = {
productId: productID,
transactionId: String(id),
Expand All @@ -159,6 +167,7 @@ export const transactionSk2ToPurchaseMap = ({
originalTransactionIdentifierIOS: originalID,
verificationResultIOS: verificationResult ?? '',
appAccountToken: appAccountToken ?? '',
transactionReasonIOS: transactionReasonIOS ?? '',
};
return purchase;
};
Expand Down Expand Up @@ -194,7 +203,7 @@ export interface PaymentDiscountSk2 {
}

export const offerSk2Map = (
offer: Apple.PaymentDiscount | undefined,
offer: Apple.PaymentDiscount | undefined,
): Record<keyof PaymentDiscountSk2, string> | undefined => {
if (!offer) {
return undefined;
Expand Down
34 changes: 20 additions & 14 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type {
AndroidModuleProps,
IosModuleProps,
} from '../modules';
import type {IosModulePropsSk2} from '../modules/iosSk2';
import type { IosModulePropsSk2 } from '../modules/iosSk2';

import type * as Apple from './apple';

Expand Down Expand Up @@ -46,6 +46,11 @@ export enum ProductType {
iap = 'iap',
}

export enum TransactionReason {
PURCHASE = "PURCHASE",
RENEWAL = "RENEWAL"
}

export interface ProductCommon {
type: 'subs' | 'sub' | 'inapp' | 'iap';
productId: string; //iOS
Expand Down Expand Up @@ -102,6 +107,7 @@ export interface SubscriptionPurchase extends ProductPurchase {
originalTransactionDateIOS?: number;
originalTransactionIdentifierIOS?: string;
verificationResultIOS?: string;
transactionReasonIOS?: TransactionReason | string;
}

export type Purchase = ProductPurchase | SubscriptionPurchase;
Expand Down Expand Up @@ -192,10 +198,10 @@ export interface SubscriptionIOS extends ProductCommon {
introductoryPrice?: string;
introductoryPriceAsAmountIOS?: string;
introductoryPricePaymentModeIOS?:
| ''
| 'FREETRIAL'
| 'PAYASYOUGO'
| 'PAYUPFRONT';
| ''
| 'FREETRIAL'
| 'PAYASYOUGO'
| 'PAYUPFRONT';
introductoryPriceNumberOfPeriodsIOS?: string;
introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;

Expand All @@ -204,9 +210,9 @@ export interface SubscriptionIOS extends ProductCommon {
}

export type Subscription =
| SubscriptionAndroid
| SubscriptionAmazon
| SubscriptionIOS;
| SubscriptionAndroid
| SubscriptionAmazon
| SubscriptionIOS;

export interface RequestPurchaseBaseAndroid {
obfuscatedAccountIdAndroid?: string;
Expand All @@ -233,9 +239,9 @@ export interface RequestPurchaseIOS {
export type RequestPurchaseAmazon = RequestPurchaseIOS;

export type RequestPurchase =
| RequestPurchaseAndroid
| RequestPurchaseAmazon
| RequestPurchaseIOS;
| RequestPurchaseAndroid
| RequestPurchaseAmazon
| RequestPurchaseIOS;

/**
* In order to purchase a new subscription, every sku must have a selected offerToken
Expand All @@ -258,9 +264,9 @@ export type RequestSubscriptionIOS = RequestPurchaseIOS;
export type RequestSubscriptionAmazon = RequestSubscriptionIOS;

export type RequestSubscription =
| RequestSubscriptionAndroid
| RequestSubscriptionAmazon
| RequestSubscriptionIOS;
| RequestSubscriptionAndroid
| RequestSubscriptionAmazon
| RequestSubscriptionIOS;

declare module 'react-native' {
interface NativeModulesStatic {
Expand Down

0 comments on commit d6b6233

Please sign in to comment.