Receipts
Cash-Out Receipt

Payout receipt

In this section, you will learn how to retrieve the receipt (comprovante) for a payout you have sent.

The receipt is fetched live from the bank that processed the payout, using your own banking credentials, and is returned as a base64-encoded PDF inside a JSON response.

Available Endpoint

  • Sandbox: https://sandbox.pixtopay.com.br/v2/withdrawals/receipt
  • Production: https://api.pixtopay.com.br/v2/withdrawals/receipt

Supported providers

Receipts are available for payouts processed by StarkBank, EFIPAY and GENIAL. A payout sent through any other provider returns 400.


Get the receipt

Route

GET /v2/withdrawals/receipt

Headers

{
  "Authorization": "YOUR_API_KEY"
}

Query Parameters

Important: Use only one of the parameters below, never both.

ParameterTypeRequiredDescription
idintegerYes*Internal payout ID generated by PixToPay
transaction_idstringYes*Unique payout identifier on your platform

* Provide either id or transaction_id

Request example by ID

curl --location 'https://api.pixtopay.com.br/v2/withdrawals/receipt?id=685' \
--header 'Authorization: API_KEY'

Request example by transaction_id

curl --location 'https://api.pixtopay.com.br/v2/withdrawals/receipt?transaction_id=12345678911' \
--header 'Authorization: API_KEY'

Response 200 - Success

{
  "type": "payout",
  "provider": "STARKBANK",
  "id": 685,
  "transaction_id": "12345678911",
  "e2e_id": "E20018183202507030306IVCXWQNh0fQ",
  "filename": "payout_E20018183202507030306IVCXWQNh0fQ.pdf",
  "content_type": "application/pdf",
  "pdf": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBl..."
}
FieldTypeDescription
typestringAlways payout for this endpoint
providerstringBank that processed the payout: STARKBANK, EFIPAY, GENIAL
idnumberInternal payout ID
transaction_idstringYour own payout identifier
e2e_idstringPIX end-to-end identifier
filenamestringSuggested file name when saving the PDF
content_typestringAlways application/pdf
pdfstringThe receipt itself, base64-encoded

Decode pdf from base64 to obtain the file. See the examples below.

Response 400 - Invalid parameters

{
  "type": "ValidationError",
  "message": "please provide only one of transaction_id, id"
}

When neither parameter is sent:

{
  "type": "ValidationError",
  "message": "one of transaction_id, id is required!"
}

Response 400 - Provider not enabled or not supported

{
  "message": "STARKBANK is not enabled for this account."
}
{
  "message": "Receipts are not supported for provider PAGSMILE."
}

Response 403 - API key not allowed

Returned when a read-only API key does not have access to withdrawals.

{
  "message": "Access to withdrawals is forbidden for this API key!"
}

Response 404 - Payout not found

{
  "message": "Payout not found!"
}

Response 409 - Receipt not available yet

The payout exists but the bank has not issued a receipt for it, typically because the transfer has not settled.

{
  "message": "Receipt not available yet: the transfer has not settled at StarkBank.",
  "detail": "vouchers can only be requested for successful transfers"
}

Retry once the payout is settled.

Response 502 - Provider refused the request

The bank was reachable but rejected the request — for example an IP allow-list rejection, or an account that can no longer be queried.

{
  "message": "Failed to retrieve the receipt from EFIPAY.",
  "detail": "Request failed with status code 403"
}

The detail field carries the provider's own message and is intended for troubleshooting.


Saving the PDF

JavaScript/TypeScript

async function downloadReceipt(transactionId) {
  const response = await fetch(
    `https://api.pixtopay.com.br/v2/withdrawals/receipt?transaction_id=${transactionId}`,
    {
      headers: {
        Authorization: "YOUR_API_KEY",
      },
    }
  );
 
  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.message);
  }
 
  const receipt = await response.json();
 
  // Browser: turn the base64 payload into a downloadable file
  const bytes = Uint8Array.from(atob(receipt.pdf), (c) => c.charCodeAt(0));
  const blob = new Blob([bytes], { type: receipt.content_type });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = receipt.filename;
  document.body.appendChild(a);
  a.click();
  a.remove();
  window.URL.revokeObjectURL(url);
}

On Node.js, write the file directly instead:

const fs = require("fs");
 
fs.writeFileSync(receipt.filename, Buffer.from(receipt.pdf, "base64"));

Python

import base64
import requests
 
def download_receipt(transaction_id):
    url = "https://api.pixtopay.com.br/v2/withdrawals/receipt"
    headers = {"Authorization": "YOUR_API_KEY"}
 
    response = requests.get(url, headers=headers, params={"transaction_id": transaction_id})
 
    if response.status_code != 200:
        print(f"Error: {response.json()['message']}")
        return
 
    receipt = response.json()
 
    with open(receipt["filename"], "wb") as f:
        f.write(base64.b64decode(receipt["pdf"]))
 
    print(f"Saved {receipt['filename']}")

PHP

<?php
$transactionId = "12345678911";
$url = "https://api.pixtopay.com.br/v2/withdrawals/receipt?transaction_id=" . urlencode($transactionId);
 
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: YOUR_API_KEY']);
 
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
 
$body = json_decode($output, true);
 
if ($httpCode === 200) {
    file_put_contents($body['filename'], base64_decode($body['pdf']));
    echo "Saved " . $body['filename'];
} else {
    echo "Error: " . $body['message'];
}
?>

Important Notes

  • Live data: the receipt is fetched from the bank on every request, using the banking credentials configured for your account. Nothing is cached on our side.
  • Availability: a receipt only exists once the bank has settled the payout. Before that the endpoint returns 409, not an error you should treat as permanent.
  • Errors are specific: 409 means "not ready yet, retry later", while 502 means the bank refused the request and something needs to be looked at. Use the status to decide whether to retry.
  • Size: the base64 payload is roughly 33% larger than the PDF itself, which is usually between 50KB and 200KB.

Related