银联支付,实现代码对接

简介: 和其他支付平台一样,根据不同的移动端银联也提供了相应的支付渠道,比如在线网关支付、云闪付APP支付(原手机支付控件)、企业网银支付(商户版)、手机网页支付(WAP支付)、二维码支付等。

做过支付的同学都知道,支付宝和微信支付只适合小额付款,如果遇到业务场景是大额支付的,还是得对接银联支付。

和其他支付平台一样,根据不同的移动端银联也提供了相应的支付渠道,比如在线网关支付、云闪付APP支付(原手机支付控件)、企业网银支付(商户版)、手机网页支付(WAP支付)、二维码支付等。

要对接平台接口第一步自然是要有账号,注册账号的过程就不多说了。

image.png

选择需要对接的产品填写信息,提交入网申请,会有商务对接。

image.png

很友好的是,平台会提供测试参数用来调试接口,在个人中心-商户入网测试中心-测试参数,包括测试商户号、测试证书、测试地址。

image.png

有了这些东西,就可以开始写代码调试接口了,当然了,最让人舒心的是,平台也有提供SDK供你参考,实测了一下,确实只是仅供参考,因为跑不起来,哈哈😀。
代码虽然很简单,但要成功集成还是要花功夫的。

acp_sdk.properties配置文件主要放置一些证书文件,证书从商户入网测试中心下载。

# 报文版本号,固定5.1.0
acpsdk.version=5.1.0

# 签名方式,证书方式固定01
acpsdk.signMethod=01

##测试交易请求地址
acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do
acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do
acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do

# 是否验证验签证书的CN,测试环境设置false,生产环境设置true。
acpsdk.ifValidateCNName=false

# 是否验证https证书,测试环境设置false,生产环境设置true。
acpsdk.ifValidateRemoteCert=false

######################### 入网测试环境签名证书配置 ################################
# 签名证书路径
acpsdk.signCert.path=/data/acp_test_sign.pfx

# 签名证书密码,测试环境固定000000
acpsdk.signCert.pwd=000000
# 签名证书类型,固定不需要修改
acpsdk.signCert.type=PKCS12

########################## 加密证书配置 ################################
# 敏感信息加密证书路径
acpsdk.encryptCert.path=/data/acp_test_enc.cer

########################## 验签证书配置 ################################
# 验签中级证书路径
acpsdk.middleCert.path=/data/acp_test_middle.cer
# 验签根证书路径
acpsdk.rootCert.path=/data/acp_test_root.cer

将acp_sdk.properties配置文件放到根目录下

image.png

再写个配置类UnionPayConfig,启动的时候加载证书内容

@Component
@Configuration
@EnableConfigurationProperties({UnionProperties.class})
public class UnionPayConfig {
    private UnionProperties union;
    public UnionPayConfig(UnionProperties union) {
        this.union = union;
        SDKConfig.getConfig().loadPropertiesFromSrc();
    }
}

PC端唤起支付页面,注意交易金额,单位为分,不能带小数点,结果是以form表单的形式打开支付页面。

    public void  webPay(HttpServletResponse resp) throws IOException {
        logger.info("银联电脑端支付");
        UnionPayParam param = new UnionPayParam();
        param.setOrderId(UnionConfig.getCurrentTime())
                .setTxnTime(UnionConfig.getCurrentTime())
                .setTxnAmt("330000")
                .setReqReserved(param.getOrderId());
        unionPayService.webPay000202(param, resp);
        Map<String, String> data = new HashMap<>(29);
        // 版本号,全渠道默认值
        data.put("version", UnionConfig.version);
        // 字符集编码,可以使用UTF-8,GBK两种方式
        data.put("encoding", UnionConfig.encoding_UTF8);
        // 签名方法
        data.put("signMethod", SDKConfig.getConfig().getSignMethod());
        // 交易类型 ,01:消费
        data.put("txnType", "01");
        // 交易子类型, 01:自助消费
        data.put("txnSubType", "01");
        // 业务类型 000202: B2B
        data.put("bizType", "000202");
        // 渠道类型 固定07
        data.put("channelType", "07");
        // 商户号码
        data.put("merId", unionProperties.getMerId());
        // 接入类型,0:直连商户
        data.put("accessType", "0");
        // 商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则
        data.put("orderId", param.getOrderId());
        // 订单发送时间,取系统时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
        data.put("txnTime", param.getTxnTime());
        // 交易币种(境内商户一般是156 人民币)
        data.put("currencyCode", "156");
        // 交易金额,单位分,不要带小数点
        data.put("txnAmt", CommonUtils.subZeroAndDot(param.getTxnAmt()));
        // 业务场景,取值参考接口规范
        data.put("bizScene", "110001");
        // 收款方账户名称
        data.put("payeeAcctNm", URLEncoder.encode(unionProperties.getPayeeAcctNm(),UnionConfig.encoding_UTF8));
        // 收款方账号
        data.put("payeeAcctNo", unionProperties.getPayeeAcctNo());
        // 收款银行名称
        data.put("payeeBankName", URLEncoder.encode(unionProperties.getPayeeBankName(),UnionConfig.encoding_UTF8));
        // 前台通知地址
        data.put("frontUrl", unionProperties.getFrontUrl());
        // 后台通知地址
        data.put("backUrl", unionProperties.getBackUrl());
        // 订单超时时间
        data.put("payTimeout", new SimpleDateFormat("yyyyMMddHHmmss").format(System.currentTimeMillis() + 15 * 60 * 1000));
        // 请求方保留域, 内容不会出现&={}[]"'等符号时,可以直接填写数据
        data.put("reqReserved", Base64.encodeBase64String(param.getReqReserved().getBytes(UnionConfig.encoding_UTF8)));
        Map<String, String> reqData = AcpUtils.sign(data,UnionConfig.encoding_UTF8);
        String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl();
        String html = AcpUtils.createAutoFormHtml(requestFrontUrl,reqData,UnionConfig.encoding_UTF8);
        logger.info("打印请求HTML,此为请求报文:{}", html);
        resp.getWriter().write(html);
}

和其他支付方式一样,支付结果以异步通知告知开发者,在这里处理业务逻辑,比如更改订单状态为已支付。

    public void unionPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("银联接收后台通知开始");
        String encoding = request.getParameter(SDKConstants.param_encoding);
        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> reqParam = AcpUtils.getAllRequestParam(request);
        Map<String, String> valideData = new HashMap<>();
        if (!reqParam.isEmpty()) {
            Iterator<Map.Entry<String, String>> it = reqParam.entrySet().iterator();
            valideData = new HashMap<>(reqParam.size());
            while (it.hasNext()) {
                Map.Entry<String, String> e = it.next();
                String key = e.getKey();
                String value = e.getValue();
                value = new String(value.getBytes(encoding), encoding);
                valideData.put(key, value);
            }
        }
        if (!AcpUtils.validate(valideData, encoding)) {
            logger.info("银联验证签名结果[失败].");
        } else {
            logger.info("银联回调结果参数=====:{}", JSON.toJSONString(valideData));
            logger.info("银联验证签名结果[成功].");
            AsyncNotifyResult result = JSON.parseObject(JSON.toJSONString(valideData), AsyncNotifyResult.class);
            // 应答码
            String respCode = result.getRespCode();
            // 应答信息
            String respMsg = result.getRespMsg();
            if (StringUtils.equals("00", respCode) && StringUtils.equals("成功[0000000]", respMsg)) {
                // 商户订单号
                String orderId = result.getOrderId();
                // 银联查询流水号
                String queryId = result.getQueryId();
                // 银联订单发送时间
                String txnTime = result.getTxnTime();

                String txnAmt = result.getTxnAmt();
                // 辅助信息
                String reqReserved = result.getReqReserved();
                logger.info("reqReserved=====:{}", new String(Base64.decodeBase64(reqReserved), UnionConfig.encoding_UTF8));
                // TODO
                // 银联没有返回付款时间,系统自己生成
                logger.info("处理业务逻辑,orderId:{},更新queryId:{},txnTime:{}=====", orderId, queryId, txnTime);

            }
            response.getWriter().print("ok");
        }
    }

看一下效果

image.png

这是测试环境,选择卡号,输入验证码,点击提交

image.png

image.png

image.png

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

上一篇:美团联盟怎么实现用户订单跟单功能

相关文章
|
9月前
|
JSON 安全 API
淘宝订单接口对接实战:从申请到代码实现的全流程
随着电子商务的飞速发展,订单管理已成为电商生态中的核心环节。为了更高效地进行订单管理,许多商家选择通过API接口与外部系统进行数据交互。本文以淘宝订单接口为例,详细介绍如何从申请到代码实现,成功对接淘宝订单接口。
|
10月前
|
设计模式 数据库
淘东电商项目(59) -聚合支付(集成银联支付)
淘东电商项目(59) -聚合支付(集成银联支付)
72 0
|
移动开发 前端开发 Android开发
前端微信支付开发H5支付(微信外)
前端微信支付开发H5支付(微信外)
422 0
前端微信支付开发H5支付(微信外)
|
前端开发 数据库
下单接口的开发对接第三方支付
下单接口的开发对接第三方支付
|
开发工具 数据安全/隐私保护 Android开发
支付宝完整流程
支付宝完整流程
406 0
支付宝完整流程
支付宝卡包集成流程
该产品可以用于管理电子凭证的产品,该产品聚合来自各类生活服务的票据凭证,包括优惠券、折扣券、代金券、换购券、电影票、演出票、火车票、机票。 用户交易创建后,企业或者个人开发者根据交易外部订单号可以通过支付宝提供的开放接口,把卡券添加到支付宝卡包,用户可以通过支付宝钱包客户端,在卡包功能中查看并使用卡券。
908 12
|
Java PHP
支付宝一码多付接口开发指南
1.接口说明   接口介绍     该方案适用于通过一个二维码,可以使用多种第三方支付,常见的一码多付产品:收钱吧     使用场景流程,申请条件,产品费率点击【更多】查看   常见问题     Q:怎么判断自己的需求可以使用一码多付方案?     A:一般都是想使用一个固定的二维码,可以使用...
1391 0
|
JSON API 数据格式
电商企业在线预约快递取件接口API对接demo
(1)支持自定义预约时间,不遗漏订单(2)已支持三通一达(申通不支持)、顺丰、EMS、宅急送、德邦、优速等物流公司(3)快递公司会在两小时内联系发件人并上门揽件(4)接口支持的消息接收方式为HTTP POST,请求方法的编码格式(utf-8):“application/x-www-form-urlencoded;charset=utf-8”。
1368 0
|
移动开发
快速对接payjs的个人支付接口(收银台模式)
近期在了解个人支付接口,希望能解决我在微信上支付的问题。找了很多平台对比再三,感觉payjs比较专业,其它多是模仿payjs的东西。同时支持支付宝和微信,由于本人支付宝还没开通(需要有一定流量才给开通),本文重点讲一下微信收银台模式的对接。
2083 0
|
测试技术 PHP 开发工具
小程序接入微信支付的流程
近日开发一个顺风小巴的小程序,开发还是比较简单的,只是有些语法真是反人类,主要难点是微信支付,其他的调调接口渲染一下数据就ok了,下面就详细说一下整个流程及中间遇到的坑。
1620 0
下一篇
DDNS