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

内容一览

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

官方接入文档

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

开始集成

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

//(必需)添加API版本:它需要显式声明IAPV 5
<meta-dataandroid:name="iap:api_version"android:value="5" />
//(可选)指定支付屏幕UI:API版本5支持弹出格式中的支付屏幕UI。如果在下面的iap:view_选项中输入弹出值,则支付窗口将弹出。如果没有设置值,默认情况下它将被视为全屏(Android:value=“Full”)。
<meta-dataandroid: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() {@Overridepublic void onConnected() {Log.d(TAG, "Service connected");checkBillingSupportedAndLoadPurchases();}@Overridepublic void onDisconnected() {Log.d(TAG, "Service disconnected");}@Overridepublic void onErrorNeedUpdateException() {Log.e(TAG, "connect onError, 需要更新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() {@Overridepublic void run() {// 先执行 查询是否支持应用内支付mPurchaseClient.isBillingSupportedAsync(IAP_API_VERSION, mBillingSupportedListener);}});}/** PurchaseClient的isBillingSupportedAsync (查询是否支持)回调监听器*/PurchaseClient.BillingSupportedListener mBillingSupportedListener = new PurchaseClient.BillingSupportedListener() {@Overridepublic void onSuccess() {Log.d(TAG, "isBillingSupportedAsync onSuccess");isBillingSupported = true;//检查掉单的情况// queryPurchase(IapEnum.ProductType.IN_APP);}@Overridepublic void onError(IapResult result) {Log.e(TAG, "isBillingSupportedAsync onError, " + result.toString());if (IapResult.RESULT_NEED_LOGIN == result) {loadLoginFlow();}}@Overridepublic void onErrorRemoteException() {Log.e(TAG, "isBillingSupportedAsync onError, 无法连接ONE store服务");}@Overridepublic void onErrorSecurityException() {Log.e(TAG, "isBillingSupportedAsync onError, 应用状态异常下请求支付");}@Overridepublic void onErrorNeedUpdateException() {Log.e(TAG, "isBillingSupportedAsync onError, 需要更新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() {@Overridepublic 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;// }}@Overridepublic void onError(IapResult result) {if(result == IapResult.RESULT_NEED_LOGIN ) {//需要登陆onestoreloadLoginFlow();}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{}}@Overridepublic void onErrorRemoteException() {Log.e(TAG, "queryPurchasesAsync onError, 无法连接ONE store服务");}@Overridepublic void onErrorSecurityException() {Log.e(TAG, "queryPurchasesAsync onError, 应用状态异常下请求支付");}@Overridepublic void onErrorNeedUpdateException() {Log.e(TAG, "queryPurchasesAsync onError, 需要更新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() {@Overridepublic void onSuccess(PurchaseData purchaseData) {Log.d(TAG, "consumeAsync onSuccess, " + purchaseData.toString());// 商品消耗成功后,按各开发者编写的购买成功方案进行。}@Overridepublic void onErrorRemoteException() {Log.e(TAG, "consumeAsync onError, 无法连接ONE store服务");}@Overridepublic void onErrorSecurityException() {Log.e(TAG, "consumeAsync onError, 应用状态异常下请求支付");}@Overridepublic void onErrorNeedUpdateException() {Log.e(TAG, "consumeAsync onError, 需要更新ONE store客户端 ");updateOrInstallOneStoreService();}@Overridepublic void onError(IapResult result) {Log.e(TAG, "consumeAsync onError, " + result.toString());}};

其他代码里用到的方法

 //未登陆onestore调用private void loadLoginFlow() {if (mPurchaseClient == null) {Log.d(TAG, "PurchaseClient is not initialized");return;}mActivity.runOnUiThread(new Runnable() {@Overridepublic 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() {@Overridepublic void run() {mPurchaseClient.queryPurchasesAsync(IAP_API_VERSION, PRODUCT_TYPE,         mQueryPurchaseListener);}});}/** PurchaseClient的queryPurchasesAsync API (查询购买记录)回调监听器*/PurchaseClient.QueryPurchaseListener mQueryPurchaseListener = new PurchaseClient.QueryPurchaseListener() {@Overridepublic void onSuccess(List<PurchaseData> purchaseDataList, String productType) {Log.d(TAG, "queryPurchasesAsync onSuccess, " + purchaseDataList.toString());if (IapEnum.ProductType.IN_APP.getType().equalsIgnoreCase(productType)) {onLoadPurchaseInApp(purchaseDataList);} else if (IapEnum.ProductType.AUTO.getType().equalsIgnoreCase(productType)) {// 如为查询购买记录后获取的包月自动支付商品( auto),先验证签名,成功后根据开发者应用处理需求编写方案。}}@Overridepublic void onErrorRemoteException() {Log.e(TAG, "queryPurchasesAsync onError, 无法连接ONE store服务");}@Overridepublic void onErrorSecurityException() {Log.e(TAG, "queryPurchasesAsync onError, 应用状态异常下请求支付");}@Overridepublic void onErrorNeedUpdateException() {Log.e(TAG, "queryPurchasesAsync onError, 需要更新ONE store客户端 ");updateOrInstallOneStoreService();}@Overridepublic void onError(IapResult result) {Log.e(TAG, "queryPurchasesAsync onError, " + result.toString());}};//掉单消耗private void onLoadPurchaseInApp(List<PurchaseData> purchaseDataList) {for (PurchaseData purchase : purchaseDataList) {  ......verifyPurchaseToServerAndConsumeItem(purchase);}}//商店更新private void updateOrInstallOneStoreService() {PurchaseClient.launchUpdateOrInstallFlow(mActivity);}

onActivityResult

@Overridepublic 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 nullreportErrorToServer(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传递是否可行)
我们项目内商品的分类比较特殊,如果玩家连续多次点击多个不同的商品,会导致错单的情况(订单号跟商品无法匹配),这就需要特殊处理,各位大佬一般用不着,本文不再赘述。


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

韩国ONE store平台支付集成(android)相关推荐

  1. 韩国渠道接入三星支付(Android 接入 Samsung in app purchase)

    Android 接入 Samsung In-App Purchase 在三星后台注册应用 获取Samsung IAP-Helper SDK 三星支付SDK集成 总结: 在三星后台注册应用 注册开发者账 ...

  2. Android开发支付集成——微信集成

    支付宝支付传送门:https://www.cnblogs.com/dingxiansen/p/9208949.html 二.微信支付 1. 微信支付流程图 相比较而言,微信支付是要比支付宝麻烦一些,并 ...

  3. Android PayPal 支付集成

    Android PayPal 支付集成 PayPal本身自己有移动端的SDK,但是已经不推荐使用了,我也自己集成了一下,还有一些问题存在,在这里就不做介绍了,官方推荐使用BraintreeSDK来集成 ...

  4. android支付宝开放平台开发,支付宝开放平台支付更新升级全解析

    由于支付宝增加开放平台的概念,支付申请和调用有了较大的更新和升级,本篇文章会带你介绍开放平台的支付申请方式和新支付接口和之前的区别. 0 系列文章 1 背景介绍 支付宝现在开始着重推开发平台这个概念, ...

  5. android sdk所有版本下载,android sdk全平台版本集成

    这是android sdk 全平台版本集成下载,谷歌经常被墙,有的同学也不知道如何下载平台环境,所以特意把全平台工具环境打包上来,方便大家下载. 软件介绍 android sdk全平台版本集成是一个管 ...

  6. Android平台上集成海康SDK(二)

    Android平台上集成海康SDK 以上是我之前写的一篇Android平台上集成海康SDK的文章,其中对于Android平台上集成海康SDK.基于海康SDK进行二次开发基本上进行了详细地介绍. 这篇文 ...

  7. Android paypal支付 集成 Manifest merger failed with multiple errors, see logs

    paypal 第一次接触,听说很强大,在这里我门先不深究它的来历,上代码 首先你要下在个SDK,呵呵..... 1官网链接:https://developer.paypal.com/docs/clas ...

  8. Android平台上集成大华SDK(二)

    Android平台上集成大华SDK 以上是我之前写的一篇Android平台上集成大华SDK的文章,其中对于Android平台上集成大华SDK.基于大华SDK进行二次开发基本上进行了详细地介绍. 这篇文 ...

  9. iOS微信支付集成 SDK1 7 5

    最近做了一个新项目,涉及到支付宝和微信支付,支付宝和微信都是业界的老大哥,相信大家都有所觉得文档.SDK都是各种坑吧(纯粹吐槽而已),这是继上篇支付宝支付集成后接着的微信支付集成. 1.微信商户申请步 ...

最新文章

  1. c++小项目:通讯录管理系统
  2. 黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (高级)
  3. Visual Studio 批量注释 快捷键
  4. 深入理解javascript原型和闭包(5)——instanceof
  5. C++中的IPv6网络程序设计
  6. python old six day
  7. c++ 类的sizeof
  8. AI基础:机器学习和深度学习的练习数据
  9. 基于 MongoDB 动态字段设计的探索 (二) 聚合操作
  10. 代码编译方式 ant +ivy
  11. 小米虚高的估值泡沫要破了么?
  12. acr122 java,ACR122U使用教程
  13. 时间序列数据处理2——时间序列聚类算法
  14. 《智慧城市》顶层设计解读
  15. cmt obm odm 代工模式oem_ODM/OEM/OBM的区别
  16. NOD32升级账号更新器 [ C# | NOD32 | Eset ]
  17. 树莓派启动自动连接WiFi
  18. 微信自定义菜单的emoji图标
  19. 是德科技34461a万用表
  20. 高级自动化测试面试题(Web、App、接口)

热门文章

  1. 【流畅的 C】流畅使用 C 语言
  2. 「喜迎华诞」手把手教你用微信小程序给头像带上小旗帜
  3. 回:《孩子感冒了该吃什么药?说给程序员朋友的话》——勿以生命赌中医!...
  4. unity3D FSM有限状态机(状态设计模式)
  5. Python如何除去NaN
  6. mysql除去一段字符串_mysql如何除去一段字符串
  7. 苹果 mov avi 转 mp4 等格式
  8. 软件测试岗一位小伙伴的~同花顺一面(面经)
  9. 100%解决 微信备份聊天数据提示当前网络状况复杂,请尝试使用其他网络或提示手机和电脑不在同一网络的方法。
  10. iOS开发:App横竖屏设置问题