Distribute Payments
Make transactions with multiple payments to different beneficiaries in a single atomic operation. Perfect for marketplaces, commission-based platforms, and split payment scenarios.
All payments in a transaction succeed together or fail together - ensuring atomic operations.
Use Case: Marketplace Payment Split
Customer buys from multiple sellers in one checkout. Payment is automatically distributed to all sellers in a single transaction.
Example: Customer orders from 2 sellers:
- €10 to Seller A (wallet 11111111)
- €15 to Seller B (wallet 22222222)
- Total: €25 from customer
Payment Flow
Benefits
- ✅ Atomic Operations - Either all payments succeed or all fail
- ✅ Single Confirmation - Customer confirms once for multiple beneficiaries
- ✅ Automatic Distribution - Funds automatically distributed to all beneficiaries
- ✅ Commission Support - Easy to add platform commission as separate payment
Key Concepts
Transaction: Groups multiple payments into one atomic operation
- Single transaction_key for all payments
- Single user confirmation
- All-or-nothing execution
Payment: Individual payment to one beneficiary
- Unique beneficiary (wallet_id)
- Own amount and description
- Part of parent transaction
Implementation Examples
- PHP
- Python
- Direct API
<?php
require_once 'vendor/autoload.php';
use Paysera\WalletApi\ClientFactory;
use Paysera\WalletApi\Entity\Transaction;
use Paysera\WalletApi\Entity\Payment;
use Paysera\WalletApi\Entity\Item;
use Paysera\WalletApi\Entity\Money;
use Paysera\WalletApi\Entity\WalletIdentifier;
class MarketplacePayments
{
private $client;
public function __construct($clientId, $secret)
{
$factory = ClientFactory::create([
'auth' => [
'mac' => [
'mac_id' => $clientId,
'mac_secret' => $secret,
],
],
]);
$this->client = $factory->getWalletClient();
}
public function createMarketplacePayment($orderData)
{
$transaction = Transaction::create()
->setRedirectUri($orderData['redirect_uri']);
// Add payment for each seller
foreach ($orderData['sellers'] as $seller) {
$payment = $this->createSellerPayment($seller);
$transaction->addPayment($payment);
}
// Optional: Add platform commission
if (isset($orderData['commission'])) {
$commissionPayment = $this->createCommissionPayment(
$orderData['commission']
);
$transaction->addPayment($commissionPayment);
}
$created = $this->client->createTransaction($transaction);
return $created;
}
private function createSellerPayment($sellerData)
{
$beneficiary = WalletIdentifier::create()
->setId($sellerData['wallet_id']);
$payment = Payment::create()
->setDescription($sellerData['description'])
->setBeneficiary($beneficiary);
foreach ($sellerData['items'] as $itemData) {
$item = $this->createItem($itemData);
$payment->addItem($item);
}
return $payment;
}
private function createItem($itemData)
{
$price = Money::create()
->setAmountInCents($itemData['price'])
->setCurrency('EUR');
return Item::create()
->setTitle($itemData['title'])
->setDescription($itemData['description'])
->setPrice($price)
->setQuantity($itemData['quantity']);
}
}
// Usage
$marketplace = new MarketplacePayments('wkVd93h2uS', 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU');
$orderData = [
'redirect_uri' => 'https://yourmarketplace.com/payment-return',
'sellers' => [
[
'wallet_id' => 11111111,
'description' => 'Order from Seller A',
'items' => [
[
'title' => 'Product A1',
'description' => 'Description',
'price' => 1000,
'quantity' => 1,
],
],
],
[
'wallet_id' => 22222222,
'description' => 'Order from Seller B',
'items' => [
[
'title' => 'Product B1',
'description' => 'Description',
'price' => 1500,
'quantity' => 1,
],
],
],
],
'commission' => [
'wallet_id' => 33333333,
'amount' => 250,
],
];
$transaction = $marketplace->createMarketplacePayment($orderData);
import requests
import hmac
import hashlib
import time
from flask import Flask, request, redirect, session
app = Flask(__name__)
class MarketplacePayments:
def __init__(self, client_id, mac_secret):
self.client_id = client_id
self.mac_secret = mac_secret
self.base_url = 'https://wallet.paysera.com/rest/v1'
def create_marketplace_transaction(self, order_data):
url = f'{self.base_url}/transaction'
payments = []
for seller in order_data['sellers']:
payments.append({
'description': seller['description'],
'items': seller['items'],
'beneficiary': {'id': seller['wallet_id']}
})
if 'commission' in order_data:
comm = order_data['commission']
payments.append({
'description': 'Platform Fee',
'items': [{
'title': 'Commission',
'price': comm['amount'],
'currency': 'EUR',
'quantity': 1
}],
'beneficiary': {'id': comm['wallet_id']}
})
data = {
'payments': payments,
'redirect_uri': order_data['redirect_uri']
}
headers = self.generate_mac_headers('POST', '/rest/v1/transaction')
headers['Content-Type'] = 'application/json'
response = requests.post(url, json=data, headers=headers)
return response.json()
@app.route('/checkout', methods=['POST'])
def checkout():
order_data = {
'redirect_uri': 'http://localhost:5000/payment-return',
'sellers': [
{
'wallet_id': 11111111,
'description': 'Order from Seller A',
'items': [{'title': 'Product A', 'price': 1000, 'currency': 'EUR', 'quantity': 1}]
},
{
'wallet_id': 22222222,
'description': 'Order from Seller B',
'items': [{'title': 'Product B', 'price': 1500, 'currency': 'EUR', 'quantity': 1}]
}
],
'commission': {'wallet_id': 33333333, 'amount': 250}
}
transaction = marketplace.create_marketplace_transaction(order_data)
session['transaction_key'] = transaction['transaction_key']
return redirect(f"https://www.paysera.com/wallet/confirm/{transaction['transaction_key']}")
POST https://wallet.paysera.com/rest/v1/transaction
Request Body:
{
"payments": [
{
"description": "Order from Seller A",
"items": [{"title": "Product A", "price": 1000, "currency": "EUR", "quantity": 1}],
"beneficiary": {"id": 11111111}
},
{
"description": "Order from Seller B",
"items": [{"title": "Product B", "price": 1500, "currency": "EUR", "quantity": 1}],
"beneficiary": {"id": 22222222}
},
{
"description": "Platform Fee",
"items": [{"title": "Commission", "price": 250, "currency": "EUR", "quantity": 1}],
"beneficiary": {"id": 33333333}
}
],
"redirect_uri": "https://yoursite.com/return"
}
Common Use Cases
1. Marketplace Platform
Scenario: Multi-vendor marketplace
Implementation: Payment per vendor + platform commission
$payments = [
['vendor_1', €10],
['vendor_2', €15],
['platform_fee', €2.50],
];
2. Affiliate Commission Split
Scenario: Product sale with affiliate
Implementation: Payment to merchant (80%) + affiliate (20%)
3. Service Fee Collection
Scenario: Service booking with fee
Implementation: Service provider + platform fee + insurance (optional)
Advanced Topics
Best Practices
Do:
- ✅ Validate wallet IDs before creating payments
- ✅ Calculate commission server-side
- ✅ Store transaction mapping in database
- ✅ Handle all-or-nothing gracefully
- ✅ Verify beneficiaries are active
- ✅ Log all distributions
Don't:
- ❌ Don't exceed limits on number of payments
- ❌ Don't create duplicate payments to same beneficiary
- ❌ Don't skip validation of amounts
- ❌ Don't forget commission calculation
- ❌ Don't ignore failed transactions
Database Schema
-- Marketplace orders
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
total_amount INT NOT NULL,
commission_amount INT NOT NULL,
transaction_key VARCHAR(50),
status VARCHAR(20),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_transaction (transaction_key)
);
-- Order items per seller
CREATE TABLE order_items (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT NOT NULL,
seller_id INT NOT NULL,
seller_wallet_id INT NOT NULL,
product_name VARCHAR(255),
amount INT NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
Commission Calculations
Percentage Commission:
function calculateCommission($orderTotal, $commissionRate = 0.10) {
return (int)($orderTotal * $commissionRate);
}
// Example: 10% of €25 = €2.50
$commission = calculateCommission(2500, 0.10); // 250 cents
Tiered Commission:
function getTieredCommission($amount) {
if ($amount < 5000) return $amount * 0.15; // 15%
elseif ($amount < 10000) return $amount * 0.10; // 10%
else return $amount * 0.05; // 5%
}
Error Handling
Insufficient funds:
try {
$transaction = $client->createTransaction($data);
} catch (ApiException $e) {
if ($e->getErrorCode() === 'insufficient_funds') {
return 'Insufficient balance for all payments';
}
}
Invalid beneficiary:
foreach ($sellers as $seller) {
if (!$this->isValidWallet($seller['wallet_id'])) {
throw new Exception("Invalid seller wallet: {$seller['wallet_id']}");
}
}
Testing
Wallet API does not have a sandbox environment. All testing must be done in production with real transactions.
Test Scenarios:
- Single payment - Verify basic flow
- Multiple payments - 2-3 beneficiaries
- With commission - Include platform fee
- Insufficient funds - Customer can't pay all
- Partial confirmation - Transaction behavior
Testing Strategy:
- Use small test amounts (1-5 EUR)
- Test with real wallet accounts
- Monitor all transactions carefully
- Verify distribution to all beneficiaries
Resources
- Transaction Resource - Transaction handling
- Payment Resource - Payment details
- PHP Library - PHP SDK
Next Steps
- Set up seller wallet validation
- Implement commission calculation
- Create distribution reports
- Add payout scheduling
- Monitor transaction success rates
Always validate beneficiary wallet IDs and calculate commissions server-side to prevent manipulation.