Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

程序内支付(IAP)编程及例子解析

From Wiki
Jump to: navigation, search

本文介绍如何使用Nokia IAP api开发程序内支付应用


Article Metadata

文章
flycarl 在 19 Dec 2011 创建
最后由 renlin 在 11 Jul 2012 编辑

Contents

Introduction

1.指定程序内支付物品

程序内支付的物品必须有Nokia商店收费。你必须在Nokia商店注册物品名,描述,和价格点。Nokia商店对每个物品提供一个ID标识,来给API调用。

环境

在开始开发前,你就可以标定程序内支付物品。 向Nokia商店提交信息后,就可以被程序内支付API访问到。为避免泄露你的产品信息,你可以提交一个零食的描述用于测试,当发布时再改成真正的描述。你可以设一个很低的价格,以降低测试消费。

步骤

1. 登陆 http://publish.ovi.com.
2. 创建一个新的 Qt Based Application. 你不能向一个已有的内容物品中添加程序内支付功能。
3. 在内部物品名中添加IAP字样(不是外部显示名)。
4. 勾选程序内支付物品选择框。如果Ovi publish没有显示这个选择框,那么你的账号不能访问程序内支付的功能,请联系Nokia申请这个权限.


5.提交所有媒质信息,点Create。
6. 点In-app purchases选项卡。为第一个支付物品提交名字,描述,和价格点。


7. 点Create。
8. 点Add in-app purchase给其他物品提交信息。Ovi pulish 为每个物品显示一个ID,在你的程序中使用这个ID标定每个物品。

9. 点Submit(提交)。 将这些信息上传到Nokia商店。这样你都可以放我那支付数据,并向在线服务器提交支付申请,以测试你的应用。之后你可以根据需要修改这些媒质信息。

页面结果

现在你有了支付物品及其ID,接下来将这些ID用在:

  • 资源文件夹的名字,如设置开发环境章节中的描述。
  • API调用,如使用程序内支付API章节里的描述。你可以决定如何存储这些ID,及你的应用如何访问你的存储。示例应用章节中演示了如何从资源子文件夹中读取ID。


2.设置开发环境

你程序的私有文件夹中必须有几个特殊文件,并适当设置你的Qt开发环境。

设置私有文件夹

你的程序的私有文件夹不能被其他程序访问。你有一个默认的私有文件夹:

<drive>:\private\<UID>\

其中<drive>是盘符(如, C:,D:),<UID>时候全局唯一标示号,是你的symbian程序的UID。8位16进制数,没有0x前缀。在这个私有文件夹中放两个文件
1. IAP_VARIANTID.txt: 包含000000(6个0)的文本。这是程序内支付API所要求的。 你的程序提交以后,Ovi Publish在这个文本文件中写入数据,用于DRM的访问。
2. TEST_MODE.txt: 用来模拟支付,绕过真实付款。去掉这个文件将访问在线Nokia商店进行真实支付。 参考测试应用获取具体细节。

设置DRM保护

通过以下步骤你可以使用 OMA DRM 2.0 保护你的文件:

1. 申请免费签名服务。 之后我们可以打开你提交的应用,添加DRM保护然后签名 再打包。申请免费签名后,Nokia商店提供给你UID,你用这个UID来编码你的私有文件夹路径。如何申请参考: http://www.developer.nokia.com/Distribute/Packaging_and_signing.xhtml.

2. 设置外部资源文件。适当组织你的程序访问外部资源的结构。例如,一个游戏中每关的数据和图片文件。将这些文件放在适当的子文件夹中:

  • <drive>:\private\<UID>\drm\data\ — 保护需要支付的应用的基本资源文件
  • <drive>:\private\<UID>\drm\data\resourceId_XXXXXX\ — 保护程序内支付的资源文件

其中XXXXXX是6位程序内ID,由之前Ovi Publish提供。一个子资源文件夹的例子是: D:\private\ef80c1a8\data\resourceId_593032.

设置Qt开发环境

如果你刚开始接触Qt SDK, 请先学习如何设置Qt 开发环境,及如何编译应用。参见Portal:Qt (Chinese)

开发程序内支付应用,需要如下设置Qt应用的 pro文件。

CONFIG += mobility \
iapppurchasing \
symbian: {
TARGET.UID3 = 0xee774112
ICON = icon.svg
TARGET.EPOCSTACKSIZE = 0x14000
TARGET.EPOCHEAPSIZE = 0x020000 \
0x800000
DEPENDPATH += ./Symbian
SOURCES += Symbian/drmfile_p.cpp
HEADERS += Symbian/drmfile_p.h
LIBS += -lcaf \
-lcafutils \
-lapmime
 
# capabilities required for IAP API
TARGET.CAPABILITY += NetworkServices
 
# IAP configuration
addConfigFiles.sources = ./unlocked_data/IAP_VARIANTID.txt ./data/TEST_MODE.txt
addConfigFiles.path = .
DEPLOYMENT += addConfigFiles
 
# resources to be DRM protected
addDrm.sources = ./data
addDrm.path = ./drm
DEPLOYMENT += addDrm
 
# resources no need to be DRM protected
addUnlocked.sources = ./unlocked_data/unlocked_resources
addUnlocked.path = .
DEPLOYMENT += addUnlocked
}

如下构建程序: 1.运行qmake,在pkg文件中应该生成以下依赖语句:

    ; Has dependency on IAP component
(0x200345C8), 0, 1, 1, {IAP}

2.编译运行产生 sis包。

3.使用程序内支付API

使用程序内支付API,你需要在你的应用中实现购买内容和恢复内容的场景。

处理异步事件

程序内支付API的方法都是异步方法。你的应用先调用一个程序内支付方法。当API完成方法请求,API返回一个或多个信号。你的应用中用slot来处理每个可能的信号,

有两种函数调用的方法:

  • 一次发一个:当一个调用结束后发出下一个。例如,你请求一个物品的信息,然后请求下一个。推荐这个方法,因为你可以很容易处理到来的信号。也更容易处理延后的调用反应。
  • 并发的:同时调用多个方法。例如,用一个循环访问所有物品的媒质信息,然后按返回顺序处理返回信号。这种方法比较快速,但是回复顺序不可控(例如你请求A,然后B,但是接到B回复然后接到A回复)。你需要建立请求与回复之间的关系,并确保所有期望的回复都收到。

请参看示例应用如何连接signal,slot和发出调用。 下面的表列出你能调用的方法,和返回的信号。

API function Returned signals Used with built-in DRM or not built-in DRM content
getProductData() productDataReceived() Both
purchaseProduct() purchaseCompleted() and purchaseFlowFinished() Both
getUserAndDeviceId() userAndDeviceDataReceived() Not built-in
getRestorableProducts() restorableProductsReceived() Built-in
restoreProduct() restorationCompleted() (and restorationFlowFinished() , not needed in the application.) Built-in

执行一个销售流程

1.要弹出程序的待售目录,调用getProductData() 并传递产品ID。API返回productDataReceived()信号。用你的应用的slot连接这个信号并处理。
重复这个步骤以显示你的待售物品。
2.将待售物品显示给用户,至少显示品名。显示一个购买的按钮或其他方法以让用户触发购买。连接clicked()信号到一个slot比如,buyProduct()。
3.在buyProduct()slot中,调用purchaseProduct()方法,并传递商品ID。
4.这时程序内支付API接手,开始Nokia商店支付流程。这个过程中你的程序UI变灰色在背景,下面的步骤不需处理,只描述一下:
a.如果用户没有登录Nokia商店,API弹出Nokia商店登录对话框。API也显示相应的对话框供用户确认购买。API选择支付方法,通常是Nokia账户的首选支付方法。
b. 当用户支付完毕,API发送purchaseCompleted() 信号,并传递状态值。
c.发送purchaseCompleted() 信号后,API显示交易的输出对话框,或者是支付成功信息,或错误信息。
d. 当用户点击OK忽略交易输出,API发出purchaseFlowFinished() 信号给你的应用。
5.收到 purchaseFlowFinished() 信号时,你的应用重新获得了UI控制权。如果支付成功,开始让用户访问购买物品内容的过程。

  • 如果内容是程序内的DRM保护的,IAP API将其自动解锁
  • 如果内容不是由DRM保护,你的应用需要自己处理内容。
  • 如果你使用后台服务器下载内容到用户手机,服务器需要首先调用Purchase Ticket Verification API来验证产品已经售出。

恢复已买物品

你可以使用程序内支付API恢复DRM加密内容的证书。恢复内容的过程取决于你是否使用了内建的DRM保护。

  • 要恢复内建DRM保护的内容,Nokia商店重新部署DRM key到手机。Nokia商店可以保存关于可恢复的内容的信息也可以限制恢复的次数。
  • 要恢复其他内容,你可以决定支持哪种类型的恢复,你可以使用getUserANdDeviceId()来获取用户和当前使用设备的信息,你可以使用这些信息来决定用户可否恢复。

4.使用Purchase Ticket Verification API

使用 Purchase Ticket Verification (PTV) API来验证购买票的有效性。

PTV API通过HTTPS访问Nokia商店获取XML。如果你使用后台服务器向用户手机提供下载服务,服务器可使用PTV API来向Nokia商店验证商品是否已售出。 1.向Nokia商店发送PurchaseVerificationRequest 请求 2.Nokia商店返回PurchaseVerificationResponse ,其中结果的属性表明支付是否成功。 请求和回复使用UTF-8编码,由PTV API XML语法描述。

所有PTV API请求使用HTTPS POST方法发送。请求XML设置to form参数内容。调用者必须设置Content-Type HTTP头参数为application/x-www-form-urlencoded并包含charset参数如 Content-Type: application/x-www-form-urlencoded; charset=UTF-8。API不需要额外的验证。

API调用返回下面的HTTP状态值:

  • 返回 200 如果调用成功。返回体包含XML回复文本。
  • 返回非200则调用失败。不同的错误原因返回值不同。

你可以通过发送购买验证请求来验证购买是否成功。

购买验证请求

要验证购买票相关的购买是否成功,向Nokia商店发送PurchaseVerificationRequest 。请求URL是/iap/1.0/purchases/verify?method=GET。

在请求中,使用一个PurchaseTicket 或二进制XML 元素。PurchaseTicket 是标示单个购买的一个结构体。二进制的值是PurchaseTicket 值得64位编码的值。 下表列出了PurchaseTicket 元素的属性,

Attribute Data type Description
transactionId IdType The unique identification of the purchase transaction.
transactionTime xs:datetime The date and time of the purchase in the UTC time zone, for example 2010-12-22T08:47:59.000Z
productId IdType The product ID of the purchased product.
applicationId IdType The identifier of the application.
accountId HashType The hashed value of the user's account ID.
imei HashType The hashed value of the user's IMEI.
imsi HashType The hashed value of the user's IMSI.
signature SignatureType Used for verifying data integrity. The value is a hexadecimal string presentation of an SHA–1 hash. The hash is calculated over a string that is derived by concatenating the other PurchaseTicket attribute values, in the following order: transactionId, transactionTime, productId, applicationId, accountId, imei, imsi.

下表列出PurchaseTicket 属性使用的数据类型。

Data type Description
IdType A string value, length between 1 and 128 characters.
HashType A string value, length 128 characters.
SignatureType A string value, length 40 characters.

PurchaseTicket 元素示例:

<?xml version=1.0” encoding=”UTF-8” standalone=”yes”?>
<PurchaseVerificationRequest xmlns=”http://payment.ovi.com/iap”>
<PurchaseTicket
transactionId="TH4B7CJE6P629"
transactionTime="2010-12-22T08:47:59.000Z"
productId="IAP_Resource_1"
applicationId="IAP_Product_1"
accountId="c738d9a3e5cbe57abac12c2e342bf5cdee19536e72de81532be680d9bcf1a17d6fb5f382467b78bcec0f669b09f753bc392586c29d99c7e6316d2b62a617e35b"
imei="d892bd0af1b5c124753be58ec7e3091cab2ecadc201069b63a3a7baace31edf04dee79f72a9ffb969093da62745ad9f42f4a3100bcbf56e550d3502efa846bf7"
imsi="9efd65ed7dbb77cb7d9c96503158a3139f0346576dd80f00d22c0076e11c1c34d3bde4877446eb6b4d122265f5bed8b75f7b4ae8d8c2cee7e724230b4a930136"
signature="99c10faffc36e944dd20a2f71ff55c91276690af"
</PurchaseTicket>
</PurchaseVerificationRequest>

上例中的签名如下计算:

SHA1(“TH4B7CJE6P6292010-12-22T08:47:59.000ZIAP_Resource_1IAP_Product_1c738d9a3e5cbe57abac12c2e342bf5cdee19536e72de81532be680d9bcf1a17d6fb5f382467b78bcec0f669b09f753bc392586c29d99c7e6316d2b62a617e35bd892bd0af1b5c124753be58ec7e3091cab2ecadc201069b63a3a7baace31edf04dee79f72a9ffb969093da62745ad9f42f4a3100bcbf56e550d3502efa846bf79efd65ed7dbb77cb7d9c96503158a3139f0346576dd80f00d22c0076e11c1c34d3bde4877446eb6b4d122265f5bed8b75f7b4ae8d8c2cee7e724230b4a930136”).

二进制元素示例:

<?xml version=1.0” encoding=”UTF-8” standalone=”yes”?>
<PurchaseVerificationRequest xmlns=”http://payment.ovi.com/iap”>
<Binary>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxQdXJjaGFzZVRpY2tldCBzaWduYXR1cmU9IjRhOTRiMWUzMzljZmI5MjkzMjdlNTJhYzBiZjRiNGUyNzAwYjEwMjUiIGltc2k9Ijg0ODI0YWE5NTM2NjBkNjkxZjlkZTQxNWQ2NzJkMGY3NTg4MTgzODQiIGltZWk9ImUxZDAwOWIwMjBkNGQzMTBmNGUzODEwN2I1MWQ4YjAyYWEyYjI2MDUiIGFjY291bnRJZD0iYzM2YzYyODVhZmQzNWYwYTkwZDg2MWE2Y2Q0ZTVmMTQyNjc5NWNiZCIgcHJvZHVjdElkPSJJQVBfUmVzb3VyY2VfMSIgYXBwbGljYXRpb25JZD0iSUFQX1Byb2R1Y3RfMSIgdHJhbnNhY3Rpb25UaW1lPSIyMDEwLTExLTAyIDA5OjI0OjM0IFVUQyIgdHJhbnNhY3Rpb25JZD0iMDdjMzI4NGUtODhiMS00MzYxLTljZDYtNTUxMzkwMzk5NTA2IiB4bWxucz0iaHR0cDovL3BheW1lbnQub3ZpLmNvbS9pYXAiLz4=</Binary>
</PurchaseVerificationRequest>

购买 验证回复

如果请求成功(返回HTTP状态值200),Nokia商店返回PurchaseVerificationResponse。回复中PurchaseVerificationResultType 元素的属性表明购买是否成功。下表列出可能的属性值。

Value Description
OK The payment succeeded.
Failed The payment failed.
Refunded The payment was refunded.
InvalidPurchaseTicket The PurchaseTicket element in the request contained invalid data. For example, the signature was invalid.

例子:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PurchaseVerificationResponse xmlns="http://payment.ovi.com/iap" result="OK" />

5.使用DRM保护内置资源

你可以使用 OMA DRM 2.0 来保护你程序中的可购买资源。

如果你从你的后台服务器发布你的支付物品,你需要自己保护这些物品,如果你随程序发布物品,你可以请Nokia运用OMA DRM 2.0来保护这些物品。OMA DRM 2.0是数字版权管理技术,由Open Mobile Alliance定义来管理数字媒体的发布。

DRM 如何工作

你提交包含支付物品的应用到Nokia Publish后,Nokia Publish解开安装包,使用OMA DRM 2.0加密预先定义在工程文件夹中的资源文件,根据需要签名文件,然后重新打包发布,你可以加密资源文件和核心资源文件,例如,你有一个游戏,前两关在游戏在初始销售,后面的关卡需要额外支付。每一关的资源文件(数据,图片文件)可单独使用OMA DRM 2.0加密。 如果是服务,那么可以这样设计,使用一些访问服务的门控口令,口令保存在文本文件中,用 OMA DRM 2.0保护。

OMA DRM 2.0 保护如何工作: IAP2.PNG
1. 消费者 -- 从Nokia商店下载你的应用
2. Nokia商店 -- 如果应用不免费,则进行支付流程,然后发送应用
3. 消费者手机,DRM代理 -- 收到支付确认,获取加密核心文件的访问权限
4. 证书密钥管理器 -- 认证设备,然后发送加密核心文件的访问权限
5. 消费者手机,DRM代理 -- 注册访问权限
6. 消费者 -- 使用应用,解密核心文件前调用DRM代理检查访问权限
7. 消费者 -- 做一次程序内支付
8. Nokia 商店 -- 进行支付流程
9. 消费者手机,DRM代理 -- 收到支付确认,获得加密的支付物品文件的权限
10. 证书密钥管理器 -- 认证设备,然后发送加密支付物品文件的访问权限
11. 消费者手机,DRM代理 -- 注册访问权限
12. 消费者 -- 使用程序内支付,解密程序内支付文件前调用DRM代理检查访问权限

设置开发环境

设置外部资源文件采用DRM保护的细节,参见设置开发环境章节。

访问DRM保护的文件

要访问受DRM保护的资源文件,你的应用需要使用内容访问框架(CAF)API,使用设备的DRM代理来检查访问权限。更多CAF API信息,参看:

Qt应用要访问加密文件,使用DRMFile类包裹CAF API, 在例子程序 \Examples\TryAndBuyExample\中有一个Qt 转换类DRMFile,打开、读或关闭的文件如下代码所示:

#include "DRMFile.h"
 
// create a file using the DRMFile class
DRMFile file;
 
// try to access the encrypted file
int error = file.open(protectedFileName[0]);
 
// if the device can access the encrypted file
if(!error)
{
// process the file data
 :
file.close();
}
// if the device cannot access the encrypted file
else
{
file.close();
// check the cause of the error
if(file.isDRMError(error))
{
 :
}
}

完整代码请参考\Examples\TryAndBuyExample Note: 接入未受保护的文件资源既可以通过CAF API也可以试Symbian C++或者Qt的文件接入方法。

6 .设置应用的工程文件

编译构建应用前,需要在Qt的pro文件中加入依赖的lib和需要的能力,例如\Examples\TryAndBuyExample中:

CONFIG += mobility \
iapppurchasing \
symbian:{
LIBS += -lcaf \
-lcafutils \
-lapmime
 
# capabilities required for IAP API
TARGET.CAPABILITY += NetworkServices
}

同时需要在pro中加入需要打包部署到设备中的文件:

 # IAP configuration
addConfigFiles.sources = ./unlocked_data/IAP_VARIANTID.txt #./data/TEST_MODE.txt
addConfigFiles.path = .
DEPLOYMENT += addConfigFiles
 
addDrm.sources = ./data
addDrm.path = ./drm
DEPLOYMENT += addDrm
 
addUnlocked.sources = ./unlocked_data/unlocked_resources
addUnlocked.path = .
DEPLOYMENT += addUnlocked

正确的设置应用程序的工程文件才能确保程序正确编译并正常运行,如果你是Qt的初学者,关于Qt的工程文件请参考帮助文档:[1]

Summary

使用程序内支付进行编程需要去实现一些特定的步骤,参照本文以及API包中提供的例子可以帮助你实现应用的程序内支付功能。

This page was last modified on 11 July 2012, at 03:15.
415 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×