I'm working with charging credit cards on an ionic application. If I check the Stripe website, only the token is created successfully. There is no event for the charge. When I check Firebase everything seems to be working (previously I had error message "An error occurred with our connection to Stripe" which was eliminated by upgrading to paid version Blaze).

I've structured the following code so you can see the sequence of events.

Here is the sequence of events:

1) Here I get the token and pass to payByStripe function:

checkOut() {
  let alert = this.alertCtrl.create({
    title: 'card information',
    cssClass:'alert-css',
    inputs: [{
      name: 'cardNumber',
      placeholder: 'card number',
    },
    {
      name: 'expMonth',
      placeholder: 'expMonth',
    },
    {
      name: 'expYear',
      placeholder: 'expYear',
    },
    {
      name: 'cvc',
      placeholder: 'cvc',
    }],
    buttons: [{
      text: 'Cancel',
      role: 'cancel',
      handler: data => {
        console.log('Cancel clicked');
      }
    },
    {
      text: 'PAY',
      handler: data => {
        this.stripe.setPublishableKey('pk_test_abcdef1BC');
        let card = {
          number: data.cardNumber,
          expMonth: data.expMonth,
          expYear: data.expYear,
          cvc: data.cvc
        };
        this.stripe.createCardToken(card)
        .then(token => {
          this.goodsData.payByStripe(this.totalMoniesPlusTaxAndCharge,this.userEmail,token);
            let alert = this.alertCtrl.create({
              title: 'Charged',
              cssClass:'alert-css',
              subTitle: 'Successful Charge!',
              buttons: ['Dismiss']
            });
            alert.present();
          }, error => {
            this.loading.dismiss();
            let alert = this.alertCtrl.create({
              title: 'ERROR',
              cssClass:'alert-css',
              subTitle: JSON.stringify(error),
              buttons: ['Dismiss']
            });
            alert.present();
          })
        .catch(error => console.log(JSON.stringify(error)) );
      }
    }]
  });
  alert.present();
} 

2) Here, I push the charge to Firebase, where cloud functions will handle it:

payByStripe(amount,email,token): firebase.database.Reference {
  return firebase.database().ref('/stripe_customers/charges/').push({
    amount:amount,
    email:email,
    token:token
  });
}

3) Here is what the cloud functions are doing:

const functions = require('firebase-functions'),
      admin = require('firebase-admin'),
      logging = require('@google-cloud/logging')();

admin.initializeApp(functions.config().firebase);

const stripe = require('stripe')(functions.config().stripe.token),
      currency = functions.config().stripe.currency || 'USD';

// [START chargecustomer]
// Charge the Stripe customer whenever an amount is written to the Realtime database
exports.createStripeCharge = functions.database.ref('/stripe_customers/charges/').onWrite(event => {
  const val = event.data.val();
  // This onWrite will trigger whenever anything is written to the path, so
  // noop if the charge was deleted, errored out, or the Stripe API returned a result (id exists) 
  if (val === null || val.id || val.error) return null;
  // Look up the Stripe customer id written in createStripeCustomer

    // Create a charge using the pushId as the idempotency key, protecting against double charges 
    const amount = val.amount;
    const email = val.email;
    const token = val.token;

    stripe.charges.create({
      amount: amount,
      currency: "usd",
      source: token,
      description: "Charge for " + email
    }).then(response => {
      // If the result is successful, write it back to the database
      return event.data.adminRef.set(response);
    }, error => {
      // We want to capture errors and render them in a user-friendly way, while
      // still logging an exception with Stackdriver
      return event.data.adminRef.child('error').set(userFacingMessage(error)).then(() => {
        return reportError(error, {user: event.params.userId});
      });
    });
});
// [END chargecustomer]]

1 Answers 11

I'm pretty sure that's a Firebase-specific error, so if the cause isn't clear, you may want to reach out to them - though someone else with more Firebase experience may have a more useful answer for you!

Not the answer you're looking for? Browse other questions tagged or ask your own question.