预支付
大白话来讲,就是用户点击支付但还未支付钱,但已经在抖音平台生成了订单,只不过这比订单用户没有付款
预下单
就是预支付,然后用户支付钱,
api接口:https://developer.open-douyin.com/microapp/ttfa7b8cc6654489e201/pay
demo
tt.createOrder({
goodsList: [
{
quantity: that.orderData.quantity,
price: amos / that.orderData.quantity,
goodsName: that.orderData.movieName,
goodsPhoto: that.orderData.pic,
goodsId: that.orderData.outOrderNo + "g",
goodsType: 2,
}
],
payment: {
totalAmount: 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();
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();
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));
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);
}
}