如何在我的服务器上验证安卓应用内结算交易?

2022-08-30 13:26:58

我制作了一个Android应用程序,可以使用应用内结算购买项目。购买商品后,交易可以在Android Market和手机之间轻松同步 - 在应用程序中使用。但是,我需要我的服务器知道购买。交付特定于应用的数据的决定应在我的服务器上做出,而不是在客户端应用中做出。

例如:

  1. 用户从安卓市场购买项目X。
  2. 交易数据 Y 被发送到客户端。
  3. 客户端将 Y 发送到我的服务器。
  4. 客户端要求服务器为 X 提供内容。
  5. 如果 Y 有效,则服务器传递内容。如何做到这一点?

问:如何验证来自 Android 客户端(可能来自 Google 服务器)的交易数据是否为假数据?也就是说,黑客没有生成数据。

谷歌服务器 ->安卓客户端 -> 我的服务器 -> 安卓客户端

也许这更像是一个PHP问题,而不是其他任何东西。我的服务器脚本(PHP)究竟应该做什么来验证检索到的数据是否真实?


答案 1

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

$data变量和$signature应使用https从Android客户端发送到php服务器。事务包含这两个项目。在客户端上确认事务之前,将其发送到您的服务器。(请参阅此处的文档 - http://developer.android.com/guide/market/billing/billing_integrate.html)

变量$key是您的 Google 公钥,可从“许可和应用内结算”面板中的发布商帐户获得。复制公钥并在php代码中使用它,最好使用安装在服务器上的配置文件,而不是在实际的php代码中。

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


答案 2

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

}

推荐