Search code examples
stripe-paymentspayout

Stripe connect payout - throws exceptions


I'm working on a .net project. I am trying to pay out some amount to my connected account. I tried with amount = 15

This is my account balance object.

"object": "balance",
    "available": [
      {
        "amount": 1929490,
        "currency": "aud",
        "sourceTypes": {
          "card": 1929490
        },
        "rawJObject": null,
        "stripeResponse": null
      }
    ],
    "connectReserved": [
      {
        "amount": 0,
        "currency": "aud",
        "sourceTypes": null,
        "rawJObject": null,
        "stripeResponse": null
      }
    ],
    "instantAvailable": [
      {
        "amount": 1200000,
        "currency": "aud",
        "sourceTypes": {
          "bankAccount": 0,
          "card": 1200000,
          "fpx": 0,
          "rawJObject": null,
          "stripeResponse": null
        },
        "rawJObject": null,
        "stripeResponse": null
      }
    ],
    "issuing": null,
    "livemode": false,
    "pending": [
      {
        "amount": 108924,
        "currency": "aud",
        "sourceTypes": {
          "card": 108924
        },
        "rawJObject": null,
        "stripeResponse": null
      }
    ],

I've tried some methods. I'll post them here.

Method 1: Connect account selected his bank account for payouts (NOT card) and check following request [![connect account setting - payout - bank account][1]][1] Request :

 var options = new PayoutCreateOptions
                {
                    // Destination = connectAccountId,
                    Description = description,
                    Method = "standard",// standard or instant
                    SourceType = "bank_account", // options are bank_account, card, or fpx
                    Amount = amount,
                    Currency = "aud",
                    Metadata = new Dictionary<string, string> { { "ConnectAccountId", connectAccountId } },
                };

                var requestOptions = new RequestOptions();
                requestOptions.StripeAccount = connectAccountId;

                var service = new PayoutService();
                return service.Create(options, requestOptions);

Response : "You have insufficient funds in your Stripe account for this transfer. Your ACH balance is too low. You can use the /v1/balance endpoint to view your Stripe balance (for more details, see stripe.com/docs/api#balance)."

Nethod 2:Connect account selected his bank account for payouts (NOT card) and check following request

var options = new PayoutCreateOptions
                {
                    // Destination = connectAccountId,
                    Description = description,
                    Method = "standard",// standard or instant
                    SourceType = "card", // options are bank_account, card, or fpx
                    Amount = amount,
                    Currency = "aud",
                    Metadata = new Dictionary<string, string> { { "ConnectAccountId", connectAccountId } },
                };

Response:

"You have insufficient funds in your Stripe account for this transfer. Your card balance is too low. You can use the /v1/balance endpoint to view your Stripe balance (for more details, see stripe.com/docs/api#balance)."

Method 3: Connect account selected his debit card for payouts (NOT bank account) and check the following request.

[![connect account setting payout - card][2]][2]

Request: is same as request of method 2.

Response:

"Method standard is not supported for payouts to debit cards."

Method 4: Connect account selected his debit card for payouts (NOT bank account) and check the following request.

var options = new PayoutCreateOptions
                {
                    // Destination = connectAccountId,
                    Description = description,
                    Method = "instant",// standard or instant
                    SourceType = "card", // options are bank_account, card, or fpx
                    Amount = amount,
                    Currency = "aud",
                    Metadata = new Dictionary<string, string> { { "ConnectAccountId", connectAccountId } },
                };

Response:

"You have insufficient funds in your Stripe account for this transfer. Your card balance is too low. You can use the /v1/balance endpoint to view your Stripe balance (for more details, see stripe.com/docs/api#balance)."

Method 5: Connect account selected his debit card for payouts (NOT bank account) and check the following request.

Request :

  var options = new PayoutCreateOptions
                {
                    // Destination = connectAccountId,
                    Description = description,
                    Method = "instant",// standard or instant
                    SourceType = "bank_account", // options are bank_account, card, or fpx
                    Amount = amount,
                    Currency = "aud",
                    Metadata = new Dictionary<string, string> { { "ConnectAccountId", connectAccountId } },
                };

Response :

"You have insufficient funds in your Stripe account for this transfer. Your ACH balance is too low. You can use the /v1/balance endpoint to view your Stripe balance (for more details, see stripe.com/docs/api#balance)."

I'm tired of searching for the reason for these issues. I want to payout the amount to Connect's bank account. Please help me.


Updated question :

According to Lucky's answer, I've updated my code.

  1. First I transferred the amount to the connect account and tried to payout.
 var options = new TransferCreateOptions
                {
                    Amount = amount,
                    Currency = "aud",
                    Destination = connectAccountId,
                    Description = description,
                    // SourceType = "bank_account" //bank_account, card, or fpx  // This didn't works. got invalid source type error.
                };
                var service = new TransferService();
                return service.Create(options);

Balance in my connect account

 "available": [
      {
        "amount": 30,
        "currency": "aud",
        "sourceTypes": {
          "card": 30
        },
        "rawJObject": null,
        "stripeResponse": null
      }
    ],
    "connectReserved": null,
    "instantAvailable": [
      {
        "amount": 30,
        "currency": "aud",
        "sourceTypes": {
          "bankAccount": 0,
          "card": 30,
          "fpx": 0,
          "rawJObject": null,
          "stripeResponse": null
        },
        "rawJObject": null,
        "stripeResponse": null
      }
    ],
    "issuing": null,
    "livemode": false,
    "pending": [
      {
        "amount": 0,
        "currency": "aud",
        "sourceTypes": {
          "card": 0
        },
        "rawJObject": null,
        "stripeResponse": null
      }

Method 1: try to pay out to the bank _account

  var options = new PayoutCreateOptions
                {
                    // Destination = connectAccountId,
                    Description = description,
                    Method = "standard",// standard or instant
                    SourceType = "bank_account", // options are bank_account, card, or fpx
                    Amount = amount,
                    Currency = "aud",
                    Metadata = new Dictionary<string, string> { { "ConnectAccountId", connectAccountId } },
                };

                var requestOptions = new RequestOptions();
                requestOptions.StripeAccount = connectAccountId;

                var service = new PayoutService();
                return service.Create(options, requestOptions);

This didn't work. Got the same insufficient error.

Method 2: Payout to connects card - worked

    var options = new PayoutCreateOptions
                {
                    // Destination = connectAccountId,
                    Description = description,
                    Method = "standard",// standard or instant
                    SourceType = "card", // options are bank_account, card, or fpx
                    Amount = amount,
                    Currency = "aud",
                    Metadata = new Dictionary<string, string> { { "ConnectAccountId", connectAccountId } },
                };

After the payout, Connect acc's dashboard looks like this. [![last 2 Transcation summary][3]][3] [![summary][4]][4] [![last4][5]][5]

What does "Settled" mean? The transactions with "0.15dolar" are only Transfer (Payout failed at that time) 0.48 dolar one is Transfer and payout are succeeded.

How my connect account holder will know these differences? 0.48 is in minus amount What does it mean?


Solution

  • I think the problem is that the funds are in your platform's balance. They need to be in your connected account's balance for you to make a payout.

    To clarify:

    • A Payout is a transfer of funds between the Stripe account's balance and a bank account connected to that account.
    • A Transfer is a transfer of funds between Stripe accounts' balance.

    If you have available funds in your platform balance, you can make a payout to the bank account connected to your platform.
    If you want to make a payout to the bank account connected to your connected account, you need available funds in the connected account's balance.

    With that in mind:

    • Check the balance for your platform (optional, you already did this)
      https://docs.stripe.com/api/balance/balance_retrieve
    • Create a Transfer from your platform to your connected account:
      https://docs.stripe.com/api/transfers/create
    • Check the balance for your connected account (same as above with the stripeAccount header)
    • Create your payout, with the stripeAccount header and bank account / card ID as destination.
      source_type should be card but doesn't need to be specified. In fact I don't think destination does either, provided the connected account only has one valid external_account / you want to use the default one.