Hash calculator
Work out the hashCheck a request carries, and see the exact string it is computed from.
On this page6 sections
Build with AI 2 packages
A build package is every page for one task, with the API operations they use. Copy the prompt into a coding assistant, or hand it the package itself: slim links to each page, full inlines all of them in one document.
- Embed checkout in your own pageEverything needed to keep the customer on your site while they pay, as an iframe, a modal, or the Wallet SDK for Apple Pay and Google Pay, with the notification that actually confirms the payment.
- Migrate a payin from the Payments API to One APIEverything needed to move an existing redirect payin onto One API, with the legacy guide and its One API counterpart side by side.
Every request that moves money carries a hashCheck, and a request whose hash does not match is
rejected. The rejection does not say which field was wrong, so this shows you the string the hash is
computed from, one field at a time.
It works in both directions. Build it fills in the fields you send and shows the string they concatenate to. Check mine goes the other way: give it what your own code produced, and it says where that leaves the documented string and names the mistake that would explain it.
Important
Neither of those needs your private key, and the page asks for one only if you choose the last of three options. It builds the string with a placeholder in place of the key, which is all you need: a hash is determined entirely by the string it is computed from, so if your string matches this one, your hash matches too. Comparing strings finds every mistake except a wrong key, because every other mistake changes the string before the key is reached.
Before you paste a key anywhere
check the address bar. This page is the only one on this site that will ever ask for one, it holds it in the tab and nowhere else, and it still asks you to try the string comparison first. A page imitating this one would ask sooner and explain less.
What usually goes wrong
The key is rarely the problem. In order of how often they occur:
| Cause | What it looks like |
|---|---|
| Field order | The fields are concatenated in a fixed order, not the order your object happens to serialise in. Reordering them changes the hash. |
| Amount format | A payinPayin A payment made by a consumer to a merchant. The direction most of this site is about: money coming in. Its counterpart is a payout, which sends money out and is not tied to any payment anyone made you. writes the amount with two decimals, 100.00. A payoutPayout Money sent from a merchant to a bank account. Unlike a refund, a payout is not tied to a payment anyone made you, so you can pay anyone with a bank account. Payouts draw on your float rather than on your incoming payments, and they are not self-service: they need approval from Ozow and testing in staging first. writes it in cents, 10000. |
| A blank optional field | An empty field contributes nothing at all. It does not contribute a placeholder, a space or the word null. |
| Lowercasing | Payin, payout and verification hashes lowercase the whole concatenated string, including the key. Refunds do not: see below. |
| The key itself | Test and production keys differ. A hash built with the wrong one fails in exactly the same way as a hash built in the wrong order. |
Three things the notification hashes do differently
- The payout notification takes
customerMerchantReference, where the payout request takescustomerBankReference. Check which one you are reading before you hash it. - The payout notification's two statuses go in as integers, not as their names.
- A voucher payout appends the voucher pin after the key, so the key is not last for that one hash.
The refund notification also arrives with the account number already masked, so verify it with the masked value you received rather than the number you sent.
Refunds do not lowercase
Payin, payout and payout verification hashes lowercase the entire concatenated string before hashing. A refund hash does not.
Apply the payin rule to a refund and your hash is rejected the moment your refund reason or notify URL contains a capital letter. Build the refund string exactly as your values are, with no lowercasing.
Which direction the hash goes
A request hash is one you build and send. Ozow rejects the request if it does not match.
A notification hash is one you check on something Ozow sent you, and its field order is not the same as the request's. Reusing a request's order to verify an incoming notification rejects every notification you receive, which is the single most expensive way to get this wrong: your integration looks fine until money starts moving.
One API does not use a hash
One API authenticates every call with an OAuth 2.0OAuth 2.0 The authorisation framework behind the token endpoint. Ozow uses the client credentials flow: your server exchanges a client ID and secret for a short-lived access token, and sends that token rather than the secret on every subsequent call.RFC 6749 bearer tokenBearer token An access token sent in the Authorization header as Authorization: Bearer <token>. Anyone holding the token can use it, which is why it belongs on your server and never in a browser or a mobile app.RFC 6750, and its requests carry no
hashCheck field.
Its webhooks are not verified with a hash either. One API delivers them through
Svix, which signs each one with an HMACHMAC A hash of a message combined with a secret key, so the result proves both that the message is unchanged and that the sender held the key. A plain hash proves only the first: anybody can compute one. This is what makes a webhook signature worth checking.RFC 2104 over the svix-id,
svix-timestamp and body. Verify it with the secret from the Get WebhookWebhook A URL of yours that Ozow calls when something happens, rather than you polling to find out. The call carries no credential of yours and arrives at a public URL, so authenticate it before acting on it: a hash field on the Payments API, a Svix signature on One API. Secret endpoint, using the
Svix libraries. Redirect to Ozow covers the
headers and how to check them.
Use this page for the Payments API and the Payouts API.
Where each hash is used
| Request | Concatenates | Key |
|---|---|---|
| Payments API payin request | 32 fields, from site to token |
Your private key |
| Payments API payin notification | 13 fields, from site to status |
Your private key |
| Payments API refund request | transaction, amount, refund, notify |
Your private key |
| Payments API refund notification | 8 fields, from refund to status |
Your private key |
| Payouts API payout request | 11 fields, from site to identity |
Your API key |
| Payouts API payout verification | The payout fields, with payout in front |
Your API key |
| Payouts API payout notification | 6 fields, from payout to payout |
Your API key |
The payin hash is described in full in Redirect to Ozow, and the payout hash in Send a payout.
Note
Compute the hash on your server, never in browser JavaScript. A hash built in the browser needs the private key in the browser, and anything that reaches the client can be read by anyone holding the client.
Last updated