> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shoppex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoices

> Understanding the invoice lifecycle and statuses

## Overview

Every payment in Shoppex starts with an invoice. Whether a customer checks out through your storefront, clicks a payment link, or your backend creates one via API — the invoice is always the central object that tracks who is paying, what they're buying, and whether the payment succeeded.

<Info>
  This guide covers the Shoppex invoice model used by both hosted checkout flows and the Developer API.
</Info>

<Note>
  An invoice can go through more than one payment attempt before it reaches its final state. A customer might try PayPal, abandon it, and come back with a credit card — it's still the same invoice.
</Note>

## Invoice Statuses

| Status                      | Description                                     |
| --------------------------- | ----------------------------------------------- |
| `PENDING`                   | Invoice created, awaiting payment               |
| `COMPLETED`                 | Payment completed successfully                  |
| `PARTIAL`                   | Partial payment received (crypto underpayment)  |
| `VOIDED`                    | Invoice cancelled or expired                    |
| `WAITING_FOR_CONFIRMATIONS` | Crypto payment pending blockchain confirmations |
| `CUSTOMER_DISPUTE_ONGOING`  | Customer opened a dispute/chargeback            |
| `REVERSED`                  | Payment reversed (chargeback won by customer)   |
| `REFUNDED`                  | Payment was refunded                            |

## Creating an Invoice

### Via Dashboard

<Steps>
  <Step title="Navigate to Invoices">
    Go to **Invoices → Create Invoice**
  </Step>

  <Step title="Select products">
    Select products and quantities
  </Step>

  <Step title="Enter customer email">
    Enter customer email (optional)
  </Step>

  <Step title="Choose payment methods">
    Choose allowed payment methods
  </Step>

  <Step title="Create the invoice">
    Click **Create**
  </Step>
</Steps>

### Via API (Developer API)

Use the [POST /payments](/api-reference/payments/create) endpoint to create an invoice programmatically:

<CodeGroup>
  ```typescript TypeScript theme={"system"}
  const response = await fetch('https://api.shoppex.io/dev/v1/payments', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      title: 'Order #456',
      email: 'customer@example.com',
      value: 29.99,
      currency: 'EUR'
    })
  });

  const { data } = await response.json();
  // Redirect to data.url for checkout
  ```
</CodeGroup>

## Completing or Processing an Invoice

The Dashboard calls the manual merchant action **Process Invoice**. The public Developer API calls the same operation **complete invoice**:

```http theme={"system"}
POST /dev/v1/invoices/{uniqid}/complete
```

Use it only after your server has independently confirmed payment. The invoice must still be `PENDING` or `PENDING_PAYMENT`; an already completed or otherwise non-completable invoice returns `422 VALIDATION_ERROR`. Every request must include an `Idempotency-Key` header.

See [Manual payment auto-completion](/guides/manual-payment-completion) for request examples, idempotency, webhook verification, and common errors.

## Invoice Expiration

By default, Shoppex-hosted invoice payment windows expire after **24 hours**.
You can customize the default expiration in **Settings → Invoices**.

<Note>
  The current Dev API payment example on this page does not accept an `expires_at` request field.
  Configure a different default expiration in the dashboard instead.
</Note>

<Warning>
  Expired invoices cannot be paid. Create a new invoice for the customer if needed.
</Warning>

## Partial Payments

Partial payments can occur with cryptocurrency when the customer sends slightly less than required. You can:

<AccordionGroup>
  <Accordion title="Accept as paid">
    Mark the invoice as paid manually from the dashboard. Use this when the shortfall is negligible and you want to fulfill the order immediately.
  </Accordion>

  <Accordion title="Request remaining">
    Customer pays the difference. The invoice stays in `PARTIAL` status until the remaining amount is received, then transitions to `COMPLETED`.
  </Accordion>

  <Accordion title="Refund">
    Cancel and refund the partial payment. The invoice moves to `VOIDED` and you can create a new one if needed.
  </Accordion>
</AccordionGroup>

## Webhooks

Get notified when invoice status changes:

```json theme={"system"}
{
  "event": "order:paid",
  "data": {
    "uniqid": "abc123def456",
    "type": "PRODUCT",
    "status": "COMPLETED",
    "gateway": "STRIPE",
    "total": 29.99,
    "total_display": 29.99,
    "currency": "USD",
    "customer_email": "customer@example.com",
    "product_id": "prod_xyz",
    "product_title": "Pro License",
    "created_at": "2026-01-15T09:10:00.000Z",
    "updated_at": "2026-01-15T09:10:50.000Z"
  },
  "created_at": 1705314650
}
```

See [Webhooks Guide](/guides/webhooks) for setup instructions.

## Integration Rule

If you sync invoices into your own system, use the Shoppex invoice status as the final source of truth. The first payment attempt might fail, the second might succeed — the invoice ends as `COMPLETED` regardless of how many tries it took.

<Tip>
  React to the final invoice state via webhook events, not to individual gateway callbacks. This is the single most important integration rule in Shoppex.
</Tip>

## Next Steps

<CardGroup cols={2}>
  <Card title="Payments Guide" icon="credit-card" href="/guides/payments">
    Learn about payment gateways, configuration, and processing.
  </Card>

  <Card title="Webhooks Guide" icon="bell" href="/guides/webhooks">
    Set up real-time notifications for invoice status changes.
  </Card>
</CardGroup>
