API Reference

Table of Contents

1. Get Started

Note: This is a Developer level doc provided as guidance.

2. Payment

2.1. Payment Service URL

2.2. Payment API Requests Parameters

2.2.1. Requests Parameters

Field Name Max Length Field Type Data Type Comments
version 2 Y string Version,default:31
payment_type 10 N string Default:Credit Card
auth_trans 10 N string Pre-sale:1-YES,2-NO
merchant_id 10 Y String Your Merchant ID
channel_id 20 Y String Your Channel ID
transaction_type 10 Y String Transaction Method:PAY,3DSPAY,VIEWPAY
transaction_id 50 Y String Shop Payment Order ID
transaction_amount 18 Y String Order amount
transaction_currency 3 Y String Currency Code(ISO)
card_number 20 Y String Card Number
card_secureid 3 Y String CVV2
card_expiry 5 Y String Expiry:MM/YYYY
payment_bank 50 Y String Issuing Bank
customer_firstname 50 Y String Cardholder first name
customer_lastname 50 Y String Cardholder last name
customer_email 100 Y String Cardholder email
customer_phone 50 Y String Cardholder phone
device_fingerprintid 100 Y String Device fingerprintid
device_ipaddress 50 Y String Cardholder ip
shipping_firstname 50 Y String First name
shipping_lastname 50 Y String Last name
shipping_phone 50 Y String Phone
shipping_address 100 Y String Address
shipping_postalcode 20 Y String Post Code
shipping_country 2 Y String ISO standard currency code(eg. US)
shipping_state 30 Y String State
shipping_city 30 Y String City
client_id 100 N String Client identity
pay_ext1 100 N String Extension field 1
pay_ext2 100 N String Extension field 2
submit_url 100 N String Merchant transaction URL
return_url 100 N String Return url
sign 100 Y String View "The Signature step"

Field Type: Y= Required N= Optional

2.2.2. The Signature Step

  1. Sign field
    version=31
    merchant_id=Your_merchant_id
    channel_id=Your_channel_id
    transaction_type=PAY
    transaction_id=Shop_transaction_id
    transaction_amount=1
    transaction_currency=USD
    secret_key=Your_secret_key
    
  2. Generate URL-encoded query string
  3. MD5 String
    494387a8af71bc255a9d1c463df336b2
    
  4. MD5 Uppercase(sign)
    494387A8AF71BC255A9D1C463DF336B2
    

2.3. Payment API Responses Parameters

2.3.1. Responses Parameters

Field Name Data Type Comments
order_id String Payment Service Order yyyyMMddHHmmss
transaction_currency String Transaction Currency
transaction_amount String Transaction Amount
merchant_id String Your Merchant ID
channel_id String Your Channel ID
result_code String Result:SUCCESSFUL, FAILED, PROCESSING, ERROR
response_message String Response Info
response_code String Response Code
risk_info String Risk info
auth_trans String authorization status
pay_ext1 String Extension field 1
pay_ext2 String Extension field 1
sign String Signature:view "The Signature Step"

2.3.2. The Signature Step

  1. Sign field
    merchant_id=your_merchant_id
    channel_id=channel_id
    order_id=175840506
    transaction_id=20210429151711
    transaction_amount=15.16
    transaction_currency=USD
    result_code=SUCCESSFUL
    secret_key=your_secret_key
    
  2. Generate URL-encoded query string
  3. MD5 Uppercase(sign)
    59DA9864347B880AE7F806FF81F889CA
    

2.4. Examples

2.4.1. Shell/Curl

#!/usr/bin/bash

order_id=`date +%s`

sign_arr_config=(
"version=31"
"merchant_id=Your_merchant_id"
"channel_id=Your_channel_id"
"transaction_type=PAY"
"transaction_id=${order_id}"
"transaction_amount=25"
"transaction_currency=USD"
"secret_key=Your_secret_key"
)

sign_str="${sign_arr_config[@]}"
sign=`echo -n ${sign_str// /&}|md5sum|awk '{print $1}'|tr 'a-z' 'A-Z'`

curl -s -X  POST \
  https://xxxxxx.xxx/pay_direct.jsp \
  -d "version"="${sign_arr_config[0]/*=}" \
  -d "merchant_id"="${sign_arr_config[1]/*=}" \
  -d "channel_id"="${sign_arr_config[2]/*=}" \
  -d "transaction_type"="${sign_arr_config[3]/*=}" \
  -d "transaction_id"="${sign_arr_config[4]/*=}" \
  -d "transaction_amount"="${sign_arr_config[5]/*=}" \
  -d "transaction_currency"="${sign_arr_config[6]/*=}" \
  -d "card_number"="4242424242424242" \
  -d "card_secureid"="234" \
  -d "card_expiry"="12/2088" \
  -d "payment_bank"="Creditcard_Bank_Name" \
  -d "customer_firstname"="charlotte" \
  -d "customer_lastname"="smith" \
  -d "customer_email"="[email protected]" \
  -d "customer_phone"="6628130885" \
  -d "device_ipaddress"="127.0.0.1" \
  -d "shipping_firstname"="charlotte" \
  -d "shipping_lastname"="smith" \
  -d "shipping_phone"="6628130885" \
  -d "shipping_address"="Street address" \
  -d "shipping_postalcode"="90001" \
  -d "shipping_country"="US" \
  -d "shipping_state"="California" \
  -d "shipping_city"="Los Angeles" \
  -d "sign"="${sign}"

2.4.2. PHP / Curl

<?php
$timestamp                 = time();
$order_id = (string)$timestamp;

$sign_arr = array(
    'version'              =>'31',
    'merchant_id'          =>'Your_merchant_id',
    'channel_id'           =>'Your_channel_id',
    'transaction_type'     =>'PAY',
    'transaction_id'       =>$order_id,
    'transaction_amount'   =>'25',
    'transaction_currency' =>'USD',
    'secret_key'           =>'Your_secret_key',
);
echo http_build_query($sign_arr);
echo "\n";
echo $sign = strtoupper(md5(http_build_query($sign_arr)));
echo "\n";
$data = array(
    'version'              =>$sign_arr['version'],
    'merchant_id'          =>$sign_arr['merchant_id'],
    'channel_id'           =>$sign_arr['channel_id'],
    'transaction_type'     =>$sign_arr['transaction_type'],
    'transaction_id'       =>$sign_arr['transaction_id'],
    'transaction_amount'   =>$sign_arr['transaction_amount'],
    'transaction_currency' =>$sign_arr['transaction_currency'],
    'card_number'          =>'4242424242424242',
    'card_secureid'        =>'234',
    'card_expiry'          =>'12/2088',
    'payment_bank'         =>'Creditcard_Bank_Name',
    'customer_firstname'   =>'charlotte',
    'customer_lastname'    =>'smith',
    'customer_email'       =>'[email protected]',
    'customer_phone'       =>'6628130885',
    'device_ipaddress'     =>'127.0.0.1',
    'shipping_firstname'   =>'charlotte',
    'shipping_lastname'    =>'smith',
    'shipping_phone'       =>'6628130885',
    'shipping_address'     =>'Street address',
    'shipping_postalcode'  =>'90001',
    'shipping_country'     =>'US',
    'shipping_state'       =>'California',
    'shipping_city'        =>'Los Angeles',
    'sign'                 =>$sign,
);
print_r($data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://xxxxxx.xxx/pay_direct.jsp');
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
// curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    var_dump($err);
} else {
    print_r(json_decode($response));
}

2.4.3. Python

import requests
import time
import hashlib
import json

port_url = "https://xxxxxx.xxx/pay_direct.jsp"

order_id=time.strftime('%Y%m%d%H%M%S',time.localtime())

sign_dic = {
    'version'              :'31',
    'merchant_id'          :'Your_merchant_id',
    'channel_id'           :'Your_channel_id',
    'transaction_type'     :'PAY',
    'transaction_id'       :order_id,
    'transaction_amount'   :'25',
    'transaction_currency' :'USD',
    'secret_key'           :'Your_secret_key',
};

md5 = hashlib.md5()
md5.update('&'.join(['{0}={1}'.format(k,v) for k,v in sign_dic.items()]).encode('utf-8'))

sign=md5.hexdigest().upper()


data={
    'version'              :sign_dic['version'],
    'merchant_id'          :sign_dic['merchant_id'],
    'channel_id'           :sign_dic['channel_id'],
    'transaction_type'     :sign_dic['transaction_type'],
    'transaction_id'       :sign_dic['transaction_id'],
    'transaction_amount'   :sign_dic['transaction_amount'],
    'transaction_currency' :sign_dic['transaction_currency'],
    'card_number'          :'4242424242424242',
    'card_secureid'        :'234',
    'card_expiry'          :'12/2088',
    'payment_bank'         :'Creditcard_Bank_Name',
    'customer_firstname'   :'charlotte',
    'customer_lastname'    :'smith',
    'customer_email'       :'[email protected]',
    'customer_phone'       :'6628130885',
    'device_ipaddress'     :'127.0.0.1',
    'shipping_firstname'   :'charlotte',
    'shipping_lastname'    :'smith',
    'shipping_phone'       :'6628130885',
    'shipping_address'     :'Street address',
    'shipping_postalcode'  :'90001',
    'shipping_country'     :'US',
    'shipping_state'       :'California',
    'shipping_city'        :'Los Angeles',
    'sign'                 :sign
}

response = requests.request("POST", url=port_url, data=data)

print(response.text)

2.4.4. Java

package test;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class DirectPayDemo {

    public static void main(String[] args) {
        sendData();
    }

    /**
     * payment process
     */
    public static void sendData() {

        //Fill in the correct payment service URL, merchant number, channel number, secret key
        String sendUrl = "https://xxxxxx.xxx/pay_direct.jsp";
        String merchant_id = "Your_merchant_id";
        String channel_id = "Your_channel_id";
        String key = "Your_secret_key";

        String version = "31";
        String transaction_type = "PAY";
        String transaction_id = String.valueOf(System.currentTimeMillis());
        String transaction_currency = "USD";
        String transaction_amount = "1.23";
        String firstName = "ning";
        String lastName = "li";
        // Fill in the correct type card number according to the opened card type
        String card_number = "4242424242424242";
        // credit card type,  001:Visa;  002:Master; 003:JCB;  004:AE
        String card_expiry = "10/2023";
        String cardExpireMonth = "11";
        String card_secureid = "256";
        String email = "[email protected]";
        String customerID = "afc20000002";

        StringBuffer encryptStr = new StringBuffer();
        encryptStr.append("version=").append(version)
            .append("&merchant_id=").append(merchant_id)
            .append("&channel_id=").append(channel_id)
            .append("&transaction_type=").append(transaction_type)
            .append("&transaction_id=").append(transaction_id)
            .append("&transaction_amount=").append(transaction_amount)
            .append("&transaction_currency=").append(transaction_currency)
            .append("&secret_key=").append(key);

        String signInfo = getMD5Encrypt(encryptStr.toString()).toUpperCase();
        Map<String, String> data = new HashMap<String, String>();
        data.put("version", version);
        data.put("merchant_id", merchant_id);
        data.put("channel_id", channel_id);
        data.put("transaction_type", transaction_type);
        data.put("transaction_id", transaction_id);
        data.put("transaction_amount", transaction_amount);
        data.put("transaction_currency", transaction_currency);
        data.put("device_fingerprintid", "1232fff32-2fsdfsd");
        data.put("device_ipaddress", "192.168.1.11");

        // Unique identification of cardholder
        data.put("customerID", customerID);
        data.put("card_number", card_number);
        data.put("cardExpireMonth", cardExpireMonth);
        data.put("card_expiry", card_expiry);
        data.put("card_secureid", card_secureid);
        data.put("payment_bank", "Test Bank");

        data.put("customer_firstname", firstName);
        data.put("customer_lastname", lastName);
        data.put("customer_email", email);
        data.put("customer_phone", "88270212");

        data.put("shipping_firstname", firstName);
        data.put("shipping_lastname", lastName);
        data.put("shipping_phone", "88270212");
        data.put("shipping_postalcode", "100000");
        data.put("shipping_address", "931 North");
        //ISO code
        data.put("shipping_country", "US");
        data.put("shipping_state", "California");
        data.put("shipping_city", "Garden Grove");
        data.put("address", "Street 931 North");
        data.put("submit_url", "https://test.com");
        data.put("return_url", "https://www.test.com/result.html");

        data.put("sign", signInfo);

        String content = "";
        try {
            System.out.println(transaction_id + " request = " + data.toString());
            content = doPost(sendUrl, data, "UTF-8");
            System.out.println(transaction_id + " response = " + content);
        } catch (Exception e) {
            e.getMessage();
        }
    }

    /**
     * http request post
     */
    public static String doPost(String sendUrl, Map<String, String> params,  String encode) throws Exception {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        String content = null;
        try {
            // Create a default httpClient instance.
            httpclient = HttpClients.custom().build();
            // Create httppost
            HttpPost httppost = new HttpPost(sendUrl);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(15000)
                    .setConnectionRequestTimeout(15000)
                    .setSocketTimeout(30000)
                    .build();
            httppost.setConfig(requestConfig);
            if(null != params){
                // Create parameter queue
                List<BasicNameValuePair> formparams = new ArrayList<BasicNameValuePair>();
                for (String key : params.keySet()) {
                    String val = params.get(key);
                    formparams.add(new BasicNameValuePair(key, val));
                }
                UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, encode);
                httppost.setEntity(uefEntity);
            }

            httppost.setHeader("Content-type", "application/x-www-form-urlencoded");

            response = httpclient.execute(httppost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {//A link exception occurs, throw
                System.out.println("statusCode="+statusCode);
                httppost.abort();
                throw new Exception();
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                content = EntityUtils.toString(entity, encode);
            }
        } catch (Exception e) {
            //Send exception, throw

            throw e;
        } finally {
            // Close the connection and release resources
            try {
                if(null != response){
                    response.close();
                }
                if(null != httpclient){
                    httpclient.close();
                }
            } catch (Exception e) {
            }
        }
        return content;
    }

    /**
     * MD5 encryption
     */
    public static String getMD5Encrypt(String strSrc) {
        MessageDigest md = null;
        String strDes = null;

        try {
            byte[] bt = strSrc.getBytes("UTF-8");
            md = MessageDigest.getInstance("MD5");
            md.update(bt);
            strDes = bytes2Hex(md.digest());
        }
        catch (Exception e) {
            return null;
        }
        return strDes.toUpperCase();
    }

    public static String bytes2Hex(byte[]bts) {
        StringBuffer des = new StringBuffer();
        String tmp = null;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des.append("0");
            }
            des.append(tmp);
        }
        return des.toString();
    }
}


2.4.5. Ruby

require 'net/http'
require 'uri'
require 'digest'


order_id=Time.now.to_i

post_url='https://xxxxxx.xxx/pay_direct.jsp'
sign_hash=Hash[
    'version'              =>'31',
    'merchant_id'          =>'Your_merchant_id',
    'channel_id'           =>'Your_channel_id',
    'transaction_type'     =>'PAY',
    'transaction_id'       =>order_id,
    'transaction_amount'   =>'25',
    'transaction_currency' =>'USD',
    'secret_key'           =>'Your_secret_key',
]

sign= (Digest::MD5.hexdigest URI.encode_www_form(sign_hash)).upcase

uri = URI(post_url)
res = Net::HTTP.post_form(uri,
    'version'              => sign_hash['version'],
    'merchant_id'          => sign_hash['merchant_id'],
    'channel_id'           => sign_hash['channel_id'],
    'transaction_type'     => sign_hash['transaction_type'],
    'transaction_id'       => sign_hash['transaction_id'],
    'transaction_amount'   => sign_hash['transaction_amount'],
    'transaction_currency' => sign_hash['transaction_currency'],
    'card_number'          => '4242424242424242',
    'card_secureid'        => '234',
    'card_expiry'          => '12/2088',
    'payment_bank'         => 'Creditcard_Bank_Name',
    'customer_firstname'   => 'charlotte',
    'customer_lastname'    => 'smith',
    'customer_email'       => '[email protected]',
    'customer_phone'       => '6628130885',
    'device_ipaddress'     => '127.0.0.1',
    'shipping_firstname'   => 'charlotte',
    'shipping_lastname'    => 'smith',
    'shipping_phone'       => '6628130885',
    'shipping_address'     => 'Street address',
    'shipping_postalcode'  => '90001',
    'shipping_country'     => 'US',
    'shipping_state'       => 'California',
    'shipping_city'        => 'Los Angeles',
    'sign'                 => sign
    )
puts res.body

3. Transaction Query

3.1. Transaction Query Service URL

3.2. Transaction Query Request Parameters

3.2.1. Request Parameters

Field Name Max Lenth Field Type Data Type Comments
version 2 Y String Version,default:31
merchant_id 5 Y String Your Merchant ID
channel_id 8 Y String Your Channel ID
order_id 50 Y String Payment Service Order yyyyMMddHHmmss
sign 64 Y String View the Signature step

Field Type: Y= Required N= Optional

3.2.2. The Signature Step

  1. Sign field
    version=31
    merchant_id=Your_merchant_id
    channel_id=Your_channel_id
    order_id=Payment_Service_order_id
    ecret_key=Your_secret_key
    
  2. Generate URL-encoded query string
    version=31&merchant_id=Your_merchant_id&channel_id=Your_channel_id&order_id=Payment_Service_order_id&secret_key=Your_secret_key
    
  3. MD5 String
    4c135e9bd4469650606815f8fa188576
    
  4. MD5 Uppercase(sign)
    4C135E9BD4469650606815F8FA188576
    

3.3. Transaction Query Response Parameters

Field Name Data Type Comments
merchant_id String Your Merchant ID
channel_id String Your Channel ID
order_id String Payment Service Order yyyyMMddHHmmss
transaction_id Int Transaction ID
transaction_currency String Transaction Currency
transaction_amount String Transaction Amount
result String Result:SUCCESSFUL, FAILED, PROCESSING, ERROR
error_info String Error Info

3.4. Examples

3.4.1. Shell/Curl

#!/usr/bin/bash

sign_config=(
"version=31"
"merchant_id=Your_merchant_id"
"channel_id=Your_channel_id"
"order_id=20210415202659969494955"
"secret_key=Your_secret_key"
)

sign_str="${sign_config[@]}"
sign=`echo -n ${sign_str// /&}|md5sum|awk '{print $1}'|tr 'a-z' 'A-Z'`

curl -s -X  POST \
  https://xxxxxx.xxx/trans_query.jsp \
  -d "version"="${sign_config[0]/*=}" \
  -d "merchant_id"="${sign_config[1]/*=}" \
  -d "channel_id"="${sign_config[2]/*=}" \
  -d "order_id"="${sign_config[3]/*=}" \
  -d "sign"="${sign}"

3.4.2. PHP / Curl

<?php

$sign_config = array(
    'version'     => '31',
    'merchant_id' => 'Your_merchant_id',
    'channel_id'  => 'Your_channel_id',
    'order_id'    => '20210415202659969494955',
    'secret_key'  => 'Your_secret_key',
);

echo $sign = strtoupper(md5(http_build_query($sign_config)));
echo "\n";

$data = array(
    'version'     => $sign_config['version'],
    'merchant_id' => $sign_config['merchant_id'],
    'channel_id'  => $sign_config['channel_id'],
    'order_id'    => $sign_config['order_id'],
    'sign'        => $sign,
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://xxxxxx.xxx/trans_query.jsp');
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
// curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    var_dump($err);
} else {
    print_r(json_decode($response));
}

3.4.3. Python

#!/usr/bin/python3
import requests
import hashlib


port_url = "https://xxxxxx.xxx/trans_query.jsp"


sign_config = {
    'version'     : '31',
    'merchant_id' : 'Your_merchant_id',
    'channel_id'  : 'Your_channel_id',
    'order_id'    : '20210415202659969494955',
    'secret_key'  : 'Your_secret_key',
};

md5 = hashlib.md5()
md5.update('&'.join(['{0}={1}'.format(k,v) for k,v in sign_config.items()]).encode('utf-8'))

sign=md5.hexdigest().upper()


data={
    'version'     : sign_config['version'],
    'merchant_id' : sign_config['merchant_id'],
    'channel_id'  : sign_config['channel_id'],
    'order_id'    : sign_config['order_id'],
    'sign'        : sign,
}

response = requests.request("POST", url=port_url, data=data)

print(response.text);

3.4.4. Java

package test;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class DirectPayDemo {

    public static void main(String[] args) {
        queryTrans();
    }


    /**Transaction Query */
    public static void queryTrans(){
        String sendUrl = "https://xxxxxx.xxx/trans_query.jsp";
        String version = "31";
        String merchant_id = "Your_merchant_id";
        String channel_id = "Your_channel_id";
        String order_id = "20191226161036503402984";
        String signKey = "Your_secret_key";

        StringBuffer encryptStr = new StringBuffer();
        encryptStr.append("version=").append(version)
        .append("&merchant_id=").append(merchant_id)
        .append("&channel_id=").append(channel_id)
        .append("&order_id=").append(order_id)
        .append("&secret_key=").append(signKey);

         String signInfo = getMD5Encrypt(encryptStr.toString()).toUpperCase();


         Map<String, String> data = new HashMap<String, String>();
        data.put("version", version);
        data.put("merchant_id", merchant_id);
        data.put("channel_id", channel_id);
        data.put("order_id", order_id);
        data.put("sign", signInfo);

        String content = "";
        try {
            System.out.println(" request = " + data.toString());
            content = doPost(sendUrl, data, "UTF-8");
            System.out.println(" response = " + content);
        } catch (Exception e) {
            e.getMessage();
        }
    }

    /**
     * http request post
     */
    public static String doPost(String sendUrl, Map<String, String> params,  String encode) throws Exception {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        String content = null;
        try {
            // Create a default httpClient instance.
            httpclient = HttpClients.custom().build();
            // Create httppost
            HttpPost httppost = new HttpPost(sendUrl);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(15000)
                    .setConnectionRequestTimeout(15000)
                    .setSocketTimeout(30000)
                    .build();
            httppost.setConfig(requestConfig);
            if(null != params){
                // Create parameter queue
                List<BasicNameValuePair> formparams = new ArrayList<BasicNameValuePair>();
                for (String key : params.keySet()) {
                    String val = params.get(key);
                    formparams.add(new BasicNameValuePair(key, val));
                }
                UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, encode);
                httppost.setEntity(uefEntity);
            }

            httppost.setHeader("Content-type", "application/x-www-form-urlencoded");

            response = httpclient.execute(httppost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {//A link exception occurs, throw
                System.out.println("statusCode="+statusCode);
                httppost.abort();
                throw new Exception();
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                content = EntityUtils.toString(entity, encode);
            }
        } catch (Exception e) {
            //Send exception, throw

            throw e;
        } finally {
            // Close the connection and release resources
            try {
                if(null != response){
                    response.close();
                }
                if(null != httpclient){
                    httpclient.close();
                }
            } catch (Exception e) {
            }
        }
        return content;
    }

    /**
     * MD5 encryption
     */
    public static String getMD5Encrypt(String strSrc) {
        MessageDigest md = null;
        String strDes = null;

        try {
            byte[] bt = strSrc.getBytes("UTF-8");
            md = MessageDigest.getInstance("MD5");
            md.update(bt);
            strDes = bytes2Hex(md.digest());
        }
        catch (Exception e) {
            return null;
        }
        return strDes.toUpperCase();
    }

    public static String bytes2Hex(byte[]bts) {
        StringBuffer des = new StringBuffer();
        String tmp = null;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des.append("0");
            }
            des.append(tmp);
        }
        return des.toString();
    }
}

3.4.5. Ruby

#!/usr/bin/ruby

require 'net/http'
require 'uri'
require 'digest'


post_url="https://xxxxxx.xxx/trans_query.jsp"

sign_config=Hash[
    'version'     => '31',
    'merchant_id' => 'Your_merchant_id',
    'channel_id'  => 'Your_channel_id',
    'order_id'    => '20210415202659969494955',
    'secret_key'  => 'Your_secret_key',
]

sign= (Digest::MD5.hexdigest URI.encode_www_form(sign_config)).upcase

uri = URI(post_url)

res = Net::HTTP.post_form(uri,
    'version'     => sign_config['version'],
    'merchant_id' => sign_config['merchant_id'],
    'channel_id'  => sign_config['channel_id'],
    'order_id'    => sign_config['order_id'],
    'sign'        => sign
    )

puts res.body

4. Refund

4.1. Refund Service URL

4.2. Refund Request Parameters

4.2.1. Request Parameters

Field Name Max Lenth Field Type Data Type Comments
version 2 Y String ersion,default:31
merchant_id 10 Y String Your Merchant ID
channel_id 20 Y String Your Channel ID
sign 64 Y String View the sign step
order_id 64 Y String Payment Service Order yyyyMMddHHmmss
p_refund_type 1 Y int 1:Full Refund 2:Partial Refund
refund_amount 10 Y double Refund Amount,2 decimal
refund_reason 100 Y String Refund Reason
transaction_amount 10 Y double Transaction Amount
transaction_currency 10 Y String Transaction Currency
p_remark 100 Y String Remark

Field Type: Y= Required N= Optional

4.2.2. The Signature Step

  1. Sign field
    version=31
    merchant_id=Your_merchant_id
    channel_id=Your_channel_id
    order_id=Payment_Service_order_id
    secret_key=Your_secret_key
    
  2. Generate URL-encoded query string
    version=31&merchant_id=Your_merchant_id&channel_id=Your_channel_id&order_id=Payment_Service_order_id&secret_key=Your_secret_key
    
  3. MD5 String
    4c135e9bd4469650606815f8fa188576
    
  4. MD5 Uppercase(sign)
    4C135E9BD4469650606815F8FA188576
    

4.3. Refund Response Parameters

4.3.1. Response Parameters

Field Name Data Type Comments
version String version,default:31
merchant_id String Your Merchant ID
channel_id String Your Channel ID
order_id String Payment Service Order yyyyMMddHHmmss
refund_order_id Int Refund Order Id
result String Result:SUCCESSFUL, FAILED, PROCESSING, ERROR
error_info String Error Info

4.3.2. The Signature Step

  1. Sign field
    merchant_id=your_merchant_id
    channel_id=your_channel_id
    refund_order_id=1614221
    result=SUCCESSFUL
    secret_key=your_secret_key
    
  2. Generate URL-encoded query string
  3. MD5 Uppercase(sign)
    9BE4962A9482E7DA3A46EA7F9AB788F5
    

4.4. Examples

4.4.1. Shell/Curl

#!/usr/bin/bash

sign_config=(
"version=31"
"merchant_id=Your_merchant_id"
"channel_id=Your_channel_id"
"order_id=20210415202659969494955"
"secret_key=Your_secret_key"
)

sign_str="${sign_config[@]}"
sign=`echo -n ${sign_str// /&}|md5sum|awk '{print $1}'|tr 'a-z' 'A-Z'`

curl -s -X  POST \
  https://xxxxxx.xxx/trans_refund.jsp \
  -d "version"="${sign_config[0]/*=}" \
  -d "merchant_id"="${sign_config[1]/*=}" \
  -d "channel_id"="${sign_config[2]/*=}" \
  -d "order_id"="${sign_config[3]/*=}" \
  -d "transaction_amount"="25" \
  -d "transaction_currency"="USD" \
  -d "refund_amount"="25" \
  -d "refund_reason"="refund" \
  -d "sign"="${sign}"

4.4.2. PHP / Curl

<?php

$sign_config = array(
    'version'     => '31',
    'merchant_id' => 'Your_merchant_id',
    'channel_id'  => 'Your_channel_id',
    'order_id'    => '20210415202659969494955',
    'secret_key'  => 'Your_secret_key',
);

echo $sign = strtoupper(md5(http_build_query($sign_config)));
echo "\n";

$data = array(
'version'              => $sign_config['version'],
'merchant_id'          => $sign_config['merchant_id'],
'channel_id'           => $sign_config['channel_id'],
'order_id'             => $sign_config['order_id'],
'transaction_amount'   => '25',
'transaction_currency' => 'USD',
'refund_amount'        => '25',
'refund_reason'        => 'refund',
'sign'                 => $sign,
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://xxxxxx.xxx/trans_refund.jsp');
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
// curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    var_dump($err);
} else {
    print_r(json_decode($response));
}

4.4.3. Python

#!/usr/bin/python3
import requests
import hashlib


port_url = "https://xxxxxx.xxx/trans_refund.jsp"


sign_config = {
    'version'     : '31',
    'merchant_id' : 'Your_merchant_id',
    'channel_id'  : 'Your_channel_id',
    'order_id'    : '20210415202659969494955',
    'secret_key'  : 'Your_secret_key',
};

md5 = hashlib.md5()
md5.update('&'.join(['{0}={1}'.format(k,v) for k,v in sign_config.items()]).encode('utf-8'))

sign=md5.hexdigest().upper()


data={
'version'              : sign_config['version'],
'merchant_id'          : sign_config['merchant_id'],
'channel_id'           : sign_config['channel_id'],
'order_id'             : sign_config['order_id'],
'transaction_amount'   : '25',
'transaction_currency' : 'USD',
'refund_amount'        : '25',
'refund_reason'        : 'refund',
'sign'                 : sign,
}

response = requests.request("POST", url=port_url, data=data)

print(response.text);

4.4.4. Java

package test;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class DirectPayDemo {

    public static void main(String[] args) {
        refundAppay();
    }


/** Refund Appay */
    public static void refundAppay(){
        String sendUrl = "https://xxxxxx.xxx/trans_refund.jsp";
        String version = "31";
        String merchant_id = "Your_merchant_id";
        String channel_id = "Your_channel_id";
        String order_id = "20191226161036503402984";
        String signKey = "Your_secret_key";
        String trans_type = "REFUND";
        String transaction_amount = "0.01";
        String transaction_currency = "USD";
        String refund_amount = "0.01";
        String refund_reason = "Refund";

        StringBuffer encryptStr = new StringBuffer();
        encryptStr.append("version=").append(version)
        .append("&merchant_id=").append(merchant_id)
        .append("&channel_id=").append(channel_id)
        .append("&order_id=").append(order_id)
        .append("&secret_key=").append(signKey);

         String signInfo = getMD5Encrypt(encryptStr.toString()).toUpperCase();


         Map<String, String> data = new HashMap<String, String>();
        data.put("version", version);
        data.put("merchant_id", merchant_id);
        data.put("channel_id", channel_id);
        data.put("order_id", order_id);
        data.put("trans_type", trans_type);
        data.put("transaction_amount", transaction_amount);
        data.put("transaction_currency", transaction_currency);
        data.put("refund_reason", refund_reason);
        data.put("refund_amount", refund_amount);
        data.put("sign", signInfo);

        String content = "";
        try {
            System.out.println(" request = " + data.toString());
            content = doPost(sendUrl, data, "UTF-8");
            System.out.println(" response = " + content);
        } catch (Exception e) {
            e.getMessage();
        }
    }

    /**
     * http request post
     */
    public static String doPost(String sendUrl, Map<String, String> params,  String encode) throws Exception {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        String content = null;
        try {
            // Create a default httpClient instance.
            httpclient = HttpClients.custom().build();
            // Create httppost
            HttpPost httppost = new HttpPost(sendUrl);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(15000)
                    .setConnectionRequestTimeout(15000)
                    .setSocketTimeout(30000)
                    .build();
            httppost.setConfig(requestConfig);
            if(null != params){
                // Create parameter queue
                List<BasicNameValuePair> formparams = new ArrayList<BasicNameValuePair>();
                for (String key : params.keySet()) {
                    String val = params.get(key);
                    formparams.add(new BasicNameValuePair(key, val));
                }
                UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, encode);
                httppost.setEntity(uefEntity);
            }

            httppost.setHeader("Content-type", "application/x-www-form-urlencoded");

            response = httpclient.execute(httppost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {//A link exception occurs, throw
                System.out.println("statusCode="+statusCode);
                httppost.abort();
                throw new Exception();
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                content = EntityUtils.toString(entity, encode);
            }
        } catch (Exception e) {
            //Send exception, throw

            throw e;
        } finally {
            // Close the connection and release resources
            try {
                if(null != response){
                    response.close();
                }
                if(null != httpclient){
                    httpclient.close();
                }
            } catch (Exception e) {
            }
        }
        return content;
    }

    /**
     * MD5 encryption
     */
    public static String getMD5Encrypt(String strSrc) {
        MessageDigest md = null;
        String strDes = null;

        try {
            byte[] bt = strSrc.getBytes("UTF-8");
            md = MessageDigest.getInstance("MD5");
            md.update(bt);
            strDes = bytes2Hex(md.digest());
        }
        catch (Exception e) {
            return null;
        }
        return strDes.toUpperCase();
    }

    public static String bytes2Hex(byte[]bts) {
        StringBuffer des = new StringBuffer();
        String tmp = null;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des.append("0");
            }
            des.append(tmp);
        }
        return des.toString();
    }
}

4.4.5. Ruby

#!/usr/bin/ruby

require 'net/http'
require 'uri'
require 'digest'


post_url="https://xxxxxx.xxx/trans_refund.jsp"

sign_config=Hash[
    'version'     => '31',
    'merchant_id' => 'Your_merchant_id',
    'channel_id'  => 'Your_channel_id',
    'order_id'    => '20210415202659969494955',
    'secret_key'  => 'Your_secret_key',
]

sign= (Digest::MD5.hexdigest URI.encode_www_form(sign_config)).upcase

uri = URI(post_url)

res = Net::HTTP.post_form(uri,
    'version'              => sign_config['version'],
    'merchant_id'          => sign_config['merchant_id'],
    'channel_id'           => sign_config['channel_id'],
    'order_id'             => sign_config['order_id'],
    'transaction_amount'   => '25',
    'transaction_currency' => 'USD',
    'refund_amount'        => '25',
    'refund_reason'        => 'refund',
    'sign'                 => sign,
    )

puts res.body

5. REFERENCE

5.1. Test Credit Card Account Numbers

NUMBER BRAND CVC DATE
4242424242424242 Visa Any 3 digits Any future date
4000056655665556 Visa (debit) Any 3 digits Any future date
5555555555554444 Mastercard Any 3 digits Any future date
2223003122003222 Mastercard (2-series) Any 3 digits Any future date
5200828282828210 Mastercard (debit) Any 3 digits Any future date
5105105105105100 Mastercard (prepaid) Any 3 digits Any future date
378282246310005 American Express Any 4 digits Any future date
371449635398431 American Express Any 4 digits Any future date
6011111111111117 Discover Any 3 digits Any future date
6011000990139424 Discover Any 3 digits Any future date
3056930009020004 Diners Club Any 3 digits Any future date
36227206271667 Diners Club (14 digit card) Any 3 digits Any future date
3566002020360505 JCB Any 3 digits Any future date
6200000000000005 UnionPay Any 3 digits Any future date

5.2. Currency Codes

Currency Name Currency Code
Won KRW
Yeni Türk Liras TRY
Rand ZAR
UAE Dirham AED
Mexican Peso MXN
Chilean Peso CLP
Belarussian Ruble BYR
Malaysian Ringgit MYR
Swiss Franc CHF
Serbian Dinar CSD
Pakistan Rupee PKR
Hryvnia UAH
Iranian Rial IRR
Tanzanian Shilling TZS
Armenian Dram AMD
Iceland Krona ISK
Azerbaijan Manat AZN
Lek ALL
Taka BDT
Saudi Riyal SAR
Lari GEL
Zloty PLN
New Zealand Dollar NZD
Norvegian Krone NOK
Danish Krone DKK
Swedish Krona SEK
Convertible Marks BAM
Bulgarian Lev BGN
Croatian Kuna HRK
Forint HUF
Lithuanian Litas LTL
Latvian Lats LVL
Leu romacircnesc RON
Serbian dinars RSD
Brazilian Real BRL
Baht THB
New Israeli Sheqel ILS
Paraguayan Guarani PYG
US Dollar USD
Pound Sterling GBP
Euro EUR
Australian Dollar AUD
Canadian Dollar CAD
Yen JPY
Singapore Dollar SGD
Hong Kong Dollar HKD
Malaysian Ringgit MYR
Philippine Peso PHP
New Taiwan Dollar TWD
Indian Rupee INR
Czech Koruna CZK
Denar MKD

5.3. Country Codes

Countries and Regions Code
Andorra AD
Antigua and Barbuda AG
Anguilla AI
Angola AO
Argentina AR
Austria AT
Australia AU
Barbados BB
Bangladesh BD
Belgium BE
Burkina-faso BF
Bulgaria BG
Burundi BI
Benin BJ
Bermuda Is. BM
Brunei BN
Bolivia BO
Brazil BR
Bahamas BS
Botswana BW
Belize BZ
Canada CA
Congo CG
Switzerland CH
Cook Is. CK
Chile CL
Cameroon CM
Colombia CO
Costa Rica CR
Czech CS
Cyprus CY
Czech Republic CZ
Germany DE
Djibouti DJ
Denmark DK
Dominica Rep. DO
Algeria DZ
Ecuador EC
Estonia EE
Spain ES
Ethiopia ET
Finland FI
Fiji FJ
France FR
Gabon GA
United Kiongdom GB
Grenada GD
French Guiana GF
Ghana GH
Gibraltar GI
Gambia GM
Guinea GN
Greece GR
Guatemala GT
Guam GU
Hongkong HK
Honduras HN
Haiti HT
Hungary HU
Ireland IE
Iceland IS
Italy IT
Jamaica JM
Japan JP
Kenya KE
Kyrgyzstan KG
Kampuchea (Cambodia ) KH
Korea KR
Republic of Ivory Coast KT
St.Lucia LC
Liechtenstein LI
Sri Lanka LK
Lesotho LS
Lithuania LT
Luxembourg LU
Latvia LV
Morocco MA
Monaco MC
Madagascar MG
Mali ML
Mongolia MN
Macao MO
Montserrat Is MS
Malta MT
Mauritius MU
Maldives MV
Malawi MW
Mexico MX
Malaysia MY
Mozambique MZ
Namibia NA
Niger NE
Nigeria NG
Nicaragua NI
Netherlands NL
Norway NO
Nepal NP
Nauru NR
New Zealand NZ
Panama PA
Peru PE
French Polynesia PF
Philippines PH
Poland PL
Puerto Rico PR
Portugal PT
Paraguay PY
Romania RO
Solomon Is SB
Seychelles SC
Sweden SE
Singapore SG
Slovakia SK
San Marino SM
Senegal SN
Suriname SR
Sao Tome and Principe ST
EI Salvador SV
Swaziland SZ
Chad TD
Togo TG
Thailand TH
Tunisia TN
Tonga TO
Trinidad and Tobago TT
Taiwan TW
Tanzania TZ
United States of America US
Uruguay UY
Saint Vincent VC
Venezuela VE
Vietnam VN
Yugoslavia YU
South Africa ZA
Zambia ZM
Zaire ZR

5.4. MD5 Signature Check Tools

MD5 Signature Check Tools

MD5 Signature Check Tools

Sign