如何在MY服务器上validationAndroid应用内结算交易?

我制作了一个Android应用程序,可以使用应用内结算function购买商品。 购买商品后,交易可以在Android电子市场和手机之间轻松同步 – 可以在应用程序中使用。 但是,我需要我的服务器来了解购买。 交付特定于应用程序的数据的决定应在我的服务器上进行,而不是在客户端应用程序中进行。

例如

  1. 用户从Android电子市场购买项目X.
  2. 交易数据Y被发送到客户端。
  3. 客户端将Y发送到我的服务器。
  4. 客户端请求服务器为X提供内容。
  5. 如果Y有效,服务器将传送内容。 这怎么能做到呢?

问:如何validation来自Android客户端(可能源自Google服务器)的交易数据不是假的? 即黑客没有生成数据。

Google服务器 – > Android客户端 – >我的服务器 – > Android客户端

也许这是一个比其他任何问题更多的PHP问题。 我的服务器脚本(PHP)为了validation检索的数据是真实的,究竟应该做什么?

使用openssl_verify($ data,$ signature,$ key)

variables$ data和$签名应该从Android客户端发送到您的PHP服务器使用HTTPS。 交易包含这两个项目。 在确认客户端的事务之前,将其发送到您的服务器(请参阅此处的文档 – http://developer.android.com/guide/market/billing/billing_integrate.html

variables$ key是您的发布者帐户在许可和应用内结算面板中可用的Google公钥。 复制公钥并在你的php代码中使用,最好使用你在你的服务器上安装的configuration文件,而不是在你实际的php代码中。

如果openssl_verify调用成功,您应该将订单号存储在您的服务器上,并确保它们是唯一的,以便它们不能被重播。 请注意,单个数据收据和签名对可能包含许多订单号码(通常是一个订单)。

我们使用了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 } } 

交易数据使用特定于您的应用的私钥进行签名。 还有一个随机数来防止重放(即多次发送相同的有效数据)。 如果您确认nonce是唯一的,并且签名在您的服务器上有效,则可以合理确定它不是假的。 查看关于此Google IO演示文稿的 IAB部分的讨论。