Skip to main content
Facilitate split payment services where a single payment is divided among multiple recipients. Perfect for splitting bills, shared expenses, or distributing funds to multiple stakeholders efficiently. ⏱️ Time to complete: 25-35 minutes 🎯 What you’ll build: A split payment system where users deposit USD into a virtual account, funds convert to USDC, then split payments are distributed to multiple recipients. This guide covers two approaches: settlement rules for configured automatic splits, and batch transfers for on-demand splits.

Use Case Overview

This recipe demonstrates a split payment flow where:
  • ✅ Users deposit USD into dedicated virtual accounts
  • ✅ USD automatically converts to USDC stablecoin
  • ✅ Payments are split among multiple recipients using one of two methods
  • ✅ Operational overhead is minimized through automation
This flow enables scalable split payment services with reduced processing costs and efficient fund distribution. Choose the method that best fits your use case:
  • Settlement Rules (Option 1): Configure split percentages or amounts once, then every deposit automatically splits according to your rules. Perfect for recurring splits with fixed recipients and ratios.
  • Batch Transfers (Option 2): Manually initiate split payments on-demand with full control over amounts and recipients. Perfect for bill payments or dynamic splits that vary per transaction.

What you’ll build

Here’s what we’ll accomplish in this recipe:
  1. Generate API Keys - Set up authentication for HIFI API
  2. Create User - Onboard a user and complete KYC for USD rail
  3. Add Virtual Account - Set up account for collecting USD payments that convert to USDC
  4. Choose Your Split Method:
    • Option 1: Settlement Rules - Configure automatic split payment distribution
    • Option 2: Batch Transfers - Execute on-demand split payments
Payment Flow (Option 1 - Settlement Rules):
USD → User Bank Account → Virtual Account → USDC → Settlement Rule → Automatic Split to Multiple Recipients
Payment Flow (Option 2 - Batch Transfers):
USD → User Bank Account → Virtual Account → USDC → Batch Transfer → Multiple Recipients
All examples in this guide use the sandbox environment. When you’re ready for production, simply replace the sandbox URL with the production endpoint and use your production API keys.

Generate API Keys

Access to the HIFI API requires authentication via API keys. Generate your keys from the HIFI Dashboard before making any API calls. Be sure to copy the key immediately as it’s only shown once. For a complete guide on API authentication, see our Authentication Documentation.
Include your API key in the Authorization header of all API requests:
--header 'authorization: Bearer YOUR_API_KEY'

Create User

Create a verified user account for the person making the split payment. Every user must accept HIFI’s Terms of Service and complete KYC verification before they can access fiat rails and make payments.
Complete Onboarding Guide: For a comprehensive walkthrough of user onboarding and KYC verification, see our User Guide.
Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "type": "individual",
  "firstName": "John",
  "lastName": "Doe",
  "email": "[email protected]",
  "dateOfBirth": "1990-01-01",
  "address": {
    "addressLine1": "123 Park Ave",
    "city": "Kansas City",
    "stateProvinceRegion": "KS",
    "postalCode": "10001",
    "country": "USA"
  },
  "signedAgreementId": "c9c91801-d3a2-4a1c-aa2e-fcb2c473198c",
  "requestId": "705f1f8b-a080-467c-b683-174eca409928"
}
'
Response:
{
  "id": "3b77cec8-1bb9-5ea0-91a1-e8c1411dd429",
  "type": "individual",
  "email": "[email protected]",
  "name": "John Doe",
  "wallets": {
    "INDIVIDUAL": {
      "ETHEREUM": {
        "address": "0x062f27D749Db9AdE709FaCF753e71618a0d64eF7"
      },
      "POLYGON": {
        "address": "0x63dAbB631bcE6d6090A4e6c5c7aB20d3D853C338"
      }
    }
  }
}
Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users/3b77cec8-1bb9-5ea0-91a1-e8c1411dd429/kyc \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "firstName": "John",
  "phone": "+11111111111",
  "taxIdentificationNumber": "678898765",
  "nationality": "USA"
}
'
Response:
{
  "userId": "3b77cec8-1bb9-5ea0-91a1-e8c1411dd429",
  "kycInfo": {
    "type": "individual",
    "firstName": "John",
    "lastName": "Doe",
    "nationality": "USA",
    "email": "[email protected]",
    "phone": "+11111111111",
    "address": {
      "city": "Kansas City",
      "country": "USA",
      "postalCode": "10001",
      "addressLine1": "123 Park Ave",
      "stateProvinceRegion": "KS"
    },
    "dateOfBirth": "1990-01-01T00:00:00+00:00",
    "taxIdentificationNumber": "678898765",
    "documents": []
  }
}
Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users/3b77cec8-1bb9-5ea0-91a1-e8c1411dd429/kyc/submissions \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "rails": "USD"
}
'
Response:
{
  "currency": "USD",
  "status": "ACTIVE",
  "reviewResult": {
    "reviewAnswer": "APPROVED",
    "reviewRejectType": "",
    "rejectReasons": [],
    "comment": ""
  },
  "details": {
    "identity": {
      "reviewAnswer": "APPROVED",
      "documents": [
        {
          "id": "c00791d0-213a-480a-9e54-1c535673f10c",
          "type": "PASSPORT",
          "subType": "SINGLE_SIDE",
          "reviewAnswer": "APPROVED"
        }
      ]
    },
    "questionnaire": {
      "reviewAnswer": "APPROVED",
      "details": []
    },
    "personalInfo": {
      "reviewAnswer": "APPROVED",
      "details": []
    }
  }
}

Add Virtual Account

Now that the user has passed KYC, create a Virtual Account for collecting the payment to be split. This is a bank account number automatically created by HIFI that users can deposit USD into. When fiat arrives, it’s automatically converted to USDC and ready for distribution.
Virtual Account for Split Payments: Each virtual account comes with unique ACH/wire/RTP details you can surface in your app. When deposits arrive, HIFI detects the funds and applies your conversion settings (e.g., USD → USDC). You can then use settlement rules for automatic splitting or batch transfers for on-demand splitting.
Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users/3b77cec8-1bb9-5ea0-91a1-e8c1411dd429/virtual-accounts \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "sourceCurrency": "usd",
  "destinationCurrency": "usdc",
  "destinationChain": "POLYGON"
}
'
Response:
{
  "id": "c48d1dd1-b5cd-5bc7-b85e-df1b0f17c1c8",
  "status": "activated",
  "provider": "CROSS_RIVER",
  "userId": "3b77cec8-1bb9-5ea0-91a1-e8c1411dd429",
  "source": {
    "paymentRails": ["ach", "wire", "rtp"],
    "currency": "usd"
  },
  "destination": {
    "chain": "POLYGON",
    "currency": "usdc",
    "walletAddress": "0x63dAbB631bcE6d6090A4e6c5c7aB20d3D853C338"
  },
  "depositInstructions": {
    "bankName": "Cross River Bank",
    "bankAddress": "885 Teaneck Road, Teaneck, NJ 07666",
    "beneficiary": {
      "name": "John Doe",
      "address": "123 Park Ave, Kansas City, KS, 10001, US"
    },
    "ach": {
      "routingNumber": "021214891",
      "accountNumber": "372232122120"
    },
    "wire": {
      "routingNumber": "021214891",
      "accountNumber": "372232122120"
    },
    "instruction": "Please deposit USD to the bank account provided. Ensure that the beneficiary name matches the account holder name provided, or the payment may be rejected."
  }
}

Option 1: Split Payments with Settlement Rules

Settlement rules automatically distribute funds to multiple recipients whenever a deposit arrives at the virtual account. Configure the split percentages or amounts once, and every deposit will automatically split according to your rules.
When to Use Settlement Rules: Use settlement rules when you have: - Fixed recipient lists that don’t change frequently - Consistent split ratios (e.g., always split 50/50 or 33/33/34) - Recurring split payments that should happen automatically - Set-and-forget split configurations Perfect for shared expenses, recurring bill splits, or fixed revenue sharing.
Create a settlement rule that defines how to split payments among multiple recipients. Each rule in the array sends a portion of the payment to a different wallet address.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/virtual-accounts/settlement-rules \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "chain": "POLYGON",
  "includeHIFIFee": false,
  "rules": [
    {
      "type": "PERCENTAGE",
      "calculationModel": "FIXED",
      "value": 0.3333,
      "walletAddress": "0xA4C951a7ca4138220a9D4611e7A058d4673e14c3"
    },
    {
      "type": "PERCENTAGE",
      "calculationModel": "FIXED",
      "value": 0.3333,
      "walletAddress": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760"
    },
    {
      "type": "PERCENTAGE",
      "calculationModel": "FIXED",
      "value": 0.3334,
      "walletAddress": "0x8356d234077d4b7c71E35c95B075ed4ba5FF7681"
    }
  ]
}
'
Request Fields:
requestId
string
required
Unique identifier (UUID) for this request to ensure idempotency.
chain
string
required
Blockchain network for the settlement rule. Must match the virtual account’s destination chain (e.g., POLYGON, ETHEREUM, BASE, SOLANA).
includeHIFIFee
boolean
Whether to include HIFI’s platform fee in the calculation. Defaults to false. Contact HIFI support if you want to include HIFI’s fee.
rules
array
required
Array of settlement rules. Each rule defines a portion of the payment to send to a recipient wallet.
Response:
{
  "id": "15c786fb-de7a-520c-a4b3-f312d4a122d2",
  "chain": "POLYGON",
  "includeHIFIFee": false,
  "rules": [
    {
      "type": "PERCENTAGE",
      "calculationModel": "FIXED",
      "value": 0.3333,
      "tiers": null,
      "walletAddress": "0xA4C951a7ca4138220a9D4611e7A058d4673e14c3"
    },
    {
      "type": "PERCENTAGE",
      "calculationModel": "FIXED",
      "value": 0.3333,
      "tiers": null,
      "walletAddress": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760"
    },
    {
      "type": "PERCENTAGE",
      "calculationModel": "FIXED",
      "value": 0.3334,
      "tiers": null,
      "walletAddress": "0x8356d234077d4b7c71E35c95B075ed4ba5FF7681"
    }
  ]
}
Settlement rule created!Response Fields:
id
string
The unique settlement rule ID. Save this - you’ll need it to apply the rule to the virtual account.
chain
string
Blockchain network the rule is configured for. Must match your virtual account’s destination chain.
rules
array
Array of rules defining how the payment is split among recipients.
Split Payment Example: In this example, we’re splitting payments equally among three recipients (33.33%, 33.33%, 33.34%). You can adjust the percentages to split unevenly, or use fixed amounts if you prefer. The remaining amount after all rules are applied goes to the user’s wallet.
After creating the settlement rule, apply it to the virtual account. Once applied, every deposit will automatically be split according to the rule.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users/3b77cec8-1bb9-5ea0-91a1-e8c1411dd429/virtual-accounts/c48d1dd1-b5cd-5bc7-b85e-df1b0f17c1c8/settlement-rules/15c786fb-de7a-520c-a4b3-f312d4a122d2 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY'
Path Parameters:
userId
string
required
The user ID who owns the virtual account.
accountId
string
required
The virtual account ID to apply the rule to.
ruleId
string
required
The settlement rule ID from the create response.
Response:
{
  "success": true
}
Settlement rule applied!
Chain Compatibility: The settlement rule must be created on the same blockchain network as the virtual account’s destination chain. For example, a virtual account configured for POLYGON can only use settlement rules created on POLYGON.
Automatic Split Payments: Once the settlement rule is applied, every deposit to this virtual account will automatically be split according to your rules. No manual intervention required! Monitor split payments by subscribing to ONRAMP.CREATE and ONRAMP.UPDATE webhook events.
For a complete guide on settlement rules including tiered pricing and advanced configurations, see our Settlement Rules Guide.

Option 2: Split Payments with Batch Transfers

Batch transfers let you manually initiate split payments with full control over amounts and recipients for each transaction. You decide when to split and can customize the distribution for each payment.
When to Use Batch Transfers: Use batch transfers when you need: - On-demand split payments that vary per transaction - Dynamic recipient lists that change based on the payment - Conditional logic before splitting (e.g., verify amounts, check balances) - Bill payments where amounts differ each time
  • One-time or irregular split payments Perfect for bill payment services, dynamic revenue sharing, or variable expense splits.
Create a batch transfer to split a payment among multiple recipients in a single transaction using the Create Batch Transfer endpoint.In this example, we’ll split a payment to three different recipients with 10 USDC each from the user’s wallet.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/wallets/transfers/batches \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "requestId": "b91772a6-f9c0-4479-a34c-c8723608d2e8",
  "currency": "usdc",
  "chain": "POLYGON",
  "source": {
    "userId": "3b77cec8-1bb9-5ea0-91a1-e8c1411dd429"
  },
  "destination": {
    "batch": [
      {
        "walletAddress": "0xA4C951a7ca4138220a9D4611e7A058d4673e14c3",
        "amount": "10"
      },
      {
        "walletAddress": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760",
        "amount": "10"
      },
      {
        "walletAddress": "0x8356d234077d4b7c71E35c95B075ed4ba5FF7681",
        "amount": "10"
      }
    ]
  },
  "requireApproval": false
}
'
Request Fields:
requestId
string
required
Unique identifier (UUID) for this batch transfer request to ensure idempotency.
currency
string
required
Cryptocurrency to transfer. Use usdc for USD Coin.
chain
string
required
Blockchain network for the transfer. Options: POLYGON, ETHEREUM
source
object
required
Source of the batch transfer (the user making the split payment).
destination
object
required
Destination configuration containing the batch of recipients.
requireApproval
boolean
Whether the batch transfer requires manual approval before execution. Set to false for automatic processing.
Response:
{
  "id": "467e8eed-c6e2-4f78-9404-a82148c49e0e",
  "type": "WALLET.TRANSFER.BATCH",
  "status": "CREATED",
  "chain": "POLYGON",
  "currency": "usdc",
  "contractAddress": "0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582",
  "source": {
    "userId": "3b77cec8-1bb9-5ea0-91a1-e8c1411dd429",
    "walletAddress": "0x63dAbB631bcE6d6090A4e6c5c7aB20d3D853C338",
    "walletType": "INDIVIDUAL"
  },
  "destination": {
    "batch": [
      {
        "amount": "10",
        "walletAddress": "0xA4C951a7ca4138220a9D4611e7A058d4673e14c3"
      },
      {
        "amount": "10",
        "walletAddress": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760"
      },
      {
        "amount": "10",
        "walletAddress": "0x8356d234077d4b7c71E35c95B075ed4ba5FF7681"
      }
    ]
  },
  "receipt": {
    "transactionHash": null,
    "userOpHash": null
  }
}
Batch transfer created!Response Fields:
id
string
Unique batch transfer ID. Save this to monitor the batch status and retrieve transaction details.
type
string
Transfer type. Always WALLET.TRANSFER.BATCH for batch transfers.
status
string
Current batch status. Starts as CREATED, then progresses through: - CREATED - Batch transfer initiated - PENDING - Being processed on blockchain - COMPLETED - All payments successfully delivered - FAILED - One or more payments failed (check individual statuses)
chain
string
Blockchain network where the transfer is being executed.
currency
string
Cryptocurrency being transferred.
contractAddress
string
Smart contract address handling the USDC transfers on the blockchain.
source
object
Source details showing the user’s wallet information.
destination
object
Destination details showing all recipients in the batch.
receipt
object
Transaction receipt information.
Understanding the Batch Transfer:In this example:
  • Source: User’s wallet (0x63dA...C338) with 30+ USDC available
  • Batch: 3 recipients receiving 10 USDC each
  • Total: 30 USDC distributed in a single blockchain transaction
  • Cost Savings: One transaction fee instead of three separate transactions
Monitoring Batch Transfers: Subscribe to WALLET.TRANSFER.BATCH.UPDATE webhook events to receive real-time notifications as the batch progresses. You can also poll the Retrieve Batch Transfer endpoint to check individual payment statuses within the batch.
For a complete guide on batch transfers including advanced features like approval workflows and error handling, see our Batch Transfers Guide.

🎉 Congratulations!

You’ve successfully built a split payment system! By following this recipe, you can now:
  • ✅ Generate API keys and authenticate with HIFI
  • ✅ Onboard users and complete KYC for USD operations
  • ✅ Create virtual accounts for collecting payments with automatic conversion
  • ✅ Configure settlement rules for automatic split payments (Option 1)
  • ✅ Execute batch transfers for on-demand split payments (Option 2)
  • ✅ Choose the right method based on your use case
  • ✅ Reduce operational overhead with automated or consolidated transactions

Next Steps

Ready to scale your split payment service? Here’s what to explore next:
  • Settlement Rules Guide - Deep dive into advanced settlement rule features like tiered pricing, fixed amounts, and multiple rule configurations
  • Batch Transfers Guide - Learn about batch transfers with approval workflows, failure handling, and advanced features
  • Webhooks - Set up real-time notifications for deposit detection, conversion completion, and split payment distribution
  • Virtual Accounts Guide - Learn about monitoring deposits and handling multiple virtual accounts per user
  • API Reference - Explore all available endpoints and parameters for advanced features