{
  "manifest_version": "1.0.0",
  "template": {
    "id": "7846020c-de59-4e11-bb7f-0dc1078e64bd",
    "slug": "square-pickup-storefront",
    "name": "Square Pickup Storefront",
    "description": "Square pickup ecommerce starter (RC); developer-led sandbox setup.",
    "url": "https://railway.com/deploy/square-pickup-storefront"
  },
  "status": "unvalidated",
  "validated_at": null,
  "success_rate_30d": null,
  "services": [
    {
      "name": "Postgres",
      "source": {
        "image": "ghcr.io/railwayapp-templates/postgres-ssl:18"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "http": false
    },
    {
      "name": "square-pickup-storefront",
      "source": {
        "repo": "https://github.com/sparkpressstudios/square-pickup-storefront"
      },
      "needs_volume": false,
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "PGDATA",
      "service": "Postgres",
      "description": "Persistent PostgreSQL data directory beneath the preserved /var/lib/postgresql/data volume mount. Keep aligned with the Railway PostgreSQL image.",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/postgresql/data/pgdata"
    },
    {
      "key": "PGHOST",
      "service": "Postgres",
      "description": "Railway private hostname of this database service; keep the runtime reference and do not expose PostgreSQL publicly.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGPORT",
      "service": "Postgres",
      "description": "PostgreSQL internal port 5432; referenced by the private connection URL.",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "PGUSER",
      "service": "Postgres",
      "description": "Reference to POSTGRES_USER; must match the database login.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGDATABASE",
      "service": "Postgres",
      "description": "Reference to POSTGRES_DB; the database used by the merchant application.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGPASSWORD",
      "service": "Postgres",
      "description": "Reference to the deployment-generated POSTGRES_PASSWORD; do not paste or publish a real password.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "POSTGRES_DB",
      "service": "Postgres",
      "description": "Initial database name for this dedicated merchant installation.",
      "secret": false,
      "strategy": "default",
      "default": "merchant"
    },
    {
      "key": "DATABASE_URL",
      "service": "Postgres",
      "description": "Private PostgreSQL connection URL assembled from this service's defaults. The app references Postgres.DATABASE_URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "POSTGRES_USER",
      "service": "Postgres",
      "description": "Database login initialized by the PostgreSQL image; kept consistent through references.",
      "secret": false,
      "strategy": "default",
      "default": "postgres"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "Postgres",
      "description": "Random per-deployment database password expression, evaluated by Railway only during deployment. Keep private.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "MERCHANT_NAME",
      "service": "square-pickup-storefront",
      "description": "Your reviewed storefront business name, nonempty, maximum 100 characters.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "PUBLIC_ORIGIN",
      "service": "square-pickup-storefront",
      "description": "Approved planned HTTPS origin only, no path/query/fragment. No public domain during setup hold; verify exact domain and webhook URL before cutover.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "STARTER_DATASET",
      "service": "square-pickup-storefront",
      "description": "Selects the merchant catalog runtime, not synthetic demo data. Keep merchant-catalog-v1 for this installation.",
      "secret": false,
      "strategy": "default",
      "default": "merchant-catalog-v1"
    },
    {
      "key": "STARTER_STORAGE",
      "service": "square-pickup-storefront",
      "description": "Uses dedicated PostgreSQL for durable merchant orders and recovery state.",
      "secret": false,
      "strategy": "default",
      "default": "postgres"
    },
    {
      "key": "SQUARE_ENVIRONMENT",
      "service": "square-pickup-storefront",
      "description": "Sandbox only for initial installation and acceptance; do not change to production without merchant-specific readiness.",
      "secret": false,
      "strategy": "default",
      "default": "sandbox"
    },
    {
      "key": "SQUARE_LOCATION_ID",
      "service": "square-pickup-storefront",
      "description": "The approved Square Sandbox location belonging to your sandbox seller.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "BUYER_BOOTSTRAP_MODE",
      "service": "square-pickup-storefront",
      "description": "Bounded, non-serving operator setup hold. Remove all BUYER_BOOTSTRAP_* variables during documented normal-runtime cutover.",
      "secret": false,
      "strategy": "default",
      "default": "manual-ssh-only-v1"
    },
    {
      "key": "MERCHANT_DATABASE_URL",
      "service": "square-pickup-storefront",
      "description": "Private reference to Postgres.DATABASE_URL. Do not replace with a public database URL or expose it to client code.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MERCHANT_PICKUP_LABEL",
      "service": "square-pickup-storefront",
      "description": "Reviewed pickup location label, nonempty, maximum 100 characters.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "SQUARE_APPLICATION_ID",
      "service": "square-pickup-storefront",
      "description": "Your approved Square Sandbox application ID beginning sandbox-sq0idb-. Never a production application.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "BUYER_BOOTSTRAP_EXPIRES_AT",
      "service": "square-pickup-storefront",
      "description": "Owner-approved UTC ISO deadline, future and no more than one hour after startup. Manual setup only; do not extend silently. PostgreSQL/storage charges continue.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "BUYER_BOOTSTRAP_PROJECT_ID",
      "service": "square-pickup-storefront",
      "description": "Runtime project identity reference used by the setup hold; no hard-coded pilot project ID.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "BUYER_BOOTSTRAP_SERVICE_ID",
      "service": "square-pickup-storefront",
      "description": "Runtime service identity reference used by the setup hold; no hard-coded pilot service ID.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MERCHANT_ADMIN_SESSION_KEY",
      "service": "square-pickup-storefront",
      "description": "Per-deployment canonical 32-byte base64url session key expression. Railway evaluates it on deployment; never publish the resulting key.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "SQUARE_SANDBOX_MERCHANT_ID",
      "service": "square-pickup-storefront",
      "description": "The approved sandbox seller matching the application, location and token.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "SQUARE_SANDBOX_ACCESS_TOKEN",
      "service": "square-pickup-storefront",
      "description": "Your dedicated Square Sandbox access token. Enter privately in Railway; never copy into source, chat, logs or browser variables.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "MERCHANT_PICKUP_INSTRUCTIONS",
      "service": "square-pickup-storefront",
      "description": "Reviewed customer pickup instructions, nonempty, maximum 500 characters.",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "SQUARE_MERCHANT_WEBHOOK_PATH",
      "service": "square-pickup-storefront",
      "description": "Signed merchant webhook path. Align the exact HTTPS origin plus this path with your Square Sandbox subscription.",
      "secret": false,
      "strategy": "default",
      "default": "/api/commerce/webhooks"
    },
    {
      "key": "BUYER_BOOTSTRAP_ENVIRONMENT_ID",
      "service": "square-pickup-storefront",
      "description": "Runtime environment identity reference used by the setup hold; no hard-coded pilot environment ID.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "SQUARE_SANDBOX_REQUESTS_ENABLED",
      "service": "square-pickup-storefront",
      "description": "Permits Sandbox provider calls only in the configured merchant runtime; the initial setup hold itself makes no provider calls.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "SQUARE_MERCHANT_COMMERCE_ENABLED",
      "service": "square-pickup-storefront",
      "description": "Selects merchant commerce behavior after manual schema/admin setup and explicit runtime cutover.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "SQUARE_PRODUCTION_PAYMENTS_ENABLED",
      "service": "square-pickup-storefront",
      "description": "Keep false throughout Sandbox installation and acceptance. Real payments require separate merchant-specific readiness and activation.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "SQUARE_SANDBOX_WEBHOOK_SIGNATURE_KEY",
      "service": "square-pickup-storefront",
      "description": "Private sandbox webhook signing key for the exact approved HTTPS origin plus /api/commerce/webhooks.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "square-pickup-storefront"
      }
    },
    "cli": "railway deploy --template square-pickup-storefront",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "7846020c-de59-4e11-bb7f-0dc1078e64bd",
            "serializedConfig": {
              "services": {
                "009b9099-253f-4e9c-b026-31faf0c97c3d": {
                  "name": "Postgres",
                  "source": {
                    "image": "ghcr.io/railwayapp-templates/postgres-ssl:18"
                  },
                  "variables": {
                    "PGDATA": {
                      "description": "Persistent PostgreSQL data directory beneath the preserved /var/lib/postgresql/data volume mount. Keep aligned with the Railway PostgreSQL image.",
                      "defaultValue": "/var/lib/postgresql/data/pgdata"
                    },
                    "PGHOST": {
                      "description": "Railway private hostname of this database service; keep the runtime reference and do not expose PostgreSQL publicly.",
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "PGPORT": {
                      "description": "PostgreSQL internal port 5432; referenced by the private connection URL.",
                      "defaultValue": "5432"
                    },
                    "PGUSER": {
                      "description": "Reference to POSTGRES_USER; must match the database login.",
                      "defaultValue": "${{POSTGRES_USER}}"
                    },
                    "PGDATABASE": {
                      "description": "Reference to POSTGRES_DB; the database used by the merchant application.",
                      "defaultValue": "${{POSTGRES_DB}}"
                    },
                    "PGPASSWORD": {
                      "description": "Reference to the deployment-generated POSTGRES_PASSWORD; do not paste or publish a real password.",
                      "defaultValue": "${{POSTGRES_PASSWORD}}"
                    },
                    "POSTGRES_DB": {
                      "description": "Initial database name for this dedicated merchant installation.",
                      "defaultValue": "merchant"
                    },
                    "DATABASE_URL": {
                      "description": "Private PostgreSQL connection URL assembled from this service's defaults. The app references Postgres.DATABASE_URL.",
                      "defaultValue": "postgresql://${{PGUSER}}:${{PGPASSWORD}}@${{PGHOST}}:${{PGPORT}}/${{PGDATABASE}}"
                    },
                    "POSTGRES_USER": {
                      "description": "Database login initialized by the PostgreSQL image; kept consistent through references.",
                      "defaultValue": "postgres"
                    },
                    "POSTGRES_PASSWORD": {
                      "description": "Random per-deployment database password expression, evaluated by Railway only during deployment. Keep private.",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    }
                  },
                  "volumeMounts": {
                    "009b9099-253f-4e9c-b026-31faf0c97c3d": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  }
                },
                "97fca091-12f6-40c6-883c-d171a7541137": {
                  "name": "square-pickup-storefront",
                  "deploy": {
                    "startCommand": "node scripts/merchant-bootstrap-hold.mjs",
                    "preDeployCommand": [
                      "node scripts/check-setup.mjs --profile merchant-sandbox"
                    ],
                    "restartPolicyType": "NEVER"
                  },
                  "source": {
                    "repo": "sparkpressstudios/square-pickup-storefront"
                  },
                  "variables": {
                    "MERCHANT_NAME": {
                      "description": "Your reviewed storefront business name, nonempty, maximum 100 characters.",
                      "defaultValue": "{{MERCHANT_NAME}}"
                    },
                    "PUBLIC_ORIGIN": {
                      "description": "Approved planned HTTPS origin only, no path/query/fragment. No public domain during setup hold; verify exact domain and webhook URL before cutover.",
                      "defaultValue": "{{PUBLIC_ORIGIN}}"
                    },
                    "STARTER_DATASET": {
                      "description": "Selects the merchant catalog runtime, not synthetic demo data. Keep merchant-catalog-v1 for this installation.",
                      "defaultValue": "merchant-catalog-v1"
                    },
                    "STARTER_STORAGE": {
                      "description": "Uses dedicated PostgreSQL for durable merchant orders and recovery state.",
                      "defaultValue": "postgres"
                    },
                    "SQUARE_ENVIRONMENT": {
                      "description": "Sandbox only for initial installation and acceptance; do not change to production without merchant-specific readiness.",
                      "defaultValue": "sandbox"
                    },
                    "SQUARE_LOCATION_ID": {
                      "description": "The approved Square Sandbox location belonging to your sandbox seller.",
                      "defaultValue": "{{SQUARE_LOCATION_ID}}"
                    },
                    "BUYER_BOOTSTRAP_MODE": {
                      "description": "Bounded, non-serving operator setup hold. Remove all BUYER_BOOTSTRAP_* variables during documented normal-runtime cutover.",
                      "defaultValue": "manual-ssh-only-v1"
                    },
                    "MERCHANT_DATABASE_URL": {
                      "description": "Private reference to Postgres.DATABASE_URL. Do not replace with a public database URL or expose it to client code.",
                      "defaultValue": "${{Postgres.DATABASE_URL}}"
                    },
                    "MERCHANT_PICKUP_LABEL": {
                      "description": "Reviewed pickup location label, nonempty, maximum 100 characters.",
                      "defaultValue": "{{MERCHANT_PICKUP_LABEL}}"
                    },
                    "SQUARE_APPLICATION_ID": {
                      "description": "Your approved Square Sandbox application ID beginning sandbox-sq0idb-. Never a production application.",
                      "defaultValue": "{{SQUARE_APPLICATION_ID}}"
                    },
                    "BUYER_BOOTSTRAP_EXPIRES_AT": {
                      "description": "Owner-approved UTC ISO deadline, future and no more than one hour after startup. Manual setup only; do not extend silently. PostgreSQL/storage charges continue.",
                      "defaultValue": "{{BUYER_BOOTSTRAP_EXPIRES_AT}}"
                    },
                    "BUYER_BOOTSTRAP_PROJECT_ID": {
                      "description": "Runtime project identity reference used by the setup hold; no hard-coded pilot project ID.",
                      "defaultValue": "${{RAILWAY_PROJECT_ID}}"
                    },
                    "BUYER_BOOTSTRAP_SERVICE_ID": {
                      "description": "Runtime service identity reference used by the setup hold; no hard-coded pilot service ID.",
                      "defaultValue": "${{RAILWAY_SERVICE_ID}}"
                    },
                    "MERCHANT_ADMIN_SESSION_KEY": {
                      "description": "Per-deployment canonical 32-byte base64url session key expression. Railway evaluates it on deployment; never publish the resulting key.",
                      "defaultValue": "{{MERCHANT_ADMIN_SESSION_KEY}}"
                    },
                    "SQUARE_SANDBOX_MERCHANT_ID": {
                      "description": "The approved sandbox seller matching the application, location and token.",
                      "defaultValue": "{{SQUARE_SANDBOX_MERCHANT_ID}}"
                    },
                    "SQUARE_SANDBOX_ACCESS_TOKEN": {
                      "description": "Your dedicated Square Sandbox access token. Enter privately in Railway; never copy into source, chat, logs or browser variables.",
                      "defaultValue": "{{SQUARE_SANDBOX_ACCESS_TOKEN}}"
                    },
                    "MERCHANT_PICKUP_INSTRUCTIONS": {
                      "description": "Reviewed customer pickup instructions, nonempty, maximum 500 characters.",
                      "defaultValue": "{{MERCHANT_PICKUP_INSTRUCTIONS}}"
                    },
                    "SQUARE_MERCHANT_WEBHOOK_PATH": {
                      "description": "Signed merchant webhook path. Align the exact HTTPS origin plus this path with your Square Sandbox subscription.",
                      "defaultValue": "/api/commerce/webhooks"
                    },
                    "BUYER_BOOTSTRAP_ENVIRONMENT_ID": {
                      "description": "Runtime environment identity reference used by the setup hold; no hard-coded pilot environment ID.",
                      "defaultValue": "${{RAILWAY_ENVIRONMENT_ID}}"
                    },
                    "SQUARE_SANDBOX_REQUESTS_ENABLED": {
                      "description": "Permits Sandbox provider calls only in the configured merchant runtime; the initial setup hold itself makes no provider calls.",
                      "defaultValue": "true"
                    },
                    "SQUARE_MERCHANT_COMMERCE_ENABLED": {
                      "description": "Selects merchant commerce behavior after manual schema/admin setup and explicit runtime cutover.",
                      "defaultValue": "true"
                    },
                    "SQUARE_PRODUCTION_PAYMENTS_ENABLED": {
                      "description": "Keep false throughout Sandbox installation and acceptance. Real payments require separate merchant-specific readiness and activation.",
                      "defaultValue": "false"
                    },
                    "SQUARE_SANDBOX_WEBHOOK_SIGNATURE_KEY": {
                      "description": "Private sandbox webhook signing key for the exact approved HTTPS origin plus /api/commerce/webhooks.",
                      "defaultValue": "{{SQUARE_SANDBOX_WEBHOOK_SIGNATURE_KEY}}"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {},
  "resources": {
    "expected_services": 2,
    "needs_volume": true
  },
  "generated_at": "2026-10-26T22:14:46.852Z",
  "generator_version": "0.1.0"
}
