第三方支付

第三方支付?

第三方支付是指销售商(以下称开发者)在不使用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.co.kr )是否正常发送交易记录。

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

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

    • 接着连接商用环境,接入开发者想要使用的第三方支付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 (发送第三方支付的购买记录)

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

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

  • 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 进行传输

adId

String

50

true

手机中获取的 ADID(如无会以UNKNOWN_ADID发送)

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发送)

installerPackageName

String

150

true

手机上获取的 installerPackageName 信息

(如无会以UNKNOWN_INSTALLER发送)

purchaseMethodList

true

purchaseMethodCd

String

30

true

支付平台代码(参照代码表)

purchasePrice

Double

10

true

不同支付平台的支付金额

totalPrice

Double

10

true

支付总额

purchaseTime

Long

19

true

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

  • Example

{
    "countryCode": "KR",
    "currencyCode": "KRW",
    "adId": "abcdefgh-abcd-1234-abcd-abcdefgh1234",
    "developerOrderId" : "your_order_id_1234567890",
    "developerProductList" : [
       {"developerProductId" : "your_product_id_1111",
       "developerProductName" : "A",
       "developerProductPrice" : 5000,
       "developerProductQty" : 2
       },
       {"developerProductId" : "your_product_id_2222",
       "developerProductName" : "B",
       "developerProductPrice" : 5000,
       "developerProductQty" : 1
       }
    ],
    "simOperator" : "45005",
    "installerPackageName" : "com.skt.skaf.A000Z00040",
    "purchaseMethodList" : [
       {"purchaseMethodCd" : "TRD_CREDITCARD",
       "purchasePrice" : 10000
       },
       {"purchaseMethodCd" : "TRD_PAYCO",
       "purchasePrice" : 5000
       }
    ],
    "totalPrice" : 15000,
    "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": "Request has been completed successfully.",
    "developerOrderId": "test1695105094231"
}

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"
}

代码表

支付平台代码(purchaseMethodCd)

支付平台代码 (purchaseMethodCd)

支付平台名称

备注

TRD_MOBILEBILLING

手机话费扣款

DCB、小额结账

TRD_CREDITCARD

信用卡

含借记卡

TRD_11PAY

11pay

TRD_NAVERPAY

N pay

TRD_KAKAOPAY

Kakaopay

TRD_PAYCO

Payco

TRD_SAMSUNGPAY

Samsung Pay

TRD_SSGPAY

SSG Pay

TRD_TOSS

TOSS

TRD_BANKTRANSFER

银行卡转账

含无存折汇款和虚拟账户汇款

TRD_TMONEY

Mobile T money

TRD_CASHBEE

Mobile CashB

TRD_OKCASHBAG

OK cashbag

TRD_CULTURELAND

Culture Cash

文化商品券

TRD_HAPPYMONEY

Happy Money

Happy Money商品券

TRD_BOOKNLIFE

图书文化商品券

TRD_CASHGATE

便利店Cash

TRD_PAYPAL

PayPal

TRD_TMEMBERSHIP

T Membership

TRD_KTMEMBERSHIP

KT Membership

TRD_LGMEMBERSHIP

U+ Membership

TRD_GOOGLEPLAY

Google Play

TRD_BITCOIN

Bit Coin

TRD_SKINSCASH

Skins Cash

TRD_AMAZONPAY

Amazon Pay

TRD_PURCHASE_ETC

其他结算方式

取消理由代码 (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.

PayMethodPriceSumNotMatch

결제총액과 결제수단 별 결제금액의 합이 일치하지 않습니다.

The total amount of payment and the sum of the amount of each payment method do not match.

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.om.ktpackageinstaller
* 3. com.android.ktpackageinstaller
* 4. com.kt.olleh.storefront
* 5. com.kt.olleh.istore
* 6. com.lguplus.installer
* 7. com.lguplus.appstore
* 8. android.lgt.appstore
*
* Samsung Galaxy Apps : com.sec.android.app.samsungapps
*
* 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";
}
编号InstallerInstaller Package Name

1

ONE store SKT

com.skt.skaf.A000Z00040

2

ONE store KT

com.kt.om.ktpackageinstaller com.android.ktpackageinstaller com.kt.olleh.storefront com.kt.olleh.istore

3

ONE store LG U+

com.lguplus.installer com.lguplus.appstore android.lgt.appstore

获取手机运营商信息

  • 从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";
}

获取Advertising ID

  • Google Advertising ID是在 play service提供的数据,要获取相应数据必须将google play service library包含在项目中。

  • Google Play Service library指南可以根据以下链接操作即可。

  • 用户设定为无法获取Advertising ID的模式,可发送 “UNKNOWN_ADID”。

Example

/**
* Returns the Google Advertising ID.
* The getGoogleAdID Api has dependency of the google service.
* Please check include google service api into your project.
*
* If you can't read of Advertising ID, return the "UNKNOWN_ADID".
*
* @param context application context
* @return Google AdIDAdvertising ID or "UNKNOWN_ADID"
*/
public static String getGoogleAdID(@NonNull Context context) {
    if (context != null) {

       Context applicationContext = context.getApplicationContext();

       try {
com.google.android.gms.ads.identifier.AdvertisingIdClient.Info idInfo =

com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertising
IdInfo(applicationContext);

            if (idInfo != null) {
                return idInfo.getId();
            }
       } catch (GooglePlayServicesNotAvailableException e) {
      } catch (GooglePlayServicesRepairableException e) {
      } catch (IOException e) {
      }
    }
    return "UNKNOWN_ADID";
}

其他信息

外部支付流程(全球)

  • 外部支付税收政策

    • 开发者直接通过外部支付进行出售时,其附加税和其他相关税款缴纳义务则由开发者承担,并直接向相应国家缴纳附加税和其他相关税款。

  • 外部支付服务费

    • 从最终消费者支付金额中,扣除附加税后计算服务费。

    • 即使通过外部支付在多国出现交易时,需要截止到每月25日将服务费合计汇到虚拟账户。

      • 在韩卖家:KRW汇款

      • 韩国以外的国家的卖家:USD汇款

    • 虚拟账户验证路径:开发者中心>结算>外部支付>结算现状>底部

  • 手续费凭证

    • 在韩卖家:以1张税金账单发行(韩国+全球出售的总手续费)

      • 然而,在韩出售时,作为共同合资,将分One Store/KT/LG U+3家公司分别出具凭证。

    • 韩国以外国家的卖家:以1张发票发行(韩国+全球出售的总手续费)

    • 路径:开发者中心>结算>外部支付>结算现状>税收凭证 / INVOICE

  • 凭证信息修改

    • 如果需要修改税单(发票)中的我的会员信息,请在出售月底之前将开发者中心(devhelper@onestore.co.kr)发出需求。

  • 未缴手续费

    • 当一直未缴手续费时,根据销售条款,停止出售商品等有可能服务会被受限。

技术或管理政策询问

Last updated