官方文档
官方文档调用用的是python
写的,作为一名Android开发,看的我一脸懵逼,记录下自己写的方法
实战
1.首先是参数,这里的支付金额(txamt
)填的是1,实际支付是0.01,切记不能填0.01,会返回参数txamt
错误
Map<String, String> map = new HashMap<>();
map.put("txamt", "1");
map.put("txcurrcd", "CNY");
map.put("pay_type", type);
map.put("out_trade_no", String.valueOf(System.currentTimeMillis()));
map.put("txdtm", format);
map.put("goods_name", "张雷");

2.根据参数生成未签名的字符串,必须给Map
的key
和value
进行编码转换,然后根据key
升序排序,并后用&
符号连接每个key
和value
(举个例子:a=b&c=d),最后拼接上钱方提供的key后MD5
一下就完成了
private String make_req_sign(Map<String, String> params, String key) {
Set<String> keys = params.keySet();
List<String> result = new ArrayList<>(keys);
Collections.sort(result);
StringBuilder data = new StringBuilder();
for (String s : result) {
Log.e("test", "make_req_sign: " + s);
String k = unicodeToUtf8(s);
String v = unicodeToUtf8(params.get(k));
String format = String.format("%s=%s", k, v);
data.append(format);
data.append("&");
}
String unsign_str = "";
if (data.length() > 0) {
unsign_str = data.substring(0, data.length() - 1) + key;
}
Log.e("test", "make_req_sign:unsign_str = " + unsign_str);
return MD5(unsign_str);
}
unicodeToUtf8
方法
/**
* unicode 转换成 utf-8
*
* @param theString
* @return
* @author fanhui
* 2007-3-15
*/
public String unicodeToUtf8(String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (int x = 0; x < len; ) {
aChar = theString.charAt(x++);
if (aChar == '\\') {
aChar = theString.charAt(x++);
if (aChar == 'u') {
// Read the xxxx
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = (value << 4) + aChar - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (value << 4) + 10 + aChar - 'A';
break;
default:
throw new IllegalArgumentException(
"Malformed \\uxxxx encoding.");
}
}
outBuffer.append((char) value);
} else {
if (aChar == 't')
aChar = '\t';
else if (aChar == 'r')
aChar = '\r';
else if (aChar == 'n')
aChar = '\n';
else if (aChar == 'f')
aChar = '\f';
outBuffer.append(aChar);
}
} else
outBuffer.append(aChar);
}
return outBuffer.toString();
}
MD5
方法
private String MD5(String s) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(s.getBytes("utf-8"));
return toHex(bytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private String toHex(byte[] bytes) {
final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
StringBuilder ret = new StringBuilder(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
}
return ret.toString();
}
}
3.请求钱方接口获取签名信息,每个人的网络框架不同,我就贴一下关键代码(我用的是OkHttp)
.addHeader("X-QF-APPCODE", "钱方的code")
.addHeader("X-QF-SIGN", make_req_sign(map, "钱方的key"))
.params(map)
4.返回结果
{
"pay_type": "800201",
"sysdtm": "2016-04-11 17:58:34",
"txdtm": "2016-04-11 17:51:00",
"resperr": "",
"txcurrcd": "CNY",
"txamt": "1",
"respmsg": "",
"out_trade_no": "145399626053599943",
"syssn": "20160411016600020003620875",
"qrcode": "https://o2.qfpay.com/q/mid?h=zxrLRO8kbLV3QmqdgTm8da",
"respcd": "0000"
}

网友评论