Portal de Integração
PaymentForm
"O foco são os estabelecimentos, a prioridade sua rentabilidade, o objetivo a inovação e o pragmatismo."
PaymentForm é o formulário de pagamento hospedado da PROCASH. Seu site nunca vê os dados do cartão: o formulário é servido a partir de um domínio em conformidade com PCI (PCI-compliant). Você só executa duas chamadas server-to-server a partir do seu backend: OrderInitial para criar o pedido e OrderFinal para confirmar o resultado.
Apenas 2 chamadas S2S
OrderInitial para criar o pedido, OrderFinal para confirmar o resultado. Todo o resto é automático.
PCI SAQ-A incluído
Seu servidor nunca vê nem processa dados do cartão. O escopo PCI é mínimo por design.
2 modos de integração
Redirect completo (mais simples) ou iframe embutido com postMessage para uma experiência sem sair do seu site.
Parcelas e QR
Suporte nativo a parcelas (1 a N) com planos financeiros configuráveis por adquirente. Pagamentos por QR dinâmico disponíveis de acordo com a configuração da plataforma.
Contexto argentino
Moeda ARS (032) · Valores em centavos · CUIT/CUIL como identificador tributário · Fuso horário UTC-3 (Buenos Aires).
Como funciona
Diagrama de sequência completo: atores, chamadas e fluxo de dados.
Modos de integração
O PaymentForm suporta três modos de acordo com o nível de controle de UX e integração que você precisa. Os três mantêm o PCI SAQ-A — o estabelecimento nunca captura os dados do cartão.
Modo A — Redirect
O browser do comprador sai do seu site e vai para o formulário hospedado. O modo mais simples e rápido de integrar.
✓ PCI SAQ-A Mais fácilModo B — Embutido (iframe completo)
O formulário completo é exibido em um iframe cross-origin dentro da sua página. Comunicação via postMessage.
✓ PCI SAQ-A Melhor UXModo C — Hosted Fields
Apenas os campos do cartão (PAN + CVV) vão em um iframe da PROCASH. O lojista monta o resto do formulário — controle máximo de design, sem tocar em CHD.
✓ PCI SAQ-A Controle máximo Projetado · em implementaçãoVocê redireciona o comprador usando o CustomerRedirectAddress retornado pelo OrderInitial. O formulário processa o pagamento e retorna o comprador para a sua MerchantRedirectURL.
// 1. Chamar OrderInitial a partir do seu servidor
const response = await fetch('https://api.procash.dev/OrderInitial', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify({
OrderInitial: {
MerchantSystemID: 'SHOP-01', // requerido
MerchantCompanyID: '0', // requerido
TransactionAmount: 1000000, // $10.000,00 ARS (em centavos)
CurrencyCode: '032', // desejável — se omitido, assume ARS
ReferenceNumber: 'ORD-2026-0001',
MerchantRedirectURL: 'https://www.mi-tienda.com.ar/pago/retorno', // opcional
MerchantNotifyURL: 'https://www.mi-tienda.com.ar/webhooks/pago', // recomendado
FacilityNumber: 3, // opcional — parcelas (1 = à vista)
}
})
});
const { OrderInitialResponse: r } = await response.json();
// 2. Verificar se o pedido foi criado corretamente
// ResponseActions é a fonte de verdade — deve conter "OK"
// ResponseCode "-1" é o indicador de sucesso neste contrato
if (!r.ResponseActions?.includes('OK') || r.ResponseCode !== '-1') {
// Pedido rejeitado pela plataforma — não redirecionar
throw new Error(`OrderInitial fallido: [${r.ResponseActions}] ${r.ResponseMessage}`);
}
// 3. Validar presença dos campos obrigatórios na resposta
if (!r.InitialIdentification || !r.CustomerRedirectAddress) {
throw new Error('Respuesta incompleta: faltan InitialIdentification o CustomerRedirectAddress');
}
// 4. ⚠️ Salve InitialIdentification no seu DB ANTES de redirecionar
// É PRIVADO — nunca viaja para o browser
await db.orders.update({ referenceNumber: 'ORD-2026-0001' }, {
initialIdentification: r.InitialIdentification
});
// 5. Redirecionar o comprador para o formulário — apenas o InitialToken (PÚBLICO) viaja na URL
res.redirect(302, r.CustomerRedirectAddress);
Embuta o formulário na sua página com um iframe usando a mesma URL. Escute os eventos postMessage — os dados do cartão nunca viajam fora do iframe.
paymentform:ready · paymentform:resize · paymentform:submitted · paymentform:error
<!-- iframe cross-origin — PCI SAQ-A mantenido -->
<iframe
id="payment-frame"
src="https://payment.procash.dev/?token=INITIAL_TOKEN_AQUI"
style="width:100%;border:none;min-height:420px;"
allow="payment"
></iframe>
<script>
window.addEventListener('message', (e) => {
// Sempre verificar a origem
if (e.origin !== 'https://payment.procash.dev') return;
const { type, result } = e.data;
if (type === 'paymentform:submitted') {
if (result === 'approved') {
// Chamar o seu backend para executar OrderFinal
confirmOrder(result);
} else if (result === 'refused') {
showRefusedMessage();
}
}
if (type === 'paymentform:resize') {
document.getElementById('payment-frame').style.height = e.data.height + 'px';
}
});
</script>
embed-fields.ts) está implementada. A infraestrutura de subdomínio cross-origin e a criptografia WASM→JWE estão pendentes. Consulte a equipe da PROCASH sobre a disponibilidade no sandbox.¿Qué es Hosted Fields?
Em vez de embutir o formulário completo, apenas os campos sensíveis (PAN + CVV) ficam em um iframe cross-origin servido pela PROCASH. Sua página monta o resto do checkout — valor, parcelas, dados do comprador, design — enquanto os dados do cartão nunca tocam seu DOM.
Tiers de hosting disponibles
| Tier | Domínio do iframe | Para quem |
|---|---|---|
| T1 — Compartilhado | {tenant}.payment.procash.dev | Padrão — rápido de integrar (onboarding) |
| T2 — White-label | pay.tudominio.com (CNAME → PROCASH) | Estabelecimentos com branding próprio |
| T3 — Enterprise | Domínio completamente personalizado | Bancos / grandes varejistas (hospedagem regional/on-prem) |
Contrato postMessage (eventos del iframe)
| Evento | Direção | Payload |
|---|---|---|
paymentform:ready | iframe → parent | { mode: 'fields' } — iframe pronto para receber interação |
paymentform:fieldValidity | iframe → parent | { field: 'pan'|'cvv', valid: bool } — para habilitar/desabilitar o botão |
paymentform:resize | iframe → parent | { height: px } — ajustar altura do iframe |
paymentform:submit | parent → iframe | { token } — trigger de envio a partir do seu botão |
paymentform:submitted | iframe → parent | { result: 'approved'|'refused'|'challenge' } |
paymentform:error | iframe → parent | { code, message } |
<!-- Solo el iframe de campos sensibles (cross-origin) -->
<div id="checkout">
<!-- Tu UI: monto, cuotas, nombre del titular -->
<p>Total: <strong>$10.000,00 ARS</strong> en 3 cuotas</p>
<!-- iframe de PROCASH: solo PAN + CVV -->
<iframe
id="fields-frame"
src="https://{tenant}.payment.procash.dev/fields?token=INITIAL_TOKEN"
style="width:100%;border:none;height:120px;"
allow="payment"
sandbox="allow-scripts allow-same-origin"
></iframe>
<!-- Tu propio botón de pago -->
<input type="text" placeholder="Nombre en la tarjeta" id="cardName">
<button id="pay-btn" disabled>Pagar</button>
</div>
<script>
const frame = document.getElementById('fields-frame');
const payBtn = document.getElementById('pay-btn');
let panOk = false, cvvOk = false;
// Escutar eventos do iframe
window.addEventListener('message', (e) => {
if (e.origin !== 'https://{tenant}.payment.procash.dev') return;
const { type, field, valid, height, result } = e.data;
if (type === 'paymentform:resize')
frame.style.height = height + 'px';
if (type === 'paymentform:fieldValidity') {
if (field === 'pan') panOk = valid;
if (field === 'cvv') cvvOk = valid;
payBtn.disabled = !(panOk && cvvOk); // habilitar apenas se ambos estiverem OK
}
if (type === 'paymentform:submitted' && result === 'approved')
confirmOrder(); // llamar tu backend → OrderFinal
});
// Seu botão dispara o envio (submit) no iframe
payBtn.addEventListener('click', () => {
frame.contentWindow.postMessage(
{ type: 'paymentform:submit' },
'https://{tenant}.payment.procash.dev'
);
});
</script>
sandbox do iframe e o allow-same-origin são configurados pela plataforma para que a comunicação postMessage funcione sem expor o DOM sensível.Passo a passo
Siga estes passos para integrar o PaymentForm ao seu backend.
OrderInitial (S2S)
Chamada a partir do seu servidor para criar o pedido de pagamento. Nunca a partir do browser.
Auth: Authorization: Bearer {API_KEY}
{
"OrderInitial": {
"MerchantSystemID": "SHOP-01", // requerido
"MerchantCompanyID": "0", // requerido
"TransactionAmount": 1000000, // $10.000,00 ARS (em centavos)
"CurrencyCode": "032", // desejável — se omitido, assume ARS
"ReferenceNumber": "ORD-2026-0001", // seu ID interno do pedido
"MerchantRedirectURL": "https://www.mi-tienda.com.ar/pago/retorno", // opcional
"MerchantNotifyURL": "https://www.mi-tienda.com.ar/webhooks/pago", // recomendado
"FacilityNumber": 3, // opcional — parcelas (1 = à vista)
"Products": [
{ "Code": "PLAN-PRO", "Name": "Plan Pro Mensual", "Quantity": 1, "UnitAmount": 1000000 }
]
}
}
{
"OrderInitialResponse": {
"ResponseActions": ["OK"], // ← fonte de verdade
"ResponseCode": "-1", // ← informativo (-1 = OK neste contrato)
"ResponseMessage": "Orden creada", // ← informativo
"InitialToken": "11111111-1111-5111-8111-111111111111",
"InitialIdentification": "99999999-9999-5999-8999-999999999999",
"CustomerRedirectAddress": "https://payment.procash.dev/?token=11111111-1111-5111-8111-111111111111",
"MerchantRedirectURL": "https://www.mi-tienda.com.ar/pago/retorno",
"TransactionValidThru": "2026-06-04T23:59:59-03:00", // UTC-3 · Buenos Aires
"Sequence": ""
}
}
InitialIdentification no seu banco de dados associado ao pedido. Ele é PRIVADO — nunca o envie para o browser nem o exponha em URLs.
Redirecionar o comprador
Use o CustomerRedirectAddress (já possui o token embutido). Equivale a https://payment.procash.dev/?token={InitialToken}
const { OrderInitialResponse: r } = await orderInitial(); // ver Passo 1
// ✅ Apenas redirecionar se ResponseActions contiver "OK" e ResponseCode for "-1"
if (r.ResponseActions?.includes('OK') && r.ResponseCode === '-1'
&& r.InitialIdentification && r.CustomerRedirectAddress) {
res.redirect(302, r.CustomerRedirectAddress);
} else {
// Tratar erro — o pedido não foi criado
res.status(400).json({ error: r.ResponseMessage });
}
O formulário processa o pagamento (interno)
O formulário gerencia todo o processamento do pagamento de forma interna — obtém a configuração do pedido, captura os dados do cartão do comprador e processa a transação junto à plataforma. Não requer código da sua parte neste passo.
Retorno ao seu site
O browser retorna para a sua MerchantRedirectURL. O redirect não inclui o resultado do pagamento — o status sempre é obtido com o OrderFinal (ou OrderStatus) a partir do seu servidor.
https://www.mi-tienda.com.ar/pago/retorno
?token=11111111-1111-5111-8111-111111111111
// ← sem status, sem resultado — apenas o token público
// O resultado real é obtido chamando OrderFinal a partir do seu servidor
MerchantNotifyURL) também o confirma de forma assíncrona.
MerchantNotifyURL) e/ou o OrderStatus para conhecer o resultado no seu backend.OrderFinal (S2S)
Confirme o resultado a partir do seu servidor usando o InitialIdentification que você salvou no Passo 1.
{
"OrderFinal": {
"InitialIdentification": "99999999-9999-5999-8999-999999999999"
}
}
{
"OrderFinalResponse": {
"ResponseActions": ["OK", "Approve", "Tickets", "Completed"], // ← fonte de verdade
// OK → operação bem-sucedida
// Approve → pagamento aprovado
// Tickets → existem comprovantes para renderizar
// Completed → circuito completo: OrderInitial→formulário→OrderFinal executado
"ResponseCode": "-1", // ← informativo (-1 = aprovado)
"ResponseMessage": "Aprobado", // ← informativo
"AuthCode": "AUTH123",
"TransactionAmount": 1000000,
"CurrencyCode": "032",
"Tickets": [
{ "Type": "Customer", "Content": "..." },
{ "Type": "Merchant", "Content": "..." }
]
}
}
{
"OrderFinalResponse": {
"ResponseActions": ["OK", "Refuse", "Completed"], // ← fonte de verdade — pago NO acreditado
// OK → operação processada
// Refuse → recusado pelo emissor
// Completed → circuito completo executado (igual que no Approve)
"ResponseCode": "05", // ← informativo, apenas um exemplo — pode ser qualquer código
"ResponseMessage": "Tarjeta rechazada por el emisor", // ← informativo, apenas um exemplo
"TransactionAmount": 1000000,
"CurrencyCode": "032"
}
}
OK → siempre presente junto con Approve o Refuse.
Approve → pago aprobado · confirmar y entregar.
Refuse → rechazado · no cobrado · notificar al comprador.
Completed → circuito completo: el comercio ejecutó OrderFinal y cerró el ciclo de integración.
Tickets → hay comprobantes en Tickets[] para renderizar al comprador.
Não use ResponseCode nem ResponseMessage como critérios de decisão. Lógica correta:
includes('Approve') para aprovado · includes('Refuse') para recusado · includes('Completed') para circuito encerrado.
📡 Webhook — MerchantNotifyURL
O Core chama sua MerchantNotifyURL de forma assíncrona com o resultado do pagamento. Garante que você receberá o resultado mesmo que o browser não retorne ao seu site.
Look & Feel do formulário
O PaymentForm se adapta completamente ao branding do estabelecimento. Os estilos, o modelo de interface, os produtos e o logotipo são configurados por pedido, diretamente no OrderInitial via AdditionalInformation — sem tocar no código do formulário.
AdditionalInformation[].Name = "PaymentForm.Styles" com o JSON de estilos em Base64. O branding do estabelecimento (nome + logo) vai em Name = "PaymentForm.Company". Ambos são enviados no OrderInitial e o formulário os aplica com prioridade sobre a configuração base.Modelos de interfaz
É selecionado com FormMode na configuração. Você pode combinar qualquer modelo com qualquer tema de cor.
Capturas — la misma orden en las cuatro combinaciones
interactive-card · ShowProducts:true
interactive-card · ShowProducts:false
classic · ShowProducts:true
classic · ShowProducts:falseComo configurar os estilos a partir do OrderInitial
Os estilos são enviados em AdditionalInformation como JSON em Base64. O formulário os aplica com prioridade sobre qualquer configuração padrão.
Background, Text e Form. Qualquer propriedade de personalização de campos ou cartões deve ser configurada dentro desses blocos (por exemplo, use Form.input_color em vez de um objeto Input independente). Objetos raiz legados como Card ou Input não são reconhecidos e serão ignorados.// Objeto de estilos (JSON plano antes de codificar)
const stylesArray = [
{ "Background": { "color": "#fcf9fb" } },
{ "Text": { "color": "#130a25" } },
{
"Form": {
"background_color": "#fcf9fb",
"button_color": "#a47fab",
"price_color": "#68ac5c",
"error_color": "#dc2626",
"border_radius": "10px",
"max_width": "520px",
"input_color": "#ffffff",
"input_innertext_color": "#130a25",
"input_border_color": "#f3f3f4",
"form_label": "orden", // "pedido" | "orden" | "operacion" | "transaction"
"show_cft": true,
"show_tea": false,
"show_interest_rate": true,
"show_installment_calculation": false,
"installment_calculation_mode": "simple"
}
}
];
const stylesB64 = btoa(JSON.stringify(stylesArray)); // codificar para Base64
// Branding do estabelecimento
const companyB64 = btoa(JSON.stringify({
"Name": "Tu Comercio",
"LogoUrl": "https://www.mi-tienda.com.ar/logo.png" // URL pública — requer acesso a partir do browser do comprador
// — ou —
// "LogoUrl": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0i..." // Data URI — zero requisições externas (recomendado para PCI)
}));
// Exemplo real de Data URI com um ícone SVG (64×64, fundo #004785)
// Você pode gerar o seu com: btoa(svgString) no browser, ou base64.b64encode(svg.encode()).decode() no Python
const iconoBase64 = "data:image/svg+xml;base64," +
// PNG: ícone + branco sobre fundo #004785 (32×32 px)
"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAc0lEQVR42u3WWw4AERQDULuzMuvmW+J1S+sRN36nJ0Zm1LnjxgdCYnsRo3HGFG1m4PQhYzK9Y9SfiaWxG1yguWszUDC4QO/cECAzxEBE51lg7I0jQM34Z7D/OyAA9//snrhwFHeyolUoepGi2Ym66Yp2nQBekRDCxivTugAAAABJRU5ErkJggg==";
{
"OrderInitial": {
"MerchantSystemID": "SHOP-01",
"MerchantCompanyID": "0",
"TransactionAmount": 1000000,
"CurrencyCode": "032",
"ReferenceNumber": "ORD-2026-0001",
"Products": [
{
"Code": "PLAN-PRO",
"Name": "Plan Pro Mensual",
"Quantity": 1,
"UnitAmount": 1000000,
"ImageUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAc0lEQVR42u3WWw4AERQDULuzMuvmW+J1S+sRN36nJ0Zm1LnjxgdCYnsRo3HGFG1m4PQhYzK9Y9SfiaWxG1yguWszUDC4QO/cECAzxEBE51lg7I0jQM34Z7D/OyAA9//snrhwFHeyolUoepGi2Ym66Yp2nQBekRDCxivTugAAAABJRU5ErkJggg=="
// ↑ PNG real 32×32 px — ícone + branco sobre fundo #004785 — 172 bytes / 232 chars base64
}
],
"AdditionalInformation": [
{
"Name": "PaymentForm.Styles",
"Value": "<stylesB64>" // resultado de btoa(JSON.stringify(stylesArray))
},
{
"Name": "PaymentForm.Company",
"Value": "<companyB64>" // resultado de btoa(JSON.stringify(companyObj))
}
]
}
}
Tokens de estilo disponíveis
| Token | Objeto | Descrição | Exemplo |
|---|---|---|---|
color | Background | Cor de fundo da página | #fcf9fb · #0f172a |
color | Text | Cor dos textos principais del card | #130a25 · #ffffff |
background_color | Form | Cor de fundo do card do formulário | #fcf9fb · #ffffff |
button_color | Form | Cor do botão "Pagar" | #a47fab · #004785 |
price_color | Form | Cor do valor total | #68ac5c · #22c55e |
error_color | Form | Cor das mensagens de erro de validação | #dc2626 · #fb7185 |
input_color | Form | Cor de fundo dos campos de texto | #ffffff · #f8fafc |
input_innertext_color | Form | Cor do texto digitado nos campos | #130a25 · #0f172a |
input_border_color | Form | Cor da borda dos campos de texto | #f3f3f4 · #e2e8f0 |
border_radius | Form | Arredondamento do card do formulário | 10px · 0 |
max_width | Form | Largura máxima do formulário | 520px |
form_label | Form | Título do formulário | orden · pedido · operacion · transaction |
show_cft | Form | Habilita/Desabilita a exibição do Custo Financiero Total (CFT) no seletor de parcelas | true · false |
show_tea | Form | Habilita/Desabilita a exibição da Taxa Efetiva Anual (TEA) no seletor de parcelas | true · false |
show_interest_rate | Form | Habilita/Desabilita a exibição da Taxa Nominal Anual (TNA) no seletor de parcelas | true · false |
show_installment_calculation | Form | Se for true, calcula o valor de cada parcela aplicando os juros do plano em vez de uma divisão direta simples | true · false |
installment_calculation_mode | Form | Fórmula para calcular a parcela com juros: simple (direto), french_tna (Francés TNA), french_tea (Francés TEA), cft (Francés CFT) | simple · french_tna · french_tea · cft |
header_align | Form | Alinhamento horizontal do cabeçalho do pedido | left · center · right |
header_font | Form | Família tipográfica do cabeçalho do pedido | Outfit, sans-serif |
header_size | Form | Tamanho da fonte do cabeçalho do pedido | 14px · 0.875rem |
header_color | Form | Cor do texto do cabeçalho do pedido | #475569 |
button_align | Form | Alinhamento e estiramento do botão de pagamento | flex-start · center · flex-end · stretch |
button_width | Form | Largura explícita do botão de pagamento | 200px · 100% |
button_padding | Form | Espaçamento interno (padding) do botão de pagamento | 12px 24px |
button_font_size | Form | Tamanho da fonte do botão de pagamento | 16px |
button_icon_url | Form | URL do ícone personalizado para substituir o cadeado padrão | https://example.com/shield.png |
amount_font | Form | Família tipográfica do valor do pagamento | Inter, sans-serif |
amount_font_size | Form | Tamanho da fonte do valor do pagamento | 24px · 1.5rem |
amount_color | Form | Cor do texto do valor do pagamento | #16a34a |
PaymentForm.Styles) dentro do bloco "Form" (ex: Styles[].Form.form_mode). Se não forem enviadas, a plataforma aplicará os valores pré-configurados para a sua conta ou os valores padrão do formulário.Configuração do formulário
| Campo | Tipo | Default | Descrição |
|---|---|---|---|
FormMode | string | classic | classic — formulario tradicional · interactive-card — tarjeta 3D interactiva (premium) |
ShowProducts | boolean | true | Mostra ou oculta o detalhe dos produtos. Se false, o formulário fica mais compacto. |
AllowInstallments | boolean | true | Habilita o seletor de parcelas. Os planos disponíveis são determinados pelo BIN do cartão. |
AllowAmountEdit | boolean | false | Permite que o comprador modifique o valor antes de pagar. |
ProductLayout | string | list | list — vertical · grid — grade de 2 colunas · compact — sem imagens, ideal para carrinhos grandes |
Locale | string | es-AR | Idioma e formato. es-AR · en-US · pt-BR. Altera rótulos, formatos de data e moeda. |
ImageUrl em Products[] aceita URL pública ou Data URI base64. Quando base64 é usado, a imagem não gera requisições de rede externas — conformidade estrita com o PCI. As imagens também podem vir no Products[] retornado pelo Core.ImageUrl:data:<mime>;base64,<dados> — RFC 2397. O cabeçalho iVBORw0KGgo sempre identifica um PNG (bytes mágicos \x89PNG). Suporta image/png, image/jpeg, image/webp, image/svg+xml.reader.onload = e =>
reader.readAsDataURL(imageFile);
with
b64 = base64.b64encode(f.read()).decode()
uri = f"data:image/png;base64,{b64}"
const b64 = fs.readFileSync('logo.png')
.toString('base64');
const uri = `data:image/png;base64,${b64}`;
Dados de teste
Use estes cartões e cenários no ambiente sandbox da PROCASH.
Cartões de teste
| Número do cartão | Bandeira | CVV | Vencimento | Resultado |
|---|---|---|---|---|
4111 1111 1111 1111 |
Visa | 123 |
12/28 |
✅ Aprovada |
4000 0000 0000 0002 |
Visa | 123 |
12/28 |
❌ Recusada |
5555 5555 5555 4444 |
Mastercard | 123 |
12/28 |
✅ Aprovada |
5105 1051 0510 5100 |
Mastercard | 123 |
12/28 |
❌ Recusada |
ResponseActions — valores possíveis
ResponseActions é um array — sempre pode conter múltiplos valores ao mesmo tempo. OK e Completed sempre acompanham Approve ou Refuse quando o circuito está completo.
| ResponseActions (array) | ResponseCode | Significado |
|---|---|---|
["OK", "Approve", "Completed"] |
-1 |
✅ Pagamento aprovado · circuito fechado |
["OK", "Approve", "Tickets", "Completed"] |
-1 |
✅ Aprovado + comprovantes disponíveis |
["OK", "Refuse", "Completed"] |
05 (ej.) |
❌ Recusado — o código é informativo e pode variar |
⚠️ Os valores de ResponseCode são apenas exemplos. Existe uma grande variedade de códigos possíveis de acordo com o emissor e a plataforma. A fonte de verdade é sempre a action Refuse ou Error em ResponseActions — esse é o indicador real de que o pagamento não foi aprovado, independentemente do código.
|
||
actions.includes('Approve') → aprovado, creditar.actions.includes('Refuse') → recusado, não cobrado.actions.includes('Completed') → o estabelecimento executou o OrderFinal e fechou o ciclo.actions.includes('Tickets') → renderizar Tickets[] para o comprador.Pagamento NÃO aprovado:
includes('Refuse') ou includes('Error') são os únicos indicadores reais de recusa. ResponseCode e ResponseMessage são informativos e podem variar — nunca os use como critérios de decisão.
Cenários de teste
Cenários configuráveis no sandbox — consulte a equipe da PROCASH para ativá-los.
Métodos de pago en sandbox
| Método | Disponível no sandbox | Notas |
|---|---|---|
| 💳 Cartão de crédito (parcelas) | ✅ Sí | Visa, Mastercard, Amex · hasta 12 cuotas según plan del BIN |
| 💳 Cartão de débito | ✅ Sí | Apenas 1 parcela · PIN não requerido no canal CNP |
| 📱 QR dinâmico | ⚡ De acordo com config. | Requer habilitação na plataforma · consulte a equipe da PROCASH |
| 🏦 Transferência / CVU | ⚡ De acordo com config. | Disponível se o plano incluir · o formulário mostra o CVU de destino |
Endpoints Sandbox
Referência rápida
Campos principais da requisição OrderInitial.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
MerchantSystemID |
string | ✅ Sí | Identificador do sistema merchant (lojista) |
MerchantCompanyID |
string | ✅ Sí | ID da empresa |
MerchantBranch |
string | Não se aplica | Não é utilizado na integração web CNP. A plataforma o resolve por meio da configuração do estabelecimento. |
MerchantPOSID |
string | Não se aplica | Não é utilizado na integração web CNP. A plataforma o resolve por meio da configuração do estabelecimento. |
TransactionAmount |
integer | ✅ Sí | Valor em centavos (ex: 1000000 = $10.000,00 ARS) |
CurrencyCode |
string | ⚡ Desejável | ISO 4217 — 032 = ARS (Pesos argentinos). Se omitido, a plataforma assume a moeda do país do estabelecimento. Recomenda-se enviá-lo sempre. |
ReferenceNumber |
string | ✅ Sí | Seu ID interno do pedido (para reconciliação) |
MerchantRedirectURL |
string | Opcional | URL para a qual o comprador retorna após o pagamento. Se omitida, não há redirect: o formulário exibe diretamente o resultado final (aprovado / recusado) sem sair da página do formulário. |
MerchantNotifyURL |
string | ⚡ Recom. | Webhook — o Core notifica o resultado de forma assíncrona |
Products |
array | Opcional | Detalhe dos produtos para exibir no formulário |
FacilityNumber |
integer | Opcional | Quantidade de parcelas (1 = à vista, 3/6/12… = parcelas). Requer plano financeiro habilitado para o BIN. |
TaxIdentification |
string | Opcional | Identificador tributário do comprador — CUIT/CUIL para a Argentina (ex: 20-12345678-9) |
Valores em ARS — formato
O campo TransactionAmount vai em centavos (sem vírgula decimal). Use o ponto como separador de milhares e a vírgula para decimais ao exibi-lo ao usuário.
| Valor para o usuário | TransactionAmount | Nota |
|---|---|---|
| $1.000,00 ARS | 100000 | Mil pesos |
| $5.000,00 ARS | 500000 | Cinco mil pesos |
| $10.000,00 ARS | 1000000 | Dez mil pesos |
| $50.000,00 ARS | 5000000 | Cinquenta mil pesos |
| $100.000,00 ARS | 10000000 | Cem mil pesos |
💡 Para converter: TransactionAmount = Math.round(valorPesos * 100)
Flujo resumido
Obtenha token + ID
Comprador insere o cartão
+ webhook assíncrono
Confirme o resultado real
Seller · Payer · Customer · Shipping
O OrderInitial aceita quatro objetos opcionais que enriquecem a transação com dados das partes envolvidas. Todos são opcionais — incluí-los permite maior rastreabilidade, análise antifraude e conformidade regulatória.
Payer não estiver presente, a plataforma usará os dados de Customer como pagador. Na maioria dos casos de e-commerce, eles são a mesma pessoa — basta enviar Customer.
Dados do comprador/cliente. É o objeto mais comum no e-commerce. Se o Payer não for enviado, estes dados serão usados também como pagador.
| Campo | Tipo | Descrição |
|---|---|---|
FirstName | string | Primeiro nome |
LastName | string | Sobrenome |
MiddleName | string | Nome(s) do meio |
Email | string | E-mail do cliente |
Phone | string | Número de telefone |
DocumentType | enum | CI · PAS · ACCOUNT_NUMBER · CONTRACT · OTHER |
DocumentNumber | string | Número do documento |
TaxIdentificationType | string | Tipo de identificador tributário — na Argentina: CUIT ou CUIL |
TaxIdentification | string | Número do CUIT/CUIL ou outro identificador tributário |
AddressStreet | string | Rua |
AddressNumber | string | Número |
AddressInternal | string | Andar, apto, unidade |
AddressSuburb | string | Bairro |
City | string | Cidade |
State | string | Estado |
Country | string | País |
ZipCode | string | Código postal |
NotifyURL | string | URL de notificação específica para o cliente |
{
"OrderInitial": {
"MerchantSystemID": "SHOP-01",
"MerchantCompanyID": "0",
"TransactionAmount": 1000000,
"CurrencyCode": "032",
"ReferenceNumber": "ORD-2026-0001",
"Customer": {
"FirstName": "María",
"LastName": "González",
"Email": "maria.gonzalez@email.com",
"Phone": "1123456789",
"DocumentType": "CI",
"DocumentNumber": "12345678",
"TaxIdentificationType": "CUIL",
"TaxIdentification": "27-12345678-3",
"AddressStreet": "Av. Corrientes",
"AddressNumber": "1234",
"AddressInternal": "Piso 3 Dpto B",
"City": "Buenos Aires",
"State": "CABA",
"Country": "AR",
"ZipCode": "C1043"
}
}
}
Dados do pagador — a pessoa que efetua o pagamento com o seu cartão. Mesmo schema de Customer. Necessário apenas quando o pagador é diferente do comprador (ex: alguém que paga em nome de outra pessoa).
| Campo | Tipo | Descrição |
|---|---|---|
FirstName | string | Primeiro nome del pagador |
LastName | string | Sobrenome del pagador |
Email | string | E-mail do pagador |
Phone | string | Telefone do pagador |
DocumentType | enum | CI · PAS · ACCOUNT_NUMBER · CONTRACT · OTHER |
DocumentNumber | string | Número do documento del pagador |
TaxIdentificationType | string | Tipo de identificador tributário — na Argentina: CUIT ou CUIL |
TaxIdentification | string | Número do CUIT/CUIL do pagador |
AddressStreet · AddressNumber · City · State · Country · ZipCode | string | Endereço completo do pagador |
NotifyURL | string | URL de notificação específica para o pagador |
Customer e omita Payer. A plataforma usará Customer como pagador automaticamente.Dados do vendedor. Útil em modelos de marketplace ou quando o estabelecimento precisa identificar o vendedor específico dentro da plataforma.
| Campo | Tipo | Descrição |
|---|---|---|
FirstName | string | Nome do vendedor |
LastName | string | Sobrenome del vendedor |
Email | string | E-mail do vendedor |
DocumentType | enum | CI · PAS · ACCOUNT_NUMBER · CONTRACT · OTHER |
DocumentNumber | string | Número do documento del vendedor |
TaxIdentificationType | string | Tipo de identificador tributário — na Argentina: CUIT |
TaxIdentification | string | CUIT do vendedor |
Identification | string | Identificador interno do vendedor na plataforma |
IdentificationType | enum | Tipo de identificador: CI · PAS · ACCOUNT_NUMBER · CONTRACT · OTHER |
AddressStreet · AddressNumber · City · State · Country | string | Endereço do vendedor |
{
"OrderInitial": {
// ... campos base ...
"Seller": {
"Identification": "SELLER-0042",
"IdentificationType": "CONTRACT",
"FirstName": "Distribuidora",
"LastName": "Sur S.A.",
"TaxIdentificationType": "CUIT",
"TaxIdentification": "30-71234567-8",
"Email": "ventas@distribuidorasur.com.ar"
}
}
}
Endereço de entrega do pedido. Independente do endereço de cobrança do comprador. Necessário quando o envio físico faz parte do fluxo.
| Campo | Tipo | Max | Descrição |
|---|---|---|---|
FirstName | string | 100 | Nome do destinatário |
LastName | string | 100 | Sobrenome del destinatario |
Address1 | string | 255 | Endereço principal (rua e número) |
Address2 | string | 255 | Complemento (piso, dpto, unidad) |
City | string | 100 | Cidade de entrega |
StateProvince | string | 100 | Estado |
Country | string | 50 | País (ej: AR) |
ZipCode | string | 20 | Código postal |
PhoneNumber | string | 50 | Telefone de contato para a entrega |
Email | string | 255 | E-mail de contato para notificações de envio |
{
"OrderInitial": {
// ... campos base + Customer ...
"Shipping": {
"FirstName": "María",
"LastName": "González",
"Address1": "Av. Corrientes 1234",
"Address2": "Piso 3 Dpto B",
"City": "Buenos Aires",
"StateProvince": "CABA",
"Country": "AR",
"ZipCode": "C1043",
"PhoneNumber": "1123456789",
"Email": "maria.gonzalez@email.com"
}
}
}
Ejemplo completo — todos los objetos
{
"OrderInitial": {
"MerchantSystemID": "SHOP-01",
"MerchantCompanyID": "0",
"TransactionAmount": 1000000, // $10.000,00 ARS
"CurrencyCode": "032",
"ReferenceNumber": "ORD-2026-0001",
"FacilityNumber": 3, // 3 parcelas
"MerchantRedirectURL": "https://www.mi-tienda.com.ar/pago/retorno",
"MerchantNotifyURL": "https://www.mi-tienda.com.ar/webhooks/pago",
"Products": [
{ "Code": "PROD-001", "Name": "Zapatillas Running", "Quantity": 1, "UnitAmount": 1000000 }
],
"Customer": { // comprador = pagador (caso mais comum)
"FirstName": "María",
"LastName": "González",
"Email": "maria.gonzalez@email.com",
"Phone": "1123456789",
"DocumentType": "CI",
"DocumentNumber": "12345678",
"TaxIdentificationType": "CUIL",
"TaxIdentification": "27-12345678-3"
},
"Shipping": { // endereço de entrega (pode ser diferente do de Customer)
"FirstName": "María",
"LastName": "González",
"Address1": "Av. Corrientes 1234",
"Address2": "Piso 3 Dpto B",
"City": "Buenos Aires",
"StateProvince": "CABA",
"Country": "AR",
"ZipCode": "C1043",
"PhoneNumber": "1123456789",
"Email": "maria.gonzalez@email.com"
}
// Seller apenas se for marketplace — Payer apenas se for diferente de Customer
}
}