Payouts to players
A payout sends money from your project’s balance to a player’s bank account — an iGaming withdrawal.
#!/usr/bin/env bash# Pay a player's withdrawal out of the project's balance.set -euo pipefail. "$(dirname "$0")/../signed-request.sh"
body=$(cat <<JSON{ "merchant_payout_id": "${PAYOUT_REF:-withdrawal-$(mka_new_key)}", "amount": "${AMOUNT:-5000.00}", "currency": "LKR", "recipient": { "bank_name": "Commercial Bank of Ceylon", "account_holder": "S. Jayasuriya", "account_number": "8001234567" }}JSON)mka_request POST "/v1/payouts" "$body" "$(mka_new_key)"// Pay a player's withdrawal out of the project's balance.import { newKey, print, request } from "../signed-request.mjs";
const answer = await request("POST", "/v1/payouts", { body: { merchant_payout_id: process.env.PAYOUT_REF ?? `withdrawal-${newKey()}`, amount: process.env.AMOUNT ?? "5000.00", currency: "LKR", recipient: { bank_name: "Commercial Bank of Ceylon", account_holder: "S. Jayasuriya", account_number: "8001234567", }, }, idempotencyKey: newKey(),});print(answer);<?php// Pay a player's withdrawal out of the project's balance.
declare(strict_types=1);
require __DIR__ . '/../signed_request.php';
mka_show(mka_request( 'POST', '/v1/payouts', [ 'merchant_payout_id' => getenv('PAYOUT_REF') ?: 'withdrawal-' . mka_new_key(), 'amount' => getenv('AMOUNT') ?: '5000.00', 'currency' => 'LKR', 'recipient' => [ 'bank_name' => 'Commercial Bank of Ceylon', 'account_holder' => 'S. Jayasuriya', 'account_number' => '8001234567', ], ], mka_new_key(),));"""Pay a player's withdrawal out of the project's balance."""import os
from signed_request import new_key, request, show
show(request( "POST", "/v1/payouts", body={ "merchant_payout_id": os.environ.get("PAYOUT_REF") or f"withdrawal-{new_key()}", "amount": os.environ.get("AMOUNT", "5000.00"), "currency": "LKR", "recipient": { "bank_name": "Commercial Bank of Ceylon", "account_holder": "S. Jayasuriya", "account_number": "8001234567", }, }, idempotency_key=new_key(),))//go:build ignore
// Pay a player's withdrawal out of the project's balance.package main
import ( "docs.processing.yolotech.cc/examples/signedrequest")
func main() { signedrequest.Show(signedrequest.Request("POST", "/v1/payouts", map[string]any{ "merchant_payout_id": signedrequest.Env("PAYOUT_REF", "withdrawal-"+signedrequest.NewKey()), "amount": signedrequest.Env("AMOUNT", "5000.00"), "currency": "LKR", "recipient": map[string]any{ "bank_name": "Commercial Bank of Ceylon", "account_holder": "S. Jayasuriya", "account_number": "8001234567", }, }, signedrequest.NewKey()))}merchant_payout_id— your withdrawal’s id, 1–128 characters, unique in the project. It is a second idempotency key: the same id with the same body answers the payout made first.amount— what the player receives, exactly.recipient—bank_name,account_holder,account_number(6 to 20 digits). Stored sealed, read back masked, never in a webhook.
The fee is on top. Your project’s rate for payouts to an account applies: the balance holds
amount + fee at once, and the fee is charged only if the payout succeeds. More than the available balance
is 422 insufficient_available_balance; no published rate is 422 payout_method_unavailable. Nothing is
held then.
The answer is 201 for a new payout. A repeat — the same key, or the same merchant_payout_id under a new
key, with the same body — is 200 with Idempotent-Replayed: true. Another body is
409 idempotency_conflict.
Statuses
Section titled “Statuses”| Status | Meaning |
|---|---|
pending |
Held from the balance; waiting for an Agent. You can still cancel. |
processing |
An Agent took it and is sending it. |
succeeded |
Sent and proven. The fee is charged. Final. |
failed |
Nobody took it within 24 hours (not_taken), or the platform refused it (refused). Amount and fee come back. Final. |
cancelled |
You withdrew it while pending. Amount and fee come back. Final. |
Every version, creation included, is a payout.status_changed webhook, delivered in order. A payout sent
quickly may go from pending straight to succeeded.
#!/usr/bin/env bash# Read one payout.set -euo pipefail. "$(dirname "$0")/../signed-request.sh"
payout_id=$(mka_required PAYOUT_ID)mka_request GET "/v1/payouts/$payout_id"// Read one payout.import { print, request, required } from "../signed-request.mjs";
const payoutId = required("PAYOUT_ID");const answer = await request("GET", `/v1/payouts/${payoutId}`);print(answer);<?php// Read one payout.
declare(strict_types=1);
require __DIR__ . '/../signed_request.php';
$payoutId = mka_required('PAYOUT_ID');mka_show(mka_request('GET', "/v1/payouts/{$payoutId}"));"""Read one payout."""from signed_request import request, required, show
payout_id = required("PAYOUT_ID")show(request("GET", f"/v1/payouts/{payout_id}"))//go:build ignore
// Read one payout.package main
import ( "docs.processing.yolotech.cc/examples/signedrequest")
func main() { payoutID := signedrequest.Required("PAYOUT_ID") signedrequest.Show(signedrequest.Request("GET", "/v1/payouts/"+payoutID, nil, ""))}Cancel
Section titled “Cancel”Only a pending payout can be cancelled; one an Agent took is 409 payout_not_cancellable.
#!/usr/bin/env bash# Cancel a payout no Agent took yet; the amount and fee come back.set -euo pipefail. "$(dirname "$0")/../signed-request.sh"
payout_id=$(mka_required PAYOUT_ID)mka_request POST "/v1/payouts/$payout_id/cancel" "" "$(mka_new_key)"// Cancel a payout no Agent took yet; the amount and fee come back.import { newKey, print, request, required } from "../signed-request.mjs";
const payoutId = required("PAYOUT_ID");const answer = await request("POST", `/v1/payouts/${payoutId}/cancel`, { idempotencyKey: newKey(),});print(answer);<?php// Cancel a payout no Agent took yet; the amount and fee come back.
declare(strict_types=1);
require __DIR__ . '/../signed_request.php';
$payoutId = mka_required('PAYOUT_ID');mka_show(mka_request( 'POST', "/v1/payouts/{$payoutId}/cancel", null, mka_new_key(),));"""Cancel a payout no Agent took yet; the amount and fee come back."""from signed_request import new_key, request, required, show
payout_id = required("PAYOUT_ID")show(request( "POST", f"/v1/payouts/{payout_id}/cancel", idempotency_key=new_key(),))//go:build ignore
// Cancel a payout no Agent took yet; the amount and fee come back.package main
import ( "docs.processing.yolotech.cc/examples/signedrequest")
func main() { payoutID := signedrequest.Required("PAYOUT_ID") signedrequest.Show(signedrequest.Request("POST", "/v1/payouts/"+payoutID+"/cancel", nil, signedrequest.NewKey()))}Lost the answer?
Section titled “Lost the answer?”After a timeout or a 503 payout_unavailable, retry under the same Idempotency-Key, or find the payout by
your own id:
GET /v1/payouts?merchant_payout_id=withdrawal-5001#!/usr/bin/env bash# The project's payouts, newest first.set -euo pipefail. "$(dirname "$0")/../signed-request.sh"
mka_request GET "/v1/payouts?limit=10"// The project's payouts, newest first.import { print, request } from "../signed-request.mjs";
const answer = await request("GET", "/v1/payouts?limit=10");print(answer);<?php// The project's payouts, newest first.
declare(strict_types=1);
require __DIR__ . '/../signed_request.php';
mka_show(mka_request('GET', '/v1/payouts?limit=10'));"""The project's payouts, newest first."""from signed_request import request, show
show(request("GET", "/v1/payouts?limit=10"))//go:build ignore
// The project's payouts, newest first.package main
import ( "docs.processing.yolotech.cc/examples/signedrequest")
func main() { signedrequest.Show(signedrequest.Request("GET", "/v1/payouts?limit=10", nil, ""))}The list is newest first: limit 1–100 (50 by default), starting_after with the last id of the previous
page, status to filter, and has_more.