I have linked up an in-app purchase (a non_consumable) and I received a "Payment Successful" with a "how often would you like to confirm your password for purchase" alert box.
However, after the success, I received this error messages. Am I receiving these messages because I'm testing it in Alpha with test accounts? Can't seem to find documentation for these 2 errors.
Store Error {"code": 6777017,"message":" Purchase Failed: Error Purchasing: labResult: Signature verification Failed for sku com.app.Jumphop.quiz (response:6777017: Error)"}
Store Error {"code":7,"message":" Purchase failed: Error Purchasing: labResult: Unable to buy item (response: 7:Error)"}
EDIT: I'm using this code base https://github.com/thielCole/ionic-iap2 .... Here is the code the IAP is handling...
export class AboutPage implements OnInit {
public product: any = {
name: 'My Product',
appleProductId: '1234',
googleProductId: 'com.38plank.spartan_one'
};
constructor(public navCtrl: NavController,
private store: InAppPurchase2,
public platform: Platform) {
}
ngOnInit() {
this.configurePurchasing();
}
configurePurchasing() {
if (!this.platform.is('cordova')) { return; }
let productId;
try {
if (this.platform.is('ios')) {
productId = this.product.appleProductId;
} else if (this.platform.is('android')) {
productId = this.product.googleProductId;
}
// Register Product
// Set Debug High
this.store.verbosity = this.store.DEBUG;
// Register the product with the store
this.store.register({
id: productId,
alias: productId,
type: this.store.NON_RENEWING_SUBSCRIPTION
});
this.registerHandlers(productId);
this.store.ready().then((status) => {
console.log(JSON.stringify(this.store.get(productId)));
console.log('Store is Ready: ' + JSON.stringify(status));
console.log('Products: ' + JSON.stringify(this.store.products));
});
// Errors On The Specific Product
this.store.when(productId).error( (error) => {
alert('An Error Occured' + JSON.stringify(error));
});
// Refresh Always
console.log('Refresh Store');
this.store.refresh();
} catch (err) {
console.log('Error On Store Issues' + JSON.stringify(err));
}
}
registerHandlers(productId) {
// Handlers
this.store.when(productId).approved( (product: IAPProduct) => {
// Purchase was approved
product.finish();
});
this.store.when(productId).registered( (product: IAPProduct) => {
console.log('Registered: ' + JSON.stringify(product));
});
this.store.when(productId).updated( (product: IAPProduct) => {
console.log('Loaded' + JSON.stringify(product));
});
this.store.when(productId).cancelled( (product) => {
alert('Purchase was Cancelled');
});
// Overall Store Error
this.store.error( (err) => {
alert('Store Error ' + JSON.stringify(err));
});
}
async purchase() {
/* Only configuring purchase when you want to buy, because when you configure a purchase
It prompts the user to input their apple id info on config which is annoying */
if (!this.platform.is('cordova')) { return };
let productId;
if (this.platform.is('ios')) {
productId = this.product.appleProductId;
} else if (this.platform.is('android')) {
productId = this.product.googleProductId;
}
console.log('Products: ' + JSON.stringify(this.store.products));
console.log('Ordering From Store: ' + productId);
try {
let product = this.store.get(productId);
console.log('Product Info: ' + JSON.stringify(product));
let order = await this.store.order(productId);
alert('Finished Purchase');
} catch (err) {
console.log('Error Ordering ' + JSON.stringify(err));
}
}
Related
I was using tipsi-stripe library but now i migrated it to #stripe/stripe-react-native library but i am unable to create token and get country name from card , please let me know how to implement it ,Thanks in advance.
------------------ Tipsi-stripe Code ----------------
import stripe, { PaymentCardTextField, } from 'tipsi-stripe'
stripe
.paymentRequestWithCardForm()
.then(stripeTokenInfo => {
this.state.loading = true
console.log('Token created', { stripeTokenInfo });
-------------- New Code without Create token ---------------------
import { CardField, useStripe ,confirmPayment, loading} from '#stripe/stripe-react-native';
export default class CheckoutSignin extends Component {
state = {
TotalAmount:null,
clientSecret:null
}
componentDidMount(){
console.log("Total Amount : " + this.props.route.params.TotalAmount);
this.state.TotalAmount = this.props.route.params.TotalAmount;
this.setState(this.state)
}
fetchPaymentIntentClientSecret = async () => {
makePayment(100,"AUD").then(r => {
if(r.Status === "Success"){
this.state.clientSecret = r.ClientSecret;
this.setState(this.state)
// alert("Payment Indent Success");
// console.log("1===> "+ clientSecret);
this.handlePayPress();
// console.log("3===> "+ clientSecret);
}
else {
alert("Payment Indent Failed.");
}
}).catch(e => {
alert(e)
})
};
handlePayPress = async () => {
const {paymentIntent, error} = await confirmPayment(this.state.clientSecret, {
paymentMethodType: 'Card',
paymentMethodData: {
// email: _userInfo.email,
},
});
if (error) {
console.log('Payment confirmation error', error);
Alert.alert("Error","Payment confirmation error", error);
} else if (paymentIntent) {
console.log('Success from promise', paymentIntent);
// Alert.alert("Success","Succeed Payment with 3ds");
this.props.navigation.navigate("Thankyou")
}
}
}
I have installed the plugin implemented the code.. Uploaded the signed apk as Internal tester but when I click the purchase button nothing happens.. Can anyone tell me where am I going wrong
import { Component, OnInit } from '#angular/core';
import { NewTransactionPage } from '../instamojo/new_transaction';
import { IonicPage, Platform, NavController, NavParams } from 'ionic-angular';
import { InAppPurchase2, IAPProduct } from '#ionic-native/in-app-purchase-2/ngx';
#IonicPage()
#Component({
selector: 'page-pay',
templateUrl: 'pay.html',
})
export class PayPage {
public product: any = {
name: 'Upgrade to Pro',
appleProductId: 'android.test.purchased',
googleProductId: 'ultimate'
};
constructor(
public navCtrl: NavController,
public navParams: NavParams,
public platform: Platform,
public store: InAppPurchase2
) {
platform.ready().then(() => {
this.configurePurchasing();
});
}
configurePurchasing() {
if (!this.platform.is('cordova')) { return; }
let productId;
try {
if (this.platform.is('ios')) {
productId = this.product.appleProductId;
} else if (this.platform.is('android')) {
productId = this.product.googleProductId;
}
// Register Product
// Set Debug High
this.store.verbosity = this.store.DEBUG;
// Register the product with the store
this.store.register({
id: productId,
alias: productId,
type: this.store.NON_CONSUMABLE
});
this.registerHandlers(productId);
InAppPurchase2.getPlugin().ready().then((status) => {
console.log(JSON.stringify(this.store.get(productId)));
console.log('Store is Ready: ' + JSON.stringify(status));
console.log('Products: ' + JSON.stringify(this.store.products));
});
// Errors On The Specific Product
this.store.when(productId).error( (error) => {
alert('An Error Occured' + JSON.stringify(error));
});
// Refresh Always
console.log('Refresh Store');
this.store.refresh();
} catch (err) {
console.log('Error On Store Issues' + JSON.stringify(err));
}
}
registerHandlers(productId) {
// Handlers
this.store.when(productId).approved( (product: IAPProduct) => {
// Purchase was approved
product.finish();
});
this.store.when(productId).registered( (product: IAPProduct) => {
console.log('Registered: ' + JSON.stringify(product));
});
this.store.when(productId).updated( (product: IAPProduct) => {
console.log('Loaded' + JSON.stringify(product));
});
this.store.when(productId).cancelled( (product) => {
alert('Purchase was Cancelled');
});
// Overall Store Error
this.store.error( (err) => {
alert('Store Error ' + JSON.stringify(err));
});
}
async purchase() {
/* Only configuring purchase when you want to buy, because when you configure a purchase
It prompts the user to input their apple id info on config which is annoying */
if (!this.platform.is('cordova')) { return };
let productId;
if (this.platform.is('ios')) {
productId = this.product.appleProductId;
} else if (this.platform.is('android')) {
productId = this.product.googleProductId;
}
console.log('Products: ' + JSON.stringify(this.store.products));
console.log('Ordering From Store: ' + productId);
try {
let product = this.store.get(productId);
console.log('Product Info: ' + JSON.stringify(product));
let order = this.store.order(productId);
alert('Finished Purchase');
} catch (err) {
console.log('Error Ordering ' + JSON.stringify(err));
}
}
backHomePage() {
this.navCtrl.pop();
}
}
I have tried building the app without --prod but still its not working. I am calling the purchase() function but nothing happens
While testing my app, the data was not fetched and there are no errors showing up.
The status of the products are already on "ready to submit".
I turned on in-app purchase capability as well in Xcode but still, the products are not listed.
My question is, do I need to submit new version of my Live app to test with new In App Purchase Products? or is it okay to test it even I didn't submit new version.
Ionic 3
In-App Purchase 2
export class CardsPage {
public product: any = {
name: 'Elite Membership',
appleProductId: 'ph.elite_membership',
googleProductId: 'ph.elite_membership'
};
constructor(public navCtrl: NavController,
public navParams: NavParams,
public restProvider: RestProvider,
private storage: Storage,
private alertCtrl: AlertController,
public platform: Platform,
public store: InAppPurchase2) {
platform.ready().then(() => {
this.configurePurchasing();
});
}
configurePurchasing() {
if (!this.platform.is('cordova')) { return; }
let productId;
try {
if (this.platform.is('ios')) {
productId = this.product.appleProductId;
} else if (this.platform.is('android')) {
productId = this.product.googleProductId;
}
// Register Product
// Set Debug High
this.store.verbosity = this.store.DEBUG;
// Register the product with the store
this.store.register({
id: productId,
alias: productId,
type: this.store.PAID_SUBSCRIPTION
});
this.registerHandlers(productId);
InAppPurchase2.getPlugin().ready().then((status) => {
console.log(JSON.stringify(this.store.get(productId)));
console.log('Store is Ready: ' + JSON.stringify(status));
console.log('Products: ' + JSON.stringify(this.store.products));
});
// Errors On The Specific Product
this.store.when(productId).error( (error) => {
alert('An Error Occured' + JSON.stringify(error));
});
// Refresh Always
console.log('Refresh Store');
this.store.refresh();
} catch (err) {
console.log('Error On Store Issues' + JSON.stringify(err));
}
}
registerHandlers(productId) {
// Handlers
this.store.when(productId).approved( (product: IAPProduct) => {
// Purchase was approved
product.finish();
});
this.store.when(productId).registered( (product: IAPProduct) => {
console.log('Registered: ' + JSON.stringify(product));
});
this.store.when(productId).updated( (product: IAPProduct) => {
console.log('Loaded' + JSON.stringify(product));
});
this.store.when(productId).cancelled( (product) => {
alert('Purchase was Cancelled');
});
// Overall Store Error
this.store.error( (err) => {
alert('Store Error ' + JSON.stringify(err));
});
}
I am having a problem to understand what am I missing on my server side. I am sending a firebase function delete request to my Node JS server from Android client side and when printing to console everything looks fine and works synchronously and ends with status code 200, but I am getting the String cannot be converted to JSONObject error at the android side. What am I missing in my node js code?
here is my Android client side code -
private void deleteCurrentVideo(int position) {
//setProgressBarVisibility(View.GONE, View.VISIBLE);
ProgressDialog dialog = new ProgressDialog(getContext(),R.style.DialogTheme);
dialog.setMessage("Please wait");
dialog.setCancelable(false);
dialog.show();
Map<String,Object> data = new HashMap<>();
data.put("videoId",mVideoKey);
data.put("cloudinaryId", mCloudinaryId);
data.put("contestId", mContestKey);
FirebaseFunctions.getInstance()
.getHttpsCallable("https_delete_video_request")
.call(data)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
if (task.isComplete()) {
mVideoDeletedListener.onVideoDeleted(position);
dialog.dismiss();
}
} else {
Toast.makeText(getContext(),"Error deleting video", Toast.LENGTH_SHORT).show();
}
});
}
and here is my firebase function code -
exports.https_delete_video_request = functions.https.onRequest((req, res) => {
const videoId = req.body.data.videoId;
const cloudinaryId = req.body.data.cloudinaryId || "null";
const contestId = req.body.data.contestId;
console.log("Request body:", req.body);
console.log("inside delete video function with the following videoID " + videoId);
console.log("inside delete video function with the following cloudinaryId " + cloudinaryId);
console.log("inside delete video function with the following contestId " + contestId);
if (!videoId && !cloudinaryId && !contestId) {
return res.status(400).send("Bad Request: Maybe you are missing some required parameters");
}
return moddelete.deleteVideoFromCloudinary(cloudinaryId, videoId,contestId, res, function(result) {
console.log(result);
});
});
here is my deletion module -
// define global varibales
const admin = require('firebase-admin');
const database = admin.database();
const cloudinary = require('cloudinary').v2
// variables for getting the cloudinary sensitive information
const content = require('./cloudinary-account.json');
//this is the inital deletion method - it deleted the video from cloudinary, if it works successfully it continues to delete from firebase database.
//this is stage 1/3 of the deletion.
exports.deleteVideoFromCloudinary = function (cloudinaryId, videoId, contestId, response, callabck) {
if (cloudinaryId === null) {
return;
}
//initially create the map without any key
var map = {};
function addValueToList(key, value) {
map[key] = map[key] || [];
map[key].push(value);
}
addValueToList("api_secret", content.cloudinary_api_secret);
addValueToList("api_key", content.cloudinary_api_key);
addValueToList("resource_type", content.cloudinary_resource_type);
addValueToList("cloud_name", content.cloudinary_cloud_name);
cloudinary.uploader.destroy(cloudinaryId, map, function (error, result) {
if (error !== undefined) {
console.log("cloudinary error - " + error);
callabck(error);
return response.status(500).send("");
}
console.log("cloudinary result - " + JSON.stringify(result));
continueDeleteFromFirebaseVotesDB(videoId, contestId, response, function(result){
callabck("successfully deleted from cloudinary")
console.log(result);
return response.status(200).send(JSON.stringify("success"));
}) ;
});
}
//this is a function that deletes the votes associated with the deleted video.
//this is stage 2/3 of the deletion.
function continueDeleteFromFirebaseVotesDB(videoId, contestId, response, callabck) {
var query = database.ref("votes/" + contestId).orderByKey();
console.log(JSON.stringify(query));
query.once("value")
.then(function (snapshot) {
if (!snapshot.exists) {
// console.log("votes db snapshot does not exist");
callabck("votes db snapshot does not exist")
return;
}
console.log("entire snapshot - " + JSON.stringify(snapshot));
snapshot.forEach(function (childSnapshot) {
//var key = childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
if (childData.video_id !== videoId) {
//console.log("nothing to delete");
} else {
childSnapshot.ref
.remove()
.then(function () {
console.log("removed vote successfully - " + JSON.stringify(childSnapshot))
return null;
})
.catch(function (error) {
console.log("vote remove failed: " + error.message)
response.status(500).send("");
});
}
});
continueDeleteFromFirebaseVideosDB(videoId, response, function(result) {
callabck("successfully deleted from votes database");
console.log(result);
})
return query;
})
.catch(error => {
// console.log("votes query error " + JSON.stringify(error))
callabck("votes query error " + JSON.stringify(error))
response.status(500).send("");
})
}
//this is the last function that deletes the actual video from Videos table itself.
//this is stage 3/3 of the deletion.
function continueDeleteFromFirebaseVideosDB(videoId, response, callabck) {
var query = database.ref("videos/" + videoId).orderByKey();
console.log(JSON.stringify("videos DB query - " + query));
query.once("value")
.then(function (snapshot) {
if (!snapshot.exists) {
// console.log("video snapshot does not exist");
callabck("video callback - video snapshot does not exist")
return;
}
console.log("Videos DB snapshot - " + JSON.stringify(snapshot));
snapshot.ref.remove()
.then(function () {
// console.log("removed video successfully - " + JSON.stringify(snapshot))
callabck("successfully deleted from videos database")
return null;
})
.catch(function (error) {
console.log("video remove failed: " + error.message);
callabck("video callback - video remove failed: " + error.message);
response.status(500).send("");
});
return query;
})
.catch(error => {
// console.log("videos query error " + JSON.stringify(error))
callabck("videos query error " + JSON.stringify(error));
response.status(500).send("");
})
}
at the end I am getting at the function console the following messages -
Found the answer - quit Javascript.
And in a more practical manner - when I was posting the following code -
return response.status(200).send("success");
Android was not able to get a JSON object out of it. Not even when doing JSON.stringify("success"). So my solution was the following code -
return response.status(200).send('{"result": "success"}');
i need token-id after creating user to firebase but below code is not working
//here i am registering to firebase
onRegisterTap() {
console.log("firebase1");
firebase.createUser({
email: this.userRegister.email,
password: this.userRegister.password
}).then(
(result) => {
// this callback function is not trigering..help me please and i am not gettting token id
firebase.addOnPushTokenReceivedCallback((token) => {
console.log("Firebase push token: " + token);
this.firebaseToken = token;
console.log("firebase", JSON.stringify(this.firebaseToken));
}
);
sending verification mail
firebase.sendEmailVerification().then(
function () {
console.log("Email verification sent");
},
function (error) {
console.log("Error sending email verification: " + error);
}
);
console.log("firebase", result.key);
},
(errorMessage) => {
this.globals.setIsLoading(false);
alert({
title: "Registartion Failed",
message: errorMessage,
okButtonText: "OK"
})
}
);
}
//why firebase.addOnPushTokenReceivedCallback method is not triggering?