Notes
You can use Stripe Connect a few different ways
Special note about Ireland
Stripe charges VAT on their fee
VAT is not added in other EU countries

3 options for charge type:

Option 1: Direct charges
stripe.PaymentIntent.create(
amount=1099,
currency='usd',
payment_method_types=['card'],
Mark's comments
Pro
- Simple
Cons
- Recommended for Standard, generally not recommended for Express accounts
- Charges created directly on the connected account are reported only on that account; they aren’t shown in your platform’s Dashboard, exports, or other reporting, although you can always retrieve this information with a call to the API.
- It's probably possible for the seller to leave Awesound, taking their subscribers with them. This could be a feature or a bug, depending on our preference.
Notes:
- To charge a card, the Connect account must have service_type 'full' not 'recipient'.
Conclusion: we probably won't do Direct charges.

- Recommended for Standard accounts.
- Money goes to seller first, so clearly Awesound's revenue is just the
application_fee
- The connected account is responsible for Stripe fees, refunds, and chargebacks.
refund_application_fee
isfalse
by default – we can create a refund, but keep our fee unless we specify otherwise.
Option 2: Destination charges
Mark's comments:
- Probably the simplest way to get started using Connect for payments with Express accounts
- Doesn't support paying 2+ people for one purchase, e.g., the author and their agent (doing revenue share), or the author + voice actor doing revenue share.
- TBD if it's possible for an Irishman to sell a book in USD and get paid via a Destination charge in real-time.
Stripe's points:
- Destination charges are recommended for Express or Custom accounts. Destination charges are created on the platform, but as part of the charge operation, funds are transferred to the connected account specified in the transfer_data[destination] parameter of the charge.
- The platform is responsible for the cost of the Stripe fees, refunds, and chargebacks.
- Only one recipient can be set. The recipient is set at the same time as the payment

# Option 1: specificy the application_fee_amount
payment_intent = stripe.PaymentIntent.create(
payment_method_types=['card'],
amount=1000,
currency='usd',
application_fee_amount=123,
transfer_data={
'destination': '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
}
)

# Option 2: specify the transfer_data['amount']
payment_intent = stripe.PaymentIntent.create(
payment_method_types=['card'],
amount=1000,
currency='usd',
transfer_data={
'amount': 877,
'destination': '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
}
)
on_behalf_of
This only applies to Destination charges
Option 3: Separate charges and transfers are supported if both your platform and the connected account are in the same region (for example, both in Australia).
Separate charges and transfers are supported if both your platform and the connected account are in the same region (for example, both in Australia).
- Con: For our US Stripe account, only US sellers could do this clever split-revenue thing with later payouts
- TBD: All non-US sellers need to have a
tos_acceptance='service'
defined up-front when creating the Stripe Account; otherwise we can't transfer them money.

- "Cross-border payouts only work with the recipient service agreement." (https://stripe.com/docs/connect/cross-border-payouts)
Service agreement type
- Must be set when we create Stripe Connect Account
full
is required to request card_payments
service
is required for cross-border payments
TBD can an Irish Account Owner sell an audiobook in USD using a destination charge?
Questions for Stripe
What is the effect of including the transfer_group argument?
Can I create separate charges and transfers for international folks, if I just don't include 'transfer_group' argument?
Four facts that lead me to think non-US sellers might need two Stripe accounts
- "The on_behalf_of attribute is supported only for connected accounts with the card_payments capability." https://stripe.com/docs/connect/charges-transfers#on-behalf-of
- "Accounts under the recipient service agreement can’t request card_payments." https://stripe.com/docs/connect/charges-transfers#on-behalf-of
- https://stripe.com/docs/connect/account-capabilities#card-payments If the account has 'full', I can't make a manual payout to that (non-US) account.
- "Separate charges and transfers are supported if both your platform and the connected account are in the same region (for example, both in Australia)." OK, so I can't use
stripe.Transfer.create()
with atransfer_group
parameter for the UK person.
Let's test this
// from https://stripe.com/docs/connect/charges-transfers
// Create a PaymentIntent:
const paymentIntent = await stripe.paymentIntents.create({
amount: 10000,
currency: 'usd',
payment_method_types: ['card'],
transfer_group: 'testingCrossBorder',
});
// Create a Transfer to the connected account (US):
const transfer = await stripe.transfers.create({
amount: 7000,
currency: 'usd',
destination: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
transfer_group: 'testingCrossBorder',
});
// Create a second Transfer to another connected account (non-US):
const secondTransfer = await stripe.transfers.create({
amount: 2000,
currency: 'usd',
destination: '{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}',
transfer_group: 'testingCrossBorder',
});
transfer_group
argument is optional when calling stripe.Transfer.create()
on_behalf_of
Subscriptions
Hah. So I had it all figured out for one-time payments, and it turns out subscriptions are different.
- Option 1: Create the subscription authorised as the connected account.
- Pro: the fees are beautifully simple our end: we just see the €0.50 we take.
- Minor Con: We have to listen separately to webhooks for the connected account
- Con: the price needs to be pre-defined in the connected account, which complicates the update_playlist_price code, slightly.
- Con: the Stripe account must be fully set up before they can make their first sale (I think)
- Option 2: Create the subscription on our account, with
transfer_data
- Con: Won't work for non-US accounts
Code example: stripe.Subscription.create()
# test mode
subscription = stripe.Subscription.create(
customer="cus_IpB71tktXVgTGq", # "cus_4fdAW5ftNQow1a",
items=[
{
"price": "price_1IKOvyDZMz26SgvEXaK2dGIj", # velotest "price_H1y51TElsOZjG",
},
],
expand=["latest_invoice.payment_intent"],
application_fee_percent=10,
transfer_data={
"destination": "acct_1IBRVODFBHb3LtaI", // account based in Ireland with 'full' service agreement
},
)
stripe.error.InvalidRequestError: Request req_OWYmICqJ6BCiYt: Cannot create a destination charge for connected accounts in IE because funds would be settled on the platform and the connected account is outside the platform's region. You may use theon_behalf_of
parameter to have the charge settle in the connected account's country. For more information onon_behalf_of
, see https://stripe.com/docs/connect/charges-transfers#on-behalf-of. If using capabilities (e.g.card_payments
,transfers
), note that they affect settlement as well. For more information on capabilities, see https://stripe.com/docs/connect/account-capabilities. If you still need assistance, please contact us via https://support.stripe.com/contact.
OK, so we add the
on_behalf_of
parameter it suggests… but for Subscription.create()
, that's not recognised:stripe.api_key = 'sk_test_517j8p4DZMz26SgvEvpTETIDGMAtuImAx73aryLqy6HJxvCP1jBksYErbOYHkIdmE5Xeyzx511kGn7eQmTQpLkHSI00VvUKjyr6'
subscription = stripe.Subscription.create(
customer="cus_IpB71tktXVgTGq", # "cus_4fdAW5ftNQow1a",
items=[
{
"price": "price_1IKOvyDZMz26SgvEXaK2dGIj", # velotest "price_H1y51TElsOZjG",
},
],
stripe.error.InvalidRequestError: Request req_h5LzCq38HUlu8U: Received unknown parameter: on_behalf_of
Code example: Use Checkout to create the subscription
As seen in the above example,
transfer_data
is used for destination charges, but that doesn't work for international accounts, it seems. Alas, we'll use direct charges, so. This complicates webhooks (need to listen for webhooks on connected account) and complicates other things (cutransfer_data
and on_behalf_of
are not possible when creating a subscription via Stripe Checkout https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-subscription_data Direct charges: To make API calls on behalf of a connected account, add a second argument, object
var stripe = Stripe("{{PLATFORM_PUBLISHABLE_KEY }}", { stripeAccount: "{{CONNECTED_STRIPE_ACCOUNT_ID}}"});
// buyButton.jsx
if (playlist.interval != "onnce") {
// For subscriptions, use direct charges to avoid currency conversion.
stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY, {
stripeAccount: playlist.connectStripeAcId, // "acct_1IBRVODFBHb3LtaI",
});
} else {
stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY);
}
// create-checkout-session.js
if (checkout_mode == "subscription" && connectStripeAcId) {
const stripeSession = await stripe.checkout.sessions.create(postData, {
stripeAccount: connectStripeAcId,
});
res.json(stripeSession);
} else {
const stripeSession = await stripe.checkout.sessions.create(postData);
res.json(stripeSession);
}