Prepaid voucher payment method for European markets. Payers buy a CASHlib voucher offline (at a retail point of sale) and redeem the 16-digit PIN on a CashLib-hosted iframe launched from your cashier. Supports Pay-In only.Operations: Pay-In ✓ | Pay-Out - | Webhook ✓
Processing: Asynchronous - the cashier call creates a session and returns an iframe URL. The payer enters their voucher PIN on the CashLib-hosted page; final status arrives via webhook
Payment type: Prepaid voucher (PIN-based)Currency must match the country: CashLib charges in the local currency of the selected country. Supported pairs - France, Germany, Spain, Italy, Belgium, Netherlands, Austria, Portugal → EUR; United Kingdom → GBP; Switzerland → CHF; Poland → PLN; Czech Republic → CZK.
Amounts are converted to minor units when sent to CashLib: submit baseamount in major units (e.g. 1.97 EUR). Mozarto multiplies by 100 before calling CashLib. The webhook receives the amount in minor units ("197") and Mozarto converts it back to major units (1.97) before forwarding to your webhook.
CashLib requires a phone number: send phone in the request body. If you omit it, Mozarto falls back to the phone number on the authenticated user's profile (x-user-token). A phone in the body always takes precedence over the profile value. If neither is present the call is rejected with phone_number is required.
Fields marked with * are required.
Configuration (Mozarto back office)#
These fields are in the locked API Credentials section of the account's Processing Scope tab. Unlock it with your 2FA code first - see Unlock API credentials.
| Field | Description |
|---|
accountName * | Display name for this account |
apiKey * | CashLib merchant API key. Sent as the apikey header on every CashLib request. Stored per brand, encrypted at rest, and masked in the back office |
mid * | CashLib Merchant ID assigned by KAYROS/CashLib. Encrypted at rest |
siteUrl | Base URL used when a transaction does not send its own hppSuccessUrl / hppCancelUrl |
webhookUrl * | Your HTTPS endpoint that receives the final settlement notification |
comment | Optional free-text note for this configuration |
Pay-In#
POST /v1/api/mozarto/cashier
Creates a CashLib voucher-payment session. Returns an iframe URL you must open (typically in a redirect or embed) so the payer can enter their 16-digit voucher PIN on the CashLib-hosted page. The final status arrives later via webhook.Request body#
| Field | Type | Description |
|---|
pspType * | string | Always "CASHLIB" |
type * | string | Always "PAYIN" |
baseamount * | number | Amount in major units (e.g. 1.97 for €1.97). Mozarto converts to minor units before calling CashLib |
currency * | string | ISO 4217 currency code. Must match the country's local currency (see currency-pair note above) |
country * | string | Payer's country - full name, ISO 3166-1 alpha-2, or alpha-3 (e.g. "France", "FR", "FRA"). Matched against the account's Processing Scope, and converted to ISO 3166-1 alpha-3 before being sent to CashLib. Supported: FRA, DEU, ESP, ITA, BEL, NLD, AUT, PRT, GBR, CHE, POL, CZE. See Country codes |
dob * | string | Payer's date of birth in YYYY-MM-DD format |
address * | string | Payer's street address |
city * | string | Payer's city |
zipcode * | string | Payer's postal/ZIP code |
phone * | string | Payer's mobile number in international format (e.g. "33612345678"). Sent to CashLib as phone_number. Falls back to the authenticated user's profile phone when omitted - see the phone note above |
hppSuccessUrl * | string | URL the payer is redirected to after a successful redemption on the CashLib page |
hppCancelUrl * | string | URL the payer is redirected to if they cancel on the CashLib page |
webhookUrl | string | Overrides the configured webhookUrl for this transaction |
merchantReference | string | Your reference, echoed back on the webhook |
Example request#
{
"pspType": "CASHLIB",
"type": "PAYIN",
"baseamount": 1.97,
"currency": "EUR",
"country": "France",
"dob": "1990-01-01",
"address": "123 Main Street",
"zipcode": "F-75001",
"city": "Paris",
"phone": "33612345678",
"hppSuccessUrl": "https://example.com/success",
"hppCancelUrl": "https://example.com/cancel",
"merchantReference": "ORDER-4821"
}
Response#
{
"status": "success",
"message": "Successfully",
"isSuccess": true,
"data": {
"redirectUrl": "https://backoffice-test.cashlib.com/purchase/...",
"transactionId": "6a723e2b7ef5d966c4dcbd9c",
"psp_transaction_id": "1152066205307-202608041708277320",
"transaction_status": "Pending"
}
}
| Field | Type | Description |
|---|
redirectUrl | string | CashLib-hosted iframe URL - open this so the payer can enter their voucher PIN |
transactionId | string | Mozarto transaction ID - use it to match the incoming webhook |
psp_transaction_id | string | CashLib's own transaction reference (echoed on the webhook as transaction_reference) |
transaction_status | string | Always "Pending" at this point. The final outcome arrives by webhook |
Webhook#
Mozarto calls your webhookUrl when the transaction reaches a final state. CashLib notifies Mozarto on its own callback URL first; Mozarto then forwards a normalized notification to you.Non-final statuses (e.g. still awaiting the payer to enter the PIN) are acknowledged with 200 OK but not forwarded. Duplicate terminal webhooks are also ignored (idempotency guard).Payload example#
{
"transaction_id": "6a723e2b7ef5d966c4dcbd9c",
"psp_transaction_id": "1152066205307-202608041708277320",
"user_id": "000000000000000000000001",
"status": "success",
"transaction_status": "Approved",
"amount": 1.97,
"currency": "EUR",
"merchantReference": "ORDER-4821"
}
| Field | Description |
|---|
transaction_id | Mozarto transaction ID - matches data.transactionId from the Pay-In response |
psp_transaction_id | CashLib's transaction reference |
user_id | The user ID from the original transaction |
status | Raw settlement result - success or the CashLib status string. Do not use for business logic |
transaction_status | Normalized Mozarto status - "Approved", "Failed", or "Cancelled". Use this for all business logic |
amount | Transaction amount in major units (e.g. 1.97). Mozarto converts from CashLib's minor units before forwarding |
currency | Transaction currency |
merchantReference | The merchant reference passed in the original request - empty string if not set |
Error codes#
The cashier call returns an error when the payment session cannot be created. Payer-side failures (invalid PIN, insufficient balance, etc.) are reported later through the webhook with transaction_status: "Failed", not on this call.When CashLib returns a numeric status code that maps to a known Mozarto errorCode, the response carries the normalized code alongside the human message. Unmapped codes surface CashLib's raw error_message (whitespace-normalized) with no errorCode field.| HTTP status | errorCode | message | When |
|---|
| 400 | - | PSP Configuration not found. Please check you psp Configuration | The CashLib apiKey or mid is missing from the back office configuration |
| 400 | - | The currency provided is not accepted in this country. Please use <X>. | The currency sent does not match the country's local currency |
| 400 | - | Array of validation messages, e.g. ["phone_number is required"] | A required payer field is missing. Most commonly phone, when neither the request body nor the authenticated user's profile supplies one. Raised by Mozarto before CashLib is called |
| 400 | INVALID_PSP_CREDENTIALS | Payment could not be processed due to invalid PSP credentials. | CashLib returned numeric status 12 (Could not authenticate you.) - the merchant apiKey or mid is wrong |
| 400 | - | CashLib's error_message (whitespace-normalized) | Any other CashLib rejection. The numeric CashLib status code is preserved under transactionDetails.pspStatusCode and the raw body under transactionDetails.pspResponse |
Example error response#
{
"status": "error",
"message": "Payment could not be processed due to invalid PSP credentials.",
"isSuccess": false,
"errorCode": "INVALID_PSP_CREDENTIALS",
"data": {
"error": {
"status": 12,
"error_message": "Could not authenticate you."
},
"statusCode": 403
},
"transaction_status": "Failed"
}
For the full list of errorCode values and retryability guidance, see Errors. Modified at 2026-11-02 13:18:40