{
  "version": 2,
  "documentationOrigin": "https://docs.gigstack.io",
  "placeholderSyntax": "${NAME} values must be supplied; never send placeholders literally.",
  "authorization": "These examples describe requests. They do not authorize execution.",
  "workflows": [
    {
      "id": "customer",
      "guide": "/recipes/customer",
      "steps": [
        {
          "operationId": "createClients",
          "method": "POST",
          "path": "/clients",
          "body": {
            "name": "Workshop customer",
            "email": "customer@example.com",
            "metadata": {
              "external_id": "${CUSTOMER_REFERENCE}"
            },
            "search": {
              "on_key": "metadata.external_id",
              "on_value": "${CUSTOMER_REFERENCE}",
              "update": false
            }
          },
          "expectedHttp": [
            200,
            201
          ],
          "save": {
            "CLIENT_ID": "data.id"
          },
          "verify": [
            "data.livemode is false for test runs"
          ]
        }
      ],
      "countryScope": "Shared contact fields; verified with a Mexican issuing team",
      "verification": {
        "level": "staging-exercised",
        "date": "2026-10-08",
        "environment": "gigstackprodev; livemode false",
        "issuerCountry": "MX",
        "evidence": "/verification"
      }
    },
    {
      "id": "invoice",
      "guide": "/recipes/invoice",
      "prerequisites": [
        "Customer fiscal data",
        "Issuer invoicing provider and CSD",
        "Explicit approval to issue",
        "For tests, approved sandbox with known account notification recipients: invoice creation can attempt a marketing event despite test mode, send_email false, ignore_emails true and automation_type none."
      ],
      "steps": [
        {
          "operationId": "createInvoicesDraft",
          "method": "POST",
          "path": "/invoices/draft",
          "body": {
            "client": {
              "id": "${CLIENT_ID}"
            },
            "currency": "MXN",
            "exchange_rate": 1,
            "use": "G03",
            "payment_form": "03",
            "payment_method": "PUE",
            "items": [
              {
                "description": "One hour of consulting",
                "product_key": "80101500",
                "unit_key": "E48",
                "quantity": 1,
                "unit_price": 1000,
                "taxes": [
                  {
                    "type": "IVA",
                    "rate": 0.16,
                    "inclusive": false,
                    "withholding": false,
                    "factor": "Tasa"
                  }
                ]
              }
            ],
            "automation_type": "none",
            "send_email": false,
            "ignore_emails": true,
            "invoice_type": "I"
          },
          "expectedHttp": [
            201
          ],
          "save": {
            "DRAFT_ID": "data.id"
          },
          "verify": [
            "data.status == draft",
            "data.livemode == false for test runs"
          ]
        },
        {
          "operationId": "createInvoicesDraftByIdPreview",
          "method": "POST",
          "path": "/invoices/draft/${DRAFT_ID}/preview",
          "body": {},
          "expectedHttp": [
            200
          ],
          "verify": [
            "Review recipient, currency, items and taxes"
          ]
        },
        {
          "operationId": "createInvoicesDraftByIdStamp",
          "method": "POST",
          "path": "/invoices/draft/${DRAFT_ID}/stamp",
          "body": {
            "send_email": false,
            "ignore_emails": true
          },
          "expectedHttp": [
            200
          ],
          "save": {
            "INVOICE_UUID": "data.uuid"
          },
          "verify": [
            "data.status == valid",
            "Do not expect data.id; use the new UUID",
            "Stored draft mode controls stamping"
          ]
        },
        {
          "operationId": "getInvoicesIncomeById",
          "method": "GET",
          "path": "/invoices/income/${INVOICE_UUID}",
          "expectedHttp": [
            200
          ]
        }
      ],
      "countryScope": "MX",
      "verification": {
        "level": "staging-exercised",
        "date": "2026-10-08",
        "environment": "gigstackprodev; livemode false",
        "issuerCountry": "MX",
        "evidence": "/verification"
      }
    },
    {
      "id": "payment",
      "guide": "/recipes/payment",
      "steps": [
        {
          "operationId": "createPaymentsRegister",
          "method": "POST",
          "path": "/payments/register",
          "body": {
            "client": {
              "id": "${CLIENT_ID}"
            },
            "currency": "MXN",
            "payment_form": "03",
            "automation_type": "none",
            "idempotency_key": "${PAYMENT_REFERENCE}",
            "items": [
              {
                "description": "One hour of consulting",
                "product_key": "80101500",
                "unit_key": "E48",
                "quantity": 1,
                "unit_price": 1000,
                "taxes": [
                  {
                    "type": "IVA",
                    "rate": 0.16,
                    "inclusive": false,
                    "withholding": false,
                    "factor": "Tasa"
                  }
                ]
              }
            ]
          },
          "expectedHttp": [
            201
          ],
          "save": {
            "PAYMENT_ID": "data.id"
          },
          "verify": [
            "data.total == 1160 for this example",
            "data.status == succeeded"
          ],
          "replay": {
            "http": 400,
            "errorCode": "resource_conflict",
            "action": "Retrieve and reconcile existing payment; retain original key"
          }
        }
      ],
      "countryScope": "Shared payment registration; example currency and taxes are Mexican",
      "verification": {
        "level": "staging-exercised",
        "date": "2026-10-08",
        "environment": "gigstackprodev; livemode false",
        "issuerCountry": "MX",
        "evidence": "/verification"
      }
    },
    {
      "id": "paid-later",
      "guide": "/recipes/paid-later",
      "steps": [
        {
          "operationId": "createInvoicesIncome",
          "method": "POST",
          "path": "/invoices/income",
          "body": {
            "client": {
              "id": "${CLIENT_ID}"
            },
            "currency": "MXN",
            "exchange_rate": 1,
            "use": "G03",
            "payment_form": "99",
            "payment_method": "PPD",
            "items": [
              {
                "description": "One hour of consulting",
                "product_key": "80101500",
                "unit_key": "E48",
                "quantity": 1,
                "unit_price": 1000,
                "taxes": [
                  {
                    "type": "IVA",
                    "rate": 0.16,
                    "inclusive": false,
                    "withholding": false,
                    "factor": "Tasa"
                  }
                ]
              }
            ],
            "automation_type": "none",
            "send_email": false,
            "ignore_emails": true,
            "idempotency_key": "${ORDER_REFERENCE}"
          },
          "expectedHttp": [
            200
          ],
          "save": {
            "PPD_UUID": "data.uuid"
          }
        },
        {
          "operationId": "createPaymentsRegister",
          "method": "POST",
          "path": "/payments/register",
          "body": {
            "client": {
              "id": "${CLIENT_ID}"
            },
            "currency": "MXN",
            "exchange_rate": 1,
            "payment_form": "03",
            "automation_type": "none",
            "ppd_invoice_id": "${PPD_UUID}",
            "idempotency_key": "${PARTIAL_PAYMENT_REFERENCE}",
            "items": [
              {
                "description": "One hour of consulting",
                "product_key": "80101500",
                "unit_key": "E48",
                "quantity": 1,
                "unit_price": 500,
                "taxes": [
                  {
                    "type": "IVA",
                    "rate": 0.16,
                    "inclusive": false,
                    "withholding": false,
                    "factor": "Tasa"
                  }
                ]
              }
            ]
          },
          "expectedHttp": [
            201
          ],
          "verify": [
            "ppd_invoice_id enables complement automation even when automation_type is none",
            "Registration does not prove complement completion"
          ]
        },
        {
          "operationId": "getInvoicesIncomeById",
          "method": "GET",
          "path": "/invoices/income/${PPD_UUID}",
          "expectedHttp": [
            200
          ],
          "verify": [
            "After first complement: payment_complements == 580",
            "After first complement: last_balance == 580",
            "Confirm linked complement before recording the next payment"
          ]
        }
      ],
      "countryScope": "MX",
      "verification": {
        "level": "staging-exercised",
        "date": "2026-10-08",
        "environment": "gigstackprodev; livemode false",
        "issuerCountry": "MX",
        "evidence": "/verification"
      }
    },
    {
      "id": "colombia-immediate-invoice",
      "guide": "/countries/colombia#first-immediate-payment-invoice",
      "countryScope": "COL",
      "verification": {
        "level": "source-reviewed",
        "date": "2026-10-08",
        "liveExecuted": false,
        "evidence": "/verification#source-review-and-offline-contract-checks"
      },
      "prerequisites": [
        "Owner-confirmed Colombian issuer, intended team and environment",
        "Provider credentials and numbering configured for test mode",
        "Provider-approved test NIT, legal name and fiscal classification",
        "Explicit authorization before issuance; review customer, amount and taxes"
      ],
      "notes": [
        "The recipient example is a domestic legal entity in Bogota, IVA responsible, with no listed special fiscal responsibility; adjust to approved test recipient data.",
        "use G03 is an API compatibility string, not a DIAN classification. Public transfer code 03 maps to provider 47.",
        "19 percent IVA and COP 119000 total are illustrative transaction inputs.",
        "Preserve data.uuid as opaque CUFE/CUDE/document identifier; do not enforce Mexican UUID syntax."
      ],
      "steps": [
        {
          "operationId": "createClients",
          "method": "POST",
          "path": "/clients",
          "body": {
            "name": "${CO_TEST_LEGAL_NAME}",
            "legal_name": "${CO_TEST_LEGAL_NAME}",
            "company": "${CO_TEST_LEGAL_NAME}",
            "email": "customer@example.com",
            "tax_id": "${CO_TEST_NIT}",
            "document_type": "31",
            "organization_type": 1,
            "tribute_code": "01",
            "fiscal_responsibilities": [
              "R-99-PN"
            ],
            "municipality_code": "11001",
            "address": {
              "country": "COL",
              "city": "Bogotá",
              "state": "Bogotá D.C."
            },
            "metadata": {
              "external_id": "${CO_CUSTOMER_REFERENCE}"
            },
            "search": {
              "on_key": "metadata.external_id",
              "on_value": "${CO_CUSTOMER_REFERENCE}",
              "update": false
            }
          },
          "expectedHttp": [
            200,
            201
          ],
          "save": {
            "CLIENT_ID": "data.id"
          },
          "verify": [
            "data.livemode == false",
            "Existing search result matches the intended approved fiscal recipient; update:false does not refresh it"
          ]
        },
        {
          "operationId": "createInvoicesIncome",
          "method": "POST",
          "path": "/invoices/income",
          "body": {
            "client": {
              "id": "${CLIENT_ID}"
            },
            "currency": "COP",
            "exchange_rate": 1,
            "use": "G03",
            "payment_form": "03",
            "payment_method": "PUE",
            "items": [
              {
                "description": "One service for the Colombian test invoice",
                "product_key": "80101500",
                "unit_key": "E48",
                "quantity": 1,
                "unit_price": 100000,
                "taxes": [
                  {
                    "type": "IVA",
                    "rate": 0.19,
                    "inclusive": false,
                    "withholding": false,
                    "factor": "Tasa"
                  }
                ]
              }
            ],
            "automation_type": "none",
            "send_email": false,
            "ignore_emails": true,
            "idempotency_key": "${CO_ORDER_REFERENCE}",
            "metadata": {
              "external_id": "${CO_ORDER_REFERENCE}"
            }
          },
          "expectedHttp": [
            200
          ],
          "save": {
            "INVOICE_ID": "data.uuid"
          },
          "verify": [
            "data.status == valid",
            "data.livemode == false",
            "data.currency == COP",
            "data.total == 119000 for this example"
          ]
        },
        {
          "operationId": "getInvoicesIncomeById",
          "method": "GET",
          "path": "/invoices/income/${INVOICE_ID}",
          "expectedHttp": [
            200
          ],
          "verify": [
            "data.client.id matches CLIENT_ID",
            "data.status == valid and livemode == false",
            "currency and totals match the reviewed request"
          ]
        }
      ],
      "unknownOutcome": {
        "operationId": "getInvoicesIncome",
        "method": "GET",
        "path": "/invoices/income",
        "query": {
          "idempotency_key": "${CO_ORDER_REFERENCE}"
        },
        "verify": [
          "Do not combine this lookup with metadata filters",
          "Compare returned client, mode, currency and total with intended request",
          "Zero matches does not prove provider issuance failed"
        ],
        "action": "Keep the same reference; ask support to reconcile ambiguous provider state before another issuance attempt. Do not assume Mexican PAC retry guarantees."
      }
    },
    {
      "id": "mexico-cancellation",
      "guide": "/recipes/cancellation",
      "countryScope": "MX",
      "verification": {
        "level": "source-reviewed",
        "date": "2026-10-08",
        "liveExecuted": false,
        "evidence": "/verification#source-review-and-offline-contract-checks"
      },
      "prerequisites": [
        "Issued Mexican income CFDI from intended team and matching key mode",
        "Explicit authorization and true cancellation motive",
        "This example motive 02 means issued with errors without replacement; use motive 01 plus substitution_uuid when applicable."
      ],
      "steps": [
        {
          "operationId": "getInvoicesIncomeById",
          "method": "GET",
          "path": "/invoices/income/${INVOICE_UUID}",
          "expectedHttp": [
            200
          ],
          "verify": [
            "Confirm team, client, amount and mode",
            "If status is already canceled, reconcile and stop without another DELETE"
          ]
        },
        {
          "operationId": "cancelInvoice",
          "method": "DELETE",
          "path": "/invoices/${INVOICE_UUID}",
          "body": {
            "motive": "02"
          },
          "expectedHttp": [
            200
          ],
          "verify": [
            "Response cancellation_status is at top level, not in data",
            "Request acceptance alone does not establish persisted cancellation"
          ]
        },
        {
          "operationId": "getInvoicesIncomeById",
          "method": "GET",
          "path": "/invoices/income/${INVOICE_UUID}",
          "expectedHttp": [
            200
          ],
          "verify": [
            "Completion requires persisted data.status == canceled",
            "Nested cancellation fields can be absent; absence does not prove completion"
          ]
        }
      ],
      "polling": {
        "method": "GET",
        "maximumImmediateReads": 3,
        "secondsBetweenReads": 30,
        "writeRetries": 0,
        "whenNotComplete": "Preserve request evidence and arrange a later read or owner/support reconciliation. GET returns stored state, not a fresh SAT query."
      },
      "unknownOutcome": {
        "action": "After timeout or server error read the same invoice and reconcile with the provider before repeating DELETE. No idempotency key is documented."
      },
      "notes": [
        "Colombian annulment can leave the original invoice valid and is not covered by this workflow.",
        "Pending live cancellations are scheduled for reconciliation at 00:00, 08:00 and 16:00 America/Mexico_City; test invoices are excluded from that sweep.",
        "Built-in Mexican test RFCs receive a locally simulated accepted Prodigia cancellation; other Prodigia test cancellations request its accepted test scenario. Neither establishes live SAT acceptance."
      ]
    },
    {
      "id": "record-refund",
      "guide": "/recipes/refund",
      "countryScope": "Shared payment endpoint; illustrative MXN two-decimal example",
      "verification": {
        "level": "staging-exercised",
        "date": "2026-10-08",
        "environment": "gigstackprodev; livemode false",
        "issuerCountry": "MX",
        "scope": "Record-only refund; processorAlternative not executed",
        "evidence": "/verification#additional-record-only-refund-check"
      },
      "prerequisites": [
        "Succeeded payment from intended team and matching mode",
        "Explicit authorization to record MXN116 already returned through another process",
        "Read prior refunds and ensure this refund is not already recorded",
        "Serialize refund attempts for the same payment",
        "Check published refund Journeys and team automatic refund settings even with automation_type none; for test runs use a fresh synthetic payment without fiscal associations."
      ],
      "steps": [
        {
          "operationId": "getPaymentsById",
          "method": "GET",
          "path": "/payments/${PAYMENT_ID}",
          "expectedHttp": [
            200
          ],
          "save": {
            "PREVIOUS_REFUNDED_MINOR_UNITS": "data.total_refunded"
          },
          "verify": [
            "data.status == succeeded",
            "data.currency == MXN for this example",
            "Remaining currency units = data.total minus data.total_refunded/100; missing total_refunded is 0",
            "Remaining currency units >= 116 and intended refund not already in data.refunds"
          ]
        },
        {
          "operationId": "createPaymentsByIdRefund",
          "method": "POST",
          "path": "/payments/${PAYMENT_ID}/refund",
          "body": {
            "amount": 116,
            "reason": "Agreed partial refund for order 1042",
            "external_processor_refund": false
          },
          "expectedHttp": [
            200
          ],
          "save": {
            "REFUND_ID": "data.refund.id"
          },
          "verify": [
            "data.refund.total == 116 currency units",
            "data.payment.total_refunded is cumulative minor units, not currency units",
            "Internal refund status succeeded is not independent confirmation of money settlement"
          ]
        },
        {
          "operationId": "getPaymentsById",
          "method": "GET",
          "path": "/payments/${PAYMENT_ID}",
          "expectedHttp": [
            200
          ],
          "verify": [
            "data.refunds contains REFUND_ID with total 116 and intended reason",
            "data.total_refunded equals prior cumulative minor units plus 11600"
          ]
        }
      ],
      "unknownOutcome": {
        "action": "Read payment and refund history; reconcile with external money-return evidence. Do not blindly repeat POST; this endpoint has no documented idempotency key."
      },
      "processorAlternative": {
        "guide": "/recipes/refund#if-you-intend-to-return-money-through-stripe",
        "field": "external_processor_refund",
        "value": true,
        "requirements": [
          "Eligible original Stripe PaymentIntent and correct connected account confirmed by owner",
          "Explicit authorization to request processor money movement",
          "Known test webhook routing and notification recipients before a sandbox processor refund; ignore_emails does not suppress every refund notification"
        ],
        "completion": "Verify the corresponding refund in Stripe separately; refund POST does not expose the processor refund ID or final settlement. Do not run a record-only refund and then repeat to send money. Stripe webhook processing can change payment status and append a second representation of the refund; reconcile cumulative amounts with Stripe instead of counting or summing refund-list entries.",
        "verification": {
          "level": "source-reviewed",
          "liveExecuted": false
        }
      }
    }
  ],
  "countryGuides": {
    "shared": "/concepts/shared-fields",
    "MX": "/countries/mexico",
    "COL": "/countries/colombia"
  },
  "verificationPolicy": "Each workflow declares its own evidence. Source-reviewed workflows have not been executed end to end and must not inherit verification from a different country or workflow."
}
