Luna SaludReferencia de la APILuna Salud

Crear un pago

POST/payments

Registra un pago que su clínica recibió en efectivo, por transferencia bancaria, de una aseguradora o por otro medio y crea el cobro que ese pago cubre: servicios del catálogo y conceptos de texto libre, cada línea a su precio de catálogo salvo que envíe unitPrice. Un monto igual al total deja el pago en PAID; un monto menor se registra como anticipo y deja el pago en PENDING con el saldo pendiente. Los pagos con tarjeta no se registran desde la API. No se le envía nada al paciente: ni recibo ni recordatorio. idempotencyKey es obligatorio: si reintenta con la misma clave y el mismo cuerpo, recibe el pago ya registrado en lugar de un duplicado, y mientras una solicitud con esa clave sigue en proceso la respuesta es 409 hasta que termine. Requiere una clave de API con permiso de escritura.

Ejemplos de código

Node.js

const fetch = require('node-fetch');

async function llamarApi() {
  const claveApi = 'YOUR_API_KEY';
  const url = `https://account.lunahealth.app/api/payments`;
  const requestBody = {
    // Agregue sus datos del cuerpo de la solicitud aquí
  };

  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${claveApi}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(requestBody)
    });
    
    if (!response.ok) {
      throw new Error(`API error: ${response.status}`);
    }
    
    const data = await response.json();
    console.log(data);
    return data;
  } catch (error) {
    console.error('Error al llamar a la API:', error);
    throw error;
  }
}

llamarApi();

Python

import requests

def llamarApi():
    claveApi = 'YOUR_API_KEY'
    
    url = 'https://account.lunahealth.app/api/payments'
    
    headers = {
        'Authorization': f'Bearer {claveApi}',
        'Content-Type': 'application/json'
    }
    
    params = {

    }
    
    # Agregue sus datos del cuerpo de la solicitud aquí
    request_body = {}
        try:
        response = requests.post(
            url,
            headers=headers,
            params=params,
            json=request_body
        )
        response.raise_for_status()
        
        data = response.json()
        print(data)
        return data
    except requests.exceptions.RequestException as e:
        print(f'Error al llamar a la API: {e}')
        raise

llamarApi()

Cuerpo de la solicitud

Requerido

Campos de la solicitud

NombreTipoRequeridoDescripción
idempotencyKeystringSíUna clave única que usted genera para este pago, por ejemplo un UUID. Si reintenta con la misma clave y el mismo cuerpo, recibe el pago que creó la primera solicitud en lugar de registrarlo otra vez; la misma clave con un cuerpo distinto se rechaza.
patientIdstringSíID del paciente que pagó, de su organización
appointmentIdstringNoID de la cita del paciente que cubre este pago. Una cita puede tener un solo pago. Si lo envía, el pago se atribuye a los profesionales de salud de la cita salvo que envíe staffId, y la sucursal predeterminada es la de la cita.
staffIdstringNoID del profesional de salud al que se atribuye el pago. Obligatorio si no envía appointmentId.
locationIdstringNoID de la sucursal a la que pertenece el pago. Por defecto, la sucursal de la cita, si la hay.
issueDatestringNoFecha de emisión en formato YYYY-MM-DD, según el calendario de la clínica. Por defecto, la fecha de hoy en la zona horaria de la clínica.
linesarray<object>SíLo que cubre el pago: servicios del catálogo y conceptos de texto libre, de 1 a 50 líneas.
paymentobjectSíEl dinero recibido.

Ejemplo de solicitud

{
  "idempotencyKey": "string",
  "patientId": "string",
  "appointmentId": "string",
  "staffId": "string",
  "locationId": "string",
  "issueDate": "string",
  "lines": [
    {
      "serviceId": "string",
      "description": "string",
      "quantity": 0,
      "unitPrice": 0
    }
  ],
  "payment": {
    "amount": 0,
    "method": "CASH",
    "methodDetail": "string",
    "insurerId": "string"
  }
}

Respuestas

EstadoDescripción
200Respuesta exitosa
400Datos de entrada no válidos
401Autorización no proporcionada
403Acceso insuficiente
500Error interno del servidor

200 — Respuesta exitosa

Campos de la respuesta

NombreTipoRequeridoDescripción
idstringSí—
invoice_numberstringSí—
statusstringSí—
currencystringnullSí—
total_amountnumberSí—
subtotal_amountnumberSí—
tax_amountnumberSí—
paid_amountnumbernullSí—
balancenumberSí—
payment_methodstring | nullSí—
payment_datestringnullSí—
due_datestringSí—
created_atstringSí—
updated_atstringSí—
patientobject | nullSí—
cfdiobject | nullSí—

Ejemplo de respuesta

{
  "id": "string",
  "invoice_number": "string",
  "status": "PAID",
  "currency": null,
  "total_amount": 0,
  "subtotal_amount": 0,
  "tax_amount": 0,
  "paid_amount": null,
  "balance": 0,
  "payment_method": "CARD",
  "payment_date": null,
  "due_date": "string",
  "created_at": "string",
  "updated_at": "string",
  "patient": {
    "id": "string",
    "first_name": null,
    "last_name": null,
    "email": null
  },
  "cfdi": {
    "uuid": null,
    "serie": null,
    "folio": "string",
    "status": "DRAFT",
    "stamped_at": null,
    "cancelled_at": null
  }
}

400 — Datos de entrada no válidos

Campos de la respuesta

NombreTipoRequeridoDescripción
messagestringSíThe error message
codestringSíThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Ejemplo de respuesta

{
  "code": "BAD_REQUEST",
  "message": "Invalid input data",
  "issues": []
}

401 — Autorización no proporcionada

Campos de la respuesta

NombreTipoRequeridoDescripción
messagestringSíThe error message
codestringSíThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Ejemplo de respuesta

{
  "code": "UNAUTHORIZED",
  "message": "Authorization not provided",
  "issues": []
}

403 — Acceso insuficiente

Campos de la respuesta

NombreTipoRequeridoDescripción
messagestringSíThe error message
codestringSíThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Ejemplo de respuesta

{
  "code": "FORBIDDEN",
  "message": "Insufficient access",
  "issues": []
}

500 — Error interno del servidor

Campos de la respuesta

NombreTipoRequeridoDescripción
messagestringSíThe error message
codestringSíThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Ejemplo de respuesta

{
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Internal server error",
  "issues": []
}