1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 银联云闪付二维码支付对接流程和测试

银联云闪付二维码支付对接流程和测试

时间:2019-05-25 02:23:07

相关推荐

银联云闪付二维码支付对接流程和测试

因为公司已经支持了支付宝支付和微信支付,所以需要加上一个银联的云闪付,主要是二维码支付。

银联商务的官方文档其实已经很清楚了,但是因为之前对接支付宝和微信,有一个保存商户信息的表,表结构已经确定了,再更改的话会比较麻烦,但是银联的商户信息和支付宝微信又不太相同,支付宝的签名验签主要依靠公钥和秘钥,微信主要有证书,银联却是证书和公钥,而且银联的不同版本会出现不同的验签,5.1.0需要多个证书,demo里的逻辑是证书保存在本地的文件夹,验签时从本地读取,事实上我们需要的是证书保存在数据库,这样就需要进行部分改造对接,这一期的主要对接版本是5.0.0,就是需要一个证书,一个公钥的版本

就拿下单来说,组装参数调用util的地方基本一样,只是有些值的获取变成了从数据库读取

Map<String, String> contentData = new HashMap();/***银联全渠道系统,产品参数,除了encoding自行选择外其他不需修改***/contentData.put("version", payAccountInfoDO.getVersion()); //版本号 全渠道默认值contentData.put("encoding", UnionPayConfig.encoding);//字符集编码 可以使用UTF-8,GBK两种方式contentData.put("signMethod", UnionPayConfig.signMethod);//签名方法contentData.put("txnType", "01");//交易类型 01:消费contentData.put("txnSubType", "07"); //交易子类 07:申请消费二维码contentData.put("bizType", UnionPayConfig.bizType); //填写000000contentData.put("channelType", UnionPayConfig.channelType); //渠道类型 08手机/***商户接入参数***/contentData.put("merId", payAccountInfoDO.getMchId()); //商户号码,请改成自己申请的商户号或者open上注册得来的777商户号测试contentData.put("accessType", UnionPayConfig.accessType); //接入类型,商户接入填0 ,不需修改(0:直连商户, 1: 收单机构 2:平台商户)contentData.put("orderId",transOrderDO.getOutTradeNo()); //商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则contentData.put("txnTime",UnionPayConfig.getCurrentTime());//订单发送时间,取系统时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效contentData.put("txnAmt",transOrderDO.getFee().toString());//交易金额 单位为分,不能带小数点contentData.put("currencyCode", UnionPayConfig.currencyCode);contentData.put("backUrl", UnionPayConfig.BACKURL);byte[] certBytes = payAccountInfoDO.getCertBytes();String keypwd = payAccountInfoDO.getCertPassword();String type = payAccountInfoDO.getSignType(); //证书类型String publicRsa = payAccountInfoDO.getPublicRsa();UnionUnifiedOrderResult unifiedOrderResult = UnionpayApiUtil.orderResult(logId,contentData,certBytes,keypwd,type,publicRsa);

有看到除了银联原本下单需要的参数外,我还获取到了证书,证书密码,签名方式和公钥,这样就需要修改银联的签名和验签方法了,一步步的传进去处理一下签名在sdkutil里面,从里签名是在certutil里,有一个方法是将签名私钥证书文件读取为证书对象的,因为我没有保存在文件夹,所以证书是传进去从数据库读取成文件的

/*** 将签名私钥证书文件读取为证书存储对象** 证书文件名* @param keypwd* 证书密码* @param type* 证书类型* @return 证书对象* @throws IOException*/private static KeyStore getKeyInfo(byte[] certBytes, String keypwd, String type) throws IOException {LogUtil.writeLog("加载签名证书==>" + certBytes);ByteArrayInputStream fis = null;try {KeyStore ks = KeyStore.getInstance(type, "BC");LogUtil.writeLog("Load RSA CertPath=[" + certBytes + "],Pwd=["+ keypwd + "],type=["+type+"]");fis = new ByteArrayInputStream(certBytes);char[] nPassword = null;nPassword = null == keypwd || "".equals(keypwd.trim()) ? null: keypwd.toCharArray();if (null != ks) {ks.load(fis, nPassword);}return ks;} catch (Exception e) {LogUtil.writeErrorLog("getKeyInfo Error", e);return null;} finally {if(null!=fis)fis.close();}}

可以看到原本的证书地址被直接改成byte类型的证书字节流了,再修改一下读取方式变成ByteArrayInputStream的方式读取就可以了,在sdkutil里会设置一个证书的序列号对应一个证书文件,后面基本不用改变

签名完成后继续执行银联下单的post请求,会返回一个请求结果,得到结果后,进行验签,验签时会先判断版本号,因为我们只对接5.0.0,所以不考虑5.1.0时验证签名书链的情况,就是需要多个证书的情况。前面已经把需要的验签公钥传进来了,所以在验签方法中进行修改就可以,在certutil里

/*** 用配置文件acp_sdk.properties配置路径 加载验证签名证书*/private static void initValidateCertFromDir(String publicRsa) {if(!"01".equals(SDKConfig.getConfig().getSignMethod())){LogUtil.writeLog("非rsa签名方式,不加载验签证书。");return;}certMap.clear();CertificateFactory cf = null;ByteArrayInputStream in = null;try {cf = CertificateFactory.getInstance("X.509", "BC");}catch (NoSuchProviderException e) {LogUtil.writeErrorLog("LoadVerifyCert Error: No BC Provider", e);return ;} catch (CertificateException e) {LogUtil.writeErrorLog("LoadVerifyCert Error", e);return ;}try {in = new ByteArrayInputStream(publicRsa.getBytes());validateCert = (X509Certificate) cf.generateCertificate(in);if(validateCert == null) {LogUtil.writeErrorLog("Load verify cert error, " + publicRsa + " has error cert content.");return ;}certMap.put(validateCert.getSerialNumber().toString(),validateCert);// 打印证书加载信息,供测试阶段调试LogUtil.writeLog("[" + publicRsa + "][CertId="+ encryptCert.getSerialNumber().toString() + "]");} catch (CertificateException e) {LogUtil.writeErrorLog("LoadVerifyCert Error", e);}catch (Exception e) {LogUtil.writeErrorLog("LoadVerifyCert Error File Not Found", e);}finally {if (null != in) {try {in.close();} catch (IOException e) {LogUtil.writeErrorLog(e.toString());}}}LogUtil.writeLog("LoadVerifyCert Finish");}

还是把路径变成了ByteArrayInputStream这样的读取,后面的内容基本不用改变

需要注意的是银联的公钥从官网下载下来全部保存在数据库,包括前面的begin和后面的end,因为支付宝的没有,所以一开始没有保存那个,一直报错,验签失败,找了好久才发现是因为公钥保存的问题,真的很坑

开发基本就这样,条码、查询什么的基本一样,根据银联的官方文档来就可以了主要是签名和验签的问题

测试的话比较讨厌,不能用云闪付app测试,只能在银联的官网有一个二维码仿真,用那个来测试还挺麻烦的

大概就长这个样子

以上

最后共勉

I don't want to be someone that you're settling for. I don't want to be someone that anyone settles for.

我不想要你将就,我也不想成为将就的对象。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。