這兩天看到兩條關(guān)于任天堂switch主機(jī)相關(guān)的兩條新聞:
國內(nèi)普通用戶對switch主機(jī)平臺了解不多,玩主機(jī)游戲的用戶更是少之又少。而在海外,大型精品游戲一般都會在主機(jī)平臺發(fā)布。而國內(nèi)主機(jī)平臺的開發(fā)圈,也基本上可以說是盲區(qū);雖然國內(nèi)一些大游戲公司會發(fā)布主機(jī)游戲,但也基本是試試水。從去年開始,我們陸續(xù)完成了uniy和ue4平臺的switch支付接入,這里整理成文檔,可以提供相關(guān)參考。
Switch賬戶
拿到switch的開發(fā)機(jī)后,第一步肯定是去申請相關(guān)的賬戶權(quán)限。switch賬戶類型可以歸類為以下三種,大致了解下:
-
User Account
switch本地賬戶,可離線注冊。只有通過與Nintendo Account關(guān)聯(lián) ,才能獲取到switch相關(guān)權(quán)限服務(wù) -
Network Service Account
switch網(wǎng)絡(luò)服務(wù)賬戶。當(dāng)User Account與Nintendo Account關(guān)聯(lián)時,switch會先讓用戶輸入Network Service Account實現(xiàn)關(guān)聯(lián)。 -
Nintendo Account
多個UserAccount可關(guān)聯(lián)到Nintendo Account,但同一時刻只能有一個UserAccount關(guān)聯(lián)。Nintendo Account與Network Service Account是一對一的關(guān)系。

switch賬戶權(quán)限/關(guān)系

問題
我們先主要理清下面幾個問題:
- 用戶能在Switch平臺上買什么?
- 怎么買,在哪買?
1. 用戶能在Switch平臺上買什么?
可以把Switch平臺類比為天虹,在天虹你可以買到衣服、零食等,比如衣服在五樓服飾處售賣,零食在一樓的生活超市售賣等。類似,在switch平臺上,用戶可以付費購買游戲、demo、游戲道具等,而購買的地方可以是switch自帶的商店eShop,也可以是switch的指定網(wǎng)站。主要有:
-
Downloadable Software
付費游戲,需要付費才能下載??赏ㄟ^Nintendo eShop、Nintendo website購買。 -
Demo Version
游戲demo,一般免費。可通過Nintendo eShop、Nintendo website購買。 -
Downloadable Content
可下載的付費內(nèi)容,付費下載后可離線使用,如游戲的額外關(guān)卡等。通過Nintendo eShop、Nintendo website購買。 -
Subscription Service Items
訂閱,可付費購買的使用時間權(quán)限。如游戲內(nèi)30天使用某服務(wù)的權(quán)限。通過Nintendo eShop購買。 -
Consumable Service Items
可消耗的物品,如游戲內(nèi)的游戲幣、鉆石等。通過Nintendo eShop購買。
2. 怎么買,在哪買?
正如上節(jié)提到,用戶可在Nintendo eShop和Nintendo website購買。其中,Ninnteodo eShop是Switch自帶的商店,可通過switch主界面或則游戲內(nèi)拉起,上面會展示可付費的游戲列表或游戲內(nèi)物品。Nintendo website是Nintendo的網(wǎng)站,上面一般用來售賣各種游戲。
Nintendo eShop購買
如圖所示,可通過switch主界面或通過游戲內(nèi)調(diào)用相關(guān)API拉起eShop。

支付方式
Switch支持的支付方式有:賬戶余額、信用卡、優(yōu)惠券。
-
賬戶余額
用戶Nintendo Account下的賬戶余額,用戶可通過信用卡、paypal和Nintendo Prepaid Card進(jìn)行充值。 -
信用卡
用戶可直接通過信用卡進(jìn)行支付 -
兌換券
兌換券與相關(guān)商品一一關(guān)聯(lián),通過輸入兌換券上兌換碼獲得相關(guān)商品。
Switch支付
這里以游戲售賣游戲幣為例,進(jìn)行switch支付接入。由于游戲幣屬于游戲內(nèi)物品,對比前面列出的switch商品類型,可把游戲幣歸類為Consume Service Items商品,用戶在Ninteond eShop購買。

上圖是switch文檔給出的購買Consume Service Item的流程圖。結(jié)合業(yè)務(wù)整理到支付的流程圖如下:

1. 拉起eShop
游戲調(diào)用SDK API并傳入游戲ApplicationId,拉起Nintendo eShop,eShop中展示游戲售賣的Cousnme Service Items列表。
//方式1,傳入游戲ApplicationId,此時Switch首先彈出賬戶選擇界面,讓用戶選擇支付賬戶
nn::ec::ShowShopConsumableItemList(nApplicationId);
//方式2,傳入游戲ApplicationId并指定用戶User
nn::ec::ShowShopConsumableItemList(nApplicationId, selectedUser);
2. 用戶在eShop操作
用戶在eShop界面完成購買操作,最后關(guān)閉eShop界面,回到游戲。
3. eShop關(guān)閉
用戶手動關(guān)閉eShop,回到游戲。這里需要特別注意的時:游戲無法知道用戶在eShop的具體操作,也不知道操作是否成功,只能檢測到eShop關(guān)閉了。即回到游戲后,游戲并不知道用戶是否在eShop有支付行為,也不知道支付是否成功。
那游戲該如何去判斷用戶是否支付成功?并將用戶支付的物品發(fā)放給用戶呢?
4. 查詢用戶交易記錄
由于游戲并不知道用戶在eShop的操作,只能通過后臺去Nintendo Server查詢用戶的交易記錄。由于游戲后臺去Nintendo Server查詢交易記錄時,需要用戶的授權(quán)信息(Nintendo Token(JWT協(xié)議));所以,此時)戲需要帶入Nintendo Token到后臺。
下面是之前在unity接入demo中寫的Nintendo Token獲取方式,僅供參考:
//1、初始化
Account.Initialize();
//2、顯示UI,讓用戶選擇登錄
Uid uid = new Uid();
Account.ShowUserSelector(ref uid);
//3、獲取登錄用戶的UserHandle
UserHandle = new UserHandle();
Account.OpenUser(ref UserHandle, uid);
//4、檢查Network Service Account是否可用
nn.Result cResult = NetworkServiceAccount.EnsureAvailable(UserHandle);
if (!cResult.IsSuccess())
{
return false;
}
//5、獲取Network Service Account Id
NetworkServiceAccountId nId = new NetworkServiceAccountId();
nn.Result gResult = NetworkServiceAccount.GetId(ref nId, UserHandle);
if (!gResult.IsSuccess())
{
return false;
}
//6、為當(dāng)前用戶分配Token Cache
int count = 0;
bool asyncDone = false;
AsyncContext asyncContext = new AsyncContext();
nn.Result eResult = NetworkServiceAccount.EnsurIdTokenCacheAsync(asyncContext, UserHandle);
//循環(huán)檢查異步操作是否完成,最多檢查100次,避免卡死
while (!asyncDone && ++count < 100)
{
asyncContext.HasDone(ref asyncDone);
}
if (!asyncDone)
{
return false;
}
if (!asyncContext.GetResult().IsSuccess() || !eResult.IsSuccess())
{
return false;
}
//7、獲取Token cache
byte[] tokenByte = new byte[1536];
ulong actualTokenSize = 0;
nn.Result loadResult = NetworkServiceAccount.LoadIdTokenCache(ref actualTokenSize, tokenByte, UserHandle);
if (loadResult.IsSuccess())
{
NintendoToken = System.Text.Encoding.Default.GetString(tokenByte, 0,(int)actualTokenSize);
}
5. 后臺查詢
后臺拿到客戶端傳的NintendoToken,先根據(jù)JWT協(xié)議校驗該token合法性,然后向Nintendo Server發(fā)送查詢用戶交易記錄查詢。
后臺查詢接口
GET /v1/applications/{applicationId}/accounts/{nsaId}/rights? status={status}&page={page}&per_page={per_page}
Authorization: Basic {base64(clientId:clientSecret)}
X-NINTENDO-NSA-ID-TOKEN: Bearer {nsaIdToken}

后臺通過status指定查詢交易的記錄是PURCHASED還是CONSUMED,其中:
- PURCHASED:新生成的交易記錄
- CONSUMED:已完成的交易記錄
后臺查詢結(jié)果
如果查詢成功,返回json結(jié)果:
{
"total_results": (Integer; the total number of rights matching the provided criteria),
"rights": [
{
"right_id": (String; Globally unique right ID),
"nsa_id": (String; NSA ID of user who holds the right),
"item_id": (String; the ID of the purchased item),
"purchased_date_time": (Long; Date and time (UTC) of transaction in UNIX epoch fomat),
"status": "(String; the status of the transaction; PURCHASED, CONSUMED",
"country": "(String; 2 letters (ISO 3166-1 Alpha-2); the country of the created right)"
}
]
}
其中:
-
rights
json數(shù)組,可能同時返回多筆交易記錄 -
right_id
外部訂單號,每筆交易記錄關(guān)聯(lián)的全局唯一id,可通過該id改變交易記錄狀態(tài)。 -
item_id
交易記錄關(guān)聯(lián)的商品id。
6. 發(fā)貨給用戶
后臺查到新的交易記錄后(status為PURCHASED),向當(dāng)前用戶發(fā)放交易記錄中指定的商品(item_id)。
7. 改變交易記錄狀態(tài)
只有當(dāng)交易記錄的狀態(tài)為CONSUMED時,才能標(biāo)識這筆交易的結(jié)束。因此,后臺還需要發(fā)送請求到Nintendo Server改變交易記錄的狀態(tài)。
PUT /v1/applications/{applicationId}/accounts/{nsaId}/rights
Authorization: Basic {base64(clientId:clientSecret)}
X-NINTENDO-NSA-ID-TOKEN: Bearer {nsaIdToken}
Content-Type:application/json
[
{
"right_id": "(String; Globally unique right ID)",
"status": "(String; the status of the transaction; PURCHASED, CONSUMED)"
}
]
如上所示,后臺通過put請求,通過right_id唯一關(guān)聯(lián)到Nintendo Server上的交易記錄,并將該交易記錄的status設(shè)置為CONSUMED,改變交易記錄狀態(tài)。
8. 回調(diào)游戲客戶端
游戲后臺將補(bǔ)發(fā)貨結(jié)果回調(diào)給游戲客戶端,至此,一次支付行為全部結(jié)束了。
Note:由于后臺流程是先查詢,再發(fā)貨,最后再改變記錄狀態(tài)。因此可能出現(xiàn):
后臺發(fā)貨給用戶后,但交易記錄狀態(tài)改變失敗了,導(dǎo)致下次依然能查到該已發(fā)貨的交易記錄。此時,需要游戲后臺維護(hù)交易記錄發(fā)貨狀態(tài)表,每次發(fā)貨前,判斷當(dāng)前交易記錄是否已發(fā)貨。如果已發(fā)貨,則直接請求Nintendo Server改變交易記錄狀態(tài)。