GCash Collection and Payout API: A Technical Path for Foreign Merchants in the Philippines
GCash is the default wallet rail for most Philippine consumers, and increasingly for business-to-business payouts as well. A foreign company selling into the Philippines, running a marketplace with Filipino sellers, or paying remote staff and affiliates based in the country will eventually need two separate but related integrations: a collection API to receive money from GCash users, and a payout API to send money back out to GCash accounts. These are not the same endpoint, they do not share a single webhook contract, and treating them as interchangeable is one of the more common mistakes among teams that are new to the Philippine market. This article walks through how the two-directional flow actually works end to end — request structure, signing, asynchronous callbacks for both directions — and why most foreign companies integrate through a licensed aggregator rather than negotiating a direct enterprise relationship with the wallet operator.
Any entity that collects funds from the public and later disburses them is, under Bangko Sentral ng Pilipinas (BSP) rules, carrying out activity that sits under either an Operator of Payment System (OPS) registration or an Electronic Money Issuer (EMI) license. A foreign company routing GCash collection and payout traffic through its own infrastructure, without going through a BSP OPS/EMI-licensed partner, is taking on compliance exposure that it typically has no Philippine legal entity to carry.
Why the Flow Has to Be Two-Directional
Most foreign merchants start the conversation only thinking about collection, because that is the revenue-facing half of the problem: how do I get paid by a GCash user who wants to buy from me. Payout tends to get added later, usually under operational pressure rather than as a planned feature. A marketplace needs to settle its Filipino sellers. A remote-first company needs to pay contractors who do not hold a foreign bank account. An affiliate or referral program needs to send commissions to partners on the ground. A platform needs to issue a refund that a plain collection API has no mechanism to reverse.
- E-commerce refunds, cashbacks, and loyalty payouts
- Marketplace or gig-platform settlement to local sellers, drivers, or freelancers
- Payroll or contractor payments for Philippine-based remote staff
- Affiliate and referral commission disbursement
Because collection and payout sit on different internal rails — one pulls funds into an account, the other pushes funds out — a provider that only supports one direction will eventually force the merchant into a second, unrelated integration with its own credentials, its own webhook shape, and its own reconciliation report. Evaluating a provider on both capabilities from day one avoids that second project later.
How the GCash Collection API Works
The collection flow starts on the merchant's backend, not in the GCash app. The merchant creates an internal order, then calls the collection endpoint with a set of parameters that commonly include a merchant ID, a unique order number, the amount and currency, a short description, a webhook (notify) URL, and a signature computed over the other fields. The response typically returns a payment URL, a QR code payload, or a deeplink, depending on which channel the customer is on — redirect inside the GCash app, a scannable QR code at a physical or virtual checkout, or an H5 page for a mobile browser session.
Once the customer completes the payment on their side, the funds settle into the licensed partner's pooled collection account, and an asynchronous notification is posted to the merchant's notify_url. A production-grade integration should never rely on the webhook alone — it should also be able to actively query order status by order number, since any webhook can be delayed, dropped, or arrive out of order. A detailed walkthrough of this sequence, including the exact parameter list and status codes, is covered in this step-by-step GCash collection API integration walkthrough.
curl -X POST https://api.paysmartph.com/v1/gcash/collect \
-H "Content-Type: application/json" \
-d '{
"merchant_id": "MCH100234",
"order_no": "ORD-20261003-00981",
"amount": "100.00",
"currency": "PHP",
"subject": "Order #00981",
"notify_url": "https://merchant.example.com/callbacks/gcash/collect",
"timestamp": "1696320000",
"sign": "9f3a1c7e5b2d4a6f8c1e0d3b5a7f9c2e"
}'
How the GCash Payout API Works
Payout is structurally different. The merchant submits a disbursement request containing a merchant ID, a payout reference that also functions as an idempotency key, the recipient's GCash-linked mobile number or account identifier, the amount and currency, a purpose or description field, a notify_url, and a signature. The initial response is an acknowledgement that the request was accepted into a queue — it is not the final outcome. The final outcome, whether successful or failed, arrives through the payout webhook or through an explicit status query against the same payout reference.
The idempotency key matters more here than on the collection side, because a payout moves money out of the merchant's balance. If a network timeout causes the merchant's system to retry a request, it must resend the same payout reference rather than generating a new one, so the backend can recognize the retry and avoid disbursing twice for a single intended payment. For recurring runs such as payroll or commission cycles, batching reference numbers and amounts together through a single submission is usually more reliable than firing one request per recipient; the mechanics of file formats, per-batch limits, and failure retries for that pattern are covered in this batch payout methods for payroll and commission disbursement in the Philippines.
Authentication and Signature Verification Across Both Directions
Both the collection and payout APIs rely on a merchant credential pair: a merchant ID and a secret key that never leaves the server side. Every outbound request is signed by sorting the request parameters, concatenating them with the secret key, and hashing the result — commonly with HMAC-SHA256 — with a timestamp or nonce included specifically to prevent an intercepted request from being replayed later. The same discipline applies in reverse: every inbound webhook must be re-verified against its own signature before the payload is trusted, rather than assumed safe because it arrived on the expected URL.
One practice worth adopting early is using separate signing keys for the collection credential and the payout credential, even if both sit under the same merchant account. A leaked collection key lets an attacker forge a fake "paid" notification, which is contained and reversible. A leaked payout key can be used to request a real disbursement, which is a direct financial loss. Splitting the keys limits the blast radius of either leak. The mechanics of this verification step, along with how inbound notifications are structured, are also documented in this guide to GCash merchant webhook callbacks and signature verification.
const crypto = require('crypto');
function verifyCallback(payload, secretKey) {
const { sign, ...fields } = payload;
const sorted = Object.keys(fields).sort()
.map((k) => `${k}=${fields[k]}`)
.join('&');
const expected = crypto
.createHmac('sha256', secretKey)
.update(sorted)
.digest('hex');
return expected === sign;
}
app.post('/callbacks/gcash/payout', (req, res) => {
if (!verifyCallback(req.body, process.env.GCASH_PAYOUT_SECRET)) {
return res.status(400).send('invalid signature');
}
// persist payout status, then acknowledge
res.status(200).send('SUCCESS');
});
Webhook Callbacks: Collection Events vs Payout Events
Treating the two webhook contracts as one is where a surprising number of integrations go wrong. A collection callback is tied to a customer-facing action with a bounded window — the shopper either completes the payment on their session or the order expires — so the possible status values are limited and resolve relatively quickly. A payout callback is tied to backend processing that depends on downstream rail behavior, and it can carry intermediate states before a final success or failure is posted. Both directions need idempotent handling on the receiving end, because any webhook sender will retry delivery if it does not get a clean acknowledgement, and both benefit from a periodic reconciliation job that cross-checks the merchant's own records against a status-query API rather than trusting webhook delivery alone.
| Aspect | Collection Callback | Payout Callback |
|---|---|---|
| Triggering action | Customer completes or abandons payment | Backend disbursement reaches a final state |
| Typical status values | paid, pending, closed, expired | processing, success, failed, returned |
| Who controls timing | The paying customer | The disbursement rail and risk checks |
| Safety net needed | Order status query by order_no | Payout status query by payout reference |
| Risk of duplication | Low (idempotent order state) | Higher — requires strict idempotency key reuse on retry |
Direct Integration vs a Licensed Aggregator: Why Foreign Companies Choose an Intermediary
A GCash enterprise relationship is issued to a Philippine-registered business with a local bank account and a compliance officer able to respond to BSP inquiries directly. A foreign company without a Philippine subsidiary cannot hold that relationship on its own — it has to route traffic through an entity that already holds the BSP OPS/EMI license and the direct wallet relationship, and that is willing to accept responsibility for KYC, AML screening, and settlement on the merchant's behalf.
This is the practical reason most foreign companies do not attempt a direct integration. It is not that the API itself is hard — the request and signature pattern described above is fairly standard — it is that the account behind the API requires a local legal entity, a local bank account, and an ongoing compliance relationship with a Philippine regulator, none of which a foreign company has by default. A licensed aggregator absorbs all three, and in exchange offers a single integration surface that already covers both collection and payout, instead of the merchant negotiating two separate relationships on two separate timelines. Onboarding through an aggregator is also generally faster, since the aggregator's own merchant risk review is lighter than a full enterprise wallet application built around a brand-new foreign entity with no Philippine operating history. More detail on what the OPS designation specifically covers, as opposed to the EMI designation, is laid out in this explanation of what a BSP Operator of Payment System (OPS) license actually covers.
| Requirement | Direct Enterprise Integration | Licensed Aggregator |
|---|---|---|
| Philippine legal entity | Required | Not required for the merchant |
| Local PH bank account | Required | Handled by the aggregator |
| BSP OPS/EMI license held by | The merchant itself | The aggregator |
| Collection support | Yes, after full enterprise approval | Yes, under one merchant account |
| Payout support | Separate negotiation, often with a bank partner | Same merchant account, same credentials |
| Compliance/KYC ownership | The merchant | The licensed aggregator |
Settlement, Reconciliation, and Operational Readiness
Settlement timing depends on the rail and on the aggregator's own risk policy, and it is reasonable to expect same-day or next-business-day cycles rather than a single fixed number that applies to every merchant and every volume tier. What matters more for a foreign merchant going live is the reconciliation discipline around both directions: every collection order and every payout reference should be matched, on a schedule, against the aggregator's settlement report and against the merchant's own ledger, rather than relying purely on whichever webhooks happened to arrive. Build retry-safe code on both sides — a collection order query and a payout status query that can be called repeatedly without side effects — and watch for the handful of error classes that show up most often during integration: signature mismatches, timeouts on the customer-facing session, and insufficient balance on payout requests. A full list of these error codes, with the usual root cause for each, is collected in this reference on common GCash integration error codes and how to troubleshoot them.
Getting Started: What a Foreign Merchant Should Prepare
Before requesting production credentials, a foreign merchant should have its home-country business registration documents ready, a clear description of what is being sold or what the payout flow is for, an estimate of expected volume on both the collection side and the payout side (risk review looks at both separately), and a technical contact who can run a full sandbox cycle — test collection order, test webhook receipt, test payout request, test payout webhook — before any production key is issued. Settlement destination is usually more flexible than merchants expect: it does not have to be a Philippine bank account, since the aggregator's role is precisely to bridge that gap, but it does need to be confirmed and verified before the first live transaction runs.
Can a foreign company apply for a GCash merchant account directly, without a Philippine entity?
Not in the way a locally registered business can. A direct GCash enterprise relationship assumes a Philippine legal entity, a local bank account, and a party able to answer to BSP directly. A foreign company without that local footprint integrates through a BSP OPS/EMI-licensed aggregator instead, which already holds the direct relationship and extends collection and payout access under its own license.
What's the practical difference between a collection callback and a payout callback?
A collection callback reports on a customer-facing payment session that resolves within a bounded window. A payout callback reports on a backend disbursement that depends on downstream rail processing and can pass through more intermediate states before reaching a final success or failure. They use different status enums and should be handled by separate code paths, not one shared handler.
Do collection and payout need separate API credentials?
They can technically share one merchant ID, but using separate signing keys for each direction is the safer pattern. A compromised collection key only allows forging payment notifications, which is contained; a compromised payout key allows requesting real disbursements, which is a direct loss. Separate keys limit the damage from either leak.
What happens if a payout webhook never arrives?
This is exactly why a status-query endpoint exists alongside the webhook. Any integration that only listens for the callback and never actively polls for status on pending payout references will eventually have a disbursement sitting in an unknown state after a dropped notification. A scheduled reconciliation job that queries open payout references closes that gap.
Can one merchant account run both collection and payout from day one?
Usually yes, under a single aggregator relationship, though payout access may go through a separate risk review step even when it sits on the same account, since inbound and outbound flows carry different fraud profiles. It is worth requesting both during onboarding rather than adding payout later as an afterthought.
How does a foreign merchant without a Philippine bank account actually receive settlement?
Through the aggregator's own settlement arrangement, which is the specific gap a licensed partner is built to bridge. The merchant confirms its settlement destination during onboarding, and the aggregator handles the local banking relationship on the Philippine side.
What should be tested in sandbox before switching to production API keys?
At minimum: creating a collection order and confirming the webhook and status-query both agree on the result, creating a payout request and confirming idempotent behavior on a deliberate retry, verifying signatures on both inbound webhook types, and confirming that error responses for common failure cases (bad signature, expired order, insufficient balance) are handled without the integration crashing or double-processing.
GCash collection and payout each carry their own request structure, their own signature discipline, and their own webhook contract — but for a foreign merchant, the harder problem is usually not the API itself, it is the licensing and banking relationship sitting behind it. SMARTPAY operates as a BSP OPS/EMI-licensed aggregator specifically so foreign companies can integrate both directions without first building a Philippine legal entity. To talk through collection and payout volumes for your specific use case, reach the SMARTPAY team on Telegram at @LouisSMARTPAY or by email at [email protected].