• Dashboard & reporting

    © 2026 Billplz Sdn Bhd

    Introduction

    The Billplz API is a REST API for creating bills and collecting payments programmatically. All responses, including errors, are returned in JSON. The API accepts both application/x-www-form-urlencoded and application/json request bodies.

    Review all integration code carefully before deploying to production. Billplz cannot accept responsibility for loss of money due to improper use of the API.

    API endpoint:
    https://www.billplz.com/api/

    Sandbox mode

    The Billplz Sandbox mirrors the production server so you can test your integration before going live. Any data created in sandbox stays in sandbox; sandbox and production are separate accounts with separate credentials.

    When you are ready to go live, switch to your production Billplz Secret Key and the production endpoint. To create a sandbox account, see Create a sandbox account in the Guide.

    API endpoint:
    https://www.billplz-sandbox.com/api/

    API flow

    Billplz organises payments using two core objects: Collections and Bills.

    A Collection is a group of Bills. Each Bill belongs to exactly one Collection. Examples of Collections include "Tuition fee - June 2025", "Donation for flood relief", or "Event ticket payment". Each Collection has a unique collection_id used in API calls to associate Bills with it.

    A Bill is a payment request issued to a customer. Each Bill belongs to a Collection and tracks the amount, payer details, and payment status.

    For definitions of these and other Billplz-specific terms, see Glossary of Billplz terms.


    You can create Collections through the API or from the Billplz dashboard. To start collecting payments, create a Collection first, then create Bills within it.

    Step 1: Create a Bill

    Your application creates a Bill via the API. Billplz returns the Bill object, which includes a unique Bill URL.

    Step 2: Redirect the customer

    Redirect the customer to the Bill URL. The customer selects a payment method and completes payment on the Bill Page.

    Step 3: Receive the callback

    After payment succeeds or fails, Billplz sends a server-side POST request to your callback_url. Your backend must capture and process this update.

    The callback uses either Basic callback URL or X Signature Callback URL, depending on your configuration.

    Step 4: Handle the redirect

    If redirect_url is set, Billplz redirects the customer back to your site after payment. Your application should read the redirect parameters and display the payment result to the customer immediately. The redirect uses either Basic Redirect URL or X Signature Redirect URL, depending on your configuration.

    If redirect_url is not set, the customer sees the Billplz receipt page instead. Your backend still receives the callback; only the customer-facing redirect is skipped.

    Setting a redirect_url gives your customers a faster status update and a better experience. Note that the execution order of callback_url and redirect_url is not fixed, your system must handle both independently and prevent duplicate processing.

    For a hands-on version of this flow, see API quick-start guide in the Guide.

    Authentication

    Authenticate to the Billplz API by providing your API Secret Key in the request. You can get your API keys from your account's settings page. See Get your Billplz Secret Key for step-by-step instructions.

    Authentication occurs via HTTP Basic Auth. Provide your API Secret Key as the basic auth username. You do not need to provide a password.

    All API requests must be made over HTTPS. Calls made over plain HTTP will fail. You must authenticate all requests.

    For an overview of Billplz authentication methods including OAuth 2.0, see Authentication overview in the Guide.

    Example request:
    # Pass the correct HTTP Basic Auth credential with each request.
    curl https://www.billplz.com/api/v4/webhook_rank \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    
    # Alternatively, use the header with a base64-encoded API secret key.
    curl https://www.billplz.com/api/v4/webhook_rank \
      -H "Authorization: Basic NzNlYjU3ZjAtN2Q0ZS00MmI5LWE1NDQtYWVhYzZlNGIwZjgxOg=="

    Integration

    Billplz has been integrated with many systems available in the market and is continuously working to integrate with more platforms.

    For a self-hosted system, you can download a production-ready module to integrate with your e-commerce system. Refer to our GitHub or Guide for the list of available modules.

    OAuth 2.0

    Billplz provides an OAuth 2.0 integration that allows platform owners to connect merchants with Billplz. With OAuth, a merchant can integrate with your platform by signing in with their Billplz account. This means they do not have to manually copy their Billplz Secret Key, Collection ID, and X Signature Key to your platform.


    Rate limit

    All GET endpoints are subject to rate limiting. The limit is cumulative across all endpoints per IP address or per account. Making a request to one endpoint reduces the available quota for all other endpoints within the same 5-minute window.

    The rate limit is either 100 requests per 5-minute window or 10 requests per 5-minute window, depending on the level of abuse.

    RESPONSE HEADER

    Parameter

    Description

    RateLimit-Limit

    Total requests allowed per request window. Value is unlimited, 100, or 10.

    RateLimit-Remaining

    Remaining requests allowed in the current window. Value is unlimited or less than or equal to RateLimit-Limit.

    RateLimit-Reset

    Time remaining in seconds until the next request window. Value is unlimited or less than or equal to 300.

    For troubleshooting guidance on 429 and other error codes, see Common API error codes in the Guide.

    RESPONSE PARAMETER

    When the rate limit is not exceeded, the response parameters follow the standard format for the endpoint. When the limit is exceeded, the response contains the following error parameters:

    Parameter

    Value

    error[type]

    RateLimit

    error[message]

    ["Too many requests"]

    Example request:
    curl https://www.billplz.com/api/v3/bills/8X0Iyzaw \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Example response header without rate limit:
    RateLimit-Limit: unlimited
    RateLimit-Remaining: unlimited
    RateLimit-Reset: unlimited
    Content-Type: application/json;
    Example response header with rate limit:
    RateLimit-Limit: 100
    RateLimit-Remaining: 99
    RateLimit-Reset: 299
    Content-Type: application/json;
    Example response after exceeding limit:
    RateLimit-Limit: 100
    RateLimit-Remaining: 0
    RateLimit-Reset: 299
    Content-Type: application/json;
    {
      "error": {
        "type": "RateLimit",
        "message": ["Too many requests"]
      }
    }

    Direct payment gateway

    Bypass Billplz Bill Page

    This Billplz feature allows your web application to bypass the default Billplz payment option selection page, allowing your customers to proceed directly to the payment option preconfigured in your Bill. Your customers still fall back to the payment option selection page if the settings are invalid, or the selected payment gateway is not available.

    The following guide references the Create a Bill API.


    How to implement

    Step 1: Create a Bill with a bank code

    Create a Bill through the Billplz API with filled values for reference_1_label and reference_1:

    • Set the value for reference_1_label as "Bank Code"
    • Set the value for reference_1 as the value of the bank code of your target payment gateway.

    Step 2: Append the auto-submit parameter

    Append the query parameter auto_submit=true to the Bill URL returned from the API:

    https://www.billplz.com/bills/abcdef

    https://www.billplz.com/bills/abcdef?auto_submit=true


    Payment flow comparison

    Standard payment flow

    1. Merchant creates a Bill through the API.
    2. Merchant redirects the payer to the Bill URL (returned from step 1).
    3. Payer lands at the Billplz page to select a payment option.
    4. Payer is redirected to the selected payment gateway to pay.
    5. Once payment is completed, the payer is redirected to redirect_url / receipt page (refer to API flow).

    Direct payment gateway payment flow

    1. Merchant creates a Bill through the API with a valid bank code (using reference_1 and reference_1_label).
    2. Merchant redirects the payer to the Bill URL with ?auto_submit=true appended.
    3. Payer skips the payment option selection page and is redirected directly to the selected payment gateway to pay.
    4. Once payment is completed, the payer is redirected to redirect_url / receipt page (refer to API flow).

    Invalid direct payment gateway payment flow

    1. Merchant creates a Bill through the API with an invalid or inactive bank code.
    2. Merchant redirects the payer to the Bill URL with ?auto_submit=true appended.
    3. Payer falls back to the Billplz payment option selection page to select a payment gateway.
    4. Payer is redirected to the selected payment gateway to pay.
    5. Once payment is completed, the payer is redirected to redirect_url / receipt page (refer to API flow).


    Example request:
    # Create a bill for RM 2.00 with reference_1_label and reference_1
    curl https://www.billplz.com/api/v3/bills \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d collection_id="inbmmepb" \
      -d description="Maecenas eu placerat ante." \
      -d email="[email protected]" \
      -d name="Sara" \
      -d amount="200" \
      -d reference_1_label="Bank Code" \
      -d reference_1="BP-FKR01" \
      -d callback_url="http://example.com/webhook/"
    Response:
    {
      "id": "8X0Iyzaw",
      "collection_id": "inbmmepb",
      "paid": false,
      "state": "due",
      "amount": 200,
      "paid_amount": 0,
      "due_at": "2015-3-9",
      "email": "[email protected]",
      "mobile": null,
      "name": "SARA",
      "url": "https://www.billplz.com/bills/8X0Iyzaw",
      "reference_1_label": "Bank Code",
      "reference_1": "BP-FKR01",
      "reference_2_label": null,
      "reference_2": null,
      "redirect_url": null,
      "callback_url": "http://example.com/webhook/",
      "description": "Maecenas eu placerat ante.",
      "paid_at": null
    }

    V3

    V3 is no longer in active development. No new features will be introduced in this version. For new integrations, use V4.


    Collections

    Collections group your Bills by purpose or time period, for example, "Tuition fee - September 2025" or "Donation drive". Every Bill belongs to exactly one Collection. For a full explanation of how Collections and Bills relate, see API flow.

    Available endpoints

    Create a Collection


    Creates a Collection with optional Split Rule configuration. The response contains the Collection's ID (required for Bill API), Split Rule details, and logo fields.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v3/collections

    REQUIRED ARGUMENTS

    Parameter

    Description

    title

    The Collection title. Displayed on the Bill template. String format.

    OPTIONAL ARGUMENTS

    Parameter

    Description

    logo

    This image will be resized to avatar (40x40) and thumbnail (180x180) dimensions. Whitelisted formats are jpgjpeggif and png.

    split_payment[email]

    The email address of the Split Rule's recipient. (The account must be a verified account.)

    split_payment[fixed_cut]

    A positive integer in the smallest currency unit that is going in your account (e.g., 100 cents to charge RM 1.00). This field is required if split_payment[variable_cut] is not present.

    split_payment[variable_cut]

    Percentage in positive integer format that is going in your account. This field is required if split_payment[fixed_cut] is not present.

    split_payment[split_header]

    Boolean value. All bill and receipt templates will show Split Rule recipient's infographic if this was set to true.

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a collection.

    title

    The collection's title in string format.

    logo[thumb_url]

    The thumbnail URL (180x180).

    logo[avatar_url]

    The avatar URL (40x40).

    split_payment[email]

    The first recipient's email. Only the first recipient is returned, even if multiple recipients are configured. To set up 2 recipients, refer to V4 Create a Collection.

    split_payment[fixed_cut]

    The first recipient's fixed cut in smallest and positive currency unit.

    split_payment[variable_cut]

    The first recipient's percentage cut in positive integer format.

    split_payment[split_header]

    Boolean value. All bill and receipt templates will show Split Rule recipient's infographic if this was set to true.


    Example request:
    # Create a collection
    curl https://www.billplz.com/api/v3/collections \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -F title="My First API Collection"
    Response:
    {
      "id": "inbmmepb",
      "title": "My First API Collection",
      "logo": {
        "thumb_url": null,
        "avatar_url": null
      },
      "split_payment": {
        "email": null,
        "fixed_cut": null,
        "variable_cut": null,
        "split_header": false
      }
    }
    Example request with optional arguments:
    curl https://www.billplz.com/api/v3/collections \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -F title="My First API Collection" \
      -F logo=@/Users/Billplz/Documents/uploadPhoto.png \
      -F split_payment[email]="[email protected]" \
      -F split_payment[fixed_cut]=100 \
      -F split_payment[split_header]=true
    Response:
    {
      "id": "inbmmepb",
      "title": "My First API Collection",
      "logo": {
        "thumb_url": "https://sample.net/assets/uploadPhoto.png",
        "avatar_url": "https://sample.net/assets/uploadPhoto.png"
      },
      "split_payment": {
        "email": "[email protected]",
        "fixed_cut": 100,
        "variable_cut": null,
        "split_header": true
      }
    }

    Get a Collection

    Retrieves a single Collection record.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v3/collections/{COLLECTION_ID}

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in Collection object.

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a collection.

    title

    The collection's title in string format.

    logo[thumb_url]

    The thumbnail URL (180x180).

    logo[avatar_url]

    The avatar URL (40x40).

    split_payment[email]

    The first recipient's email. Returns the first recipient only, even if multiple recipients are set. To configure two recipients, refer to V4 Create a Collection.

    split_payment[fixed_cut]

    The first recipient's fixed cut in smallest and positive currency unit.

    split_payment[variable_cut]

    The first recipient's percentage cut in positive integer format.

    split_payment[split_header]

    Boolean value. All Bill and receipt templates will show split rule recipient's infographic if this is set to true.

    status

    Collection's status, either active or inactive.

    Example request:
    # Get a collection
    curl https://www.billplz.com/api/v3/collections/inbmmepb \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "id": "inbmmepb",
      "title": "My First API Collection",
      "logo": {
        "thumb_url": null,
        "avatar_url": null
      },
      "split_payment": {
        "email": null,
        "fixed_cut": null,
        "variable_cut": null,
        "split_header": false
      },
      "status": "active"
    }

    Get Collection index

    Retrieves your Collections list. To utilize paging, append a page parameter to the URL, e.g., ?page=1. If there are 15 records in the response, check if there is any more data by fetching the next page, e.g., ?page=2, and continue this process until no more results are returned.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v3/collections

    OPTIONAL ARGUMENTS

    Parameter

    Description

    page

    Up to 15 collections will be returned in a single API call per specified page. Defaults to 1 if not present.

    status

    Parameter to filter collection's status. Valid values are active and inactive.

    Example request:
    # Get collection index
    curl https://www.billplz.com/api/v3/collections \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "collections": [
        {
          "id": "inbmmepb",
          "title": "My First API Collection",
          "logo": {
            "thumb_url": null,
            "avatar_url": null
          },
          "split_payment": {
            "email": null,
            "fixed_cut": null,
            "variable_cut": null,
            "split_header": false
          },
          "status": "active"
        }
      ],
      "page": 1
    }
    Example request with optional arguments:
    # Get collection index
    curl https://www.billplz.com/api/v3/collections?page=2&status=active \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "collections": [
        {
          "id": "inbmmepb",
          "title": "My First API Collection",
          "logo": {
            "thumb_url": null,
            "avatar_url": null
          },
          "split_payment": {
            "email": null,
            "fixed_cut": null,
            "variable_cut": null,
            "split_header": false
          },
          "status": "active"
        }
      ],
      "page": 2
    }

    Deactivate a Collection

    Deactivates a Collection. The API responds with an error message if the Collection cannot be deactivated.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v3/collections/{COLLECTION_ID}/deactivate

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in the Collection object.

    Example request:
    # Deactivate a collection
    curl -X POST \
    https://www.billplz.com/api/v3/collections/qag4fe_o6/deactivate \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {}

    Activate a Collection

    Collections can be activated via this endpoint. The API responds with an error message if the collection cannot be activated.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v3/collections/{COLLECTION_ID}/activate

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in the Collection object.

    Example request:
    # Activate a collection
    curl -X POST \
    https://www.billplz.com/api/v3/collections/qag4fe_o6/activate \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {}

    Bills

    Bills are created inside a Collection via API.

    Create a Bill

    To create a Bill, you need the Collection ID. Create a Collection via the Create a Collection endpoint or through Dashboard > Collections.

    The Bill's Collection is set to active automatically.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v3/bills

    REQUIRED ARGUMENTS

    Parameter

    Description

    collection_id

    The Collection ID. A string.

    email

    The email address of the bill's recipient. Email is required if mobile is not present.

    mobile

    Recipient's mobile number. Mobile numbers must include country code, area code and number without spaces or dashes (e.g., +60122345678 or 60122345678). Use Google libphonenumber library to help. Mobile is required if email is not present.

    name

    Bill's recipient name. Useful for identification on recipient part. Max of 255 characters.

    amount

    A positive integer in the smallest currency unit (e.g., 100 cents to charge RM 1.00).

    callback_url

    Webhook URL to be called after payment's transaction completed. It will POST a Bill object.

    description

    The bill's description. Will be displayed on bill template. String format. Max of 200 characters.

    OPTIONAL ARGUMENTS

    Parameter

    Description

    due_at

    Due date for the bill. The format YYYY-MM-DD, default value is today. Year range is 19xx to 2xxx. The due_at value does not affect the bill's payability and is only for informational reference.

    redirect_url

    URL to redirect the customer after payment completed. It will do a GET to redirect_url together with bill's status and ID.

    deliver

    Boolean value to set email and SMS (if mobile is present) delivery. Default value is false. SMS is subjected to charges depending on subscribed plan.

    reference_1_label

    Label #1 to reconcile payments. Max of 20 characters. Default value is Reference 1.

    reference_1

    Value for reference_1_label. Max of 120 characters.

    reference_2_label

    Label #2 to reconcile payments. Max of 20 characters. Default value is Reference 2.

    reference_2

    Value for reference_2_label. Max of 120 characters.

    RESPONSE PARAMETER

    Parameter

    Description

    id

    Bill ID that represents a bill.

    url

    URL to the bill.

    SMS delivery is ignored if your account's Credit Balance is insufficient. Sending a Bill via email is free.

    Example request:
    # Create a bill for RM 2.00
    curl https://www.billplz.com/api/v3/bills \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d collection_id=inbmmepb \
      -d description="Maecenas eu placerat ante." \
      -d [email protected] \
      -d name="Sara" \
      -d amount=200 \
      -d callback_url="http://example.com/webhook/"
    Response:
    {
      "id": "8X0Iyzaw",
      "collection_id": "inbmmepb",
      "paid": false,
      "state": "due",
      "amount": 200,
      "paid_amount": 0,
      "due_at": "2015-3-9",
      "email": "[email protected]",
      "mobile": null,
      "name": "Sara",
      "url": "https://www.billplz.com/bills/8X0Iyzaw",
      "reference_1_label": "Reference 1",
      "reference_1": null,
      "reference_2_label": "Reference 2",
      "reference_2": null,
      "redirect_url": null,
      "callback_url": "http://example.com/webhook/",
      "description": "Maecenas eu placerat ante."
    }
    Example request with optional arguments:
    # Create a bill for RM 2.00
    curl https://www.billplz.com/api/v3/bills \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d collection_id=inbmmepb \
      -d [email protected] \
      -d name="Sara" \
      -d amount=200 \
      -d callback_url="http://example.com/webhook/" \
      -d description="Maecenas eu placerat ante." \
      -d due_at="2020-12-31" \
      -d mobile="+60112223333" \
      -d reference_1_label="First Name" \
      -d reference_2_label="Last Name" \
      -d reference_1="Sara" \
      -d reference_2="Dila" \
      -d deliver=false \
      -d redirect_url="http://example.com/redirect/"
    Response:
    {
      "id": "8X0Iyzaw",
      "collection_id": "inbmmepb",
      "paid": false,
      "state": "due",
      "amount": 200,
      "paid_amount": 0,
      "due_at": "2020-12-31",
      "email": "[email protected]",
      "mobile": "+60112223333",
      "name": "Sara",
      "url": "https://www.billplz.com/bills/8X0Iyzaw",
      "reference_1_label": "First Name",
      "reference_1": "Sara",
      "reference_2_label": "Last Name",
      "reference_2": "Dila",
      "redirect_url": "http://example.com/redirect/",
      "callback_url": "http://example.com/webhook/",
      "description": "Maecenas eu placerat ante."
    }

    Get a Bill

    Retrieves a Bill to check its current status.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v3/bills/{BILL_ID}

    URL PARAMETER

    Parameter

    Description

    BILL_ID

    Bill ID returned in the Bill object.

    RESPONSE PARAMETER

    Parameter

    Description

    paid

    Boolean value to tell if a bill has been paid. Returns false for due bills; true for paid bills.

    state

    State representing the bill's status. Possible values: due, paid, deleted.

    Example request:
    # Get a bill
    curl https://www.billplz.com/api/v3/bills/8X0Iyzaw \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "id": "8X0Iyzaw",
      "collection_id": "inbmmepb",
      "paid": false,
      "state": "due",
      "amount": 200,
      "paid_amount": 0,
      "due_at": "2020-12-31",
      "email": "[email protected]",
      "mobile": "+60112223333",
      "name": "SARA",
      "url": "https://www.billplz.com/bills/8X0Iyzaw",
      "reference_1_label": "First Name",
      "reference_1": "Sara",
      "reference_2_label": "Last Name",
      "reference_2": "Dila",
      "redirect_url": "http://example.com/redirect/",
      "callback_url": "http://example.com/webhook/",
      "description": "Maecenas eu placerat ante."
    }

    Delete a Bill

    Only due Bills can be deleted. Paid Bills cannot be deleted. Deleting a Bill is useful when payment has a time limit.

    For example, you can show a timer for the customer to complete payment within 10 minutes, with a 5-minute grace period. After 15 minutes from Bill creation, check the Bill's status and delete it if it remains due.

    HTTP REQUEST

    DELETEhttps://www.billplz.com/api/v3/bills/{BILL_ID}

    URL PARAMETER

    Parameter

    Description

    BILL_ID

    Bill ID returned in the Bill object.


    Example request:
    # Delete a bill
    curl -X DELETE https://www.billplz.com/api/v3/bills/8X0Iyzaw \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {}

    Get transaction index

    Retrieves a Bill's transactions. To use paging, append a page parameter to the URL, e.g., ?page=1. If there are 15 records in the response, check for more data by fetching the next page, e.g., ?page=2, and continue until no more results are returned.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v3/bills/{BILL_ID}/transactions

    URL PARAMETER

    Parameter

    Description

    page

    Page number for pagination. Up to 15 transactions are returned per page. Defaults to 1.

    status

    Filters transactions by status. Valid values are pending, completed, and failed.

    RESPONSE PARAMETER

    Parameter

    Description

    bill_id

    The Bill ID.

    id

    The transaction ID.

    status

    The transaction's status. Possible values are pending, completed, and failed.

    completed_at

    Timestamp of when the transaction completed. Uses ISO 8601 format.

    payment_channel

    The payment channel used for the transaction. Possible values are AMEXMBB, BANKISLAM, BILLPLZ, BOOST, TOUCHNGO, EBPGMBB, FPX, FPXB2B1, ISUPAYPAL, MPGS, OCBC, PAYDEE, RAZERPAYWALLET, SECUREACCEPTANCE, SENANGPAY, TWOCTWOP, TWOCTWOPIPP, and TWOCTWOPWALLET.

    Example request:
    # Get transaction index
    curl https://www.billplz.com/api/v3/bills/inbmmepb/transactions \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "bill_id": "inbmmepb",
      "transactions": [
        {
          "id": "60793D4707CD",
          "status": "completed",
          "completed_at": "2017-02-23T12:49:23.612+08:00",
          "payment_channel": "FPX"
        },
        {
          "id": "28F3D3194138",
          "status": "failed",
          "completed_at": null,
          "payment_channel": "FPX"
        }
      ],
      "page": 1
    }
    Example request with optional arguments:
    curl https://www.billplz.com/api/v3/bills/inbmmepb/transactions?page=1&status=completed \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "bill_id": "inbmmepb",
      "transactions": [
        {
          "id": "60793D4707CD",
          "status": "completed",
          "completed_at": "2017-02-23T12:49:23.612+08:00",
          "payment_channel": "FPX"
        }
      ],
      "page": 1
    }

    Get payment method index

    Returns all payment methods available for a Collection, including each method's enabled or disabled status.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v3/collections/{COLLECTION_ID}/payment_methods

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    ID of the Collection the payment methods belong to.

    RESPONSE PARAMETER

    Parameter

    Description

    code

    The payment method's unique code. String.

    name

    The payment method's display name. String.

    active

    The payment method's enabled status for the Collection. Boolean. Returns true if the method is enabled.

    Example Request:
    # Get payment method index
    curl https://www.billplz.com/api/v3/collections/0idsxnh5/payment_methods \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "payment_methods": [
        {
          "code": "paypal",
          "name": "PAYPAL",
          "active": true
        },
        {
          "code": "fpx",
          "name": "Online Banking",
          "active": false
        }
      ]
    }

    Update payment methods

    Updates the enabled payment methods for a Collection. Pass the code of each method to enable; omit a method's code to disable it.

    Invalid payment method codes are ignored.

    HTTP REQUEST

    PUThttps://www.billplz.com/api/v3/collections/{COLLECTION_ID}/payment_methods

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    ID of the Collection to update.

    REQUIRED ARGUMENTS

    Parameter

    Description

    payment_methods

    An array of payment method codes to enable, in hash format. Include a code key for each method to enable; omit a method's code to disable it. For example, "payment_methods"=>[{"code"=>"fpx"}] enables FPX (Online Banking) and disables PayPal (PAYPAL). Accepted values: amexmbb, bankislam, billplz, boost, touchngo, ebpgmbb, fpx, fpxb2b1, isupaypal, mpgs, ocbc, paydee, razerpaywallet, secureacceptance, senangpay, twoctwop, twoctwopipp, twoctwopwallet.

    REQUIRED ARGUMENTS

    Parameter

    Description

    code

    The payment method's unique code. String.

    name

    The payment method's display name. String.

    active

    The payment method's enabled status for the Collection. Boolean. Returns true if the method is enabled.


    Example request:
    # Update payment methods
    curl -X PUT \
    -d payment_methods[][code]='fpx' \
    -d payment_methods[][code]='paypal' \
    https://www.billplz.com/api/v3/collections/0idsxnh5/payment_methods \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "payment_methods": [
        {
          "code": "paypal",
          "name": "PAYPAL",
          "active": true
        },
        {
          "code": "fpx",
          "name": "Online Banking",
          "active": true
        }
      ]
    }

    Get FPX banks

    Returns a list of FPX bank codes for use as reference_1 when using the Direct payment gateway feature. For a complete list of payment gateway bank codes, use Get payment gateways.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v3/fpx_banks

    RESPONSE PARAMETER

    Parameter

    Description

    name

    The bank code to set as reference_1. Case sensitive.

    active

    Boolean. true if the bank is available; false if unavailable. If an inactive bank code is set as reference_1, the payment flow falls back to the Billplz Bill Page.


    Example request:
    # Get FPX banks
    curl https://www.billplz.com/api/v3/fpx_banks \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "banks": [
        {
          "name": "MBU0227",
          "active": true
        },
        {
          "name": "OCBC0229",
          "active": false
        },
        {
          "name": "MB2U0227",
          "active": true
        }
      ]
    }

    FPX bank codes

    Lookup table mapping FPX bank codes to their corresponding bank names. Use these codes as reference_1 values when creating Bills with the Direct payment gateway feature.

    For FPX bank codes and their corresponding bank names, see FPX in the Reference section.

    V4

    V4 is the current version and is in active development. New features are introduced in this version.


    Collections

    Collections group your Bills by purpose or time period, for example, "Tuition fee - September 2025" or "Donation drive". Every Bill belongs to exactly one Collection. For a full explanation of how Collections and Bills relate, see API flow.

    Available endpoints

    Create a Collection

    Creates a Collection with support for up to two Split Rule recipients. The response contains the Collection's ID (required for Bill API), Split Rule details, and logo fields.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v4/collections

    REQUIRED ARGUMENTS

    Parameter

    Description

    title

    The Collection title. Displayed on the Bill template. String format.

    OPTIONAL ARGUMENTS

    Parameter

    Description

    split_payments[][email]

    The email address of the Split Rule's recipient. (The account must be a verified account.)

    split_payments[][fixed_cut]

    A positive integer in the smallest currency unit that is going in your account (e.g., 100 cents to charge RM 1.00). This field is required if split_payments[][variable_cut] is not present.

    split_payments[][variable_cut]

    Percentage in positive integer format that is going in your account. This field is required if split_payments[][fixed_cut] is not present.

    split_payments[][stack_order]

    Integer that defines the recipient's position in the Split Rule sequence. Required when setting a Split Rule. Values must start from 0 and increment by 1.

    split_header

    Boolean value. All bill and receipt templates will show Split Rule recipient's infographic if this was set to true.

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a Collection.

    title

    The Collection's title in string format.

    logo[thumb_url]

    The thumb dimension's (180x180) URL.

    logo[avatar_url]

    The avatar dimension's (40x40) URL.

    split_header

    Boolean value. All Bill and receipt templates will show Split Rule recipient's infographic if this is set to true.

    split_payments

    Array of Split Rule recipients. Each object contains the following fields.

    split_payments[email]

    The recipient's email address.

    split_payments[fixed_cut]

    The recipient's fixed cut in smallest and positive currency unit.

    split_payments[variable_cut]

    The recipient's percentage cut in positive integer format.

    split_payments[stack_order]

    The recipient's position in the Split Rule sequence.

    Example request:
    # Creates a collection
    curl https://www.billplz.com/api/v4/collections \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -F title="My First V4 API Collection"
    Response:
    {
      "id": "inbmmepb",
      "title": "My First V4 API Collection",
      "logo": {
        "thumb_url": null,
        "avatar_url": null
      },
      "split_header": false,
      "split_payments": []
    }
    Example request with optional arguments:
    curl https://www.billplz.com/api/v4/collections \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -F title="My First V4 API Collection" \
      -F split_payments[][email]="[email protected]" \
      -F split_payments[][fixed_cut]=100 \
      -F split_payments[][variable_cut]=2 \
      -F split_payments[][stack_order]=0 \
      -F split_payments[][email]="[email protected]" \
      -F split_payments[][fixed_cut]=200 \
      -F split_payments[][variable_cut]=3 \
      -F split_payments[][stack_order]=1
    Response:
    {
      "id": "inbmmepb",
      "title": "My First V4 API Collection",
      "logo": {
        "thumb_url": null,
        "avatar_url": null
      },
      "split_header": false,
      "split_payments": [
        {
          "email": "[email protected]",
          "fixed_cut": 100,
          "variable_cut": 2,
          "stack_order": 0
        },
        {
          "email": "[email protected]",
          "fixed_cut": 200,
          "variable_cut": 3,
          "stack_order": 1
        }
      ]
    }

    Get a Collection

    Retrieves a single Collection record.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v4/collections/{COLLECTION_ID}

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in the Collection object.

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a Collection.

    title

    The Collection's title in string format.

    logo[thumb_url]

    The thumbnail URL (180x180).

    logo[avatar_url]

    The avatar URL (40x40).

    split_header

    Boolean value. All Bill and receipt templates will show Split Rule recipient's infographic if this is set to true.

    split_payments

    Array of Split Rule recipients. Each object contains the following fields.

    split_payments[email]

    The recipient's email address.

    split_payments[fixed_cut]

    The recipient's fixed cut in smallest and positive currency unit.

    split_payments[variable_cut]

    The recipient's percentage cut in positive integer format.

    split_payments[stack_order]

    The recipient's position in the Split Rule sequence.

    status

    Collection's status, either active or inactive.


    Example request:
    # Get a collection
    curl https://www.billplz.com/api/v4/collections/inbmmepb \
    -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "id": "inbmmepb",
      "title": "My First API Collection",
      "logo": {
        "thumb_url": null,
        "avatar_url": null
      },
      "split_header": false,
      "split_payments": [
        {
          "email": "[email protected]",
          "fixed_cut": 100,
          "variable_cut": 2,
          "stack_order": 0
        },
        {
          "email": "[email protected]",
          "fixed_cut": 200,
          "variable_cut": 3,
          "stack_order": 1
        }
      ],
      "status": "active"
    }

    Get Collection index

    Retrieves your Collections list. To utilize paging, append a page parameter to the URL, e.g., ?page=1. If there are 15 records in the response, check if there is any more data by fetching the next page, e.g., ?page=2, and continue this process until no more results are returned.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v4/collections

    OPTIONAL ARGUMENTS

    Parameter

    Description

    page

    Up to 15 collections will be returned in a single API call per specified page. Defaults to 1 if not present.

    status

    Parameter to filter collection's status. Valid values are active and inactive.

    Example request:
    # Get collection index
    curl https://www.billplz.com/api/v4/collections \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "collections": [
        {
          "id": "inbmmepb",
          "title": "My First API Collection",
          "logo": {
            "thumb_url": null,
            "avatar_url": null
          },
          "split_header": false,
          "split_payments": [],
          "status": "active"
        }
      ],
      "page": 1
    }
    Example request with optional arguments:
    # Get collection index
    curl https://www.billplz.com/api/v4/collections?page=2&status=active \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "collections": [
        {
          "id": "inbmmepb",
          "title": "My First API Collection",
          "logo": {
            "thumb_url": null,
            "avatar_url": null
          },
          "split_header": false,
          "split_payments": [],
          "status": "active"
        }
      ],
      "page": 2
    }

    Customer receipt delivery

    By default, Collections follow the Global Customer Receipt Notification configuration in your Account settings. To configure the Global setting from the dashboard, see Manage receipt notifications in the Guide.

    You can override the Global configuration on individual collections by calling activate and deactivate.

    Activate

    Activates customer receipt email delivery for a specific Collection, overriding the Global configuration to always send receipt emails.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v4/collections/{COLLECTION_ID}/customer_receipt_delivery/activate

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in the Collection object.


    Example request:
    # Activate a collection's customer receipt delivery
    curl -X POST \
    https://www.billplz.com/api/v4/collections/qag4fe_o6/customer_receipt_delivery/activate \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {}

    Deactivate

    Deactivates customer receipt email delivery for a specific Collection, overriding the Global configuration to never send receipt emails.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v4/collections/{COLLECTION_ID}/customer_receipt_delivery/deactivate

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in the Collection object.

    Example request:
    # Deactivate a collection's customer receipt delivery
    curl -X POST \
    https://www.billplz.com/api/v4/collections/qag4fe_o6/customer_receipt_delivery/deactivate \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {}

    Set Global

    Resets a Collection to follow the Global Customer Receipt Notification configuration. Use this if you previously activated or deactivated receipt delivery for a Collection and want to restore the default Global behaviour.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v4/collections/{COLLECTION_ID}/customer_receipt_delivery/global

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in the Collection object.

    Example request:
    # Set a collection's customer receipt delivery to Global
    curl -X POST \
    https://www.billplz.com/api/v4/collections/qag4fe_o6/customer_receipt_delivery/global \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {}

    Get status

    Returns the customer receipt delivery status for a specific Collection.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v4/collections/{COLLECTION_ID}/customer_receipt_delivery

    URL PARAMETER

    Parameter

    Description

    COLLECTION_ID

    Collection ID returned in the Collection object.

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a collection.

    customer_receipt_delivery

    Collection's customer receipt delivery status. Returns active, inactive, or global.


    Example request:
    # Get a collection's customer receipt delivery
    curl https://www.billplz.com/api/v4/collections/qag4fe_o6/customer_receipt_delivery \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "id": "qag4fe_o6",
      "customer_receipt_delivery": "global"
    }

    Webhook rank

    Retrieves your account's webhook rank, which determines callback execution priority. The higher the ranking, the higher the priority. 0.0 indicates the highest ranking (default); 10.0 indicates the lowest.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v4/webhook_rank

    RESPONSE PARAMETER

    Parameter

    Description

    rank

    Ranking number (0.010.0).

    Example request:
    # Webhook rank
    curl https://www.billplz.com/api/v4/webhook_rank \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "rank": 0.0
    }

    Payment gateways

    Get payment gateways

    Returns a complete list of supported payment gateway codes for use as reference_1 when using the Direct payment gateway feature. This includes FPX banks and all other supported payment methods.

    HTTP REQUEST

    GET https://www.billplz.com/api/v4/payment_gateways

    RESPONSE PARAMETER

    Parameter

    Description

    code

    The gateway code to set as reference_1. Case sensitive.

    active

    Boolean. true if the gateway is available; false if unavailable. If an inactive or invalid gateway code is set as reference_1, the payment flow falls back to the Billplz Bill page.

    category

    Category this payment gateway belongs to.


    Example request:
    curl https://www.billplz.com/api/v4/payment_gateways \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81:
    Response:
    {
      "payment_gateways": [
        {
          "code": "MBU0227",
          "active": true,
          "category": "fpx"
        },
        {
          "code": "OCBC0229",
          "active": false,
          "category": "fpx"
        },
        {
          "code": "BP-FKR01",
          "active": true,
          "category": "billplz"
        },
        {
          "code": "BP-PPL01",
          "active": true,
          "category": "paypal"
        },
        {
          "code": "BP-2C2P1",
          "active": false,
          "category": "2c2p"
        },
        {
          "code": "BP-OCBC1",
          "active": true,
          "category": "ocbc"
        }
      ]
    }

    Payment gateway codes

    Lookup table mapping payment gateway codes to their corresponding names. Use these codes as reference_1 values when creating Bills with the Direct payment gateway feature.

    For a complete list of payment gateway codes (FPX, card, e-wallet, and staging), see Codes in the Reference section.

    Tokenization

    Tokenization lets you securely store a customer's card details in a provider's PCI-DSS certified vault and receive a token to charge the card later.

    Providers

    Provider

    Type

    Eligibility

    Senangpay

    3DS

    Any paid membership plan

    Ways to use tokenization

    • Tokenize a customer's card so they only need to enter their card details once.
    • Charge the customer's card against a Billplz Bill at any time and for any amount.
    • Pre-authorize a Bill payment and capture it later.

    Senangpay

    Senangpay tokenization stores 3DS Visa / Mastercard card details in Senangpay's PCI-DSS certified servers and returns a token you can use to charge the card on demand.

    Available endpoints

    Create card

    Creates a card token for 3DS Visa / Mastercard cards. Store the response, as no card details or tokens are stored on Billplz's servers.

    Flow

    • Create a card and token using this endpoint.
    • Redirect the cardholder to Senangpay's 3DS authentication page.
    • The cardholder inputs credit/debit card details and submits the form.
    • Upon 3DS verification success, Billplz sends a POST request to your callback_url containing masked card details together with CARD_ID and TOKEN.
    • Compare the checksum sent, and store the card details if they match.

    To charge a card with the token generated, refer to Charge card.

    HTTP REQUEST

    POST https://www.billplz.com/api/v4/cards

    REQUIRED ARGUMENTS

    Parameter

    Description

    name

    Name on the card / name of the cardholder.

    email

    Email of the cardholder.

    phone

    Contact number of the cardholder.

    callback_url

    Webhook URL to be called after the card token is created. It will POST a Card object.


    Example request:
    # Create a card token
    curl https://www.billplz.com/api/v4/cards \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d name="Michael" \
      -d email="[email protected]" \
      -d phone="60122345678" \
      -d callback_url="https://example.com/callback_url"
    Response:
    {
      "id": "8727fc3a-c04c-4c2b-9b67-947b5cfc2fb6",
      "card_number": null,
      "provider": null,
      "token": null,
      "status": "pending",
      "authentication_redirect_url": "https://senangpay.my/some_link",
      "callback_url": "https://example.com/callback_url"
    }

    Delete card

    Deletes a card.

    HTTP REQUEST

    DELETEhttps://www.billplz.com/api/v4/cards/{CARD_ID}

    REQUIRED ARGUMENTS

    Parameter

    Description

    token

    Card token.

    Example request:
    # Delete an active card token
    curl -X DELETE https://www.billplz.com/api/v4/cards/8727fc3a-c04c-4c2b-9b67-947b5cfc2fb6 \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d token="77d62ad5a3ae56aafc8e3529b89d0268afa205303f6017afbd9826afb8394740"
    
    Response:
    {
      "id": "8727fc3a-c04c-4c2b-9b67-947b5cfc2fb6",
      "card_number": "1118",
      "provider": "mastercard",
      "token": "77d62ad5a3ae56aafc8e3529b89d0268afa205303f6017afbd9826afb8394740",
      "status": "deleted"
    }

    3D Secure update

    Billplz sends a POST request to the callback_url provided within an hour, regardless of whether the cardholder has completed 3D Secure verification. This callback_url also serves as the redirect_url on the client side. Handle the redirect on every 3D Secure update, whether delivered via callback or redirect.

    HTTP REQUEST

    POST{CALLBACK_URL}

    POST PARAMETER

    Parameter

    Description

    id

    ID that represents card.

    card_number

    Last 4 digits of the card number.

    provider

    Card provider (e.g., mastercard, visa).

    token

    Card token.

    status

    Card's status. Possible values are pending, active, failed, and deleted.

    checksum

    Digital signature computed with posted data and shared X Signature key.

    CHECKSUM

    For security purposes, a checksum is included in the POST request so you can verify the request originated from Billplz. The checksum is computed the same way as the X Signature received on Payment Completion. Refer to X Signature for details.

    Example request to callback_url:
    # POST request sent by Billplz to your callback_url
    curl https://www.example.com/callback \
      -d id="a35296ad-b50c-4179-8024-036da00c1aee" \
      -d card_number="1118" \
      -d provider="mastercard" \
      -d token="77d62ad5a3ae56aafc8e3529b89d0268afa205303f6017afbd9826afb8394740" \
      -d status="active" \
      -d checksum="ef5e54a22af0925cba88fab467119742e90262e3646eea1dee3949938daf3a38"

    Charge card

    Makes a Bill payment by charging a Visa / Mastercard card with a token generated.

    REQUIREMENTS

    • Collection without split recipients (split payment).
    • Bill. email and mobile number are required during Bill creation.
    • Card token and ID.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v4/bills/{BILL_ID}/charge

    REQUIRED ARGUMENTS

    Parameter

    Description

    card_id

    ID that represents a card.

    token

    Card token.

    Example request:
    # Make bill payment with token
    curl https://www.billplz.com/api/v4/bills/awyzmy0m/charge \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d token="77d62ad5a3ae56aafc8e3529b89d0268afa205303f6017afbd9826afb8394740" \
      -d card_id="8727fc3a-c04c-4c2b-9b67-947b5cfc2fb6"
    Response:
    {
      "amount": 10000,
      "status": "success",
      "reference_id": "15681981586116610",
      "hash_value": "1b66606732d846192b0b6aa4b754b3c8addd59072fce4bdd066b5d631c31d5e8",
      "message": "Payment was successful"
    }

    Pre-auth

    Pre-authorizes a transaction with a token generated and captures the payment later. The amount is not charged to the card, but is blocked until the transaction is captured or released.

    REQUIREMENTS

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v4/bills/{BILL_ID}/preauth

    REQUIRED ARGUMENTS

    Parameter

    Description

    card_id

    ID that represents a card.

    token

    Card token.

    Example request:
    # Pre-authorize bill payment with token
    curl https://www.billplz.com/api/v4/bills/awyzmy0m/preauth \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d token="77d62ad5a3ae56aafc8e3529b89d0268afa205303f6017afbd9826afb8394740" \
      -d card_id="8727fc3a-c04c-4c2b-9b67-947b5cfc2fb6"
    Response:
    {
      "amount": 10000,
      "preauth_status": "success",
      "preauth_id": "732d8sdk778912e81003946192b0b6aa4b754b3c8addd5",
      "hash_value": "1b66606732d846192b0b6aa4b754b3c8addd59072fce4bdd066b5d631c31d5e8",
      "message": "Preauth was successful"
    }

    Pre-auth capture

    Captures a pre-authorized transaction with a token generated. The amount is charged to the card immediately.

    REQUIREMENTS

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v4/bills/{BILL_ID}/preauth_capture

    REQUIRED ARGUMENTS

    Parameter

    Description

    card_id

    ID that represents a card.

    token

    Card token.

    preauth_id

    ID for pre-authorized transaction.

    Example request:
    # Capture a pre-authorized transaction
    curl https://www.billplz.com/api/v4/bills/awyzmy0m/preauth_capture \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d token="77d62ad5a3ae56aafc8e3529b89d0268afa205303f6017afbd9826afb8394740" \
      -d card_id="8727fc3a-c04c-4c2b-9b67-947b5cfc2fb6" \
      -d preauth_id="732d8sdk778912e81003946192b0b6aa4b754b3c8addd5"
    Response:
    {
      "amount": 10000,
      "status": "success",
      "reference_id": "15681981586116610",
      "preauth_id": "732d8sdk778912e81003946192b0b6aa4b754b3c8addd5",
      "hash_value": "1b66606732d846192b0b6aa4b754b3c8addd59072fce4bdd066b5d631c31d5e8",
      "message": "Payment was successful"
    }

    V5

    V5 is in active development. New features are introduced in this version.

    Every request to a V5 endpoint must include epoch and checksum values in addition to each endpoint's required arguments.

    • The epoch parameter must be in UNIX epoch time format.
    • Checksum calculation is specific to each endpoint. Refer to the CHECKSUM ARGUMENTS section of each endpoint for the required values.
    • Calculate checksum signatures using HMAC_SHA512 with your account X Signature key. See V5 checksum for details.


    Payment Order Collections

    Payment Order Collections group your Payment Orders for managing disbursement transfers. Create a Payment Order Collection before creating Payment Orders within it.

    Create a Payment Order Collection

    The response contains the Collection ID required when creating Payment Orders.

    HTTP REQUEST

    POSThttps://www.billplz.com/api/v5/payment_order_collections

    REQUIRED ARGUMENTS

    Parameter

    Description

    title

    The Collection title. Will be displayed on bill template. String format.

    epoch

    The current time in UNIX epoch time format.

    checksum

    Required values for checksum signature in this order: [ title, callback_url*, epoch ]

    OPTIONAL ARGUMENTS

    Parameter

    Description

    callback_url

    Webhook URL called after a Payment Order transaction completes. Billplz sends a POST request with a Payment Order object. See Payment Order callback.

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a Payment Order Collection.

    title

    The Collection's title in string format.

    payment_orders_count

    The number of Payment Orders that belong to this Collection.

    paid_amount

    Total paid amount for Payment Orders in this Collection. A positive integer in the smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    status

    Collection's status, either active or inactive.

    callback_url

    Webhook URL called after a Payment Order transaction completes. Billplz sends a POST request with a Payment Order object. See Payment Order callback.

    Example request:
    # Create a Payment Order collection
    curl https://www.billplz.com/api/v5/payment_order_collections \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d title="My First API Payment Order Collection"  \
      -d epoch=1668147670 \
      -d callback_url="https://example.com/payment_order_collection_callback" \
      -d checksum="7ea7b8aed3093b058bfee1d67387f0d6f3be1d776ae3ebd82462237ccf2ffc1ae8b9bf38ad43a81bb2b15f817970afdf656dc622258230b08aa26c7418274041"
    Response:
    {
      "id": "8f4e331f-ac71-435e-a870-72fe520b4563",
      "title": "My First API Payment Order Collection",
      "payment_orders_count": "0",
      "paid_amount": "0",
      "status": "active",
      "callback_url": "https://example.com/payment_order_collection_callback"
    }

    Get a Payment Order Collection

    Retrieves a single Payment Order Collection record.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v5/payment_order_collections/{payment_order_collection_id}

    REQUIRED ARGUMENTS

    Parameter

    Description

    payment_order_collection_id

    The Payment Order Collection ID. A string.

    epoch

    The current time in UNIX epoch time format.

    checksum

    Required values for checksum signature in this order: [ payment_order_collection_id, epoch ]

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a Payment Order Collection.

    title

    The Collection's title in string format.

    payment_orders_count

    The number of Payment Orders that belong to this Collection.

    paid_amount

    Total paid amount for Payment Orders in this Collection. A positive integer in the smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    status

    Collection's status, either active or inactive.

    callback_url

    Webhook URL called after a Payment Order transaction completes. Billplz sends a POST request with a Payment Order object. See Payment Order callback.

    Example request:
    # Get a Payment Order collection
    curl -G https://www.billplz.com/api/v5/payment_order_collections/8f4e331f-ac71-435e-a870-72fe520b4563 \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d epoch=1668147747 \
      -d checksum="2bc6333ac9539e8fc5e520432373991403155f80315c7f3c601bd6a5535ee9ae70b0d8c29823ccf3be73a251caced9f5a165d6c0e9cadd451931ec3c1ede006d"
    Response:
    {
      "id": "8f4e331f-ac71-435e-a870-72fe520b4563",
      "title": "My First API Payment Order Collection",
      "payment_orders_count": "0",
      "paid_amount": "0",
      "status": "active",
      "callback_url": "https://example.com/payment_order_collection_callback"
    }

    Payment Order

    Payment Orders disburse funds from your Billplz account to any bank account registered in Malaysia. Each Payment Order must belong to a Payment Order Collection.

    Create a Payment Order

    To create a Payment Order, you need the Payment Order Collection ID. Each Payment Order must be created within a Payment Order Collection.

    HTTP REQUEST

    POST https://www.billplz.com/api/v5/payment_orders

    REQUIRED ARGUMENTS

    Parameter

    Description

    payment_order_collection_id

    Payment Order Collection ID. String format.

    bank_code

    SWIFT bank code that represents a bank. String format. Case sensitive.

    bank_account_number

    Bank account number. String format.

    name

    Payment Order's recipient name. Useful for recipient identification.

    description

    The Payment Order's description. Displayed on the Bill template. String format (Max of 200 characters). Special characters are not allowed.

    total

    Total amount to transfer to the recipient. A positive integer in the smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    epoch

    The current time in UNIX epoch time format.

    checksum

    Required values for checksum signature in this order: [ payment_order_collection_id, bank_account_number, total, epoch ]

    OPTIONAL ARGUMENTS

    Parameter

    Description

    email

    The email address of the recipient. Defaults to the sender's email if not present. A receipt will be sent to this email once the Payment Order has been processed.

    notification

    Boolean value. As a sender, you can opt in for email notification by setting this to true. Sender will receive an email once a Payment Order has been completed. Default value is false.

    recipient_notification

    Boolean value. When set to true, the recipient of the Payment Order will receive email notification once the Payment Order has been completed. Default value is true. Set to false to disable recipient email notifications.

    reference_id

    Payment Order's unique reference ID scoped by Payment Order Collection. This helps maintain data integrity by ensuring that no two rows of data in a Payment Order Collection have identical reference_id values. Useful to prevent unintentional Payment Order creation. (Max of 255 characters).

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a Payment Order.

    payment_order_collection_id

    Payment Order Collection ID.

    bank_code

    SWIFT bank code that represents a bank. String format. Case sensitive.

    bank_account_number

    Bank account number. String format.

    name

    Payment Order's recipient name.

    description

    The Payment Order's description.

    email

    The email address of the recipient. Defaults to the sender's email if not present.

    status

    Payment Order status. Possible values: processing, enquiring, executing, reviewing, completed, refunded.

    notification

    Boolean value. Sender will receive email notification if this is true.

    recipient_notification

    Boolean value. Recipient will receive email notification if this is true.

    total

    Total amount transferred to the recipient. A positive integer in the smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    reference_id

    Payment Order's reference ID. Useful for recipient identification.

    display_name

    Bank account owner's name.

    Example request:
    # Create a Payment Order for RM 20.00
    curl https://www.billplz.com/api/v5/payment_orders \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d payment_order_collection_id="8f4e331f-ac71-435e-a870-72fe520b4563" \
      -d bank_code="MBBEMYKL" \
      -d bank_account_number="543478924652" \
      -d name="Michael Yap" \
      -d description="Maecenas eu placerat ante." \
      -d total=2000 \
      -d epoch=1668148460 \
      -d checksum="1516c31cd226119732b66dd423a5ae8d9741594953dfb4bd510efc7349cd7579dc885014bbb67baf8398150cdba5ac42c35196ef1a1acea437386711e159ce62"
    Response:
    {
      "id": "ddfb5a5d-7b09-4f8c-9258-866f7ef4fa7c",
      "payment_order_collection_id": "8f4e331f-ac71-435e-a870-72fe520b4563",
      "bank_code": "MBBEMYKL",
      "bank_account_number": "543478924652",
      "name": "Michael Yap",
      "description": "Maecenas eu placerat ante.",
      "email": "[email protected]",
      "status": "enquiring",
      "notification": false,
      "recipient_notification": true,
      "total": "2000",
      "reference_id": null,
      "display_name": "Michael Yap"
    }
    Example request with optional arguments:
    # Create a Payment Order for RM 20.00
    curl https://www.billplz.com/api/v5/payment_orders \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d payment_order_collection_id="8f4e331f-ac71-435e-a870-72fe520b4563" \
      -d bank_code="MBBEMYKL" \
      -d bank_account_number="543478924652" \
      -d name="Michael Yap" \
      -d description="Maecenas eu placerat ante." \
      -d total=2000 \
      -d email="[email protected]" \
      -d notification=true \
      -d recipient_notification=false \
      -d reference_id="paymentOrder1" \
      -d epoch=1668148796 \
      -d checksum="fce47038896eb5c70fd33a8faf91529023cf67fa48afcc31adb20263e45a37b5cd0211fd95377a1053b9bbf70de0245c9117576998264eebb932f8244c878eed"
    Response:
    {
      "id": "cc92738f-dfda-4969-91dc-22a44afc7e26",
      "payment_order_collection_id": "8f4e331f-ac71-435e-a870-72fe520b4563",
      "bank_code": "MBBEMYKL",
      "bank_account_number": "543478924652",
      "name": "Michael Yap",
      "description": "Maecenas eu placerat ante.",
      "email": "[email protected]",
      "status": "enquiring",
      "notification": true,
      "recipient_notification": false,
      "total": "2000",
      "reference_id": "paymentOrder1",
      "display_name": "Michael Yap"
    }

    Get a Payment Order

    Retrieves a single Payment Order record.


    HTTP REQUEST

    GEThttps://www.billplz.com/api/v5/payment_orders/{payment_order_id}

    REQUIRED ARGUMENTS

    Parameter

    Description

    payment_order_id

    Payment Order ID. String format.

    epoch

    The current time in UNIX epoch time format.

    checksum

    Required values for checksum signature in this order: [ payment_order_id, epoch ]

    RESPONSE PARAMETER

    Parameter

    Description

    id

    ID that represents a Payment Order.

    payment_order_collection_id

    Payment Order Collection ID.

    bank_code

    SWIFT bank code that represents a bank. String format. Case sensitive.

    bank_account_number

    Bank account number. String format.

    name

    Payment Order's recipient name.

    description

    The Payment Order's description.

    email

    The email address of the recipient. Defaults to the sender's email if not present.

    status

    Payment Order status. Possible values: processing, enquiring, executing, reviewing, completed, refunded.

    notification

    Boolean value. Sender will receive email notification if this is true.

    recipient_notification

    Boolean value. Recipient will receive email notification if this is true.

    total

    Total amount transferred to the recipient. A positive integer in the smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    reference_id

    Payment Order's reference ID. Useful for recipient identification.

    display_name

    Bank account owner's name.


    Example request:
    # Get a Payment Order
    curl -G https://www.billplz.com/api/v5/payment_orders/cc92738f-dfda-4969-91dc-22a44afc7e26 \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d epoch=1668149595 \
      -d checksum="92987e17459c6e488b83c02dea1693615011fee049d88a3eb9745538f191e323ac4f067571aa8abc335075470b06693994443b52b78be22fbd12b44cb699b265"
    Response:
    {
      "id": "cc92738f-dfda-4969-91dc-22a44afc7e26",
      "payment_order_collection_id": "8f4e331f-ac71-435e-a870-72fe520b4563",
      "bank_code": "MBBEMYKL",
      "bank_account_number": "543478924652",
      "name": "Michael Yap",
      "description": "Maecenas eu placerat ante.",
      "email": "[email protected]",
      "status": "enquiring",
      "notification": true,
      "recipient_notification": false,
      "total": "2000",
      "reference_id": "paymentOrder1",
      "display_name": "Michael Yap"
    }

    SWIFT bank code

    For SWIFT bank codes used with the bank_code parameter, see SWIFT in the Reference section.

    Payment Order Limit

    The Payment Order Limit is the pre-funded balance available for Payment Order disbursements. See Reload your Payment Order Limit for top-up instructions.

    Get a Payment Order Limit

    Retrieves your current Payment Order Limit.

    HTTP REQUEST

    GEThttps://www.billplz.com/api/v5/payment_order_limit

    REQUIRED ARGUMENTS

    Parameter

    Description

    epoch

    The current time in UNIX epoch time format.

    checksum

    Required values for checksum signature in this order: [ epoch ]

    RESPONSE PARAMETER

    Parameter

    Description

    total

    Total amount available in your Payment Order Limit. A positive integer in the smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    Example request:
    # Get a Payment Order Limit
    curl -G https://www.billplz.com/api/v5/payment_order_limit \
      -u 73eb57f0-7d4e-42b9-a544-aeac6e4b0f81: \
      -d epoch=1685591208 \
      -d checksum="e18c50ca130db623d350123ed9cc0c83120361d1045737eb172396b3b41b0141c24c26de6ca41b66dfa476c2c5299a31df21c1fdbf6e0b585ea6e7a975fbd555"
    Response:
    {
      "total": "9600"
    }

    Payment Completion

    Billplz notifies your system when a Bill or Payment Order status changes using callbacks and optional redirects. This section covers both Bill completion (V3/V4) and Payment Order completion (V5).

    Callback vs redirect

    Callbacks (callback_url) are server-side POST requests from Billplz to your backend, guaranteeing backend-to-backend transaction updates. Callbacks are compulsory for all integrations.

    Redirects (redirect_url) are client-side browser redirects that send the customer back to your site after payment. They provide instant feedback but do not guarantee execution due to network issues, browser closures, or app closures. Redirects are optional.

    You are strongly advised to integrate both, redirects for better user experience and callbacks for reliable transaction updates.

    For a step-by-step walkthrough of configuring your callback and redirect URLs, see Webhook and callback setup in the Guide.

    Basic vs X Signature variants

    Two variants exist for each callback and redirect type:

    Basic — Legacy variant disabled by default for accounts registered from September 2018 onwards for security reasons. Basic callbacks and redirects do not include data integrity verification.

    X Signature — Recommended and enabled by default for accounts registered from September 2018. Includes HMAC-SHA256 signatures for Bill callbacks/redirects, allowing you to verify that requests originated from Billplz and data has not been tampered with.

    Payment Order callbacks (V5) use a separate checksum mechanism. See Payment Order Callback.

    Bill callback retry schedule (V3/V4)

    If your endpoint fails to respond with HTTP 200 within 20 seconds, Billplz retries the callback:

    • Attempt 2: 15 seconds + random 0–300 seconds after attempt 1
    • Attempt 3: 15 minutes + random 0–300 seconds after attempt 2
    • Attempt 4: 15 minutes + random 0–300 seconds after attempt 3
    • Attempt 5 (final): 24 hours + random 0–300 seconds after attempt 4

    Example: If attempt 1 is at 13:00:00, attempt 2 is at 13:00:15 + N seconds, attempt 3 is at 13:15:15 + N seconds, attempt 4 is at 13:30:15 + N seconds, and attempt 5 is at 13:30:15 + N seconds the next day.

    After 5 attempts, the callback is permanently removed from the queue.

    Payment Order callback retry schedule (V5)

    Payment Order callbacks retry once if your endpoint fails:

    • Attempt 2: 1 hour after attempt 1

    After 2 attempts, the callback is permanently removed from the queue.

    Account rank degradation

    X Signature Callback URL

    Billplz sends a POST request to callback_url with Bill data upon payment completion. Each request includes an x_signature generated using HMAC-SHA256 and your X Signature key, allowing you to verify that the request originated from Billplz.

    See Payment Completion overview for callback behaviour, retry schedule, and variant recommendations.

    If payment fails, the Bill remains in due state.

    HTTP REQUEST

    POST{CALLBACK_URL}

    POST PARAMETER

    Parameter

    Description

    id

    ID that represents the Bill.

    collection_id

    ID that represents the Collection where the Bill belongs to.

    paid

    Boolean value indicating whether the Bill has been paid. Returns false for due and deleted Bills; true for paid Bills.

    state

    State representing the Bill's status. Possible states are due, deleted, and paid.

    amount

    Bill amount in positive integer, smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    paid_amount

    Bill paid amount in positive integer, smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    due_at

    Due date for the Bill, in format YYYY-MM-DD. Example: 2020-12-31.

    email

    Email address of the Bill recipient.

    mobile

    Recipient mobile number in format +601XXXXXXXX.

    name

    Recipient name.

    url

    URL to the Bill page.

    paid_at

    Date time when the Bill was paid, in format YYYY-MM-DD HH:MM:SS TimeZone. Example: 2015-03-09 16:23:59 +0800.

    transaction_id

    ID that represents the transaction. Only included if Extra Payment Completion Information is enabled.

    transaction_status

    Transaction status. Possible statuses are pending, completed, and failed. Only included if Extra Payment Completion Information is enabled.

    x_signature

    Digital signature computed with posted data and your X Signature key.


    X Signature verification

    To verify that the request came from Billplz, compute the HMAC-SHA256 digest according to the steps below and compare it to the value in the x_signature parameter. If they match, the callback was sent from Billplz and the data has not been compromised.

    Sample POST body POST {CALLBACK_URL}:

    {:id=>"zq0tm2wc", :collection_id=>"yhx5t1pp", :paid=>true, :state=>"paid", :amount=>100, :paid_amount=>100, :due_at=>"2018-9-27", :email=>"[email protected]", :mobile=>nil, :name=>"TESTER", :url=>"http://www.billplz-sandbox.com/bills/zq0tm2wc", :paid_at=>"2018-09-27 15:15:09 +0800", :x_signature=>"0fe0a20b8d557eeae570377783d062a3816a9ea80f368860bacfa7ec3ca4d00e"}

    Step 1:
    Extract all key-value pair parameters except x_signature.

    id="zq0tm2wc"

    collection_id="yhx5t1pp"

    paid="true"

    state="paid"

    amount="100"

    paid_amount="100"

    due_at="2018-9-27"

    email="[email protected]"

    mobile=""

    name="TESTER"

    url="http://www.billplz-sandbox.com/bills/zq0tm2wc"

    paid_at="2018-09-27 15:15:09 +0800"

    Step 2:
    Construct source string from each key-value pair.

    idzq0tm2wc

    collection_idyhx5t1pp

    paidtrue

    statepaid

    amount100

    paid_amount100

    due_at2018-9-27

    [email protected]

    mobile

    nameTESTER

    urlhttp://www.billplz-sandbox.com/bills/zq0tm2wc

    paid_at2018-09-27 15:15:09 +0800

    Step 3:
    Sort in ascending order, case-insensitive.

    amount100

    collection_idyhx5t1pp

    due_at2018-9-27

    [email protected]

    idzq0tm2wc

    mobile

    nameTESTER

    paid_amount100

    paid_at2018-09-27 15:15:09 +0800

    paidtrue

    statepaid

    urlhttp://www.billplz-sandbox.com/bills/zq0tm2wc

    Step 4:
    Combine sorted source strings with | (pipe character).

    amount100|collection_idyhx5t1pp|due_at2018-9-27|[email protected]|idzq0tm2wc|mobile|nameTESTER|paid_amount100|paid_at2018-09-27 15:15:09 +0800|paidtrue|statepaid|urlhttp://www.billplz-sandbox.com/bills/zq0tm2wc

    Step 5:
    Compute x_signature using HMAC-SHA256 and your X Signature key.

    Sample X Signature key: S-s7b4yWpp9h7rrkNM1i3Z_g

    Computed x_signature: 0fe0a20b8d557eeae570377783d062a3816a9ea80f368860bacfa7ec3ca4d00e

    Step 6:
    Compare the computed x_signature with the value in the request.

    If they match, the callback was sent from Billplz and the data has not been compromised. You do not need to trigger an additional Get a Bill API call for primary status validation.

    Example server side request from Billplz:
    POST /webhook/ HTTP/1.1
    Connection: close
    Host: 127.0.0.1
    Content-Length: 346
    Content-Type: application/x-www-form-urlencoded
    
      id="W_79pJDk"
      &collection_id="599"
      &paid="true"
      &state="paid"
      &amount="200"
      &paid_amount="0"
      &due_at="2020-12-31"
      &email="[email protected]"
      &mobile="+60112223333"
      &name="MICHAEL API"
      &url="http://billplz.dev/bills/W_79pJDk"
      &paid_at="2015-03-09 16:23:59 +0800"
      &x_signature="f0ff6c564f98d5403e2b26fbd3d45309c76eb68d8c5bcda0d48b541c3502a396"
      
    Body formatted for readability.
    Example server side request from Billplz:
    POST /webhook/ HTTP/1.1
    Connection: close
    Host: 127.0.0.1
    Content-Length: 376
    Content-Type: application/x-www-form-urlencoded
    
      id="pjpetpdy"
      &collection_id="bvgo7ueb"
      &paid="true"
      &state="paid"
      &amount="100"
      &paid_amount="100"
      &due_at="2020-8-7"
      &email="[email protected]"
      &mobile=""
      &name="WILL"
      &url="http://www.billplz.test:3000/bills/pjpetpdy"
      &paid_at="2020-08-07 15:08:19 +0800"
      &transaction_id="711044E05418"
      &transaction_status="completed"
      &x_signature="b5ca81d0f1b87ab3b17580236735c68af92936de9aaa588751a4371ac4944a56"
      
    Body formatted for readability.

    X Signature Redirect URL

    If redirect_url exists, Billplz redirects the browser to redirect_url with Bill status data appended as URL parameters. Each redirect includes an x_signature generated using HMAC-SHA256 and your X Signature key, allowing you to verify that the redirect originated from Billplz.

    See Payment Completion overview for callback behaviour, retry schedule, and variant recommendations.

    HTTP REQUEST

    GETGET {REDIRECT_URL}?billplz[id]=zq0tm2wc&billplz[paid]=true&billplz[paid_at]=2018-09-27%2015%3A15%3A09%20%2B0800&billplz[x_signature]=4aab095fe5a39b1d534500988f9a0cb085cd1b6d5bbb55dd4e02ea6fa102b47b

    URL PARAMETER

    Parameter

    Description

    billplz[id]

    ID that represents the Bill.

    billplz[paid]

    Boolean value indicating whether the Bill has been paid. Returns false for due and deleted Bills; true for paid Bills.

    billplz[paid_at]

    Date time when the Bill was paid, in format YYYY-MM-DD HH:MM:SS TimeZone. Example: 2018-09-27 15:15:09 +0800.

    billplz[transaction_id]

    ID that represents the transaction. Only included if Extra Payment Completion Information is enabled.

    billplz[transaction_status]

    Transaction status. Possible statuses are pending, completed, and failed. Only included if Extra Payment Completion Information is enabled.

    billplz[x_signature]

    Digital signature computed with URL parameter data and your X Signature key.


    X Signature verification

    To verify that the request came from Billplz, compute the HMAC-SHA256 digest according to the steps below and compare it to the value in the x_signature parameter. If they match, the redirect was sent from Billplz and the data has not been compromised.

    Sample GET request:

    GET {REDIRECT_URL}?billplz[id]=zq0tm2wc&billplz[paid]=true&billplz[paid_at]=2018-09-27%2015%3A15%3A09%20%2B0800&billplz[x_signature]=4aab095fe5a39b1d534500988f9a0cb085cd1b6d5bbb55dd4e02ea6fa102b47b

    Step 1:
    Extract all key-value pair parameters except x_signature.

    billplz[id]="zq0tm2wc"

    billplz[paid]="true"

    billplz[paid_at]="2018-09-27 15:15:09 +0800"

    Step 2:
    Construct source string from each key-value pair.

    billplzidzq0tm2wc

    billplzpaidtrue

    billplzpaid_at2018-09-27 15:15:09 +0800

    Step 3:
    Sort in ascending order, case-insensitive.

    billplzidzq0tm2wc

    billplzpaid_at2018-09-27 15:15:09 +0800

    billplzpaidtrue

    Step 4:
    Combine sorted source strings with | (pipe character).

    billplzidzq0tm2wc|billplzpaid_at2018-09-27 15:15:09 +0800|billplzpaidtrue

    Step 5:
    Compute x_signature using HMAC-SHA256 and your X Signature key.

    Sample X Signature key: S-s7b4yWpp9h7rrkNM1i3Z_g

    Computed x_signature: 4aab095fe5a39b1d534500988f9a0cb085cd1b6d5bbb55dd4e02ea6fa102b47b

    Step 6:
    Compare the computed x_signature with the value in the request.

    If they match, the redirection was sent from Billplz and the data has not been compromised. You do not need to trigger an additional Get a Bill API call for primary status validation.

    Basic Callback URL

    Billplz sends a POST request to callback_url with Bill data upon payment completion. Basic Callback URL does not include signature verification.

    See Payment Completion overview for callback behaviour, retry schedule, and variant recommendations.

    If payment fails, the Bill remains in due state.

    HTTP REQUEST

    POST{CALLBACK_URL}

    POST PARAMETER

    Parameter

    Description

    id

    ID that represents the Bill.

    collection_id

    ID that represents the Collection where the Bill belongs to.

    paid

    Boolean value indicating whether the Bill has been paid. Returns false for due and deleted Bills; true for paid Bills.

    state

    State representing the Bill's status. Possible states are due, deleted, and paid.

    amount

    Bill amount in positive integer, smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    paid_amount

    Bill paid amount in positive integer, smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    due_at

    Due date for the Bill, in format YYYY-MM-DD. Example: 2020-12-31.

    email

    Email address of the Bill recipient.

    mobile

    Recipient mobile number in format +601XXXXXXXX.

    name

    Recipient name.

    metadata

    Deprecated hash value data.

    url

    URL to the Bill page.

    paid_at

    Date time when the Bill was paid, in format YYYY-MM-DD HH:MM:SS TimeZone. Example: 2017-02-13 05:43:43 +0800.

    Example server side request from Billplz:
    POST /webhook/ HTTP/1.1
    Connection: close
    Host: 127.0.0.1
    Content-Length: 346
    Content-Type: application/x-www-form-urlencoded
    
      id="W_79pJDk"
      &collection_id="599"
      &paid="true"
      &state="paid"
      &amount="200"
      &paid_amount="0"
      &due_at="2020-12-31"
      &email="[email protected]"
      &mobile="+60112223333"
      &name="MICHAEL API"
      &metadata[id]="9999"
      &metadata[description]="This is to test bill creation"
      &url="http://billplz.dev/bills/W_79pJDk"
      &paid_at="2015-03-09 16:23:59 +0800"
      
    Body formatted for readability.

    Basic Redirect URL

    If redirect_url exists, Billplz redirects the browser to redirect_url with the Bill ID appended as a URL parameter. Basic Redirect URL does not include signature verification.

    See Payment Completion overview for callback behaviour, retry schedule, and variant recommendations.

    HTTP REQUEST

    GET{REDIRECT_URL}?billplz[id]=W_79pJDk

    URL PARAMETER

    Parameter

    Description

    billplz[id]

    ID that represents the Bill.


    Payment Order Callback

    If callback_url exists in your Payment Order collection, Billplz sends a POST request with Payment Order data when the status changes to completed or refunded. Each request includes a checksum generated using HMAC-SHA512 and your X Signature key, allowing you to verify that the request originated from Billplz.

    See Payment Completion overview for general callback behaviour and variant recommendations.

    HTTP REQUEST

    POST{CALLBACK_URL}

    POST PARAMETER

    Parameter

    Description

    id

    ID that represents the Payment Order.

    payment_order_collection_id

    Payment Order collection ID in string format.

    bank_code

    Bank code that represents the bank, in string value.

    bank_account_number

    Bank account number, in string value.

    name

    Payment Order recipient name.

    description

    Payment Order description.

    email

    Email address of the recipient.

    status

    Payment Order status. Possible statuses are processing, completed, refunded, or cancelled.

    notification

    Boolean value.

    recipient_notification

    Boolean value.

    reference_id

    Payment Order reference ID. Useful for identification on the recipient side.

    display_name

    Bank account owner name.

    total

    Total amount transferred to the recipient. A positive integer in the smallest currency unit (e.g., 100 cents to charge MYR 1.00).

    epoch

    Current time in UNIX epoch time format.

    checksum

    Computed signature of strictly ordered values of key data present in the object.

    Callback requests time out at 20 seconds. Billplz expects your endpoint to respond with HTTP status code 200.

    If your endpoint cannot respond within 20 seconds or does not respond with HTTP 200, the callback is considered failed and rescheduled for a second attempt in one hour. After two attempts, the callback is permanently removed from the queue.

    Checksum verification

    To verify that the request came from Billplz, generate the checksum signature on your end using the values below in strict order and compare it to the checksum parameter sent with the Payment Order object. If they match, the callback was sent from Billplz and the data has not been compromised.


    Sample POST body POST {CALLBACK_URL}:

    {:id=>"0b924e37-7418-4d17-b234-8de424dc48e5",:payment_order_collection_id=>"0c78f8c6-5bd3-4663-8c08-9e2c805418a2",:bank_code=>"PHBMMYKL",:bank_account_number=>"1234567890",:name=>"Michael Yap",:description=>"Maecenas eu placerat ante.",:email=>"[email protected]",:status=>"refunded",:notification=>true,:recipient_notification=>true,:reference_id=>"My first payment order",:display_name=>nil,:total=>500000,:epoch=>1681895891, :checksum=>"2720f5ef16c7d04677829789fb74bccb08b90041e4e27916d85cb6fbbece58a7ab48538e8b62bcedab3b236bd38e6517860b593b8fe9bfa77bed979994f2ca1a"}

    Required values for checksum signature in this order: [id, bank_account_number, status, total, reference_id, epoch]

    Step 1:
    Format the raw string.

    Extract only the values of the keys listed above, in strict order.

    object_keys: [:id, :bank_account_number, :status, :total, :reference_id, :epoch]

    raw_string: "0b924e37-7418-4d17-b234-8de424dc48e51234567890refunded500000My first payment order1681895891"

    Step 2:
    Digest the raw string using HMAC-SHA512.

    Compute the HMAC-SHA512 digest of the raw string using your account X Signature key.

    example_XSignature: S-R5t3Uw6SrwXNWyZV-naVHg

    generated_checksum_value: 2720f5ef16c7d04677829789fb74bccb08b90041e4e27916d85cb6fbbece58a7ab48538e8b62bcedab3b236bd38e6517860b593b8fe9bfa77bed979994f2ca1a

    Step 3:
    Compare your generated checksum with the one included in the callback.

    If the values match, the request is valid from Billplz and the data has not been altered.


    Example Server Side Request from Billplz:
    POST /webhook/ HTTP/1.1
    Connection: close
    Host: 127.0.0.1
    Content-Length: 346
    Content-Type: application/x-www-form-urlencoded
    
      id="0b924e37-7418-4d17-b234-8de424dc48e5"
      &payment_order_collection_id="0c78f8c6-5bd3-4663-8c08-9e2c805418a2"
      &bank_code="PHBMMYKL"
      &bank_account_number="1234567890"
      &name="Michae Yap"
      &description="Maecenas eu placerat ante."
      &email="[email protected]"
      &status="refunded"
      &notification="false"
      &recipient_notification="true"
      &reference_id="My first payment order"
      &display_name=""
      &total=500000
      &epoch=1681895891
      &checksum="2720f5ef16c7d04677829789fb74bccb08b90041e4e27916d85cb6fbbece58a7ab48538e8b62bcedab3b236bd38e6517860b593b8fe9bfa77bed979994f2ca1a"
      
    Body formatted for readability.
    Sample of callback POST request Payment Order Object from Billplz:
    {
      "id": "0b924e37-7418-4d17-b234-8de424dc48e5",
      "payment_order_collection_id": "0c78f8c6-5bd3-4663-8c08-9e2c805418a2",
      "bank_code": "PHBMMYKL",
      "bank_account_number": "1234567890",
      "name": "Michae Yap",
      "description": "Maecenas eu placerat ante.",
      "email": "[email protected]",
      "status": "refunded",
      "notification": "false",
      "recipient_notification": "true",
      "reference_id": "My first payment order",
      "display_name": "",
      "total": 500000,
      "epoch": 1681895891,
      "checksum": "2720f5ef16c7d04677829789fb74bccb08b90041e4e27916d85cb6fbbece58a7ab48538e8b62bcedab3b236bd38e6517860b593b8fe9bfa77bed979994f2ca1a"
    }

    Security

    V5 Checksum

    V5 API introduces request-level authentication. Every V5 endpoint request must include epoch and checksum parameters in addition to each endpoint's required arguments.

    • epoch must be in UNIX epoch time format
    • checksum calculation is endpoint-specific — refer to the CHECKSUM ARGUMENTS section of each endpoint for the required parameters
    • Checksum signature must be calculated using HMAC_SHA512 with your X Signature key (the same key used for X Signature callback verification, but with a different algorithm)

    Step 1:
    Format the raw string

    Concatenate the values of the parameters listed in the endpoint's CHECKSUM ARGUMENTS section, in the exact order specified.

    Example:

    For creating a payment order collection, the checksum arguments are [ title, epoch ]. With parameters {title: "My payment order title", epoch: 1681724303}, your raw string is:

    My payment order title1681724303

    Step 2:
    Sign the raw string

    Calculate the checksum signature by signing the raw string using HMAC_SHA512 with your X Signature key.

    Example:

    Using the raw string above with X Signature key S-R5t3Uw6SrwXNWyZV-naVHg:

    Expected checksum signature:

    575c35c13ba37ccc2a434529e5082a71a574d304ba007592af44339d4436467d6a49107c95e51905cd80dce0f745760bd42fe73e2bc3bcd7ab79d07cc7fb4fa4

    Step 3:
    Include optional arguments

    Some endpoints include optional arguments in the checksum calculation. These optional arguments are denoted with an asterisk (*) in the endpoint's CHECKSUM ARGUMENTS guide.

    If you include an optional argument in your request parameters, include its value in the checksum raw string at the position indicated. If you do not include the optional argument, omit it from the checksum calculation.

    Example:

    With parameters {title: "My payment order title", callback_url: 'https://myawesomeweb.site', epoch: 1681724303} where callback_url is optional, your raw string is:

    My payment order titlehttps://myawesomeweb.site1681724303

    References

    Lookup tables for codes used across the Billplz API, and a reference of HTTP error codes returned by all endpoints.

    • Codes — Payment gateway and bank codes for Bill creation and Payment Order disbursement
    • Errors — HTTP status codes and their meanings

    Codes

    Reference tables for all payment gateway and bank codes used across the Billplz API. These codes are used as reference_1 when creating Bills via the Direct payment gateway feature (V3, V4), or as bank_code when creating Payment Orders (V5).

    FPX

    Use these codes as reference_1 when creating Bills via the Direct payment gateway.

    Retail / B2C

    Code

    Name

    ABMB0212

    allianceonline

    ABB0233

    affinOnline

    AMBB0209

    AmOnline

    AGRO01

    AGRONet

    BCBB0235

    CIMB Clicks

    BIMB0340

    Bank Islam Internet Banking

    BKRM0602

    i-Rakyat

    BMMB0341

    i-Muamalat

    BSN0601

    myBSN

    CIT0219

    Citibank Online

    HLB0224

    HLB Connect

    HSBC0223

    HSBC Online Banking

    KFH0346

    KFH Online

    MB2U0227

    Maybank2u

    MBB0228

    Maybank2E

    OCBC0229

    OCBC Online Banking

    PBB0233

    PBe

    RHB0218

    RHB Now

    SCB0216

    SC Online Banking

    UOB0226

    UOB Internet Banking

    Corporate / B2B

    Code

    Name

    B2B1-ABB0235

    AFFINMAX

    B2B1-ABMB0213

    Alliance BizSmart

    B2B1-AGRO02

    AGRONetBIZ

    B2B1-AMBB0208

    AmAccess Biz

    B2B1-BCBB0235

    BizChannel@CIMB

    B2B1-BIMB0340

    Bank Islam eBanker

    B2B1-BKRM0602

    i-bizRAKYAT

    B2B1-BMMB0342

    iBiz Muamalat

    B2B1-BNP003

    BNP Paribas

    B2B1-CIT0218

    CitiDirect BE

    B2B1-DBB0199

    Deutsche Bank Autobahn

    B2B1-HLB0224

    HLB ConnectFirst

    B2B1-HSBC0223

    HSBCnet

    B2B1-KFH0346

    KFH Online

    B2B1-MBB0228

    Maybank2E

    B2B1-OCBC0229

    Velocity@ocbc

    B2B1-PBB0233

    PBe

    B2B1-PBB0234

    PB enterprise

    B2B1-RHB0218

    RHB Reflex

    B2B1-SCB0215

    SC Straight2Bank

    B2B1-UOB0228

    UOB BIBPlus

    Card and e-wallet

    Use these codes as reference_1 when creating Bills via the Direct payment gateway for non-FPX payment methods.

    Code

    Name

    BP-BILLPLZ1

    Visa / Mastercard (Billplz)

    BP-PPL01

    PayPal

    BP-OCBC1

    Visa / Mastercard

    BP-2C2P1

    e-pay

    BP-2C2PC

    Visa / Mastercard

    BP-2C2PU

    UnionPay

    BP-2C2PGRB

    Grab

    BP-2C2PGRBPL

    GrabPayLater

    BP-2C2PATOME

    Atome

    BP-2C2PBST

    Boost

    BP-2C2PTNG

    TnG

    BP-2C2PSHPE

    Shopee Pay

    BP-2C2PSHPQR

    Shopee Pay QR

    BP-2C2PIPP

    IPP

    BP-BST01

    Boost

    BP-TNG01

    TouchNGo E-Wallet

    BP-SGP01

    Senangpay

    BP-BILM1

    Visa / Mastercard

    BP-RZRGRB

    Grab

    BP-RZRBST

    Boost

    BP-RZRTNG

    TnG

    BP-RZRPAY

    RazerPay

    BP-RZRMB2QR

    Maybank QR

    BP-RZRWCTP

    WeChat Pay

    BP-RZRSHPE

    Shopee Pay

    BP-MPGS1

    MPGS

    BP-CYBS1

    Secure Acceptance

    BP-EBPG1

    Visa / Mastercard

    BP-EBPG2

    AMEX

    BP-PAYDE

    Paydee

    BP-MGATE1

    Visa / Mastercard / AMEX

    SWIFT

    Use these codes as bank_code when creating a Payment Order.

    Code

    Bank

    PHBMMYKL

    Affin Bank Berhad

    AGOBMYKL

    Agrobank / Bank Pertanian Malaysia Berhad

    MFBBMYKL

    Alliance Bank Malaysia Berhad

    RJHIMYKL

    Al Rajhi Banking & Investment Corporation (Malaysia) Berhad

    ARBKMYKL

    AmBank (M) Berhad

    BIMBMYKL

    Bank Islam Malaysia Berhad

    BKRMMYKL

    Bank Kerjasama Rakyat Malaysia Berhad

    BMMBMYKL

    Bank Muamalat (Malaysia) Berhad

    BSNAMYK1

    Bank Simpanan Nasional Berhad

    CIBBMYKL

    CIMB Bank Berhad

    CITIMYKL

    Citibank Berhad

    HLBBMYKL

    Hong Leong Bank Berhad

    HBMBMYKL

    HSBC Bank Malaysia Berhad

    KFHOMYKL

    Kuwait Finance House

    MBBEMYKL

    Maybank / Malayan Banking Berhad

    OCBCMYKL

    OCBC Bank (Malaysia) Berhad

    PBBEMYKL

    Public Bank Berhad

    RHBBMYKL

    RHB Bank Berhad

    SCBLMYKX

    Standard Chartered Bank (Malaysia) Berhad

    UOVBMYKL

    United Overseas Bank (Malaysia) Berhad

    Staging

    The following codes are only available in the staging environment and cannot be used in production.

    Code

    Name

    ABB0234

    Affin Bank

    BOCM01

    Bank of China

    BP-FKR01

    Billplz Simulator

    B2B1-TEST0021

    SBI Bank A

    B2B1-TEST0022

    SBI Bank B

    B2B1-TEST0023

    SBI Bank C

    TEST0001

    Test 0001

    TEST0002

    Test 0002

    TEST0003

    Test 0003

    TEST0004

    Test 0004

    TEST0021

    Test 0021

    TEST0022

    Test 0022

    TEST0023

    Test 0023

    UOB0229

    UOB Bank

    Errors

    The Billplz API uses standard HTTP status codes to indicate request success or failure. All error responses return JSON format.

    Code

    Meaning

    401

    Unauthorized — Your Billplz Secret Key is incorrect, missing, or you're using the wrong environment (sandbox key against production URL).

    404

    Not Found — The requested resource does not exist. Check the resource ID and endpoint URL.

    422

    Unprocessable Entity — Request parameters are invalid or the resource cannot be processed.

    429

    Too Many Requests — Reached the rate limit. See Rate limit for details.

    500

    Internal Server Error — Something went wrong on Billplz's servers. Retry after a few minutes.

    503

    Service Unavailable — Billplz is temporarily offline for maintenance. Retry after a few minutes.

    For troubleshooting guidance, common causes, and resolution steps for each error code, see Common API error codes in the Guide.