抖音支付的使用(Java版本)

预支付

大白话来讲,就是用户点击支付但还未支付钱,但已经在抖音平台生成了订单,只不过这比订单用户没有付款

预下单

就是预支付,然后用户支付钱,
api接口:https://developer.open-douyin.com/microapp/ttfa7b8cc6654489e201/pay

demo

 tt.createOrder({
   goodsList: [
       {
         quantity: that.orderData.quantity, // 购买数量 必填
         price: amos / that.orderData.quantity, // 商品价格 必填amos/that.orderData.quantity
         goodsName: that.orderData.movieName, // 商品名称 必填
         goodsPhoto: that.orderData.pic, // 商品图片链接 必填
         goodsId: that.orderData.outOrderNo + "g", // 商品ID 必填
         goodsType: 2, // 商品类型 必填
     }
   ],
   payment: {
     totalAmount: amos, // 订单总价 必填amos
   },
   callbackUrl: 'https://www.baidu.com/pay/dyNotify', // 预支付回调接口,必须要,否则预支付失败不会调起收银台
   callbackData: {}, // 透传数据,开发者自定义字段 非必传

   success: (res) => {
     const {
       orderId,
       outOrderNo
     } = res;
   },
   fail: (res) => {
     const {
       orderId,
       outOrderNo,
       errNo,
       errMsg,
       errLogId
     } = res;
     // 当预下单失败时会提供该数据,可供服务端排查问题
     if (errLogId) {
       console.log("预下单失败", errNo, errMsg, errLogId);
     }
     // 预下单成功,但用户支付失败
     if (orderId || outOrderNo) {
       console.log("支付失败", errNo, errMsg, orderId, outOrderNo);
     }
 });

预支付回调接口

处理前面的callbackUrl。处理成功将会调起收银台

demo

import javax.servlet.http.HttpServletRequest;

public Object dyNotify(HttpServletRequest request) {
    String builder = getBodyContent(request);
    Gson gson = new Gson();
    // 解析JSON字符串为OrderResponse对象
    CallBackResponse orderResponse = gson.fromJson(builder, CallBackResponse.class);

    log.info("抖音通知 : {} | {}", builder, request.getQueryString());

    if ("pre_create_order".equals(orderResponse.getType())) {
        PreCreateOrderMsg preCreateOrderMsg = (PreCreateOrderMsg)orderResponse.parseCallBackResponseMsg();
        DyNotifyOrderCpExtra dyNotifyOrderCpExtra = preCreateOrderMsg.parseDyNotifyOrderCpExtra();
        Integer ticketType = dyNotifyOrderCpExtra.getTicketType();
        String outOrderNo =dyNotifyOrderCpExtra.getOutOrderNo();
        JyOrder jyOrder = jyOrderMapper.getOrderByOutOrderNo(outOrderNo);
        // 异步处理内部逻辑
        executorService.execute(() -> processOrderDetails(jyOrder,preCreateOrderMsg, ticketType));
        String startDate = jyOrder.getStartDate();
        String time = jyOrder.getTime();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime epoch = LocalDateTime.of(1970, 1, 1, 0, 0);
        String[] startDateParts = startDate.split(" ");
        String[] timeParts = time.split("-");
        String startTime = startDateParts[0] + " " + timeParts[0];
        String endTime = startDateParts[0] + " " + timeParts[1];
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalDateTime startTimeLocalDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endTimeLocalDateTime = LocalDateTime.parse(endTime, formatter);


        if (startTimeLocalDateTime.isAfter(endTimeLocalDateTime)) {
            endTimeLocalDateTime = endTimeLocalDateTime.plusDays(1);
        }
        DyNotifyOrderCallBackResult dyNotifyOrderCallBackResult = new DyNotifyOrderCallBackResult();
        dyNotifyOrderCallBackResult.setErr_no(0);
        dyNotifyOrderCallBackResult.setErr_tips("success");
        OrderCallBackData orderCallBackData = new OrderCallBackData();
        orderCallBackData.setOut_order_no(outOrderNo);
        orderCallBackData.setPay_expire_seconds(300);
        orderCallBackData.setPay_notify_url(DouYinNotificationUtils.getPayNotifyUrl()); // 支付成功回调接口
        OrderEntrySchema orderEntrySchema = new OrderEntrySchema();
        orderEntrySchema.setPath("pages/index/index");
        orderEntrySchema.setParams("{\"outOrderNo\": " + outOrderNo + "}");
        orderCallBackData.setOrder_entry_schema(orderEntrySchema);
        OrderValidTime orderValidTime = new OrderValidTime();
        orderValidTime.setGoods_id(outOrderNo + "g");
        orderValidTime.setValid_start_time(Duration.between(epoch,now).toMillis());
        orderValidTime.setValid_end_time(Duration.between(epoch,endTimeLocalDateTime).toMillis());
        ArrayList<OrderValidTime> orderValidTimeArrayList = new ArrayList<>();
        orderValidTimeArrayList.add(orderValidTime);
        orderCallBackData.setOrder_valid_time(orderValidTimeArrayList);

        dyNotifyOrderCallBackResult.setData(orderCallBackData);
        System.out.println(dyNotifyOrderCallBackResult);
        System.out.println("预回调成功");
        return  dyNotifyOrderCallBackResult;
    }
}

支付成功回调

前面预支付回调接口填写的setPay_notify_url

处理支付成功回调

要对接口进行验签操作,避免黑客攻击

demo

 public Object dyNotify(HttpServletRequest request) {
     String builder = getBodyContent(request);
     Gson gson = new Gson();
     // 解析JSON字符串为OrderResponse对象
     CallBackResponse orderResponse = gson.fromJson(builder, CallBackResponse.class);

     log.info("抖音通知 : {} | {}", builder, request.getQueryString());
         //支付回调验签
         String nonceStr = request.getHeader("Byte-Nonce-Str");
         String timestamp = request.getHeader("Byte-Timestamp");
         String signature = request.getHeader("Byte-Signature");
         if (DouYinPayUtil.verify(builder,signature,Long.parseLong(timestamp),nonceStr)){
             if ("payment".equals(orderResponse.getType())){
             DyNotifyOrderPayCallBackResult dyNotifyOrderPayCallBackResult = new DyNotifyOrderPayCallBackResult();
             dyNotifyOrderPayCallBackResult.setErr_no(0);
             dyNotifyOrderPayCallBackResult.setErr_tips("success");
             return dyNotifyOrderPayCallBackResult;
         }else {
             System.out.println("支付回调验签失败");
             return new DyNotifyEmptyResult();
         }
 }


 public static boolean verify(String httpBody, String signStr, Long timestamp, String nonce){
     StringBuffer buffer = new StringBuffer();
     buffer.append(timestamp).append("\n");
     buffer.append(nonce).append("\n");
     buffer.append(httpBody).append("\n");
     String message = buffer.toString();
     try {
         Signature sign = null;
         sign = Signature.getInstance("SHA256withRSA");
         sign.initVerify(string2PublicKey(platformPublicKey)); // 注意验签时publicKey使用平台公钥而非应用公钥
         sign.update(message.getBytes(StandardCharsets.UTF_8));
         return sign.verify(Base64.getDecoder().decode(signStr.getBytes(StandardCharsets.UTF_8)));
     } catch (Exception e) {
         throw new RuntimeException(e);
     }
 }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

unique_perfect

您的支持是我创造的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值