Getting a stripe ID into my user object

I’m a bit lost here.

I’m trying to implement stripe and the first step in my situation is to create a stripe customer when a user is registered.

So I started out by adding a new call to my createUser:

Accounts.createUser({
  email: email,
  password: password,
  profile: profile
}, function(error){
  if (!error) {

    Meteor.call("StripeCreateCustomer", Meteor.userId(), Meteor.user().emails[0].address, function(error, result){
      if (error) {
        console.log(error);
      }
    });

    Router.go('/app/dashboard');
  } else{
    if(error.reason == "Email already exists."){
      validator.showErrors({
        email: "That email address is already registered to a user."
      });
    }
  }
});

Which calls this:

StripeCreateCustomer: function (userId, email) {
    var Stripe = StripeAPI(Meteor.settings.stripe.testSecretKey);

    Stripe.customers.create({
      description: userId,
      email: email
    }, function(error, customer) {
      if (error) {
        throw new Meteor.Error( 500, "Stripe customer not created" );
      }
    });
  },

Now the issue I’m having is that I need to add the (newly created) stripe ID to the meteor user. Both methods I’ve tried don’t work for different reasons:

If I attempt to catch the Stripe customer ID via a return from the method then it’s always undefined (async something something, I’m sure I’ll understand it one day…). If I attempt to update the user within the StripeCreateCustomer method then I get a mysterious error:

Stripe.customers.create({
      description: userId,
      email: email
    }, function(error, customer) {
      if (error) {
        throw new Meteor.Error( 500, "Stripe customer not created" );
      }
      Meteor.users.update( { _id: Meteor.userId() }, {$set: { 'stripeId': customer.id }});
    });

Error:

Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.

So… how do I get the customer ID into my user object?

Aha, OK so this SO covered the Meteor.bindEnvironment business, I needed:

Stripe.customers.create({
      description: userId,
      email: email
    }, Meteor.bindEnvironment(function(error, customer) {
      if (error) {
        throw new Meteor.Error( 500, "Stripe customer not created" );
      }
      var user = Meteor.users.update( { _id: Meteor.userId() }, {$set: { 'stripeId': customer.id }});
      console.log(Meteor.user());
    }));

I had found a couple other SO’s but they referred more to the ‘Fiber’ and threw me off a bit! Callbacks/async still feels like more trouble than it’s worth, but I’m sure it’ll click one day…

There’s a good SO answer/demo of wrapasync() using Stripe here http://stackoverflow.com/a/26226668

1 Like

Oooh that’s nice and specific to my use-case - thanks I’ll check it out!