Pay-Out API Specification
| Owner |
Classification |
Review Date |
Status |
| CDO Office |
Internal |
April 2027 |
Active |
openapi: 3.1.0
info:
title: Simpaisa Pay-Out API
version: 3.0.0
description: |
Simpaisa Pay-Out (Disbursements) API enables merchants to send funds to
bank accounts and mobile wallets across Pakistan, Bangladesh, Nepal,
and Iraq. The platform supports single and batch disbursements,
beneficiary management and real-time balance enquiries.
Processing 270M+ transactions and over $1B in volume, the disbursement
service provides reliable, auditable fund transfers with full idempotency
and webhook-based status notifications.
All requests must be signed using RSA-SHA256.
contact:
name: Simpaisa Platform Engineering
url: https://www.simpaisa.com
email: [email protected]
license:
name: Proprietary
url: https://www.simpaisa.com/terms
x-logo:
url: https://www.simpaisa.com/logo.png
servers:
- url: https://api.simpaisa.com
description: Production
- url: https://sandbox.simpaisa.com
description: Sandbox
security:
- rsaSha256Signature: []
paths:
/v3/disbursements/{merchantId}/transactions/initiate:
post:
operationId: initiateDisbursement
summary: Initiate a disbursement
description: |
Creates a new disbursement to transfer funds to a beneficiary's bank
account or mobile wallet. The transaction is processed asynchronously;
use the webhook callback or polling to track status.
tags:
- Transactions
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DisbursementRequest'
responses:
'201':
description: Disbursement initiated
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/DisbursementResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorised'
'409':
$ref: '#/components/responses/Conflict'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
callbacks:
disbursementStatusUpdate:
'{$request.body#/callbackUrl}':
post:
summary: Disbursement status webhook
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookPayload'
responses:
'200':
description: Webhook acknowledged
/v3/disbursements/{merchantId}/transactions/{transactionId}:
get:
operationId: getDisbursement
summary: Retrieve a disbursement
description: Returns the current state of a disbursement transaction.
tags:
- Transactions
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/TransactionIdPath'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
responses:
'200':
description: Disbursement retrieved
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/DisbursementResponse'
'401':
$ref: '#/components/responses/Unauthorised'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v3/disbursements/{merchantId}/transactions/batch:
post:
operationId: createBatchDisbursement
summary: Create a batch disbursement
description: |
Submits multiple disbursement instructions in a single request. Each
item in the batch is processed independently; partial failures are
possible. The response includes a batch identifier for tracking.
tags:
- Transactions
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchRequest'
responses:
'202':
description: Batch accepted for processing
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/BatchResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorised'
'409':
$ref: '#/components/responses/Conflict'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v3/disbursements/{merchantId}/transactions:
get:
operationId: listDisbursements
summary: List disbursement transactions
description: |
Returns a paginated list of disbursement transactions. Uses cursor-based
pagination for consistent results across large datasets.
tags:
- Transactions
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
- name: cursor
in: query
description: Opaque cursor from the previous response for pagination
schema:
type: string
- name: limit
in: query
description: Maximum number of records to return
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: status
in: query
description: Filter by transaction status
schema:
type: string
enum:
- INITIATED
- PROCESSING
- COMPLETED
- FAILED
- REVERSED
- name: fromDate
in: query
description: Start date filter (ISO 8601)
schema:
type: string
format: date-time
- name: toDate
in: query
description: End date filter (ISO 8601)
schema:
type: string
format: date-time
responses:
'200':
description: Transaction list retrieved
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
content:
application/json:
schema:
type: object
required:
- transactions
- pagination
- traceId
properties:
transactions:
type: array
items:
$ref: '#/components/schemas/DisbursementResponse'
pagination:
$ref: '#/components/schemas/CursorPagination'
traceId:
type: string
format: uuid
'401':
$ref: '#/components/responses/Unauthorised'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v3/disbursements/{merchantId}/balance:
get:
operationId: getDisbursementBalance
summary: Retrieve disbursement balance
description: Returns the merchant's current disbursement wallet balance.
tags:
- Balance
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
responses:
'200':
description: Balance retrieved
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/BalanceResponse'
'401':
$ref: '#/components/responses/Unauthorised'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v3/disbursements/{merchantId}/banks:
get:
operationId: listBanks
summary: List supported banks
description: |
Returns the list of banks and mobile wallet operators available for
disbursements in the merchant's configured corridors.
tags:
- Reference Data
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
responses:
'200':
description: Bank list retrieved
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/BankListResponse'
'401':
$ref: '#/components/responses/Unauthorised'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v3/disbursements/{merchantId}/beneficiaries:
post:
operationId: createBeneficiary
summary: Register a beneficiary
description: |
Creates a saved beneficiary record for recurring disbursements.
Beneficiary details are validated against the specified bank's
requirements.
tags:
- Beneficiaries
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BeneficiaryRequest'
responses:
'201':
description: Beneficiary created
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/BeneficiaryResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorised'
'409':
$ref: '#/components/responses/Conflict'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
components:
securitySchemes:
rsaSha256Signature:
type: apiKey
in: header
name: X-Signature
description: |
RSA-SHA256 signature computed over the canonical request string.
The merchant signs the request payload concatenated with the timestamp
using their RSA private key.
parameters:
MerchantIdPath:
name: merchantId
in: path
required: true
description: Unique merchant identifier issued during onboarding
schema:
type: string
example: MCH-00123
TransactionIdPath:
name: transactionId
in: path
required: true
description: Unique transaction identifier
schema:
type: string
format: uuid
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
description: |
Client-generated unique key for idempotent request processing.
Duplicate requests within 24 hours return the original response.
schema:
type: string
format: uuid
XMerchantId:
name: X-Merchant-Id
in: header
required: true
description: Merchant identifier for request authentication
schema:
type: string
XTimestamp:
name: X-Timestamp
in: header
required: true
description: ISO 8601 timestamp of the request
schema:
type: string
format: date-time
XSignature:
name: X-Signature
in: header
required: true
description: RSA-SHA256 signature of the canonical request string
schema:
type: string
headers:
XTraceId:
description: Unique trace identifier for request tracking
schema:
type: string
format: uuid
XRateLimitLimit:
description: Maximum requests permitted per window
schema:
type: integer
XRateLimitRemaining:
description: Requests remaining in current window
schema:
type: integer
XRateLimitReset:
description: Unix epoch when the rate limit resets
schema:
type: integer
schemas:
DisbursementRequest:
type: object
required:
- amount
- currency
- beneficiaryAccountNumber
- bankCode
- beneficiaryName
- merchantTransactionId
properties:
amount:
type: number
format: double
description: Disbursement amount
example: 25000.00
currency:
type: string
pattern: '^[A-Z]{3}$'
description: ISO 4217 currency code
example: PKR
beneficiaryAccountNumber:
type: string
description: Beneficiary account number or IBAN
example: PK36SCBL0000001123456702
bankCode:
type: string
description: Bank identifier from the banks endpoint
example: SCB
beneficiaryName:
type: string
description: Full name of the beneficiary
example: Ahmed Khan
beneficiaryId:
type: string
description: Saved beneficiary identifier (alternative to inline details)
merchantTransactionId:
type: string
description: Merchant's unique reference
maxLength: 64
example: PAYOUT-2026-00789
purpose:
type: string
description: Purpose of the disbursement
example: Salary payment
callbackUrl:
type: string
format: uri
description: URL for webhook notifications
metadata:
type: object
additionalProperties:
type: string
DisbursementResponse:
type: object
required:
- transactionId
- merchantTransactionId
- status
- amount
- currency
- traceId
properties:
transactionId:
type: string
format: uuid
merchantTransactionId:
type: string
status:
type: string
enum:
- INITIATED
- PROCESSING
- COMPLETED
- FAILED
- REVERSED
amount:
type: number
format: double
currency:
type: string
beneficiaryAccountNumber:
type: string
beneficiaryName:
type: string
bankCode:
type: string
bankTransactionId:
type: string
description: Reference from the receiving bank
failureReason:
type: string
description: Reason for failure, if applicable
completedAt:
type: string
format: date-time
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
metadata:
type: object
additionalProperties:
type: string
traceId:
type: string
format: uuid
BatchRequest:
type: object
required:
- items
- merchantBatchId
properties:
merchantBatchId:
type: string
description: Merchant's unique batch reference
maxLength: 64
example: BATCH-2026-00123
items:
type: array
minItems: 1
maxItems: 500
items:
$ref: '#/components/schemas/DisbursementRequest'
description: Individual disbursement instructions
callbackUrl:
type: string
format: uri
description: URL for batch-level webhook notifications
BatchResponse:
type: object
required:
- batchId
- merchantBatchId
- status
- totalItems
- traceId
properties:
batchId:
type: string
format: uuid
description: Simpaisa-assigned batch identifier
merchantBatchId:
type: string
status:
type: string
enum:
- ACCEPTED
- PROCESSING
- COMPLETED
- PARTIALLY_COMPLETED
- FAILED
totalItems:
type: integer
description: Total number of items in the batch
acceptedItems:
type: integer
description: Number of items accepted for processing
rejectedItems:
type: integer
description: Number of items rejected at submission
totalAmount:
type: number
format: double
description: Sum of all accepted item amounts
currency:
type: string
createdAt:
type: string
format: date-time
traceId:
type: string
format: uuid
BalanceResponse:
type: object
required:
- availableBalance
- currency
- traceId
properties:
availableBalance:
type: number
format: double
description: Funds available for disbursement
example: 5000000.00
pendingBalance:
type: number
format: double
description: Funds reserved for in-flight disbursements
example: 150000.00
currency:
type: string
example: PKR
lastUpdatedAt:
type: string
format: date-time
traceId:
type: string
format: uuid
BankListResponse:
type: object
required:
- banks
- traceId
properties:
banks:
type: array
items:
type: object
required:
- bankCode
- name
- country
- status
properties:
bankCode:
type: string
example: HBL
name:
type: string
example: Habib Bank Limited
country:
type: string
description: ISO 3166-1 alpha-2 country code
example: PK
type:
type: string
enum:
- BANK
- MOBILE_WALLET
- MICROFINANCE
accountNumberFormat:
type: string
description: Expected account number pattern
example: '^PK[0-9]{2}[A-Z]{4}[0-9]{16}$'
status:
type: string
enum:
- ACTIVE
- DEGRADED
- INACTIVE
traceId:
type: string
format: uuid
BeneficiaryRequest:
type: object
required:
- name
- accountNumber
- bankCode
properties:
name:
type: string
description: Full legal name of the beneficiary
example: Fatima Bibi
accountNumber:
type: string
description: Account number or IBAN
example: PK36SCBL0000001123456702
bankCode:
type: string
description: Bank identifier
example: SCB
accountType:
type: string
enum:
- CURRENT
- SAVINGS
- WALLET
description: Type of account
msisdn:
type: string
description: Mobile number in E.164 format (required for wallet disbursements)
email:
type: string
format: email
description: Beneficiary email for notifications
metadata:
type: object
additionalProperties:
type: string
BeneficiaryResponse:
type: object
required:
- beneficiaryId
- name
- accountNumber
- bankCode
- traceId
properties:
beneficiaryId:
type: string
format: uuid
name:
type: string
accountNumber:
type: string
bankCode:
type: string
accountType:
type: string
msisdn:
type: string
email:
type: string
createdAt:
type: string
format: date-time
traceId:
type: string
format: uuid
CursorPagination:
type: object
required:
- hasMore
properties:
cursor:
type: string
description: Opaque cursor to fetch the next page
hasMore:
type: boolean
description: Whether additional pages exist
totalCount:
type: integer
description: Total number of matching records (when available)
WebhookPayload:
type: object
required:
- event
- transactionId
- merchantTransactionId
- status
- timestamp
- signature
properties:
event:
type: string
enum:
- DISBURSEMENT_COMPLETED
- DISBURSEMENT_FAILED
- DISBURSEMENT_REVERSED
- BATCH_COMPLETED
- BATCH_PARTIALLY_COMPLETED
transactionId:
type: string
format: uuid
merchantTransactionId:
type: string
batchId:
type: string
format: uuid
status:
type: string
amount:
type: number
format: double
currency:
type: string
bankTransactionId:
type: string
failureReason:
type: string
timestamp:
type: string
format: date-time
signature:
type: string
description: RSA-SHA256 signature for webhook verification
ErrorResponse:
type: object
required:
- error
- traceId
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
example: INSUFFICIENT_BALANCE
message:
type: string
example: Insufficient funds for this disbursement.
details:
type: array
items:
type: object
properties:
field:
type: string
reason:
type: string
traceId:
type: string
format: uuid
responses:
BadRequest:
description: Invalid request parameters
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorised:
description: Authentication failed
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: Resource not found
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Conflict:
description: Duplicate Idempotency-Key with different request body
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
UnprocessableEntity:
description: Request understood but cannot be processed
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
TooManyRequests:
description: Rate limit exceeded
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
InternalServerError:
description: Unexpected server error
headers:
X-Trace-Id:
$ref: '#/components/headers/XTraceId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
tags:
- name: Transactions
description: Disbursement transaction lifecycle operations
- name: Balance
description: Wallet balance enquiries
- name: Reference Data
description: Banks and operator discovery
- name: Beneficiaries
description: Saved beneficiary management