OneStore
Ready to work!
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服务的设备以及 翻墙
Configuring the Product List
onestore 提供了两种商品类型:管理型和包月自动支付商品,
管理型商品流程:购买->消耗->再次购买
包月自动支付:购买(订阅)->退订
可通过自定义消耗管理型商品来构建消耗型或者永久型商品
Purchase process
1 客户端请求服务器获取商品信息以及自定义订单号
2 客户端发起SDK支付
3 支付完成,客户端将支付结果发送服务器做验证
4 服务器验证成功,针对管理型商品服务器调用消耗接口,消耗商品
Client Configuration
cocos2dx engine
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-level>
compileSdkVersion 28
defaultConfig {
applicationId APPLICATION_ID
minSdkVersion 16
targetSdkVersion 28
externalNativeBuild{...}
}
Background configuration
Completed by the manager
needs to provide parameters:
License Key: (public key) (client / server)
Client_ID :( server)
client_secret :( server)
Android JAR:. JAR File (EG iap_plugin_v17.01.00_20180206.jar)
Client Access
官方提供SDK方式和直接实现服务器接口两种方式,这里采用SDK,
客户端实现支付,登陆检测,以及检测漏单
服务器实现支付结果验证,消耗,以及订阅/退订
1 Set Android Manifest document
<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 Import jar package, directly into the next app / libs can be, do not have this directory, built himself a
3 initialization
call in the application of the method to perform initialization 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 need to call out when exiting
@Override
protected void onDestroy() {
super.onDestroy();
if (mPurchaseClient == null) {
Log.d(TAG, "PurchaseClient is not initialized");
return;
}
// 关闭应用时,使用PurchaseClient中断服务。
mPurchaseClient.terminate();
}```
3.3 客户端检测是否可以支付
// ONE payment within the store application API version
int IAP_API_VERSION = 5;
mPurchaseClient.isBillingSupportedAsync (IAP_API_VERSION, mBillingSupportedListener);
3.4 发起支付
IAP_API_VERSION = 5 int;
int PURCHASE_REQUEST_CODE = 1000; // return to onActivityResult code of Request
String product5000 = "P5000"; // requests to purchase merchandise ID
String productName = ""; // "" is displayed Developer Center registered trade name
String productType = IapEnum.ProductType.IN_APP.getType (); // "inapp"
String devPayload = AppSecurity.generatePayload ();
String gameUserId = ""; // default ""
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登录的请求
IAP_API_VERSION. 5 = int;
int LOGIN_REQUEST_CODE = 2000; // returns to onActivityResult request code
mPurchaseClient.launchLoginFlowAsync(IAP_API_VERSION, this, LOGIN_REQUEST_CODE, mLoginFlowListener)
3.6.2 登陆结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e(TAG, "onActivityResult resultCode " + resultCode);
switch (requestCode) {
case LOGIN_REQUEST_CODE:
/*
* 调用launchLoginFlowAsync API时收到的intent数据通过handleLoginData解析返回值。
* 析后返回结果通过调用 launchLoginFlowAsync 时返回LoginFlowListener。
*/
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");
// user canceled , do nothing..
}
break;
}
}
## 服务器验证以及消耗
1 服务器验证,one store采用sha512公钥验证
$key = openssl_pkey_get_public($publicKey);
if(!$key){
return false;
}
$ret = openssl_verify($signedData, base64_decode($signature), $key,"SHA512");
openssl_free_key($key);
return $ret
2 服务器消耗
URI: https://{host}/v2/purchase/consume/{purchaseId}/{packageName}
3 变更订阅状态
URI: https://{host}/v2/purchase/manage-payment-status/{purchaseId}/{packageName}/{action}
## 标题客户端代码: