目录:前言
android 建行龙支付教程2:传递支付url给建行,获取支付数据并处理
android想调用建行支付,只能通过url调用h5支付,再通过h5回馈的信息跳转到建行app或直接在网页进行支付,这里讲的是如何对调用支付的url进行拼接:
url需要传递的参数分为两种,一种是无论有没有值都需要传递和参与加密运算的,它们分别是:
private String MERCHANTID = "必填"; //商户代码
private String POSID = "必填"; //商户柜台代码
private String BRANCHID = "必填"; //分行代码
private String CURCODE = "01"; //币种01为人民币
private String TXCODE = "520100"; //交易码 由建行统一分配为520100
private String REMARK1 = "";
private String REMARK2 = "";
private String TYPE = "1"; //接口类型
private String PUB = "必填"; //公钥后30位
private String GATEWAY = ""; //网关类型
private String CLIENTIP = "";//客户端IP
private String REGINFO = ""; //客户注册信息
private String REFERER = ""; //商户URL
必填的数值建行会提供给你们,不是必填的,直接填空字符或者需要传递的值就行。
另一种是有值时才参与传递和加密运算的,它们分别是:
private String INSTALLNUM = "";//信用卡支付分期期数,必须为大于1的整数,当分期期数为空或无该字段上送时,则视为普通的网上支付
private String TIMEOUT = "";//订单超时时间 格式:YYYYMMDDHHMMSS 银行系统时间> TIMEOUT时拒绝交易,若送空值则不判断超时。
private String ISSINSCODE = ""; //银行代码 仅对PC跨行生效,手机跨行无需上送该字段
//二级商户信息,若上送二级商户信息则八个二级商户信息字段必须都送值
private String SMERID = ""; //二级商户代码
private String SMERNAME = ""; //二级商户名称
private String SMERTYPEID = ""; //二级商户类别代码
private String SMERTYPE = ""; //二级商户类别名称
private String TRADECODE = ""; //交易类型代码
private String TRADENAME = ""; //交易类型名称
private String SMEPROTYPE = ""; //商品类别代码
private String PRONAME = ""; //商品类别名称
private String THIRDAPPINFO = "这个值必需传,可以是任何字符串";//当该字段有值时,则会优先启动建行APP支付,否则优先启动h5页面支付。
值得注意的是 如果值为中文,则需要转换成escape编码格式
另外还有一个特殊的值mac,这是把需要传递的值和PUB一起md5加密后的值,因此mac的值为:
StringBuffer macSB = new StringBuffer();
macSB.append("MERCHANTID=").append(MERCHANTID)
.append("&POSID=").append(POSID)
.append("&BRANCHID=").append(BRANCHID)
.append("&ORDERID=").append(orderid)
.append("&PAYMENT=").append(payment)
.append("&CURCODE=").append(CURCODE)
.append("&TXCODE=").append(TXCODE)
.append("&REMARK1=").append(REMARK1)
.append("&REMARK2=").append(REMARK2)
.append("&TYPE=").append(TYPE)
.append("&PUB=").append(PUB)
.append("&GATEWAY=").append(GATEWAY)
.append("&CLIENTIP=").append(CLIENTIP)
.append("®INFO=").append(EscapeUtils.escape(REGINFO))
.append("&PROINFO=").append(EscapeUtils.escape(proinfo))
.append("&REFERER=").append(REFERER);
if (!TextUtils.isEmpty(INSTALLNUM))
macSB.append("&INSTALLNUM=").append(INSTALLNUM);
if (!TextUtils.isEmpty(SMERID))
macSB.append("&SMERID=").append(SMERID);
if (!TextUtils.isEmpty(SMERNAME))
macSB.append("&SMERNAME=").append(EscapeUtils.escape(SMERNAME));
if (!TextUtils.isEmpty(SMERTYPEID))
macSB.append("&SMERTYPEID=").append(SMERTYPEID);
if (!TextUtils.isEmpty(SMERTYPE))
macSB.append("&SMERTYPE=").append(EscapeUtils.escape(SMERTYPE));
if (!TextUtils.isEmpty(TRADECODE))
macSB.append("&TRADECODE=").append(TRADECODE);
if (!TextUtils.isEmpty(TRADENAME))
macSB.append("&TRADENAME=").append(EscapeUtils.escape(TRADENAME));
if (!TextUtils.isEmpty(SMEPROTYPE))
macSB.append("&SMEPROTYPE=").append(SMEPROTYPE);
if (!TextUtils.isEmpty(PRONAME))
macSB.append("&PRONAME=").append(EscapeUtils.escape(PRONAME));
if (!TextUtils.isEmpty(THIRDAPPINFO))
macSB.append("&THIRDAPPINFO=").append(THIRDAPPINFO);
if (!TextUtils.isEmpty(TIMEOUT))
macSB.append("&TIMEOUT=").append(TIMEOUT);
if (!TextUtils.isEmpty(ISSINSCODE))
macSB.append("&ISSINSCODE=").append(ISSINSCODE);
//把拼接完成的macSB经过md5加密后就是mac的值
String MAC = md5(macSB.toString());
完整的url为:
//拼接完整的URL
StringBuffer urlSB = new StringBuffer();
urlSB.append("https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?")
.append("MERCHANTID=").append(MERCHANTID)
.append("&POSID=").append(POSID)
.append("&BRANCHID=").append(BRANCHID)
.append("&ORDERID=").append(orderid)
.append("&PAYMENT=").append(payment)
.append("&CURCODE=").append(CURCODE)
.append("&TXCODE=").append(TXCODE)
.append("&REMARK1=").append(REMARK1)
.append("&REMARK2=").append(REMARK2)
.append("&TYPE=").append(TYPE)
.append("&GATEWAY=").append(GATEWAY)
.append("&CLIENTIP=").append(CLIENTIP)
.append("®INFO=").append(EscapeUtils.escape(REGINFO))
.append("&PROINFO=").append(EscapeUtils.escape(proinfo))
.append("&REFERER=").append(REFERER);
//
if (!TextUtils.isEmpty(INSTALLNUM))
urlSB.append("&INSTALLNUM=").append(INSTALLNUM);
if (!TextUtils.isEmpty(SMERID))
urlSB.append("&SMERID=").append(SMERID);
if (!TextUtils.isEmpty(SMERNAME))
urlSB.append("&SMERNAME=").append(EscapeUtils.escape(SMERNAME));
if (!TextUtils.isEmpty(SMERTYPEID))
urlSB.append("&SMERTYPEID=").append(SMERTYPEID);
if (!TextUtils.isEmpty(SMERTYPE))
urlSB.append("&SMERTYPE=").append(EscapeUtils.escape(SMERTYPE));
if (!TextUtils.isEmpty(TRADECODE))
urlSB.append("&TRADECODE=").append(TRADECODE);
if (!TextUtils.isEmpty(TRADENAME))
urlSB.append("&TRADENAME=").append(EscapeUtils.escape(TRADENAME));
if (!TextUtils.isEmpty(SMEPROTYPE))
urlSB.append("&SMEPROTYPE=").append(SMEPROTYPE);
if (!TextUtils.isEmpty(PRONAME))
urlSB.append("&PRONAME=").append(EscapeUtils.escape(PRONAME));
if (!TextUtils.isEmpty(THIRDAPPINFO))
urlSB.append("&THIRDAPPINFO=").append(THIRDAPPINFO);
if (!TextUtils.isEmpty(TIMEOUT))
urlSB.append("&TIMEOUT=").append(TIMEOUT);
if (!TextUtils.isEmpty(ISSINSCODE))
urlSB.append("&ISSINSCODE=").append(ISSINSCODE);
urlSB.append("&MAC=").append(MAC);
String url = uslSB.toString();
一般情况下,除价钱,订单号和订单说明外,其他的都是固定值,因此我们可以写一个工具类,传入这三个值然后生成url,代码可以参考:
import android.text.TextUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class CcbPayUtils {
//无论有无值都需要参与mac运算的参数
private String MERCHANTID = "必填"; //商户代码 //注意,这里有坑,MERCHANTID需要传的值,文档写的是商户代码,网上找有demo也是传商户代码,找建行技术员咨询也是跟我说传商户代码,但经过多次测试,这里需要传递的却是商户编号
private String POSID = "必填"; //商户柜台代码
private String BRANCHID = "必填"; //分行代码
private String CURCODE = "01"; //币种01为人民币
private String TXCODE = "520100"; //交易码 由建行统一分配为520100
private String REMARK1 = "";
private String REMARK2 = "";
private String TYPE = "1"; //接口类型
private String PUB = "必填"; //公钥后30位
private String GATEWAY = ""; //网关类型
private String CLIENTIP = "";//客户端IP
private String REGINFO = ""; //客户注册信息
private String REFERER = ""; //商户URL
//无论有无值都需要参与mac运算的参数-完
//有值时才参与mac运算的参数
private String INSTALLNUM = "";//信用卡支付分期期数,必须为大于1的整数,当分期期数为空或无该字段上送时,则视为普通的网上支付
private String TIMEOUT = "";//订单超时时间 格式:YYYYMMDDHHMMSS 银行系统时间> TIMEOUT时拒绝交易,若送空值则不判断超时。
private String ISSINSCODE = ""; //银行代码 仅对PC跨行生效,手机跨行无需上送该字段
//二级商户信息,若上送二级商户信息则八个二级商户信息字段必须都送值
private String SMERID = ""; //二级商户代码
private String SMERNAME = ""; //二级商户名称
private String SMERTYPEID = ""; //二级商户类别代码
private String SMERTYPE = ""; //二级商户类别名称
private String TRADECODE = ""; //交易类型代码
private String TRADENAME = ""; //交易类型名称
private String SMEPROTYPE = ""; //商品类别代码
private String PRONAME = ""; //商品类别名称
private String THIRDAPPINFO = "android时必需填,可以是任意字符串,获取支付结果时会用到";//当该字段有值时,则会优先启动建行APP支付,否则优先启动h5页面支付。
//有值时才参与mac运算的参数-完
/**
* 银行支付
*
* @param payment 价格
* @param orderid 订单号
* @param proinfo 商品信息
* @return 支付url
*/
public String pay(double payment, String orderid, String proinfo) {
//拼接需要参数mac运算的字符串
StringBuffer macSB = new StringBuffer();
macSB.append("MERCHANTID=").append(MERCHANTID)
.append("&POSID=").append(POSID)
.append("&BRANCHID=").append(BRANCHID)
.append("&ORDERID=").append(orderid)
.append("&PAYMENT=").append(payment)
.append("&CURCODE=").append(CURCODE)
.append("&TXCODE=").append(TXCODE)
.append("&REMARK1=").append(REMARK1)
.append("&REMARK2=").append(REMARK2)
.append("&TYPE=").append(TYPE)
.append("&PUB=").append(PUB)
.append("&GATEWAY=").append(GATEWAY)
.append("&CLIENTIP=").append(CLIENTIP)
.append("®INFO=").append(EscapeUtils.escape(REGINFO))
.append("&PROINFO=").append(EscapeUtils.escape(proinfo))
.append("&REFERER=").append(REFERER);
if (!TextUtils.isEmpty(INSTALLNUM))
macSB.append("&INSTALLNUM=").append(INSTALLNUM);
if (!TextUtils.isEmpty(SMERID))
macSB.append("&SMERID=").append(SMERID);
if (!TextUtils.isEmpty(SMERNAME))
macSB.append("&SMERNAME=").append(EscapeUtils.escape(SMERNAME));
if (!TextUtils.isEmpty(SMERTYPEID))
macSB.append("&SMERTYPEID=").append(SMERTYPEID);
if (!TextUtils.isEmpty(SMERTYPE))
macSB.append("&SMERTYPE=").append(EscapeUtils.escape(SMERTYPE));
if (!TextUtils.isEmpty(TRADECODE))
macSB.append("&TRADECODE=").append(TRADECODE);
if (!TextUtils.isEmpty(TRADENAME))
macSB.append("&TRADENAME=").append(EscapeUtils.escape(TRADENAME));
if (!TextUtils.isEmpty(SMEPROTYPE))
macSB.append("&SMEPROTYPE=").append(SMEPROTYPE);
if (!TextUtils.isEmpty(PRONAME))
macSB.append("&PRONAME=").append(EscapeUtils.escape(PRONAME));
if (!TextUtils.isEmpty(THIRDAPPINFO))
macSB.append("&THIRDAPPINFO=").append(THIRDAPPINFO);
if (!TextUtils.isEmpty(TIMEOUT))
macSB.append("&TIMEOUT=").append(TIMEOUT);
if (!TextUtils.isEmpty(ISSINSCODE))
macSB.append("&ISSINSCODE=").append(ISSINSCODE);
//把拼接完成的macSB经过md5加密后就是mac的值
String MAC = md5(macSB.toString());
//拼接完整的URL
StringBuffer urlSB = new StringBuffer();
urlSB.append("https://ibsbjstar.ccb.com.cn/CCBIS/ccbMain?")
.append("MERCHANTID=").append(MERCHANTID)
.append("&POSID=").append(POSID)
.append("&BRANCHID=").append(BRANCHID)
.append("&ORDERID=").append(orderid)
.append("&PAYMENT=").append(payment)
.append("&CURCODE=").append(CURCODE)
.append("&TXCODE=").append(TXCODE)
.append("&REMARK1=").append(REMARK1)
.append("&REMARK2=").append(REMARK2)
.append("&TYPE=").append(TYPE)
.append("&GATEWAY=").append(GATEWAY)
.append("&CLIENTIP=").append(CLIENTIP)
.append("®INFO=").append(EscapeUtils.escape(REGINFO))
.append("&PROINFO=").append(EscapeUtils.escape(proinfo))
.append("&REFERER=").append(REFERER);
//
if (!TextUtils.isEmpty(INSTALLNUM))
urlSB.append("&INSTALLNUM=").append(INSTALLNUM);
if (!TextUtils.isEmpty(SMERID))
urlSB.append("&SMERID=").append(SMERID);
if (!TextUtils.isEmpty(SMERNAME))
urlSB.append("&SMERNAME=").append(EscapeUtils.escape(SMERNAME));
if (!TextUtils.isEmpty(SMERTYPEID))
urlSB.append("&SMERTYPEID=").append(SMERTYPEID);
if (!TextUtils.isEmpty(SMERTYPE))
urlSB.append("&SMERTYPE=").append(EscapeUtils.escape(SMERTYPE));
if (!TextUtils.isEmpty(TRADECODE))
urlSB.append("&TRADECODE=").append(TRADECODE);
if (!TextUtils.isEmpty(TRADENAME))
urlSB.append("&TRADENAME=").append(EscapeUtils.escape(TRADENAME));
if (!TextUtils.isEmpty(SMEPROTYPE))
urlSB.append("&SMEPROTYPE=").append(SMEPROTYPE);
if (!TextUtils.isEmpty(PRONAME))
urlSB.append("&PRONAME=").append(EscapeUtils.escape(PRONAME));
if (!TextUtils.isEmpty(THIRDAPPINFO))
urlSB.append("&THIRDAPPINFO=").append(THIRDAPPINFO);
if (!TextUtils.isEmpty(TIMEOUT))
urlSB.append("&TIMEOUT=").append(TIMEOUT);
if (!TextUtils.isEmpty(ISSINSCODE))
urlSB.append("&ISSINSCODE=").append(ISSINSCODE);
urlSB.append("&MAC=").append(MAC);
return urlSB.toString();
}
//md5加密
public String md5(String string) {
if (TextUtils.isEmpty(string)) {
return "";
}
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest(string.getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
private static class EscapeUtils {
/**
* Escape编码
* @param src 待加盐字符串
* @return 加盐字符串
*/
public static String escape(String src) {
int i;
char j;
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length() * 6);
for (i = 0; i < src.length(); i++) {
j = src.charAt(i);
if (Character.isDigit(j) || Character.isLowerCase(j)
|| Character.isUpperCase(j))
tmp.append(j);
else if (j < 256) {
tmp.append("%");
if (j < 16)
tmp.append("0");
tmp.append(Integer.toString(j, 16));
} else {
tmp.append("%u");
tmp.append(Integer.toString(j, 16));
}
}
return tmp.toString();
}
/**
* Escape解码
* @param src 加盐字符串
* @return 明文
*/
public static String unescape(String src) {
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length());
int lastPos = 0, pos = 0;
char ch;
while (lastPos < src.length()) {
pos = src.indexOf("%", lastPos);
if (pos == lastPos) {
if (src.charAt(pos + 1) == 'u') {
ch = (char) Integer.parseInt(src
.substring(pos + 2, pos + 6), 16);
tmp.append(ch);
lastPos = pos + 6;
} else {
ch = (char) Integer.parseInt(src
.substring(pos + 1, pos + 3), 16);
tmp.append(ch);
lastPos = pos + 3;
}
} else {
if (pos == -1) {
tmp.append(src.substring(lastPos));
lastPos = src.length();
} else {
tmp.append(src.substring(lastPos, pos));
lastPos = pos;
}
}
}
return tmp.toString();
}
}
}
必填的值记得改回你需要的值,获取支付url时只需要
String url = new CcbPayUtils().pay(价格,订单号,说明);