Jeremy S. Jeremy S. - 1 month ago 6
Node.js Question

Using Stripe Connect with stripe-node to charge shared customer

I am struggling to land on the correct syntax to charge a customer for the benefit of a connected user with Stripe Connect. I am using the stripe-node api. I have tried what seems like a hundred combinations of params to create the charge and none will work for me.

The customer I wish to charge is already added as a customer on my (the Connect application's) Stripe account, and the user who I want to receive the benefit of the charge has already connected to my application. That went fine. With those steps complete I then retrieve a token for the new charge, which also appears to go fine. I call:

Stripe.tokens.create(
{ customer: myCustomer },
connectedUserAccessToken,
function(error, token){
if (error){
return error;
} else {
return token;
}
}
);


Which returns:

{ id: 'tok_15L16gLFEmuXszazTaVUA0ty',
livemode: false,
created: 1421280206,
used: false,
object: 'token',
type: 'card',
card:
{ id: 'card_15L16gLFEmuXszaz7VAu2ciH',
object: 'card',
last4: '8210',
brand: 'MasterCard',
funding: 'debit',
exp_month: 1,
exp_year: 2020,
fingerprint: 'ny39g9uj2lfhYA2H',
country: 'US',
name: null,
address_line1: null,
address_line2: null,
address_city: 'New York',
address_state: 'NY',
address_zip: '10003',
address_country: 'US',
cvc_check: null,
address_line1_check: null,
address_zip_check: null,
dynamic_last4: null,
customer: null },
client_ip: '99.99.9.99'
}


(Card data is fake from the Stripe testing page).

The problems arise when I try to use the new token to create a charge. I assign the object above to the var token and call:

Stripe.charges.create(
{ card: token.id },
function(error, result){
if (error){
return error;
} else {
return result;
}
}
);


This returns:

[ Error: There is no token with ID tok_15L16gLFEmuXszazTaVUA0ty. ]


This response makes no sense to me because, as you can see, the token id matches the id that was just created. (I see the token create events posted to my Stripe logs as well, so they are being properly created).

If instead of passing
{ card: token.id }
to
Stripe.charges.create()
I pass:

Stripe.charges.create(
token,
function(error, result){}
);


I receive:

[Error: [Error: Missing required param: currency]


That makes sense as I have not passed it a charge currency or amount. But when I try to pass these additional params as options, e.g.:

Stripe.charges.create(
{ currency: user.currency, amount: transaction.amount },
token,
function(error, result){}
);


I receive:

[Error: Stripe: Unknown arguments ([object Object]). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.]


I receive the same error if I reverse the arguments and call:

Stripe.charges.create(
token,
{ currency: user.currency, amount: transaction.amount },
function(error, result){}
);


In fact any options that I pass in any format seem to be rejected with the same error immediately above.

I tried:

Stripe.charges.create(
{ customer: token.id, currency: user.currency, amount: transaction.amount },
function(error. result){}
);


which results in:

[Error: No such customer: tok_15L16gLFEmuXszazTaVUA0ty]


I tried adding the currency directly to the token itself by way of
token.currency = user.currency
and then calling
Stripe.charges.create(token)
. This it seems to like at first as it returned the error:

[Error: Missing required param: amount]


But when I followed up and set
token.currency = user.currency; token.amount = transaction.amount;
then it rejects the whole object, returning:

[Error: Received unknown parameters: id, livemode, created, used, object, type, client_ip]


I cannot think of what else it might be looking for.

I read the link it shows me above a number of times, https://github.com/stripe/stripe-node/wiki/Using-Stripe-Connect-with-node.js, but it has not helped me conform the syntax. So I have run out of ideas for the time being. Thanks for reading.

Answer

Once you created a card token for your connected user using their publishable_key you then need to create the charge on their behalf using their access_token. This is described in the documentation on how to collect fees and the code would look like this:

// Get the credit card details submitted by the form
var token = request.body.stripeToken;

// Create the charge on Stripe's servers - this will charge the user's card
stripe.charges.create(
  {
    amount: 1000, // amount in cents
    currency: "eur",
    card: token,
    description: "payinguser@example.com",
    application_fee: 123 // amount in cents
  },
  ACCESS_TOKEN, // user's access token from the Stripe Connect flow
  function(err, charge) {
    // check for `err`
    // do something with `charge`
  }
);
Comments