Getting callback from stripe meteor method


#1

I can’t for the life of me get a stripe callback to go to client.

I have this in client:

stripeCheckout = StripeCheckout.configure({
    key: '-----------------',
    token: function(token) {
      const test = Meteor.call('chargeCard', token.id, currentPackage.price+"00");
      console.log(test);
    },

And this method in server:

    'chargeCard': function(stripeToken, pricing) {
        if (!this.isSimulation) {
        const Stripe = StripeAPI("----------");
        check(stripeToken, String); 

        Meteor.wrapAsync( Stripe.charges.create({
          source: stripeToken,
          amount: pricing,
        }, function(error, charge) {
            if (error) {
                console.log(error);
                return error;
            } else if (charge) {
                console.log(charge);
                return charge;
            };
        }));
    };
    },

It should work but in server console.log it shows the payment was accepted but in client the console.log shows undefined.

Im not sure how async await actually works, is there a simple way


#2

Your return charge; statement is returning from the callback, not the method.

Try this:

  'chargeCard': function (stripeToken, pricing) {
    if (!this.isSimulation) {
      const Stripe = StripeAPI("----------");
      check(stripeToken, String);

      const stripeChargesCreate = Meteor.wrapAsync(Stripe.charges.create, Stripe.charges);
      //                This may need to be Stripe, or removed altogether ^^^^^^^^^^^^^^
      try {
        return stripeChargesCreate({
          source: stripeToken,
          amount: pricing,
        });
      } catch (error) {
        console.log(error);
        throw new Meteor.Error('Error', error.message);
      }
    }
  },

Note the second parameter in the wrapAsync. That sets the context of the wrapped function. Sometimes it can be omitted. In this case, it may need to be the main Stripe context. I haven’t used Stripe, so don’t actually know.


#3

I think I wrote my example a bit confusing, I’m actually sending the token.id + currentPackage.price from client to the meteor method, which the Stripe.charges.create uses to create a payment charge via the server. Then when payment is complete stripe is returning back either an ‘error’ or ‘charge’.

When I console log the error/charge given back by stripe when a successful transaction is made it works on the server, but Im not sure how to get those values back to the client as its a async function and (in my example) console.log(test); fires off straight away instead of waiting


#4

Correct. I fixed the server code but didn’t look at the client code.

You cannot get data back from Meteor.call in the way you’ve written it. On the client, it must be done with a callback, which is not going to work in the place you’ve made the call.

If you want to avoid major refactoring of your client code here, you should consider using async/await syntax.

There’s a package (more than one, actually) which adds a Promise method to Meteor.call, which will resolve your client problem with the least effort.

The technique is discussed in more detail here.

Note, that your original method code is still incorrect and you will need to use the code I posted (or a variant of it).


#5

I tried your solution again and it works! Thank you

Just one question, inside the Meteor.wrapAsync I see you added Stripe.charges, what is this exactly - is that the response from stripe that you’re calling back to client?


#6