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

# Invoice now, receive a partial payment later

> Follow a MXN 1,160 PPD invoice through its first MXN 580 payment.

<Note>**Mexico example.** This walkthrough uses the Mexican CFDI flow. For another
issuing country, start with [shared fields and country rules](/concepts/shared-fields).</Note>

**Case:** you issue the consulting invoice today. The customer pays half next week.
There is one sale, one income invoice, and a payment complement for the payment received.

| Moment | Amount | Expected record |
| - | - | - |
| You issue the sale | MXN 1,160 | Income invoice, `PPD`, payment form `99` |
| First bank transfer arrives | MXN 580 | Registered payment linked to the invoice UUID |
| Complement finishes | MXN 580 paid; MXN 580 remains | CFDI `P` linked to that income invoice |

## 1. Issue the PPD invoice

Start with `draft-body.json` from [the invoice recipe](/recipes/invoice). The direct
income endpoint issues immediately; there is no separate draft review step in this call.

```bash theme={null}
set -euo pipefail
jq 'del(.invoice_type) + {
  payment_method: "PPD",
  payment_form: "99",
  idempotency_key: "order-1042-income"
}' draft-body.json > ppd-body.json

curl --fail-with-body "$GIGSTACK_BASE_URL/invoices/income" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data @ppd-body.json > ppd.json

PPD_UUID=$(jq -er '.data.uuid' ppd.json)
export PPD_UUID
```

**Observed:** HTTP `200`, `data.status: "valid"`, `payment_method: "PPD"`,
`payment_form: "99"`, and total `1160`. Keep the UUID from this response.

## 2. Record the first payment

The customer paid MXN 580: half the subtotal (`500`) plus IVA (`80`). The API derives
the payment total from its items; the example uses the same currency as the invoice.

```bash theme={null}
jq --arg uuid "$PPD_UUID" '{
  client, currency, exchange_rate,
  payment_form: "03",
  automation_type: "none",
  ppd_invoice_id: $uuid,
  idempotency_key: "order-1042-payment-1",
  items: [.items[0] + {unit_price: 500}]
}' ppd-body.json > partial-payment-body.json

curl --fail-with-body "$GIGSTACK_BASE_URL/payments/register" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY" \
  -H 'Content-Type: application/json' \
  --data @partial-payment-body.json > partial-payment.json

PAYMENT_ID=$(jq -er '.data.id' partial-payment.json)
export PAYMENT_ID
```

**Expected:** HTTP `201`, a payment ID, and total `580`.

<Note>
  `ppd_invoice_id` is the income invoice's **SAT UUID**, despite the field's name.
  It requests complement handling for that existing invoice. The handler enables that
  automation even with `automation_type: "none"`; it does not issue a second income invoice.
  Do not also call `POST /invoices/payment` for the same payment.
</Note>

## 3. Verify the complement and balance

Automation is asynchronous. A successful payment registration alone does not prove
that the complement finished stamping. Fetch the payment and parent invoice:

```bash theme={null}
curl --fail-with-body "$GIGSTACK_BASE_URL/payments/$PAYMENT_ID" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY" > payment-state.json

curl --fail-with-body "$GIGSTACK_BASE_URL/invoices/income/$PPD_UUID" \
  -H "Authorization: Bearer $GIGSTACK_API_KEY" > invoice-state.json

jq '.data | {invoices, status, total}' payment-state.json
jq '.data | {payment_complements, last_balance, installments}' invoice-state.json
```

In the verified test, the payment linked both the income UUID and a new complement UUID.
The parent returned `payment_complements: 580`, `last_balance: 580`, and `installments: 2`.
Here `installments` points to the **next** installment number; it does not mean two
payments have already happened.

For a second payment, use a new payment key and no more than the remaining balance.
Read the current balance again before registering it. Multi-currency payments require
additional exchange-rate handling; see the [payment reference](/reference/createPaymentsRegister).

If the complement remains absent, investigate the automation result before submitting
another payment. [Troubleshooting](/troubleshooting) explains how to reconcile ambiguous writes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.