如何在MY服务器上validationAndroid应用内结算交易?
我制作了一个Android应用程序,可以使用应用内结算function购买商品。 购买商品后,交易可以在Android电子市场和手机之间轻松同步 – 可以在应用程序中使用。 但是,我需要我的服务器来了解购买。 交付特定于应用程序的数据的决定应在我的服务器上进行,而不是在客户端应用程序中进行。
例如
- 用户从Android电子市场购买项目X.
- 交易数据Y被发送到客户端。
- 客户端将Y发送到我的服务器。
- 客户端请求服务器为X提供内容。
- 如果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部分的讨论。