NAV
shell php

PayNow APIs and Payment Request APIs

HitPay provides a seamless payment experience for your customers and an easy integration process for the developers.

With Hitpay's API integration you can start accepting multiple payment methods including PayNow (Singapore), Visa, Master, GrabPay, Apple Pay, Google Pay, American Express, AliPay, and WeChat Pay on a single checkout page hosted on hitpay.

HitPay's PayNow integrations allow you to fully automate PayNow acceptance in Singapore with instant feedback and webhook.

PayNow API

  1. Create payment request URLs, each request has a unique Request Id.
  2. Your customer using the URL makes the payment with their choice of payment method.
  3. You receive the payment confirmation with a unique Payment ID.

Hitpay also provides plugins for all popular e-commerce platforms without any need for API integrations:
Shopify, WooCommerce, Wix, Magento, Prestashop, EasyStore, OpenCart, Ecwid and Xero

Setup

  1. Create a Hitpay account https://dashboard.sandbox.hit-pay.com
  2. Setup PayNow (Singapore Only) in the HitPay Dashboard under Settings > Payment Methods > PayNow
  3. Connect Stripe account (to accepts card payments) under Settings > Payment Methods > Credit Cards
  4. Generate API keys under Settings > Payment Gateway > API Keys. These keys will give you access to create payment requests.

Note:

You can test all our API endpoints in our Sandbox Platform. By signing up on our Sandbox account, you can mock transactions to do end-to-end testing of your Integration flow.

The base URL for production environment will be https://api.hit-pay.com/v1/

The base URL for Sandbox environment will be https://api.sandbox.hit-pay.com/v1/

Integration Steps

Step 1 Create a payment request
Step 2 Presenting the Checkout UI
Step 3 Handle payment status using webhooks

Authentication

To authorize, use this code:

# With shell, you can just pass the correct header with each request
curl "api_endpoint_here"
  -H "X-BUSINESS-API-KEY: meowmeowmeow"
  -H "X-Requested-With: XMLHttpRequest"
$request->setHeaders(array(
  'X-BUSINESS-API-KEY' => 'meowmeowmeow',
  'Content-Type' => 'application/x-www-form-urlencoded',
  'X-Requested-With' => 'XMLHttpRequest'
));

Make sure to replace meowmeowmeow with your API key.

Hitpay uses API keys to allow access to the API. You can register a new API key at our developer portal.

Hitpay expects for the API key to be included in all API requests to the server in a header that looks like the following:

X-BUSINESS-API-KEY: meowmeowmeow

Payment Requests

Create Payment Request

curl POST "https://api.sandbox.hit-pay.com/v1/payment-requests"
  -H "X-BUSINESS-API-KEY: meowmeowmeow"
  -H "X-Requested-With: XMLHttpRequest"
  -H "Content-Type: application/x-www-form-urlencoded"
  -data-urlencode "email=tom@test.com"
  -data-urlencode "redirect_url=https://test.com/success"
  -data-urlencode "webhook=https://test.com/webhook"
  -data-urlencode "amount=599"
  -data-urlencode "currency=SGD"

$client = new http\Client;
$request = new http\Client\Request;
$request->setRequestUrl('https://api.sandbox.hit-pay.com/v1/payment-requests');
$request->setRequestMethod('POST');
$body = new http\Message\Body;
$body->append(new http\QueryString(array(
  'email' => 'tom@test.com',
  'redirect_url' => 'https://test.com/success',
  'reference_number' => 'REF123',
  'webhook' => 'https://test.com/webhook',
  'currency' => 'SGD',
  'amount' => '599')));$request->setBody($body);
$request->setOptions(array());
$request->setHeaders(array(
  'X-BUSINESS-API-KEY' => 'meowmeowmeow',
  'Content-Type' => 'application/x-www-form-urlencoded',
  'X-Requested-With' => 'XMLHttpRequest'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();

The above command returns JSON structured like this:

{
    "id": "90f28b43-2cff-4f86-a29e-15697424b3e7",
    "name": null,
    "email": "tom@test.com",
    "phone": null,
    "amount": "599.00",
    "currency": "SGD",
    "status": "pending",
    "purpose": null,
    "reference_number": null,
    "payment_methods": [
        "paynow_online",
        "card",
        "wechat",
        "alipay"
    ],
    "url": "https://securecheckout.sandbox.hit-pay.com/payment-request/@amazone-prime-pte-ltd/90f28b43-2cff-4f86-a29e-15697424b3e7/checkout",
    "redirect_url": "https://test.com/success",
    "webhook": "https://test.com/webhook",
    "send_sms": true,
    "send_email": true,
    "sms_status": "pending",
    "email_status": "pending",
    "allow_repeated_payments": true,
    "expiry_date": null,
    "created_at": "2020-07-03T02:18:49",
    "updated_at": "2020-07-03T02:18:49"
}

This endpoint creates a new payment request. This is the first step of the payment flow, once you have all the details from the user and ready to collect payment use this API to create a payment request.
Since this is a server-to-server communication, if you have a mobile or Web client that communicates with your REST API, you must have a new endpoint E.g. /create-order ,or reuse an existing endpoint. This endpoint will be responsible for making the payment request API call to hitpay.

HTTP Request

POST https://api.sandbox.hit-pay.com/v1/payment-requests

Query Parameters

Parameter Description Example
amount Amount related to the payment 2500.00
payment_methods[] Choice of payment methods you want to offer the customer paynow_online , card, wechat, alipay, grabpay
currency Currency related to the payment SGD
email Buyer’s email foo@test.com
purpose Purpose of the Payment request FIFA 16
name Buyer’s name John Doe
reference_number Arbitrary reference number that you can map to your internal reference number. This value cannot be edited by the customer XXXX123
redirect_url URL where we redirect the user after a payment. Query arguments reference (payment request id) and status are sent along https://test.com/callback
webhook URL where our server do POST request after a payment If done https://test.com/webhook
allow_repeated_payments If set to true, multiple payments can be paid on a payment request link. Default value is false false
expiry_date Time after which the payment link will be expired(time in SGT). Applicable for repeated payments. Default is Null 2021-02-02 01:01:01
send_email If set to true, an email receipt will be sent to the customer after the payment is completed. Default is false true

Response

All the request data included

Parameter Description
id Payment request id

Delete Payment request

curl DELETE "https://api.sandbox.hit-pay.com/v1/payment-requests/{request_id}"
  -H "X-BUSINESS-API-KEY: meowmeowmeow"
  -H "X-Requested-With: XMLHttpRequest"
  -H "Content-Type: application/x-www-form-urlencoded"

The above command returns JSON structured like this:

{
    "success": true
}

This is an optional API call, you may use this to delete a specific payment request.

HTTP Request

DELETE https://api.sandbox.hit-pay.com/v1/payment-requests/<ID>

URL Parameters

Parameter Description
ID Payment request ID

Get Payment Status

curl GET "https://api.sandbox.hit-pay.com/v1/payment-requests/{request_id}"
  -H "X-BUSINESS-API-KEY: meowmeowmeow"
  -H "X-Requested-With: XMLHttpRequest"
  -H "Content-Type: application/x-www-form-urlencoded"
$client = new http\Client;
$request = new http\Client\Request;
$request->setRequestUrl('https://api.sandbox.hit-pay.com/v1/payment-requests/{request_id}');
$request->setRequestMethod('GET');
$request->setOptions(array());
$request->setHeaders(array(
  'X-BUSINESS-API-KEY' => 'meowmeowmeow',
  'X-Requested-With' => 'XMLHttpRequest'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();

The above command returns JSON structured like this:

{
    "id": "90f34585-537f-4cce-8607-629f53c23827",
    "name": null,
    "email": "tom@test.com",
    "phone": null,
    "amount": "599.00",
    "currency": "SGD",
    "status": "completed",
    "purpose": null,
    "reference_number": null,
    "payment_methods": [
        "paynow_online",
        "card",
        "wechat",
        "alipay"
    ],
    "url": "https://securecheckout.sandbox.hit-pay.com/payment-request/@amazone-prime-pte-ltd/90f34585-537f-4cce-8607-629f53c23827/checkout",
    "redirect_url": "https://test.com/callback",
    "webhook": "https://test.com/webhook",
    "send_sms": true,
    "send_email": true,
    "sms_status": "pending",
    "email_status": "pending",
    "allow_repeated_payments": false,
    "expiry_date": null,
    "created_at": "2020-07-03T10:59:38",
    "updated_at": "2020-07-03T11:00:07",
    "payments": [
        {
            "id": "90f3459d-1f07-4127-8d68-691b0b239207",
            "quantity": 1,
            "status": "succeeded",
            "buyer_name": null,
            "buyer_phone": null,
            "buyer_email": "tom@test.com",
            "currency": "sgd",
            "amount": "599.00",
            "payment_type": "card",
            "fees": "5.36",
            "created_at": "2020-07-03T10:59:53",
            "updated_at": "2020-07-03T11:00:10"
        }
    ]
}

This is an optional API call, you may use this to get the status of a specific payment request.

HTTP Request

GET https://api.sandbox.hit-pay.com/v1/payment-requests/<ID>

Request Parameters

Parameter Description
ID Payment request ID

Response Parameters

Includes all the data from Create Payment Request

Parameter Description
ID Payment request ID
status completed/expired/pending/failed. pending if pending payment or the if the id is repeating payment
payments array of payments made to this request ID. Will contain more than one if its a repeating payment link

Presenting the Checkout UI

// Applicable only for Drop-In mode. Include hitpay.js in your website
<script src="https://hit-pay.com/hitpay.js"></script>

// Initialise 
// DEFAULT_URL = https://securecheckout.sandbox.hit-pay.com/payment-request/@test/

window.HitPay.init('DEFAULT_URL', {
  // Optional 
  // closeOnError: true 
},
  // Optional callbacks
{
    onClose: onClose,
    onSuccess: onSuccess,
    onError: onError
})

// Show Drop In UI
window.HitPay.toggle({
    paymentRequest: '93d015df-b0b6-4cbd-8a4b-938eb79e33b2'
})
// Applicable only for Drop-In mode. Include hitpay.js in your website
<script src="https://hit-pay.com/hitpay.js"></script>

// Initialise 
// DEFAULT_URL = https://securecheckout.sandbox.hit-pay.com/payment-request/@test/

window.HitPay.init('DEFAULT_URL', {
  // Optional 
  // closeOnError: true 
},
  // Optional callbacks
{
    onClose: onClose,
    onSuccess: onSuccess,
    onError: onError
})

// Show Drop In UI
window.HitPay.toggle({
    paymentRequest: '93d015df-b0b6-4cbd-8a4b-938eb79e33b2'
})

After the payment request is completed, your server must return the payment_request_id and url values to the client. There are 2 ways to present the checkout UI "Redirect to HitPay checkout" or "Present Drop-In UI"

Option 1: Redirect to HitPay checkout

Navigate your user to the url, hitpay will take care of the rest of the flow. Once the payment is completed the user will be navigated back to the "redirect_url" that was configured during the payment request step, along with the status


PayNow API

Option 2: Present the Drop-In:

Unlike the redirect checkout page, the drop-in is embedded into your webpage so your customer will never have to leave your site. To present this you will need 2 values "default_link" and "payment_request_id". Default link value can be found in your Dashboard > Payment Links > Default link and this value is fixed for all your payment.

Sample code for Drop-In UI can be found here
PayNow Drop-In UI

Webhook

    public function generateSignatureArray($secret, array $args) 
    {   
        $hmacSource = [];        

        foreach ($args as $key => $val) {
            $hmacSource[$key] = "{$key}{$val}";
        }    

        ksort($hmacSource);

        $sig            = implode("", array_values($hmacSource));
        $calculatedHmac = hash_hmac('sha256', $sig, $secret); 

        return $calculatedHmac;
    }

Sample webhook payload data:

payment_id=92965a2d-ece3-4ace-1245-494050c9a3c1&payment_request_id=92965a20-dae5-4d89-a452-5fdfa382dbe1&reference_number=ABC123&phone=&amount=599.00&currency=SGD&status=completed&hmac=330c34a6a8fb9ddb75833620dedb94bf4d4c2e51399d346cbc2b08c381a1399c

Webhook is a POST request send from HitPay's server to your server about the payment confirmation. If you are using hitpay APIs to integrate into your e-commerce checkout you must mark your order as paid ONLY after the webhook is received and validated.

  1. Create an endpoint (E.g. /payment-confirmation/webhook) in your server that accepts POST requests. This request is application/x-www-form-urlencoded.
  2. Validate the webhook data using your salt value
  3. Return HTTP status code 200 to Hitpay
  4. Mark your order as paid

Webhook fields

Following fields are sent with the webhook request:

Parameter Description
payment_id Payment ID
payment_request_id Payment request ID
phone Buyer’s phone number
amount Amount related to the payment
currency Currency related to the payment
status Payment status (completed / failed)
reference_number Arbitrary reference number that you have mapped during payment request creation
hmac Message Authentication code of this webhook request

Validate Webhook

Hitpay creates a list of all values from the key-value pairs that we send in the POST request and sort them in the order of their keys alphabetically. We then concatenate all these values together. We then use the HMAC-SHA256 algorithm to generate the signature. The HMAC key for the signature generation is the secret salt from your dashboard under Settings > Payment Gateway > API Keys.

Hitpay PHP API Wrapper: https://github.com/hit-pay/php-sdk

Signature Mismatch?

Possible reasons for wrong hmac value generated

Refund

curl POST "https://api.hit-pay.com/v1/refund"
  -H "X-BUSINESS-API-KEY: meowmeowmeow"
  -H "X-Requested-With: XMLHttpRequest"
  -H "Content-Type: application/x-www-form-urlencoded"
  -data-urlencode "amount=25"
  -data-urlencode "payment_id=942E8DD7-93AC-4DA5-A354-GA3410F2890B"
$client = new http\Client;
$request = new http\Client\Request;
$request->setRequestUrl('https://api.hit-pay.com/v1/refund');
$request->setRequestMethod('POST');
$body = new http\Message\Body;
$body->append(new http\QueryString(array(
  'payment_id' => '942E8DD7-93AC-4DA5-A354-GA3410F2890B',
  'amount' => '25')));$request->setBody($body);
$request->setOptions(array());
$request->setHeaders(array(
  'X-BUSINESS-API-KEY' => 'meowmeowmeow',
  'Content-Type' => 'application/x-www-form-urlencoded',
  'X-Requested-With' => 'XMLHttpRequest'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();

The above command returns JSON structured like this:

{
    "id": "94429a3a-c94d-49d8-adb2-341fb8386a8d9",
    "payment_id": "942E8DD7-93AC-4DA5-A354-GA3410F2890B",
    "amount_refunded": 25.00,
    "total_amount": 599.00,
    "currency": "sgd",
    "status": null,
    "payment_method": "card",
    "created_at": "2021-08-28T16:02:42"
}

This is an optional API call, you may use this to refund of a specific payment.

Parameter Description Example
amount Amount to refund 25
payment_id Payment ID for the successful payment request 42e8bb7-93ac-4da5-a354-f49610f2890b

Production Checklist

Ensure the following before moving to production

  1. Change the base URL for all API calls to https://api.hit-pay.com/v1/
  2. Finish paynow and other payment methods set up in production
  3. Update API keys and Salt values from the production dashboard
  4. If you are using Drop-In UI, update the default link to the production URL

Platform APIs

Overview

Hitpay Platform APIs are an extension of the above Payment Request APIs are used by e-commerce platforms or aggregators who host other merchants. Platforms will have the ability to create payment requests on behalf of the merchants that are on their platform.

Platforms will also have the ability to set a commission for the transactions that happen through their platform.

Integrations Flow

  1. Contact to Hitpay to signup for a Platform Account
  2. Individual merchant creates a Hitpay account https://dashboard.sandbox.hit-pay.com
  3. Individual merchant will setup PayNow (Singapore Only) in the HitPay Dashboard under Settings > Payment Methods > PayNow
  4. Individual merchant will generate API keys under Settings > Payment Gateway > API Keys. (Merchant API keys)
  5. These keys will give you access to create payment requests.

To authorize, use this code:

# With shell, you can just pass the correct header with each request
curl "api_endpoint_here"
  -H "X-BUSINESS-API-KEY: meowmeowmeow"
  -H "X-PLATFORM-KEY: bowbowbow"
  -H "X-Requested-With: XMLHttpRequest"
$request->setHeaders(array(
  'X-BUSINESS-API-KEY' => 'meowmeowmeow',
  'X-PLATFORM-KEY' => 'bowbowbow',
  'Content-Type' => 'application/x-www-form-urlencoded',
  'X-Requested-With' => 'XMLHttpRequest'
));

Make sure to replace meowmeowmeow with your Merchant API key and bowbowbow with your Platform API key.

Platform Authentication

Hitpay uses API keys to allow access to the API. Once your account is converted to “Platform Account” you can you can access your “Platform API Key” (Settings > Payment Gateway > Platform). This Platform API Key along with Merchant API key is expected to be included in all API requests to the server in a header that looks like the following:

X-BUSINESS-API-KEY: meowmeowmeow X-PLATFORM-KEY: bowbowbow

Errors

Hitpay API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
404 Not Found -- The payment request could not be found.
500 Internal Server Error -- We had a problem with our server. Try again later.