Skip to content

Commit

Permalink
Enhanced finishTransaction method to be more useful (#833)
Browse files Browse the repository at this point in the history
- Resolve #797.
  • Loading branch information
hyochan authored Nov 1, 2019
1 parent a600cce commit aef51e1
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 33 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Changelogs

- **[4.1.0]**
- `finishTransaction` has been renewed by the request in [#797](https://github.com/dooboolab/react-native-iap/issues/797)
- **[4.0.8]**
- Added subs to the list of unconsumed purchases [#807](https://github.com/dooboolab/react-native-iap/pull/807)
- Fixed promise never returned from requestSubscription() [#806](https://github.com/dooboolab/react-native-iap/pull/806)
Expand Down
34 changes: 19 additions & 15 deletions IapExample/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import {
View,
} from 'react-native';
import RNIap, {
Product,
ProductPurchase,
InAppPurchase,
PurchaseError,
SubscriptionPurchase,
acknowledgePurchaseAndroid,
consumePurchaseAndroid,
finishTransaction,
finishTransactionIOS,
purchaseErrorListener,
purchaseUpdatedListener,
} from 'react-native-iap';
Expand Down Expand Up @@ -120,24 +123,25 @@ class Page extends Component {
}

purchaseUpdateSubscription = purchaseUpdatedListener(
async (purchase: ProductPurchase) => {
console.log('purchaseUpdatedListener', purchase);
if (
purchase.purchaseStateAndroid === 1 &&
!purchase.isAcknowledgedAndroid
) {
async (purchase: InAppPurchase | SubscriptionPurchase) => {
const receipt = purchase.transactionReceipt;
if (receipt) {
try {
const ackResult = await acknowledgePurchaseAndroid(
purchase.purchaseToken,
);
console.log('ackResult', ackResult);
// if (Platform.OS === 'ios') {
// finishTransactionIOS(purchase.transactionId);
// } else if (Platform.OS === 'android') {
// // If consumable (can be purchased again)
// consumePurchaseAndroid(purchase.purchaseToken);
// // If not consumable
// acknowledgePurchaseAndroid(purchase.purchaseToken);
// }
const ackResult = await finishTransaction(purchase);
} catch (ackErr) {
console.warn('ackErr', ackErr);
}

this.setState({ receipt }, () => this.goNext());
}
this.setState({ receipt: purchase.transactionReceipt }, () =>
this.goNext(),
);
},
);

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,9 @@ class RootComponent extends Component<*> {
// If not consumable
RNIap.acknowledgePurchaseAndroid(purchase.purchaseToken);
}

// From react-native-iap@4.1.0 you can simplify above `method`. Try to wrap the statement with `try` and `catch` to also grab the `error` message.
RNIap.finishTransaction(purchase);
} else {
// Retry / conclude the purchase is fraudulent, etc...
}
Expand Down
54 changes: 37 additions & 17 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,13 @@ export interface Subscription extends Common {
freeTrialPeriodAndroid?: string;
}

export interface ProductPurchase {
export enum PurchaseStateAndroid {
Purchased = 0,
Canceled = 1,
Pending = 2,
}

interface ProductPurchase {
productId: string;
transactionId?: string;
transactionDate: number;
Expand All @@ -80,7 +86,7 @@ export interface ProductPurchase {
dataAndroid?: string;
signatureAndroid?: string;
autoRenewingAndroid?: boolean;
purchaseStateAndroid?: number;
purchaseStateAndroid?: PurchaseStateAndroid;
originalTransactionDateIOS?: string;
originalTransactionIdentifierIOS?: string;
isAcknowledgedAndroid?: boolean;
Expand Down Expand Up @@ -398,26 +404,36 @@ export const finishTransactionIOS = (transactionId: string): Promise<void> =>
* @returns {Promise<string | void> }
*/
export const finishTransaction = (
transactionId: string,
purchase: InAppPurchase | ProductPurchase,
isConsumable?: boolean,
developerPayloadAndroid?: string,
): Promise<string | void> => {
return Platform.select({
ios: async () => {
checkNativeiOSAvailable();
return RNIapIos.finishTransaction(transactionId);
return RNIapIos.finishTransaction(purchase.transactionId);
},
android: async () => {
if (isConsumable) {
return RNIapModule.consumeProduct(
transactionId,
developerPayloadAndroid,
);
if (purchase) {
if (isConsumable) {
return RNIapModule.consumeProduct(
purchase.purchaseToken,
developerPayloadAndroid,
);
} else if (
!purchase.isAcknowledgedAndroid &&
purchase.purchaseStateAndroid === PurchaseStateAndroid.Purchased
) {
return RNIapModule.acknowledgePurchase(
purchase.purchaseToken,
developerPayloadAndroid,
);
} else {
throw new Error('purchase is not suitable to be purchased');
}
} else {
throw new Error('purchase is not assigned');
}
return RNIapModule.acknowledgePurchase(
transactionId,
developerPayloadAndroid,
);
},
})();
};
Expand Down Expand Up @@ -613,9 +629,11 @@ export const validateReceiptAndroid = async (

/**
* Add IAP purchase event in ios.
* @returns {callback(e: ProductPurchase)}
* @returns {callback(e: InAppPurchase | ProductPurchase)}
*/
export const purchaseUpdatedListener = (e): EmitterSubscription => {
export const purchaseUpdatedListener = (
e: InAppPurchase | ProductPurchase | any,
): EmitterSubscription => {
if (Platform.OS === 'ios') {
checkNativeiOSAvailable();
const myModuleEvt = new NativeEventEmitter(RNIapIos);
Expand All @@ -632,9 +650,11 @@ export const purchaseUpdatedListener = (e): EmitterSubscription => {

/**
* Add IAP purchase error event in ios.
* @returns {callback(e: ProductPurchase)}
* @returns {callback(e: PurchaseError)}
*/
export const purchaseErrorListener = (e): EmitterSubscription => {
export const purchaseErrorListener = (
e: PurchaseError | any,
): EmitterSubscription => {
if (Platform.OS === 'ios') {
checkNativeiOSAvailable();
const myModuleEvt = new NativeEventEmitter(RNIapIos);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-iap",
"version": "4.0.8",
"version": "4.1.0",
"description": "React Native In App Purchase Module.",
"main": "index.js",
"types": "index.d.ts",
Expand Down

0 comments on commit aef51e1

Please sign in to comment.