Skip to main content

Recurring Payment

Create and manage subscriptions and recurring payment

How subscription works

API Environment

Environment NameURL
Sandboxhttps://openapi-int.qfapi.com

API Resources

For build and manage subscriptions, the following API resources are required:

API Resources
Customer
Payment Token
Product
Subscription

Create subscription steps

enter image description here

info

Current flow of subscription creation

  1. Config your notification address, you will receive notification to get token_id and track the state change of subscription.
  2. Create customer object and get customer_id
  3. Using customer_id and card information to create token intent and get token_id
  4. Create product object and get product_id, your subscription transaction amount for each billing cycle and the interval between two billing cycles will be defined in product object.
  5. Create subscription object using customer_id, product_id and token_id, your subscription start time and total billing cycles will be defined in subscription object.

Subscription state

state diagram All subscription state will be pushed to merchant's backend service once triggered

Common API response parameter

AttributeTypeDescription
respcdStringReturn code, 0000 = API call succeeded
resperrStringresult description
respmsgStringinformation description
dataObjectresult, JSON object or list of JSON object

Customer

Customer is an API resource for merchant to store customer's information. This object can be used in PaymentToken, Subscription APIs

Create customer object

Endpoint : /customer/v1/create

Method : POST

Request parameters

AttributeTypeMandatoryDescription
nameStringNocustomer name
phoneStringNocustomer contact no.
emailStringNocustomer email address
billing_addressStringNocustomer billing address, stringify JSON object

Response parameters in data field

AttributeTypeDescription
customer_idStringunqiue customer ID in QF system
nameStringcustomer name
phoneStringcustomer contact no.
emailStringcustomer email address
billing_addressJSONcustomer billing address

Update customer object

Endpoint : /customer/v1/update

Method : POST

Request parameters:

AttributeTypeMandatoryDescription
customer_idStringYesunqiue customer ID in QF system
nameStringNocustomer name
phoneStringNocustomer contact no.
emailStringNocustomer email address
billing_addressJSONNocustomer billing address

Response parameters in data field:

AttributeTypeDescription
customer_idStringunqiue customer ID in QF system
nameStringcustomer name
phoneStringcustomer contact no.
emailStringcustomer email address
billing_addressJSONcustomer billing address

Inquiry customer object

Endpoint : /customer/v1/query

Method : POST

Request parameters

AttributeTypeMandatoryDescription
customer_idStringNounqiue customer Id in QF system
nameStringNocustomer name
phoneStringNocustomer contact no.
emailStringNocustomer email address
pageIntNodefault value = 1
page_sizeIntNodefault value = 10, the max value is 100

Response parameters in data field

Array of customer objects contianing the following attributes

AttributeTypeDescription
customer_idStringunqiue customer ID in QF system
nameStringcustomer name
phoneStringcustomer contact no.
emailStringcustomer email address

Delete customer object

permanently delete customer object, cannot be undo. Any subscription plan associated with the deleted customer will be cancelled.

Endpoint : /customer/v1/delete

Method : POST

Request parameters

AttributeTypeMandatoryDescription
customer_idStringYesunique customer identifier in QF system

Product

Products are the model for goods or services that merchants will provide to the customers. It defines transaction amount, transaction currency and billing cycles(if applicable). This object will be used in subscription API.

Create product object

create a new product

Endpoint : /product/v1/create

Method : POST

Request parameters

AttributeTypeMandatoryDescription
nameStringYesproduct name that displays to the customer
typeStringNodefault value=onetime, possible values: onetime, recurring
descriptionStringNoproduct descritpion
txamtIntYestransaction amount, e.g. $1=100. Suggest value > 200 to avoid risk control
txcurrcdStringYestransaction currency, e.g. HKD
intervalStringNopossible values: monthly, yearly, mandatory for recurring product
interval_countIntNointerval between 2 charges, maximum 1 year allowed, mandatory for recurring product
usage_typeStringNodefault value=licensed, possible values: licensed

Response parameters in data field

AttributeTypeDescription
product_idStringunique identifer generated in QF system
nameStringproduct name that displays to the customer
typeStringdefault value=onetime, possible values: onetime, recurring
descriptionStringproduct descritpion
txamtInttransaction amount, e.g. $1=100.
txcurrcdStringtransaction currency, e.g. HKD
intervalStringpossible values: monthly, yearly
interval_countIntinterval between 2 charges
usage_typeStringdefault value=licensed, possible values: licensed

Update product object

update current product information

Endpoint : /product/v1/update

Method : POST

Request parameters

AttributeTypeMandatoryDescription
product_idStringYesunique identifier generated in QF system
nameStringNoproduct name that displays to the customer
descriptionStringNoproduct descritpion

Response parameters in data field

AttributeTypeDescription
product_idStringunique product identifer generated in QF system
nameStringproduct name that displays to the customer
typeStringdefault value=onetime, possible values: onetime, recurring
descriptionStringproduct descritpion
txamtInttransaction amount, e.g. $1=100.
txcurrcdStringtransaction currency, e.g. HKD
intervalStringpossible values: monthly, yearly
interval_countIntinterval between 2 charges
usage_typeStringdefault value=licensed, possible values: licensed

Inquiry product object

Endpoint : /product/v1/create

Method : POST

Request parameters

AttributeTypeMandatoryDescription
product_idStringNounique product identifier generated in QF system
nameStringNoproduct name that displays to the customer
descriptionStringNoproduct descritpion
txcurrcdStringNotransaction currency
intervalStringNopossible values: monthly,yearly
pageIntNopage no., default value=1
page_sizeIntNopage size, default value=10,max value=100

Response parameters in data field

Array of product objects containing the following attributes:

AttributeTypeDescription
product_idStringunique identifer generated in QF system
nameStringproduct name that displays to the customer
typeStringpossible values: onetime, recurring
descriptionStringproduct descritpion
txamtInttransaction amount, e.g. $1=100.
txcurrcdStringtransaction currency, e.g. HKD
intervalStringpossible values: monthly, yearly
interval_countIntinterval between 2 charges
usage_typeStringpossible values: licensed

Delete product object

note

only can delete product that is not assoicated with any subscription object

Endpoint : /product/v1/delete

Method : POST

Request parameters

AttributeTypeMandatoryDescription
product_idStringNounique product identifier generated in QF system

Subscription

QFPay automatically charges the customers on every billing cycle based on the product with the provided Payment Token until the subscription is finished or cancelled. Before create subscription, payment token, customer and product must be created.

Create subscription object

Endpoint : /subscription/v1/create

Method : POST

Request parameters

AttributeTypeMandatoryDescription
customer_idStringYesunique customer identifier in QF system
token_idStringYesunique payment token identifier in QF system
productsObjectYeslist of unique product identifier in QF system and quantity
total_billing_cyclesIntNothe total billing cycles of the subscirption, infinity if null value
start_timeStringNothe time subscription will start to work, the first payment will be

parameters in products:

AttributeTypeMandatoryDescription
product_idStringYesunique production identifier in QF system
quantityIntNodefault value=1

example request format:

{
"products": [
{
"product_id": "prod_54c3772d******9a54b236e09ec74f",
"quantity": 1
}
],
"customer_id": "cust_aaf6aae94******982c54c9cae5ba32",
"token_id": "tk_a99892fd*********d3417d168a18bb",
"total_billing_cycles": 2,
"start_time": "2020-05-14 12:32:56"
}

Response parameters in data field

AttributeTypeDescription
customer_idStringunique customer identifier in QF system
token_idStringunique payment token identifier in QF system
productsObjectlist of unique product identifier in QF system and quantity
total_billing_cyclesIntthe total billing cycles of the subscirption, infinity cycles if null value
start_timeStringthe time subscription will start to work

example response format:

{
"resperr": "success",
"respcd": "0000",
"respmsg": "success",
"data": {
"state": "ACTIVE",
"subscription_id": "sub_ce65d6feb8******d1b2e5fc90b1ef"
}
}

Update subscription object

update current subscription

Endpoint : /subscription/v1/update

Method : POST

Request parameters

AttributeTypeMandatoryDescription
subscription_idStringYesunique subscription identifier in QF system
total_billing_cyclesIntNothe total billing cycles of the subscirption, infinity if null value
start_timeStringNothe time that subscription will start to work, it will be the first subscription payment time
token_idStringNounique payment token identifier in QF system
productsObjectNolist of unique product identifier in QF system and quantity

Response parameters in data field

AttributeTypeDescription
subscription_idStringunique subscription identifier in QF system
customer_idStringunique customer identifier in QF system
token_idStringunique payment token identifier in QF system
productsObjectlist of unique product identifier in QF system and quantity
total_billing_cyclesIntthe total billing cycles of the subscirption, infinity cycles if null value
start_timeStringthe time that subscription will start to work, it will be the first subscription payment time
stateStringsubscription state

Inquiry subscription object

Endpoint : /subscription/v1/query

Method : POST

Request parameters

AttributeTypeMandatoryDescription
pageIntNopage no.,default value=1
page_sizeIntNopage size, default value=10, max value=100
subscritpion_idStringNounique subscription identifier in QF system
customer_idStringNounique customer identifier in QF system
token_idStringNounique payment otken identifier in QF system
stateStringNosubscription state, e.g. incompelete, active,...

Response parameters in data field

Array of subscription object containing the following attributes:

AttributeTypeDescription
subscription_idStringunique subscription identifier in QF system
customer_idStringunique customer identifier in QF system
token_idStringunique payment token identifier in QF system
productsObjectlist of unique product identifier in QF system and quantity
total_billing_cyclesIntthe total billing cycles of the subscirption, infinity cycles if null value
stateStringsubscription state
next_billing_timeStringnext fund deduct time
last_billing_timeStringprevious fund deduct time
completed_billing_iterationInthow many billing cycles completed
start_timeStringthe time that subscription will start to work, it will be the first subscription payment time

Cancel subscription object

cancel customer's subscription immediately

Endpoint : /subscription/v1/cancel

Method : POST

Request parameters

AttributeTypeMandatoryDescription
subscription_idStringYesunique ID of subscription object

Query subscription orders

query target subscription's orders

Endpoint : /subscription/billing_order/v1/list

Method : POST

Request parameters

AttributeTypeMandatoryDescription
subscription_idStringYesunique ID of subscription object
pageIntNopage no.,default value=1
page_sizeIntNopage size, default value=10, max value=100

Response parameters in data field

Array of subscription order object containing the following attributes:

AttributeTypeDescription
subscription_order_idStringsubscription order identifier, format: sub_ord_ + id value of subscription_id + 4 digit order sequence number (iteration of this subscription) e.g. sub_ord_a360f06exxxxxxx4c3a_0001 stands for the first payment order for subscription sub_a360f06exxxxxxx4c3a
subscription_idStringunique subscription identifier in QF system, format: sub_xxxxxxxx e.g. sub_a360f06exxxxxxx4c3a
trigger_byStringwho triggered this order payment, QF system is auto, Manual charge is manual
sequence_noIntthe iteration of this order in the subscription plan, e.g. 2

Manaul charge a subscription transaction

Use API to charge a subscription immediately for a failed order.

Endpoint : /subscription/v1/charge

Method : POST

Request parameters

AttributeTypeMandatoryDescription
subscription_idStringYesunique ID of subscription object
subscription_order_idStringNounique ID of subscription order object

This API only applied for a subscription that having a failed order and in the state UNPAID, INCOMPLETE, or PAST_DUE. For the case that the payment is successed, if manual charge date is before scheduled next billing date, the subscription plan will continue to work with state ACTIVE, if the manual charge date is after next billing date, the subscription plan will be cancelled. If the payment is failed, the subscription plan will keep the original state.

Recurring payment actions

Ansynchronous notification

Notifications are available for both payment token and subscription events and states change

Upon successful payment token creation or subscription activation, QFPay API will send an asynchronous notification message to the URL that defined by the merchant

note

To configure notification address, please send the address as well as merchant and store information via email to technical.support@qfpay.com

Format: JSON

Payment Token

AttributeDescritpion
useridQFPay Store ID
notify_typenotification type, payment_token
eventtoken event when created, possible value: NEW, MATCH(existing token for this card), CONFLICT(card information is different from existing token for this card)
tokenidpayment token id
token_expiry_datetoken expiry date
cardcdcard no.
card_schemecard scheme, e.g. VISA
respcdresponse code, e.g. 0000 (success case)
respmsgresponse message, e.g. success
sysdtmevent trigger system time
customer_idcustomer id if available
token_reasontokenization reason
token_referencetokenization reference in system

example:

{
"respmsg": "",
"card_scheme": "ECMC_DEBIT",
"cardcd": "5200****1096",
"tokenid": "tk_6a699aae75094caeb066f****988daa32de",
"respcd": "0000",
"token_expiry_date": "2024-04-30 00:00:00",
"sysdtm": "2024-04-29 15:37:17",
"notify_type": "payment_token",
"event": "CONFLICT"
}

Subscription state change

Available when a subscription state is changed

AttributeDescritpion
notify_typenotification type,subscription
subscription_idunique subscription identifier, format: sub_xxxxxxxx
statesubscription state, e.g. COMPLETED, ACTIVE, for the full list of states please reference State
sysdtmsystem time of state change

example:

{
"state": "COMPLETED",
"sysdtm": "2024-04-24 15:19:39",
"notify_type": "subscription",
"subscription_id": "sub_e51bb914919*****f6b0fe36d"
}

Subscription payment result

Available when a subscription order payment result is received

AttributeDescritpion
notify_typenotification type, subscription_payment
subscription_idunique subscription identifier, format: sub_xxxxxxxx e.g. sub_a360f06exxxxxxx4c3a
subscription_order_idsubscription order identifier, format: sub_ord_ + id value of subscription_id + 4 digit order sequence number (iteration of this subscription) e.g. sub_ord_a360f06exxxxxxx4c3a_0001
respcdresponse code, e.g. 0000 (success case)
respmsgresponse message, e.g. success
syssntranscation number
txdtmtranscation time
txamttranscation amount.
txcurrcdtranscation currency
customer_idunique customer identifier, format:cust_xxxxxx
product_idunique product identifier for all products, separated by comma, e.g.: prod_xxxxxa23f30,prod_xxxxxbe342ac
cardcdcard no.
card_schemeonly available for 0000, card scheme, e.g. VISA
current_iterationcurrent iteration of this subscription, e.g. 1

example:

{
"txcurrcd": "HKD",
"reason": "AUTHORISED",
"cardcd": "",
"subscription_order_id": "sub_ord_a360f06eb*****ad6aff24c3a",
"product_id": "prod_8c838c17ddb043b9***11f1a85c30",
"txdtm": "2024-04-24 15:19:37",
"txamt": "300",
"card_scheme": "VISA_DEBIT-SSL",
"syssn": "20240424180500020000015704",
"respcd": "0000",
"subscription_id": "sub_e51bb914919***31d800f6b0fe36d",
"customer_id": "cust_a9c0bcf2717f4***786a10e5f8f2",
"notify_type": "subscription_payment",
"current_iteration": "1",
}