Как проверить транзакции Android-биллинга в приложении на МОЕМ сервере? - PullRequest
34 голосов
/ 05 декабря 2011

Я создал приложение для Android, в котором предметы можно купить, используя in-app-billing . Когда предмет приобретен, транзакция может быть легко синхронизирована между Android Market и телефоном - для использования в приложении. Но мне нужен МОЙ сервер, чтобы быть в курсе покупки. Решение о доставке данных для конкретного приложения должно приниматься на моем сервере, а не в клиентском приложении.

* 1005 Е.Г. *

  1. Пользователь покупает товар X у Android Market.
  2. Данные транзакции Y отправляются клиенту.
  3. Клиент отправляет Y на мой сервер.
  4. Клиент просит сервер доставить контент для X.
  5. Сервер доставляет контент , если Y является действительным . Как это можно сделать?

В: Как проверить, что данные транзакций, поступающие с клиента Android (предположительно, с серверов Google), не являются поддельными? То есть хакер не сгенерировал данные.

Сервер Google -> Клиент Android -> Мой сервер -> Клиент Android

Возможно, это больше вопрос PHP, чем что-либо еще. Что именно должен делать мой серверный скрипт (PHP), чтобы убедиться, что полученные данные реальны?

Ответы [ 3 ]

20 голосов
/ 17 декабря 2011

Использовать openssl_verify ($ data, $ signature, $ key)

Переменные $ data и $ signature должны быть отправлены с Android-клиента на ваш php-сервер с использованием https.Транзакция содержит оба этих элемента.Отправьте это на свои серверы, прежде чем подтвердить транзакцию на клиенте (см. Документацию здесь - http://developer.android.com/guide/market/billing/billing_integrate.html)

Переменная $ key - это ваш открытый ключ Google, доступный из вашей учетной записи издателя в разделе «Лицензирование и биллинг в приложении»Панель. Скопируйте открытый ключ и используйте его в своем php-коде, предпочтительно используя файл конфигурации, который вы устанавливаете на своих серверах, а не в своем фактическом php-коде.

Если вызов openssl_verify завершится успешно, вы должны сохранить номера заказов наваши серверы и убедитесь, что они уникальны, поэтому их нельзя воспроизвести. Имейте в виду, что одна пара получения данных и подписи может содержать много номеров заказов, хотя обычно это один заказ.

11 голосов
/ 05 декабря 2011

Мы использовали AndroidBillingLibrary .

Установите это как проект в Eclipse и позвольте вашему проекту импортировать его как библиотеку.

Мы реализовали BillingController.IConfiguration, что-то вроде

import net.robotmedia.billing.BillingController;

public class PhoneBillingConfiguration implements BillingController.IConfiguration{
    @Override
    public byte[] getObfuscationSalt() {
        return new byte[] {1,-2,3,4,-5,6,-7,theseshouldallberandombyteshere,8,-9,0};
    }

    @Override
    public String getPublicKey() {
        return "superlongstringhereIforgothowwemadethis";
    }
}

Затем для нашего приложения мы расширили Application:

public class LocalizedApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

//      BillingController.setDebug(true);
        BillingController.setConfiguration(new PhoneBillingConfiguration());
    }
}

AndroidManifest включает это (и все остальное)

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:name=".LocalizedApplication"   <!-- use your specific Application  -->
    android:largeHeap="true"
    android:hardwareAccelerated="true"
    >

    <!-- For billing -->
    <service android:name="net.robotmedia.billing.BillingService" />
        <receiver android:name="net.robotmedia.billing.BillingReceiver">
        <intent-filter>
            <action android:name="com.android.vending.billing.IN_APP_NOTIFY" />
            <action android:name="com.android.vending.billing.RESPONSE_CODE" />
            <action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED" />
        </intent-filter>
    </receiver>

Мы реализовали ISignatureValidator

public class PhoneSignatureValidator implements ISignatureValidator {
    private final String TAG = this.getClass().getSimpleName();
    private PhoneServerLink mServerLink;


    private BillingController.IConfiguration configuration;

    public PhoneSignatureValidator(Context context, BillingController.IConfiguration configuration, String our_product_sku) {
        this.configuration = configuration;
        mServerLink = new PhoneServerLink(context);
        mServerLink.setSku(our_product_sku);
    }


    @Override
    public boolean validate(String signedData, String signature) {
        final String publicKey;
        if (configuration == null || TextUtils.isEmpty(publicKey = configuration.getPublicKey())) {
            Log.w(BillingController.LOG_TAG, "Please set the public key or turn on debug mode");
            return false;
        }
        if (signedData == null) {
            Log.e(BillingController.LOG_TAG, "Data is null");
            return false;
        }
        // mServerLink will talk to your server
        boolean bool = mServerLink.validateSignature(signedData, signature);
        return bool;
    }

}

Последние несколько строк выше указывают вашему классу, что на самом деле будет говорить с вашим сервером.

Наш PhoneServerLink начинает примерно так:

public class PhoneServerLink implements GetJSONListener {

    public PhoneServerLink(Context context) {
        mContext = context;
    }

    public boolean validateSignature(String signedData, String signature) {
        return getPurchaseResultFromServer(signedData, signature, false);
    }

    private boolean getPurchaseResultFromServer(String signedData, String signature,  boolean async) {  
            // send request to server using whatever protocols you like 
    }

}
4 голосов
/ 05 декабря 2011

Данные транзакции подписываются закрытым ключом, специфичным для вашего приложения. Существует также одноразовый номер для предотвращения повторов (то есть, отправка одних и тех же действительных данных несколько раз). Если вы убедитесь, что одноразовый номер уникален, а подпись действительна на вашем сервере, вы можете быть уверены, что это не фальшивка. Проверьте часть о IAB этой презентации Google IO для обсуждения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...