# One API errors

> Every rejection One API returns, what was checked, and what to do about it. Source: https://hub.ozow.com/errors/one-api/

A rejection is a real status code and one JSON error object: `id`, `code`, `title`, `detail`, and a `source` pointing at the field it is about. The sentence is in `detail`. `code` is the class of failure, and follows the status: `BadRequest` on a 400, `NotFound` on a 404, `Conflict` on a 409, `BadGateway` on a 502. Send a `Correlation-Id` header and it comes back in `meta.correlationId`. Quote that to support.

## Fields on the payment request

The `details` object is checked against the `paymentType` you specified. Every failure for that payment type comes back in one `400`, concatenated into `detail` and separated by spaces, with no per-field breakdown. Where a message quotes a spaced name, `'Payer Identification'` is the field `payerIdentification`.

### cardNumber must be a 19 or 16-digit number.

Arrives as HTTP 400 Bad Request.

**What was checked:** The length of the card number.

**What to do:** Send digits only. Strip the spaces a payer types and any formatting your form adds.

### cvv must be a 3 or 4-digit number.

Arrives as HTTP 400 Bad Request.

**What was checked:** The length of the security code. Three digits on most cards, four on American Express.

**What to do:** Send digits only.

### expiryMonth must be in the format MM (01-12).

Arrives as HTTP 400 Bad Request.

**What was checked:** The month, as two digits.

**What to do:** Pad a single digit: January is `01`, not `1`.

### expiryYear must be in the format YY (00-99).

Arrives as HTTP 400 Bad Request.

**What was checked:** The year, as two digits.

**What to do:** Send `27` rather than `2027`.

### 'Full Name' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The cardholder name on a card payment.

**What to do:** Send `fullName`.

### 'User Agent' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The `userAgent` field on a card payment.

**What to do:** Send the user agent string of the browser making the payment.

### emailAddress is invalid.

Arrives as HTTP 400 Bad Request.

**What was checked:** The shape of the address.

**What to do:** Send a complete address, or omit the field where the payment method does not need one.

### mobileNumber is empty or invalid.

Arrives as HTTP 400 Bad Request.

**What was checked:** The payer's mobile number.

**What to do:** Send a South African number. Bank deposit, voucher and Ozow wallet payments cannot proceed without one.

### 'Access Account' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The account an Absa Pay payment is made from.

**What to do:** Send `accessAccount`.

### 'Client Id' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The payer's Capitec Pay identifier.

**What to do:** Send `clientId`.

### 'Payer Identification' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** Who is paying, on a PayShap payment.

**What to do:** Send `payerIdentification`.

### 'Bank Id' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** Which bank the PayShap payment goes to.

**What to do:** Send `bankId`.

### 'Voucher Pin' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The voucher being redeemed.

**What to do:** Send `voucherPin`.

### 'Consent Id' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The mandate a subscription payment is charged against.

**What to do:** Send `consentId` from the subscription the payer authorised.

### 'Amount' must be greater than '0'.

Arrives as HTTP 400 Bad Request.

**What was checked:** The amount on a subscription payment.

**What to do:** Send an amount above zero.

### The specified condition was not met for 'Amount'.

Arrives as HTTP 400 Bad Request.

**What was checked:** The number of decimal places on a subscription amount.

**What to do:** Send at most two decimal places. `10.005` is refused, `10.01` is accepted.

### callbackUrl must be a valid URL.

Arrives as HTTP 400 Bad Request.

**What was checked:** The URL Ozow returns the payer to.

**What to do:** Send an absolute `https://` URL. A path on its own does not resolve from Ozow's side.

## Where the money goes

Sent when an Ozow redirect payment names the account to pay rather than letting the payer choose one.

### Beneficiary.AccountNumber cannot be null or empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The account the payment is made to.

**What to do:** Send `beneficiary.accountNumber` and `beneficiary.branchCode`. Neither works alone.

### 'Beneficiary Account Number' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The account the payment is made to.

**What to do:** Send `beneficiary.accountNumber`.

### Beneficiary.BranchCode cannot be null or empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The branch for that account.

**What to do:** Send the bank's universal branch code.

### 'Beneficiary Branch Code' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The branch for that account.

**What to do:** Send `beneficiary.branchCode`.

### VerifiedBankAccount.AccountNumber cannot be null or empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The account on a verified payment, where Ozow confirms the account belongs to the payer before charging it.

**What to do:** Send `verifiedBankAccount.accountNumber` and `verifiedBankAccount.branchCode`. Neither works alone.

### 'Verified Bank Account Account Number' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The account on a verified payment.

**What to do:** Send `verifiedBankAccount.accountNumber`.

### VerifiedBankAccount.BranchCode cannot be null or empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The branch for that verified account.

**What to do:** Send the bank's universal branch code.

### 'Verified Bank Account Branch Code' must not be empty.

Arrives as HTTP 400 Bad Request.

**What was checked:** The branch for that verified account.

**What to do:** Send `verifiedBankAccount.branchCode`.

## Subscriptions

Where individual fields are named, they replace the sentence in `detail`, joined with semicolons on a `400` and appended after it on a `409`.

### One or more fields are invalid. See details.

Arrives as HTTP 400 Bad Request.

**What was checked:** The fields of the subscription request, one at a time.

**What to do:** Check the request against the subscription contract. Field problems, where there are any, replace this sentence in `detail`.

### The subscription could not be created. See details.

Arrives as HTTP 400 Bad Request.

**What was checked:** The subscription as a whole rather than any single field.

**What to do:** Check the amount constraints, the schedule and the reference together.

### One or more fields are invalid.

Arrives as HTTP 400 Bad Request.

**What was checked:** The subscription request. No field detail is given.

**What to do:** Check the request against the subscription contract. Quote `meta.correlationId` to support if it keeps failing.

### The reference provided is already in use.

Arrives as HTTP 409 Conflict.

**What was checked:** Whether this reference already names a subscription.

**What to do:** Use a new reference. If you are retrying, look the existing subscription up rather than creating a second one.

### The requested subscription was not found.

Arrives as HTTP 404 Not Found.

**What was checked:** Whether the subscription exists on this account.

**What to do:** Check the identifier, and that it belongs to the account you authorised with.

### This subscription has no active authorisation to charge.

Arrives as HTTP 409 Conflict.

**What was checked:** Whether the payer's mandate is still live. A subscription can exist with its authorisation cancelled or expired.

**What to do:** Ask the payer to authorise again. Nothing can be charged until they do.

### A payment has already been actioned for this period.

Arrives as HTTP 409 Conflict.

**What was checked:** Whether this period has been charged.

**What to do:** Treat it as success. The money has moved.

### The amount is outside the authorised range for this subscription.

Arrives as HTTP 409 Conflict.

**What was checked:** The amount against the range the payer authorised.

**What to do:** Charge within the range, or ask the payer to authorise a new one.

### The payment was declined. Please try again or use a different payment method.

Arrives as HTTP 409 Conflict.

**What was checked:** Nothing. The bank or card issuer refused the payment, and does not say why.

**What to do:** Offer the payer another method. Retrying the same one usually declines again.

### The payment provider did not respond in time. Please try again shortly.

Arrives as HTTP 409 Conflict.

**What was checked:** Nothing. The provider did not answer in time, so the outcome is unknown.

**What to do:** Check the payment's status before retrying. A timeout is not a decline, and the payment may have gone through.

### The request conflicts with the current state of the subscription.

Arrives as HTTP 409 Conflict.

**What was checked:** The subscription's current state. No further detail is given.

**What to do:** Read the subscription's current state and work from that. Quote `meta.correlationId` to support if it keeps failing.

### We couldn't reach the payment service. Please try again shortly.

Arrives as HTTP 502 Bad Gateway.

**What was checked:** Nothing. The request was never attempted, so nothing changed.

**What to do:** Retry shortly. Check the subscription's state first if the request would charge money.

### We couldn't complete your request with the payment service. Please try again shortly.

Arrives as HTTP 502 Bad Gateway.

**What was checked:** Nothing. The request failed part-way, so it may have been partly applied.

**What to do:** Check the subscription's state before retrying rather than sending the same request again.

## Not found

### Payment could not be found for payment id {paymentId}.

Arrives as HTTP 404 Not Found.

**What was checked:** Whether the payment exists on the account you authorised with. `source.pointer` is `data/paymentId`.

**What to do:** Check the identifier. A payment created against another site is not visible here.
