On this page
No Headings
Last updated: July 10, 2026
GrabPay is a mobile wallet that enables customers to make cashless payments. It's a popular payment method in Singapore. To pay with GrabPay, customers are redirected to GrabPay's website, where they authenticate the transaction using a one-time password. After authenticating, customers are redirected back to merchant website.
| Countries | Payment type | Payment flow | Currencies | Maximum amount | Refunds |
|---|---|---|---|---|---|
Singapore(SG) | wallet | redirect | SGD | 5000 SGD | Within 365 days |
Your checkout page offers alternative payment methods.
Buyer provides their personal details and selects an alternative payment method from your checkout page.
Buyer is transferred from your checkout page to the third-party bank to confirm the purchase.
Buyer authorizes and confirms payment.
Buyer returns to your site to see confirmation of purchase.
Merchant initiates completion of payment. PayPal moves the funds to the merchant. Transaction show in your PayPal account with the payment method the buyer used.
The steps to implementing all alternative payment methods using the Orders REST API are similar. If you've implemented an alternative payment method previously, you can likely use that code and adjust it for the specific differences for this payment method.
Make sure you're subscribed to the following webhook events:
The PAYMENT.CAPTURE.COMPLETED webhook event indicates a successful order capture.
The PAYMENT.CAPTURE.DENIED webhook event indicate a failed order capture.
Upon receiving each webhook, fetch the latest order details using Show order details. The up HATEOAS link in the webhook payload indicates the order associated with the capture.
When processing GrabPay payments, capture payment for order is not required.
You'll need to create the user interface to offer GrabPay and collect the buyer's full name. Then you'll use the API calls described in the remainder of this topic to:
Create the order with GrabPay as the payment method and buyer's full name and country_code
Redirect the buyer to GrabPay
Refer to Payment method icons for icons you can use and download locations.
Use the buyer information you captured from your user interface to create an order with GrabPay as the payment source.
API endpoint used: Create order
curl --location --request POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <Access-Token>' \
--header 'PayPal-Request-Id: <PayPal-RequestId>' \
--data-raw '{
"intent": "CAPTURE",
"payment_source": {
"grabpay": {
"country_code": "SG",
"name": "John Doe",
"experience_context": {
"locale": "en-GB",
"return_url": "https://example.com/returnUrl",
"cancel_url": "https://example.com/cancelUrl"
}
}
},
"processing_instruction": "ORDER_COMPLETE_ON_PAYMENT_APPROVAL",
"purchase_units": [
{
"reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b",
"amount": {
"currency_code": "SGD",
"value": "100.00"
}
}
]
}'After you copy the code in the sample request, modify the following:
Access-Token - Your access token.
PayPal-Request-Id - Replace the sample ID with a unique ID you generate. This ID helps prevent duplicate authorizations in the event that the API call is disrupted. See also: API idempotency.
intent - This parameter must be set to CAPTURE as it is in this sample code.
payment_source - Specify the following:
grabpay as the payment_source and include the country_code.
buyer's full name on name field.
experience_context - Specify the preferred language for returned errors, the URL the buyer is returned to after approving the purchase with their selected payment method, and the URL the buyer is returned to after canceling an approval with their selected payment method. While return_url and cancel_url are optional fields, this integration requires you specify them to handle the handoff from the payment method back to your site. You can use the cancel_url to redirect buyers when an error occurs while they're on the payment method's site, so make sure your cancel URL works for that situation as well as an actual cancellation by the buyer.
processing_instruction - Set this value to ORDER_COMPLETE_ON_PAYMENT_APPROVAL as it is in this sample code.
purchase_units: amount - Pass the amount of the order and the currency code.
Note: Change or add other parameters in the Create order request body to create an order that reflects the actual order details.
A successful request results in the following:
A return status code of HTTP 200 OK.
A JSON response body that contains the order ID. You'll use the order ID and payer-action HATEOAS URL in the next step. See also: HATEOAS links.
{
"id": "5V159329PV571861D",
"status": "PAYER_ACTION_REQUIRED",
"payment_source": {
"grabpay": {
"name": "John Doe",
"country_code": "SG"
}
},
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5V159329PV571861D",
"rel": "self",
"method": "GET"
},
{
"href": "https://www.sandbox.paypal.com/payment/grabpay?token=5V159329PV571861D",
"rel": "payer-action",
"method": "GET"
}
]
}In your user interface, attach the payer-action redirect URL returned in the Create Order response to the GrabPay payment button. This sends the buyer to their wallet to approve the purchase. Once the buyer approves the purchase, the payment is automatically captured.
In the sample, the redirect URL is: "https://www.sandbox.paypal.com/payment/grabpay?token=5V159329PV571861D".
After successfully completing the wallet transaction:
The buyer is redirected to the return_url mentioned in the Create Order request.
The PAYMENT.CAPTURE.COMPLETED webhook event is triggered, which indicates that payment capture was successful.
After unsuccessful bank approval:
cancel_url mentioned in the Create Order request.Listen to the following webhooks to get the result of order capture:
The PAYMENT.CAPTURE.COMPLETED webhook event indicates a successful order capture.
The PAYMENT.CAPTURE.DENIED webhook events indicate a failed order capture.
Optional: Use Show order details endpoint to determine the status of an order.
up HATEOAS link indicates the order associated with this capture.See Subscribe to checkout webhooks for more information.
Here are some additional resources as you create webhook handler code:
Webhook Management API - Manage webhooks, list event notifications, and more.
Webhook events
Checkout webhook events - Checkout buyer approval-related webhooks.
Order webhook events - Other order-related webhooks.
Show order details endpoint - Determine the status of an order.
{
"id": "WH-9LK14475MF9937440-9EG47645TP521822L",
"event_version": "1.0",
"create_time": "2022-05-10T06:04:12.533Z",
"resource_type": "capture",
"resource_version": "2.0",
"event_type": "PAYMENT.CAPTURE.COMPLETED",
"summary": "Payment completed for SGD 100.0 SGD",
"resource": {
"amount": {
"value": "100.00",
"currency_code": "SGD"
},
"supplementary_data": {
"related_ids": {
"order_id": "5V159329PV571861D"
}
},
"update_time": "2022-01-19T06:04:08Z",
"create_time": "2022-01-19T06:04:08Z",
"final_capture": true,
"seller_receivable_breakdown": {
"paypal_fee": {
"value": "3.80",
"currency_code": "SGD"
},
"gross_amount": {
"value": "100.00",
"currency_code": "SGD"
},
"net_amount": {
"value": "96.20",
"currency_code": "SGD"
}
},
"custom_id": "Custom-1234",
"invoice_id": "Invoice-12345",
"links": [
{
"method": "GET",
"rel": "self",
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5R102774VL663561J"
},
{
"method": "POST",
"rel": "refund",
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5R102774VL663561J/refund"
},
{
"method": "GET",
"rel": "up",
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5V159329PV571861D"
}
],
"id": "5R102774VL663561J",
"status": "COMPLETED"
},
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9LK14475MF9937440-9EG47645TP521822L",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9LK14475MF9937440-9EG47645TP521822L/resend",
"rel": "resend",
"method": "POST"
}
]
}Note: The order ID from Step 2 should match the resource.supplementary_data.related_ids.order_id parameter in the webhook payload.
{
"id": "WH-9LK14475MF9937440-9EG47645TP521822L",
"event_version": "1.0",
"create_time": "2022-05-10T06:04:12.533Z",
"resource_type": "capture",
"resource_version": "2.0",
"event_type": "PAYMENT.CAPTURE.DENIED",
"summary": "Payment denied for SGD 100.0 SGD",
"resource": {
"amount": {
"value": "100.00",
"currency_code": "SGD"
},
"supplementary_data": {
"related_ids": {
"order_id": "5V159329PV571861D"
}
},
"update_time": "2022-05-10T06:04:08Z",
"create_time": "2022-05-10T06:04:08Z",
"final_capture": true,
"seller_receivable_breakdown": {
"paypal_fee": {
"value": "3.80",
"currency_code": "SGD"
},
"gross_amount": {
"value": "100.00",
"currency_code": "SGD"
},
"net_amount": {
"value": "96.20",
"currency_code": "SGD"
}
},
"links": [
{
"method": "GET",
"rel": "self",
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5R102774VL663561J"
},
{
"method": "POST",
"rel": "refund",
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5R102774VL663561J/refund"
},
{
"method": "GET",
"rel": "up",
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5V159329PV571861D"
}
],
"id": "5R102774VL663561J",
"status": "DECLINED"
},
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9LK14475MF9937440-9EG47645TP521822L",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.sandbox.paypal.com/v1/notifications/webhooks-events/WH-9LK14475MF9937440-9EG47645TP521822L/resend",
"rel": "resend",
"method": "POST"
}
]
}Note: The order ID from Step 2 should match the resource.supplementary_data.related_ids.order_id parameter in the webhook payload.
Alternatively, you can get the order capture result from the Show order details endpoint.
Important: Exercise caution when polling for order capture result using the Show order details endpoint. PayPal enforces rate limits on API requests.
curl -v -X GET https://api-m.sandbox.paypal.com/v2/checkout/orders/5V159329PV571861D \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <Access-Token>"{
"id": "5V159329PV571861D",
"intent": "CAPTURE",
"status": "COMPLETED",
"payment_source": {
"grabpay": {
"name": "John Doe",
"country_code": "SG"
}
},
"processing_instruction": "ORDER_COMPLETE_ON_PAYMENT_APPROVAL",
"purchase_units": [
{
"reference_id": "default",
"amount": {
"currency_code": "SGD",
"value": "100.00"
},
"payments": {
"captures": [
{
"id": "5R102774VL663561J",
"status": "COMPLETED",
"amount": {
"currency_code": "SGD",
"value": "100.00"
},
"final_capture": true,
"seller_receivable_breakdown": {
"gross_amount": {
"currency_code": "SGD",
"value": "100.00"
},
"paypal_fee": {
"currency_code": "SGD",
"value": "3.80"
},
"net_amount": {
"currency_code": "SGD",
"value": "96.20"
}
},
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5R102774VL663561J",
"rel": "self",
"method": "GET"
},
{
"href": "https://api-m.sandbox.paypal.com/v2/payments/captures/5R102774VL663561J/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5V159329PV571861D",
"rel": "up",
"method": "GET"
}
]
}
]
}
}
],
"links": [
{
"href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/5V159329PV571861D",
"rel": "self",
"method": "GET"
}
]
}A successful request returns the HTTP 200 OK status code with a JSON response body that returns a COMPLETED status.
A successfully captured order has the following:
The order status as COMPLETED, which means the order was captured successfully.
A capture with COMPLETED status is present in the response parameter purchase_units[0].payments.captures[0].
The up HATEOAS link indicates the order associated with this capture.
After a successful payment, notify the buyer of a successful transaction. You can do this by sending a confirmation email.