3

I am using a meteor method to retrieve values from a client side function. I am using stripe api, it is working fine

However when there is a error in the stripe.charges.create function the error is not passed back to the client, which results in the stripeCheckout method sending the user to the complete template. I assume there is a way to take the errors in the Stripe.charges.create err.type response from stripes servers or the Stripe.customers.create function on the server side pass them to the client and let the user know the specific error as well as not sending them to the complete template using a if statement based on errors or Status of success from the stripe server which is passed to the meteor.

It's that connection from the error response from stripes 'Stripe.charges.createfunction to the meteor server and then passing it back to the client through thestripeCheckout` method.

Ok Hope I can get this solved. And any tips to approach this token creation, customer creation and charge in better practice, I am open to any suggestions.

Thanks!

Client JS

Stripe.card.createToken({
  number: $('.card-number').val(),
  cvc: $('.card-cvc').val(),
  exp_month: $('.card-expiry-month').val(),
  exp_year: $('.card-expiry-year').val(),
  address_line1: addressValue1,
  address_line2 : addressValue2,
  address_city: cityValue,
  address_state: provinceState,
  address_country: country,
  address_zip: zip,
  name: firstName + lastName
}, stripeResponseHandler);

function stripeResponseHandler(status, response) {
  if (response.error) {

    alert(response.error.message);
  }else{

  // response contains id and card, which contains additional card details
  var token = response.id;

  Meteor.call('stripeCheckout',token,  function (error, result) {
    Router.go("/complete");
  });

  }
}

Server JS

Meteor.methods({

  stripeCheckout: function (token) {

    Stripe.customers.create({
      source: token
    }, function(err, customer) {
      id = customer.id;

      if(err){
       throw new Meteor.Error("create-failed", err.message);
      }else{
       throw new Meteor.Error("create-failed", err.message);
      }

      Stripe.charges.create({
          amount: 1000,
          currency: 'usd',
          customer: id
      }, function (err, res) {

       if(err){
        throw new Meteor.Error("create-failed", err.message);
       }else{
        throw new Meteor.Error("create-failed", err.message);
       }

      });

    });
  }
});

UPDATE:

I added my current error detecting, I throw a error in all instances and I get this response in my console.

Exception in delivering result of invoking 'stripeCheckout': TypeError: Cannot read property 'error' of undefined
    at http://localhost:3000/client/stripeClient.js?0eb126fd5e018d3cac3f8ec1505f32b7fdc97604:197:22
    at Meteor.bindEnvironment [as _callback] (http://localhost:3000/packages/meteor.js?81e2f06cff198adaa81b3bc09fc4f3728b7370ec:977:22)
    at _.extend._maybeInvokeCallback (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:3858:12)
    at _.extend.receiveResult (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:3878:10)
    at _.extend._livedata_result (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:4931:9)
    at onMessage (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:3723:12)
    at http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:2717:11
    at Array.forEach (native)
    at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
    at _.extend._launchConnection.self.socket.onmessage (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:2716:11)

This is the Stripe POST /v1/customers response

{
error:{
  message: "Your card was declined."
  type: "card_error"
  code: "card_declined"
 }
}
Tom Sawyer
  • 59
  • 1
  • 7

1 Answers1

3

Simply throw a Meteor.Error like this:

Meteor.methods({
  stripeCheckout: function (token) {
    Stripe.customers.create({
      source: token
    }, function(err, customer) {
      id = customer.id;

      Stripe.charges.create({
          amount: 1000,
          currency: 'usd',
          customer: id
      }, function (err, res) {

        // first argument is error code, second is error details
        throw new Meteor.Error("create-failed", err.message);

      });
    });
  }
});

You will get the error you threw in the error argument of the method callback.

See the docs here: http://docs.meteor.com/#/full/meteor_error

stubailo
  • 6,077
  • 1
  • 26
  • 32
  • 2
    When I `console.log(error);` on the client side meteor.call function I get a undefined value. hmm. – Tom Sawyer Mar 13 '15 at 17:38
  • Does your server-side code even get to the second callback? Maybe you should also throw an error if creating a customer fails. – stubailo Mar 13 '15 at 17:52
  • I have outputted errors in both functions with only a undefined return. I updated my code above. – Tom Sawyer Mar 13 '15 at 20:05
  • I still haven't solved this if you have any other ideas. – Tom Sawyer Mar 14 '15 at 19:05
  • This solution won't work as the call is asynchronous. The client code will have executed by the time the meteor error is thrown. Hence why the response is always 'undefined'. For this to work the call to stripe would have to be synchronous, and the method would need to wait for its response to be able to return a value the client can use. (I'm having the same problem, btw, needing to return a server stripe error, and can't…) – Nathan Hornby Nov 20 '15 at 11:14
  • @NathanHornby exactly! So have you solved this? I'm in the same situation :( – JohnnyQ Feb 15 '17 at 09:10