{
  "info": {
    "name": "GiftU Partner API · PARTNER · TEST",
    "description": "Secret-free TEST integration kit for PARTNER.\n\nAdd the one-time API key to a private Postman environment; do not save it in this collection.\n\nThe key selects TEST or LIVE. Confirm the current authentication policy with GiftU: source-IP allowlisting applies when enabled.\n\nEvery partner price is the final gross SAR charge with VAT included, never a net or pre-VAT amount.\n\nBefore purchasing, set partnerReference to a unique, literal reference. Keep that value and the SKU unchanged for retries and reconciliation. Change it only for an intentional new purchase. Dynamic variables such as {{$guid}} must not be used as the reference.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{partnerApiKey}}",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "const rejectRequest = (message) => { pm.execution.skipRequest(); throw new Error(message); };",
          "const environment = pm.collectionVariables.get('environment');",
          "const partnerApiKey = pm.variables.get('partnerApiKey');",
          "if (!partnerApiKey) { rejectRequest('Set partnerApiKey in a private Postman environment.'); }",
          "const expectedPrefix = environment === 'LIVE' ? 'pk_live_' : 'pk_test_';",
          "if (!partnerApiKey.startsWith(expectedPrefix)) { rejectRequest(`Expected a ${environment} API key starting with ${expectedPrefix}.`); }",
          "const partnerReference = pm.variables.get('partnerReference');",
          "if (pm.request.method === 'POST' || pm.request.url.toString().includes('/orders/by-reference/')) {",
          "  if (!partnerReference || partnerReference.includes('REPLACE_WITH_UNIQUE_REFERENCE') || !/^[A-Za-z0-9._:-]{1,100}$/.test(partnerReference)) { rejectRequest('Set partnerReference to a unique literal value (1–100 letters, digits, dots, underscores, colons or hyphens). Keep it unchanged for retries.'); }",
          "}"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "environment",
      "value": "TEST",
      "type": "string"
    },
    {
      "key": "baseUrl",
      "value": "https://mob.gift-o.io/api/partner/v1",
      "type": "string"
    },
    {
      "key": "partnerApiKey",
      "value": "",
      "type": "string"
    },
    {
      "key": "sku",
      "value": "REPLACE_WITH_CATALOG_SKU",
      "type": "string"
    },
    {
      "key": "partnerReference",
      "value": "TEST-SUCCESS:PARTNER:REPLACE_WITH_UNIQUE_REFERENCE",
      "type": "string"
    },
    {
      "key": "orderId",
      "value": "REPLACE_WITH_ORDER_ID",
      "type": "string"
    },
    {
      "key": "statementId",
      "value": "REPLACE_WITH_STATEMENT_ID",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Connectivity",
      "item": [
        {
          "name": "Ping",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/ping",
            "description": "Verify bearer authentication under the deployment’s current network policy."
          }
        }
      ]
    },
    {
      "name": "Catalog",
      "item": [
        {
          "name": "List products",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/products?page=1&size=20",
            "description": "List current eligible products."
          }
        },
        {
          "name": "Get product",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/products/{{sku}}",
            "description": "Read the current product snapshot."
          }
        },
        {
          "name": "Check price",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/products/{{sku}}/price",
            "description": "Check the final gross SAR price with VAT included. Purchase resolves it again."
          }
        }
      ]
    },
    {
      "name": "Finance",
      "item": [
        {
          "name": "Get balance",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/balance",
            "description": "Read the authoritative purchasing position."
          }
        },
        {
          "name": "List ledger",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/ledger?page=1&size=20",
            "description": "Page immutable partner ledger entries."
          }
        }
      ]
    },
    {
      "name": "Orders",
      "item": [
        {
          "name": "Purchase one card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"partnerReference\": \"{{partnerReference}}\",\n  \"sku\": \"{{sku}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": "{{baseUrl}}/orders",
            "description": "Set partnerReference to a unique literal value before the first purchase. It is the case-sensitive idempotency identity. After an ambiguous response, resend the exact same body; keep both partnerReference and sku unchanged. Change the reference only for an intentional new purchase. Do not add an Idempotency-Key header."
          }
        },
        {
          "name": "List orders",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/orders?page=1&size=20",
            "description": "Page partner orders."
          }
        },
        {
          "name": "Get order by reference",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/orders/by-reference/{{partnerReference}}",
            "description": "Reconcile an ambiguous purchase by its stable reference."
          }
        },
        {
          "name": "Get order by ID",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/orders/{{orderId}}",
            "description": "Poll PROCESSING using pollAfterSeconds."
          }
        }
      ]
    },
    {
      "name": "Statements",
      "item": [
        {
          "name": "List statements",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/statements?page=1&size=20",
            "description": "Page monthly statements."
          }
        },
        {
          "name": "Get statement",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": "{{baseUrl}}/statements/{{statementId}}",
            "description": "Read one monthly statement."
          }
        }
      ]
    }
  ]
}
