支付中心接口调用逻辑解析

项目简介:

oa系统需要报销发票,这个钱是oracle支付,oracle通过银行付给oa。有这种情况,oracle支付失败了,银行没有把钱付给oa,但是oracle这边的支付状态是支付成功。这时候就用到我们系统了,oa会把支付失败的数据-OA付款申请,推到我们系统,直接实时落到业务表,(不需要先落中间表,再落业务表),原因?,最后落接口表(状态已同步,仅供查询)。那我们怎么接受过来的数据,在我们系统提供一个restful接口,给他们调用(发布项目即可,不用关系如何调用),他们调这个接口把数据传过来(接收oralce支付结果同样)。

oa支付数据失败,通过该系统把支付请求发送给oracle线下支付

涉及系统:oa系统,支付中心,oralce财务支付系统 

1,处理OA推送来的支付请求数据

入参是报文,具体怎么推送过来的?oa数据-oa中间表

2,同步【OA】接口数据到业务表,中间表到业务表

同步方式:

 *手动同步OA中间表数据到业务表
 *定时任务

详细逻辑:

 *写入支付台账表,生成支付台账编号

 *更新中间表,支付台账编号

oa发送支付请求-支付中心-落中间表-落业务表payment_account(创建退票支付申请)

3,通知【Oracle】支付账单,支付中心发送退票支付申请到oracle财务系统,调用方式HttpClient,根据oracle响应码判断支付是否成功,更新业务表状态

4,接收来自Oracle的付款结果数据

入参是报文,具体怎么推送过来的?oracle数据-oracle中间表

5,同步【Oracle】接口表数据到业务表

从oracle中间表payment_middle_oracle到业务表payment_account_detail

同步方式:

5.1,实时处理Oracle推送数据,原始报文落oracle业务表

实时同步详解:

  *判断是否存在重复数据,(付款凭证编号),stream对数据进行分组

Map<String, List<OracleApplyRequest>> groupBy = requestList.stream().collect(Collectors.groupingBy(OracleApplyRequest::getpDocNum));

*处理数据,校验数据
 **支付台账编号进行分组
 **支付台账中支付编号code是否存在/取消,
 **支付台账中付款凭证编号docNum是否已存在,
 **支付台账是否超额支付
*Oracle数据同步到业务表,实时同步,定时/手动共同调用
 **校验支付台账,根据支付编号查询
 **写入oracle业务表payment_account_detail
 **更新支付台账表已付款金额,状态等字段
*写入中间表(最后才写入中间表)
 **报文数据写入中间表

5.2,非实时处理又分为,前提是已经落到中间表

1),手动同步OA中间表数据到业务表
2),定时任务

6,通知【OA】支付结果,通过webService调用

推送Oracle支付结果到OA,哪些数据支付台账payment_account未同步,已支付完成

 推送Oracle支付结果到OA

通知方式

*手动,重处理

*定时任务

一,处理OA推送来的支付请求数据

如果OA更新了该付款申请编号下数据信息,需要先删除中间表及业务表数据,再写入
1,删除payment_account数据,条件oa_codeOA付款申请编号
2,删除payment_middle_oa数据,条件oa_codeOA付款申请编号
3,oa数据落payment_middle_oa中间表,批量写入

三,通知【Oracle】支付账单

支付中心推送退票申请数据到oracle财务系统,httpClient详解

@JsonProperty的使用

https://www.cnblogs.com/winner-0715/p/6109037.html?utm_source=itdadao&utm_medium=referral

http authorization 基本认证

https://www.cnblogs.com/chenrong/articles/5818498.html

https://blog.csdn.net/luckyzsion/article/details/80216861

需要关注

非http(作用?)

1,url

2,请求头,###看不懂?

3,请求体,请求参数

http信息

1,url

2,请求头(包含上面请求头,请求体),并进行基础认证,用户名:密码,进行basse64编码

3,请求体,json字符串封装成StringEntity发送

4,根据响应码更新业务表状态,是否处理成功

六,通知【OA】支付结果,webservice实现

请参考:https://mp.csdn.net/postedit/102676600

 推送Oracle支付结果到OA

七,http代码实现详解

1 ,业务调用逻辑

*包装请求头及请求参数

*处理最终请求参数为json字符串

ObjectMapper objectMapper = new ObjectMapper();
String object = objectMapper.writeValueAsString(oracleRequest);

*获取配置用户名密码,待工具类基本认证

*调用工具类

 /**
     * 推送OA支付请求到Oracle
     *
     * @param request
     * @return
     */
    @Override
    public String pushMsgToOracle(CallOracleRequest request) {
        log.info(">>>>>> 开始请求访问 [ Oracle ] 接口: URL == " + applyOracleUrl);
        OracleRequest oracleRequest = new OracleRequest();
        OracleInput oracleInput = new OracleInput();
        OracleParameters parameters = new OracleParameters();
        BeanUtils.copyProperties(request, parameters);
        OracleRestHeader restHeader = new OracleRestHeader();
        // 封装请求头(此处请求头非Http请求头),请求体(非http请求体此处只有请求入参,http请求体包含此处请求+请求体)
        oracleInput.setRestHeader(restHeader);
        oracleInput.setParameters(parameters);
        oracleRequest.setOracleInput(oracleInput);
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String object = objectMapper.writeValueAsString(oracleRequest);
            log.info(">>>>apply[Oracle]<<<< object == " + object);
            String up = oracleUsername + ":" + oraclePassword;
            String response = HttpPostUtil.getHttpClient(applyOracleUrl, object, up);
            System.out.println("<---[Oracle]---> response: " + response);
            JSONObject oracleMsg = JSONObject.parseObject(response);
            JSONObject outputParameters = (JSONObject) oracleMsg.get("OutputParameters");
            //oracle响应码响应消息
            String status = (String) outputParameters.get("X_RETURN_STATUS");
            String msg = (String) outputParameters.get("X_MSG_DATA");
            log.info(">>>>>> 收到来自【Oracle】的响应:msg == " + msg);
            if (StringUtils.isNotEmpty(status) && !Const.S.equals(status)) {
                return msg;
            }
        } catch (Exception e) {
            log.error("对外接口【Oracle】访问异常");
            e.printStackTrace();
            return "E";
        }
        return "";
    }

2,请求头及请求参数封装

 

OracleRequest oracleRequest = new OracleRequest();
OracleInput oracleInput = new OracleInput();
OracleParameters parameters = new OracleParameters();
BeanUtils.copyProperties(request, parameters);
OracleRestHeader restHeader = new OracleRestHeader();
// 封装请求头(此处请求头非Http请求头),请求体(非http请求体此处只有请求入参,http请求体包含此处请求+请求体)
oracleInput.setRestHeader(restHeader);
oracleInput.setParameters(parameters);
oracleRequest.setOracleInput(oracleInput);

*请求头

public class OracleRestHeader {

    @JsonProperty(value = "@xmlns")
    private String xmlns;

    @JsonProperty(value = "Responsibility")
    private String responsibility;

    @JsonProperty(value = "RespApplication")
    private String respApplication;

    @JsonProperty(value = "SecurityGroup")
    private String securityGroup;

    @JsonProperty(value = "NLSLanguage")
    private String language;


    public OracleRestHeader() {
        this.xmlns = "http://xmlns.oracle.com/apps/ap/rest/cux_pc_pay_request_pub/header";
        this.responsibility = "";
        this.respApplication = "";
        this.securityGroup = "STANDARD";
        this.language = "SIMPLIFIED CHINESE";
    }

**请求参数

@JsonProperty

需要做序列化字段处理,处理成接收方需要的字段类型,

public class OracleParameters {

    // 支付中心支付编号 */  /*唯一标识
    @JsonProperty("P_PAY_NUM")
    private String pPayNum;
    // 财务公司OU代码,安吉总部为OU_1000
    @JsonProperty("P_OU_CODE")
    private String pOuCode;
    // OA付款申请编号
    @JsonProperty("P_APPLY_NUM")
    private String pApplyNum;
    // OA付款申请名称
    @JsonProperty("P_APPLY_NAME")
    private String pApplyName;
    // 供应商名称
    @JsonProperty("P_VENDOR_NAME")
    private String pVendorName;
    // 供应商编号
    @JsonProperty("P_VENDOR_CODE")
    private String pVendorCode;
    // 申请日期:2019/07/01
    @JsonProperty("P_APPLY_DATE")
    @JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8")
    private Date pApplyDate;
    // 申请人
    @JsonProperty("P_APPLY_USER")
    private String pApplyUser;
    // 币种
    @JsonProperty("P_CURRENCY_CODE")
    private String pCurrencyCode;
    // 申请金额
    @JsonProperty("P_APPLY_AMOUNT")
    private BigDecimal pApplyAmount;

***包装类1:包装以上请求头,请求参数

public class OracleInput<T> {

    @JsonProperty(value = "@xmlns")
    private String xmlns;

    @JsonProperty("RESTHeader")
    private OracleRestHeader restHeader;

    @JsonProperty("InputParameters")
    private OracleParameters parameters;

    public OracleInput() {
        this.xmlns = "http://xmlns.oracle.com/apps/ap/rest/cux_pc_pay_request_pub/Create_Payment_Apply/";
    }

 ****包装类2,包装:包装类1

public class OracleRequest<T> {

    @JsonProperty("PAYMENT_APPLY_CODE_Input")
    private OracleInput<T> oracleInput;

    public OracleInput<T> getOracleInput() {
        return oracleInput;
    }

    public void setOracleInput(OracleInput<T> oracleInput) {
        this.oracleInput = oracleInput;
    }
}

3,httpclient工具类

*url

*请求头,请求格式

*用户名密码base64编码,封装成请求头

*把最终请求参数,String类型转化为StringEntity

*执行http请求

*获取响应数据

/**
     * Http调用
     *
     * @param path
     * @param stringObject
     */
    public static String getHttpClient(String path, String stringObject, String up) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String content = "";
        // 创建HttpGet请求,相当于在浏览器输入地址
        HttpPost httpPost = new HttpPost(path);
        //请求头:1,请求格式 2,用户名:密码基础认证
        httpPost.addHeader("Content-Type", "application/json");
        byte[] encodeBase = Base64.encodeBase64(up.getBytes());
        String authorization = new String(encodeBase);
        authorization = "Basic " + authorization;
        httpPost.addHeader("Authorization", authorization);
        //把请求体json字符串封装成StringEntity
        StringEntity stringEntity = new StringEntity(stringObject, "utf-8");
        stringEntity.setContentEncoding("UTF-8");
        httpPost.setEntity(stringEntity);
        CloseableHttpResponse response = null;
        try {
            // 执行请求,相当于敲完地址后按下回车。获取响应
            response = httpclient.execute(httpPost);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                // 解析响应,获取数据
                content = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                // 关闭资源
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 关闭浏览器
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return content;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值