limco
limco

Reputation: 1420

Stripe Connect - Create multiple tokens for multiple Destination Charges

I'm trying to create multiple tokens clientside to send to the server to make multiple Destination Charges on Stripe Connect.

I can't use the Customer object because for Destination Charges, the Customer has to be a connected account on the platform, so guest checkouts won't work.

So i need to call Stripe.createToken 'x' times, and save the tokens in 'x' number of hidden inputs using the stripeResponseHandler function, which are then submitted to serverside for processing the charges.

This is how I managed to do it for 2 tokens very very manually:

Stripe.createToken( {
    number:     card,
    cvc:        cvc,
    exp_month:  month,
    exp_year:   year,
    name:       name,
    address_line1: address_line1,
    address_line2: address_line2,
    address_state: address_state,
    address_city: address_city,
    address_zip: address_zip,
    address_country: address_country
}, stripeResponseHandler1 );

Stripe.createToken( {
    number:     card,
    cvc:        cvc,
    exp_month:  month,
    exp_year:   year,
    name:       name,
    address_line1: address_line1,
    address_line2: address_line2,
    address_state: address_state,
    address_city: address_city,
    address_zip: address_zip,
    address_country: address_country
}, stripeResponseHandler2 );

function stripeResponseHandler1( status, response ) {
    var $form = jQuery("form.checkout, form#order_review");

    if ( response.error ) {
        jQuery('.woocommerce_error, .woocommerce-error, .woocommerce-message, .woocommerce_message, .stripe_token').remove();
        jQuery('#dokan-stripe-connect-card-number').closest('p').before( '<ul class="woocommerce_error woocommerce-error"><li>' + response.error.message + '</li></ul>' );

        $form.unblock();

    } else {
        var token = response['id'];
        wc_stripe_connect_params.token_done = true;

        jQuery( '.stripe_token').remove();

        $form.append("<input type='hidden' class='stripe_token' name='stripe_token1' value='" + token + "'/>");
    }
}

function stripeResponseHandler2( status, response ) {
    var $form = jQuery("form.checkout, form#order_review");

    if ( response.error ) {
        jQuery('.woocommerce_error, .woocommerce-error, .woocommerce-message, .woocommerce_message, .stripe_token').remove();
        jQuery('#dokan-stripe-connect-card-number').closest('p').before( '<ul class="woocommerce_error woocommerce-error"><li>' + response.error.message + '</li></ul>' );

        $form.unblock();

    } else {
        var token = response['id'];
        wc_stripe_connect_params.token_done = true;

        $form.append("<input type='hidden' class='stripe_token2' name='stripe_token2' value='" + token + "'/>");

        $form.submit();
    }
}

Obviously, this is not how anything should be coded, so I'm thinking I need it do something along the lines of:

var vendor_count = jQuery(".vendor_count").first().data("count");
for(i = 1; i <= vendor_count; i++ ) {
    Stripe.createToken( {
        number:     card,
        cvc:        cvc,
        exp_month:  month,
        exp_year:   year,
        name:       name,
        address_line1: address_line1,
        address_line2: address_line2,
        address_state: address_state,
        address_city: address_city,
        address_zip: address_zip,
        address_country: address_country
    }, stripeResponseHandler );
}

But I can't figure out how to pass the vendor_count index to the stripeResponseHandler to create the extra hidden input fields for sending.

Am I totally going about this the wrong way? I feel like based on my reasons at the beginning of this post, I have reason to require multiple token creation in this way.

Upvotes: 0

Views: 1440

Answers (1)

koopajah
koopajah

Reputation: 25652

When you use destination charges, the customer must exist on the platform and not on the connected account. The reason is that, as a platform, you create the charge in your account and tell Stripe to transfer part of the funds to the connected account automatically. Since the charge is created on the platform, that's where the customer must live.

If you are really using destination charges, then you only need one token. You can then create a charge for each connected account by passing their account id acct_XXX in the destination[account] parameter.

In PHP the code looks like this:

$charge = \Stripe\Charge::create(array(
  'amount' => 1000,
  'currency' => 'usd',
  'customer' => "cus_AAAAA",
  'destination' => array(
    "account" => "acct_1234,
    "amount" => 900
  )
));

On the other hand, if you are creating direct charges then it would live directly on the connected account. In that case, you can't charge the customer created in the platform but you still don't need to create multiple tokens client-side.

The idea instead is to use Shared customers. This means that you save the card details in the platform on a customer once. And then, every time you want to charge that card on a connected account, you use this feature to create a new token, server-side, for that customer and one of its saved card. You get a new card token and you then use that token to create a charge on the connected account.

In PHP, the code looks like this:

// Create a new token for the saved card
$token = \Stripe\Token::create(
  array(
    "customer" => "cus_AAAAA",
    "card" => "card_BBBBB"
  ),
  array("stripe_account" => "acct_AAAAAA")
);

// Charge that new token on the connected account
$charge = \Stripe\Charge::create(
  array(
    "amount" => 1000,
    "currency" => "USD",
    "source" => $token->id,
  ),
  array("stripe_account" => "acct_AAAAAA")
);

Stripe also just launched the ability to split funds between multiple recipients. This allows you to create one charge on the platform and then split the funds with multiple connected accounts using transfer_group. This is likely the best solution for you assuming your platform and your connected accounts are based in countries where this is supported.

Upvotes: 1

Related Questions