Preauth详解

发布时间:2023-05-19

一、preauth基本概念

preauth是指在用户购物时,商家在支付前对用户所持资金进行一定的预先授权,以保证用户支付能成功完成。在授权期内,用户的资金将不会被扣除,直到商家确认订单后才会进行正式的支付操作。preauth的主要作用是保护商家的利益,减少恶意购买行为的发生。 在preauth中,商家会向支付网关请求对用户资金进行一定数量的冻结,从而确保订单的货款能在未来支付成功,而不会因为余额不足等原因支付失败。

二、preauth的实现方法

在实现preauth时,主要有以下几种方法:

1. 基于信用卡的预授权

这是最常见的一种preauth实现方式,商家会在用户信用卡上授权一定的金额。当确认订单后,商家会再次向支付网关提交授权确认,并扣除相应的资金。

2. 基于银行账户的预授权

这种方式是在用户银行账户中进行资金冻结,和信用卡方式类似。不同之处在于,用户银行账户还需要额外开通一些支持预授权的服务,如国内的“代扣代缴”功能。

3. 基于第三方支付账户的预授权

目前像支付宝、微信等大型的第三方支付平台也开始支持preauth功能,商家可以通过这些平台进行资金的冻结和确认。不过,这种方式的可用性和安全性需要商家自行权衡。

三、preauth的优点和注意事项

1. 优点

a. 提高商家利润率:通过preauth方式,商家可以提高交易成功率,减少因为拍单行为等原因造成的不良影响。 b. 提高用户购买体验:授权期内用户的资金不会被扣除,冻结期结束后即可完成正常的支付操作。 c. 更高的交易安全性:以资金冻结的方式来完成授权,确保交易双方的权益。

2. 注意事项

a. 商家需要根据具体需求选择授权方式,并确保预授权服务的开通和使用。 b. 订单确认前,商家需要对用户资金情况进行严格地审核和确认,保证授权资金数量和订单金额一致。 c. 在授权期内,商家需要保证订单的及时确认,确保资金能够及时解冻。

四、代码示例

//基于信用卡的preauth实现
//授权请求
public void preauthRequest(CreditCard creditCard, Double amount) {
    // 发送授权请求至银行
    Bank bank = new Bank();
    PreauthResponse response = bank.preauthRequest(creditCard, amount);
    // 接收银行反馈结果,并进行处理
    AppResponse appResponse = new AppResponse();
    if (response.isSuccess()) {
        appResponse.setCode("0000");
        appResponse.setMsg("授权请求成功");
        // 将授权信息存入数据库
        Preauth preauth = new Preauth();
        preauth.setPreauthId(response.getPreauthId());
        preauth.setPreauthAmount(amount);
        preauth.setCreditCard(creditCard);
        preauthRepository.save(preauth);
    } else {
        appResponse.setCode("9999");
        appResponse.setMsg("授权请求失败");
    }
    // 返回授权结果
    return appResponse;
}
//确认订单
public void confirmOrder(Long orderId) {
    // 从数据库中查询授权信息
    Order order = orderRepository.findByOrderId(orderId);
    Preauth preauth = preauthRepository.findByPreauthId(order.getPreauthId());
    // 发送确认请求至银行
    Bank bank = new Bank();
    PreauthResponse response = bank.confirmRequest(preauth.getPreauthId(), preauth.getPreauthAmount());
    // 根据银行反馈结果进行处理
    if (response.isSuccess()) {
        // 扣款成功,将订单状态改为已支付状态
        order.setStatus(PAID);
        orderRepository.save(order);
        // 将授权信息从预授权表中删除
        preauthRepository.deleteById(preauth.getPreauthId());
    } else {
        // 扣款失败,将订单状态改为支付失败状态
        order.setStatus(FAILED);
        orderRepository.save(order);
    }
}