34 votes

Comment vérifier les transactions de facturation in-app Android sur MY server?

J'ai fait une application pour Android, où les articles peuvent être achetés à l'aide dans l'application de la facturation. Quand un article est acheté à la transaction peuvent être facilement synchronisées entre l'Android Market et le téléphone à être utilisé dans l'application. Mais, j'ai besoin de MON serveur pour être au courant de l'achat. La décision de livrer spécifiques à l'application les données doivent être faites sur mon serveur, pas dans l'application cliente.

E. g.

  1. L'utilisateur achète de l'élément X à partir de l'Android Market.
  2. Les données de la Transaction Y est envoyé au client.
  3. Client envoie Y sur mon serveur.
  4. Le Client demande au serveur de fournir du contenu pour l'X.
  5. Le serveur fournit du contenu si Y est valide. Comment cela peut-il être réalisé?

Q: Comment puis-je vérifier que les données de la transaction à venir à partir de l'Android client (vraisemblablement provenant de serveurs de Google) n'est pas faux? I. e. un hacker n'ont pas généré les données.

Google Serveur -> client Android -> Mon serveur -> client Android

C'est peut-être plus de PHP en question qu'autre chose. Exactement ce que mon script serveur (PHP) afin de vérifier que les données récupérées est réel?

20voto

abdollar Points 1546

Utilisation openssl_verify ($data, $signature, $key)

Les variables $données $et la signature doit être envoyé par le client android pour votre serveur php en utilisant le protocole https. La transaction contient à la fois de ces éléments. Envoyer à vos serveurs avant que vous reconnaissez la transaction sur le client.(voir la documentation ici http://developer.android.com/guide/market/billing/billing_integrate.html)

La variable $key est votre google à clé publique disponible à partir de votre compte d'éditeur à partir de la délivrance de permis et Dans l'application de Facturation panneau. Copier la clé publique et l'utiliser dans votre code php, de préférence à l'aide d'un fichier de configuration, vous installer sur vos serveurs plutôt que dans votre code php.

Si le openssl_verify appel réussit, vous devez stocker les numéros de commande sur vos serveurs et de s'assurer qu'ils sont uniques, de sorte qu'ils ne peuvent pas être relus. Sachez que d'un seul de réception des données et la signature paire pourrait contenir de nombreux numéros de commande si il est habituellement un ordre.

11voto

Thunder Rabbit Points 2285

Nous avons utilisé AndroidBillingLibrary.

Installer un projet dans Eclipse et de laisser votre projet d'importation comme une bibliothèque.

Nous avons mis en place BillingController.IConfiguration, quelque chose comme

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";
    }
}

Ensuite, pour notre application, nous avons étendu Application:

public class LocalizedApplication extends Application {

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

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

AndroidManifest comprend ce (et tous les autres trucs)

<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>

Nous avons mis en oeuvre 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;
    }

}

C'est le dernier quelques lignes ci-dessus que l'appel de votre classe sur le fait de parler à votre serveur.

Notre PhoneServerLink commence quelque chose comme ceci:

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 
    }

}

4voto

Nikolay Elenkov Points 32843

Les données de la Transaction est signé avec une clé privée spécifique à votre application. Il y a aussi un nonce pour prévenir les replays (j'.e, en envoyant le même, valide, les données plusieurs fois). Si vous vérifiez que le nonce est unique et que la signature est valide à votre serveur, vous pouvez être raisonnablement sûr que c'est pas du fake. Vérifiez la partie à propos de l'IAB et de ce Google IO présentation pour une discussion.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X