openapi: 3.0.3
info:
title: Kora (Korapay) Merchant Balances Charges API
description: 'The Kora merchant REST API for pan-African payments. It supports pay-ins (card, bank transfer, mobile money, pay-with-bank), payouts (single, bulk, remittance), NGN and USD virtual bank accounts, balances, refunds, multi-currency conversion, and payout utilities (bank / mobile-money lookups and account resolution). All requests are authenticated with API keys - a public key for client-side charge initiation and a secret key (Bearer) for server-side and financial operations - and each account has separate Test and Live mode keys. Card charge payloads must be AES-256 encrypted with your encryption key. Webhook notifications carry an `x-korapay-signature` header that is an HMAC SHA-256 of the response `data` object signed with your secret key.
This document is a representative, grounded subset of the public Kora API. Request and response schemas are simplified; consult the Kora developer documentation for the authoritative field-level contract. Endpoints are confirmed against Kora''s published documentation except where a description notes an inferred path.'
version: '1.0'
contact:
name: Kora Developer Support
url: https://developers.korapay.com
email: support@korapay.com
servers:
- url: https://api.korapay.com/merchant/api/v1
description: Kora merchant API (Test and Live selected by the API key used)
security:
- secretKeyAuth: []
tags:
- name: Charges
description: Pay-ins - card, bank transfer, mobile money, and pay-with-bank.
paths:
/charges/initialize:
post:
operationId: initializeCharge
tags:
- Charges
summary: Initialize a charge
description: Initializes a checkout charge and returns a hosted checkout URL / reference. Typically called with your public key from the client side.
security:
- publicKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/InitializeChargeInput'
responses:
'200':
description: The initialized charge.
content:
application/json:
schema:
$ref: '#/components/schemas/ChargeResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/charges/card:
post:
operationId: chargeCard
tags:
- Charges
summary: Charge a card
description: Charges a card. The card and payment details must be AES-256 encrypted with your encryption key and submitted as a single `charge_data` string. The response `status` (success, processing, or failed) and, when processing, the returned `auth_model` determine the next authorization step (PIN, OTP, AVS/address, or phone). Card payments require the feature to be enabled on your account and PCI DSS Level 1 certification.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EncryptedChargeInput'
responses:
'200':
description: The card charge result.
content:
application/json:
schema:
$ref: '#/components/schemas/ChargeResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/charges/card/authorize:
post:
operationId: authorizeCardCharge
tags:
- Charges
summary: Authorize a card charge
description: Completes a processing card charge by supplying the authorization the card requires (PIN, OTP, AVS/address, or phone), together with the transaction reference. NOTE - the exact path of this authorization endpoint is inferred by convention; Kora's documentation links to a Postman entry rather than printing the literal path. Verify before use.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CardAuthorizationInput'
responses:
'200':
description: The authorization result.
content:
application/json:
schema:
$ref: '#/components/schemas/ChargeResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/charges/mobile-money:
post:
operationId: chargeMobileMoney
tags:
- Charges
summary: Charge a mobile money wallet
description: Charges a customer's mobile money wallet. Available in Kenya (KES), Ghana (GHS), Cameroon (XAF), Cote d'Ivoire (XOF), Egypt (EGP), and Tanzania (TZS). The response `auth_model` (OTP, STK_PROMPT, or REDIRECT) indicates the action required to complete the transaction.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MobileMoneyChargeInput'
responses:
'200':
description: The mobile money charge result.
content:
application/json:
schema:
$ref: '#/components/schemas/ChargeResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/charges/mobile-money/authorize:
post:
operationId: authorizeMobileMoneyCharge
tags:
- Charges
summary: Authorize a mobile money charge
description: Authorizes a mobile money charge whose `auth_model` was OTP by submitting the OTP collected from the customer along with the transaction reference. The response indicates the next required action.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MobileMoneyAuthorizationInput'
responses:
'200':
description: The authorization result.
content:
application/json:
schema:
$ref: '#/components/schemas/ChargeResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/charge/pay-with-bank:
post:
operationId: chargePayWithBank
tags:
- Charges
summary: Charge with Pay with Bank
description: Initiates a Pay with Bank charge and returns a redirect URL used to complete the payment. Supports ZAR Instant EFT and NGN direct-debit style flows (currently Opay and Palmpay for NGN).
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PayWithBankInput'
responses:
'200':
description: The pay-with-bank charge with a redirect URL.
content:
application/json:
schema:
$ref: '#/components/schemas/ChargeResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/charge/pay-with-bank/banks:
get:
operationId: listPayWithBankBanks
tags:
- Charges
summary: List Pay with Bank banks
description: Retrieves the list of banks supported for Pay with Bank (Instant EFT).
responses:
'200':
description: A list of supported banks.
content:
application/json:
schema:
$ref: '#/components/schemas/BankList'
'401':
$ref: '#/components/responses/Unauthorized'
/charges/{reference}:
parameters:
- $ref: '#/components/parameters/Reference'
get:
operationId: verifyCharge
tags:
- Charges
summary: Verify / query a charge
description: Retrieves the current status and details of a charge by its payment reference. Always verify a charge server-side before delivering value.
responses:
'200':
description: The charge status and details.
content:
application/json:
schema:
$ref: '#/components/schemas/ChargeResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
CardAuthorizationInput:
type: object
required:
- transaction_reference
- authorization
properties:
transaction_reference:
type: string
authorization:
type: object
description: The authorization payload - pin, otp, avs/address, or phone.
additionalProperties: true
MobileMoneyChargeInput:
type: object
required:
- reference
- amount
- currency
- mobile_money
- customer
properties:
reference:
type: string
amount:
type: number
currency:
type: string
example: KES
mobile_money:
type: object
properties:
number:
type: string
example: '254700000000'
notification_url:
type: string
format: uri
merchant_bears_cost:
type: boolean
default: false
narration:
type: string
customer:
$ref: '#/components/schemas/Customer'
ChargeResponse:
type: object
properties:
status:
type: boolean
message:
type: string
data:
type: object
properties:
reference:
type: string
transaction_reference:
type: string
status:
type: string
enum:
- success
- processing
- failed
- pending
auth_model:
type: string
description: OTP, PIN, STK_PROMPT, REDIRECT, AVS, PHONE, etc.
amount:
type: number
currency:
type: string
checkout_url:
type: string
format: uri
redirect_url:
type: string
format: uri
additionalProperties: true
ErrorResponse:
type: object
properties:
status:
type: boolean
message:
type: string
data:
type: object
additionalProperties: true
Customer:
type: object
properties:
name:
type: string
email:
type: string
format: email
InitializeChargeInput:
type: object
required:
- reference
- amount
- currency
- customer
properties:
reference:
type: string
description: Unique merchant reference for the transaction.
amount:
type: number
currency:
type: string
example: NGN
redirect_url:
type: string
format: uri
notification_url:
type: string
format: uri
narration:
type: string
customer:
$ref: '#/components/schemas/Customer'
metadata:
type: object
additionalProperties: true
MobileMoneyAuthorizationInput:
type: object
required:
- transaction_reference
- authorization
properties:
transaction_reference:
type: string
authorization:
type: object
properties:
otp:
type: string
BankList:
type: object
properties:
status:
type: boolean
message:
type: string
data:
type: array
items:
type: object
properties:
name:
type: string
code:
type: string
additionalProperties: true
EncryptedChargeInput:
type: object
required:
- charge_data
properties:
charge_data:
type: string
description: The card charge payload (reference, card, amount, currency, customer, redirect_url, metadata) AES-256 encrypted with your encryption key.
PayWithBankInput:
type: object
required:
- reference
- amount
- currency
- customer
properties:
reference:
type: string
amount:
type: number
currency:
type: string
example: ZAR
redirect_url:
type: string
format: uri
notification_url:
type: string
format: uri
customer:
$ref: '#/components/schemas/Customer'
responses:
NotFound:
description: The requested resource was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
parameters:
Reference:
name: reference
in: path
required: true
description: The transaction / payment reference.
schema:
type: string
securitySchemes:
secretKeyAuth:
type: http
scheme: bearer
description: 'Secret API key passed as `Authorization: Bearer sk_...`. Required for server-side and financial operations (payouts, balances, virtual bank accounts, refunds, conversions, charge verification). Test and Live modes use different keys.'
publicKeyAuth:
type: http
scheme: bearer
description: Public API key (`pk_...`) used from client-side code to initiate charges. Cannot access financial data.