Skip to content
API documentationGlobal2Pay

Merchant API IP allowlist ​

The policy lists the public egress IP addresses of your API servers. It does not list your customer's IP, browser IP, webhook destination, or slip-provider allowlist. Keep the existing API key and HMAC signature; this policy adds a source check and does not change the signed canonical request.

Defaults and CIDRs ​

  • LIVE and TEST each have an independent Merchant-self policy. No LIVE list is copied into TEST, and changing one mode does not change the other.
  • The default is disabled, version 0, cidrs: [], updated_at: null.
  • enforced requires 1–32 canonical IPv4/IPv6 CIDRs, sorted as strings with no duplicates. disabled requires an empty list. Use /32 for an IPv4 host and /128 for an IPv6 host; a bare address is not a CIDR.
  • Example: ["198.51.100.0/24", "2001:db 8::/32"]. These documentation ranges are illustrative; use your actual server egress networks.
  • The server rejects /0, host bits such as 198.51.100.1/24, leading-zero IPv4, uppercase or expanded IPv6, zones, and dotted IPv6. Compatible ::/96 and mapped ::ffff/96 source literals are unsupported, including :: and ::1. CIDRs wholly within those ranges are rejected; broader canonical IPv6 networks such as ::/64 remain permitted.

Admission and source trust ​

The service checks the authoritative policy at new request admission, then consumes the HMAC nonce in the same transaction only if admission succeeds. Both policy errors below leave that nonce unconsumed and cause no business effect. Continue using a fresh PG-Nonce for each HTTP attempt and retain the same idempotency key for the same intended mutation.

Changing the policy affects later admissions. A request admitted before the change may finish; existing payment instructions and already issued slip capabilities are not canceled by this setting. The slip-upload capability endpoint has its own authentication boundary and does not use this HMAC policy.

Source trust requires qualified direct Cloudflare ingress on the exact API host. The service does not accept X-Forwarded-For, X-Real-IP, an IP in JSON, or caller-supplied Cloudflare headers as proof. Requests forwarded by another Cloudflare Worker, or otherwise lacking proven ingress context, cannot supply a usable source under this profile. They get 503 source_ip_unavailable when the policy is enforced; a disabled policy continues to accept absent context. Do not enable enforcement for a Worker-origin integration expecting header forwarding to establish its original client IP.

CodeHTTPRetryableAction
source_ip_not_allowed403falseCorrect the configured network or server egress.
source_ip_unavailable503trueCheck direct ingress/platform readiness; repeated retries do not make unsupported Worker provenance valid.

The existing route-specific error envelope is retained. A LIVE unavailable response includes Retry-After: 1; TEST IP-policy errors have no Retry-After.

Manage the policy ​

These are same-origin Back Office session operations, separate from Merchant API-key/HMAC endpoints. Both require exact Merchant self in the selected mode, the api_ip_allowlist contract and all three capabilities: api_keys:read_metadata, api_keys:create, api_keys:revoke. White Labels and Agents cannot select a descendant Merchant to impersonate it. Existing key metadata and Owner/WL operations keep their current contracts.

http
GET /v1/bo/api-ip-allowlist
X-PG-BO-Client: 1

GET accepts no query parameters; the current cookie principal selects scope and mode. It returns { "data": <policy> }, a quoted-version ETag, and Cache-Control: private, no-store, no-transform.

http
PUT /v1/bo/api-ip-allowlist
Content-Type: application/json
X-PG-BO-Client: 1
If-Match: "0"
Idempotency-Key: merchant-network-change-001
X-PG-Step-Up-Token: <dedicated-request-bound-assertion>
json
{
  "scope_id": "11110000-0000-4000-8000-000000000004",
  "state": "enforced",
  "cidrs": ["198.51.100.0/24", "2001:db 8::/32"],
  "reason_code": "API_EGRESS_UPDATE"
}

The body has exactly those four fields and is limited to 8192 UTF-8 bytes. If-Match is required: "0" creates, later writes use the current version (0..2147483646). The idempotency key is 8–200 printable non-space ASCII characters. Success returns {data:{status,replayed,http_status:200,policy, request_digest}} and the policy's new ETag. Each new change increments the version; exact retained replay returns the original receipt after current authority and fresh proof checks. Replays do not create another revision.

For enforced, the server must establish an enrolled API host and a valid trusted ingress profile before proof validation or mutation. If unavailable, PUT returns 503 api_ip_allowlist_enforcement_unavailable with no mutation. Saving disabled remains possible with the same normal authority, CAS and fresh proof requirements, even when ingress readiness is unavailable.

Dedicated fresh authentication ​

Start with POST /v1/bo/auth/step-up/api-ip-allowlist. Its proof binds api_ip_allowlist.replace, PUT, the exact canonical path, resource type merchant_api_ip_allowlist, Merchant UUID, expected version, selected mode, raw body digest, idempotency-key digest and canonical request digest. The session is rechecked and OIDC requires fresh authentication within 5 minutes.

This is a distinct family: state pgsit1., assertion pgsia1., callback message paygate:api-ip-allowlist-step-up. The browser must verify the exact popup and origin. API-key, approval and other step-up assertions are not interchangeable. A changed body/version/mode requires a new proof.

For a version conflict, read the current policy and review the change before a new mutation. Keep a request's raw body/idempotency identity stable for an uncertain-outcome retry, while obtaining fresh authentication as required.

เอกสารชุดนี้อิงสัญญา API เวอร์ชัน 2026-08-01