add_action('woocommerce_order_status_processing', 'execute_vendor_stripe_transfers', 10, 1);
function execute_vendor_stripe_transfers($order_id) {
$order = wc_get_order($order_id);
$charge_id = $order->get_transaction_id(); // Charge ID-ul primit de la Stripe
if (!$charge_id || $order->get_meta('_stripe_transfers_executed')) {
return;
}
\Stripe\Stripe::setApiKey(get_option('my_stripe_secret_key'));
foreach ($order->get_items() as $item) {
$vendor_id = get_post_field('post_author', $item->get_product_id());
$vendor_stripe_id = get_user_meta($vendor_id, 'stripe_account_id', true);
if (!$vendor_stripe_id) continue;
$item_total = $item->get_total();
$platform_fee = $item_total * 0.12; // 12% comision
$transfer_amount = round(($item_total - $platform_fee) * 100); // Suma în bani marunți (cents/bani)
try {
$transfer = \Stripe\Transfer::create([
'amount' => $transfer_amount,
'currency' => strtolower($order->get_currency()),
'destination' => $vendor_stripe_id,
'source_transaction' => $charge_id,
'description' => 'Plata comanda #' . $order->get_id()
]);
$order->add_order_note('Transfer Stripe executat: ' . $transfer->id . ' catre ' . $vendor_stripe_id);
} catch (\Exception $e) {
$order->add_order_note('Eroare transfer Stripe Vendor (' . $vendor_id . '): ' . $e->getMessage());
}
}
$order->update_meta_data('_stripe_transfers_executed', true);
$order->save();
}Am lucrat anul trecut la un marketplace B2B pe WooCommerce cu vreo 140 de furnizori activi și 4.000 de comenzi pe lună. Problema clasică: clientul pune în coș produse de la 3 vendori diferiți, plătește o singură dată, iar banii trebuie să plece instant către cei 3 vânzători, minus comisionul platformei de 12%.
Dacă încasezi totul în contul tău Stripe și faci payout manual prin bancă la sfârșit de lună, ai încurcat-o legal și fiscal. Devii procesator de plăți neautorizat și plătești impozit pe toată suma încasată, nu doar pe comisionul tău. Soluția curată e Stripe Connect.
Destination Charges vs Transfers separați
Când lucrezi cu WooCommerce și Stripe Connect, ai două opțiuni principale pentru împrăștierea banilor:
- Destination Charges: Banii merg direct la vendor, iar platforma își ia un
application_fee_amount. Merge excelent dacă într-un coș ai produse de la un singur vendor. - Separate Charges and Transfers: Încasezi plata pe platformă (Payment Intent unic), iar după ce plata e confirmată, generezi transferuri individuale către conturile conectate ale fiecărui vendor.
La un marketplace unde coșul e mixt (multi-vendor), Destination Charges nu funcționează direct dintr-o singură tranzacție de card fără să complici checkout-ul. Așa că varianta 2 este sfântul grail, deși aduce un trade-off nasol: riscul de credit rămâne pe umerii mei. Dacă un buyer dă chargeback, Stripe îmi trage mie banii din cont, nu vendorului, așa că trebuie să am mereu un buffer de capital în contul principal.
Cum arată fluxul în backend
Când Woo schimbi starea comenzii în processing, hooks-urile noastre preiau liniile din comandă, calculează comisionul pentru fiecare vendor și apelează API-ul Stripe pentru transfer.
Atenție uriașă la ID-urile de Stripe Account ale vendorilor (acct_12345...). Dacă un vendor nu are onboarding-ul completat în Stripe Express sau Custom, apelul de transfer va arunca o eroare 400 și îți blochează procesarea comenzii.
Coșmarul refund-urilor parțiale
Aici se rupe filmul la 90% din implementările amatoare. Clientul cumpără o jachetă de la Vendor A (200 RON) și o pereche de papuci de la Vendor B (100 RON). Returnează doar papucii.
Dacă faci refund simplu din interfața WooCommerce, Stripe va trimite banii clientului din soldul tău principal, NU din contul Vendorului B. Trebuie să apelezi explicit API-ul de Transfer Reversal (Stripe\Transfer::createReversal), specificând ID-ul transferului inițial și suma exactă. Dacă uiți de asta, ai plătit papucii din buzunarul tău, iar Vendor B rămâne cu banii primiți la comanda inițială.
Ce folosesc în producție
Nu re-inventez roata cu plugin-uri obeze gen WCFM sau Dokan dacă clientul vrea o arhitectură custom. Folosesc direct SDK-ul oficial stripe/stripe-php conectat pe hook-ul woocommerce_order_status_processing.
Voi cum gestionați transferurile când aveți vendori cu monede diferite sau din țări din afara SEE? Ați trecut la Stripe Connect Custom sau ați rămas pe variantele Express?