中金支付APP跳转支付对接

1、与相关对接人员沟通并索要相关开发文档及jar包

2、将相关jar包打到maven或者直接引用

3、对接支付配置信息(支付宝不需要appId,微信appId中金提供,不需要自己去处理支付宝微信的移动应用绑定)

package com.tb.pay.config;

import com.ruoyi.common.core.exception.param.ParamException;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import payment.api.system.PaymentEnvironment;
import payment.api.tx.redirectpayment.Tx2101Request;
import payment.api.tx.redirectpayment.Tx2102Request;
import payment.api.tx.redirectpayment.Tx2111Request;
import payment.api.tx.redirectpayment.Tx2112Request;

@Data
@Validated
@Component
@ConfigurationProperties(prefix = "zhongjin")
public class ZhongJinPayConfig {


    @ApiModelProperty("中金下发的机构号")
    private String institutionID;
    @ApiModelProperty("交易编码 固定2101")
    private String txCode;
    /**
     * 支付方式限制:
     * 10=不限定
     * 20=仅支持借记卡
     * 30=仅支持贷记卡
     */
    @ApiModelProperty("固定传: 10")
    private String limitPay;
    @ApiModelProperty("固定传: 0001 ")
    private String settlementFlag;
    @ApiModelProperty("支付宝appId ")
    private String appIdByAli;
    @ApiModelProperty("微信appId ")
    private String appIdByWx;
    @ApiModelProperty("固定传10 ")
    private String splitType;
    @ApiModelProperty("平台名称 ")
    private String platformName;
    @ApiModelProperty("服务器IP 必填")
    private String clientIP;
    @ApiModelProperty("回调地址")
    private String pageUrl;
    /**
     * 分期控制标识
     * 10-不指定分期(默认)
     * 20-指定分期
     * 支付类型为 33,支付方式为 45=H5 支付或者支
     * 付类型为支付宝时生效
     */
    @ApiModelProperty("10 ")
    private String installmentType;
    /**
     * 手续费收取模式:
     * 10=商户贴息
     * 20=持卡人付费
     * 分期控制标识 20 时必填,且必须传为商户贴息
     */
    @ApiModelProperty("固定传 10 ")
    private String feeMode;
    @ApiModelProperty("appId")
    private String appId;
    /**
     * 支付证书文件路径
     */
    private String paymentConfigPath;
    /**
     * 支付宝支付回调地址
     */
    private String aliNotifyUrl;
    /**
     * 微信支付回调地址
     */
    private String wxNotifyUrl;
    /**
     * 支付
     */
    private Tx2101Request tx2101Request = null;
    /**
     * 退款
     */
    private Tx2111Request tx2111Request = null;
    /**
     * 支付状态查询
     */
    private Tx2102Request tx2102Request = null;
    /**
     * 退款状态查询
     */
    private Tx2112Request tx2112Request = null;


    public String getAppId(String payType) {
        if (payType.equals("32")) {
            return getAppIdByAli();
        }
        if (payType.equals("31")) {
            return getAppIdByWx();
        }
        throw new ParamException("");
    }

    public String getPageUrl(String payType) {
        if (payType.equals("32")) {
            return getAliNotifyUrl();
        } else {
            return getWxNotifyUrl();
        }
    }

    public Tx2101Request getTx2101() throws Exception {
        PaymentEnvironment.initialize(paymentConfigPath);
        if (tx2101Request == null) {
            tx2101Request = new Tx2101Request();
        }
        tx2101Request.setInstitutionID(institutionID);
        tx2101Request.setLimitPay(limitPay);
        tx2101Request.setSettlementFlag(settlementFlag);
        tx2101Request.setSplitType(splitType);
        tx2101Request.setPlatformName(platformName);
        tx2101Request.setClientIP(clientIP);
        tx2101Request.setInstallmentType(installmentType);
        tx2101Request.setFeeMode(feeMode);
        return tx2101Request;
    }

    public Tx2111Request getTx2111() throws Exception {
        PaymentEnvironment.initialize(paymentConfigPath);
        if (tx2111Request == null) {
            tx2111Request = new Tx2111Request();
        }
        tx2111Request.setInstitutionID(institutionID);
        return tx2111Request;
    }

    public Tx2102Request getTx2102() throws Exception {
        PaymentEnvironment.initialize(paymentConfigPath);
        if (tx2102Request == null) {
            tx2102Request = new Tx2102Request();
        }
        tx2102Request.setInstitutionID(institutionID);
        return tx2102Request;
    }

    public Tx2112Request getTx2112() throws Exception {
        PaymentEnvironment.initialize(paymentConfigPath);
        if (tx2112Request == null) {
            tx2112Request = new Tx2112Request();
        }
        tx2112Request.setInstitutionID(institutionID);
        return tx2112Request;
    }
}

业务代码:

package com.tb.pay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.github.pagehelper.PageException;
import com.ruoyi.common.core.domain.R;
import com.tb.pay.config.AliPayConfig;
import com.tb.pay.config.ZhongJinPayConfig;
import com.tb.pay.model.*;
import com.tb.pay.service.IPayService;
import cpcn.institution.tools.net.RequestDgtEnvlp;
import cpcn.institution.tools.util.Base64;
import cpcn.institution.tools.util.DigitalEnvelopeUtil;
import cpcn.institution.tools.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import payment.api.system.PaymentEnvironment;
import payment.api.system.TxMessenger;
import payment.api.tx.redirectpayment.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

@Slf4j
@Service
public class CPCNPayService {

    @Autowired
    private ZhongJinPayConfig zhongJinPayConfig;


    /**
     * 支付方式
     * 13=微信 APP 支付
     * 23=支付宝 APP 支付
     * 24=支付宝 H5 支付
     * 25=支付宝服务窗
     * 33=银联 APP 支付
     * 34=银联 H5 支付
     * 35=移动大额支付
     * 36=银联手机 Pay
     */
    public R zhongjinPay(ZhongJinPayBean bean) {
        try {
            // 2.创建交易请求对象
            Tx2101Request tx2101Request = zhongJinPayConfig.getTx2101();
            tx2101Request.setAppID(zhongJinPayConfig.getAppId(bean.getPayType()));
            tx2101Request.setPageUrl(zhongJinPayConfig.getPageUrl(bean.getPayType()));
            tx2101Request.setPaymentNo(bean.getPaymentNo());
            tx2101Request.setRedirectSource(bean.getRedirectSource());
            tx2101Request.setPayWay(bean.getPayWay());
            tx2101Request.setPayType(bean.getPayType());
            tx2101Request.setAmount(bean.getAmount());
            tx2101Request.setGoodsName(bean.getGoodsName());
            // 3.执行报文处理
            tx2101Request.process();
            log.info("--------处理报文结果:" + JSONObject.toJSONString(tx2101Request));
            JSONObject map = new JSONObject();
            map.put("message", tx2101Request.getRequestMessage());
            map.put("signature", tx2101Request.getRequestSignature());
            map.put("digitalEnvelope", tx2101Request.getDgtlEnvlp());
            map.put("signAlgorithm", tx2101Request.getSignAlgorithm());
            map.put("signSN", tx2101Request.getSignSN());
            map.put("encryptSN", tx2101Request.getEncryptSN());
            map.put("institutionID", tx2101Request.getInstitutionID());
            map.put("payType", tx2101Request.getPayType());
            map.put("notifyUrl", tx2101Request.getPageUrl());
            map.put("orderNo", bean.getPaymentNo());
            R r = dealRequestResult(map, tx2101Request.getTxCode());
            log.info("--------支付返回最终结果:" + JSONObject.toJSONString(r));
            return r;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.fail("支付失败");
    }


    public R dealRequestResult(JSONObject map, String txCode) {
        log.info("------------请求类进行处理,进行签名和报文组装结果:" + JSONObject.toJSONString(map));
        // 获得参数message和signature
        String message = map.getString("message");
        String signature = map.getString("signature");
        String digitalEnvelope = map.getString("digitalEnvelope");
        String signAlgorithm = map.getString("signAlgorithm");
        String signSN = map.getString("signSN");
        String encryptSN = map.getString("encryptSN");
        String institutionID = map.getString("institutionID");
        log.info("------------message=" + message);
        log.info("------------signature=" + signature);
        log.info("------------digitalEnvelope=" + digitalEnvelope);
        log.info("------------signAlgorithm=" + signAlgorithm);
        log.info("------------signSN=" + signSN);
        log.info("------------encryptSN=" + encryptSN);
        log.info("------------institutionID=" + institutionID);


        RequestDgtEnvlp requestDgtEnvlp = new RequestDgtEnvlp();
        requestDgtEnvlp.setIsDgEnv("NO");
        requestDgtEnvlp.setDgtlEnvlp(digitalEnvelope);
        requestDgtEnvlp.setSignAlgorithm(signAlgorithm);
        requestDgtEnvlp.setSignSN(signSN);
        requestDgtEnvlp.setEncryptSN(encryptSN);
        requestDgtEnvlp.setInstitutionID(institutionID);
        // 与支付平台进行通讯
        TxMessenger txMessenger = new TxMessenger();
        try {
            // 发送交易请求并获取响应报文
            String[] respMsg = txMessenger.send(message, signature, requestDgtEnvlp);
            log.info("------------PaymentEnvironment.txURL=" + PaymentEnvironment.txURL);
            log.info("---------------分割线--------------");
            log.info("--------------------respMsg:{}",JSONObject.toJSONString(respMsg));
            String plainText;
            if ("YES".equals(respMsg[2])) {
                //如果响应是数字信封,对消息进行对称解密
                try {
                    log.info("---------------开始对响应消息做对称解密。。。。。。");
                    respMsg[0] = DigitalEnvelopeUtil.decryptResponse(respMsg[0], respMsg[3], respMsg[5], respMsg[6]);
                    plainText = respMsg[0];
                    respMsg[0] = Base64.encode(respMsg[0], "UTF-8");
                    respMsg[0] = respMsg[0] + "," + respMsg[5] + "," + respMsg[4] + "," + respMsg[2];
                    log.info("---------------响应消息做对称解密完成。。。。。。");
                    log.info("---------------响应消息报文:[" + plainText + "]");
                } catch (Exception e) {
                    log.info("---------------异常内容:" + e);
                    throw new Exception(e + "对称解密异常!");
                }
            } else {
                // 1:signature
                plainText = new String(Base64.decode(respMsg[0]), "UTF-8");
                if (StringUtil.isNotEmpty(respMsg[5])) {
                    respMsg[0] = respMsg[0] + "," + respMsg[5] + "," + respMsg[4] + "," + respMsg[2];
                }
            }
            log.info("--------------------respMsg:{}",JSONObject.toJSONString(respMsg));
            if (txCode.equals("2101")) {
                String orderNo = map.getString("orderNo");
                // 生成响应类
                Tx2101Response tx2101Response = new Tx2101Response(respMsg[0], respMsg[1]);
                log.info("---------------交易结果:" + JSONObject.toJSONString(tx2101Response));
                // 获取响应中的字段值并进行业务处理
                String responseCode = tx2101Response.getCode();
                String responseMessage = tx2101Response.getMessage();
                //当code=2000时,解析body体里的内容
                if ("2000".endsWith(responseCode)) {
                    String status = tx2101Response.getStatus();
                    if (status.equals("10")) {
                        String responseStatus = tx2101Response.getStatus();
                        log.info("---------------中金交易预支付结果:" + responseStatus);
                        log.info("---------------中金交易预支付结果:" + tx2101Response.getAuthCode());
                        String authCode = tx2101Response.getAuthCode();
                        JSONObject object = new JSONObject();
                        object.put("authCode", authCode);
                        object.put("orderNo", orderNo);
                        return R.ok(object);
                    } else {
                        return R.fail("授权失败");
                    }
                } else {
                    return R.fail(responseMessage);
                }
            }
            if (txCode.equals("2111")) {
                // 生成响应类
                Tx2111Response response = new Tx2111Response(respMsg[0], respMsg[1]);
                log.info("---------------退款结果:" + JSONObject.toJSONString(response));
                // 获取响应中的字段值并进行业务处理
                String responseCode = response.getCode();
                String responseMessage = response.getMessage();
                //当code=2000时,解析body体里的内容
                if ("2000".endsWith(responseCode)) {
                    ZhongJinQueryRefundResp refundResp = new ZhongJinQueryRefundResp();
                    String status = response.getStatus();
                    if (status.equals("10")){
                        refundResp.setRefundInfo("处理中");
                    }else if (status.equals("20")){
                        refundResp.setRefundInfo("退款失败");
                    }
                    refundResp.setRefundStatus(status);
                    return R.ok(refundResp);
                } else {
                    return R.fail(responseMessage);
                }
            }
            if (txCode.equals("2102")) {
                // 生成响应类
                Tx2102Response response = new Tx2102Response(respMsg[0], respMsg[1]);
                log.info("---------------查询结果:" + JSONObject.toJSONString(response));
                // 获取响应中的字段值并进行业务处理
                String responseCode = response.getCode();
                String responseMessage = response.getMessage();
                String status = response.getStatus();
                log.info("----------responseCode:{}", responseCode);
                log.info("----------responseMessage:{}", responseMessage);
                log.info("----------status:{}", status);
                if ("2000".endsWith(responseCode)) {
                    ZhongJinQueryPayResp resp = new ZhongJinQueryPayResp();
                    if (status.equals("20")) {
                        resp.setPayInfo("交易成功");
                    } else if (status.equals("10")) {
                        resp.setPayInfo("交易未支付");
                    } else if (status.equals("30")) {
                        resp.setPayInfo("交易支付失败");
                    } else if (status.equals("40")) {
                        resp.setPayInfo("交易关闭");
                    }
                    resp.setPayStatus(status);
                    resp.setOrderNo(response.getPaymentNo());
                    resp.setPayAmount(BigDecimal.valueOf(Long.valueOf(response.getAmount())).divide(BigDecimal.valueOf(100).setScale(2)));
                    resp.setTradeNo(response.getTraceNo());
                    return R.ok(resp);
                } else {
                    return R.fail(responseMessage);
                }
            }
            if (txCode.equals("2112")){
                Tx2112Response tx2112Response = new Tx2112Response(respMsg[0],respMsg[1]);
                String responseCode = tx2112Response.getResponseCode();
                String responseMessage = tx2112Response.getResponseMessage();
                log.info("----------------查询退款结果:{}",JSONObject.toJSONString(tx2112Response));
                if ("2000".equals(responseCode)){
                    String paymentNo = tx2112Response.getPaymentNo();
                    String refundTraceNo = tx2112Response.getRefundTraceNo();
                    // 退款状态
                    // 10=已经受理
                    // 20=退款失败
                    // 30=正在退款
                    // 40=已经执行(已经发送转账指令)
                    ZhongJinQueryRefundResp refundResp = new ZhongJinQueryRefundResp();
                    String status = tx2112Response.getStatus();
                    if (status.equals("10")){
                        refundResp.setRefundInfo("已经受理");
                    }else if (status.equals("20")){
                        refundResp.setRefundInfo("退款失败");
                    }else if (status.equals("30")){
                        refundResp.setRefundInfo("正在退款");
                    }else if (status.equals("40")){
                        refundResp.setRefundInfo("已经执行");
                    }
                    refundResp.setRefundStatus(status);
                    refundResp.setRefundOrderNo(paymentNo);
                    refundResp.setRefundTradeNo(refundTraceNo);
                    return R.ok(refundResp);
                }
                return R.fail(responseMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.fail("操作失败");
    }

    public R zhongjinRefund(ZhongJinRefundBean bean) {
        log.info("----------------中金退款请求参数:{}",JSONObject.toJSONString(bean));
        try {
            // 2.创建交易请求对象
            Tx2111Request tx2111Request = zhongJinPayConfig.getTx2111();
            tx2111Request.setRefundNo(bean.getRefundNo());
            tx2111Request.setPaymentNo(bean.getOrderNo());
            tx2111Request.setAmount(bean.getAmount());
            // 3.执行报文处理
            tx2111Request.process();
            log.info("--------退款处理报文结果:" + JSONObject.toJSONString(tx2111Request));
            JSONObject map = new JSONObject();
            map.put("message", tx2111Request.getRequestMessage());
            map.put("signature", tx2111Request.getRequestSignature());
            map.put("digitalEnvelope", tx2111Request.getDgtlEnvlp());
            map.put("signAlgorithm", tx2111Request.getSignAlgorithm());
            map.put("signSN", tx2111Request.getSignSN());
            map.put("encryptSN", tx2111Request.getEncryptSN());
            map.put("institutionID", tx2111Request.getInstitutionID());
            map.put("payType", "0");
            log.info("--------退款请求参数:" + JSONObject.toJSONString(map));
            R r = dealRequestResult(map, tx2111Request.getTxCode());
            log.info("--------退款返回最终结果:" + JSONObject.toJSONString(tx2111Request));
            return r;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.fail("支付失败");
    }

    public R<ZhongJinQueryPayResp> queryPay(String orderNo) throws Exception {
        log.info("------------查询支付订单号:{}", orderNo);
        // 2.创建交易请求对象
        Tx2102Request tx2102Request = zhongJinPayConfig.getTx2102();
        tx2102Request.setPaymentNo(orderNo);
        // 3.执行报文处理
        tx2102Request.process();
        log.info("--------查询处理报文结果:" + JSONObject.toJSONString(tx2102Request));
        JSONObject request = new JSONObject();
        // 4.将参数放置到request对象
        request.put("plainText", tx2102Request.getRequestPlainText());
        request.put("message", tx2102Request.getRequestMessage());
        request.put("signature", tx2102Request.getRequestSignature());
        request.put("txCode", "2102");
        request.put("txName", "跳转支付订单查询");
        request.put("isDgEnv", PaymentEnvironment.isDgEnv);
        request.put("dgtlEnvlp", tx2102Request.getDgtlEnvlp());
        request.put("signAlgorithm", tx2102Request.getSignAlgorithm());
        request.put("signSN", tx2102Request.getSignSN());
        request.put("encryptSN", tx2102Request.getEncryptSN());
        request.put("institutionID", tx2102Request.getInstitutionID());
        R r = dealRequestResult(request, tx2102Request.getTxCode());
        log.info("--------支付查询返回最终结果:" + JSONObject.toJSONString(tx2102Request));
        return r;
    }

    public R<ZhongJinQueryPayResp> queryRefund(String orderNo) throws Exception {
        log.info("------------查询支付订单号:{}", orderNo);
        // 2.创建交易请求对象
        Tx2112Request tx2112 = zhongJinPayConfig.getTx2112();
        tx2112.setRefundNo(orderNo);
        // 3.执行报文处理
        tx2112.process();
        log.info("--------查询处理报文结果:" + JSONObject.toJSONString(tx2112));
        JSONObject request = new JSONObject();
        // 4.将参数放置到request对象
        request.put("plainText", tx2112.getRequestPlainText());
        request.put("message", tx2112.getRequestMessage());
        request.put("signature", tx2112.getRequestSignature());
        request.put("txCode", "2102");
        request.put("txName", "跳转支付订单查询");
        request.put("isDgEnv", PaymentEnvironment.isDgEnv);
        request.put("dgtlEnvlp", tx2112.getDgtlEnvlp());
        request.put("signAlgorithm", tx2112.getSignAlgorithm());
        request.put("signSN", tx2112.getSignSN());
        request.put("encryptSN", tx2112.getEncryptSN());
        request.put("institutionID", tx2112.getInstitutionID());
        R r = dealRequestResult(request, tx2112.getTxCode());
        log.info("--------支付查询返回最终结果:" + JSONObject.toJSONString(tx2112));
        return r;
    }

}



支付请求到的结果(authCode)不要处理直接返回给前端,他们处理,中金提供安卓、ios、uniapp相关的API对接方式,至此服务端对接完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值