Ozow Hub
On this page15 sections
Build with AI 1 package

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.

  • Migrate refunds from the Payments API to One APIEverything needed to move an existing refunds integration onto One API, with the legacy guide and its One API counterpart side by side.
    View package

Legacy integration

The Payments API is a legacy integration path. For new integrations, use Refunds: One API instead. This guide is for merchants already using the Payments API.

This guide walks you through issuing refunds to your customers using the Payments API. Refunds are merchant-initiated backend operations, there is no customer-facing step. The entire flow happens in your backend.

FloatFloat The balance held with Ozow that payouts and refunds are paid out of. Both draw on it, and neither will process while it is empty. Payins do not need one, so if you only take payments you never meet it. required

Ozow uses your float balance to fund refunds. Make sure your float has sufficient funds before issuing refunds. See the Float top-up guide to load funds into your float.

Before you start

  • You have your API key and site codeSite code The unique code for a site registered under a merchant. A site is a place to transact: a website, or a branch of a store. A merchant can have several, and each transaction names the one it belongs to, so sending the wrong code files the payment against the wrong place. from your Ozow Dashboard
  • Your float balance is sufficient to cover the refund amounts
  • You have the transaction IDs of the original payments you want to refund
  • If you use notifyUrl to receive refund status updates, it is publicly accessible via HTTPS

Environments

Environment Base URL Dashboard
Production https://api.ozow.com dash.ozow.com
Staging https://stagingapi.ozow.com stagingdash.ozow.com

How refunds work

The Payments API processes refunds in batches. Even when you are refunding a single transaction, you submit it as an array containing one refund request. Each refund item in the array requires its own hash check.


Step 1: Get a bearer token

Refund endpoints authenticate with a 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 rather than the API key directly. Request one before submitting refunds.

POST Get API token Reference
POST https://api.ozow.com/token
ApiKey: YOUR_API_KEY
Content-Type: application/x-www-form-urlencoded
curl -X POST "https://api.ozow.com/token" \
  -H "ApiKey: <YOUR_API_KEY>" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=Password&SiteCode=YOUR_SITE_CODE"

Successful response

{
  "access_token": "YOUR_ACCESS_TOKEN",
  "token_type": "Bearer",
  "expires_in": "14400"
}

Store the access_token and request a new one before it expires. Include it in the Authorization header of every refund request:

Authorization: Bearer YOUR_ACCESS_TOKEN

Step 2: Generate the hash check

Each refund item in the batch requires its own SHA512SHA-512 A hashing algorithm. Ozow uses it to sign the values in a request or a notification so you can tell that they arrived unaltered and came from us. Hashing is one-way: the hash cannot be turned back into what produced it.Wikipedia hash check.

Critical, field order matters

Concatenate the fields in exactly the order shown below. Using the wrong order results in a hash check failure and the refund is rejected.

Hash field concatenation order

Position Field
1 transactionId
2 amount, formatted with two decimal places, for example 100.00
3 refundReason
4 notifyUrl

Steps

  1. Concatenate the fields above in order
  2. Append your private key to the concatenated string
  3. Generate a SHA512 hash of the result and send the digest as lowercase hexadecimal
using System.Security.Cryptography;
using System.Text;

var transactionId = "00000000-0000-0000-0000-000000000000";
var amount = "50.00";
var refundReason = "Order cancellation";
var notifyUrl = "https://yourstore.com/notify";
var privateKey = "YOUR_PRIVATE_KEY";

var inputString = string.Concat(transactionId, amount, refundReason, notifyUrl, privateKey);

using SHA512 sha = SHA512.Create();
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(inputString));
var hashCheck = string.Concat(bytes.Select(b => b.ToString("x2")));
Console.WriteLine($"hashCheck: {hashCheck}");

Step 3: Submit the refund request

POST Submit refund Reference
POST https://api.ozow.com/secure/refunds/submit
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json

Submit every refund you want to process in a single request, as an array. Each item includes its own hash check from Step 2.

Request example

[
  {
    "transactionId": "00000000-0000-0000-0000-000000000000",
    "amount": 50.00,
    "refundReason": "Order cancellation",
    "notifyUrl": "https://yourstore.com/notify",
    "hashCheck": "YOUR_GENERATED_HASH"
  },
  {
    "transactionId": "00000000-0000-0000-0000-000000000001",
    "amount": 100.00,
    "refundReason": "Duplicate charge",
    "notifyUrl": "https://yourstore.com/notify",
    "hashCheck": "YOUR_GENERATED_HASH"
  }
]

Request fields

Field Type Required Description
transactionId string Yes The Ozow transaction ID of the original payment
amount number Yes Amount to refund. Must not exceed the original transaction amount
refundReason string No Reason for the refund
notifyUrl string No URL Ozow posts the refund notification to
isRtc boolean No Whether the refund is processed as an RTCReal-Time Clearing Payments that clear immediately rather than waiting for a batch. A batch run settles at set times through the day; a Real-Time Clearing payment moves the funds between the two bank accounts as it is made, so the recipient can rely on them straight away.PayInc refund. Defaults to false
hashCheck string Yes SHA512 hash generated in Step 2

For the full field reference see Submit refund.

Successful response

[
  {
    "refundId": "00000000-0000-0000-0000-000000000000",
    "transactionId": "00000000-0000-0000-0000-000000000000",
    "refundAmount": "50.00",
    "errors": null
  },
  {
    "refundId": null,
    "transactionId": "00000000-0000-0000-0000-000000000001",
    "refundAmount": "100.00",
    "errors": ["Hash check invalid"]
  }
]

Note

The API returns a response for each refund item in the array. Check the errors field for each item, a null value means the refund was accepted. A non-null value means the refund was rejected and includes the reason.

Store the refundId for each accepted refund, you can use it to check the status later.


Step 4: Handle the notification

Ozow sends a notification to your notifyUrl when a refund either completes or fails.

Notification fields

Field Description
refundId The refund identifier
transactionId The transaction identifier of the payment that was refunded
currencyCode The refund currency
amount The refund amount
status The refund status. See Notification statuses
bankName The name of the bank the refund was paid to
accountNumber The masked account number the refund was paid to
statusMessage Message about the refund status. Not always present
isRtc Whether RTC was used to pay the refund
hash SHA512 hash used to verify the notification

Verifying the notification hash

  1. Concatenate the fields in this order: refundId, transactionId, currencyCode, amount, status, bankName, accountNumber, statusMessage, excluding isRtc and hash
  2. Append your private key
  3. Lowercase the entire string
  4. Generate a SHA512 hash and compare it to the hash field received

Important

Always verify the notification hash before updating your records. Never update refund status without first verifying the hash.


Refund statuses

Two different endpoints represent refund status differently.

Refund resource status

Returned by getrefund, getrefunds, and getrefundsbytransactionid:

Status Description
0 Pending, the refund request has been submitted and accepted
1 Complete, the refund has been paid successfully
2 Submitted, the refund has been assigned to a batch and is being processed
3 Failed, the refund payment has failed
4 Cancelled, the refund was cancelled before it was submitted
5 Returned, the refund payment was returned because the destination account no longer exists

Notification statuses

Sent in the status field of the notifyUrl notification:

Status Description
Pending The refund request has been submitted and accepted
Submitted The refund has been assigned to a batch and is being processed
Complete The refund has been paid successfully
Failed The refund payment has failed
Cancelled The refund was cancelled before it was submitted
Returned The refund payment was returned because the destination account no longer exists
PendingInvestigation The refund is being investigated
Invalid The refund notification could not be validated
Error The refund could not be processed due to an error

Querying refunds

Get refund by ID

GET Get refund Reference
GET https://api.ozow.com/secure/refunds/getrefund?refundId={refundId}
Authorization: Bearer YOUR_ACCESS_TOKEN

Get refunds by transaction ID

Retrieve every refund issued against a specific original payment transaction:

GET Get refunds by transaction ID Reference
GET https://api.ozow.com/secure/refunds/getrefundsbytransactionid?transactionId={transactionId}
Authorization: Bearer YOUR_ACCESS_TOKEN

Get refunds by date and status

GET Get refunds Reference
GET https://api.ozow.com/secure/refunds/getrefunds?refundDate={refundDate}&status={status}
Authorization: Bearer YOUR_ACCESS_TOKEN

Query parameters

Parameter Type Required Description
refundDate string Yes Date of refunds to return. See Get refunds for the exact accepted format
status string Yes Refund status code to filter by, from the Refund resource status table

Next steps

In the API reference

6 entries

Last updated