Conceptos
Sobre de respuesta
Qué devuelve el gateway: el sobre de transacción de las escrituras (status, transaction_id, module, data, idempotent_replay), el cuerpo del motor en las lecturas y cómo lo exponen los modelos de cada SDK.
En esta página
El gateway responde de dos formas, según el tipo de operación.
Escrituras: el sobre de transacción #
Toda operación que cambia algo (las que llevan Idempotency-Key) responde con el mismo sobre,
sea del módulo que sea:
{
"status": "success",
"transaction_id": "a1b2c3d4-0000-4a1b-9c2d-000000000001",
"module": "wallet",
"data": {
"transaction_id": "9a8b…",
"status": "COMPLETED",
"amount": "30000.00",
"currency": "COP"
},
"idempotent_replay": true
}| Campo | Qué es |
|---|---|
status | Resultado del gateway (success). Los fallos no llegan aquí: son errores HTTP problem+json. |
transaction_id | Id de la transacción en el gateway. Guárdalo: sirve para consultar su estado, conciliar y abrir casos con soporte. |
module | Módulo que la procesó (credits, subsidies, wallet, loans, pqrs, health, admin, webhooks…). |
data | El cuerpo del motor, tal cual: ids del dominio (application_id, payment_id…), estados y montos. |
idempotent_replay | Solo aparece (en true) cuando la respuesta es la repetición guardada de una Idempotency-Key ya usada. |
Consejo
No confundas transaction_id (del gateway, en el sobre) con los ids del dominio que vienen dentro
de data (data.application_id, el data.transaction_id de la billetera, el data.id de un
endpoint de webhook…). Para decidir o desembolsar un crédito usas el application_id, no el
transaction_id del sobre.
Lecturas: el cuerpo del motor #
Los GET (y los POST que solo consultan: resolver un destinatario, consultar una factura,
cotizar FX, calcular impuestos) devuelven directamente el objeto o la lista del motor, sin sobre.
Las listas vienen paginadas (Paginación).
Cómo lo exponen los SDK #
Cada SDK convierte el sobre en un Transaction y, donde aporta, convierte las lecturas en modelos
tipados (Balance, Resolution, AffiliateLookup, WebhookEndpoint, TestClock, Page…). Todo
modelo conserva el cuerpo original en raw (Raw en .NET y Go) para los campos que el SDK no tipa.
| Python | JavaScript / TS | PHP | .NET | Go | |
|---|---|---|---|---|---|
| Sobre | Transaction | Transaction | Compense\Sdk\Model\Transaction | Compense.Sdk.Models.Transaction | *compense.Transaction |
| Id del gateway | tx.transaction_id | tx.transactionId | $tx->transactionId | tx.TransactionId | tx.TransactionID |
| Repetición | tx.idempotent_replay | tx.idempotentReplay | $tx->idempotentReplay | tx.IdempotentReplay | tx.IdempotentReplay |
| Cuerpo del motor | tx.data (dict) | tx.data (JsonObject) | $tx->data (array) | tx.Data (JsonObject) | tx.Data (map[string]any) |
| Lecturas sin modelo | dict | JsonObject | array | JsonObject | map[string]any |
tx = client.credits.submit_application(
affiliate={"document_type": "CC", "document_number": "1000000001"},
product_code="LIBRANZA_12M", amount="3500000", term_months=12,
external_reference="HORIZONTE-CRED-2026-000123",
)
app_id = tx.data["application_id"] # id del dominio, para decidir y desembolsar
save(tx.transaction_id, app_id) # guarda ambosconst tx = await client.credits.submitApplication({
affiliate: { document_type: "CC", document_number: "1000000001" },
productCode: "LIBRANZA_12M", amount: "3500000", termMonths: 12,
externalReference: "HORIZONTE-CRED-2026-000123",
});
const appId = String(tx.data.application_id);
await save(tx.transactionId, appId);use Compense\Sdk\Model\AffiliateRef;
$tx = $client->credits->submitApplication(
affiliate: new AffiliateRef('CC', '1000000001'),
productCode: 'LIBRANZA_12M', amount: '3500000', termMonths: 12,
externalReference: 'HORIZONTE-CRED-2026-000123',
);
$appId = $tx->data['application_id'];
save($tx->transactionId, $appId);Transaction tx = await client.Credits.SubmitApplicationAsync(
new AffiliateRef("CC", "1000000001"), "LIBRANZA_12M", "3500000", 12, "HORIZONTE-CRED-2026-000123");
string appId = (string)tx.Data["application_id"]!;
await SaveAsync(tx.TransactionId, appId);tx, err := client.Credits.SubmitApplication(ctx, &compense.CreditApplicationParams{
Affiliate: compense.AffiliateRef{DocumentType: "CC", DocumentNumber: "1000000001"},
ProductCode: "LIBRANZA_12M",
Amount: "3500000",
TermMonths: 12,
ExternalReference: "HORIZONTE-CRED-2026-000123",
})
if err != nil {
log.Fatal(err)
}
appID := fmt.Sprint(tx.Data["application_id"])
save(tx.TransactionID, appID)curl -s -X POST https://sandbox.dev.compense.co/gw/v1/gateway/credits/application/ \
-H "X-API-Key: $COMPENSE_API_KEY" -H "Idempotency-Key: horizonte-cred-2026-000123" \
-H "Content-Type: application/json" \
-d '{"afiliado":{"document_type":"CC","document_number":"1000000001"},"product_code":"LIBRANZA_12M","amount":"3500000","term_months":12,"external_reference":"HORIZONTE-CRED-2026-000123"}' \
| jq '{tx: .transaction_id, app: .data.application_id}'Cabeceras útiles de la respuesta #
| Cabecera | Para qué |
|---|---|
X-Request-ID | Id de la petición; coincide con el trace_id de los errores. Regístralo. |
RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset | Estado de tu límite (Límites de tasa). |
Retry-After | En 429 (y algunos 5xx): segundos a esperar. Los SDK lo respetan. |
Deprecation, Sunset, Link | La operación está deprecada (Deprecaciones). |