Skip to content
msMarketSDK

// guide

Payments and payouts

With payments on, the buyer pays on your Stripe account, the money is held while the deal happens, and the seller's share moves to their connected account when it is done. Your platform fee stays with you. Connect Stripe first: see connecting Stripe.

The settings

  • payments, on by default. Off, orders are committed at once and no money moves through us.
  • seller verification, on by default. On, a seller must pass Stripe Identity before they can publish.
  • hold funds until completion, on by default. Off, the seller's share is released as soon as the buyer has paid, instead of when the order completes.
  • platform fee: a percentage in basis points (250 is 2.5 percent) plus a fixed amount, for the whole marketplace, or per category.

1. Onboard each seller

The first onboarding link creates the seller's Express account on your Stripe account. Send the seller to its URL; Stripe collects what the law requires.

POST /v1/sellers/{id}/onboarding_linksrequest
curl https://api.marketsdk.com/v1/sellers/sel_.../onboarding_links \
  -H "Authorization: Bearer $MARKETSDK_KEY" \
  -H "Content-Type: application/json" \
  -d '{"return_url": "https://shop.example/sell/done", "refresh_url": "https://shop.example/sell/again"}'

The seller's payouts status follows what Stripe reports, and each change sends seller.payouts_updated. Until payouts are enabled, an order for their listings is refused with seller_payouts_not_enabled.

2. Verify the seller, if you ask for it

POST /v1/sellers/{id}/verificationsrequest
curl https://api.marketsdk.com/v1/sellers/sel_.../verifications \
  -H "Authorization: Bearer $MARKETSDK_KEY" \
  -H "Content-Type: application/json" \
  -d '{"return_url": "https://shop.example/sell/verified"}'

The answer has the Stripe Identity page, shown once. Send the seller there. We keep only the outcome and Stripe's session id; the documents stay with Stripe. The seller's verification status changes when Stripe decides, and sends seller.verification_updated.

3. Take the payment

Make the order as usual. It waits in awaiting_payment for the payment window. Choose how the buyer pays:

  • With checkout URLs, the order's payment.checkout_url is a Stripe-hosted page. Redirect the buyer to it.
  • Without them, payment.client_secret is for Stripe Elements on your own page, with your own Stripe publishable key.
POST /v1/ordersrequest
curl https://api.marketsdk.com/v1/orders \
  -H "Authorization: Bearer $MARKETSDK_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-user_2002-1" \
  -d '{"listing": "lst_...", "buyer": "buy_...",
       "checkout": {"success_url": "https://shop.example/paid", "cancel_url": "https://shop.example/cart"}}'

When Stripe confirms the payment, the order becomes committed and you get payment.succeeded and order.committed. If the window passes first, the order is cancelled with reason payment_expired; a payment that still arrives after that is refunded in full.

4. Release to the seller

  • When the order completes, the price less your platform fee is transferred to the seller's connected account: payment.released. The amount is fixed when the release is queued.
  • If Stripe refuses the transfer, for example because the seller cannot receive transfers yet, you get payment.release_failed. We try again when the seller's payouts become enabled, or you can call POST /v1/payments/{id}/retry_release.
  • Stripe charges its processing fees to your account, as the platform. We never add to them.

Refunds

  • A cancelled or expired order is refunded in full, by itself.
  • Refund part or all of any payment with POST /v1/refunds, giving payment or order, and an amount in minor units. Without an amount, everything not yet refunded goes back.
  • If the seller's share was already released, the transfer is reversed in the same proportion, so your fee is given back in proportion too.
  • A refund starts pending and changes as Stripe reports: refund.updated.

Card disputes

When a buyer disputes the charge with their bank, Stripe tells us and we link the card dispute to the order, as card_disputes on any marketplace dispute for it, and send card_dispute.created. Card disputes are between you, Stripe, and the bank; answer them in your Stripe dashboard. They are separate from the disputes your team decides.

next: connecting stripe