韩国ONE store平台支付集成(android)

韩国ONE store平台支付集成(android),第1张

概述前端时间接入韩国Onestore平台的时候踩了一些坑,国内的文档又很少,记录一下,废话不多说。我们开始吧。内容一览官方接入文档开始集成支付逻辑集成一、集成步骤二、集成代码三、集成问题官方接入文档官方文档有中英韩三种语言,可移步官方接入文档开始集成1】目前的新版本是V

前端时间接入韩国Onestore平台的时候踩了一些坑,国内的文档又很少,记录一下,废话不多说。我们开始吧。

内容一览官方接入文档开始集成支付逻辑集成一、集成步骤二、集成代码三、集成问题

官方接入文档

官方文档有中英韩三种语言,可移步官方接入文档

开始集成

1】目前的新版本是V5,直接放V5的jar包。从gizub下载OneStore在应用程序中购买SDK
2】清单文件添加

//(必需)添加API版本:它需要显式声明IAPV 5<Meta-data     androID:name="iap:API_version"     androID:value="5" />//(可选)指定支付屏幕UI:API版本5支持d出格式中的支付屏幕UI。如果在下面的iap:vIEw_选项中输入d出值,则支付窗口将d出。如果没有设置值,默认情况下它将被视为全屏(AndroID:value=“Full”)。<Meta-data    androID:name="iap:vIEw_option"    androID:value="popup | full" >
支付逻辑集成一、集成步骤

1】初始化API并绑定One Store服务
2】绑定成功,检查是否支持onestore支付,如果支持,继续
3】检查未完成的订单(掉单的情况处理),如果有执行验单,消单逻辑(如果是游戏,也可放到进入游戏后进行)
4】验单:玩家请求支付,支付成功后将有效数据发给服务器进行验证(本地也可进行验证,详见代码)
5】消单:服务器验证成功,告知客户端,客户端进行消单,服务器发送奖励

二、集成代码

初始化,绑定

	//需要引入的头文件	import com.onestore.iap.API.IapEnum;	import com.onestore.iap.API.IapResult;	import com.onestore.iap.API.ProductDetail;	import com.onestore.iap.API.PurchaseClIEnt;	import com.onestore.iap.API.PurchaseData;    // onestore 渠道参数配置    private static final int IAP_API_VERSION = 5;    private static final int COIN_PER_GAME = 5;    private static final int PURCHASE_REQUEST_CODE = 1000;    private static final int LOGIN_REQUEST_CODE = 2000;    private static final String PRODUCT_TYPE = IapEnum.ProductType.IN_APP.getType(); // "inapp"    //此处在你的初始化方法中执行{        // PurchaseClIEnt 初始化——将公钥作为参数传递,以验证context和Signature。        mpurchaseClIEnt = new PurchaseClIEnt(this, mpublicKey);        // 请求绑定ONE store服务,以启动应用内支付。        mpurchaseClIEnt.connect(mServiceConnectionListener);}/*     * PurchaseClIEnt的 connect API 回调监听器     * 返回绑定成功或失败以及是否要更新ONE store服务的结果。     */    PurchaseClIEnt.ServiceConnectionListener mServiceConnectionListener = new PurchaseClIEnt.ServiceConnectionListener() {        @OverrIDe        public voID onConnected() {            Log.d(TAG, "Service connected");            checkBillingSupportedAndLoadPurchases();        }             @OverrIDe        public voID ondisconnected() {            Log.d(TAG, "Service disconnected");        }             @OverrIDe        public voID one rrorNeedUpdateException() {            Log.e(TAG, "connect one rror, 需要更新ONE store客户端 ");            updateOrInstallOnestoreService();        }    };

检查是否支持

private voID checkBillingSupportedAndLoadPurchases() {        Log.d(TAG, "checkBillingSupportedAndLoadPurchases()");        if (mpurchaseClIEnt == null) {            Log.d(TAG, "PurchaseClIEnt is not initialized");            return;        }        // 方法名字中以postfix加上“Async”,UI线程中为保证安全执行,创建线程处理        this.runOnUiThread(new Runnable() {            @OverrIDe            public voID run() {                // 先执行 查询是否支持应用内支付                mpurchaseClIEnt.isBillingSupportedAsync(IAP_API_VERSION, mBillingSupportedListener);            }        });    }    /*     * PurchaseClIEnt的isBillingSupportedAsync (查询是否支持)回调监听器     */    PurchaseClIEnt.BillingSupportedListener mBillingSupportedListener = new PurchaseClIEnt.BillingSupportedListener() {             @OverrIDe        public voID onSuccess() {            Log.d(TAG, "isBillingSupportedAsync onSuccess");            isBillingSupported = true;            //检查掉单的情况            // queryPurchase(IapEnum.ProductType.IN_APP);        }             @OverrIDe        public voID one rror(IapResult result) {            Log.e(TAG, "isBillingSupportedAsync one rror, " + result.toString());            if (IapResult.RESulT_NEED_LOGIN == result) {                loadLoginFlow();            }        }             @OverrIDe        public voID one rrorremoteexception() {            Log.e(TAG, "isBillingSupportedAsync one rror, 无法连接ONE store服务");        }             @OverrIDe        public voID one rrorSecurityException() {            Log.e(TAG, "isBillingSupportedAsync one rror, 应用状态异常下请求支付");        }             @OverrIDe        public voID one rrorNeedUpdateException() {            Log.e(TAG, "isBillingSupportedAsync one rror, 需要更新ONE store客户端");            updateOrInstallOnestoreService();        }    };

发起支付

String devPayload = AppSecurity.generatePayload();//参数大多数在开头部分说明了,单独说明第9个参数false:是否支持onestore 促销活动mpurchaseClIEnt.launchPurchaseFlowAsync(IAP_API_VERSION, this, PURCHASE_REQUEST_CODE, goods_ID, goods_name,                                            PRODUCT_TYPE, devPayload_, role_ID, false, mpurchaseFlowListener);                                            	/*    * PurchaseClIEnt的 launchPurchaseFlowAsync API (购买)回调监听器     */    PurchaseClIEnt.PurchaseFlowListener mpurchaseFlowListener = new PurchaseClIEnt.PurchaseFlowListener() {        @OverrIDe        public voID onSuccess(PurchaseData purchaseData) {            String logStr = "pay success, purchaseData: " + purchaseData.toString();            reportErrorToServer(Code_PayResult, logStr);            // 购买成功后客户端检查开发者payload。            // if (!isValIDPayload(purchaseData.getDeveloperPayload())) {            //     Log.d(TAG, "launchPurchaseFlowAsync onSuccess, Payload is not valID.");            //     return;            // }                 // 购买成功后客户端检查签名。            // boolean valIDPurchase = AppSecurity.verifyPurchase(purchaseData.getPurchaseData(), purchaseData.getSignature(), mpublicKey);            // if (valIDPurchase) {                // 管理型商品(inapp)购买成功后消耗。                verifyPurchasetoServerAndConsumeItem(purchaseData);            // } else {            //     Log.d(TAG, "launchPurchaseFlowAsync onSuccess, Signature is not valID.");            //     return;            // }        }             @OverrIDe        public voID one rror(IapResult result) {            if(result == IapResult.RESulT_NEED_LOGIN ) {            	//需要登陆onestore                loadLoginFlow();            }            else if(result == IapResult.RESulT_ITEM_UNAVAILABLE){                LogD("purchase Failed , item unavailable");            }            else if(result == IapResult.RESulT_ITEM_ALREADY_OWNED){                LogD("purchase Failed , item ALREADY_OWNED");                //掉单了                queryPurchase(IapEnum.ProductType.IN_APP);            }            else{            }        }             @OverrIDe        public voID one rrorremoteexception() {            Log.e(TAG, "queryPurchasesAsync one rror, 无法连接ONE store服务");        }        @OverrIDe        public voID one rrorSecurityException() {            Log.e(TAG, "queryPurchasesAsync one rror, 应用状态异常下请求支付");        }        @OverrIDe        public voID one rrorNeedUpdateException() {            Log.e(TAG, "queryPurchasesAsync one rror, 需要更新ONE store客户端 ");            updateOrInstallOnestoreService();        }    };

服务器验单(略) + 客户端消单

private voID verifyPurchasetoServerAndConsumeItem(final PurchaseData purchaseData) {        if (mpurchaseClIEnt == null) {            Log.d(TAG, "PurchaseClIEnt is not initialized");            return;        }        ......        //服务器验单成功,执行消耗        mpurchaseClIEnt.consumeAsync(IAP_API_VERSION, purchaseData, mConsumeListener);}	/*     * PurchaseClIEnt的 consumeAsync API (商品消耗)回调监听器     */    PurchaseClIEnt.ConsumeListener mConsumeListener = new PurchaseClIEnt.ConsumeListener() {        @OverrIDe        public voID onSuccess(PurchaseData purchaseData) {            Log.d(TAG, "consumeAsync onSuccess, " + purchaseData.toString());            // 商品消耗成功后,按各开发者编写的购买成功方案进行。        }             @OverrIDe        public voID one rrorremoteexception() {            Log.e(TAG, "consumeAsync one rror, 无法连接ONE store服务");        }             @OverrIDe        public voID one rrorSecurityException() {            Log.e(TAG, "consumeAsync one rror, 应用状态异常下请求支付");        }             @OverrIDe        public voID one rrorNeedUpdateException() {            Log.e(TAG, "consumeAsync one rror, 需要更新ONE store客户端 ");            updateOrInstallOnestoreService();        }             @OverrIDe        public voID one rror(IapResult result) {            Log.e(TAG, "consumeAsync one rror, " + result.toString());        }    }; 

其他代码里用到的方法

	//未登陆onestore调用	private voID loadLoginFlow() {        if (mpurchaseClIEnt == null) {            Log.d(TAG, "PurchaseClIEnt is not initialized");            return;        }        mActivity.runOnUiThread(new Runnable() {            @OverrIDe            public voID run() {                if (mpurchaseClIEnt.launchLoginFlowAsync(IAP_API_VERSION, mActivity, LOGIN_REQUEST_CODE, mLoginFlowListener) == false) {                    // Listener is null                }            }        });    }    	//查询订单	private voID queryPurchase(final IapEnum.ProductType productType) {        Log.d(TAG, "queryPurchase() :: productType - " + productType.getType());        if (mpurchaseClIEnt == null) {            Log.d(TAG, "PurchaseClIEnt is not initialized");            return;        }        this.runOnUiThread(new Runnable() {            @OverrIDe            public voID run() {                mpurchaseClIEnt.queryPurchasesAsync(IAP_API_VERSION, PRODUCT_TYPE, 		mqueryPurchaseListener);            }        });    }    	/*     * PurchaseClIEnt的queryPurchasesAsync API (查询购买记录)回调监听器     */    PurchaseClIEnt.queryPurchaseListener mqueryPurchaseListener = new PurchaseClIEnt.queryPurchaseListener() {        @OverrIDe        public voID onSuccess(List<PurchaseData> purchaseDataList, String productType) {            Log.d(TAG, "queryPurchasesAsync onSuccess, " + purchaseDataList.toString());            if (IapEnum.ProductType.IN_APP.getType().equalsIgnoreCase(productType)) {                onl oadPurchaseInApp(purchaseDataList);            } else if (IapEnum.ProductType.auto.getType().equalsIgnoreCase(productType)) {                // 如为查询购买记录后获取的包月自动支付商品( auto),先验证签名,成功后根据开发者应用处理需求编写方案。            }        }        @OverrIDe        public voID one rrorremoteexception() {            Log.e(TAG, "queryPurchasesAsync one rror, 无法连接ONE store服务");        }             @OverrIDe        public voID one rrorSecurityException() {            Log.e(TAG, "queryPurchasesAsync one rror, 应用状态异常下请求支付");        }             @OverrIDe        public voID one rrorNeedUpdateException() {            Log.e(TAG, "queryPurchasesAsync one rror, 需要更新ONE store客户端 ");            updateOrInstallOnestoreService();        }             @OverrIDe        public voID one rror(IapResult result) {            Log.e(TAG, "queryPurchasesAsync one rror, " + result.toString());        }    };    	//掉单消耗	private voID onl oadPurchaseInApp(List<PurchaseData> purchaseDataList) {        for (PurchaseData purchase : purchaseDataList) {          	......            verifyPurchasetoServerAndConsumeItem(purchase);        }    }        //商店更新    private voID updateOrInstallOnestoreService() {        PurchaseClIEnt.launchUpdateOrInstallFlow(mActivity);    }

onActivityResult

@OverrIDe    public voID onActivityResult(int requestCode, int resultCode, Intent data) {       super.onActivityResult(requestCode, resultCode, data);        LogD("onActivityResult: " + requestCode + " resultCode: " + resultCode);        switch (requestCode) {            case LOGIN_REQUEST_CODE:                if (resultCode == Activity.RESulT_OK) {                    if (mpurchaseClIEnt.handleLoginData(data) == false) {                        Log.e(TAG, "onActivityResult handleLoginData false ");                        // Listener is null                    }                } else {                    Log.e(TAG, "onActivityResult user canceled");                }                break;            case PURCHASE_REQUEST_CODE:                /*                 * 调用 launchPurchaseFlowAsync API 时收到的intent数据通过handlePurchaseData解析返回值。                 * 解析后返回结果通过调用 launchPurchaseFlowAsync 时的 PurchaseFlowListener 返回。                 */                if (resultCode == Activity.RESulT_OK) {                    if (mpurchaseClIEnt.handlePurchaseData(data) == false) {                        Log.e(TAG, "onActivityResult handlePurchaseData false ");                        // Listener is null                        reportErrorToServer(Code_CommonLog, "Listener is null");                    }                } else {                    Log.e(TAG, "onActivityResult user canceled");                    reportErrorToServer(Code_CommonLog, "onActivityResult user canceled");                    // user canceled , do nothing..                }                break;            default:        }    }
AppSecurity,这个是案例里有的一个类,可以拿来用。

官方案例

三、集成问题

1、无法拉起支付
1.1】手机必须安装最新版本的Onestore客户端,否则无法支付,自备梯子去拿,分享目前最新版连接
提取码:w0nu
1.2】手机需要翻墙,并且能够进入onestore客户端(可在初始化回调里面查看错误码知晓)
1.3】手机必须支持onestore支付(可在查询是否支持的回调里面查看错误码知晓)
1.4】查看支付回调错误码,常见的错误类型详见代码示例
1.5】查询购买记录,并且进行消费(主要是针对管理型商品(inapp))。注意:如果不进行消费是不能进行购买请求的1

2、 掉单的问题
如果代码逻辑正常,这种情况一般发生在玩家支付过程中网络中断、强退应用等情况。出现这种情况会导致2.1】玩家支付成功,但是没有收到相应的奖励。–未完成验单
2.2】玩家支付成功,没收到奖励,并且还不能继续购买这个商品。–未消单
俗称掉单。掉单了,如果无法处理,我们就只能补单。
为了减少补单的情况发生(总会有掉单),我们需要进行一些规避的方法。在应用启动后或者在发生无法继续购买商品时,重新查询当前是否存在未消耗的商品,如果存在,继续执行验单和消单逻辑,

3、极端 *** 作的情况
3.1】新版本中无法传递透传字段(可以试下payload传递是否可行)
我们项目内商品的分类比较特殊,如果玩家连续多次点击多个不同的商品,会导致错单的情况(订单号跟商品无法匹配),这就需要特殊处理,各位大佬一般用不着,本文不再赘述。


此内容参考https://blog.csdn.net/Silencemuyi/article/details/90708000,写的也很详细,想必也是被坑的厉害。 ↩︎

总结

以上是内存溢出为你收集整理的韩国ONE store平台支付集成(android)全部内容,希望文章能够帮你解决韩国ONE store平台支付集成(android)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1063733.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存