# Interface protocol

# Protocol

Transfer method Using HTTP
Request method POST/GET
Encoding UTF-8
Signature algorithm MD5

# Parameter specification

Transanction amount: default CAD,in cents,no decimal.

# Online signature checker

demo

# Signature algorithm

# Step 1:

Treat all parameters sending or received as a set M, sort all non-empty parameters in lexicographic order by parameter's name, ascendingly. Concat all sorted parameters in URL format(key1=value1&key2=value2) into stringA.

make sure to follow:

  • sort parameter name ascendingly in lexicographic order;
  • discard any paramter with empty value;
  • parameter name is case sensitive;
  • when validating the response or notify message, don't sign on parameter 'sign', compare parameter 'sign' with the signature you calculated.
  • payment center may add more parameters, need to support when validating the signature.

# Step 2:

Append &key=merchant_key to the end of stringA to get stringSignTemp, use MD5 to sign stringSignTemp, then convert the MD5 hash to upper case to get sign value. Merchant can get merchant_key from IOTPay.

# PHP code

/** sign the string
	*$prestr string to be signed
	*return  
 */
function md5sign($prestr,$sign_type)
{
    $sign='';
    if($sign_type == 'MD5')
	{
        $sign = strtoupper(md5($prestr));//to upper case
    }
	else
	{
        die("only support MD5 for now".$sign_type);
    }
    return $sign;
}
/**
    *convert array to “key=value&key2=value2...” string
	*$array
	*return
*/
function create_linkstring($array)
{
    $arg  = "";
    while (list ($key, $val) = each ($array))
	{
       if($val!=''){
          $arg.=$key."=".$val."&";
		}
    }
    $arg = substr($arg,0,count($arg)-2);  //remove last '&'
    return $arg;
}
function build_mysign($sort_array,$key,$sign_type = "MD5") 
{
    $prestr = create_linkstring($sort_array); 
    $prestr = $prestr."&key=".$key;	

    $mysgin = md5sign($prestr,$sign_type);
    return $mysgin;
}	

function arg_sort($array) 
{
    ksort($array,SORT_NATURAL | SORT_FLAG_CASE);
    reset($array);
    return $array;
}

$arr = array(
    'mchId'=>$merchant_id,
    'mchOrderNo'=>$order_sn,
    'extra'=> $sceneInfo,    
    'channelId'=>$channelId,
    'currency'=>'CAD',
    'amount'=>intval($order_amount*100),
    'clientIp'=>$ip,
    'device'=>'WEB',
    'notifyUrl'=>$notifyUrl,
    'subject'=>$subject,
    'body'=>$body,
  );
   
$sort_array = arg_sort($arr);
$arr['sign']= build_mysign($sort_array,$merchant_key,"MD5");//generate signature
$param = 'params='.json_encode($arr);
$outputparams =  "Param: " . $param . '<br/>';
$resBody = request($url,$param);//submit request

# C# code

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace demo_sign
{
    class Program
    {
        //get the merchantKey from IOTPay
        static string merchantKey = "xxxxxxxxxxxxxxxxxxx";

        public static string GetMD5Hash(string str)
        {
            StringBuilder sb = new StringBuilder();
            using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
            {
                byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
                int length = data.Length;
                for (int i = 0; i < length; i++)
                    sb.Append(data[i].ToString("X2"));
            }
            return sb.ToString();
        }

        static string create_linkstring(SortedDictionary<string, string> dict)
        {
            string arg = "";
            foreach (KeyValuePair<string, string> kv in dict)
            {
                if (kv.Value != "")
                {
                    arg += kv.Key + "=" + kv.Value + "&";
                }
                
            }
            arg = arg.TrimEnd('&');
            return arg;

        }

        static void Main(string[] args)
        {
            //add all parameters into sorted dict, order by key name in lexicographic order
            SortedDictionary<string, string> para_array = new SortedDictionary<string, string>();
            para_array.Add("mchId", "10000XXX");
            para_array.Add("mchOrderNo", "6199200000006");
            para_array.Add("channelId", "WX_MICROPAY");
            para_array.Add("currency", "CAD");
            para_array.Add("codeType", "barcode");
            para_array.Add("amount", "1");
            para_array.Add("clientIp", "127.0.0.1");
            para_array.Add("identityCode", "135021906891251756");
            para_array.Add("device", "superscanner");
            para_array.Add("deviceId", "superscanner_NS010");
            para_array.Add("notifyUrl", "http://www.xxxx.ca/getnotify");
            para_array.Add("subject", "test");
            para_array.Add("body", "test body");

            Console.WriteLine(para_array.Count);
            //convert the dict to url string
            string link_str = create_linkstring(para_array);
            //append the merchant key as the last parameter
            link_str += ("&key="+merchantKey);
            Console.WriteLine(link_str);
            //get md5 sign value
            string sign = GetMD5Hash(link_str);
            Console.WriteLine(sign);

        }
    }
}

# VB code

Private Sub test()
    Dim disc As Object
    Set disc = CreateObject("Scripting.Dictionary")
    'get the merchantKey from IOTPay
    Dim merchantKey As String
    merchantKey = "xxxxxxxxxxxxxxxxxxxx"
    
    'add all parameters into sorted dict, order by key name in lexicographic order
    disc.Add "mchId", "10000xxx"
    disc.Add "mchOrderNo", "6199200000006"
    disc.Add "channelId", "WX_MICROPAY"
    disc.Add "currency", "CAD"
    disc.Add "codeType", "barcode"
    disc.Add "amount", "1"
    disc.Add "clientIp", "127.0.0.1"
    disc.Add "identityCode", "135021906891251756"
    disc.Add "device", "superscanner"
    disc.Add "deviceId", "superscanner_NS010"
    disc.Add "notifyUrl", "http://www.xxxx.ca/getnotify"
    disc.Add "subject", "test"
    disc.Add "body", "test body"

    sign = GetSign(disc, merchantKey)

    Debug.Print sign

    
End Sub
Function GetSign(disc As Object, merchantKey As String) As String

    ' Sort the keys
    Dim arrList As Object
    Set arrList = CreateObject("System.Collections.ArrayList")
    
    ' Put keys in an ArrayList
    Dim key As Variant, coll As New Collection
    For Each key In disc
        arrList.Add key
    Next key
    
    arrList.Sort
    
    ' convert the dict to url string
    Dim result As String
    Dim result_segment As String
    result_segment = ""
    For Each key In arrList
        result = result & result_segment & key & "=" & disc(key)
        result_segment = "&"
    Next key
    
    'append the merchant key as the last parameter
    result = result & result_segment & "key" & "=" & merchantKey
    
    'get md5 sign value
    GetSign = UCase(StringToMD5Hex(result))
End Function


Function StringToMD5Hex(ByVal s As String) As String
    Dim enc As Object
    Dim bytes() As Byte
    Dim pos As Long
    Dim outstr As String

    Set enc = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider")

    bytes = StrConv(s, vbFromUnicode)
    bytes = enc.ComputeHash_2(bytes)

    For pos = 1 To UBound(bytes) + 1
        outstr = outstr & LCase(Right("0" & Hex(AscB(MidB(bytes, pos, 1))), 2))
    Next pos

    StringToMD5Hex = outstr
    Set enc = Nothing
End Function

Last Updated: 1/23/2020, 3:56:38 PM