Accepting GrabPay payments

Learn how to integrate GrabPay



Upon your account's activation with us, please expect around 5 business days for your account to be activated for GrabPay transactions. Test transactions can still be made.


GrabPay is one of the popular e-wallets in the Philippines. A GrabPay user can send money from one person to another by authorizing a transfer using their GrabPay accounts.

Collecting GrabPay payments on your website starts with creating a resource to generate a checkout URL where your customer needs to authorize an amount, wait for the authorization to complete and create a Payment resource to receive the authorized amount.

A Source resource is used to generate GrabPay checkout URL to authorize a certain amount to be deducted from your customer's GrabPay account and send it to your PayMongo account. After completing the authorization, your integration uses the chargeable source to make a create payment request and receive the payment.

1. Create a Source

GrabPay requires your customers to fulfill the authorization process from a GrabPay checkout URL in order to authorize an amount. First, you need to create a Source resource. The type of the Source is grab_pay. You need to specify information such as the amount to authorize, where to redirect the customer once the authorization is successful and if the customer failed to authorize the amount. The GrabPay checkout URL should be rendered to your page.

2. Have the customer authorize the payment

Your customer needs to complete the authorization process. After the successful authorization, the amount will be deducted from the customer's e-wallet and the Source status becomes chargeable.

Take note that you haven't received your customer's payment yet. You need to use this chargeable source to create a Payment resource in order to finally receive the authorized amount.

3. Create a Webhook

To be notified about any source that becomes chargeable, you need to listen to source.chargeable event by creating a webhook using our Webhook API.



You should not create a webhook in your code. You can try using API tools such as Postman or curl to create your webhook once. Please take note that you should not create multiple webhooks for every source that will be created. One webhook with event source.chargeable is enough to receive the chargeable source information.

4. Create a Payment from chargeable Source

You will be notified of any source that becomes chargeable via the webhook you registered. To create a Payment object, you need to pass the id of the Source resource as source id and source as the source type.

If you didn't manage to create a Payment after one hour once the amount is authorized, the source status becomes 'cancelled', the authorized amount will be automatically refunded to your customer's e-wallet and you need to create another source again.

The code below is an example of how to set up a webhook handler that creates a Payment object after being sent a source.chargeable event:

header('Content-Type: application/json');
$request = file_get_contents('php://input');
$payload = json_decode($request, true);
$type = $payload['data']['attributes']['type'];

//If event type is source.chargeable, call the createPayment API
if ($type == 'source.chargeable') {
  $amount = $payload['data']['attributes']['data']['attributes']['amount'];
  $id = $payload['data']['attributes']['data']['id'];
  $description = "GrabPay Payment Description"
  $curl = curl_init();
  $fields = array("data" => array ("attributes" => array ("amount" => $amount, "source" => array ("id" => $id, "type" => "source"), "currency" => "PHP", "description" => $description)));
  $jsonFields = json_encode($fields);
  curl_setopt_array($curl, [
    CURLOPT_URL => "",
    CURLOPT_POSTFIELDS => $jsonFields,
      "Accept: application/json",
      //Input your encoded API keys below for authorization
      "Authorization:" ,
      "Content-Type: application/json"

  $response = curl_exec($curl);
  //Log the response
  $fp = file_put_contents( 'test.log', $response );
  $err = curl_error($curl);


  if ($err) {
    echo "cURL Error #:" . $err;
    //Log the response
    $fp = file_put_contents( 'test.log', $err );
  } else {
    echo $response;

5. Verifying successful transactions

If you prefer to monitor the success status of the Source from your backend, you could be notified for successful payments by listening to the payment.paid event by registering or updating your webhook endpoint using our Webhook API.

Event notifications will be sent to your registered webhook endpoint containing relevant payment information as shown below:

  "data": {
    "id": "evt_2qsJXQpDKxizooMjSarThgxk",
    "type": "event",
    "attributes": {
      "type": "payment.paid",
      "livemode": false,
      "data": {
        "id": "pay_PNajsy16jmdq2PacfHexeihd",
        "type": "payment",
        "attributes": {
          "access_url": null,
          "amount": 20050,
          "balance_transaction_id": "bal_txn_fKHzW5jsFNE2J1GmHBoTGWu4",
          "billing": null,
          "currency": "PHP",
          "description": null,
          "disputed": false,
          "external_reference_number": null,
          "fee": 441,
         "livemode": false,
          "net_amount": 19469,
          "origin": "api",
          "payment_intent_id": null,
          "payout": null,
          "source": {
            "id": "src_bB5v8tvpmFLALVkrX3W8wZva",
            "type": "grab_pay"
          "statement_descriptor": "PAYMONGO",
          "status": "paid",
          "tax_amount": null,
          "refunds": [],
          "taxes": [],
          "available_at": 1630659600,
          "created_at": 1630463172,
          "paid_at": 1630463172,
          "updated_at": 1630463172
      "previous_data": {},
      "created_at": 1630463172,
      "updated_at": 1630463172

You can determine if a payment is successful or not by checking the event type or the status of the payment intent.