Skip to main content

Overview

If your billing model uses dynamic amounts or does not follow a fixed cycle, you can save a customer’s payment method and charge it later on demand. This feature supports: This API integration has 4 main steps:

Create a Recurring Billing

Create a recurring billing with save payment method enabled

Present the Checkout UI

Redirect the customer to attach a payment method

Charge the Saved Method

Charge the saved card or APM anytime

Handle Payment Processing

After the customer confirms, handle payment processing and schedule recurring charges.

Step 1 – Save a Payment Method

This step creates the billing session the customer will use to attach their payment method.

HTTP Request

POST https://api.sandbox.hit-pay.com/v1/recurring-billing

Query Parameters

Mandatory fields are name, customer_email, and amount. Remember to include the header Content-Type: application/x-www-form-urlencoded.
ParameterDescriptionExample
namePlan nameSpotify Premium
descriptiondescription of the planSpotify Membership
save_payment_methodNew. Saves any supported payment method (cards or APMs) to charge later. Recommended.true
save_cardDeprecated field, equivalent to save_payment_method. Still supported for now.true
customer_emailCustomer email[email protected]
customer_nameCustomer namePaul
amountAmount related to the recurring billing9.90
currencyCurrency related to the recurring billingSGD
payment_methods[]Choice of payment methods you want to offer the customer. Default value is cardgiro, card, grabpay_direct, shopee_pay
redirect_urlURL where hitpay redirects the user after the users enters the card details and the subscription is active. Query arguments reference (subscription id) and status are sent alonghttps://spotify.com/subscription-completed
referenceArbitrary reference number that you can map to your internal reference number. This value cannot be edited by the customerXXXX123
webhookOptional URL value to which hitpay will send a POST request when there is a new charge or if there is an error charging the cardhttps://webhoo.site/test
send_emailHitpay to send email receipts to the customer. Default value is falsetrue
curl --location --request POST 'https://api.staging.hit-pay.com/v1/recurring-billing' \
--header 'X-BUSINESS-API-KEY: meowmeowmeow' \
--header 'X-Requested-With: XMLHttpRequest' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'name=Spotify Premium' \
--data-urlencode 'description=Spotify Membership' \
--data-urlencode 'save_payment_method=true' \
--data-urlencode '[email protected]' \
--data-urlencode 'customer_name=Paul' \
--data-urlencode 'amount=9.90' \
--data-urlencode 'currency=SGD' \
--data-urlencode 'payment_methods[]=giro' \
--data-urlencode 'payment_methods[]=card' \
--data-urlencode 'payment_methods[]=shopee_pay' \
--data-urlencode 'payment_methods[]=grabpay_direct' \
--data-urlencode 'redirect_url=https://spotify.com/subscription-completed' \
--data-urlencode 'reference=cust_id_123' \
--data-urlencode 'webhook=https://webhoo.site/test' \
--data-urlencode 'send_email=true'

Response

{
    "id": "9741164c-06a1-4dd7-a649-72cca8f9603a",
    "business_recurring_plans_id": "",
    "customer_name": "Paul",
    "customer_email": "[email protected]",
    "name": "Spotify Premium",
    "description": "Spotify Membership",
    "reference": "cust_id_123",
    "cycle": "save_card",
    "cycle_repeat": null,
    "cycle_frequency": null,
    "currency": "sgd",
    "amount": 9.9,
    "times_to_be_charged": 3,
    "times_charged": 0,
    "status": "scheduled",
    "send_email": false,
    "save_card": 1,
    "redirect_url": "https://github.com/",
    "payment_methods": ["giro", "card", "grabpay_direct", "shopee_pay"],
    "created_at": "2022-09-13T16:33:47",
    "updated_at": "2022-09-13T16:33:47",
    "expires_at": null,
    "url": "https://securecheckout.staging.hit-pay.com/9673bdea-058c-44b5-a957-845a7c487bc2/recurring-plan/9741164c-06a1-4dd7-a649-72cca8f9603a",
    "webhook": "https://webhoo.site/test"
}

Step 2 - Redirect customer to recurring billing page (One time set up)

Redirect the customer to the “url” value. Recurring Billing API UI Once the customer completes the flow, their card or supported APM will be saved and ready to charge.

Step 3 - Charge the Saved Payment Method

Use this endpoint anytime after the customer attaches their payment method to charge it.

HTTP Request

POST https://api.sandbox.hit-pay.com/v1/charge/recurring-billing/{recurring-billing-id}
recurring-billing-id is the id value from step 1 response.

Query Parameters

ParameterDescriptionExample
currencyCurrency related to the recurring billingSGD
amountAmount related to the recurring billing9.90
curl --location --request POST 'https://api.sandbox.hit-pay.com/v1/charge/recurring-billing/{recurring_billing_id}' \
--header 'X-BUSINESS-API-KEY: meowmeowmeow' \
--header 'X-Requested-With: XMLHttpRequest' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI4YjdiYzdhYS1iZGUxLTQzODAtYjQ5ZS03ZjFiYWViOGMzY2UiLCJqdGkiOiJjYTA4NjVmMjMxYzA2Yjg2NTY5ODc1ZTFkNjVlMmUwM2EwMmI1ZDcxZTBiMTEwMWUwYzE4Y2Y3NWU2ZjYwZmM0MTIxYmVkMTExZWI4YjRlZSIsImlhdCI6MTY2MzExNzUxOCwibmJmIjoxNjYzMTE3NTE4LCJleHAiOjE2OTQ2NTM1MTcsInN1YiI6IjkwMjdjYTRkLTBhYmItNDk2NC04MzIxLTQ0NWQ0YjMyNzY5NCIsInNjb3BlcyI6W119.VfQoR_luqIZKSBTEXMv_srTVRApk9OfimbX_ghmRkCjrnvZUm-gCSHUbVnBUSzUcjRbVs-rCFs5wKZX4V0bL_76_WqBwxmNzsxRFf-QXFHSt1dDG7TnH6OSduHFeI-6akfQX0DGqal2pStz-UQY07lUiJ_aRe6QnvYqKZaA_eKsAn5XnEo0vn92mk8_i9KTxhvPH85qinfpg23-j3RJNlTDXeRWPn7CmufsrFfdRGtDL2h2thyqEQvju47XAM_Nyar2IjHw_ZcT9ZWnS7sskSwrsrBmOvjSuHA-ANr55ufc11GwjdRyzBPLu3SOUJ8kHJnprdep70VIpYLtO_nKG1xMzJRJzSno-Hvhn7RzjT-xpSudfUzRKb6M9z_BVmSQ8eUfuigwcmadH-pAFP67noNQAL5zeOjlr4RXGRKoMdeOOM4hxciojZRqoiBT-i74aAHg0AAlJHx4NQnM4LcDkN_Sh0kK4Ip4BHZHuxE4t9CZ24erizjXcdwvzv0UG0QCYRSfWN41PcHTbljDXQWmV719PDtPVwoAb1Ht2EKzuAQ4umuLx6NzOpBFuXpElZfwVT9XoDr22Dwts-7cW2fqj_C6igptqoAeRuCGEejDRgq2dA-UJTpRxfi6J02XXKpeDv-hGyFCYE8TUHBqTg5HMRQeHtga3-Hq05IPFhp9fmyk' \
--data-urlencode 'amount=9.90' \
--data-urlencode 'currency=SGD
Response
{
    "payment_id": "9746f906-bdbb-4064-8372-642cf5877e0c",
    "recurring_billing_id": "9746f8c2-2b7c-4c78-8832-012f203ae687",
    "amount": 9.9,
    "currency": "sgd",
    "status": "succeeded"
}

Step 4: Handle Successful Payment

Webhooks

HitPay will send a Webhook POST request when there is a new charge or if there is an error charging the card.
If you are using HitPay APIs to integrate into your app 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
sample webhook payload data
payment_id=974f65d6-88ea-42a0-a67a-15acafc4dc66&recurring_billing_id=9741164c-06a1-4dd7-a649-72cca8f9603a&amount=9.90&currency=sgd&status=succeeded&reference=cust_id_123&hmac=7690ff7ab7d88480a480b8be722f6dd12cc58f489da25c504dbe29c04b297418

Webhook fields

Following fields are sent with the webhook request:
ParameterDescription
payment_idPayment ID
recurring_billing_idRecurring billing request ID
amountAmount related to the recurring billing
currencyCurrency related to the recurring billing
statusPayment status (succeeded / failed)
referenceArbitrary reference number that you have mapped during recurring billing 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 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;
    }
Congrats! You’ve successfully completed the integration for saving a payment method.

FAQs

No, hitpay does not support authorization or holding of card transaction.
Yes, a minimum amount of 1 is required to initiate the save-payment-method session.
Yes, once your customer has attached a payment method to the subscription, you can charge any amount using the charge the saved payment method API.
Ensure the following before moving to production - Change the base URL for all API calls to https://api.hit-pay.com/v1/ - Update API keys and Salt values from the production dashboard