海外SDK接入1 onestore

本文档详细介绍了如何接入OneStore SDK,包括准备工作、配置商品列表、客户端与服务器的设置、购买流程及代码实现。主要内容涉及AndroidManifest配置、jar包导入、客户端初始化、支付发起、服务器验证和订阅状态管理等步骤。
摘要由CSDN通过智能技术生成

OneStore

准备工作!

1,官方文档:https://dev.onestore.co.kr/devpoc/reference/view/Tools
2,https://github.com/ONE-store/inapp-sdk-chi/wiki/Tools-Developer-Guide
3 demo:https://github.com/ONE-store/iap_v5/tree/onestore_iap_sample
4 需要有ONE store服务的设备以及 翻墙

配置商品列表

onestore 提供了两种商品类型:管理型和包月自动支付商品,
管理型商品流程:购买->消耗->再次购买
包月自动支付:购买(订阅)->退订
可通过自定义消耗管理型商品来构建消耗型或者永久型商品

购买流程

1 客户端请求服务器获取商品信息以及自定义订单号
2 客户端发起SDK支付
3 支付完成,客户端将支付结果发送服务器做验证
4 服务器验证成功,针对管理型商品服务器调用消耗接口,消耗商品	

客户端配置

cocos2dx引擎
ndk-r11c

build.gradle <project级别>

        classpath 'com.android.tools.build:gradle:3.2.0'

gradle/wrapper/gradle-wrapper.properties

distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

buld.gradle <app级别>

    compileSdkVersion 28
    defaultConfig {
        applicationId APPLICATION_ID
        minSdkVersion 16
        targetSdkVersion 28
		
		externalNativeBuild{...}
	}

后台配置

由管理人员完成
需要提供参数:
License Key: (公钥) (客户端/服务器)
Client_ID:(服务器)
Client_secret:(服务器)
android jar:jar file(eg. iap_plugin_v17.01.00_20180206.jar)

客户端接入

官方提供SDK方式和直接实现服务器接口两种方式,这里采用SDK,
客户端实现支付,登陆检测,以及检测漏单
服务器实现支付结果验证,消耗,以及订阅/退订

1 设置 Android Manifest文档

<application ...... >
        <!-- One Store SDK begin -->
        <meta-data android:name="iap:api_version"
                   android:value="5" />
        <!-- (可选) 选择支付界面(UI):API V5支持弹窗式的支付界面。在iap:view_option里加入popup时,会显示弹窗式的支付画面。 -->
        <!-- <meta-data
            android:name="iap:view_option"
            android:value="popup | full" > -->

        <!-- One Store SDK end -->          

2 导入jar包,直接放到app/libs下即可,没有此目录的话,自己建一个
3 初始化
在应用的Oncreate方法中调用执行初始化

@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
    // PurchaseClient 初始化——将公钥作为参数传递,以验证context和Signature。
    mPurchaseClient = new PurchaseClient(this, AppSecurity.getPublicKey());
 
    // 请求绑定ONE store服务,以启动应用内支付。
    mPurchaseClient.connect(mServiceConnectionListener);
}

3.2 退出时需要调用登出

@Override
protected void onDestroy() {
    super.onDestroy();
 
    if (mPurchaseClient == null) {
        Log.d(TAG, "PurchaseClient is not initialized");
        return;
    }
 
    // 关闭应用时,使用PurchaseClient中断服务。
    mPurchaseClient.terminate();
}

3.3 客户端检测是否可以支付

// ONE store应用内支付API版本
int IAP_API_VERSION = 5;
mPurchaseClient.isBillingSupportedAsync(IAP_API_VERSION, mBillingSupportedListener);

3.4 发起支付

int IAP_API_VERSION = 5;
int PURCHASE_REQUEST_CODE = 1000; // 返回至onActivityResult的request code
String product5000 = "p5000"; // 请求购买的商品ID
String productName = ""; // ""时显示开发者中心注册的商品名称
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
String devPayload = AppSecurity.generatePayload();
String gameUserId = ""; // 默认 ""
boolean promotionApplicable = false;
 
mPurchaseClient.launchPurchaseFlowAsync(IAP_API_VERSION, this, PURCHASE_REQUEST_CODE, product5000, productName, productType, devPayload, gameUserId, promotionApplicable, mPurchaseFlowListener);

3.5 查询购买记录(检测是否有未消耗商品)

 
int IAP_API_VERSION = 5;
String productType = IapEnum.ProductType.IN_APP.getType(); // "inapp"
mPurchaseClient.queryPurchasesAsync(IAP_API_VERSION, productType, mQueryPurchaseListener);

3.6 ONE store登录的请求

int IAP_API_VERSION = 5;
int LOGIN_REQUEST_CODE = 2000; // 向onActivityResult 返回的 request code
 mPurchaseClient.launchLoginFlowAsync(IAP_API_VERSION, this, LOGIN_REQUEST_CODE, mLoginFlowListener)

3.6.2 登陆结果

        switch (reqcode ){
            case SDKHelper.REQ_CODE_GOOGLE_LOGIN:
                if (resultCode == mActivity.RESULT_OK) {
                    if (mPurchaseClient.handleLoginData(intent) == false) {
                        Log.e(TAG, "onActivityResult handleLoginData false ");
                    }
                } else {
                    Log.e(TAG, "onActivityResult user canceled");
                }
                break;
            default:
        }

服务器处理

1 服务器验证,one store采用sha512公钥验证
2 服务器消耗
URI: https://{host}/v2/purchase/consume/{purchaseId}/{packageName}
3 变更订阅状态
URI: https://{host}/v2/purchase/manage-payment-status/{purchaseId}/{packageName}/{action}

客户端代码

APPactivity,java

package org.cocos2dx.lua;

import android.content.Intent;
import android.os.Bundle;
import org.cocos2dx.lib.Cocos2dxActivity;
public class AppActivity extends Cocos2dxActivity{
   
    private SDKHelper mSDKHelper = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.setEnableVirtualButton(false);
        super.onCreate(savedInstanceState);
        // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
        if (!isTaskRoot()) {
   
            // Android launched another instance of the root activity into an existing task
            //  so just quietly finish and go away, dropping the user back into the activity
            //  at the top of the stack (ie: the last state of this task)
            // Don't need to finish it again since it's finished in super.onCreate .
            return;
        }
        // DO OTHER INITIALIZATION BELOW
        // 初始化渠道SDK
        this.initSDKHelper();
    }

    @Override
    protected void onStart() {
   
        super.onStart();
        if (mSDKHelper != null){
   
            mSDKHelper.onStart();
        }
    }

    @Override
    protected void onDestroy() {
   
        super.onDestroy();

        if (mSDKHelper != null ){
   
            mSDKHelper.onDestroy();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   
        super.onActivityResult(requestCode, resultCode, data);
        if (mSDKHelper != null ){
   
            mSDKHelper.onActivityResult(requestCode,resultCode,data);
        }
    }

    private void initSDKHelper(){
   
        mSDKHelper = new SDKHelper();
        mSDKHelper.initSDK(this);
    }
}

2 SDKHelper.java

public class SDKHelper {
   
    private static String TAG = SDKHelper.class.getSimpleName();

    private static Cocos2dxActivity mActivity = null;
    private static OneStoreHelper mOneStoreHelper = null;

    public static final int REQ_CODE_ONE_STORE_LOGIN  = 1000;
    public static final int REQ_CODE_ONE_STORE_PURCHAS= 1001;

    public void initSDK(Cocos2dxActivity context)
    {
   
        mActivity = context;
        // one store pay
        mOneStoreHelper = new OneStoreHelper();
        mOneStoreHelper.initSDK(context);
    }
   
    public void onDestroy(){
   
        mOneStoreHelper.onDestroy();
    }

    public void onActivityResult(int reqcode, int resultCode, Intent intent){
   
        mOneStoreHelper.onActivityResult(reqcode,resultCode,intent);
    }



    public static void runOnGL(final int luaFunc, final String retData){
   
        if (luaFunc == -1 || luaFunc == 0) return;

        mActivity.runOnGLThread(new Runnable() {
   
            @Override
            public void run() {
   
                Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaFunc,retData);
                Cocos2dxLuaJavaBridge.releaseLuaFunction(luaFunc);
            }
        });
    }
    //  ------------------------------------------------------------
    //              lua 调用 android
    //  ------------------------------------------------------------
    public static int test(final int luaFunc){
   
        mActivity.runOnUiThread(new Runnable() {
   
            @Override
            public void run() {
   
                Log.i(TAG, "test----->");
            }
        });
        return 1;
    }

    // 返回SDK是否成功
    public static boolean checkSDKInit(){
   
        Log.d(TAG,"checkinit===");
//        return false;
        return mOneStoreHelper.mInitResult && mOneStoreHelper.mBillingSupported;
    }

    public static void onLoginPayment(final String args ,final int luaFunc){
   
        Log.d(TAG,"onLoginPayment");
        JSONObject jsonObject = new JSONObject();

        if (checkSDKInit() == true) {
   
            try{
   
                jsonObject.put("code",1);
                jsonObject.put("error_msg","sdk unInit");
            } catch (JSONException e) {
   
                e.printStackTrace();
            }
            runOnGL(luaFunc,jsonObject.toString());
            Log.d(TAG,"onLoginPayment  1111");

            return;
        };
        boolean ret = false;
        if (mOneStoreHelper.mInitResult == false){
   
            Log.d(TAG,"onLoginPayment 2222");

            mOneStoreHelper.initWithCallback(luaFunc);
        }else if(mOneStoreHelper.mBillingSupported == false){
   
            Log.d(TAG,"onLoginPayment 333");

            mOneStoreHelper.checkBillingSupportedAndLoadPurchases(luaFunc);
        }else {
   
            try{
   
                jsonObject.put("code",0);
            } catch (JSONException e) {
   
                e.printStackTrace();
            }
            Log.d(TAG,"onLoginPayment 4444");

            runOnGL(luaFunc,jsonObject.toString());
        }

    }

    public static void onPayment(final String args,final int luaFunc){
   
        mOneStoreHelper.onPayment(args,luaFunc);
    }

    public static void queryPurchases(final String args,final 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值