Skip to main content

GCash

Accept payments from GCash, the Philippines' #1 digital wallet with over 86 million users and the country's most widely used cashless payment method.

Overview

User Statistics

User numbers are approximate and based on publicly available information. Actual active user counts may vary.

GCash is the leading mobile wallet in the Philippines, operated by Mynt (Globe Fintech Innovations). It's the go-to payment method for Filipinos, used for everything from bills and remittances to e-commerce and peer-to-peer transfers.

Key Features:

  • Market leader - 86+ million users across the Philippines
  • Fast confirmation - Near real-time payment verification (typically within seconds)
  • High trust - Backed by Globe Telecom and Ant Group
  • Wide adoption - Used by 60%+ of online shoppers
  • Versatile - Bills, shopping, transfers, investments
  • Low friction - Quick MPIN authentication

Supported Region

RegionCurrencyMin AmountMax AmountMonthly Limit
PhilippinesPHP₱1.00₱100,000Varies*

*Monthly limits depend on customer's GCash account verification level

Account Limits by Verification Level

Verification LevelWallet LimitPer TransactionMonthly Limit
Unverified₱100,000₱8,000₱100,000
Semi-Verified (Phone + ID)₱100,000₱50,000₱100,000
Fully Verified (KYC complete)₱500,000₱100,000₱500,000
GSave/GInvest (Banking features)Unlimited₱100,000Unlimited

How It Works

Customer Experience:

  1. Customer selects GCash at checkout
  2. Redirected to GCash authorization page
  3. GCash app opens automatically (deep link on mobile)
  4. Customer reviews payment details
  5. Enters 4-digit MPIN to confirm
  6. Returns to merchant site
  7. Receives SMS confirmation from GCash

Typical completion time: 30-60 seconds

Payment Flow Examples

Mobile Payment Flow:

Mobile Payment Flow

Seamless mobile wallet experience:

  • ❶ Select GCash - Customer taps GCash at mobile checkout
  • ❷ App redirect - Deep link automatically opens GCash app
  • ❸ Review payment - Transaction details displayed (merchant, amount)
  • ❹ Authenticate - Enter 4-digit MPIN to authorize
  • ❺ Payment processed - Funds deducted from GCash wallet
  • ❻ SMS confirmation - Receive transaction confirmation text
  • ❼ Return to merchant - Redirect back to merchant success page

Desktop Payment Flow:

Desktop Payment Flow

QR code scanning for desktop:

  • ❶ Choose GCash - Customer selects GCash payment on desktop
  • ❷ Generate QR - System creates unique GCash payment QR code
  • ❸ Display QR - QR code shown on screen with payment details
  • ❹ Open GCash app - Customer launches GCash on mobile device
  • ❺ Scan QR - Use in-app scanner to capture QR code
  • ❻ Verify details - Payment amount and merchant name shown
  • ❼ Enter MPIN - Authenticate with 4-digit mobile PIN
  • ❽ Confirm - Tap to authorize payment
  • ❾ Success - Desktop shows confirmation, payment complete

Implementation

Step 1: Create GCash Source

curl https://api.omise.co/sources \
-u skey_test_YOUR_SECRET_KEY: \
-d "type=gcash" \
-d "amount=50000" \
-d "currency=PHP"

Response:

{
"object": "source",
"id": "src_test_5rt6s9vah5lkvi1rh9c",
"type": "gcash",
"flow": "redirect",
"amount": 50000,
"currency": "PHP"
}

Step 2: Create Charge and Redirect

app.post('/checkout/gcash', async (req, res) => {
try {
const { amount, order_id, customer_email, customer_mobile } = req.body;

// Validate amount
if (amount < 100) { // ₱1.00 minimum
return res.status(400).json({
error: 'Minimum amount is ₱1.00'
});
}

if (amount > 10000000) { // ₱100,000 maximum
return res.status(400).json({
error: 'Maximum amount is ₱100,000'
});
}

// Create source
const source = await omise.sources.create({
type: 'gcash',
amount: amount,
currency: 'PHP'
});

// Create charge
const charge = await omise.charges.create({
amount: amount,
currency: 'PHP',
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
customer_email: customer_email,
customer_mobile: customer_mobile,
payment_method: 'gcash'
}
});

// Redirect to GCash
res.redirect(charge.authorize_uri);

} catch (error) {
console.error('GCash error:', error);
res.status(500).json({ error: error.message });
}
});

Step 3: Handle Return Callback

app.get('/payment/callback', async (req, res) => {
try {
const chargeId = req.query.charge_id;
const charge = await omise.charges.retrieve(chargeId);

if (charge.status === 'successful') {
await processOrder(charge.metadata.order_id);
res.redirect(`/order-success?order=${charge.metadata.order_id}`);
} else if (charge.status === 'failed') {
res.redirect(`/payment-failed?reason=${charge.failure_message}`);
} else {
res.redirect('/payment-pending');
}
} catch (error) {
res.redirect('/payment-error');
}
});

Step 4: Handle Webhook

app.post('/webhooks/omise', async (req, res) => {
const event = req.body;

if (event.key === 'charge.complete') {
const charge = event.data;

if (charge.source.type === 'gcash') {
if (charge.status === 'successful') {
await fulfillOrder(charge.metadata.order_id);
await sendSMSConfirmation(charge.metadata.customer_mobile);
} else if (charge.status === 'failed') {
await handleFailedPayment(charge.metadata.order_id);
}
}
}

res.sendStatus(200);
});

Complete Implementation Example

const express = require('express');
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

const app = express();
app.use(express.json());

// GCash configuration
const GCASH_CONFIG = {
currency: 'PHP',
minAmount: 100, // ₱1.00
maxAmount: 10000000, // ₱100,000
displayName: 'GCash',
timeout: 15 * 60 * 1000 // 15 minutes
};

// Create GCash payment
app.post('/checkout/gcash', async (req, res) => {
try {
const { amount, order_id, customer_email, customer_mobile, customer_name } = req.body;

// Validate currency
if (req.body.currency && req.body.currency !== 'PHP') {
return res.status(400).json({
error: 'GCash only supports PHP currency'
});
}

// Validate amount
if (amount < GCASH_CONFIG.minAmount) {
return res.status(400).json({
error: `Minimum amount is ₱${GCASH_CONFIG.minAmount / 100}`
});
}

if (amount > GCASH_CONFIG.maxAmount) {
return res.status(400).json({
error: `Maximum amount is ₱${GCASH_CONFIG.maxAmount / 100}`
});
}

// Create source
const source = await omise.sources.create({
type: 'gcash',
amount: amount,
currency: GCASH_CONFIG.currency
});

// Create charge
const charge = await omise.charges.create({
amount: amount,
currency: GCASH_CONFIG.currency,
source: source.id,
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id,
customer_email: customer_email,
customer_mobile: customer_mobile,
customer_name: customer_name,
payment_method: 'gcash'
}
});

// Log for tracking
console.log(`GCash payment initiated: ${charge.id} for order ${order_id}`);

// Return authorization URL
res.json({
authorize_uri: charge.authorize_uri,
charge_id: charge.id
});

} catch (error) {
console.error('GCash error:', error);
res.status(500).json({ error: error.message });
}
});

// Payment callback
app.get('/payment/callback', async (req, res) => {
try {
const charge = await omise.charges.retrieve(req.query.charge_id);

if (charge.status === 'successful') {
res.redirect(`/order-confirmation?order=${charge.metadata.order_id}`);
} else {
res.redirect(`/payment-failed?charge=${req.query.charge_id}`);
}
} catch (error) {
res.redirect('/payment-error');
}
});

// Webhook handler
app.post('/webhooks/omise', async (req, res) => {
const event = req.body;

if (event.key === 'charge.complete' && event.data.source.type === 'gcash') {
const charge = event.data;

if (charge.status === 'successful') {
await fulfillOrder(charge.metadata.order_id);
await sendReceipt(charge.metadata.customer_email, charge);
console.log(`GCash payment successful: ${charge.id}`);
} else {
await cancelOrder(charge.metadata.order_id);
console.log(`GCash payment failed: ${charge.id}`);
}
}

res.sendStatus(200);
});

app.listen(3000);

Refund Support

GCash supports full and partial refunds within 180 days:

// Full refund
const fullRefund = await omise.charges.refund('chrg_test_...', {
amount: 50000 // Full amount
});

// Partial refund
const partialRefund = await omise.charges.refund('chrg_test_...', {
amount: 25000 // Partial amount
});

console.log('Refund status:', fullRefund.status);
Refund Processing

Refunds are processed back to the customer's GCash wallet within 5-7 business days.

Common Issues & Troubleshooting

Issue: Customer doesn't have GCash app

Cause: Customer selected GCash but doesn't have app installed

Solution:

// Display app requirement and download links
function checkGCashApp() {
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);

if (!isMobile) {
alert('GCash is only available on mobile devices.');
return false;
}

// Show app links
const isAndroid = /Android/i.test(navigator.userAgent);
const appLink = isAndroid
? 'https://play.google.com/store/apps/details?id=com.globe.gcash.android'
: 'https://apps.apple.com/ph/app/gcash/id520020791';

showMessage(`GCash app required. <a href="${appLink}">Download here</a>`);
return true;
}

Issue: Insufficient balance

Error: Payment declined - insufficient funds

Solution:

if (charge.failure_code === 'insufficient_balance') {
showMessage(
'Kulang ang GCash balance. Mag-cash in muna o gumamit ng ibang payment method.'
);
showCashInOptions();
}

Issue: Transaction limit exceeded

Error: Transaction exceeds account limit

Solution:

if (charge.failure_code === 'transaction_limit_exceeded') {
showMessage(
'Lumampas sa limit ng iyong GCash account. ' +
'I-verify ang account o gumamit ng ibang payment method.'
);
showVerificationLink();
}

Issue: Payment timeout

Cause: Customer didn't complete payment within 15 minutes

Solution:

const TIMEOUT = 15 * 60 * 1000;

setTimeout(() => {
if (!paymentCompleted) {
showMessage('Nag-timeout ang payment. Subukan ulit.');
enableRetry();
}
}, TIMEOUT);

Best Practices

1. Display in Filipino/Tagalog

<div class="gcash-payment">
<h3>Magbayad gamit ang GCash</h3>
<div class="instructions">
<ol>
<li>Siguruhing nakainstall ang GCash app</li>
<li>May sapat na balance sa GCash wallet</li>
<li>Ide-redirect ka sa GCash app</li>
<li>I-enter ang iyong 4-digit MPIN</li>
</ol>
</div>
<p class="help-text">
Wala pang GCash?
<a href="https://www.gcash.com" target="_blank">Mag-register dito</a>
</p>
</div>

2. Mobile-Only Detection

function validateGCashPayment() {
const userAgent = navigator.userAgent;
const isMobile = /Android|iPhone|iPad|iPod/i.test(userAgent);

if (!isMobile) {
return {
valid: false,
message: 'GCash ay available lang sa mobile devices'
};
}

return { valid: true };
}
function openGCashApp(authorizeUri) {
// Redirect to GCash
window.location = authorizeUri;

// Fallback if app doesn't open
setTimeout(() => {
if (!document.hidden) {
showInstallPrompt();
}
}, 2500);
}

function showInstallPrompt() {
const isAndroid = /Android/i.test(navigator.userAgent);
const downloadUrl = isAndroid
? 'https://play.google.com/store/apps/details?id=com.globe.gcash.android'
: 'https://apps.apple.com/ph/app/gcash/id520020791';

if (confirm('GCash app hindi nakainstall. I-download ngayon?')) {
window.location = downloadUrl;
}
}

4. Amount Formatting

function formatPHP(amount) {
return new Intl.NumberFormat('en-PH', {
style: 'currency',
currency: 'PHP',
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount / 100);
}

// Usage
const displayAmount = formatPHP(50000); // "₱500.00"

5. Show Cash-In Options

<div class="gcash-cash-in">
<h4>Paano mag-cash in sa GCash:</h4>
<ul>
<li><strong>Bank Transfer</strong> - BPI, BDO, UnionBank, etc.</li>
<li><strong>7-Eleven</strong> - CLiQQ Kiosk</li>
<li><strong>Remittance</strong> - Cebuana, M Lhuillier, Palawan</li>
<li><strong>Online Banking</strong> - Instapay, PESONet</li>
<li><strong>GCash Padala</strong> - Bayad Centers nationwide</li>
</ul>
</div>

Testing

Test Credentials

Use Omise test mode credentials:

  • Secret Key: skey_test_YOUR_SECRET_KEY
  • Public Key: pkey_test_YOUR_PUBLIC_KEY

Test Amounts

Amount (PHP)Expected Result
100 - 99999Success
100000Insufficient balance
100001Transaction declined

Test Flow

  1. Create charge with test credentials
  2. Use test amounts above
  3. Complete payment in GCash test environment
  4. Verify webhook received
  5. Check charge status

FAQ

What is GCash?

GCash is the Philippines' leading mobile wallet with over 86 million users. It's operated by Mynt (Globe Fintech Innovations) and is the most widely used cashless payment method in the Philippines.

Do customers need a GCash account?

Yes, customers must have the GCash mobile app installed and an activated GCash account linked to their mobile number.

What are the transaction limits?
  • Minimum: ₱1.00
  • Maximum: ₱100,000 per transaction

Limits also depend on customer's account verification level (Unverified, Semi-Verified, Fully Verified).

How long does settlement take?

GCash settlements typically occur within 1-3 business days. Check your Omise dashboard for specific settlement schedules.

Can I refund GCash payments?

Yes, GCash supports both full and partial refunds within 180 days of the original transaction.

What if customer has insufficient balance?

The payment will be declined. Customers can cash in to their GCash wallet via:

  • Bank transfer (BPI, BDO, UnionBank, etc.)
  • 7-Eleven CLiQQ kiosks
  • Remittance centers (Cebuana, M Lhuillier, Palawan)
  • Online banking (Instapay, PESONet)
  • GCash Padala centers nationwide
Does GCash work on desktop?

No, GCash requires the mobile app and is mobile-only. Desktop users should be shown alternative payment methods like credit cards or online banking.

Should I display instructions in Filipino/Tagalog?

Yes! Since GCash is Philippines-specific, displaying instructions in Filipino or Tagalog will significantly improve user experience and conversion rates.

Testing

Test Mode

GCash can be tested using your test API keys. In test mode:

Test Credentials:

  • Use test API keys (skey_test_xxx)
  • Currency: PHP (Philippine Peso)
  • No actual GCash account required for testing

Test Flow:

  1. Create source and charge with test API keys
  2. Customer redirects to test authorize_uri
  3. Test page simulates GCash authorization
  4. Use Omise Dashboard Actions to mark charge as successful/failed
  5. Verify webhook and return_uri handling

Testing Implementation:

// Test GCash payment
const source = await omise.sources.create({
type: 'gcash',
amount: 10000, // ₱100.00
currency: 'PHP'
});

const charge = await omise.charges.create({
amount: 10000,
currency: 'PHP',
source: source.id,
return_uri: 'https://example.com/callback'
});

console.log('Test authorize URL:', charge.authorize_uri);

Test Scenarios:

  • Successful payment: Verify order fulfillment workflow
  • Failed payment: Test error handling
  • Amount limits: Test minimum and maximum amounts
  • Mobile flow: Test deep-linking to GCash app
  • Insufficient balance: Simulate low wallet balance
  • Timeout: Test abandoned payment scenarios
  • Webhook delivery: Verify all webhook notifications

Important Notes:

  • Test mode doesn't connect to real GCash servers
  • Use dashboard to simulate payment outcomes
  • Test mobile app flow thoroughly
  • Verify webhook handling for all charge statuses
  • Test amount validation for PHP currency

For comprehensive testing guidelines, see the Testing Documentation.

Next Steps

  1. Create GCash source
  2. Implement redirect flow
  3. Handle return callback
  4. Set up webhook
  5. Test payment flow
  6. Go live