# Crea pagos con cuotas y planes

Esta guía te muestra cómo procesar pagos con tarjeta de crédito en cuotas con la Getnet Payment App. Puedes dejar que el terminal calcule los intereses (modo Manual) o enviar el monto final calculado desde tu propio sistema (modo Calculado).

## Antes de comenzar

Antes de seguir los pasos, necesitas:

* La Getnet Payment App instalada en el terminal.
* Usar una tarjeta de crédito como medio de pago (`paymentMethod="1"`).
* El comercio debe estar autorizado para planes de cuotas específicos mediante la configuración de su Tax Engine.

<Callout type="note">

los parámetros de cuotas solo aplican a transacciones con tarjeta de crédito. No aplican a pagos con débito, QR Code o voucher.

</Callout>

## Cómo funciona

Cuando se detecta una tarjeta de crédito, el terminal valida el plan solicitado contra las configuraciones autorizadas del comercio mediante un Tax Engine. Entender este proceso de validación te ayuda a anticipar el comportamiento del terminal:

| Paso | Condición | Comportamiento del terminal |
|------|-----------|-------------------|
| **Selección** | Si faltan los parámetros `planId` o `installments` | El terminal muestra una pantalla de selección para que el operador elija el plan manualmente. |
| **Validación del plan** | Si el `planId` enviado coincide con la respuesta del Tax Engine | El terminal omite la pantalla de selección del plan. |
| **Validación de cuotas** | Si el valor de `installments` es compatible con la respuesta del Tax Engine | El terminal omite la pantalla de selección de cuotas y avanza a la confirmación. |
| **Ajuste** | Si el plan solicitado no está autorizado o difiere del Tax Engine | El terminal obliga al usuario a seleccionar manualmente una opción válida y autorizada. |

## Paso 1: Elige el modo de operación

Antes de iniciar la transacción, define el `operationMode`. Este parámetro controla cómo se calculan los valores de la transacción:

| Modo de operación | Valor | Comportamiento |
| :--- | :--- | :--- |
| **Manual** | "0" (predeterminado) | El terminal calcula los valores finales de la transacción según reglas de negocio internas y los datos que el usuario ingresa en tiempo real durante el flujo de pago. |
| **Calculado** | "1" | La aplicación de terceros se encarga de hacer los cálculos y enviar el monto final. El terminal recibe los datos sin modificarlos. |

> Si no se especifica el `operationMode`, el terminal usa el modo manual (`"0"`) de forma predeterminada.

## Paso 2: Crea el pago con cuotas

Para procesar un pago con cuotas, creas un Intent con la operación de pago e incluyes los parámetros específicos de cuotas.

> **Cómo funciona la validación del plan y de las cuotas**
>
> El terminal ejecuta un proceso de validación de dos pasos contra el Tax Engine:
>
> 1. **Validación del plan**: si el `planId` que envías coincide con los planes autorizados del comercio que devuelve el Tax Engine, el terminal omite la pantalla de selección del plan.
>
> 2. **Validación de cuotas**: después de validar el plan, si el valor de `installments` es compatible con la respuesta del Tax Engine para ese plan, el terminal también omite la pantalla de selección de cuotas.
>
> El terminal avanza directo a la pantalla de confirmación solo cuando **ambas** validaciones pasan. Si alguna falla, el terminal le pide al usuario que seleccione manualmente una opción válida y autorizada.

La siguiente tabla lista los parámetros que puedes enviar en el Intent:

| Parámetro | Tipo | Descripción | Obligatorio |
| :--- | :--- | :--- | :--- |
| `amount` | String | Monto de la transacción con dos decimales implícitos (por ejemplo, "10000" = \$100.00). | Sí |
| `originalAmount` | String | Valor en moneda local para realizar la transacción. | Sí |
| `tip` | String | Monto de la propina que se suma al total de la transacción. La representación decimal es la misma que en el parámetro amount (por ejemplo, "500" = \$5.00). | No |
| `waiterCode` | String | Código del mesero para atribuir la propina. Obligatorio si se envía una propina. | Condicional |
| `receiptCode` | String | Código de identificación que se imprime en el comprobante. | Sí |
| `callerId` | String | Identificador único para correlacionar la solicitud con la respuesta. | Sí |
| `paymentMethod` | String | Medio de pago: `"1"` para tarjeta, `"2"` para QR Code. Si no se especifica, se le pide al usuario que elija. | No |
| `installments` | String | Cantidad de cuotas deseada. Solo aplica a transacciones de crédito. | No |
| `planId` | String | ID del plan de cuotas. Consulta los planes disponibles en tu mercado. | No |
| `interest` | String | Indica si el plan de cuotas incluye interés (`"true"`) o es sin interés (`"false"`). | No |
| `operationMode` | String | Define el modo de cálculo: `"0"` para manual (calcula el terminal) o `"1"` para calculado (calcula la app). Consulta la guía Estrategia de cálculo de intereses. | No |
| `skipConfirmation` | String | Define `"true"` para omitir las pantallas de confirmación de los detalles de cuotas; `"false"` (predeterminado) muestra la pantalla normalmente: el usuario debe interactuar para continuar. | No |
| `skipReceipt` | String | Define `"true"` para suprimir la pantalla del comprobante del cliente después de la aprobación. `"false"` (predeterminado) muestra la pantalla normalmente. | No |
| `allowPrintCurrentTransaction` | String | Define `"true"` para que Getnet se encargue de imprimir el comprobante (comportamiento predeterminado), `"false"` para recibir los datos del comprobante sin procesar. Consulta la guía Responsabilidad de impresión. | No |

El siguiente bloque de código muestra un ejemplo de cómo crear un pago con cuotas:

```
private val REQUEST_CODE = 1001

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val intent = Intent(Intent.ACTION_VIEW, Uri.parse("getnet://payment/v1/payment"))
    
    // Mandatory for Payment
    intent.putExtra("amount", "10000") // $100.00
    intent.putExtra("originalAmount", "10000")
    intent.putExtra("callerId", "123456")
    intent.putExtra("receiptCode", "654321")
    
    // Specific for Installments and Plans
    intent.putExtra("installments", 5) 
    intent.putExtra("planId", "plan_emisor")
    intent.putExtra("interest", "false")
    intent.putExtra("operationMode", "1") // Calculated mode
    intent.putExtra("skipConfirmation", "false")
    
    startActivityForResult(intent, REQUEST_CODE)
}
```

## Paso 3: Procesa la respuesta

Después de que el cliente completa la transacción, la Getnet Payment App devuelve a tu aplicación los detalles finales del plan confirmado mediante `onActivityResult`.

**Parámetros de respuesta**

La siguiente tabla lista los parámetros de respuesta que vas a recibir:

| Parámetro | Tipo | Descripción |
| :--- | :--- | :--- |
| result | String | Resultado de la transacción: `"0"` indica éxito. Consulta la referencia de Códigos de resultado para ver todos los códigos. |
| resultDetails | String | Mensaje detallado sobre el resultado de la transacción (por ejemplo, "APPROVED", descripciones de error) |
| amount | String | Monto final de la transacción con dos decimales implícitos |
| tip | String | Monto de la propina agregado a la transacción (si se envió) |
| waiterCode | String | Código del mesero para atribuir la propina (si se envió) |
| receiptCode | String | Código de identificación impreso en el comprobante |
| callerId | String | El identificador único enviado en la solicitud para correlacionarla con la respuesta |
| nsu | String | Código de autorización de la transacción de Getnet: único por terminal (no se puede repetir en un mismo día) |
| authorizationCode | String | Código de autorización entregado por el emisor de la tarjeta |
| paymentType | String | Tipo de pago usado: crédito, débito, voucher, etc. |
| brand | String | Marca de tarjeta (por ejemplo, "VISA", "MASTERCARD") |
| cardBin | String | Primeros 8 dígitos de la tarjeta (BIN) |
| cardLastDigits | String | Últimos 4 dígitos de la tarjeta usada |
| inputType | String | Método de lectura de la tarjeta: `"021"` (banda magnética), `"051"` (chip), `"071"` (chip contactless), `"801"` (banda magnética - fallback) |
| gmtDateTime | String | Fecha y hora GMT de la transacción (formato: MMDDhhmmss, GMT UTC 0) |
| installments | String | Cantidad de cuotas confirmada para la transacción |
| planId | String | Plan de cuotas seleccionado o validado durante la transacción |
| interest | String | Indica si se aplicó interés: `"true"` (con interés) o `"false"` (sin interés) |
| automationSlip | String | Datos del comprobante en formato JSON (se devuelve cuando `allowPrintCurrentTransaction = "false"`). Consulta la guía Responsabilidad de impresión. |

El siguiente bloque de código muestra un ejemplo de cómo procesar la respuesta:

```
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        val extras = data?.extras
        val result = extras?.getString("result")
        
        if (result == "0") {
            // SUCCESS: Extract transaction details
            val installments = extras?.getString("installments")
            val planId = extras?.getString("planId")
            val interest = extras?.getString("interest")
            val nsu = extras?.getString("nsu")
            val authCode = extras?.getString("authorizationCode")
            val amount = extras?.getString("amount")
            
            Log.d("Payment", "Payment approved with $installments installments")
            Log.d("Payment", "Plan: $planId, Interest: $interest")
            Log.d("Payment", "NSU: $nsu, Auth Code: $authCode")
        } else {
            // FAILURE: Handle error
            val errorDetails = extras?.getString("resultDetails")
            Log.e("Payment", "Payment failed: $errorDetails (Code: $result)")
        }
    }
}
```

Ejemplo de una respuesta exitosa:

```json
{
  "result": "0",
  "resultDetails": "APPROVED",
  "amount": "10000",
  "installments": "5",
  "planId": "plan_emisor",
  "interest": "false",
  "callerId": "123456",
  "nsu": "57003",
  "authorizationCode": "004433"
}
```

## Siguientes pasos

* [Reglas de cuotas por país](/es/app2app/reference-a2a/installment-rules) - los IDs de plan y las restricciones de medios de pago por país.
* [Estrategia de cálculo de intereses](/es/app2app/core-concept-a2a/interest-calculation-strategy) - decide si el terminal o tu app calcula los intereses.