由于业务需要,我们公司最近开始对接新的一款二维码---全民付二维码,其实归根结底就是对银联接口进行了二次封装,然后在自己的基础上做了一些改变推出的一款二维码,对接流程相对简单,接下来我来介绍一下对接全民付二维码的过程
1.银联商务平台地址:https://open.chinaums.com/
2.文档地址:https://download.csdn.net/download/t_james/11199530
3.参数获取:appId,appKey,mId(商户号),tId(终端号),需要联系相关支持人员获取,自身登录后的测试参数无权限使用
4.SDK或者demo获取,截止目前,银联商务平台还未把c2b主扫业务封装进SDK.所以需要另写demo
5.接口开发,完成后填写测试文档,提交支持人员等待后续商务操作
1.确认SDK是否支持自己开发业务需求
将SDK下载安装到自己项目后可以看到相关源码,此处进行对比,看是否有符合自己的请求url
如果没有,要么找对接人员获取,要么自己敲...
2.对接接口
由于内部做了相应封装,所以我只需对接有限的几个关键接口即可
参数我再截几页都截不完,所以大家可以去看文档,这里要说三点:
1.最简单传递商户订单号的方法就是传递账单号billNo,但是测试线是需要用1017+订单号的模式---101720190524010203,否则,即使生成二维码,到最后付款的时候也会提示订单号错误(其实和滴滴等大型供应商一样,都有一套自己的规则),正式线则需要等待另行通知
2.回调地址设置,这里没有非80端口不发送的限制,只需要传递外网可正常访问的IP地址即可,需要注意的是,如果是微信扫码支付后,要点击完成按钮才会触发回调,我感觉这点挺那个的....
3.请求头设置,这边会提供一个token,直接自己封装一个工具类放在里面即可,下面我把工具类代码放在下面
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.commons.codec.binary.Base64;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class PeoplepayUtil {
static String appId = ;
static String appKey = ;
static String authorization;
public static String send(String url, String entity) throws Exception{
authorization = getOpenBodySig(appId, appKey, entity);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Authorization", authorization);
StringEntity se = new StringEntity(entity,"UTF-8");
se.setContentType("application/json");
httpPost.setEntity(se);
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity1 = response.getEntity();
String resStr = null;
if(entity1 != null){
resStr = EntityUtils.toString(entity1, "UTF-8");
}
httpClient.close();
response.close();
return resStr;
}
public static String getOpenBodySig(String appId, String appKey, String body) throws Exception{
String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String nonce = UUID.randomUUID().toString().replace("-", "");
byte[] data = body.getBytes("UTF-8");
System.out.println("data:\n" + body);
InputStream is = new ByteArrayInputStream(data);
String bodyDigest = testSHA256(is);
String str1_C = appId+timestamp+nonce+bodyDigest;
byte[] localSignature = hmacSHA256(str1_C.getBytes(), appKey.getBytes());
String localSignatureStr = Base64.encodeBase64String(localSignature);
System.out.println("Authorization:\n" + "OPEN-BODY-SIG AppId="+"\""+appId+"\""+", Timestamp="+"\""+timestamp+"\""+", Nonce="+"\""+nonce+"\""+", Signature="+"\""+localSignatureStr+"\"");
return ("OPEN-BODY-SIG AppId="+"\""+appId+"\""+", Timestamp="+"\""+timestamp+"\""+", Nonce="+"\""+nonce+"\""+", Signature="+"\""+localSignatureStr+"\"");
}
private static String testSHA256(InputStream is) {
try {
return DigestUtils.sha256Hex(is);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
String algorithm = "HmacSHA256";
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(key, algorithm));
return mac.doFinal(data);
}
}
调用send方法即可,内部会自己封装请求头
最后会得到一个包含二维码链接地址的结果串,转成识别二维码即可。
这里需要说一下的是,支付结果通知和退款结果通知是同一个地址,也就是你获取二维码传递的回调地址,所以内部要做好区分,其次,如果内部有一点点小卡顿,就会造成二次回调,这里需要处理好,可以加同步,可以加标识等等,看自身情况吧。
Map properties = request.getParameterMap();
System.out.println("回调返回参数");
// 返回值Map
Map returnMap = new HashMap();
Iterator entries = properties.entrySet().iterator();
Map.Entry entry;
String name = "";
String value = "";
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
name = (String) entry.getKey();
Object valueObj = entry.getValue();
if(null == valueObj){
value = "";
}else if(valueObj instanceof String[]){
String[] values = (String[])valueObj;
for(int i=0;i
这边可以打印出参数和文档进行对比,保存自己想要的参数和数据,最终返回一个字符串SUCCESS代表成功
return "SUCCESS";
退款操作其实大同小异了,传递账单号或者商户订单号,传递退款金额(单位:分),可以实时退款,然后就是接收退款通知了,这里确实没什么好操作的。大家不明白的可以看我之前对接其他几家二维码的博客分析一下
1.银联二维码,最好对接银联本身的,流程更加规范,文档和支持更佳齐全
2.每次对接,都可以体会到上一次对接的不足,这样就可以再加以改进和进步
3.对待每一件事都要严谨