Payment (Payin)
Purpose
The POST /v1/payin/sessions endpoint allows a merchant to create a secure payment session between their system and the payment platform. This session corresponds to a payment intent: it does not charge the customer until they confirm or validate the transaction.
Request Details
| Element | Description |
|---|---|
| Method | POST |
| Endpoint | /v1/payin/sessions |
| Auth | ✅ Authorization: Basic base64(api_key:api_client) |
| Idempotence | ✅ X-Idempotency-Key required to avoid duplicates |
| Payload Type | application/json |
Request Parameters
| Field | Type | Description | Required |
|---|---|---|---|
reference | string | Unique transaction identifier on the merchant side (UUID recommended). | ✅ |
accountId | string | Merchant account or sub-account identifier to debit/credit. | ✅ |
amount | number | Amount to pay (in whole units, no decimals). | ✅ |
msisdn | string | Customer's phone number (E.164 format). | ✅ |
customerName | string | Name of the customer initiating the payment. | ✅ |
country | string | Country ISO code (CI, CM). | ✅ |
Request Example
{
"reference": "{{$randomUUID}}",
"accountId": "merchant_9923lkdz",
"amount": 300,
"msisdn": "+2250702968786",
"customerName": "John Doe",
"country": "CI"
}Response Example
{
"type": "payin",
"fee": 6,
"reference": "tr_fhchi842jyimwiugjgszcxvb8n",
"phoneNumber": "+2250700000000",
"amount": 300,
"chargedAmount": 306,
"status": "processing",
"currency": "XOF",
"customerReference": "ef76fb64-af0b-4c37-8729-bf61d85721fd",
"confirmationRequired": true,
"confirmationStatus": "none",
"paymentUrl": "https://link.novasend.app/link/{shortCode}",
"createdAt": "2025-08-22T01:34:48.189Z"
}Response Interpretation
| Field | Description |
|---|---|
| type | Operation type — here "payin", for an incoming payment. |
| fee | Service fees applied to the transaction. |
| reference | API-side system reference for the transaction. |
| phoneNumber | Customer's phone number. |
| amount | Gross payment amount. |
| chargedAmount | Total charged amount (amount + fees). |
| status | Initial payment status (processing, processed, expired, etc.). |
| currency | Currency used, e.g., "XOF". |
| customerReference | Request identifier generated or transmitted by the merchant. |
| confirmationRequired | Indicates if the customer must confirm the payment before execution. |
| confirmationStatus | Customer confirmation status (see table below). |
| paymentUrl | Web link (deep link) allowing the customer to confirm payment via a mobile or web interface. |
| createdAt | Session creation date. |
The confirmationRequired and confirmationStatus Attributes
confirmationRequired
- Type:
boolean - Possible values:
true→ the customer must confirm the payment (e.g., OTP entry, approval in their mobile wallet, or click on a secure link).false→ the payment is automatically validated (case of internal transfers or instant payments).
- Role:
Allows the merchant to know if they must wait for a customer action before considering the payment complete.
Example:
- If
confirmationRequired = true, the system sends a validation link (paymentUrl) to the customer. - The payment then goes to "processing" status until the customer responds.
- If
confirmationStatus
-
Type:
string -
Possible values:
Value Description noneNo response from the customer (initial status). acceptedThe customer confirmed the payment (OTP validated, or clicked "Accept"). declinedThe customer explicitly refused the payment. expiredConfirmation deadline exceeded (timeout). -
Role: Provides the current state of the customer validation process. This status evolves dynamically based on customer actions and can be tracked via:
- Webhook (
payin.confirmed,payin.declined) - Or via a
GET /v1/payin/{reference}request.
- Webhook (
Obligation
- Always store
referenceandcustomerReferenceto track the transaction. - Display the
paymentUrllink to the customer for validation ifconfirmationRequired = true. - If
confirmationStatus = declinedorexpired, the payment should be considered invalid.
Payment Status
Purpose
This endpoint allows you to check the status of a payment initiated via the Merchant API at any time.
It is particularly useful for:
- Verifying customer confirmation (accepted or declined).
- Getting the final payment status (success, failure, pending).
- Accessing enriched information about the transaction processed by the Core System (in the
transactionfield).
Request Details
| Element | Description |
|---|---|
| Method | GET |
| Endpoint | /v1/payin/{reference} |
| Auth | ✅ Requires Authorization: Basic base64(api_key:api_client) header |
| Parameter | reference → unique payment identifier (generated during POST /v1/payin/sessions) |
| Payload | None |
How It Works
When a merchant initiates a payment (POST /v1/payin/sessions), the API returns an initial status of processing or processed.
The payment then goes through several internal stages:
| Stage | Description |
|---|---|
| processing | Confirmation in progress or technical validation |
| processed | Payment validated by the customer (But does not define the final transaction status) |
| expired | Confirmation deadline exceeded |
This endpoint allows you to check the complete progress of a payment from its reference.
Response Example
{
"type": "payin",
"fee": 6,
"reference": "mtr_fhscgaywizujwjyymlge1hncaq",
"phoneNumber": "+2250700000000",
"customerName": "John Doe",
"amount": 300,
"chargedAmount": 306,
"status": "processed",
"currency": "XOF",
"customerReference": "55a4e677-5700-4ed0-9a2a-9300db894ddb",
"confirmationRequired": true,
"confirmationStatus": "none",
"createdAt": "2025-08-22T02:00:16.026Z",
"transaction": {
"reference": "tr_dkjd5ljficphlqmt",
"status": "completed",
"customerName": "dd soûl",
"processedAt": "2025-11-05T16:12:42.096Z",
"phoneNumber": "+2250700000000",
"amount": "153.00",
"fees": "0.00",
"chargedAmount": "153.00",
"currency": "XOF"
},
"failure": null
}Response Interpretation
| Key | Description |
|---|---|
| type | Operation type (payin) |
| fee | Applied fee amount |
| reference | Internal payment reference |
| phoneNumber | Phone number of the customer who made the payment |
| customerName | Name associated with the payer account |
| amount | Initial payment amount |
| chargedAmount | Total charged amount (amount + fees) |
| status | Overall payment status (processing, processed) |
| currency | Transaction currency (XOF, USD, etc.) |
| customerReference | Original reference provided by the merchant |
| confirmationRequired | Indicates if the customer must confirm (OTP, mobile validation, etc.) |
| confirmationStatus | Current confirmation status (none, pending, accepted, declined) |
| createdAt | Payment session creation date |
| failure | Error details in case of failure (null if successful) |
transaction Key
The transaction field represents the final transaction recorded in the Core System once the payment is validated or rejected.
| Key | Description |
|---|---|
| transaction.reference | Core System internal identifier |
| transaction.status | Actual processing status (completed, failed, pending) |
| transaction.customerName | Name of the debited account holder |
| transaction.phoneNumber | Account number that performed the operation |
| transaction.amount | Actually processed amount |
| transaction.fees | Fees applied at the processor level |
| transaction.chargedAmount | Total charged amount |
| transaction.currency | Currency used |
| transaction.processedAt | Exact timestamp of final processing |
Reading Example
- If
status = "processed"andtransaction.status = "completed"→ ✅ Payment successful and confirmed. - If
status = "processed"buttransaction.status = "failed"→ ⚠️ Payment recorded but refused by customer. - If
transactionisnullor{}in this case, the payment has not yet been confirmed by the customer. - If
failurecontains an object → error information will be present (code,message, etc.).
Obligation
- Always store the
referenceandcustomerReferencefor correlation. - The
transaction.statusfield is the final source of truth on the settlement system side.