Developer Documentation

XPayLink API Integration

Use this when a merchant wants their own website, LMS, billing system, or store to accept GCash payments through XPayLink. The merchant site creates a payment session, redirects the customer to the hosted XPayLink payment page, then marks the local order paid only after receiving a valid signed webhook.

Step 1

Create session

Merchant backend calls XPayLink using Public Key.

Step 2

Redirect

Send customer to payment_url.

Step 3

Verify

XPayLink detects and verifies payment.

Step 4

Webhook

Merchant marks paid after signed webhook.

Before merchants integrate

Merchant dashboard setup

  1. Merchant account must be active.
  2. Merchant GCash receiving number must be saved.
  3. Merchant Android phone must be paired and Notification Access enabled.
  4. Merchant must copy Public Key and Secret Key.
  5. Merchant webhook URL should be public and not require login.

Safe payment rule

Do not mark an order paid after a redirect, button click, screenshot, or customer message. Mark paid only after X-PayLink-Signature is verified and the webhook payload is valid.

1. Create Payment Session

Call this from the merchant backend/server only. Do not call this directly from frontend JavaScript because the merchant controls order validation server-side.

POST https://synthwave.space/api/create-session.php
Headers:
  Content-Type: application/json
  X-PayLink-Key: pk_live_your_public_key
  X-PayLink-Secret: sk_live_your_secret_key

Body:
{
  "external_bill_id": "ORDER-1001",
  "customer_name": "Juan Dela Cruz",
  "amount": 200.00,
  "callback_url": "https://merchantwebsite.com/xpaylink_merchant_sdk/webhook.php",
  "success_url": "https://merchantwebsite.com/order-success.php?order=ORDER-1001"
}

Required fields

FieldMeaningExample
external_bill_idMerchant local order/bill ID. Use this to update the merchant database.ORDER-1001
customer_nameCustomer display name.Juan Dela Cruz
amountMerchant amount before XPayLink identifier/admin fee.200.00

Optional fields

{
  "callback_url": "https://merchantwebsite.com/xpaylink-webhook.php",
  "success_url": "https://merchantwebsite.com/order-success.php?order=ORDER-1001",
  "return_url": "https://merchantwebsite.com/order-success.php?order=ORDER-1001",
  "failed_url": "https://merchantwebsite.com/order-failed.php?order=ORDER-1001",
  "customer_gcash_number": "09123456789"
}

customer_gcash_number is optional. If not provided, the hosted XPayLink payment page will collect it from the customer.

Success response

{
  "success": true,
  "session_id": "PS-ABC123",
  "merchant_amount": "200.00",
  "paylink_admin_fee": "5.13",
  "customer_should_pay": "205.13",
  "final_amount": "205.13",
  "gcash_number": "09xxxxxxxxx",
  "customer_gcash_required": true,
  "expires_at": "2026-05-24 10:00:00",
  "status": "pending",
  "payment_url": "https://synthwave.space/pay.php?sid=PS-ABC123"
}

2. Redirect Customer to payment_url

This is required. The hosted page shows the final payment amount, GCash receiver, payer details, and live status.

$payment = json_decode($apiResponse, true);
if (!empty($payment["success"])) {
    header("Location: " . $payment["payment_url"]);
    exit;
}
Important: Customer return/success page is only for navigation. The signed webhook is the official payment confirmation.

3. Check Session Status

Optional endpoint for status pages or debugging. The merchant should still rely on webhooks for final database updates.

GET https://synthwave.space/api/session-status.php?sid=PS-ABC123
{
  "success": true,
  "session_id": "PS-ABC123",
  "status": "paid",
  "is_paid": true,
  "paid_at": "2026-05-24 10:05:00",
  "final_amount": "205.13",
  "gcash_number": "09xxxxxxxxx",
  "customer_gcash_saved": true,
  "business_name": "Merchant Store"
}

4. Webhook Receiver

When XPayLink verifies payment, it sends a signed POST request to the session callback_url. If no session callback URL was provided, XPayLink uses the merchant dashboard webhook URL.

POST https://merchantwebsite.com/xpaylink-webhook.php
Headers:
  Content-Type: application/json
  X-PayLink-Signature: hmac_sha256_signature

Payload

{
  "event": "payment.paid",
  "status": "paid",
  "session_id": "PS-ABC123",
  "external_bill_id": "ORDER-1001",
  "customer_name": "Juan Dela Cruz",
  "customer_paid": "205.13",
  "merchant_amount": "200.00",
  "paylink_admin_fee": "5.13",
  "amount": "205.13",
  "sender_gcash_number_masked": "0912***6789",
  "match_source": "auto_match",
  "manual_review_note": null,
  "matched_at": "2026-05-24 10:05:00"
}

PHP signature verification

$secretKey = 'sk_live_your_secret_key';
$raw = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PAYLINK_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $raw, $secretKey);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

$payload = json_decode($raw, true);
if (($payload['status'] ?? '') === 'paid') {
    // 1. Find local order by external_bill_id
    // 2. Compare merchant_amount with local amount
    // 3. Mark order PAID idempotently
    // 4. Return HTTP 200 OK
}

5. Error Responses

HTTPExampleFix
401Invalid API keyUse the merchant Public Key and confirm merchant is active.
422Amount is required / invalid URL / invalid GCash numberValidate request fields before calling API.
503merchant_maintenanceMerchant gateway is disabled or temporarily locked.

6. SDK / Drop-in Kits

1-File PHP Kit

Best for Hostinger/cPanel/plain PHP merchants. Upload one file, edit config, connect the Pay button.

Download 1-File PHP Kit

Full PHP SDK

Best for developers who want separate checkout, webhook, demo store, and reusable SDK class.

Download Full PHP SDK

WooCommerce Plugin

Best for WordPress stores. Install plugin, enable gateway, enter API keys, and receive signed webhooks.

Download WooCommerce Plugin

Production Checklist