XPay

本文档主要描述XPay软件异步通知

异步通知

以POST方式,键值对形式(application/x-www-form-urlencoded)

名称 描述
Sign 签名结果
TransactionID 支付宝交易号
TransactionName 名称
TransactionTime 交易时间
TransactionUserName 付款人
TransactionAmount 交易金额
TransactionStatus 交易状态

签名描述

POST的所有键值对(除Sign外),key按照字典排序(小到大)后,按照以下方式拼接,最后拼接软件设置的密钥 拼接的字符串进行MD5加密(32位,小写) 得出签名结果可以跟POST的Sign进行比较

SignStr = key1+value1+key2+value2+......+keyn+valuen+密钥
Sign = md5(SignStr)

PHP Demo

$sign_key = '123456';
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
    if (isset($_POST['Sign']))
    {
        $sign = $_POST['Sign'];
        unset($_POST['Sign']);
        $data = $_POST;
        ksort($data);
        $str = '';
        foreach ($data as $k => $v)
        {
            $str .= $k . $v;
        }
        $str .= $sign_key;
        if ($sign == md5($str))
        {
            $transaction = array(
                'transaction_id' => $_POST['TransactionID'],
                'transaction_desc' => $_POST['TransactionName'],
                'transaction_time' => $_POST['TransactionTime'],
                'transaction_user_name' => $_POST['TransactionUserName'],
                'transaction_amount' => $_POST['TransactionAmount'],
                'transaction_status' => $_POST['TransactionStatus']
            );
            //Todo
            echo 'success';
        }
    }
}
else
{
    echo '出错';
}

Java Demo

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import constants.Constants;
import util.Utils;

public class ReceiveAliPayTransactionInfoDemo {

    public String analysisSign(HttpServletRequest request,String privateKey){
        // 获取http请求参数
        Map bodyMap =  acquisitionParameters(request);
        String Sign = bodyMap.get("Sign").toString();
        Map<String,String> newMap = PickUpNessaryMap(bodyMap);
        String MD5SignStr = getMD5Str(sortMap(newMap)+privateKey);
        if(Sign.equals(MD5SignStr)){
            return "true";
        }else{
            return "false";
        }
    }


    /**
     * 获取http请求参数
     * @param request
     * @return
     */
    public static Map acquisitionParameters(HttpServletRequest request) {
        // 保存参数值
        Map paramMap = new HashMap();
        if (request != null) {
            Enumeration en = request.getParameterNames();
            while (en.hasMoreElements()) {
                String paramName = (String) en.nextElement();
                paramMap.put(paramName, request.getParameter(paramName));
            }
        }
        return paramMap;
    }

    /**
     * 将所需参数提取到新map中
     * @param bodyMap
     * @return
     */
    public Map<String,String> PickUpNessaryMap(Map bodyMap){
        Map<String,String> newMap = new HashMap<String,String>();
        try {
            newMap.put("TransactionID", bodyMap.get("TransactionID").toString());
            newMap.put("TransactionName", bodyMap.get("TransactionName").toString());
            newMap.put("TransactionTime", bodyMap.get("TransactionTime").toString());
            newMap.put("TransactionUserName", bodyMap.get("TransactionUserName").toString());
            newMap.put("TransactionAmount", bodyMap.get("TransactionAmount").toString());
            newMap.put("TransactionStatus", bodyMap.get("TransactionStatus").toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return newMap;
    }

    /**
     * lyb提供的md5
     * @param str
     * @return
     */
    private String getMD5Str(String str) {  
        MessageDigest message_digest = null;   
        try {  
            message_digest = MessageDigest.getInstance("MD5");  
            message_digest.reset();  
            message_digest.update(str.getBytes("UTF-8"));  
        } catch (NoSuchAlgorithmException e) {  
            System.exit(-1);
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }
        byte[] byte_array = message_digest.digest();  
        StringBuffer md5_str_buff = new StringBuffer();  
        for (int i = 0; i < byte_array.length; i++) {              
            if (Integer.toHexString(0xFF & byte_array[i]).length() == 1) {
                md5_str_buff.append("0").append(Integer.toHexString(0xFF & byte_array[i])); 
            } else {
                md5_str_buff.append(Integer.toHexString(0xFF & byte_array[i]));  
            }
        }
        return md5_str_buff.toString();  
    }

    /**
     * 将map按照字典排序(小到大)后,按照以下方式拼接
     * SignStr = key1+value1+key2+value2+......+keyn+valuen+密钥
     * @param newMap
     * @return
     */
    public static String sortMap(Map<String,String> newMap){
        String SignStr = "";
        try {
            List<Map.Entry<String,String>> mappingList = null; 
            mappingList = new ArrayList<Map.Entry<String,String>>(newMap.entrySet()); 
            Collections.sort(mappingList, new Comparator<Map.Entry<String,String>>(){ 
                   public int compare(Map.Entry<String,String> mapping1,Map.Entry<String,String> mapping2){ 
                    return mapping1.getKey().compareTo(mapping2.getKey()); 
                   } 
                  }); 
            StringBuilder stringBuilder = new StringBuilder();;
            for(Map.Entry<String,String> mapping:mappingList){ 

                   stringBuilder.append(mapping.getKey()).append(mapping.getValue());
                  } 
            SignStr = stringBuilder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SignStr;
    }
}