为什么在苹果应用程序购买中在服务器端找不到交易记录?

Why could not find transaction record on the server side in Apple app purchase?

我正在我的Flutter项目中开发一个app purchase,我现在要验证我的purchase。在客户端,我传递了这个参数:

public class ReceiptVerifyRequest implements Serializable {


    @ApiModelProperty(value = "product ID")
    @NonNull
    private String productId;

    @ApiModelProperty(value = "receipt")
    @NonNull
    private String receipt;

  
    @ApiModelProperty(value = "transaction ID")
    @NonNull
    private String transactionId;
}

因为我现在是订阅产品和自动续订(SUBSCRIPTION product),所以我从服务器端的latest_receipt_info列表字段中选择记录是这样的:

private void savePayTransactionRecord(JSONArray latestReceiptInfo, IapProduct iapProduct, ReceiptVerifyRequest request) {
        if (ApplePayProductType.SUBSCRIPTION.getKey().equals(iapProduct.getProductType())) {
            if (latestReceiptInfo == null || latestReceiptInfo.size() == 0) {
                return;
            }
            for (Object item : latestReceiptInfo) {
                if (item instanceof JSONObject) {
                    JSONObject jsonObjectItem = (JSONObject) item;
                    if (request.getTransactionId().equals(jsonObjectItem.getString("transaction_id"))) {
                        mapFieldAndSave(jsonObjectItem);
                    }
                }
            }
        }
    }

令我惊讶的是,我无法通过交易ID匹配找到任何订单。为什么会这样?难道我做错了什么?我正在按照 Apple 手册的指南进行操作。我应该怎么做才能解决它?是什么导致了这种情况?对了,client transaction id是从purchased id中获取的,我看了flutter plugin的in app purchase源码,purchased id是从transaction identity中获取的,我认为transaction identity就是交易id。

现在我在沙盒中,我的订阅产品是 30 天。在沙盒中,它是 3 分钟,然后服务器每 3 分钟自动更新订阅。很长一段时间,最新生成的收据超过 latest_receipt_info 大小的最大值。所以找不到交易ID。这个逻辑对吗?

那么 latest_receipt_info 的最大大小是多少?但他的问题是:在服务器 latest_receipt_info 中找不到我所有的验证交易,这很奇怪。我已经尝试使用 web_order_line_item_id:

private void savePayTransactionRecord(JSONArray latestReceiptInfo, IapProduct iapProduct, ReceiptVerifyRequest request) {
        if (ApplePayProductType.SUBSCRIPTION.getKey().equals(iapProduct.getProductType())) {
            
            if (latestReceiptInfo == null || latestReceiptInfo.size() == 0) {
                return;
            }
            for (Object item : latestReceiptInfo) {
                if (item instanceof JSONObject) {
                    JSONObject jsonObjectItem = (JSONObject) item;
                    if (request.getTransactionId().equals(jsonObjectItem.getString("web_order_line_item_id"))) {
                        mapFieldAndSave(jsonObjectItem);
                    }
                }
            }
        }
    }

也不匹配。

实际上每次客户端向服务器请求时,交易ID都会改变。

交易标识符过去可用于确保单个收据不会被黑客攻击、复制、安装在许多设备中以及用于获取多个 IAP。当 Apple 使用相同的交易 ID 进行原始购买、免费回购和 restoreCompletedTransaction 时,这个保护系统就崩溃了。

这句话放在文档中是一个很好的句子。将为一些开发人员节省很多时间。来自 here