Last active
May 9, 2018 06:41
-
-
Save scottopolis/5e4afe1b8b4c0c3d64954220e74d2071 to your computer and use it in GitHub Desktop.
Cordova In App Purchase Subscriptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Injectable} from '@angular/core'; | |
import {Device} from '@ionic-native/device'; | |
import {InAppPurchase} from '@ionic-native/in-app-purchase'; | |
import {Storage} from '@ionic/storage'; | |
import {AppAds} from '../appads/appads'; | |
import {Http, Headers, RequestOptions} from '@angular/http'; | |
import 'rxjs/add/operator/map'; | |
import { Events } from 'ionic-angular'; | |
/* | |
In App Purchases | |
This is a provider, you need to add this to your app module then call the methods from somewhere else | |
See http://scottbolinger.com/cordova-in-app-purchases-validating-subscriptions for tutorial | |
Required plugin: http://ionicframework.com/docs/native/in-app-purchase/ | |
Also see https://github.com/AlexDisler/cordova-plugin-inapppurchase | |
*/ | |
@Injectable() | |
export class IAP { | |
productId: string; | |
constructor( | |
private iap: InAppPurchase, | |
public appads: AppAds, | |
public storage: Storage, | |
private http: Http, | |
public events: Events | |
) { | |
} | |
// create the subscription | |
subscribeMembership( id ) { | |
// we have to get products before we can buy | |
this.iap.getProducts( [ id ] ).then( products => { | |
// after we get product, buy it | |
this.iap.subscribe( id ).then( result => { | |
console.log(result) | |
// subscribed! do something... | |
}) | |
.catch( err => { | |
console.log(err) | |
}) | |
}) | |
.catch( err => { | |
console.log(err) | |
}) | |
} | |
// restore in app purchase (required) | |
restoreMembership( id ) { | |
this.productId = id; | |
this.iap.restorePurchases().then( result => { | |
// loop through purchases to find the one we are looking for | |
for (var i = 0; i < result.length; ++i) { | |
// TODO: check result[i].state for cancelled or refunded | |
if( result[i].productId == this.productId ) { | |
console.log( 'Purchase found! Do something...', result ) | |
return; | |
} | |
} | |
}) | |
.catch( err => { | |
console.log(err) | |
}) | |
} | |
// check if membership is still active. Don't call this every app open, it requires iTunes login. | |
checkStatus() { | |
// nested promises, oh my! | |
return new Promise( (resolve, reject) => { | |
// first, ask Apple for the receipt. We get back an encrypted string. | |
this.iap.getReceipt() | |
.then( receipt => { | |
console.log('encoded', receipt) | |
return receipt | |
}) | |
.then( receiptData => { | |
// next, validate the encoded receipt with Apple, and get back the human readable format | |
this.validateReceipt( receiptData ).then( receipt => { | |
console.log('validate receipt response', receipt) | |
// finally, send the receipt to the server and resolve the promise with the result | |
this.sendReceiptToServer(receipt).then( validity => { | |
console.log('validity response', validity) | |
resolve( validity ) | |
}) | |
}) | |
}) | |
.catch( err => { | |
let error = this.getErrMsg( err ); | |
reject( err ) | |
console.log(err) | |
}) | |
}) | |
} | |
validateReceipt( receiptData ) { | |
return new Promise( (resolve ) => { | |
let headers = new Headers({ 'Content-Type': 'application/json' }); | |
let options = new RequestOptions({ headers: headers }); | |
let data = { | |
'password': 'XXXXXXXXXXXXXXXXXXX', // the shared secret key for your in app purchase https://stackoverflow.com/questions/5022296/generate-shared-secret-key-in-itunes-connect-for-in-app-purchase | |
'receipt-data': receiptData | |
} | |
this.http.post( 'https://buy.itunes.apple.com/verifyReceipt', data, options ) | |
.subscribe(response => { | |
let receipt = JSON.parse(response['_body']).receipt | |
resolve(receipt) | |
// purchases can be found at receipt.in_app <Array> | |
// will need to loop through them and get most recent, then work with expiration date | |
}, | |
error => { | |
// probably a bad url or 404 | |
console.log(error); | |
}) | |
}) | |
} | |
sendReceiptToServer( receipt ) { | |
return new Promise( (resolve ) => { | |
console.log( 'sendReceiptToServer', receipt ) | |
let url = 'https://mysite.com/wp-json/app/membership-status' // url to the PHP file or endpoint, see code below | |
let data = { | |
receipt: JSON.stringify( receipt ) | |
} | |
let headers = new Headers({ 'Content-Type': 'application/json' }); | |
let options = new RequestOptions({ headers: headers }); | |
this.http.post( url, data, options ) | |
.subscribe(response => { | |
console.log('server response', response) | |
// This is the end of the road. We resolve with the server response so we know if the subscription is active or not. | |
resolve( response['_body'] ); | |
}, | |
error => { | |
resolve(false) | |
// probably a bad url or 404 | |
console.log(error); | |
}) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
its very awesome