Remittance API Specification
| Owner |
Classification |
Review Date |
Status |
| CDO Office |
Internal |
April 2027 |
Active |
openapi: 3.1.0
info:
title: Simpaisa Remittance API
version: 3.0.0
description: |
Simpaisa Remittance API enables licensed remittance partners to send
cross-border transfers to recipients in Pakistan, Bangladesh, Nepal,
and Iraq. The platform provides real-time FX rates, quote
confirmation, beneficiary management and end-to-end transaction tracking.
Processing 270M+ transactions and over $1B in volume, the remittance
corridor supports bank account credits, mobile wallet top-ups and
cash pick-up disbursements with full regulatory compliance.
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/remittances/{merchantId}/fx-rates:
get:
operationId: getFXRates
summary: Retrieve current FX rates
description: |
Returns indicative foreign exchange rates for available currency
corridors. Rates are refreshed periodically and include a validity
window. Use the quote confirmation endpoint to lock a rate.
tags:
- Foreign Exchange
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
- name: sourceCurrency
in: query
description: Filter by source currency (ISO 4217)
schema:
type: string
example: GBP
- name: destinationCurrency
in: query
description: Filter by destination currency (ISO 4217)
schema:
type: string
example: PKR
responses:
'200':
description: FX rates 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/FXRateResponse'
'401':
$ref: '#/components/responses/Unauthorised'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v3/remittances/{merchantId}/quotes/confirm:
post:
operationId: confirmQuote
summary: Confirm and lock an FX quote
description: |
Locks an FX rate for a specified duration, creating a confirmed quote
that can be used to initiate a remittance transaction. The quote
includes the guaranteed exchange rate and the calculated receive amount.
tags:
- Foreign Exchange
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/QuoteConfirmRequest'
responses:
'201':
description: Quote confirmed and locked
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/QuoteConfirmResponse'
'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/remittances/{merchantId}/transactions/initiate:
post:
operationId: initiateRemittance
summary: Initiate a remittance transaction
description: |
Creates a new cross-border remittance using a confirmed quote. The
transaction is processed asynchronously; status updates are delivered
via webhook or can be polled.
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/RemittanceRequest'
responses:
'201':
description: Remittance 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/RemittanceResponse'
'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:
remittanceStatusUpdate:
'{$request.body#/callbackUrl}':
post:
summary: Remittance status webhook
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookPayload'
responses:
'200':
description: Webhook acknowledged
/v3/remittances/{merchantId}/transactions/{transactionId}:
get:
operationId: getRemittance
summary: Retrieve a remittance transaction
description: Returns the current state of a remittance 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: Remittance 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/RemittanceResponse'
'401':
$ref: '#/components/responses/Unauthorised'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v3/remittances/{merchantId}/transactions:
get:
operationId: listRemittances
summary: List remittance transactions
description: Returns a paginated list of remittance transactions.
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 for pagination
schema:
type: string
- name: limit
in: query
description: Maximum 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
- COMPLIANCE_HOLD
- PROCESSING
- COMPLETED
- FAILED
- RETURNED
- name: fromDate
in: query
schema:
type: string
format: date-time
- name: toDate
in: query
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/RemittanceResponse'
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/remittances/{merchantId}/balance:
get:
operationId: getRemittanceBalance
summary: Retrieve remittance balance
description: Returns the merchant's remittance corridor balances.
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/remittances/{merchantId}/banks:
get:
operationId: listRemittanceBanks
summary: List banks for remittance corridors
description: |
Returns the list of receiving banks and payout channels available
in the merchant's configured remittance corridors.
tags:
- Reference Data
parameters:
- $ref: '#/components/parameters/MerchantIdPath'
- $ref: '#/components/parameters/XMerchantId'
- $ref: '#/components/parameters/XTimestamp'
- $ref: '#/components/parameters/XSignature'
- name: country
in: query
description: Filter by destination country (ISO 3166-1 alpha-2)
schema:
type: string
example: PK
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/remittances/{merchantId}/beneficiaries:
post:
operationId: createRemittanceBeneficiary
summary: Register a remittance beneficiary
description: |
Creates a saved beneficiary for recurring remittances. Includes
mandatory KYC fields required for cross-border compliance.
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.
parameters:
MerchantIdPath:
name: merchantId
in: path
required: true
description: Unique merchant identifier
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 processing
schema:
type: string
format: uuid
XMerchantId:
name: X-Merchant-Id
in: header
required: true
schema:
type: string
XTimestamp:
name: X-Timestamp
in: header
required: true
schema:
type: string
format: date-time
XSignature:
name: X-Signature
in: header
required: true
schema:
type: string
headers:
XTraceId:
description: Unique trace identifier
schema:
type: string
format: uuid
XRateLimitLimit:
description: Maximum requests per window
schema:
type: integer
XRateLimitRemaining:
description: Requests remaining in current window
schema:
type: integer
XRateLimitReset:
description: Unix epoch when rate limit resets
schema:
type: integer
schemas:
FXRateResponse:
type: object
required:
- rates
- traceId
properties:
rates:
type: array
items:
type: object
required:
- sourceCurrency
- destinationCurrency
- rate
- validUntil
properties:
sourceCurrency:
type: string
example: GBP
destinationCurrency:
type: string
example: PKR
rate:
type: number
format: double
description: Exchange rate (1 unit of source = rate units of destination)
example: 365.50
inverseRate:
type: number
format: double
spread:
type: number
format: double
validUntil:
type: string
format: date-time
traceId:
type: string
format: uuid
QuoteConfirmRequest:
type: object
required:
- sourceCurrency
- destinationCurrency
- sendAmount
properties:
sourceCurrency:
type: string
pattern: '^[A-Z]{3}$'
example: GBP
destinationCurrency:
type: string
pattern: '^[A-Z]{3}$'
example: PKR
sendAmount:
type: number
format: double
example: 1000.00
receiveAmount:
type: number
format: double
description: |
Desired receive amount in destination currency. Provide either
sendAmount or receiveAmount, not both.
QuoteConfirmResponse:
type: object
required:
- quoteId
- sourceCurrency
- destinationCurrency
- sendAmount
- receiveAmount
- rate
- expiresAt
- traceId
properties:
quoteId:
type: string
format: uuid
sourceCurrency:
type: string
destinationCurrency:
type: string
sendAmount:
type: number
format: double
receiveAmount:
type: number
format: double
rate:
type: number
format: double
fee:
type: number
format: double
totalDebit:
type: number
format: double
expiresAt:
type: string
format: date-time
traceId:
type: string
format: uuid
RemittanceRequest:
type: object
required:
- quoteId
- beneficiaryAccountNumber
- beneficiaryName
- beneficiaryBankCode
- senderName
- purpose
- merchantTransactionId
properties:
quoteId:
type: string
format: uuid
beneficiaryAccountNumber:
type: string
example: PK36SCBL0000001123456702
beneficiaryName:
type: string
example: Ahmed Khan
beneficiaryBankCode:
type: string
example: HBL
beneficiaryId:
type: string
senderName:
type: string
example: John Smith
senderIdType:
type: string
enum:
- PASSPORT
- NATIONAL_ID
- DRIVING_LICENCE
senderIdNumber:
type: string
senderCountry:
type: string
example: GB
purpose:
type: string
example: Family maintenance
merchantTransactionId:
type: string
maxLength: 64
example: REM-2026-00456
deliveryMethod:
type: string
enum:
- BANK_ACCOUNT
- MOBILE_WALLET
- CASH_PICKUP
default: BANK_ACCOUNT
callbackUrl:
type: string
format: uri
metadata:
type: object
additionalProperties:
type: string
RemittanceResponse:
type: object
required:
- transactionId
- merchantTransactionId
- status
- sendAmount
- sendCurrency
- receiveAmount
- receiveCurrency
- rate
- traceId
properties:
transactionId:
type: string
format: uuid
merchantTransactionId:
type: string
quoteId:
type: string
format: uuid
status:
type: string
enum:
- INITIATED
- COMPLIANCE_HOLD
- COMPLIANCE_APPROVED
- PROCESSING
- COMPLETED
- FAILED
- RETURNED
sendAmount:
type: number
format: double
sendCurrency:
type: string
receiveAmount:
type: number
format: double
receiveCurrency:
type: string
rate:
type: number
format: double
fee:
type: number
format: double
beneficiaryName:
type: string
beneficiaryAccountNumber:
type: string
beneficiaryBankCode:
type: string
deliveryMethod:
type: string
bankTransactionId:
type: string
complianceNote:
type: string
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
BalanceResponse:
type: object
required:
- balances
- traceId
properties:
balances:
type: array
items:
type: object
required:
- currency
- availableBalance
properties:
currency:
type: string
example: GBP
availableBalance:
type: number
format: double
example: 250000.00
pendingBalance:
type: number
format: double
example: 15000.00
corridor:
type: string
example: GBP-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
example: PK
type:
type: string
enum:
- BANK
- MOBILE_WALLET
- CASH_PICKUP_AGENT
supportedDeliveryMethods:
type: array
items:
type: string
enum:
- BANK_ACCOUNT
- MOBILE_WALLET
- CASH_PICKUP
accountNumberFormat:
type: string
status:
type: string
enum:
- ACTIVE
- DEGRADED
- INACTIVE
traceId:
type: string
format: uuid
BeneficiaryRequest:
type: object
required:
- name
- accountNumber
- bankCode
- country
- relationship
properties:
name:
type: string
example: Fatima Bibi
accountNumber:
type: string
example: PK36SCBL0000001123456702
bankCode:
type: string
example: SCB
country:
type: string
example: PK
msisdn:
type: string
idType:
type: string
enum:
- CNIC
- PASSPORT
- NATIONAL_ID
idNumber:
type: string
relationship:
type: string
example: Spouse
address:
type: string
city:
type: string
metadata:
type: object
additionalProperties:
type: string
BeneficiaryResponse:
type: object
required:
- beneficiaryId
- name
- accountNumber
- bankCode
- country
- traceId
properties:
beneficiaryId:
type: string
format: uuid
name:
type: string
accountNumber:
type: string
bankCode:
type: string
country:
type: string
msisdn:
type: string
relationship:
type: string
createdAt:
type: string
format: date-time
traceId:
type: string
format: uuid
CursorPagination:
type: object
required:
- hasMore
properties:
cursor:
type: string
hasMore:
type: boolean
totalCount:
type: integer
WebhookPayload:
type: object
required:
- event
- transactionId
- merchantTransactionId
- status
- timestamp
- signature
properties:
event:
type: string
enum:
- REMITTANCE_COMPLETED
- REMITTANCE_FAILED
- REMITTANCE_RETURNED
- COMPLIANCE_HOLD
- COMPLIANCE_APPROVED
transactionId:
type: string
format: uuid
merchantTransactionId:
type: string
status:
type: string
sendAmount:
type: number
format: double
sendCurrency:
type: string
receiveAmount:
type: number
format: double
receiveCurrency:
type: string
bankTransactionId:
type: string
complianceNote:
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: QUOTE_EXPIRED
message:
type: string
example: The confirmed quote has expired. Please request a new quote.
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 payload
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: Foreign Exchange
description: FX rates and quote management
- name: Transactions
description: Remittance transaction lifecycle
- name: Balance
description: Corridor balance enquiries
- name: Reference Data
description: Bank and payout channel discovery
- name: Beneficiaries
description: Saved beneficiary management