Create Transaction
Creates a PIX charge. PIX is the only payment method this endpoint accepts (any other paymentMethod returns 400). Monetary values in the request are always in cents (integers).
/api/v1/transactions/createHeaders
| Header | Value | Status |
|---|---|---|
| Content-Type | application/json | Required |
| Accept | application/json | Recommended |
| X-Client-Id | <client_id> | Required |
| X-API-Key | <api_key> | Required |
| X-Operation-Token | <token with scope transaction:create> | Optional |
| Idempotency-Key | tx_<unique> | Recommended |
The header X-Operation-Token is optional, but recommended. When sent, it must be valid (generated at POST /api/v1/operation-auth/token with scope transaction:create), otherwise the API returns 401. See the section Authentication for more details.
The header Idempotency-Key is optional, but recommended to avoid duplicate transactions. Repeating the same key returns the same transaction.
Without the header, the API builds the key itself from your company, the payment method, the amount and the transaction reference. If you send the same reference with the same amount, the existing transaction is reused. With no reference, every call creates a new transaction.
Your transaction reference (externalRef)
To link the transaction to your order, send the field customer.externalRef. It comes back as externalRef in the response, in the transaction lookup and in the webhooks.
The reference used to build the idempotency key, when the header is not sent, follows this order: customer.externalRef, the externalRef of the first item, one of the keys externalRef, orderId, reference or clientRef inside metadata, and finally customer.id.
Important
All monetary values (amount, unitPrice, fee) must be sent in cents (integers).
Request Body (PIX)
{ "amount": 500, "currency": "BRL", "paymentMethod": "PIX", "installments": 1, "customer": { "id": "CUST-1729131560000", "name": "Joao Teste", "email": "joao.teste+1729131560000@exemplo.com", "document": { "number": "24577481600", "type": "CPF" }, "phone": "11987654321", "externalRef": "LEAD-1234" }, "shipping": { "fee": 0, "address": { "street": "Rua dos Testes", "streetNumber": "123", "complement": "Sala 2", "zipCode": "01001000", "neighborhood": "Centro", "city": "Sao Paulo", "state": "SP", "country": "BR" } }, "items": [ { "title": "Produto X", "unitPrice": 500, "quantity": 1, "tangible": true, "externalRef": "SKU-001" } ], "pix": { "expiresInDays": 1 }, "postbackUrl": "", "metadata": "{\"origem\":\"n8n\",\"ambiente\":\"homologacao\"}", "traceable": true, "ip": "177.123.45.67"}Request Body Fields
| Parameter | Type | Description |
|---|---|---|
amount* | integer | Amount in cents (500 = R$ 5.00). Greater than 0 and within your account's per-PIX limit |
currency | string | BRL (default) |
paymentMethod | string | PIX (default) |
installments | integer | Default 1. Changes nothing for PIX |
customer.externalRef | string | Your order reference. Comes back as externalRef in the response, the lookup and the webhooks |
customer | object | Optional as a whole. Any payer field you do not send is filled with a fixed placeholder, never left empty (see Payer placeholders below). The payer data is free text: it is not checked against the person who actually pays. The real payer name and document arrive after payment, in the payer object of the webhook and the lookup |
customer.name | string | Payer name. Placeholder when missing or blank: Cliente |
customer.email / phone / id | string | Payer data. Placeholders when missing or blank: nao-informado@respawnpay.com (email) and 00000000000 (phone) |
customer.document | object | { number, type } with CPF or CNPJ. Placeholder when missing or blank: number 00000000000, type CPF. It must be an object, a plain string returns a 400 error. Placeholder values are not valid documents, so an acquirer that validates the payer document can refuse the charge; send the real document when you have it |
shipping, items | object / array | Optional. Stored with the transaction; they do not change the PIX |
pix.expiresInDays | integer | Accepted in whole days (minimum 1, default 1); hours and minutes do not exist. With the OnlyUp acquirer the charge is created with a fixed validity of 1 hour (3600 s) at the bank, and this field only changes the pix.expiresAt value echoed in the response. A charge that is not paid within that hour can no longer be paid |
postbackUrl | string | Not used to notify you. Webhooks go to the URLs registered under Webhooks |
metadata | string | Free text, returned in the response |
traceable, ip | boolean / string | Optional and informational |
amountAmount in cents (500 = R$ 5.00). Greater than 0 and within your account's per-PIX limit
currencyBRL (default)
paymentMethodPIX (default)
installmentsDefault 1. Changes nothing for PIX
customer.externalRefYour order reference. Comes back as externalRef in the response, the lookup and the webhooks
customerOptional as a whole. Any payer field you do not send is filled with a fixed placeholder, never left empty (see Payer placeholders below). The payer data is free text: it is not checked against the person who actually pays. The real payer name and document arrive after payment, in the payer object of the webhook and the lookup
customer.namePayer name. Placeholder when missing or blank: Cliente
customer.email / phone / idPayer data. Placeholders when missing or blank: nao-informado@respawnpay.com (email) and 00000000000 (phone)
customer.document{ number, type } with CPF or CNPJ. Placeholder when missing or blank: number 00000000000, type CPF. It must be an object, a plain string returns a 400 error. Placeholder values are not valid documents, so an acquirer that validates the payer document can refuse the charge; send the real document when you have it
shipping, itemsOptional. Stored with the transaction; they do not change the PIX
pix.expiresInDaysAccepted in whole days (minimum 1, default 1); hours and minutes do not exist. With the OnlyUp acquirer the charge is created with a fixed validity of 1 hour (3600 s) at the bank, and this field only changes the pix.expiresAt value echoed in the response. A charge that is not paid within that hour can no longer be paid
postbackUrlNot used to notify you. Webhooks go to the URLs registered under Webhooks
metadataFree text, returned in the response
traceable, ipOptional and informational
Payer placeholders
The payer data is optional. When you omit the customer object or any of its fields (or send a blank value), we fill them with these fixed values, so the transaction, the lookup and the webhooks never carry an empty payer. A value you send is always kept as is.
| Parameter | Type | Description |
|---|---|---|
customer.name | string | Cliente |
customer.email | string | nao-informado@respawnpay.com |
customer.phone | string | 00000000000 |
customer.document.number | string | 00000000000 |
customer.document.type | string | CPF |
customer.nameCliente
customer.emailnao-informado@respawnpay.com
customer.phone00000000000
customer.document.number00000000000
customer.document.typeCPF
Response 200 (PIX)
Example of a created PIX charge:
{ "data": { "id": "6dcf2aee0d6148e1a12b78db78", "externalRef": "LEAD-1234", "amount": 500, "refundedAmount": 0, "providerCompanyId": null, "companyId": "2f3c1c0e-6a52-4a0f-9d34-6a7b3f6f2b10", "installments": 1, "paymentMethod": "PIX", "status": "WAITING_PAYMENT", "postbackUrl": "https://...", "metadata": null, "traceable": true, "secureId": null, "secureUrl": null, "pix": { "brcode": "00020126580014br.gov.bcb.pix...6304ABCD", "qrcode": "data:image/png;base64,iVBORw0KGgo...", "payloadBase64": "MDAwMjAxMjY1ODAwMTRici5nb3YuYmNiLnBpeC4uLg==", "imagemQrCodeInBase64": "iVBORw0KGgo...", "qrcodeBase64": "iVBORw0KGgo...", "txId": "6dcf2aee0d6148e1a12b78db78", "expiresAt": "2025-10-18T01:38:51.943+00:00" } }, "status": 200, "message": "Transação criada e registrada com sucesso (OnlyUp)."}| Parameter | Type | Description |
|---|---|---|
data.id | string | Transaction ID. Store it for lookups and reconciliation (it is the transactionId in webhooks) |
data.externalRef | string | Your reference (customer.externalRef sent on creation) |
data.postbackUrl | string | Internal callback address of the acquirer. It is not your webhook URL |
pix.brcode | string | PIX copy and paste code. This is the text the payer pastes in the bank app |
pix.qrcode | string | QR Code image as a data URL (data:image/png;base64,...). Use it in an image src |
pix.expiresAt | string | QR Code expiration date/time as echoed from expiresInDays. For OnlyUp the real validity at the bank is 1 hour from creation |
data.idTransaction ID. Store it for lookups and reconciliation (it is the transactionId in webhooks)
data.externalRefYour reference (customer.externalRef sent on creation)
data.postbackUrlInternal callback address of the acquirer. It is not your webhook URL
pix.brcodePIX copy and paste code. This is the text the payer pastes in the bank app
pix.qrcodeQR Code image as a data URL (data:image/png;base64,...). Use it in an image src
pix.expiresAtQR Code expiration date/time as echoed from expiresInDays. For OnlyUp the real validity at the bank is 1 hour from creation
The set of data.pix fields and the text of message depend on your account's acquirer (the message ends with the acquirer name). If the same Idempotency-Key is repeated, the API returns ok, message Idempotente and the transactionId of the transaction already created.
Important Notes
- •
amount,unitPrice,feeare in cents - •
providerCompanyIdcan be null; use thecompanyId(UUID) to identify your company - •The PIX copy and paste code comes in
pix.brcode.pix.qrcodeis the QR Code image - •Dates are ISO-8601 strings and may be null until the event happens (for example paidAt). Do not rely on the UTC offset printed in them; use the webhook events for ordering
- •The WAITING_PAYMENT status only appears in the creation response. After that, the status comes through webhooks (awaiting, pending, successful, failure, refunded) and the transaction lookup (pending, paid, canceled, failure, refunded)
- •Save the
data.id(it is also the providerTxId) for later queries and reconciliation
Errors
Errors come with an HTTP status code and a JSON body (see Error Handling for all body shapes). Examples from this endpoint:
{ "title": "amount inválido (centavos > 0)."}{ "title": "Valor acima do limite permitido.", "detail": "O valor máximo por cobrança PIX é R$ 1,500.00.", "maxValueCents": 150000}{ "title": "Somente PIX é suportado neste endpoint."}{ "title": "Token de operação inválido.", "detail": "Token inválido ou expirado.", "header": "X-Operation-Token"}| Code | Description |
|---|---|
| 400 | Bad Request: amount invalid or above your limit, payment method other than PIX, malformed body |
| 401 | Unauthorized: invalid or missing credentials, or an invalid X-Operation-Token |
| 403 | Forbidden: your IP is not in the company whitelist |
| 404 | Not Found: company not found for the credentials |
| 500 | Internal Server Error: unexpected error. The body only has an error code and a correlationId; retry with the same Idempotency-Key and send the correlationId to support |
cURL Example
# 1. First, generate the operation token (optional step)TOKEN=$(curl -s -X POST https://api.respawnpay.com/api/v1/operation-auth/token \ -H "Content-Type: application/json" \ -H "X-Client-Id: <CLIENT_ID>" \ -H "X-API-Key: <API_KEY>" \ -d '{"scopes": ["transaction:create"]}' | jq -r '.token')# 2. Create the transaction with the tokencurl -X POST https://api.respawnpay.com/api/v1/transactions/create \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "X-Client-Id: <CLIENT_ID>" \ -H "X-API-Key: <API_KEY>" \ -H "X-Operation-Token: $TOKEN" \ -H "Idempotency-Key: tx_$(date +%s)_$RANDOM" \ -d '{ "amount": 500, "currency": "BRL", "paymentMethod": "PIX", "installments": 1, "customer": { "id": "CUST-123", "name": "John", "email": "joao@ex.com", "document": {"number": "24577481600", "type": "CPF"}, "phone": "11987654321" }, "items": [{ "title": "Produto X", "unitPrice": 500, "quantity": 1, "tangible": true }], "pix": { "expiresInDays": 1 }, "postbackUrl": "", "traceable": true, "ip": "177.123.45.67" }'JavaScript (fetch) Example
// 1. Generate the operation token (optional step)const tokenResponse = await fetch("https://api.respawnpay.com/api/v1/operation-auth/token", { method: "POST", headers: { "Content-Type": "application/json", "X-Client-Id": "<CLIENT_ID>", "X-API-Key": "<API_KEY>" }, body: JSON.stringify({ scopes: ["transaction:create"], expiresInSeconds: 300 })});const { token } = await tokenResponse.json();// 2. Create the transaction with the tokenconst response = await fetch("https://api.respawnpay.com/api/v1/transactions/create", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json", "X-Client-Id": "<CLIENT_ID>", "X-API-Key": "<API_KEY>", "X-Operation-Token": token, "Idempotency-Key": `tx_${Date.now()}_${Math.floor(Math.random()*1e6)}` }, body: JSON.stringify({ amount: 500, currency: "BRL", paymentMethod: "PIX", installments: 1, customer: { id: "CUST-123", name: "John", email: "joao@ex.com", document: { number: "24577481600", type: "CPF" }, phone: "11987654321" }, items: [{ title: "Produto X", unitPrice: 500, quantity: 1, tangible: true }], pix: { expiresInDays: 1 }, postbackUrl: "", traceable: true, ip: "177.123.45.67" })});const data = await response.json();console.log(data);Final Notes
Save the id returned as providerTxId for later queries and reconciliation.
Status updates arrive through the webhooks registered on your account (Webhooks menu). The field postbackUrl is not used for this notification.
Polling with GET /api/Transaction/transactionByTransactionId/{id} is optional, but useful to check the transaction's current status.