# UnionPay ExpressPay API
ExpressPay (UPOP Mode, hereinafter referred to as ExpressPay) provides a fast and convenient UnionPay online payment solution to acquirers and merchants. It allows cardholder to stay on merchant/acquirer page to complete a payment on different terminals, such as PC, laptop, tablet and other mobile devices. ExpressPay will process E-commerce Non-Authentication mode transactions for acquirers. ExpressPay can accept UnionPay credit cards, signature debit cards, signature prepaid cards, and PIN debit/PIN prepaid cards issued outside Mainland China, Hong Kong and Macau. This mode allows acquirers or merchants to utilize UPOP system’s interface via Internet.
- There are two modes for credit card integration:
Simple Purchase
Recurring Purchase
# Sign generate and check
# Request and response format
All request and response are in JSON format. The response body is also in JSON format. It should not be treated as fixed or as a schema, new fields may be added as the API evolves, and the order of fields might change. Your applications must therefore be resilient to the reordering of fields within a JSON object.
# Sending request demo code
$arr = array(
'mchOrderNo' => 'm12345',
'mchUserId' => 'jacky.chen@yahoo.com' //user id assigned by merchant
'mchId' => 'your merchant id',
'currency' => 'CAD',
'amount' => 100, // in cents
'loginName' => 'jack', //your login name
'notifyUrl' => 'http://yourdomain.com/notifyme.php',
'returnUrl' => 'http://yourdomain.com/returnhere.php',
'subject' => "ipad pro",
'body' => '64G,wifi,white',
'channel' => 'UPI_EX'
);
$Utility = new Utility();
$sort_array = $Utility->arg_sort($arr); //sort the parameters
$arr['sign'] = $Utility->build_mysign($sort_array, $merchantKey, "MD5"); //generate sign and put it into the array
$param = json_encode($arr); //generate json string to send
$resBody = $Utility->request($url, $param);//Submit to the gateway
$res = json_decode($resBody, true);
if ($res['retCode'] == 'SUCCESS') {
header('Location: ' . $res['redirectUrl']);//Redirect to payment page
} else {
echo $res['retMsg'];
}
# Simple purchase
User input card info and purchase once, users will be prompted to input card info each time when they purchase.
# Sequence
1, Call cc_purchase and redirect to redirectUrl to let user input credit card info;
2, After purchase, will redirect to returnUrl;
3, If the transaction is successful, IOTPay will notify to notifyUrl;
# Request URL for simple purchase
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_purchase
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
mchOrderNo | y | String(30) | 1234567890abc | assigned by merchant |
mchUserId | y | String(30) | 007 | assigned by merchant |
amount | y | Int | 1500 | in cents |
currency | y | String(3) | CAD | for now only CAD supported |
loginName | y | String(12) | jack123 | merchant's login name |
subject | n | String(64) | ||
body | n | String(250) | ||
channel | y | String | UPI_EX | fixed value: UPI_EX |
notifyUrl | y | String(200) | get notify when success | |
returnUrl | y | String(200) | redirect to this url after payment | |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData.redirectUrl | y | String | if retCode=SUCCESS, merchant redirect to this url | |
retData.secureId | y | String | For SDK integration only |
# NotifyUrl message(post request in json format)
name | required | type | sample | description |
---|---|---|---|---|
payOrderId | y | String | SUCCESS or FAIL | |
mchId | y | String | ||
mchOrderNo | y | String | ||
originalOrderId | y | String | original pay order id if payType=refund | |
amount | y | Int | 100 | in cents |
currency | y | String | CAD | |
payType | y | String | pay or refund | |
refundable | y | Int | 100 | in cents |
status | y | Int | 2 | 2 or 3 means success |
invoiceNum | y | String | ||
paySuccTime | y | String | 2021-04-07 19:44:51 | |
cardNum | y | String | 432567******2266 | |
cardType | y | String | V or M | |
expiryDate | y | String | ||
authNum | y | String | ||
transNum | y | String | ||
channel | y | String | UPI_EX | fixed value: UPI_EX |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
# ReturnUrl parameters
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | n | String | ||
status | y | Int | 2 | 2 or 3 both mean the transaction is successful |
# Recurring purchase
User input card info once, can purchase with the tokenized card multiple times.
# Sequence
1, Call cc_addcard and then redirect to retData.redirectUrl to let user input credit card info;
2, After addcard, will redirect to returnUrl with the following parameters:
If success: retCode=SUCCESS
If fail: retCode=FAIL&retMsg=xxxx
3, (optional) Call cc_querycard to get card info;
4, If cc_addcard is successful, call cc_purchasewithtoken to do a real purchase
# Request URL for cc_addcard
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_addcard
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
cardId | y | String(30) | 604567999 | assigned by merchant,must be unique |
loginName | y | String(12) | jack123 | merchant's login name |
channel | y | String | UPI_EX | fixed value: UPI_EX |
returnUrl | y | String(200) | redirect to this url after payment | |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
each cardId
can bind only one credit card, if one user need to bind more cards, use different cardId
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData.redirectUrl | y | String | if retCode=SUCCESS, merchant redirect to this url | |
retData.secureId | y | String | used for sdk integration |
# ReturnUrl parameters
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | n | String |
# Request URL for cc_directaddcard
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_directaddcard
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
As an IOTPAY client or partner using this method of integration, your solution must demonstrate compliance to the Payment Card Industry Data Security Standard (PCI DSS) .
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
cardId | y | String(30) | 604567999 | assigned by merchant |
cardNum | y | String | 4223456789564532 | card number |
expiryDate | n | String | 0725 | |
holder | y | String | card holder's name | |
cvv | y | String | 786 | |
loginName | y | String(12) | jack123 | merchant's login name |
channel | y | String | UPI_EX | fixed value: UPI_EX |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData | y | JSON | if retCode=SUCCESS, card info returned |
# retData contains card infomation:
name | required | type | sample | description |
---|---|---|---|---|
cardId | y | String | ||
cardNum | y | String | ||
expiryDate | n | String | ||
holder | y | String | ||
cvv | y | String |
# Request URL for cc_querycard
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_querycard
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
cardId | y | String(30) | 604567999 | assigned by merchant |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData | y | JSON | if retCode=SUCCESS, card info returned |
# retData contains card infomation:
name | required | type | sample | description |
---|---|---|---|---|
cardId | y | String | ||
cardNum | y | String | ||
expiryDate | y | String | ||
holder | y | String | ||
cvv | y | String |
# Request URL for purchasewithtoken
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_purchasewithtoken
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
mchOrderNo | y | String(30) | 1234567890abc | assigned by merchant |
mchUserId | y | String(30) | 007 | assigned by merchant |
cardId | y | String(30) | 604567999 | assigned by merchant |
amount | y | Int | 1500 | in cents |
currency | y | String(3) | CAD | for now only CAD supported |
loginName | y | String(12) | jack123 | merchant's login name |
subject | n | String(64) | ||
body | n | String(250) | ||
clientIp | n | String(50) | 192.77.33.56 | consumer's ip address, for better transaction trace |
notifyUrl | y | String(250) | http://abc.com/notify.php | callback url to get transaction result |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData | y | JSON | if retCode=SUCCESS, order detailed info returned |
# retData contains order infomation:
name | required | type | sample | description |
---|---|---|---|---|
payOrderId | y | String | SUCCESS or FAIL | |
mchId | y | String | ||
mchOrderNo | n | String | ||
originalOrderId | y | String | original pay order id if payType=refund | |
amount | y | Int | 100 | in cents |
currency | y | String | CAD | |
payType | y | String | pay or refund | |
refundable | y | Int | 100 | in cents |
status | y | Int | 2 | 2 or 3 means success |
invoiceNum | y | String | ||
paySuccTime | y | String | 2021-04-07 19:44:51 | |
cardNum | y | String | 432567******2266 | |
cardType | y | String | V or M | |
expiryDate | y | String | ||
authNum | y | String | ||
transNum | y | String | ||
channel | y | String | UPI_EX | fixed value:UPI_EX |
# NotifyUrl message(post request in json format)
name | required | type | sample | description |
---|---|---|---|---|
payOrderId | y | String | SUCCESS or FAIL | |
mchId | y | String | ||
mchOrderNo | y | String | ||
originalOrderId | y | String | original pay order id if payType=refund | |
amount | y | Int | 100 | in cents |
currency | y | String | CAD | |
payType | y | String | pay or refund | |
refundable | y | Int | 100 | in cents |
status | y | Int | 2 | 2 or 3 means success |
invoiceNum | y | String | ||
paySuccTime | y | String | 2021-04-07 19:44:51 | |
cardNum | y | String | 432567******2266 | |
cardType | y | String | V or M | |
expiryDate | y | String | ||
authNum | y | String | ||
transNum | y | String | ||
channel | y | String | UPI_EX | fixed value:UPI_EX |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
Merchant's system always get transaction status from notify message, because ExpressPay transaction is an asynchronous call. Merchant's client app( or web) need to poll the transaction status from the merchant's server.
# Refund a transaction
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_refund
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
mchRefundNo | y | String(30) | R1234567890abc | assigned by merchant |
loginName | y | String(12) | jack_chen | assigned by merchant,equals to jobNo |
refundAmount | y | Int | 100 | in cents |
payOrderId | y | String(30) | ||
notifyUrl | y | String(250) | http://abc.com/notify.php | callback url to get transaction result |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData | y | JSON | if retCode=SUCCESS, order detailed info returned |
# Notify message
As same as the notify message of purchasewithtoken.
Merchant's system always get transaction status from notify message, because ExpressPay transaction is an asynchronous call. Merchant's client app( or web) need to poll the transaction status from the merchant's server.
# Void a transaction
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_void
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
mchRefundNo | y | String(30) | R1234567890abc | assigned by merchant |
loginName | y | String(12) | jack_chen | assigned by merchant,equals to jobNo |
payOrderId | y | String(30) | ||
notifyUrl | y | String(250) | http://abc.com/notify.php | callback url to get transaction result |
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData | y | JSON | if retCode=SUCCESS, order detailed info returned |
# Notify message
As same as the notify message of purchasewithtoken.
Merchant's system always get transaction status from notify message, because ExpressPay transaction is an asynchronous call. Merchant's client app( or web) need to poll the transaction status from the merchant's server.
# Query order
Endpoint: https://ccapi.iotpaycloud.com/v3/cc_query
Reqeust method:
- POST
- Content-Type: application/json;charset=UTF-8
# Parameters
name | required | type | sample | description |
---|---|---|---|---|
mchId | y | String(30) | 10000701 | assigned by IOTPay |
mchOrderNo | y | String(30) | 1234567890abc | assigned by merchant |
payOrderId | y | String(30) | ||
sign | y | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | Sign algorithm |
use either payOrderId
or mchOrderNo
, use one of them
# Response
name | required | type | sample | description |
---|---|---|---|---|
retCode | y | String | SUCCESS or FAIL | |
retMsg | y | String | ||
retData | y | JSON | if retCode=SUCCESS, order detailed info returned |
# SDKs and document
For iOS integration: iOS sdk
For Android integration: Android sdk
PHP and JS integration: Php sdk
# Demo and source code
Simple purchase: demo Recurring purchase: demo source code download