Gcash payment 是否提供 API 集成?
支付小周
结论
GCash 可以用于应用支付,但一般不能直接调用面向所有开发者开放的“公共 GCash API”。
通常有两种接入方式:
- 通过支持 GCash 的支付服务商或支付网关接入。
- 申请成为 GCash 商户,审核通过后使用其商户支付能力。
对于 React Native 应用,更可行的做法是选择支持 GCash 的支付网关。应用先请求自己的后端创建支付订单,再打开网关返回的结账页面或跳转链接。商户密钥不能保存在移动端,也不要从移动端直接调用需要密钥签名的支付接口。
推荐的接入结构
React Native App
|
| HTTPS
v
Your Backend
|
| Merchant API
v
Payment Gateway / GCash
|
| Webhook
v
Your Backend
支付流程通常是:
- 用户在应用中提交订单。
- React Native 请求业务后端创建支付。
- 后端调用支付网关接口,并将 GCash 指定为支付方式。
- 网关返回结账 URL、支付会话 ID 或二维码数据。
- 应用打开结账页面,用户通过 GCash 完成付款。
- 支付网关通过 webhook 通知后端。
- 后端验证通知并更新订单状态。
- 应用重新查询订单,显示最终支付结果。
使用 WebView、系统浏览器、二维码还是 App 跳转,需要根据支付服务商的 SDK 和接口设计决定。
React Native 示例
以下代码只演示推荐的客户端调用方式。/api/payments/gcash 是应用自己的后端接口,不是 GCash 官方接口。
import React, { useState } from 'react';
import {
Alert,
Button,
Linking,
View,
} from 'react-native';
export default function CheckoutScreen() {
const [loading, setLoading] = useState(false);
const payWithGCash = async () => {
try {
setLoading(true);
const response = await fetch(
'https://api.example.com/api/payments/gcash',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer YOUR_USER_ACCESS_TOKEN',
},
body: JSON.stringify({
orderId: 'ORDER_12345',
}),
},
);
if (!response.ok) {
throw new Error(`Create payment failed: ${response.status}`);
}
const data: {
paymentId: string;
checkoutUrl: string;
} = await response.json();
const supported = await Linking.canOpenURL(data.checkoutUrl);
if (!supported) {
throw new Error('Cannot open the payment page');
}
await Linking.openURL(data.checkoutUrl);
} catch (error) {
const message =
error instanceof Error ? error.message : 'Unknown payment error';
Alert.alert('Payment unavailable', message);
} finally {
setLoading(false);
}
};
return (
<View>
<Button
title={loading ? 'Creating payment...' : 'Pay with GCash'}
disabled={loading}
onPress={payWithGCash}
/>
</View>
);
}
支付金额不能由客户端直接决定。客户端只提交 orderId,后端再根据数据库中的订单计算应付金额,防止用户篡改请求。
后端示例
下面的 Express 示例使用占位网关地址和字段,仅用于说明客户端与后端的职责划分。实际 URL、认证方式、请求参数和响应格式应以所选支付服务商的文档为准。
import express from 'express';
const app = express();
app.use(express.json());
app.post('/api/payments/gcash', async (req, res) => {
const { orderId } = req.body;
// 应从数据库读取订单,并验证订单属于当前登录用户。
const order = await findOrderById(orderId);
if (!order || order.status !== 'pending') {
return res.status(400).json({
error: 'Invalid order',
});
}
const gatewayResponse = await fetch(
process.env.PAYMENT_GATEWAY_CREATE_URL,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.PAYMENT_GATEWAY_SECRET_KEY}`,
},
body: JSON.stringify({
referenceId: order.id,
amount: order.amount,
currency: 'PHP',
paymentMethod: 'GCASH',
successUrl: 'myapp://payment/success',
cancelUrl: 'myapp://payment/cancel',
}),
},
);
if (!gatewayResponse.ok) {
return res.status(502).json({
error: 'Payment provider rejected the request',
});
}
const payment = await gatewayResponse.json();
await savePayment({
orderId: order.id,
providerPaymentId: payment.id,
status: 'pending',
});
return res.json({
paymentId: payment.id,
checkoutUrl: payment.checkoutUrl,
});
});
paymentMethod、successUrl、checkoutUrl 等字段没有统一标准,不同服务商使用的名称可能完全不同。
Webhook 处理
不能只因为用户进入了成功页面,就把订单标记为已支付。用户可能中途关闭页面或伪造跳转 URL,付款结果也可能仍在处理中。最终支付状态应以后端查询结果或通过签名验证的 webhook 为准。
app.post('/api/webhooks/payment', async (req, res) => {
const signature = req.headers['x-provider-signature'];
const valid = verifyWebhookSignature(
req.body,
signature,
process.env.PAYMENT_GATEWAY_WEBHOOK_SECRET,
);
if (!valid) {
return res.sendStatus(401);
}
const event = req.body;
if (event.type === 'payment.succeeded') {
await markOrderAsPaid(event.data.referenceId);
}
if (event.type === 'payment.failed') {
await markOrderAsFailed(event.data.referenceId);
}
return res.sendStatus(200);
});
签名请求头、签名算法和事件名称同样要按照实际支付服务商的文档实现。
接入前需要确认
选择支付服务商或申请商户能力时,需要确认以下事项:
- 是否支持在菲律宾注册的个人或企业商户。
- 是否明确支持 GCash,而不只是银行卡支付。
- 是否提供测试环境。
- 是否支持移动端浏览器跳转、App Link 或 Universal Link。
- 交易费率、结算周期和退款费用。
- 是否支持全额退款和部分退款。
- webhook 是否带签名,发送失败后是否自动重试。
- React Native WebView 能否打开支付页面。
- 商户审核是否要求菲律宾公司、银行账户或相关身份材料。
GCash 的商户政策、开放范围和合作网关可能会发生变化。申请前应查看 GCash 商户渠道以及候选支付服务商的最新官方文档。
注意事项
- 商户密钥只能保存在后端或安全的密钥管理系统中,不能写入 React Native 包。
- 服务端必须重新读取订单金额、币种和商品信息。
- 创建支付时应使用幂等键,避免用户重复点击后产生多个支付订单。
- webhook 可能重复发送,因此订单状态更新也要支持幂等处理。
pending、paid、failed、expired和refunded等状态应分别处理。- 返回 URL 只能改善用户体验,不能作为款项到账的判断依据。
- 使用 WebView 前,应确认支付服务商是否允许。部分身份验证或外部 App 跳转可能无法在 WebView 中正常运行。
- 普通 GCash 用户转账或个人二维码收款不能代替完整的应用支付 API。正式商用通常还需要订单关联、回调验签、退款和对账能力。
备注:内容仅供参考。
