feat(googleplay): 新增购买成功记录服务并注入使用
This commit is contained in:
@@ -0,0 +1,137 @@
|
|||||||
|
package com.yolo.keyborad.googleplay;
|
||||||
|
|
||||||
|
import com.yolo.keyborad.googleplay.model.GooglePlayPurchaseSnapshot;
|
||||||
|
import com.yolo.keyborad.model.entity.KeyboardProductItems;
|
||||||
|
import com.yolo.keyborad.model.entity.KeyboardUserPurchaseRecords;
|
||||||
|
import com.yolo.keyborad.model.entity.googleplay.GooglePlayOrder;
|
||||||
|
import com.yolo.keyborad.model.entity.googleplay.GooglePlayUserEntitlement;
|
||||||
|
import com.yolo.keyborad.service.KeyboardUserPurchaseRecordsService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GooglePlayPurchaseRecordService {
|
||||||
|
|
||||||
|
private static final String PURCHASE_STATUS_PAID = "PAID";
|
||||||
|
|
||||||
|
private final KeyboardUserPurchaseRecordsService purchaseRecordsService;
|
||||||
|
|
||||||
|
public void recordSuccess(Long userId,
|
||||||
|
KeyboardProductItems product,
|
||||||
|
GooglePlayPurchaseSnapshot snapshot,
|
||||||
|
GooglePlayOrder order,
|
||||||
|
GooglePlayUserEntitlement entitlement) {
|
||||||
|
if (!shouldRecord(userId, order, entitlement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String transactionId = resolveTransactionId(order);
|
||||||
|
if (alreadyRecorded(transactionId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
purchaseRecordsService.save(buildRecord(userId, product, snapshot, order, transactionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldRecord(Long userId,
|
||||||
|
GooglePlayOrder order,
|
||||||
|
GooglePlayUserEntitlement entitlement) {
|
||||||
|
return userId != null
|
||||||
|
&& order != null
|
||||||
|
&& entitlement != null
|
||||||
|
&& Boolean.TRUE.equals(entitlement.getActive())
|
||||||
|
&& !GooglePlayConstants.DELIVERY_REVOKED.equals(order.getDeliveryStatus())
|
||||||
|
&& !GooglePlayConstants.DELIVERY_MANUAL_REVIEW.equals(order.getDeliveryStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean alreadyRecorded(String transactionId) {
|
||||||
|
return purchaseRecordsService.lambdaQuery()
|
||||||
|
.eq(KeyboardUserPurchaseRecords::getTransactionId, transactionId)
|
||||||
|
.eq(KeyboardUserPurchaseRecords::getPaymentMethod, GooglePlayConstants.PAYMENT_METHOD_GOOGLE_PLAY)
|
||||||
|
.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyboardUserPurchaseRecords buildRecord(Long userId,
|
||||||
|
KeyboardProductItems product,
|
||||||
|
GooglePlayPurchaseSnapshot snapshot,
|
||||||
|
GooglePlayOrder order,
|
||||||
|
String transactionId) {
|
||||||
|
KeyboardUserPurchaseRecords record = new KeyboardUserPurchaseRecords();
|
||||||
|
record.setUserId(Math.toIntExact(userId));
|
||||||
|
record.setProductId(product.getProductId());
|
||||||
|
record.setPurchaseQuantity(resolvePurchaseQuantity(product, snapshot, order));
|
||||||
|
record.setPrice(product.getPrice());
|
||||||
|
record.setCurrency(product.getCurrency());
|
||||||
|
record.setPurchaseType(resolvePurchaseType(product, snapshot));
|
||||||
|
Date purchaseTime = resolvePurchaseTime(snapshot, order);
|
||||||
|
record.setPurchaseTime(purchaseTime);
|
||||||
|
record.setStatus(PURCHASE_STATUS_PAID);
|
||||||
|
record.setPaymentMethod(GooglePlayConstants.PAYMENT_METHOD_GOOGLE_PLAY);
|
||||||
|
record.setTransactionId(transactionId);
|
||||||
|
record.setOriginalTransactionId(order.getPurchaseToken());
|
||||||
|
record.setProductIds(new String[]{product.getProductId()});
|
||||||
|
record.setPurchaseDate(purchaseTime);
|
||||||
|
record.setExpiresDate(snapshot.getExpiryTime());
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer resolvePurchaseQuantity(KeyboardProductItems product,
|
||||||
|
GooglePlayPurchaseSnapshot snapshot,
|
||||||
|
GooglePlayOrder order) {
|
||||||
|
Integer configured = product.getDurationValue();
|
||||||
|
if (configured != null) {
|
||||||
|
return configured;
|
||||||
|
}
|
||||||
|
Integer parsed = parseInteger(product.getName());
|
||||||
|
if (parsed != null) {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
if (snapshot.getQuantity() != null) {
|
||||||
|
return snapshot.getQuantity();
|
||||||
|
}
|
||||||
|
return Objects.requireNonNullElse(order.getQuantity(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer parseInteger(String raw) {
|
||||||
|
if (raw == null || raw.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String digits = raw.replaceAll("[^\\d]", "");
|
||||||
|
if (digits.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Integer.parseInt(digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolvePurchaseType(KeyboardProductItems product, GooglePlayPurchaseSnapshot snapshot) {
|
||||||
|
if (product.getType() != null && !product.getType().isBlank()) {
|
||||||
|
return product.getType();
|
||||||
|
}
|
||||||
|
if (GooglePlayConstants.PRODUCT_TYPE_SUBSCRIPTION.equals(snapshot.getProductType())) {
|
||||||
|
return "subscription";
|
||||||
|
}
|
||||||
|
return "in-app-purchase";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date resolvePurchaseTime(GooglePlayPurchaseSnapshot snapshot, GooglePlayOrder order) {
|
||||||
|
if (snapshot.getStartTime() != null) {
|
||||||
|
return snapshot.getStartTime();
|
||||||
|
}
|
||||||
|
if (order.getLastEventTime() != null) {
|
||||||
|
return order.getLastEventTime();
|
||||||
|
}
|
||||||
|
if (snapshot.getLastSyncedAt() != null) {
|
||||||
|
return snapshot.getLastSyncedAt();
|
||||||
|
}
|
||||||
|
return new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveTransactionId(GooglePlayOrder order) {
|
||||||
|
if (order.getGoogleOrderId() != null && !order.getGoogleOrderId().isBlank()) {
|
||||||
|
return order.getGoogleOrderId();
|
||||||
|
}
|
||||||
|
return order.getOrderKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ public class GooglePlayStateService {
|
|||||||
private final GooglePlayPurchaseTokenMapper purchaseTokenMapper;
|
private final GooglePlayPurchaseTokenMapper purchaseTokenMapper;
|
||||||
private final KeyboardProductItemsService productItemsService;
|
private final KeyboardProductItemsService productItemsService;
|
||||||
private final GooglePlayEntitlementApplier entitlementApplier;
|
private final GooglePlayEntitlementApplier entitlementApplier;
|
||||||
|
private final GooglePlayPurchaseRecordService purchaseRecordService;
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public GooglePlaySyncResult sync(GooglePlaySyncCommand command, GooglePlayPurchaseSnapshot snapshot) {
|
public GooglePlaySyncResult sync(GooglePlaySyncCommand command, GooglePlayPurchaseSnapshot snapshot) {
|
||||||
@@ -37,6 +38,7 @@ public class GooglePlayStateService {
|
|||||||
GooglePlayUserEntitlement entitlement = null;
|
GooglePlayUserEntitlement entitlement = null;
|
||||||
if (command.getUserId() != null) {
|
if (command.getUserId() != null) {
|
||||||
entitlement = entitlementApplier.apply(command.getUserId(), product, snapshot, order);
|
entitlement = entitlementApplier.apply(command.getUserId(), product, snapshot, order);
|
||||||
|
purchaseRecordService.recordSuccess(command.getUserId(), product, snapshot, order, entitlement);
|
||||||
}
|
}
|
||||||
saveOrder(order);
|
saveOrder(order);
|
||||||
token.setLatestOrderKey(order.getOrderKey());
|
token.setLatestOrderKey(order.getOrderKey());
|
||||||
|
|||||||
@@ -8,6 +8,4 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public interface KeyboardUserPurchaseRecordsService extends IService<KeyboardUserPurchaseRecords>{
|
public interface KeyboardUserPurchaseRecordsService extends IService<KeyboardUserPurchaseRecords>{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user