Inicio / Desarrolladores
Documentación de integración para comercios

API de cobro y pago: intégrela en pocos pasos

Interfaz unificada HTTP + JSON, firma y verificación SHA-256, notificaciones asíncronas y consulta activa de pedidos. Este documento cubre las reglas de firma, todos los campos de la interfaz y ejemplos de solicitud.

Descripción general

India Payme ofrece a los comercios dos capacidades transaccionales principales: Cobro (Payin): cobra en nombre del comercio a los usuarios finales; Pago (Payout): paga en nombre del comercio a una cuenta especificada. Todas las interfaces externas son POST + JSON y deben incluir una firma de API. Una vez procesada la operación, la plataforma notifica al comercio mediante una notificación asíncrona, y también admite la consulta activa de pedidos.

FunciónMétodoRuta
Crear pedido de cobroPOST/transaction/payin/v1/apply
Consultar pedido de cobroPOST/transaction/payin/v1/query
Crear pedido de pagoPOST/transaction/payout/v1/apply
Consultar pedido de pagoPOST/transaction/payout/v1/query
Consulta de saldoPOST/transaction/payout/v1/balance

URL base (el dominio de la pasarela de producción se proporcionará a través de la plataforma tras la apertura de la cuenta):

https://{dominio-de-la-pasarela}

Preparación para la integración

Inicie sesión en el panel del comercio → Claves de la aplicación. Cada aplicación cuenta con un par de credenciales: appKey y appSecret. El appKey corresponde al encabezado de solicitud appId; el appSecret es la clave de firma, que se utiliza únicamente para calcular la firma de forma local y no se transmite.

Todas las solicitudes deben incluir los siguientes encabezados HTTP, con Content-Type igual a application/json:

HeaderObligatorioDescripción
appIdID de la aplicación del comercio (es decir, appKey)
timestampMarca de tiempo Unix en milisegundos
nonceCadena aleatoria, ≥10 caracteres, de un solo uso, no reutilizable
signFirma calculada según las reglas de la siguiente sección

Reglas de firma

El algoritmo de firma es SHA-256 puro (hexadecimal en minúsculas), no HMAC. El appSecret se concatena directamente al final de la cadena a firmar antes de aplicar SHA-256. Pasos:

  1. Tome los "campos de nivel superior del cuerpo de la solicitud (solo los no vacíos)" + los "encabezados de firma appId, timestamp, nonce" y combínelos en un Map (el propio sign no participa);
  2. Ordénelos por nombre de parámetro en orden ascendente ASCII y concaténelos como key1=value1&key2=value2…;
  3. Concatene el appSecret al final (sin separador) y aplique SHA-256 a toda la cadena; el resultado hexadecimal en minúsculas es el sign.
# Cadena a firmar signString = "key1=value1&key2=value2…&keyN=valueN" + appSecret sign = SHA256_HEX(signString) // Hexadecimal en minúsculas

Vigencia y prevención de reenvíos:

  • Vigencia de la marca de tiempo: 30 segundos: |hora del servidor − timestamp| ≤ 30s; si se supera, se devuelve timestamp has expired. Asegúrese de que el cliente y la pasarela tengan el reloj sincronizado (NTP).
  • Prevención de reenvíos con nonce: el mismo nonce solo puede usarse una vez; si se repite, se devuelve nonce has been used (código de error 900).
  • Los campos con valor vacío no participan en la firma: el "conjunto de campos incluidos en la firma" debe coincidir exactamente con los "campos JSON realmente enviados".

Ejemplo de firma en Node.js:

const crypto = require('crypto'); function buildSign(appId, appSecret, timestamp, nonce, body) { const params = { ...body, appId, timestamp, nonce }; const signString = Object.keys(params) .filter(k => params[k] !== null && params[k] !== undefined) .sort() .map(k => `${k}=${params[k]}`) .join('&') + appSecret; return crypto.createHash('sha256').update(signString, 'utf8').digest('hex'); }

Crear pedido de cobro POST

POST /transaction/payin/v1/apply — crea un pedido de cobro y devuelve el enlace de pago de la caja payUrl, que se utiliza para dirigir al usuario a completar el pago.

CampoTipoObligatorioDescripción
merchantOrderNostringNúmero de pedido del comercio, no puede repetirse
amountnumberMonto del pedido, decimal (p. ej., 100.02)
namestringNombre del usuario. Solo en inglés, ≥3 letras, puede contener espacios, sin símbolos ni números
phonestringNúmero de teléfono móvil
emailstringCorreo electrónico
currencystringMoneda: INR / PKR / USDT / BDT
productstringCódigo de producto de pago, proporcionado por la plataforma según el acuerdo firmado
notifyUrlstringNoDirección de notificación asíncrona; si no se envía, se utiliza la dirección de notificación predeterminada del comercio
returnUrlstringNoPágina de redirección tras el pago exitoso
payTypestringNoMétodo de pago directo por billetera: JAZZCASH / EASYPAISA / BKASH / NAGAD
POST /transaction/payin/v1/apply { "merchantOrderNo": "ORD1751731200123", "amount": "600.00", "currency": "INR", "product": "{código-de-producto}", "name": "John Doe", "phone": "9910099100", "email": "john@example.com", "notifyUrl": "https://shop.example/pay/notify" }
// Respuesta { "code": 0, "msg": "Success", "data": { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "currency": "INR", "payUrl": "https://{dominio-de-la-caja}/cashier/xxxx", "payStatus": 0 } }

Una vez obtenido el payUrl, dirija al usuario a la página de pago; el resultado final se determina mediante la notificación asíncrona.

Crear pedido de pago POST

POST /transaction/payout/v1/apply — inicia un pago a una cuenta especificada. Procesamiento asíncrono: la interfaz primero valida y congela la cuenta, y luego procesa el desembolso de forma asíncrona a través del canal correspondiente; la respuesta suele ser payStatus=0 (aceptado correctamente), y el resultado final se determina mediante la consulta del pedido o la notificación.

CampoTipoObligatorioDescripción
merchantOrderNostringNúmero de pedido del comercio
amountnumberMonto del pago, mínimo 100.00
accountNamestringNombre del beneficiario. Solo en inglés, ≥3 letras, puede contener espacios
accountstringNúmero de cuenta del beneficiario
phonestringNúmero de teléfono móvil
emailstringCorreo electrónico
currencystringMoneda: INR / PKR / USDT / BDT
bizCodestringTipo de operación de desembolso: IMPS / UPI / BANK / JAZZCASH / EASYPAISA / BKASH / NAGAD / ECARD
payCodestringMétodo de pago: CARD / WALLET / NBK / ITT / VC
branchCodestringCódigo de compensación: para India, IFSC; para Pakistán, bankcode; para Bangladés, según bizCode
productstringCódigo de producto de pago, proporcionado por la plataforma
bankNamestringNoNombre del banco
swiftCodestringNoCódigo SWIFT (se utiliza en transferencias internacionales ITT)
POST /transaction/payout/v1/apply { "merchantOrderNo": "PO1751731200123", "amount": "1500.00", "currency": "INR", "product": "{código-de-producto}", "accountName": "John Doe", "account": "1234567890", "bizCode": "IMPS", "payCode": "NBK", "branchCode": "HDFC0000001", "bankName": "HDFC", "phone": "9910099100", "email": "john@example.com" }

Consulta de pedidos POST

Cobro: POST /transaction/payin/v1/query; pago: POST /transaction/payout/v1/query. Envíe merchantOrderNo u orderNo para localizar el pedido. Límite de frecuencia: 5 solicitudes por segundo.

POST /transaction/payin/v1/query { "merchantOrderNo": "ORD1751731200123" }
// Datos de respuesta { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "realAmount": 600, "currency": "INR", "payStatus": 1 // 0 en proceso / 1 cobrado / -1 cancelado }

Consulta de saldo POST

POST /transaction/payout/v1/balance — consulta el saldo de la cuenta del comercio. Límite de frecuencia: 5 solicitudes por segundo.

POST /transaction/payout/v1/balance { "currency": "INR" }
// Datos de respuesta { "accountNo": "ACC0001", "currency": "INR", "balance": 100000.00, // Saldo total "balanceActive": 98500.00, // Saldo disponible "balanceFreeze": 1500.00 // Saldo congelado }

Notificación asíncrona

Cuando un pedido alcanza su estado final, la plataforma notifica al notifyUrl del comercio mediante POST (JSON) (si no se proporcionó, se usa la dirección predeterminada del comercio), y envía los mismos encabezados de firma junto con la notificación (appId/timestamp/nonce/sign). El comercio debe recalcular la firma con su propio appSecret siguiendo las mismas reglas y compararla para verificar la autenticidad de la notificación.

El mensaje de notificación de cobro incluye: merchantOrderNo, orderNo, currency, product, amount, realAmount, status ("1" indica cobro exitoso). La notificación de pago incluye además utr (número de referencia bancaria) y statusDes (descripción del estado); status es "1" para éxito y "2" para fallo.

// Ejemplo del cuerpo de la notificación de cobro { "merchantOrderNo": "ORD1751731200123", "orderNo": "P1751731200999", "currency": "INR", "product": "{código-de-producto}", "amount": "600.00", "realAmount": "600.00", "status": "1" }

El comercio debe responder con el texto plano OK o success (sin distinguir mayúsculas/minúsculas). De lo contrario, la plataforma entrará en una cola de reintentos: máximo 5 veces, con intervalos crecientes en minutos (1 / 2 / 5 / 10 / 30 / 60 / 120). Por ello, la interfaz del comercio debe garantizar la idempotencia (el mismo orderNo puede notificarse varias veces).

Estado del pedido

El comercio debe basarse en los siguientes estados públicos (la máquina de estados interna es más detallada y no se expone directamente):

EscenarioCampoValores
Respuesta de creación del pedidopayStatus0 creado / 1 exitoso / 2 fallido / 3 cancelado
Consulta de pedido de cobropayStatus0 en proceso / 1 cobrado / -1 cancelado
Consulta de pedido de pagopayStatus0 pendiente de pago / 1 pagado / -1 cancelado
Notificación asíncronastatusCobro exitoso "1"; pago "1" exitoso / "2" fallido

Códigos de error

Si el cuerpo de la respuesta tiene code != 0, la solicitud ha fallado; msg contiene el mensaje. Códigos de error de negocio comunes:

codeDescripción
0Éxito
400Error de parámetros / fallo en la verificación de firma (Sign invalid)
900Solicitud duplicada / reenvío de nonce
10000 / 10001La aplicación no existe / la aplicación no está disponible
10002Moneda no compatible
10003 / 10007Comercio no disponible / cuenta del comercio no disponible
10004Producto no habilitado o acuerdo vencido
10005 / 10009No hay canal disponible por el momento / canal no disponible temporalmente
10008Saldo de cuenta insuficiente
10010La IP no está en la lista blanca
10011 / 10012Producto no válido / método de pago no válido
10020Número de pedido del comercio duplicado
30001 / 30002Número de pedido incorrecto / moneda incorrecta o cuenta no activada

Proceso completo de integración

Tomando el cobro como ejemplo:

  1. Arme el cuerpo de la solicitud de negocio (véanse los campos de "Crear pedido de cobro").
  2. Genere el timestamp (milisegundos) y el nonce (cadena aleatoria de ≥10 caracteres).
  3. Calcule el sign según las "Reglas de firma".
  4. Envíe los 4 encabezados de firma junto con el cuerpo JSON mediante POST /transaction/payin/v1/apply.
  5. Si code==0, tome data.payUrl para dirigir al usuario al pago.
  6. Espere la notificación asíncrona; también puede consultar el pedido activamente para confirmar el estado final.
  7. Al recibir la notificación, verifique la firma, procese la operación y responda con el texto plano OK.

Nota: las rutas de la interfaz, los campos y los códigos de estado de este documento corresponden a la implementación de producción; el dominio de la pasarela de producción, los códigos de producto product disponibles y la política de lista blanca de IP se proporcionarán a través de la plataforma tras la apertura de la cuenta.

Obtenga sus claves y comience a construir

Al abrir una cuenta en línea, obtiene credenciales de prueba y códigos de producto; una vez validado en el entorno sandbox, puede pasar a producción con un solo clic.