curl --request POST \
--url https://api.gigstack.io/v2/payments/register \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"client": {
"id": "client_1234567890"
},
"automation_type": "pue_invoice",
"currency": "MXN",
"exchange_rate": 1,
"payment_form": "03",
"items": [
{
"id": "service_1234567890",
"quantity": 1,
"unit_price": 1000
}
]
}
'{
"success": true,
"message": "Payment registered successfully",
"timestamp": 1767225600000,
"data": {
"id": "payment_1234567890",
"client": {
"id": "client_1234567890",
"name": "Juan Pérez García",
"email": "juan.perez@ejemplo.com",
"tax_id": "PEGJ800101ABC"
},
"status": "succeeded",
"currency": "MXN",
"exchange_rate": 1,
"payment_form": "03",
"total": 1160,
"subtotal": 1000,
"taxes": 160,
"discount": 0,
"items": [
{
"id": "service_1234567890",
"description": "Professional consulting services",
"quantity": 1,
"unit_price": 1000,
"product_key": "80141503",
"unit_key": "E48"
}
],
"invoices": [
"B0C3E4F2-1A2B-4C5D-9E8F-0123456789AB"
],
"created_at": 1677651234,
"succeeded_at": 1677651234,
"payment_processor": "api",
"livemode": true,
"team": "team_1234567890",
"owner": "user_1234567890"
}
}Register payment
Integration note: Records money already received; does not charge a card. Repeating a creation idempotency_key returned HTTP 400 with error.code resource_conflict in staging. Reconcile the existing payment. ppd_invoice_id is a SAT UUID and enables complement automation even with automation_type none. Registration success is not proof that the asynchronous complement finished.
Register a payment with optional automation for invoice creation.
gigstack Connect: Register payments for other teams using the team parameter.
Automation Types
Control what happens automatically when registering a payment:
pue_invoice: Creates a PUE (Pago en Una sola Exhibición) invoice immediatelynone: No automation, registers payment only
PPD Invoice Linking
You can link a payment to an existing PPD (Pago en Parcialidades o Diferido) invoice by providing the ppd_invoice_id field.
When set, a payment complement (complemento de pago) CFDI will be automatically generated and linked to the PPD invoice.
The referenced invoice must have payment_method='PPD' and status='valid'.
Payment Form
The payment_form field specifies the Mexican SAT payment form code:
Common codes include: 01 (cash), 02 (check), 03 (electronic transfer), 04 (credit card), etc.
The payment will be marked as ‘succeeded’ immediately upon registration.
Required fields
client, currency, items (at least one), payment_form and automation_type
are required. automation_type has no default — omitting it fails validation.
Allowed values: pue_invoice, ppd_invoice_and_complement, none.
date
Optional, in Unix epoch milliseconds (13 digits). Compared against
Luxon.now().toMillis(); a future value returns 400.
transfer_data — all-or-nothing
transfer_data is optional, but when it is present all four of master, connect,
master_to and connect_to are required; omitting any one fails validation.
| field | type | constraint |
|---|---|---|
master | number | required, 0 ≤ master ≤ 100 (percentage retained by the master team) |
connect | string | required, non-empty — RFC of the connected team |
master_to | enum | required — client or connect |
connect_to | enum | required — client or master |
connect_custom_config | object | optional; every field inside it is optional except type, rate and withholding on each taxes[] entry |
invoice_config
All nested fields are optional:
| field | type | meaning |
|---|---|---|
serie | string | invoice series |
folio | number | invoice folio number |
date | number | invoice issue date, Unix epoch milliseconds |
global.year | number | fiscal year of the global (EOM) invoice, e.g. 2026 |
global.months | string | SAT c_Meses code, e.g. 01 for January or 13 for Jan–Feb |
global.periodicity | string | SAT c_Periodicidad code — 01 daily, 02 weekly, 03 fortnightly, 04 monthly, 05 bimonthly |
validUntil | number | expiry of the self-invoicing window, Unix epoch milliseconds |
Email suppression
ignore_emails: true suppresses notification emails. On this endpoint send_email is
accepted but has no effect — only ignore_emails is persisted onto the payment.
Unknown fields
Body validation runs in strict allowlist mode — any undeclared key is rejected with
400 validation_failed / unexpected_key.
curl --request POST \
--url https://api.gigstack.io/v2/payments/register \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"client": {
"id": "client_1234567890"
},
"automation_type": "pue_invoice",
"currency": "MXN",
"exchange_rate": 1,
"payment_form": "03",
"items": [
{
"id": "service_1234567890",
"quantity": 1,
"unit_price": 1000
}
]
}
'{
"success": true,
"message": "Payment registered successfully",
"timestamp": 1767225600000,
"data": {
"id": "payment_1234567890",
"client": {
"id": "client_1234567890",
"name": "Juan Pérez García",
"email": "juan.perez@ejemplo.com",
"tax_id": "PEGJ800101ABC"
},
"status": "succeeded",
"currency": "MXN",
"exchange_rate": 1,
"payment_form": "03",
"total": 1160,
"subtotal": 1000,
"taxes": 160,
"discount": 0,
"items": [
{
"id": "service_1234567890",
"description": "Professional consulting services",
"quantity": 1,
"unit_price": 1000,
"product_key": "80141503",
"unit_key": "E48"
}
],
"invoices": [
"B0C3E4F2-1A2B-4C5D-9E8F-0123456789AB"
],
"created_at": 1677651234,
"succeeded_at": 1677651234,
"payment_processor": "api",
"livemode": true,
"team": "team_1234567890",
"owner": "user_1234567890"
}
}Authorizations
Authentication Method: HTTP Bearer token.
The runtime requires the literal Bearer prefix — a bare token in the
Authorization header is rejected with 401 unauthorized.
Header Format: Authorization: Bearer YOUR_API_KEY
Your API key is a JWT. Live keys operate on live data (livemode: true);
test keys operate on isolated test data (livemode: false).
Get your key at: app.gigstack.pro/settings?tab=api
Errors: credential failures are answered by the authentication layer with a raw
{ "message": … } body, not the standardized envelope — 401 for a missing, malformed or
expired token, 403 for a revoked key or a plan without API access. See the Unauthorized
and AuthForbidden responses.
Query Parameters
gigstack Connect: Target team ID for multi-team access.
Requires gigstack Connect enabled on your team and shared billing account.
Also requires the multipleIssuerAccounts feature on your plan. Requests targeting a
team other than the one your API key belongs to return 403 without it.
Only API keys can use it: an OAuth access token sent with another team's id is rejected with
403 Team mismatch with OAuth token.
Optional — omit it entirely unless you are acting on another team. It deliberately
carries no example value so generated snippets do not emit ?team=undefined; when the
parameter is absent, the team is derived from your API key.
Example: ?team=team_xyz789
Body
Unknown top-level keys are rejected (400 validation_failed / unexpected_key).
team, livemode and owner are reserved and injected by the auth middleware.
Show child attributes
Show child attributes
Payment automation type:
pue_invoice: Create PUE (Pago en Una sola Exhibición) invoice immediately when payment succeedsppd_invoice_and_complement: Create PPD (Pago en Parcialidades o Diferido) invoice immediately, then payment complement when payment succeedsnone: No automation, register payment only
pue_invoice, ppd_invoice_and_complement, none "pue_invoice"
Currency code (ISO 4217)
"MXN"
1Show child attributes
Show child attributes
Mexican SAT payment form code:
01: Cash02: Check03: Electronic transfer04: Credit card05: Electronic money06: Digital money08: Gift voucher12: Credit for unregistered bills13: Payment by subrogation14: Payment by consignment15: Condonation17: Compensation23: Novation24: Confusion25: Remission of debt26: Prescription or expiration27: To creditor's satisfaction28: Credit card29: Debit card30: Service card31: Applicable only to the complementary concept of donations99: To be defined
01, 02, 03, 04, 05, 06, 08, 12, 13, 14, 15, 17, 23, 24, 25, 26, 27, 28, 29, 30, 31, 99 "03"
Exchange rate for currency conversion. If not provided, the rate from the payment date (or current date if no date specified) will be fetched automatically from our rates collection.
1
Stable key for one business event. A duplicate returns HTTP 400 with error.code resource_conflict, not the existing payment as a successful response. Reconcile the existing record and retain this key; do not create a new key for a retry.
"payment-register-12345"
Additional metadata to store with the payment
Optional invoice configuration. Every field is optional. Controls the folio/serie the generated invoice will use, its issue date, the global (EOM) period it belongs to, and how long the self-invoicing window stays open.
Show child attributes
Show child attributes
Unix epoch timestamp in milliseconds (13 digits) for when the payment was received. Must be in the past. Defaults to now.
1767225600000
Accepted for compatibility, but on this endpoint it has no effect — only
ignore_emails is persisted onto the payment. Use ignore_emails to suppress mail.
true
Suppress email and WhatsApp notifications for this payment and any documents
it automates (invoices, receipts). Defaults to false.
false
UUID of an existing PPD invoice to link this payment to. When provided, a payment complement (complemento de pago) will be automatically generated and linked to the PPD invoice. The referenced invoice must have payment_method='PPD', status='valid' and invoice_type='I' — a payment complement only ever settles an income CFDI, never an egress one.
"invoice_ppd_1234567890"
Configuration for splitting payments between master and connect teams in a marketplace. Only available for master teams with marketplace-enabled billing accounts.
All-or-nothing: the object itself is optional, but when it is present
master, connect, master_to and connect_to are all required.
Sending transfer_data with any of them missing fails validation with
400 validation_failed. connect_custom_config stays optional.
Show child attributes
Show child attributes
Response
Payment registered successfully. Both the standard path and the
transfer_data split path return 201 with the standardized success envelope.
Standardized success envelope emitted by sendSuccessResponse.
true true
The operation payload.
- Option 1
- Option 2
Show child attributes
Show child attributes
Server time in epoch milliseconds (Luxon.now().toMillis()).
1767225600000
Payment registered successfully on the standard path, Split payments registered successfully on the split path.
"Payment registered successfully"