Odit Verify

Awash Bank

Detail page — public receipt URL, page structure, captured fields, and return shape.

Awash Bank's awashpay.awashbank.com:8225 is a server-rendered static HTML "VAT Invoice / Customer Receipt" page. We fetch it directly and scrape the structured tables into JSON.

URL format

https://awashpay.awashbank.com:8225/-<TOKEN>
PartPatternExample
hostliteralawashpay.awashbank.com
portliteral:8225
<TOKEN>leading dash + alphanumerics-and-dashes-ABCD1234EF-1A2B3C

The leading dash on the path is part of the URL — every Awash receipt link starts with one. The token interior carries one or more additional dashes.

What we actually hit

The URL is passed through unchanged — no SPA bypass, no API endpoint substitution. A direct GET returns the receipt HTML in ~250 ms.

Return type

receipt.source === "awash-html". The static company-info block (TIN 0000030100, VAT Reg 17264, etc.) is dropped — it's identical on every Awash receipt. We capture two sub-objects: customer (the receipt holder) and transaction (the payment itself).

interface AwashReceipt {
  source: 'awash-html';
 
  customer: {
    customerName?: string;             // e.g. "<customer name>"
    accountNo?: string;                // masked: "XXXXX******XXXX/BANK"
    city?: string;                     // e.g. "Addis Ababa"
    vatRegNo?: string;                 // "-" when the customer isn't VAT-registered
    vatRegDate?: string;
    tinTaxId?: string;                 // labelled "TIN (TAX ID)" on the receipt
    branch?: string;                   // e.g. "<branch name>"
  };
 
  transaction: {
    transactionTime?: string;          // "YYYY-MM-DD HH:MM:SS AM|PM"
    transactionType?: string;          // see "Supported transaction types" below
    amount?: string;                   // string with currency: "<amount> ETB"
    vat?: string;                      // string with currency: "<vat> ETB"
    charge?: string;                   // service charge — present on wallet/bill receipts
    senderName?: string;
    senderAccount?: string;            // masked: "XXXXX*******XXX"
    beneficiaryName?: string;
    beneficiaryAccount?: string;
    beneficiaryBank?: string;          // e.g. "Commercial Bank of Ethiopia"
    reason?: string;                   // e.g. "Transfer"
    transactionId?: string;            // 15-digit numeric (placeholder: "000000000000000")
 
    // Any label found in the transaction table that didn't map to one of the
    // typed fields above — e.g. "Branch", "CBS Trans ID" on WITHDRAW/DEPOSIT;
    // "Student Code", "Student Class", "School" on School Fees. Absent when
    // every label resolved to a typed field (IPS Bank Transfer, etc.).
    extra?: Record<string, string>;
  };
}

Not every field is set on every receipt — Awash issues at least nine distinct layouts depending on transactionType, each carrying a different subset.

Supported transaction types

Awash uses synonym labels across receipt types (Sender Name / Customer Name / Name, Beneficiary Account / Phone Number / CA Number, etc.). The parser maps each synonym into the same typed field below. Type-specific labels we don't have first-class names for surface inside transaction.extra.

transactionTypesenderName sourcebeneficiaryName / …Account sourceLands in extra
IPS Bank TransferSender NameBeneficiary Name + Account + Bank
Telebirr TransferCustomer Name— / Phone Number
Send Moneycustomer fallbackRecipient
Bill PaymentCustomer Name— / CA NumberInvoice Number, Invoice Date
Ethiotelecom Postpaid BillCustomer Name— / Service Number
Bulk PaymentSenderRecipient
WITHDRAWcustomer fallbackBranch, CBS Trans ID
DEPOSITcustomer fallbackBranch, CBS Trans ID
School Feescustomer fallbackStudent NameStudent Code, Student Class, School, Payment Period

senderName fallback

For receipt types where Awash doesn't include a separate sender field — WITHDRAW, DEPOSIT, Send Money, School Fees — the receipt-holder is implicitly the originating party, so transaction.senderName falls back to customer.customerName. This guarantees the validation rule below holds across all nine types; you can detect whether the fallback fired by comparing transaction.senderName === customer.customerName.

Samples

IPS Bank Transfer

{
  "source": "awash-html",
  "customer": {
    "customerName": "<customer name>",
    "accountNo": "XXXXX******XXXX/BANK",
    "city": "Addis Ababa",
    "vatRegNo": "-",
    "vatRegDate": "-",
    "tinTaxId": "-",
    "branch": "<branch>"
  },
  "transaction": {
    "transactionTime": "2026-01-01 00:00:00 AM",
    "transactionType": "IPS Bank Transfer",
    "amount": "100 ETB",
    "vat": "0.09 ETB",
    "senderName": "<sender name>",
    "senderAccount": "XXXXX*******XXX",
    "beneficiaryName": "<beneficiary name>",
    "beneficiaryAccount": "1000000000000",
    "beneficiaryBank": "Commercial Bank of Ethiopia",
    "reason": "Transfer",
    "transactionId": "000000000000000"
  }
}

Telebirr Transfer

{
  "source": "awash-html",
  "customer": {
    "customerName": "<customer name>",
    "accountNo": "XXXXX******XXXX/BANK",
    "city": "Addis Ababa",
    "branch": "<branch>"
  },
  "transaction": {
    "transactionTime": "2026-01-01 00:00:00 AM",
    "transactionType": "Telebirr Transfer",
    "amount": "100 ETB",
    "vat": "0.09 ETB",
    "charge": "1 ETB",
    "senderName": "<customer name>",
    "senderAccount": "XXXXX*******XXX",
    "beneficiaryAccount": "251********",
    "reason": "Transfer",
    "transactionId": "000000000000000"
  }
}

School Fees (with extra)

{
  "source": "awash-html",
  "customer": { "customerName": "<customer name>", "branch": "<branch>" },
  "transaction": {
    "transactionTime": "2026-01-01 00:00:00 AM",
    "transactionType": "School Fees",
    "amount": "100 ETB",
    "senderName": "<customer name>",
    "beneficiaryName": "<student name>",
    "transactionId": "000000000000000",
    "extra": {
      "Student Code": "<student code>",
      "Student Class": "<student class>",
      "School": "<school name>",
      "Payment Period": "<payment period>"
    }
  }
}

WITHDRAW (with extra)

{
  "source": "awash-html",
  "customer": { "customerName": "<customer name>", "branch": "<branch>" },
  "transaction": {
    "transactionTime": "2026-01-01 00:00:00 AM",
    "transactionType": "WITHDRAW",
    "amount": "100 ETB",
    "senderName": "<customer name>",
    "senderAccount": "XXXXX*******XXX",
    "transactionId": "000000000000000",
    "extra": {
      "Branch": "<branch>",
      "CBS Trans ID": "<trans id>"
    }
  }
}

Quirks

  • The receipt page is a static HTML render — no SPA hydration needed, curl returns the full page. The embedded QR code re-encodes the same URL the page was served from.
  • Amounts are strings with currency suffix"1800 ETB", not 1800. Awash ships them this way; we preserve verbatim so the caller can decide whether to strip ETB or keep it.
  • Duplicate field labels — "VAT Reg No" and "VAT Reg Date" appear in both the company-info section (dropped) and the customer-info section (captured). The parser slices by the second <table class="info-table"> to avoid the company's static 17264 shadowing the customer's -.
  • Multi-payee beneficiary names — Awash receipts for batch transfers contain &amp;-separated names (e.g. "<NAME-1> &<NAME-2> &<NAME-3>"). HTML entities are decoded before return.
  • Two different masks for the same account — the receipt-holder's account on customer.accountNo carries one mask shape (e.g. XXXXX******XXXX/BANK with the /BANK suffix), while transaction.senderAccount carries a slightly different one (e.g. XXXXX*******XXX, no suffix). Awash masks them at the source; we don't unmask or re-mask.
  • transaction.extra is type-specific — same parser, different layout per transactionType. If you only consume the typed fields, extra can be ignored; if you need to render the full receipt faithfully, iterate over extra and render its (key, value) pairs alongside.
  • Validation rule — receipt is considered valid only when transaction.transactionId, transaction.senderName, AND transaction.amount are all present. With the customer-fallback for senderName, this passes for all nine receipt types whenever the upstream HTML is complete.

On this page