Integration Steps

Integration Steps

Authentication

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

Hitpay expects 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

$request->setHeaders(array(
  'X-BUSINESS-API-KEY' => 'meowmeowmeow',
  'Content-Type' => 'application/x-www-form-urlencoded',
  'X-Requested-With' => 'XMLHttpRequest'
));
# 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"

❗️

API Security

API keys should be kept confidential and only stored on your servers. Do not store it on your mobile or web client.

Step 1: Create Payment Request

This is the first step of the payment flow, once you have all the details from the user and are ready to collect payments, 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

Mandatory fields are amount and currency. Remember to include header Content-Type: application/x-www-form-urlencoded
ParameterDescriptionExample
amountAmount related to the payment2500.00
payment_methods[]Choice of payment methods you want to offer the customerpaynow_online , card, wechat, alipay, grabpay, fave_duit, shopback, atome
currencyCurrency related to the paymentSGD
emailBuyer’s email[email protected]
purposePurpose of the Payment request FIFA 16
nameBuyer’s nameJohn Doe
reference_numberArbitrary reference number that you can map to your internal reference number. This value cannot be edited by the customerXXXX123
redirect_urlURL where we redirect the user after a payment. Query arguments reference (payment request id) and status are sent alonghttps://example.com/callback
webhookURL where our server do POST request after a payment If donehttps://example.com/webhook
allow_repeated_paymentsIf set is true, multiple payments can be paid on a payment request link. Default value is falsefalse
expiry_dateTime after which the payment link will be expired(time in SGT). Applicable for repeated payments. Default is Null2021-02-02 01:01:01
$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' => '[email protected]',
  '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();

Response

{
    "id": "90f28b43-2cff-4f86-a29e-15697424b3e7",
    "name": null,
    "email": "[email protected]",
    "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"
}

Step 2: Presenting the Checkout UI

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, and 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

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". The 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

📘

NOTE

Drop-in UI currently does not support Apple Pay.

🚧

Warning

Do not use status or onSuccess to mark your order as completed. Please refer to the webhook section for more details.

Step 3: Handle Successful payment

Once the payment is completed, the user will be redirected to "redirect_url" defined in step 1. You might be tempted to just use the "redirect_url" to mark your order as completed and show an "Order Success" screen to your users but this could be a security issue. You must always use the "Webhook" to confirm your order.

Webhooks

Webhook is a POST request sent 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
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 fields

Following fields are sent with the webhook request:

ParameterDescription
payment_idPayment ID
payment_request_idPayment request ID
phoneBuyer’s phone number
amountAmount related to the payment
currencyCurrency related to the payment
statusPayment status (completed / failed)
reference_numberArbitrary reference number that you have mapped during payment request creation
hmacMessage 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.

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;
    }

Signature Mismatch?

Possible reasons for wrong hmac value generated

  1. Ensure that you are using the correct salt value from the correct environment (Sandbox or Production)
  2. Make sure NOT to include the hamc value when calculating the hmac
  3. Make sure all the values stated above are included in the payload including reference_number. Use an empty string if the value does not exist

Next Step

Congrats! You have now successfully completed the payment integration.

Refund API: This is an optional API call, you may use this to refund a specific payment.
Production Checklist: Checkout before you go live.
Payment Request: Reference to the API Details