第三方支付

第三方支付?

第三方支付是指销售商(以下称开发者)在不使用ONE store应用内支付模块(应用内支付SDK)的情况, 直接接入第三方支付平台提供支付服务。

第三方支付使用方法

发送交易记录

  • 开发者即使采用第三方支付,也须将第三方支付交易记录(购买记录、取消记录)发送给ONE store,开发者有必要开发和审核相应逻辑。

  • 开发者发送的第三方支付交易记录会用于ONE store 应用排行榜和服务,以及ONE store和开发者之间的结算业务。

开发与审核流程

  • (A) [开发者] 进入ONE store开发者中心> Apps >点击 “商品注册”按钮,注册新增应用。

    • 在“商品注册”画面的“使用第三方支付平台”选项,设为“使用”。

    • 确认“第三方支付使用之同意”弹窗中所示内容,设为同意(“确认”)。

  • (B) [开发者] 获取 OAuth Key(Client_secret)在“商品注册”画面。

  • (C) [开发者] 开发时须参照服务器API规范。

    • 开发获取OAuth AccessToken、发送交易记录等的方法。

  • (D) [开发者] 务必确认在Sandbox环境下(https://sbpp.onestore.net )是否正常发送交易记录。

  • (E) [开发者] 将开发的最终版安装包(APK)上传至ONE store开发者中心,并连接商用环境。

    • 首先连接开发者商用环境和ONE store商用环境(https://apis.onestore.net )

    • 接着连接商用环境,接入开发者想要使用的第三方支付PG。

  • (F) [开发者] 向ONE store申请审核。

  • (G) [ONE store] 务必确认在开发者应用中完成支付后,能否在商用环境下发送交易记录。

  • (H) [ONE store] 向开发者发起取消用于审核的第三方支付请求。(向开发者联络人发送相应邮件)

  • (I) [开发者] 取消相应交易的支付。

  • (J) [ONE store] 确认在商用环境下开发者的交易取消记录能否正常发送,如果无误就意味着通过审核。

  • (K) [开发者] 上架通过审核的应用。

发送交易记录的条件

  • 需发送交易记录的标准如下:

    • 使用第三方支付的情况

      • 使用第三方支付服务直接购买商品

      • 使用第三方支付服务充值应用内要支付的货币* (*应用内货币:只能在相关应用可充值,只能购买相关应用内的商品的货币)

      • 使用开发者自设的支付货币**来购买商品(**开发者自设的支付货币:不仅是相关应用程序,还可以同样开发公司的其他应用或Web等其他渠道适用第三方支付购买,在多个应用中可以使用的结算手段 )

    • 除外情况 (不使用第三方支付服务)

      • 通过开发者内部推广活动建立的支付平台(如免费优惠券,积分式cash)来购买商品

      • 不在One Store分发国家范围内的其他国家上发生交易时

  • 根据购买ID(developerOrderId)来确认交易记录。

    • 所开发的应用接入第三方支付服务,须在“第三方支付完成”后,向用户提供购买ID。(支付完成界面内及邮件通知)

    • ONE store审核队伍须根据购买ID确认相应应用的第三方支付交易记录是否正常发送给ONE store。

  • 发送国家代码和货币代码时,请注意以下事项:

    • 对于One Store分发的国家中出现的交易,则以 ISO_3166-1_alpha-2为准传输国家代码。

    • 货币代码根则以过家代码为准,根据 ISO_4217 进行传输,如果交易的货币与国家货币不同,则将其转换为国家货币进行传输。(谷歌搜索,截至当天00时)

    • 国家代码为KR时,Request Header的x-market-code则传输至MKT_ONE。

    • 国家代码不是KR时,Request Header的x-market-code则传输值MKT_GLB。

  • ONE store由审核队伍进行确认程序,如无法传达准确的总供应价格,可进行验证退回或停止销售处理。

服务器API

什么是第三方支付服务器API?

  • 开发者支付完成(成功)后,须将相应数据发送给ONE store,同步支付记录。同时,支付成功且完成同步的交易如需更改相关数据(取消交易)时,同样需要发送相关交易记录。

  • 发送给ONE store的第三方支付购买或取消的交易内容会用于ONE store 应用排行榜,面向一般顾客公开,以及用于ONE store和开发者之间的结算资料。

  • 第三方支付接入API可将开发者应用中包含的所有第三方支付购买或取消购买记录发送给ONE store。

    • send3rdPartyPurchase (发送第三方支付的购买记录)

    • cancel3rdPartyPurchase (取消第三方支付的购买记录)

  • 应先进行OAuth认证,应先获取client_id和client_secret后,进行 OAuth认证,才能接入各API。

连接环境

  • ONE store API服务器按照使用目的分成开发环境(Sandbox)和商用环境。

    • 开发环境(Sandbox):

      • 与商用 API同规则的虚拟连接环境。

      • 开发者开发可连接ONE store和服务器API后,将应用在开发者中心正式上架之前,连接开发环境进行测试。

      • 该流程中,开发者发送的支付信息不用于排行榜信息或结算。

    • 商用环境:

      • 实际服务的环境,应同步用户的支付完成或取消记录。

      • 开发者在商用环境中发送的支付数据会用于结算业务,如果在商用环境中进行支付测试,须取消相应交易。

  • 开发环境和商用环境的host信息如下。

连接流程

发送第三方支付的购买记录

  • 用户在应用中购买应用内商品时,应用会自动获取接入时所需信息。(参照4. Reference Code)

  • 将应用自动获取的信息和用户发起的购买请求发送给开发者服务器。

  • 开发者服务器通过第三方支付平台(支付平台或其他应用商店应用内支付程序)处理支付,将支付结果发送给相应应用。

  • 同时,将通过第三方支付进行的购买记录发送给ONE store API 服务器。

    • (如果ONE store的 OAuth 访问令牌到期)先获取OAuth 访问令牌(AccessToken),再接入API。

    • 建议保存API接入结果作为状态值,接入失败时重试。

取消第三方支付的购买记录

  • 如接入ONE store的单项购买记录被取消,应将通过第三方支付平台取消的记录发送到ONE store API服务器。

    • (如果ONE store的 OAuth 访问令牌到期)先获取OAuth 访问令牌(AccessToken),再接入API。

    • 建议保存API接入结果作为状态值,接入失败时重试。

ONE store OAuth

概况

  • 接入ONE store 交易有关服务器 API时,必须经过 OAuth认证获取 AccessToken (访问令牌)。

  • AccessToken的有效时间为3600秒,如果有效时间到期或只剩下600秒以下,再次调用 getAccessToken(),可获取新令牌。

    • 这时,已有的AccessToken也可以使用到有效时间。

    • 开发者可重复获取AccessToken,故按照开发者的服务实例(instance),获取及使用不同AccessToken。

  • 基本流程如下:

  • 获取AccessToken的流程(1)是如果调用API时出现认证错误时采用。

  • 为了调用ONE store服务器Open API,使用 Authorization Bearer,调用案例如下。(Bearer值是指调用 getAccessToken()后获取的 AccessToken )

POST /v6/purchase/developer/com.onestore.game.goindol/send HTTP/1.1
Host: iap-apis.onestore.net
Authorization: Bearer 680b3621-1234-1234-1234-8adfaef561b4
...

getAccessToken (获取AccessToken)

  • Desc: 获取AccessToken,用于接入服务器Server API。

  • URI: /v6/oauth/token

  • Method: POST, PUT

  • Request Header

Parameter Name

Description

Example

Content-Type

请求Http 时,应以Content Type设置为 application/x-www-form-urlencoded

Content-Type: application/x-www-form-urlencoded

x-market-code

市场分类代码

x-market-code: MKT_GLB

  • Request Body

Element Name

Description

Example

client_id

一般与packageName一致

com.onestore.game.goindol

client_secret

将应用注册于开发者中心时生成的 client secret值

vxIMAGcVz3DAx20uDBr/IDWNJAPNHFl7YruF4uxB6BI=

grant_type

固定值

client_credentials

  • Example

POST /v6/oauth/token HTTP/1.1
Host: iap-apis.onestore.net
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
x-market-code: MKT_GLB

grant_type=client_credentials&client_id=com.onestore.game.goindol&client _secret=vxIMAGcVz3DAx20uDBr/IDWNJAPNHFl7YruF4uxB6BI=
  • Response Body

Element Name

Data Type

Data Size

Description

status

String

7

访问令牌获取结果

client_id

String

255

OAuth认证 client_id

access_token

String

36

token_type

String

6

只提供 bearer方式

expires_in

Integer

10

令牌有效期,单位为秒(second)

scope

String

1024

令牌使用范围

  • Example

{
    "status":"SUCCESS",
    "client_id":"com.onestore.game.goindol",
    "access_token":"680b3621-1234-1234-1234-8adfaef561b4",
    "token_type":"bearer",
    "expires_in":3010,
    "scope":"DEFAULT"
}

服务器API详细内容

将第三方支付的购买记录及取消记录发送给ONE store服务器的详细内容。

send3rdParyPurchase-p1 (发送第三方支付的购买记录)

  • Desc: 发送开发者应用通过第三方支付平台购买的记录。

  • URI: /v6/purchase/developer/{packageName}/send/p1

  • Method: POST

  • Parameters: String packageName : 调用API的应用包名称。 (Data Size : 128)

  • Request Header

Parameter Name

Data Type

Required

Description

Authorization

String

true

通过Access Token API获取的访问令牌

Content-Type

String

true

application/json

x-market-code

String

FALSE

市场分类代码

Example

Request.setHeader("Authorization", " Bearer <Access-Token>");
Request.setHeader("Content-Type", "application/json");
Request.setHeader("x-market-code", "MKT_GLB");
  • Request Body

    Element Name

    Data Type

    Data Size

    Required

    Description

    countryCode

    String

    2

    TRUE

    对于One Store分发的国家中出现的交易,则以 ISO_3166-1_alpha-2为准传输国家代码。

    currencyCode

    String

    3

    TRUE

    根据 ISO_4217 进行传输

    developerOrderId

    String

    100

    true

    开发者的购买ID,以识别各项购买

    (唯一的价值。重复储存时会发生错误,参照Error Response)

    developerProductList [

    true

    developerProductId

    String

    150

    true

    开发者应用内商品的ID

    developerProductName

    String

    200

    true

    开发者应用内商品名称

    developerProductPrice

    Double

    10

    true

    开发者应用内商品价格(不含税价格)

    developerProductQty

    Integer

    10

    true

    开发者应用内商品购买数量

    ]

    simOperator

    String

    20

    true

    手机上获取的simOperator信息

    (如无会以UNKNOWN_SIM_OPERATOR发送)

    totalSuppliedAmount

    Double

    20

    true

    总供应价格(除去税金的结算对象金额)

    purchaseTime

    Long

    19

    true

    1970年1月1日后购买商品的时间(单位:ms) (未有效时间传送时发生9002错误,参考Error Response)

  • Example

{
    "countryCode": "KR",
    "currencyCode": "KRW",
    "developerOrderId": "your_order_id_1234567890",
    "developerProductList": [
        {
            "developerProductId": "your_product_id_1111",
            "developerProductName": "게임아이템A",
            "developerProductPrice": 5000.0,
            "developerProductQty": 2
        },
        {
            "developerProductId": "your_product_id_2222",
            "developerProductName": "게임아이템B",
            "developerProductPrice": 5000.0,
            "developerProductQty": 1
        }
    ],
    "simOperator": "45005",
    "totalSuppliedAmount": 15000.0,
    "purchaseTime": 1345678920000
}
  • Response Body

Element Name

Data Type

Data Size

Required

Description

responseCode

String

50

true

数据保存情况(0 : 成功)

responseMessage

String

500

true

developerOrderId

String

100

true

开发者的购买ID,以识别各项购买

  • Example

{
    "responseCode": "Success",
    "responseMessage": "The request has been completed successfully.",
    "developerOrderId": "your_order_id_1234567890"
}

cancel3rdPartyPurchase (取消第三方支付的购买记录)

  • Desc: 取消开发者应用通过第三方支付平台购买的记录。

  • URI: https://{host}/v2/purchase/developer/{packageName}/cancel

  • Method: POST

  • Parameters: String packageName : 调用API的应用包名称。 (Data Size : 128)

  • Request Header

    Parameter Name

    Data Type

    Required

    Description

    Authorization

    String

    true

    通过Access Token API获取的访问令牌

    Content-Type

    String

    true

    application/json

    x-market-code

    String

    FALSE

    市场分类代码

  • Example

Request.setHeader("Authorization", " Bearer <Access-Token>");
Request.setHeader("Content-Type", "application/json");
Request.setHeader("x-market-code", "MKT_GLB");
  • Request Body

Element Name

Data Type

Data Size

Required

Description

developerOrderId

String

100

true

开发者的购买ID,以识别各项购买

(重复发起取消请求时会发生错误,参照Error Response)

cancelTime

Long

19

true

1970年1月1日后购买商品的时间(单位:ms)

cancelCd

String

30

true

取消理由码(参照代码表)

  • Example

{
    "developerOrderId" : "your_order_id_1234567890",
    "cancelTime" : 1345678920000,
    "cancelCd" : "TRD_CANCEL_USER"
}
  • Response Body

    Element Name

    Data Type

    Data Size

    Required

    Description

    responseCode

    String

    50

    true

    数据保存情况(0 : 成功)

    responseMessage

    String

    500

    true

    developerOrderId

    String

    100

    true

    开发者的购买ID,以识别各项购买

  • Example

{
    "responseCode": "Success",
    "responseMessage": "Request has been completed successfully.",
    "developerOrderId": "test1695105094231"
}

代码表

取消理由代码 (cancelCd)

carrierCd

取消理由

备注

TRD_CANCEL_USER

用户请求取消购买

TRD_CANCEL_TEST

取消测试用购买

TRD_CANCEL_ETC

其他

Error Response

服务器API除正常回应外,出错时另以JSON形式发送相应信息,参考以下内容:

  • Response Body : JSON形式

Element Name

Data Type

Description

error

Object

错误信息

code

Integer

错误码

message

String

错误消息

  • Example

{
    "error": {
        "code": "AccessTokenExpired",
        "message": "The access token was expired. Expired access token."
    }
}

Error Codes

RequiredValueNotExist

필수값이 존재하지 않습니다. [ fields1, fields2, ... ]

Request parameters are required. {0}

NoSuchData

조회된 결과값이 존재하지 않습니다.

The requested data could not be found.

InvalidRequest

입력된 값이 유효하지 않습니다. [ fields1, fields2, ... ]

Request parameters are invalid. {0}

InternalError

정의되지 않은 오류가 발생하였습니다.

An undefined error has occurred.

DuplicatedPurchase

중복된 구매데이터입니다.

The purchase are duplicated.

Not3rdPartyPurchaseProduct

외부결제로 등록된 상품이 아닙니다.

The product is not registered with external payment.

Invalid3rdPartyCancelState

외부결제 구매내역 전송/취소가 불가능한 판매상태입니다.

It is in a sales state where it is impossible to send or cancel the purchase details of external payment.

NotExistPurchaseOrCannotCancel

취소할 구매데이터가 존재하지 않거나 취소할 수 없는 상태입니다.

The purchase data to be canceled does not exist or cannot be canceled.

Invalid3rdPartyMarketCodeOne

국가/통화 코드를 확인해주세요. 대한민국이 아닌 국가에서 발생한 거래내역은 마켓 구분 코드 MKT_GLB로 전송해야 합니다.

Please check the country/currency code. For transactions outside Korea, use MKT_GLB as the market code.

Invalid3rdPartyMarketCodeGlb

국가/통화 코드를 확인해주세요. 대한민국에서 발생한 거래내역은 마켓 구분 코드 MKT_ONE으로 전송해야 합니다.

Please check the country/currency code. For transactions in Korea, use MKT_ONE as the market code.

NotSupport3rdPartyCountryCode

원스토어에서 판매중인 국가의 거래내역이 아닙니다.

These transaction details are not related to distribution countries.

NotMatch3rdPartyCurrencyCode

거래가 발생한 국가의 국가 통화로 거래내역을 전송해야 합니다. ({0} 만 가능합니다)

Use the local currency code for transaction details. (Only the {0} is allowed.)

Reference Code

本指南包含客户端开发内容,主要支持上架于ONE store,但使用第三方支付平的应用发送交易记录。

开发者先确认以下内容,开发时自行加入或参照案例代码。

获取应用安装程序的信息

  • 通过ONE store安装的应用会带有共八个安装包(install package)信息,参照下表。

  • 如果按照以下代码通过ONE store安装程序(Installer)安装了应用 ,必须将相应应用的支付信息发送给ONE store。

  • 如果无法确认Installer来源,可发送 “UNKNOWN_INSTALLER”。

Example

/**
* Returns the package name of the application that installed a package.
* The OneStore has many installer package names.
* Please check below list of package names.
*
* Google Play : com.android.vending
*
* ONE Store :
* 1. com.skt.skaf.A000Z00040
* 2. com.kt.olleh.storefront
* 3. com.lguplus.appstore
* 4. com.onestorecorp.gaa.storeapp
* 5. com.dti.folderlauncher
*
* If you read null string, return the "UNKNOWN_INSTALLER".
*
* @param context application context
* @return Name of installer package name or "UNKNOWN_INSTALLER"
*/
public static String getInstallerPackageName(@NonNull Context context) {
    if (context != null) {

        Context applicationContext = context.getApplicationContext();
        PackageManager pm = applicationContext.getPackageManager();
        final String installPackageName =
pm.getInstallerPackageName(applicationContext.getPackageName());

    if (!TextUtils.isEmpty(installPackageName)) {
         return installPackageName;
    }
   }
   return "UNKNOWN_INSTALLER";
}
编号
Installer
Installer Package Name

1

ONE store SKT

com.skt.skaf.A000Z00040

2

ONE store KT

com.kt.olleh.storefront

3

ONE store LG U+

com.lguplus.appstore

4

ONE store GLOBAL

  • com.onestorecorp.gaa.storeapp

  • com.dti.folderlauncher

获取手机运营商信息

  • 从USIM 卡获取手机运营商信息,通过ONE store第三方支付交易记录的发送API进行发送。

  • 要发送的手机运营商信息以MCC+MNC形式的SIM Operator信息, 以5 至6位数组成。

  • 如使用连接Wi-Fi的便携设备等无法获取SIM Operator时,可发送 "UNKNOWN_SIM_OPERATOR" 。

Example

/**
* Returns the MCC+MNC (mobile country code + mobile network code) of
the provider of the SIM. 5 or 6 decimal digits
* If you can't read of SinOpreater, return the "UNKOWN_SIM_OPERATOR".
*
* @param context application context
* @return MCC+MNC information or "UNKNOWN_SIM_OPERATOR"
*/
public static String getSimOperator(@NonNull Context context) 
    {if (context != null) {

       Context applicationContext = context.getApplicationContext();
       TelephonyManager telephonyManager =
               (TelephonyManager)
applicationContext.getSystemService(Context.TELEPHONY_SERVICE);

       if (telephonyManager != null && telephonyManager.getSimState()
== TelephonyManager.SIM_STATE_READY) {
            return telephonyManager.getSimOperator();
       }
    }
    return "UNKNOWN_SIM_OPERATOR";
}

其他信息

结算

  • 请参考[这里]了解结算相关内容。

技术或管理政策询问

Last updated