# Portal de proveedores

> Lleve a su ERP las facturas que sus proveedores le mandan por el portal en cuanto se aprueban, y devuelva la fecha en que las paga y el pago.

El **Portal de proveedores** es donde sus proveedores dan su alta, suben sus facturas (revisadas antes de llegar: SAT, 69-B, PUE o PPD, retenciones, tipo de cambio, orden de compra…) y ven cuándo se les paga. Con la API, su ERP (SAP, NetSuite, CONTPAQi o el suyo) recibe lo aprobado sin que nadie lo exporte a mano, y le devuelve a Fiscalisto la fecha de pago y el pago, que el proveedor ve en su portal.

- Un **proveedor del portal** (`sup_…`): su alta, sus documentos, la cuenta a la que se le paga y su calificación.
- Una **factura de proveedor** (`spi_…`): lo que se revisó, su orden de compra, su contrarecibo y sus fechas. Su estado: `received` (por revisar) → `approved` → `scheduled` → `paid`, o `rejected`.

La revisión y la aprobación (con sus niveles) se hacen en la app, en **Compras › Portal de proveedores**.

## Su empresa de la app

Si su portal está en una empresa de la app (no en un emisor que creó con la API), conéctela a su cuenta API: en [Desarrolladores › Emisores](/desarrolladores/emisores), en producción, pulse **Conectar una empresa** y elija la empresa y su RFC. Queda como un emisor más (`iss_…`, con `source: "empresa"`) y estas rutas y sus eventos funcionan con su llave `fk_live_`. Es la misma empresa, no una copia. Con la API solo se usa su portal: cualquier otra ruta con ese emisor responde `403` `issuer_linked_empresa`. `DELETE /v1/issuers/{id}` la desconecta sin cambiar la empresa.

## Las facturas aprobadas

Escuche `supplier_invoice.approved` en sus [webhooks](https://fiscalisto.com/docs/api/webhooks), o pida las aprobadas:

```bash tab="cURL"
curl -G https://api.fiscalisto.com/v1/supplier_invoices \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -d status=approved
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

for await (const item of fiscalisto.supplierInvoices.list({ status: "approved" })) {
  console.log(item.id);
}
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

for item in fiscalisto.supplier_invoices.list({"status": "approved"}):
    print(item["id"])
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

foreach ($fiscalisto->supplierInvoices->list(['status' => 'approved']) as $item) {
    echo $item['id'], "\n";
}
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	for item, err := range client.SupplierInvoices.ListAutoPaging(ctx, &fiscalisto.ListSupplierInvoicesParams{
		Status: fiscalisto.String("approved"),
	}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(item.ID)
	}
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.model.ListSupplierInvoicesParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

for (var item : fiscalisto.supplierInvoices().listAutoPaging(new ListSupplierInvoicesParams().setStatus("approved"))) {
    System.out.println(item.getId());
}
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

await foreach (var item in fiscalisto.SupplierInvoices.ListAutoPagingAsync(new ListSupplierInvoicesParams { Status = "approved" }))
    Console.WriteLine(item.Id);
```

Cada una trae `payable` (lo que se le paga: el total sin las diferencias con su orden ni el descuento de pronto pago), `due_on` (cuándo vence por sus fechas de pago), `purchase_order`, `contrarecibo` y `warnings` (lo que se revisó y quedó como aviso). Su XML y su PDF están en `GET /v1/sat_invoices/{sat_invoice}/xml` y `/pdf`. Filtre también por `supplier` (`sup_…`) o `received_since` (AAAA-MM-DD).

## Programar el pago

El día en que la pagará. El proveedor lo ve en su portal y llega `supplier_invoice.scheduled`:

```bash tab="cURL"
curl https://api.fiscalisto.com/v1/supplier_invoices/spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx/schedule \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "pay_on": "2026-11-27" }'
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

const supplierInvoice = await fiscalisto.supplierInvoices.schedule("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", { pay_on: "2026-11-27" });
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

supplier_invoice = fiscalisto.supplier_invoices.schedule("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", {"pay_on": "2026-11-27"})
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

$supplierInvoice = $fiscalisto->supplierInvoices->schedule('spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx', ['pay_on' => '2026-11-27']);
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	supplierInvoice, err := client.SupplierInvoices.Schedule(ctx, "spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", &fiscalisto.ScheduleSupplierInvoiceParams{
		PayOn: "2026-11-27",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(supplierInvoice.ID)
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.model.ScheduleSupplierInvoiceParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var supplierInvoice = fiscalisto.supplierInvoices().schedule("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", new ScheduleSupplierInvoiceParams().setPayOn("2026-11-27"));
System.out.println(supplierInvoice.getId());
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var supplierInvoice = await fiscalisto.SupplierInvoices.ScheduleAsync("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", new ScheduleSupplierInvoiceParams { PayOn = "2026-11-27" });
```

Solo una aprobada o ya programada, en una fecha de hoy en adelante. Si el SAT la reporta cancelada desde que se aprobó, responde `400` `supplier_invoice_invalid` y no se programa.

## Marcar pagada

Cuando su ERP o su banco la paga. Si es PPD, le pedimos al proveedor su complemento de pago (a más tardar el día 5 del mes siguiente) y llega `supplier_invoice.paid`:

```bash tab="cURL"
curl https://api.fiscalisto.com/v1/supplier_invoices/spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx/mark_paid \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "paid_on": "2026-11-27", "reference": "SPEI 004512" }'
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

const supplierInvoice = await fiscalisto.supplierInvoices.markPaid("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", {
  paid_on: "2026-11-27",
  reference: "SPEI 004512",
});
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

supplier_invoice = fiscalisto.supplier_invoices.mark_paid("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", {
    "paid_on": "2026-11-27",
    "reference": "SPEI 004512",
})
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

$supplierInvoice = $fiscalisto->supplierInvoices->markPaid('spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx', [
    'paid_on' => '2026-11-27',
    'reference' => 'SPEI 004512',
]);
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	supplierInvoice, err := client.SupplierInvoices.MarkPaid(ctx, "spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", &fiscalisto.MarkSupplierInvoicePaidParams{
		PaidOn:    "2026-11-27",
		Reference: fiscalisto.String("SPEI 004512"),
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(supplierInvoice.ID)
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.model.MarkSupplierInvoicePaidParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var supplierInvoice = fiscalisto.supplierInvoices().markPaid("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", new MarkSupplierInvoicePaidParams()
        .setPaidOn("2026-11-27")
        .setReference("SPEI 004512"));
System.out.println(supplierInvoice.getId());
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var supplierInvoice = await fiscalisto.SupplierInvoices.MarkPaidAsync("spi_OufpKqnrvx9p7Hq2mZr1XyT5uBcW8sKdLx", new MarkSupplierInvoicePaidParams
{
    PaidOn = "2026-11-27",
    Reference = "SPEI 004512",
});
```

Fiscalisto no hace el pago: lo registra. `paid_on` es de hoy o antes.

## Sus proveedores

```bash tab="cURL"
curl -G https://api.fiscalisto.com/v1/portal_suppliers \
  -H "Authorization: Bearer $FISCALISTO_API_KEY" \
  -d status=approved
```

```ts tab="TypeScript"
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

for await (const item of fiscalisto.portalSuppliers.list({ status: "approved" })) {
  console.log(item.id);
}
```

```python tab="Python"
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

for item in fiscalisto.portal_suppliers.list({"status": "approved"}):
    print(item["id"])
```

```php tab="PHP"
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

foreach ($fiscalisto->portalSuppliers->list(['status' => 'approved']) as $item) {
    echo $item['id'], "\n";
}
```

```go tab="Go"
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	for item, err := range client.PortalSuppliers.ListAutoPaging(ctx, &fiscalisto.ListPortalSuppliersParams{
		Status: fiscalisto.String("approved"),
	}) {
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(item.ID)
	}
}
```

```java tab="Java"
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.model.ListPortalSuppliersParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

for (var item : fiscalisto.portalSuppliers().listAutoPaging(new ListPortalSuppliersParams().setStatus("approved"))) {
    System.out.println(item.getId());
}
```

```csharp tab="C#"
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

await foreach (var item in fiscalisto.PortalSuppliers.ListAutoPagingAsync(new ListPortalSuppliersParams { Status = "approved" }))
    Console.WriteLine(item.Id);
```

- `status`: `invited`, `onboarding` (dando su alta), `in_review`, `approved` (puede mandar facturas), `rejected` o `suspended`. Llega `portal_supplier.approved` cuando se aprueba un alta.
- `bank_account`: la CLABE a la que se le paga. Una nueva queda `pending` hasta que se aprueba en la app, que pide confirmar quién es; mientras, se le paga a `previous_clabe`. Así nadie cambia la cuenta de un proveedor sin que su equipo lo vea.
- `documents`: si su alta está completa y vigente, y cuántos documentos faltan, esperan revisión o vencieron.
- `score`: su calificación de 0 a 100 de los últimos 12 meses (`excellent`, `good`, `fair` o `poor`) y cada parte: `invoices` (facturas a la primera), `deliveries` (entregas a tiempo), `prices` (precio y cantidad de la orden), `documents` (documentos al día) y `complements` (complementos de pago), con cuántos casos se midió.

## Eventos

| Evento | Cuándo llega |
| --- | --- |
| `supplier_invoice.received` | Un proveedor mandó una factura. |
| `supplier_invoice.approved` | Se aprobó, con todos sus niveles: ya puede ir a su ERP. |
| `supplier_invoice.rejected` | Se rechazó, con `rejection_reason`. |
| `supplier_invoice.scheduled` | Se programó o cambió su fecha de pago. |
| `supplier_invoice.paid` | Se marcó pagada. |
| `portal_supplier.approved` | Se aprobó el alta de un proveedor. |

`data.object` es la factura de proveedor o el proveedor, como los da `GET`.
