SMARTPAY

GCash API Documentation Explained: Endpoints, Request Fields, Signatures and Error Codes (2026)

I lead payment integrations for a company headquartered outside the Philippines, and the first thing every new engineer on my team does when we add a Philippine payment method is type "gcash api documentation" into a search engine. What comes back is confusing: a developer program page with no open reference behind it, blog posts that paraphrase someone else's integration, and a dozen gateway doc sites that each describe GCash slightly differently. Nobody explains which of these you will actually be reading, or how to judge whether a doc set is good enough to build on.

This article is the orientation I now give new hires. It explains where the documentation really lives and who gets access, then walks through what a complete payment API doc set for GCash must contain: the endpoint catalog, the request fields, the status machine, the signature rules, the callback contract, the error table and the go-live checklist. Where a topic deserves its own deep dive we already have one, and I link to it rather than repeat it. Treat this page as the map you read before opening the actual reference.

Where the GCash API Documentation Actually Lives

There is no public, anonymous-access GCash API reference you can read end to end before signing anything. GCash runs a developer and partner program for approved merchants and partners, and the technical material inside it is gated behind onboarding. If you are an approved direct merchant, the reference reaches you through your onboarding contact. For everyone else, and in practice for almost every foreign business, the "GCash documentation" you will read is the doc set of a licensed gateway or aggregator that already holds the GCash connection and exposes it through its own API.

That distinction matters. Through a gateway you never call GCash directly; you call the gateway's unified payment endpoint and select GCash as the channel. The field names, signature scheme, status values and error codes are the gateway's, not GCash's. Two gateways can both offer "GCash native" and document completely different request bodies. So when a colleague says "the GCash API returns status 2 for success," ask whose API they mean.

Before you sign with any provider, ask for three things in writing: the full API reference including the webhook section, the sandbox credentials policy, and the name of the licensed entity on the contract. The commercial and licensing side is covered in our guide to payment gateway integration for global merchants; this page stays technical. A provider that will not share documentation before contract is telling you how the relationship will go after it.

SMARTPAY operates under BSP OPS/EMI authorizations and publishes one doc set that covers GCash, QR Ph, Maya and bank rails behind a single request format. The structure described here follows that reference, but the checklist applies to any gateway's documentation you are evaluating.

The Endpoint Catalog a Complete Doc Set Must Contain

Open the table of contents first. A usable doc set lists its endpoints and tells you, for each one, whether a repeated call is safe and whether the result arrives in the response or later through a callback. If that catalog is missing, build it yourself from the section headings before reading anything else; it is the fastest way to discover that refunds or payout status queries are not documented at all. For the business logic of running collection and payout side by side, read our walkthrough of the GCash collection and payout API; the table below is only about what to look for in the reference.

EndpointPurposeIdempotent?Sync or async resultRead first
Create paymentOpen an order and receive a redirect URL, QR payload or app-invoke parametersShould be, keyed on your order numberCreation is sync; payment outcome is asyncChannel enum, notify URL, expiry
Query paymentPull the current status of an orderYesSyncStatus enum and mapping
RefundReturn funds to the original payer, full or partialShould be, keyed on your refund numberAcceptance is sync; completion is asyncPartial refund rules, callback type
Create payoutSend funds to a GCash account or bank accountMust be, keyed on your batch or item numberAcceptance is sync; completion is asyncAccount fields, balance checks
Query payoutConfirm the final payout stateYesSyncTerminal states and failure reasons
Balance or settlement reportReconcile what was collected, paid out and settledYesSync, often paged or file-basedTimezone and cut-off definitions
Webhook notificationsPush payment, refund and payout events to your serverYour handler must beAsync, retriedSignature, response contract, retry schedule

Two columns deserve a comment. "Idempotent?" is the one most doc sets leave implicit; if the reference does not say what happens when you resend a create request with the same order number, test it in the sandbox on day one. "Sync or async" is where new engineers get burned: a successful HTTP response from create payment means the order exists, not that anyone has paid.

Request Fields: What Each One Means and Where Teams Go Wrong

Every gateway names these fields differently, but a complete reference defines the same dozen concepts. Here is what each means and the mistake we see most often against it.

  • Merchant identifier. Issued per environment. The most common production-only failure is a sandbox identifier left in a config file.
  • Order number. Your reference, unique per merchant. The doc should state length and character rules and whether uniqueness is for all time or per day. Your idempotency depends on this field; see why idempotency keys prevent duplicate payments.
  • Amount. Almost always a string with two decimals, such as "100.00". Sending a float is the classic signature failure: your serializer prints 100 while the gateway hashed "100.00". Confirm whether the unit is pesos or centavos.
  • Currency. A fixed code, "PHP" for local rails, usually part of the signed string.
  • Payment method or channel. An enum separating GCash native (the payer approves inside the GCash app via redirect or app invoke), GCash QR (a code scanned with GCash) and QR Ph (the national standard any participating wallet or bank app can scan). The doc should state which response fields each channel returns; a redirect URL and a QR payload are not interchangeable.
  • Notify URL. Where callbacks go. It must be HTTPS and publicly reachable. If it is part of the signed string, encoding it differently between signing and sending breaks verification.
  • Return URL. Where the payer's browser lands afterwards. User experience only; never treat arrival there as proof of payment.
  • Expiry. How long the order stays payable. Confirm the unit and whether the clock starts at creation or at first payer action.
  • Timestamp and nonce. Replay protection. Confirm the expected timezone; a server in Frankfurt signing with local time against a gateway validating in Manila time is a recurring support ticket.
  • Extra or metadata. Free-form data echoed back in callbacks. Keep it small and never put anything sensitive in it.

A good reference marks each field as required, optional or conditional per channel. If the doc has one flat table for all channels, expect to discover the conditional rules by trial.

Response Bodies and the Order Status Machine

The create-payment response carries two things: a gateway-side transaction identifier and the material you hand to the payer. Store the gateway identifier next to your order number immediately; every later query, refund and dispute references it. The doc should also define a status enum, and this is the part to read most carefully, because your order system becomes a state machine driven by it.

A complete status set looks roughly like this: created (order exists, nobody has acted), pending or user-paid (payer has started or approved, confirmation outstanding), success (funds confirmed), failed (decline, risk rejection or channel error), closed or expired (never paid within expiry), refunding and refunded. Keep the mapping rule simple: only success and refunded trigger business actions, pending states schedule a query, and failed or closed states release inventory. Confirm whether the gateway can ever move an order from failed back to success; most cannot, but a few treat failed as non-terminal for certain channels.

Also check how the doc represents the same status in the create response, the query response and the webhook body. If any one differs in value or type, write a normalizer at the boundary instead of scattering three comparisons through your code.

Signature Rules and the Callback Section

Every reference has a short section titled something like "Signature Algorithm," and it is where most integration time is lost. Read for four facts: how the canonical string is built (usually key-sorted name=value pairs joined by an ampersand), which fields are excluded (the signature itself, often empty values), what encoding is applied before hashing, and where the signature travels (a body field or a header). The cryptographic reasoning and the mistakes we see in merchant code are in our article on signature verification for payment APIs; the snippets below only show the shape most gateway docs describe.

curl -X POST https://apix.example.com/api/pay \
  -H "Content-Type: application/json" \
  -d '{
    "merid": "M100001",
    "tno": "ORDER-20261022-0001",
    "amt": "100.00",
    "currency": "PHP",
    "channel": "GCASH_NATIVE",
    "notify_url": "https://shop.example.com/webhooks/pay",
    "return_url": "https://shop.example.com/thanks",
    "timestamp": "1760000000",
    "sign": "REPLACE_WITH_HMAC"
  }'
const crypto = require('crypto');

function canonical(params) {
  return Object.keys(params)
    .filter(k => k !== 'sign' && params[k] !== '' && params[k] != null)
    .sort()
    .map(k => `${k}=${params[k]}`)
    .join('&');
}

function sign(params, secret) {
  return crypto.createHmac('sha256', secret).update(canonical(params)).digest('hex');
}

async function createPayment(secret) {
  const body = {
    merid: 'M100001',
    tno: 'ORDER-20261022-0001',
    amt: '100.00',                       // string with two decimals, never a float
    currency: 'PHP',
    channel: 'GCASH_NATIVE',
    notify_url: 'https://shop.example.com/webhooks/pay',
    return_url: 'https://shop.example.com/thanks',
    timestamp: String(Math.floor(Date.now() / 1000)),
  };
  body.sign = sign(body, secret);
  const res = await fetch('https://apix.example.com/api/pay', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  return res.json();                     // store the gateway txn id next to tno
}

// Webhook handler: verify first, act idempotently, then acknowledge.
function handleWebhook(req, res, secret) {
  const payload = req.body;
  const given = payload.sign || '';
  const expected = sign(payload, secret);
  if (given.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(given))) {
    return res.status(400).send('bad signature');
  }
  // Look up the order by payload.tno; ignore if already in a final state.
  // Update status, release side effects once, then acknowledge.
  return res.status(200).send('SUCCESS');
}

The callback section is the other half of the contract. It should list the event types you will receive (payment success, payment closed, refund result, payout result), the exact body each carries, the response the gateway expects (often a literal string such as SUCCESS, sometimes an HTTP status alone), and the retry schedule when you fail to respond. Three rules no doc set should let you skip: verify the signature before parsing anything else, make the handler idempotent because retries deliver the same event twice, and never trust the amount in the callback over the amount you stored. The event contract and throttling behaviour are covered in our guide to payment gateway webhooks and rate limits, and the receiver side in our article on webhook retry design.

Error Codes: Reading the Table Like a Runbook

The error table is the part of the reference you will reread most after launch, so judge it by whether each row tells you what to do, not just what went wrong. Codes vary by gateway; the classes below are the ones a complete doc set must cover, and the action column is how our runbook treats each.

Error classWhat it usually meansRetry?What to do
Parameter errorMissing or malformed field, wrong amount format, unknown channel enumNoFix the request; log the field the gateway names
Signature errorCanonical string or secret mismatchNoCompare your canonical string with the doc's example byte by byte; check environment keys
Duplicate orderOrder number already usedNoQuery the existing order instead of creating a new one
Channel unavailableGCash or the rail is in maintenance or degradedYes, with backoffOffer another channel at checkout; alert operations
Risk rejectedThe gateway or wallet risk engine declined the payer or the merchantNoNever retry automatically; show a neutral message; review patterns weekly
Insufficient balanceThe payout account lacks funds for the batchAfter top-upPause the batch; reconcile the balance report before resubmitting
Order not foundWrong environment, wrong identifier or an expired order that was purgedNoConfirm which identifier the query expects; check sandbox versus production
System or timeoutThe gateway did not answer in timeYes, via queryNever re-create; query by order number until a terminal state appears

The pattern across the table is that almost nothing should be retried blindly. The one safe reflex is "when in doubt, query." How to structure that in code, including the timeout case, is the subject of our article on payment API error handling.

Sandbox and Go-Live Checklist

The last section of a good reference describes the sandbox: how to obtain credentials, which scenarios can be simulated (success, decline, expiry, refund, payout failure) and how the sandbox differs from production. Read the differences list twice. Typical gaps are that sandbox signature checks are more forgiving, that callbacks fire faster or are not retried, and that some error classes cannot be triggered. Our detailed walkthrough is sandbox testing before going live in the Philippines; the condensed checklist we require before flipping the production flag is below.

  • Every endpoint in the catalog has been called from the production codebase against the sandbox, not from a throwaway script.
  • The callback handler has processed a duplicate delivery without a double side effect.
  • A deliberately wrong signature has been rejected and logged.
  • Order expiry has been observed end to end, including inventory release.
  • A partial refund has completed and reconciled against the settlement report.
  • Production credentials live in a secrets manager, separate from sandbox ones, with the environment name in the key.
  • A small live transaction has been made, refunded and reconciled before any marketing traffic is sent.

Frequently Asked Questions

Is there a public GCash API documentation I can read without an account?

Not in the sense of an open reference you can build against anonymously. GCash provides technical material to approved merchants and partners after onboarding. Most developers outside the Philippines end up reading a licensed gateway's documentation, where GCash is one channel among several.

Do I need a Philippine entity to get API access?

For a direct GCash merchant relationship, local onboarding requirements apply and a Philippine entity is the normal path. Through a licensed gateway the entity question is settled on the commercial side, and your technical access is the gateway's API. Either way, ask which licensed entity is on the contract before you read a single endpoint.

What is the difference between GCash native and QR Ph in the documentation?

GCash native means the payer approves inside the GCash app, reached by redirect or app invoke, and only GCash users can pay. QR Ph is the national QR standard; the payer can scan it with GCash or any other participating wallet or bank app. In the reference they are different channel enum values with different response fields, and QR Ph callbacks may identify the paying institution rather than GCash.

Why does my signature work in the sandbox but fail in production?

Nearly always one of four things: a sandbox secret still in the production config, a canonical-string rule that differs between environments and was mentioned in a footnote, amount formatting that changed when real prices replaced test values, or a timezone issue the more tolerant sandbox ignored. Reproduce the doc's signature example byte for byte with your production code before suspecting anything else.

How do I test webhooks on a local machine?

Expose your local port through a tunnelling tool so the gateway can reach an HTTPS URL, point the sandbox notify URL at it, and log the raw body and headers before any parsing. Save a few real sandbox payloads as fixtures; they become regression tests for your signature and idempotency logic.

What should I do when a documented field is missing from the actual response?

Treat the behaviour as the truth and the doc as a claim. Log the discrepancy, ask the provider to confirm which is current, and code defensively so a missing optional field never crashes the handler. Repeated discrepancies tell you something about the provider's change management.

Where to Go From Here

Before you write a line of integration code, obtain the full reference and check it against this page: an endpoint catalog with idempotency and sync-versus-async stated, a field table with per-channel conditions, a status enum consistent across responses and callbacks, a signature section you can reproduce from its own example, an error table with actions, and a sandbox section that lists its differences from production. A doc set that passes those checks will carry you through launch; one that fails two of them will cost weeks in support tickets. If you are integrating GCash from outside the Philippines and want to walk through a reference built on this structure, reach out on Telegram at @LouisSMARTPAY or by email at [email protected].

相关推荐