curl --request GET \
--url https://api.paj.cash/pub/v2/transaction/{id} \
--header 'x-api-key: <api-key>'import requests
url = "https://api.paj.cash/pub/v2/transaction/{id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.paj.cash/pub/v2/transaction/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.paj.cash/pub/v2/transaction/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.paj.cash/pub/v2/transaction/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.paj.cash/pub/v2/transaction/{id}")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paj.cash/pub/v2/transaction/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "679be2527f99f556d77b8cc2",
"address": "4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j",
"signature": "2oLx7XrXP7Df9dZca1difJ91ZFmA44EEadNqrZTecta6ugcX8BAETbpvKQs54r58fmJTQVLzUSuzvRBFwS1GfJLo",
"mint": "So11111111111111111111111111111111111111112",
"currency": "NGN",
"amount": 100000,
"usdcAmount": 100,
"fiatAmount": 100,
"sender": "4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j",
"recipient": "4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j",
"rate": 9,
"status": "PENDDING",
"transactionType": "OFF_RAMP",
"createdAt": "2026-09-28T14:55:27.097Z",
"accountNumber": "0025635480",
"accountName": "Paj Inc.",
"bank": "First Bank",
"fee": 0.2,
"chain": "SOLANA"
}Get a transaction
Looks up an onramp or offramp order by the id returned when it was created, at any stage from INIT through to COMPLETED or ERROR. Only orders belonging to the API key’s business are found; any other id returns 404.
curl --request GET \
--url https://api.paj.cash/pub/v2/transaction/{id} \
--header 'x-api-key: <api-key>'import requests
url = "https://api.paj.cash/pub/v2/transaction/{id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.paj.cash/pub/v2/transaction/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.paj.cash/pub/v2/transaction/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.paj.cash/pub/v2/transaction/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.paj.cash/pub/v2/transaction/{id}")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paj.cash/pub/v2/transaction/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": "679be2527f99f556d77b8cc2",
"address": "4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j",
"signature": "2oLx7XrXP7Df9dZca1difJ91ZFmA44EEadNqrZTecta6ugcX8BAETbpvKQs54r58fmJTQVLzUSuzvRBFwS1GfJLo",
"mint": "So11111111111111111111111111111111111111112",
"currency": "NGN",
"amount": 100000,
"usdcAmount": 100,
"fiatAmount": 100,
"sender": "4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j",
"recipient": "4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j",
"rate": 9,
"status": "PENDDING",
"transactionType": "OFF_RAMP",
"createdAt": "2026-09-28T14:55:27.097Z",
"accountNumber": "0025635480",
"accountName": "Paj Inc.",
"bank": "First Bank",
"fee": 0.2,
"chain": "SOLANA"
}id is the one on
the response that created the order — from Create an onramp
order or Create an offramp
order — and it stays the same for the
order’s whole life, so the id you stored at creation finds it at INIT,
PROCESSING, COMPLETED or ERROR alike.
The body uses the same fields as the response that created the order and as a
ramp webhook delivery, so one parser handles all three. Two differences are
worth knowing:
- The payout account (
accountNumber,accountName,bank) that Create an offramp order adds to its response is not repeated here. Keep it from the creation response if you need it. - Once an onramp order is
COMPLETED, the virtual account it was paid into is no longer included — it has served its purpose.
When to call it
Webhooks are the primary way to follow an order; this is the fallback. It is the right call when:- a webhook delivery failed or your handler was down, and you need to know where an order ended up;
- you want to confirm a webhook against Paj’s own record before acting on it;
- you have no webhook configured and are polling.
PROCESSING. An order in INIT is waiting on your user, not on Paj, so there
is no point polling it quickly.
Only your own orders
The lookup is scoped to the business behind your API key. An id that belongs to another business returns404, exactly as an id that does not exist does, so the
response never reveals whether someone else’s order is real.
An id that is not a well-formed id at all is a 400.
INIT eventually starts returning 404. Treat that as expired rather
than as an error.Authorizations
Path Parameters
The id returned when the order was created
"68ff3a4ee9834db8927f61ed"
Response
The transaction in its current state
Transaction Id
"679be2527f99f556d77b8cc2"
Address
"4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j"
Transaction Signature
"2oLx7XrXP7Df9dZca1difJ91ZFmA44EEadNqrZTecta6ugcX8BAETbpvKQs54r58fmJTQVLzUSuzvRBFwS1GfJLo"
Mint Address
"So11111111111111111111111111111111111111112"
Currency
"NGN"
Mint Amount
100000
Usdc Amount
100
Fiat Amount
100
Wallet Public Key
"4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j"
Recipient Public Key
"4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j"
Rate of currency to usdc
9
Transaction Status
"PENDDING"
Transaction Type
"OFF_RAMP"
Transaction creation date
"2026-09-28T14:55:27.097Z"
Account Number (for onramp transactions)
"0025635480"
Account Name (for onramp transactions)
"Paj Inc."
Bank Name (for onramp transactions)
"First Bank"
Transaction fee in usdc
0.2
Chain
"SOLANA"