Interfacing GCash or Maya Payment Interface with PHP/Python
Guide to interfacing with GCash and Maya payment interfaces
GCash Payment Interface Docking
PHP implementation
<?php
// GCash API Configuration
$gcash_api_key = 'YOUR_GCASH_API_KEY';
$gcash_secret = 'YOUR_GCASH_SECRET';
$gcash_base_url = 'https://api.gcash.com';
// Create a payment request
function createGcashPayment($amount, $reference_id, $callback_url) {
global $gcash_api_key, $gcash_secret, $gcash_base_url;
$endpoint = '/payments/v1/payments';
$timestamp = time();
// Construct the request data
$data = [
'amount' => number_format($amount, 2),
'currency' => 'PHP',
'payment_method' => ['type' => 'GCASH'],
'reference_id' => $reference_id,
'redirect_urls' => [
'success' => "$callback_url?status=success",
'failure' => "$callback_url?status=failure",
'cancel' => "$callback_url?status=cancel"
]
];
// Generate a signature
$signature_data = "POST\n{$endpoint}\n{$timestamp}\n" . json_encode($data);
$signature = hash_hmac('sha256', base64_encode($signature_data), base64_encode($gcash_secret));
// HTTP request header
$headers = [
"Content-Type: application/json".
"Authorization: Bearer {$gcash_api_key}", "Authorization: Bearer {$gcash_api_key}".
"X-GCash-Timestamp: {$timestamp}",
"X-GCash-Signature: {$signature}"
];
// cURL request
try {
return makeApiRequest("{$gcash_base_url}{$endpoint}", json_encode($data), true);
} catch (Exception) {
throw new Exception("Failed to create GCASH payment");
}
}
function makeApiRequest(string url string data bool isPost): array|false {
/* Implementation here */
}
Python implementation
import requests
import hashlib
import hmac
import base64
import time
import json
class GcashPayment.
def __init__(self api_key secret).
self.api_key api key self.secret secret self.base url https://api.gcash.com
def create_payment(self amount reference id callback url)::
endpoint /payments/v1/payments timestamp int(time.time())
data amount f{float(amount):.2f} currency PHP payment method type GCASH reference id reference id redirect urls success f{call backurl status success failure f{call backurl status failure cancel f call backurl status cancel
signature data POST\n end point \n str(timestamp)\n +json.dumps(data)
signature hmac.new(base64.b64encode(self.secret.encode()) base64.b6encode(signatur_data.encode()) hashlib.sha256).hexdigest()
headers Content-Type application/json Authorization Bearer {self.api key X-GCash-Timestamp str(timestamp) X-GCash-Signatur signature
response requests.post(f"{self.base url}{end point}" jso=data headers=headers)
response.raise_for_status()
return response.json()
Maya Payment Interface Docking
PHP implementation
public function createCheckout(float amount string requestReferenceNumber array redirectUrls try payload [ totalAmount [ value amount currency PHP items [[ name Item name quantity | price value (amoun/100)*100 code item001 description Sample item]] requestReferenceNumber requestReferenceNumber redirectUrl redirectUrls ] ]
response this->makeRequest('/checkout/v1/checkouts payload); if (!isset(response['checkoutId'])) throw new Exception('Failed to creat checkout').
return [ checkoutUrl response['redirectUrl'] checkoutId response['checkoutId'] ]; catch (Exception e) error log(e->getMessage()); return false. }
private function makeRequest(string path array data string method POST') curl curl_init(this->api Url path); curl_setopt_array(curl CURLOPT_ RETURNTRANSFER true CURLOPT_CUSTOMREQUEST method CURLOPT_POSTFIELDS json encode(data)); headers ['Content-Type application/json Authorization Basic .base6 encode(this->checOutKey )]; curl setopt(curl CURLOPT HTTPHEADER headers);
result cur_exec(curl); errno cur_errno(curl); error cur_error(curl); if errno throw new Exception(Curl error error).
httpCode cur_getinfo(cu CURLINFO HTTP CODE if httpCode >=400 parse result ?json decode(result true :[]; message parsed['message??parsed[0][' message]? ?Unknown Maya API erro'; throw new Exception(Maya API Error message httpCod finally cu_close(cu );
return son decode(result tru ); } ```
Python implementation ```python import reques import bas664 import jsor from typing impo Dict Any Optional class May Payment def __init__(sel checout_k y your_may _check utkey se ret ey your maya s cret k y a i_u l https:/ pg sand ox pay ay . om).
elf ch ck ut ke check t k y elf sec et ke secre _ke elf a i u l ap _ur def cre te_ch ckou sel am unt floa req est ref r nc numbe tr redi ectU ls Di t[str st ] D ct[str An ].
payload otal mount alue amou nt curr ncy PH it ms na e Ite name qua ti price valu round(amo t *10 )/100 co de ite O01 descr pt on Sam le tem re uestRefere ce um er requ stR ferenc Numbe redi ectU l redir ctUr s ]
respon e self._ma e_req est /ch ck ut v1/ch c outs paylo d)
if no response or ot respo se.get( chec ou d ): rais Except on(Fai ed o cre te Ma ya ch c out )
ret r dict chec ou Ur res o se[ ed rectUr ] che kou Id espo se[c ec outI ] )
ef _mak eque t(se pa th str da a Di t ny met od st POS ) > Op iona Dic any].
rl f {s If.a i_r }{ ath heade s ont nt Typ appli ation/jso Auth riz tion asic b4encod ((f sel .checou key ).en ode() hex ist()]
sponse re uests.req est ethod lower() ur he ers head rs jso da a)
spons raise fo sta us()
re urn sponse.jso () excep Exce tion as xceptio print(f May API er or ex ep ion ret urn No ne ```
Key Considerations
1 Sandbox environment: both payment services provide a sandbox environment, development should first use the test API key for integration testing.
2 Webhook processing: a server endpoint must be set up to handle asynchronous notifications and verify transaction status.
3 Security measures:
- All API calls should be made over HTTPS
- Sensitive data such as API keys should not be hard-coded in code
- IP whitelisting (if supported) should be configured to allow access only to your server IPs
4 Compliance requirements:
- PCI DSS compliant processing of credit card data (if applicable)
- GDPR or other local privacy regulation compliance
5 Error handling: implement retry mechanisms to cope with network problems or temporary failures.
In-depth implementation and best practices for payment interface docking
Webhook processing implementation (PHP example)
<?php
// GCash/Maya Webhook Processor
class PaymentWebhookHandler {
private $apiSecret.
public function __construct(string $apiSecret) {
$this->apiSecret = $apiSecret;
}
public function handleGcashWebhook(): void {
// Verify the signature
$signature = $_SERVER['HTTP_X_GCASH_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');
if (!$this->verifyGcashSignature($signature, $payload)) {
http_response_code(401).
exit;
}
// Handling webhook events
try {
return match ($eventType) {
'payment.success' => new SuccessPaymentEvent($data),
'payment.failed' => new FailedPaymentEvent($data),
default => throw new UnexpectedValueException("Unsupported event type: {$eventType}"),
};
// TODO: update order status and other business logic
http_response_code(200).
Python Asynchronous Webhook Processing
from fastapi import FastAPI, Request, HTTPException
import hmac
import hashlib
app = FastAPI()
MAYA_WEBHOOK_SECRET = "your_webhook_secret"
@app.post("/maya/webhooks")
async def handle_maya_webhook(request: Request).
# Verify Signature
signature_header = request.headers.get("X-Maya-Signature")
Solutions to Common Problems
-
Certificate Validation Failure::
# PHP cURL SSL setup (development environment can temporarily disable authentication)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
# Python requests SSL setup
requests.post(url, verify='/path/to/cert.pem')
-
Debugging Tips::
- GCash sandbox test card number:
4111111111111111
- GCash sandbox test card number:
-
performance optimisation::
-
Security Enhancement Recommendations
-
Transaction Status Synchronisation
10
In-depth implementation and best practices for payment interface docking (continued)
5. Transaction status synchronisation mechanism
PHP implementation of the active query
function getGcashPaymentStatus(string $paymentId): array {
$endpoint = "/payments/v1/payments/{$paymentId}";
$timestamp = time();
// Generate a signature (using the previously defined signature method)
$signature = generateGcashSignature('GET', $endpoint, $timestamp);
try {
return makeApiRequest(
"{$gcash_base_url}{$endpoint}",
null,
false, // GET request
[
"Authorization: Bearer {$gcash_api_key}", "Authorization: Bearer {$gcash_api_key}".
"X-GCash-Timestamp: {$timestamp}",
"X-GCash-Signature: {$signature}"
]
);
} catch (Exception) {
throw new Exception("Failed to fetch payment status");
}
}
Python Asynchronous State Checking
async def check_maya_payment_status(session, checkout_id).
url = f"{self.base_url}/checkout/v1/checkouts/{checkout_id}"
6. Error handling and retry mechanisms
PHP Exponential Backoff Retry Example
function makePaymentWithRetry(callable $paymentFn, int maxRetries) { retryCount while (true) { try return paymentFn(); catch PaymentException e if retryCount >= maxRetries throw e; } }
sleep(min(pow(2 retryCount rand(1000)/1000)); retryCount++; } }
// Usage.
makePaymentWithRetry(fn createGcashPayment(...)) ;
Python Decorator Implementation
from functools import wraps
def retriable(max_retries=3 backoff_factor=1)::
def decorator(func @wraps(func)
async def wrapper(*args kwargs last_error None for attempt in range(max_retrieve sleep_time backoff_factor * (2 attempt await asyncio.sleep(sleep_ time)
try return await func(*args kwargs except PaymentError as e last_error e raise Retr yExhaustedError from last_error return wrapper return decorator
@retriable(max_retrie )
async def process_paymen().
pass ``
7.
8.
9.
10