PIX Cash-In(收款)
概述
PIX Cash-In 端点允许您生成动态 PIX 收款码以接收付款。每笔收款会生成一个唯一的二维码和一个 PIX 代码(复制粘贴),您的客户可以使用它们完成付款。
此端点需要有效的 Bearer token。详情请参阅认证文档。
功能特性
- 动态二维码生成
- EMV 格式 PIX 代码(复制粘贴)
- 可配置的到期时间(5 分钟至 7 天)
- 通过
externalId唯一标识 - 可自定义的附加信息
- 自动验证 CPF/CNPJ
- 支付分账:在多个收款方之间自动分配
端点
POST /api/pix/cash-in
生成新的 PIX 收款。
必需请求头
Authorization: Bearer {token}
Content-Type: application/json请求体
{
"transaction": {
"value": 150.00,
"description": "Payment for order #12345",
"expirationTime": 86400,
"externalId": "ORDER-12345-20240119",
"generateQrCode": true
},
"payer": {
"fullName": "Carlos Oliveira",
"document": "12345678901"
},
"additionalInfo": {
"orderId": "12345",
"storeName": "Tech Solutions",
"productCategory": "Electronics"
},
"splits": [
{
"pixKey": "supplier@email.com",
"pixKeyType": "EMAIL",
"name": "Supplier Ltd",
"document": "12345678000199",
"type": "PERCENTAGE",
"value": 10,
"immediate": false
}
]
}请求
curl -X POST https://api.public.firebanking.com.br/api/pix/cash-in \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"transaction": {
"value": 150.00,
"description": "Payment for order #12345",
"expirationTime": 86400,
"externalId": "ORDER-12345-20240119",
"generateQrCode": true
},
"payer": {
"fullName": "Carlos Oliveira",
"document": "12345678901"
},
"additionalInfo": {
"orderId": "12345"
},
"splits": [
{
"pixKey": "supplier@email.com",
"pixKeyType": "EMAIL",
"name": "Supplier Ltd",
"document": "12345678000199",
"type": "PERCENTAGE",
"value": 70,
"immediate": false
}
]
}'splits 字段为可选。有关类型、金额格式和频率的完整详情,请参阅支付分账指南。
响应 (201 Created)
{
"transactionId": "7845",
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"externalId": "ORDER-12345-20240119",
"status": "PENDING",
"pixCode": "00020126580014br.gov.bcb.pix0136550e8400-e29b-41d4-a716-4466554400005204000053039865802BR5916Tech Solutions Ltda6009SAO PAULO62070503***63041D3D",
"generateTime": "2024-01-19T14:30:00.000Z",
"expirationDate": "2024-01-20T14:30:00.000Z",
"qrCodeImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51..."
}qrCodeImage 字段仅在请求中发送 generateQrCode: true 时返回。值为 Data URL 格式的 Base64 编码 PNG 图片。
请求参数
Transaction 对象
transaction.valuenumberobrigatorio交易金额,单位为巴西雷亚尔 (BRL)。最多 2 位小数。
最小值: 0.01
示例: 150.00
transaction.descriptionstringobrigatorio交易描述,将显示在付款方的账单中。
最大长度: 140 个字符
示例: "Payment for order #12345"
transaction.expirationTimenumber到期时间,单位为秒。
最小值: 300(5 分钟)
最大值: 604800(7 天)
默认值: 86400(24 小时)
transaction.externalIdstringobrigatorio交易的唯一外部标识符。用于与您的系统关联。
最大长度: 255 个字符
建议: 使用包含日期/时间的格式以确保唯一性
示例: "ORDER-12345-20240119-143000"
transaction.generateQrCodeboolean是否生成 Base64 格式的二维码。
默认值: false
建议: 使用 true 以向用户展示二维码
Payer 对象
payer.fullNamestringobrigatorio付款方全名。
示例: "Carlos Oliveira"
payer.documentstringobrigatorio付款方的 CPF 或 CNPJ(仅数字)。
CPF: 11 位数字
CNPJ: 14 位数字
示例: "12345678901" 或 "12345678000199"
Additional Info 对象
additionalInfoobject键值对格式的附加信息(string:string)。
最大数量: 10 个键
示例:
{
"orderId": "12345",
"customerId": "67890",
"storeName": "Tech Solutions"
}Splits 数组(可选)
splitsarray收款方列表,用于自动分配收到的付款。当 PIX-IN 确认后,金额将被分配并通过 PIX 自动发送给每位收款方。
最大数量: 每笔交易 10 个收款方
splits[].pixKeystringobrigatorio分账收款方的 PIX 密钥。
最大长度: 255 个字符
示例: "supplier@email.com"
splits[].pixKeyTypestringobrigatorio收款方的 PIX 密钥类型。
可选值: EMAIL、PHONE、CPF、CNPJ、RANDOM
示例: "EMAIL"
splits[].namestringobrigatorio收款方全名。
最大长度: 255 个字符
示例: "Supplier Ltd"
splits[].documentstringobrigatorio收款方的 CPF 或 CNPJ(仅数字)。
CPF: 11 位数字 | CNPJ: 14 位数字
示例: "12345678000199"
splits[].typestringobrigatorio分账类型:固定金额或百分比。
可选值:
FIXED-- 固定金额(BRL)(例如:10.00= R$ 10.00)PERCENTAGE-- 直接百分比(例如:10= 10%)
示例: "PERCENTAGE"
splits[].valuenumberobrigatorio根据类型设置的分账金额:
- FIXED: BRL 金额,最多 2 位小数。
10.50= R$ 10.50 - PERCENTAGE: 直接百分比。
10= 10%,25.5= 25.5%
最小值: 0.01
示例: 10(PERCENTAGE 类型表示 10%)或 10.00(FIXED 类型表示 R$ 10.00)
splits[].immediateboolean如果为 true,分账将在 PIX-IN 确认后立即执行,忽略账户配置的频率。
默认值: false
分账总和(固定金额 + 总额百分比)加上手续费不能超过交易金额。如果超过,API 将返回 400 错误。
响应结构
transactionIdstringsempre presenteAvista 生成的内部交易 ID。
示例: "7845"
correlationIdstringsempre presente用于跟踪和关联交易的 UUID。
示例: "550e8400-e29b-41d4-a716-446655440000"
externalIdstringsempre presente请求中提供的外部 ID(与输入值相同)。
示例: "ORDER-12345-20240119"
statusstringsempre presente当前交易状态。
可选值:
PENDING:等待付款CONFIRMED:付款已确认ERROR:处理错误
示例: "PENDING"
pixCodestringsempre presenteEMV 格式的 PIX 代码(复制粘贴)。
示例: "00020126580014br.gov.bcb.pix..."
generateTimestringsempre presente收款码生成日期和时间(ISO 8601 UTC)。
示例: "2024-01-19T14:30:00.000Z"
expirationDatestringsempre presente收款码到期日期和时间(ISO 8601 UTC)。
示例: "2024-01-20T14:30:00.000Z"
qrCodeImagestringData URL 格式的 Base64 二维码。仅在请求中设置 generateQrCode: true 时返回。
格式: data:image/png;base64,{base64_encoded_image}
示例: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51..."
用途: 可直接在 HTML <img> 标签中显示,或解码后保存为文件。
实现示例
Node.js / TypeScript
import axios from 'axios';
interface CashInRequest {
transaction: {
value: number;
description: string;
expirationTime?: number;
externalId: string;
generateQrCode?: boolean;
};
payer: {
fullName: string;
document: string;
};
additionalInfo?: Record<string, string>;
}
interface CashInResponse {
transactionId: string;
correlationId: string;
externalId: string;
status: 'PENDING' | 'CONFIRMED' | 'ERROR';
pixCode: string;
generateTime: string;
expirationDate: string;
qrCodeImage?: string; // Present only when generateQrCode: true
}
async function createPixCharge(
token: string,
orderId: string,
amount: number,
customerName: string,
customerDocument: string
): Promise<CashInResponse> {
const payload: CashInRequest = {
transaction: {
value: amount,
description: `Payment for order ${orderId}`,
expirationTime: 3600, // 1 hour
externalId: `ORDER-${orderId}-${Date.now()}`,
generateQrCode: true
},
payer: {
fullName: customerName,
document: customerDocument
},
additionalInfo: {
orderId: orderId,
timestamp: new Date().toISOString()
}
};
try {
const response = await axios.post<CashInResponse>(
'https://api.public.firebanking.com.br/api/pix/cash-in',
payload,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
console.log('PIX charge generated successfully!');
console.log(`Transaction ID: ${response.data.transactionId}`);
console.log(`PIX Code: ${response.data.pixCode}`);
console.log(`Expires at: ${new Date(response.data.expirationDate).toLocaleString('pt-BR')}`);
if (response.data.qrCodeImage) {
console.log('QR Code Image available for display');
}
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Error generating charge:', error.response?.data);
throw new Error(error.response?.data?.message || 'Error generating PIX charge');
}
throw error;
}
}
// Usage
const token = 'your_token_here';
createPixCharge(token, '12345', 150.00, 'Carlos Oliveira', '12345678901');Python
import requests
from datetime import datetime, timedelta
from typing import Dict, Optional
def create_pix_charge(
token: str,
order_id: str,
amount: float,
customer_name: str,
customer_document: str,
expiration_hours: int = 1,
additional_info: Optional[Dict[str, str]] = None
) -> Dict:
"""
Generate a PIX charge
Args:
token: Valid Bearer token
order_id: Order ID
amount: Value in BRL
customer_name: Customer name
customer_document: CPF or CNPJ (numbers only)
expiration_hours: Hours until expiration (default: 1)
additional_info: Additional information
Returns:
Generated charge data
"""
url = 'https://api.public.firebanking.com.br/api/pix/cash-in'
payload = {
'transaction': {
'value': round(amount, 2),
'description': f'Payment for order {order_id}',
'expirationTime': expiration_hours * 3600,
'externalId': f'ORDER-{order_id}-{int(datetime.now().timestamp())}',
'generateQrCode': True
},
'payer': {
'fullName': customer_name,
'document': customer_document
},
'additionalInfo': additional_info or {}
}
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
try:
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
print('PIX charge generated successfully!')
print(f"Transaction ID: {data['transactionId']}")
print(f"PIX Code: {data['pixCode']}")
print(f"Status: {data['status']}")
expiration = datetime.fromisoformat(data['expirationDate'].replace('Z', '+00:00'))
print(f"Expires at: {expiration.strftime('%d/%m/%Y %H:%M:%S')}")
if 'qrCodeImage' in data:
print('QR Code Image available for display')
return data
except requests.exceptions.RequestException as e:
print(f'Error generating charge: {e}')
if hasattr(e.response, 'json'):
print(f'Details: {e.response.json()}')
raise
# Usage
token = 'your_token_here'
charge = create_pix_charge(
token=token,
order_id='12345',
amount=150.00,
customer_name='Carlos Oliveira',
customer_document='12345678901',
expiration_hours=24,
additional_info={
'storeName': 'Tech Solutions',
'productCategory': 'Electronics'
}
)PHP
<?php
function createPixCharge(
string $token,
string $orderId,
float $amount,
string $customerName,
string $customerDocument,
int $expirationHours = 1
): array {
$url = 'https://api.public.firebanking.com.br/api/pix/cash-in';
$payload = [
'transaction' => [
'value' => round($amount, 2),
'description' => "Payment for order $orderId",
'expirationTime' => $expirationHours * 3600,
'externalId' => "ORDER-$orderId-" . time(),
'generateQrCode' => true
],
'payer' => [
'fullName' => $customerName,
'document' => $customerDocument
],
'additionalInfo' => [
'orderId' => $orderId
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 201) {
throw new Exception("Error generating charge: HTTP $httpCode - $response");
}
$data = json_decode($response, true);
echo "PIX charge generated successfully!" . PHP_EOL;
echo "Transaction ID: {$data['transactionId']}" . PHP_EOL;
echo "PIX Code: {$data['pixCode']}" . PHP_EOL;
echo "Status: {$data['status']}" . PHP_EOL;
if (isset($data['qrCodeImage'])) {
echo "QR Code Image available for display" . PHP_EOL;
}
return $data;
}
// Usage
$token = 'your_token_here';
$charge = createPixCharge(
$token,
'12345',
150.00,
'Carlos Oliveira',
'12345678901',
24
);使用场景
1. 电子商务 - PIX 结账
// E-commerce checkout integration
class PixCheckout {
constructor(token) {
this.token = token;
}
async generatePayment(order) {
const charge = await createPixCharge(
this.token,
order.id,
order.total,
order.customer.name,
order.customer.document
);
// Display QR Code on the page (using API image or generating locally)
this.displayQrCode(charge);
// Start polling to check payment
this.startPaymentPolling(charge.transactionId);
return charge;
}
displayQrCode(charge) {
const qrCanvas = document.getElementById('qr-canvas');
const qrImage = document.getElementById('qr-image');
// Use Base64 image from API (preferred - avoids client-side processing)
if (charge.qrCodeImage) {
qrImage.src = charge.qrCodeImage;
qrImage.style.display = 'block';
qrCanvas.style.display = 'none';
} else {
// Fallback: generate QR Code locally using a library (e.g.: qrcode.js)
QRCode.toCanvas(qrCanvas, charge.pixCode, {
width: 300,
margin: 2
});
qrCanvas.style.display = 'block';
qrImage.style.display = 'none';
}
// Also show the PIX Copy and Paste code
document.getElementById('pix-code').textContent = charge.pixCode;
}
startPaymentPolling(transactionId) {
// Check status every 3 seconds
const interval = setInterval(async () => {
const status = await this.checkPaymentStatus(transactionId);
if (status === 'CONFIRMED') {
clearInterval(interval);
this.onPaymentConfirmed();
}
}, 3000);
// Stop after 10 minutes
setTimeout(() => clearInterval(interval), 10 * 60 * 1000);
}
onPaymentConfirmed() {
// Redirect to success page
window.location.href = '/payment/success';
}
}2. POS(销售终端)
class PixPDV:
"""POS system with PIX charge"""
def __init__(self, token: str):
self.token = token
def process_sale(self, items: list, customer: dict) -> dict:
"""Process sale and generate PIX charge"""
# Calculate total
total = sum(item['price'] * item['quantity'] for item in items)
# Generate description
description = self.generate_sale_description(items)
# Create PIX charge (expires in 15 minutes)
charge = create_pix_charge(
token=self.token,
order_id=self.generate_sale_id(),
amount=total,
customer_name=customer['name'],
customer_document=customer['document'],
expiration_hours=0.25, # 15 minutes
additional_info={
'items_count': str(len(items)),
'cashier_id': self.get_cashier_id()
}
)
# Print receipt with QR Code
self.print_receipt(charge, items, total)
return charge
def generate_sale_description(self, items: list) -> str:
"""Generate a summary description of the sale"""
if len(items) == 1:
return f"{items[0]['name']}"
else:
return f"{len(items)} items - {items[0]['name']} and more"
def print_receipt(self, charge: dict, items: list, total: float):
"""Print receipt with QR Code"""
# Implement thermal printing or generate PDF
print("\n" + "="*50)
print("PIX CHARGE RECEIPT")
print("="*50)
for item in items:
print(f"{item['name']}: R$ {item['price']:.2f}")
print("-"*50)
print(f"TOTAL: R$ {total:.2f}")
print(f"\nTransaction ID: {charge['transactionId']}")
print(f"PIX Code:\n{charge['pixCode']}")
print("="*50 + "\n")3. SaaS - 订阅计费
class SubscriptionBilling {
constructor(private token: string) {}
async chargeMonthlySubscription(
subscriptionId: string,
userId: string,
planValue: number
) {
// Fetch user data
const user = await this.getUserData(userId);
// Generate charge with 3-day expiration
const charge = await createPixCharge(
this.token,
`SUB-${subscriptionId}-${new Date().getMonth() + 1}`,
planValue,
user.name,
user.document
);
// Send email with payment link
await this.sendPaymentEmail(user.email, charge);
// Schedule reminder 1 day before expiration
await this.scheduleReminder(user, charge, 24);
return charge;
}
async sendPaymentEmail(email: string, charge: CashInResponse) {
// Implement email sending
const paymentLink = `https://app.example.com/payment/${charge.transactionId}`;
await sendEmail({
to: email,
subject: 'Invoice available - Pay with PIX',
html: `
<h2>Your invoice is available</h2>
<p>Amount: R$ ${charge.value}</p>
<p>Due date: ${new Date(charge.expirationDate).toLocaleDateString('pt-BR')}</p>
<p><a href="${paymentLink}">Click here to pay with PIX</a></p>
`
});
}
}付款监控
要在付款确认时收到通知,您可以:
配置 webhooks 以在状态变更时接收自动通知。
// Webhook endpoint on your server
app.post('/webhooks/pix', (req, res) => {
const { transactionId, status, externalId } = req.body;
if (status === 'CONFIRMED') {
// Process confirmed payment
processPaymentConfirmation(externalId);
}
res.sendStatus(200);
});定期查询交易状态。
async function monitorPayment(transactionId, maxAttempts = 200) {
for (let i = 0; i < maxAttempts; i++) {
const status = await checkTransactionStatus(transactionId);
if (status === 'CONFIRMED') {
return true;
}
// Wait 3 seconds before trying again
await new Promise(resolve => setTimeout(resolve, 3000));
}
return false; // Timeout
}响应状态码
| 状态码 | 描述 | 含义 |
|---|---|---|
201 | 收款已创建 | PIX 收款码生成成功 |
400 | 数据无效 | 请检查必填字段和格式 |
401 | 令牌无效 | 未提供令牌、令牌已过期或无效 |
请参阅 API 参考 获取响应字段的完整详情。
最佳实践
重要说明
已过期的收款码无法重新激活。如需要,请生成新的收款码。
- 最小金额: R$ 0.01
- 最短到期时间: 5 分钟(300 秒)
- 最长到期时间: 7 天(604,800 秒)