开发者控制台

适用于亚马逊应用商店计费兼容性的RVS生产设置

适用于亚马逊应用商店计费兼容性的RVS生产设置

发布应用后,您可以设置应用服务器与RVS生产服务器进行通信。亚马逊建议您从安全服务器调用RVS,因为它托管共享密钥。不要通过您的应用调用RVS。使用您的首选语言和技术设置应用服务器。服务器必须使用HTTPS之类的安全协议与RVS通信。您的服务器将向RVS发送验证请求并处理其收到的响应。

客户端设置

在客户端,对新的购买会调用亚马逊应用商店计费兼容性SDK的onPurchaseUpdated()方法。下面的Android示例代码执行以下任务:

  1. 通过覆盖onPurchaseUpdated()方法来监听新购买。
  2. 如果购买清单不为空,则通过将购买令牌传递给服务器来验证每笔购买。
  3. 如果购买有效,则授予商品,否则记录验证错误。
private void processPurchaseList(List<Purchase> purchases, List<String> skusToUpdate) {

    if (null != purchases) {
        for (final Purchase purchase : purchases) {
            // 使用收据验证服务验证收据
            final String purchaseToken = purchase.getPurchaseToken();
            // 将购买令牌发送到您的安全后端进行验证
            if(verifyInAppItemReceipt(purchaseToken, productType, packageName)) {
                // 处理购买,授予商品
            } else {
                Log.d("Purchase is not valid")
            }
        }
    }
}

@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {
    
    switch (billingResult.getResponseCode()) {
    
        case BillingClient.BillingResponseCode.OK:
            if(list != null) {
                processPurchaseList(list, null);
                return;
            }
            else {
                Log.d(TAG, "Null Purchase List Returned from OK response!");
            }
            break;
        case BillingClient.BillingResponseCode.USER_CANCELED:
        case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
        case BillingClient.BillingResponseCode.DEVELOPER_ERROR:
            // 处理这些案例
            break;
        default:
            // 处理默认情况
            break;
    }
}

服务器端设置

以下示例代码针对的是通用Java服务器。此代码调用purchases.products.getpurchases.subscriptionsv2.get API来执行以下任务:

  1. 创建包含相应开发者和交易信息的URL字符串。
  2. 连接到亚马逊RVS服务器并将交易URL传递给服务器。
  3. 从亚马逊RVS服务器检索响应。
  4. 将响应传递给应用。
// 验证权利或消费品收据
public static void verifyInAppItemReceipt(final String developerSecret, final String packageName, final String token) {

    // 调用purchases.products.get API以验证应用程序内商品购买
    String url = "https://appstore-sdk.amazon.com/version/1.0/" + 
    "developer/" + developerSecret + "/applications/" + packageName + "/purchases/subscriptionsv2/tokens/" + token

    JSONObject responseJson = verifyReceipt(url);

    JSONObject canceledStateContext = responseJson.getJSONObject("CanceledStateContext");
    String purchaseToken = responseJson.getString("purchaseToken");
    long purchaseTimeMillis = responseJson.getString("purchaseTimeMillis");
    long cancelDate = responseJson.optLong("cancelDate");
    boolean testTransaction = responseJson.optBoolean("testTransaction");
}

// 验证订阅收据
public static void verifySubscriptionReceipt(final String developerSecret, final String packageName, final String productId, final String token) {
    
    // 调用purchases.subscriptionsv2.get API来验证订阅商品的购买。
    String url = "https://appstore-sdk.amazon.com/version/1.0/" + 
    "developer/" + developerSecret + "/applications/" + packageName + "/purchases/products/" + productId + "/tokens/" + token

    JSONObject responseJson = verifyReceipt(url);

    String purchaseToken = responseJson.getString("purchaseToken");
    String productType = responseJson.getString("productType");
    String productId = responseJson.getString("productId");
    long purchaseTimeMillis = responseJson.getString("purchaseTimeMillis");
    long cancelDate = responseJson.optLong("cancelDate");
    boolean testTransaction = responseJson.optBoolean("testTransaction");
}

private static void verifyReceipt(final String url) {
    System.out.println("Start Receipt Validation");

    System.out.println("Amazon Receipt Validation URL: " + url);


    JSONObject responseJson = null;
    try {
        System.out.println("Open HTTP connection to Amazon RVS");

        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        int responseCode = con.getResponseCode();

        System.out.println("Amazon RVS Response Code: " + responseCode);

        switch (responseCode)
        {
            case 400:
                System.out.println("Amazon RVS Error: Invalid purchase token or productId");
                // 在本地处理响应数据
                // 响应应用
                break;

            case 401:
                System.out.println("Amazon RVS Error: Invalid developerSecret");
                // 在本地处理响应数据
                // 响应应用
                break;

            case 404:
                System.out.println("Amazon RVS Error: Invalid packageName");
                // 在本地处理响应数据
                // 响应应用
                break;

            case 500:
                System.out.println("Amazon RVS Error: Internal Server Error");
                // 在本地处理响应数据
                // 响应应用
                break;

            case 200:

                // 取回亚马逊RVS响应
                BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream()));

                String inputLine;
                StringBuffer response = new StringBuffer();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                // 记录Amazon RVS响应
                System.out.println("Amazon RVS Response: " + response.toString()());

                // 为RVS响应创建JSONObject
                JSONObject responseJson = new JSONObject(response.toString());

                // 解析RVS响应
                responseJson = new JSONObject(response.toString());
                break;

            default:
                System.out.println("Amazon RVS Error: Undefined Response Code From Amazon RVS");
                // 在本地处理响应数据
                // 响应应用
                break;
        }

    } catch (MalformedURLException e) {

        // 作为最佳实践,将以下逻辑替换为日志记录逻辑。
        System.out.println("Amazon RVS MalformedURLException");
        e.printStackTrace();
        // 在本地处理响应数据
        // 响应应用
    } catch (IOException e) {

        // 作为最佳实践,将以下逻辑替换为日志记录逻辑。
        System.out.println("Amazon RVS IOException");
        e.printStackTrace();
        // 在本地处理响应数据
        // 响应应用
    }

    return responseJson;
}

Last updated: 2024年5月22日