Receipts

Generate a branded, view-only receipt for a completed payment with one API call. MoneyHash returns a hosted receipt URL. Your customer opens it in a browser and can download it as a PDF.

MoneyHash does not send receipts

You trigger receipt creation and deliver the link to your customer yourself - by email, SMS, WhatsApp, or any channel you use.


When to use it

Create a receipt from your success webhook handler: when MoneyHash tells you a payment succeeded, call the Receipts API with the intent ID and hand the returned URL to your customer.

Diagram: payment → success webhook → POST /api/v1.4/receipts → embed_url → customer.

For how to receive and verify your success webhook, see Webhooks and Payment Webhook.


Before you start

StepWhere
Configure the receipt content: document title, company name and address, VAT/CR number, header, footer, termsDashboard → Checkout Studio → Receipt tab
Configure colours and logoCheckout Studio branding. Receipts inherit it.
Test without real paymentsUse your test API key. See Sandbox.
Content and branding are copied into the receipt when it is created

Later changes in Checkout Studio apply only to receipts created afterwards. Existing receipts never change.


Sandbox

Receipts created with a test API key carry is_live: false. The same base URL serves test and live; the key decides which mode a request runs in. See Integration Modes and Sandbox.


Create a receipt

POST /api/v1.4/receipts
Base URL and authentication

Receipts use the same base URL and authentication as the rest of the MoneyHash API. Send requests to https://web.moneyhash.io/api/v1.4/ with your account API key in the x-api-key header. The same base URL serves test and live; the key decides the mode. See Programmatic Access.

Request fields

FieldTypeRequiredNotes
payment_sourcestringNoMONEYHASH
referencestringNoThe receipt number shown to your customer. Unique per account. Auto-generated if omitted.
receipt_dataobjectYesThe receipt content. See below.

receipt_data

FieldTypeRequiredNotes
intent_idstringYesThe intent must have a successful purchase or authorize transaction.
amountnumberIgnoredAlways taken from the intent transaction.
amount_currencystringIgnoredAlways taken from the intent transaction.
paid_atISO 8601IgnoredThe success time of the intent transaction.
customerUUIDOptionalA MoneyHash Customer ID. Used to fill customer details.
customer_detailsobjectOptionalname, email, phone_number, tax_id. Overrides customer.
product_itemsarrayOptionalSee product_items[].
feesarrayOptionalSee fees[].
Note

Anything you send for amount, amount_currency or paid_at is ignored. These always come from the intent transaction.

product_items

FieldTypeNotes
namestringLine name
amountnumberUnit amount
quantityinteger
descriptionstringOptional
category, subcategory, typestringOptional

fees

FieldTypeNotes
titleobjectLocalized: { "en": "...", "ar": "...", "fr": "..." }
valuenumberFee amount

Use fees for the subtotal, VAT, shipping, handling, or any other line shown under the items.

MoneyHash does not calculate tax or validate your line items, fees or totals

Amounts render exactly as you send them.


How MoneyHash fills in the receipt

What you send takes priority over what the intent holds - except amount, currency and paid-at, which always come from the intent transaction.

FieldWhere it comes from, in order
amount, amount_currencyThe intent transaction only
paid_atThe success time of the intent transaction
product_itemsYour payload → the intent
feesYour payload → the intent
customer_detailsYour customer_details → your customer ID → the intent's customer

Diagram: which source wins for each receipt field.

Values are resolved when the receipt is created and stored. They cannot be changed afterwards.


Examples

{
  "reference": "REC-MH-500",
  "receipt_data": {
    "intent_id": "gNWnNBq"
    }
}
{
  "reference": "REC-MH-50",
  "receipt_data": {
    "intent_id": "19zGjLY",
    "customer_details": {
      "name": "Ahmed Khalid",
      "email": "[email protected]",
      "phone_number": "+966500000000",
      "tax_id": "310000000000003"
    },
    "product_items": [
      { "name": "Postpaid line — September 2026", "description": "Test product description", "amount": 45.00, "quantity": 1 }
    ],
    "fees": [
      { "title": { "en": "VAT 15%", "ar": "ضريبة القيمة المضافة ١٥٪" }, "value": 5.00 }
    ]
  }
}

Example response

{
  "status": {
    "code": 200,
    "message": "success",
    "errors": []
  },
  "data": {
    "id": "e5d92f6e-a45d-41b7-8279-13dc91b5bdce",
    "payment_source": "MONEYHASH",
    "reference": "REC-MH-500",
    "embed_url": "https://embed.moneyhash.io/link/receipt/e5d92f6e-a45d-41b7-8279-13dc91b5bdce",
    "intent_id": "gNWnNBq",
    "amount": 500,
    "amount_currency": "AED",
    "paid_at": "2026-11-03T10:51:41.912938+00:00",
    "is_live": true,
    "created_at": "2026-11-10 04:58:59.786035+00:00"
  },
  "count": 1,
  "next": null,
  "previous": null
}
Note

amount, amount_currency and paid_at come from the intent transaction, whatever you send for them. If you omit reference, MoneyHash generates one. Send the embed_url to your customer.


Response

FieldNotes
idThe receipt ID. Use it to retrieve the receipt.
payment_sourceMONEYHASH
referenceYour reference, or the auto-generated one.
embed_urlThe hosted receipt page. Send this to your customer.
intent_idThe intent the receipt was created for.
amountThe amount taken from the intent transaction.
amount_currencyThe currency taken from the intent transaction.
paid_atThe success time of the intent transaction.
is_livefalse for receipts created with a test key.
created_atWhen the receipt was created.
Anyone with the embed_url can view the receipt

Do not publish it. Send it only to the customer it belongs to.


Retrieve a receipt

GET /api/v1.4/receipts/{id}

Returns the full stored receipt plus the brand_settings that were applied when it was created: a snapshot of your Checkout Studio branding.

{
  "status": {
    "code": 200,
    "message": "success",
    "errors": []
  },
  "data": {
    "account": "Test Account",
    "receipt_data": {
      "id": "e5d92f6e-a45d-41b7-8279-13dc91b5bdce",
      "payment_source": "MONEYHASH",
      "reference": "REC-MH-500",
      "fees": null,
      "amount": 500,
      "paid_at": "2026-11-03T10:51:41.912938+00:00",
      "product_items": null,
      "amount_currency": "AED",
      "customer_details": {
        "name": "test customer",
        "email": "[email protected]",
        "tax_id": null,
        "phone_number": "+201234567891"
      }
    },
    "brand_settings": {
      "brand_primary_color": "#1E3A8A",
      "brand_accent_color": "#F4C542",
      "icon": "https://www.example.com/icons/e3ba5.png",
      "privacy_policy": "https://www.example.com/Privacy-Policy",
      "terms_of_service": "https://www.example.com/Terms-of-Service",
      "light": {
        "brand_color": "#1E3A8A",
        "accent_color": "#F4C542",
        "background_color": "#ffffff",
        "header_color": "#ffffff",
        "primary_text_color": "#444444",
        "secondary_text_color": "#6b7280",
        "border_color": "#e5e7eb"
      },
      "dark": {
        "brand_color": "#23395b",
        "accent_color": "#ffe3c3",
        "background_color": "#18181b",
        "header_color": "#18181b",
        "primary_text_color": "#fafafa",
        "secondary_text_color": "#a1a1aa",
        "border_color": "#27272a"
      },
      "font_family": "Inter",
      "corner_radius": "regular",
      "logo_position": "left",
      "extra_methods": "collapsed",
      "saved_cards_display": "dropdown",
      "methods_layout": "accordion",
      "card_form_format": "expanded",
      "visibility": {
        "logo": false,
        "summary_sidebar": true,
        "payment_form_title": true,
        "payment_selector_title": true
      },
      "copy": {
        "receipt": {
          "footer": {
            "ar": "",
            "en": "",
            "fr": ""
          },
          "header": {
            "ar": "",
            "en": "",
            "fr": ""
          },
          "address": {
            "ar": "",
            "en": "",
            "fr": ""
          },
          "cr_number": "",
          "sub_header": {
            "ar": "",
            "en": "",
            "fr": ""
          },
          "vat_number": "",
          "company_name": {
            "ar": "",
            "en": "",
            "fr": ""
          }
        }
      },
      "apple_pay": {
        "merchant_name": ""
      },
      "icon_dark": null
    }
  },
  "count": 1,
  "next": null,
  "previous": null
}

The hosted receipt page

BehaviourDetail
AccessAnyone with the embed_url. Do not publish it, send it only to the customer it belongs to.
ContentYour Checkout Studio receipt content and branding, the reference, the customer (omitted if none), items, fees, totals, paid date, and terms/footer
No items sentOne line is generated: quantity 1, amount equal to the payment amount
PDFA download button on the page. Same content and layout as the page.
Payment actionsNone. The page never shows a checkout or a payment method.

Rules and errors

When a create request fails validation, the response comes back in this shape. Each entry in errors pairs a field name with a message:

{"status": {"code": 400, "message": "", "errors": [{"<field>": "<message>"}]}, "data": {}, ...}

Create a receipt

Top-level fields

FieldMessageWhen
receipt_dataThis field is required.It is missing
non_field_errorsInvalid data. Expected a dictionary, but got str.receipt_data is not an object
payment_source"X" is not a valid choice.MONEYHASH. This is the default, so you can omit it.
referenceEnsure this field has no more than 255 characters.It is longer than 255 characters
referenceA receipt with this reference already exists for the account.The reference is already used on this account

intent_id

FieldMessageWhen
intent_idThis field is required.It is missing
intent_idIntent not found.The ID does not exist, belongs to another account, or is in the other mode (live or test)
intent_idIntent has no active transaction.The intent has no active transaction
intent_idThe active transaction doesn't have a successful purchase or authorize operation.The intent has not been paid or authorized
Note

An intent created in live mode cannot be used with a test key, and the other way around. Both cases return Intent not found.

Optional fields

FieldMessage
customerMust be a valid UUID. / Customer not found. (the customer is not in this organization or this mode)
customer_detailsEnter a valid phone number. / Enter a valid email address.
product_itemsThis field is required. for name, amount, description and quantity; Subcategory and type are required; Category, Subcategory and type combination is not supported; number and range errors on the amount fields (minimum 0, up to the maximum amount)
feestitle: This field is required. (title.en is required). value: A valid number is required.

Retrieve a receipt

HTTPErrorWhen
404{"error": "Receipt not found."}The receipt does not exist, belongs to another account, or is in the other mode
Note

The 404 response body does not follow the status / errors shape shown above. Handle it separately in your error parsing.

Other rules

CaseResult
Edit, void or delete a receiptNot supported. A receipt is permanent once created.
A receipt is proof of payment. It is not a tax invoice

MoneyHash does not calculate tax or validate line items, fees or totals.


Common errors and troubleshooting

My request was rejected for an intent. +
The intent needs a successful purchase or authorize transaction. Check the intent's status and create the receipt after your success webhook fires.
My request was rejected for the reference. +
`reference` must be unique per account. Use a new one, or omit it and let MoneyHash generate it.
The amount on the receipt is not the amount I sent. +
Amount, currency and paid-at always come from the intent transaction. Anything you send for them is ignored.
I changed my receipt settings but the receipt looks the same. +
Content and branding are copied at creation. Changes in Checkout Studio affect only receipts created afterwards.
I need to correct a receipt. +
Receipts cannot be edited, voided or deleted. Create a new receipt with a new reference if you need to issue another.
I got a 404 when retrieving a receipt. +
The receipt ID does not exist. Use the `id` from the create response.

Related pages


Did this page help you?