自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

出海支付實(shí)戰(zhàn):Google Play與Apple Store接入避坑指南

開發(fā) 項(xiàng)目管理
海外支付的接入涉及復(fù)雜的流程和細(xì)致的狀態(tài)管理,通過合理的系統(tǒng)設(shè)計(jì)和流程優(yōu)化,可以有效解決掉單和賬單對(duì)賬的問題,確保用戶權(quán)益得到保障。?

1. 引言

今天我們來聊聊錢,一個(gè)項(xiàng)目想要掙錢就離不開商業(yè)化,說白了就是讓用戶掏錢,所以,支付系統(tǒng)也是我們?cè)陧?xiàng)目開發(fā)中必不可少的一個(gè)關(guān)鍵模塊。

而在 APP 出海的征途上,海外支付堪稱"必渡之河"。

根據(jù) Statista 2024 數(shù)據(jù),Google Play 與 Apple Store 合計(jì)占據(jù)全球移動(dòng)應(yīng)用市場(chǎng) 83% 的營(yíng)收份額,其支付系統(tǒng)(IAP)如同支付寶與微信支付在國(guó)內(nèi)的地位。

本文聚焦于兩大主流平臺(tái)的接入實(shí)踐,解析跨境支付的特殊場(chǎng)景與解決方案,以及業(yè)務(wù)上可能遇到的一些坑。

2. 業(yè)務(wù)交互流程

支付系統(tǒng)的核心在于狀態(tài)機(jī)的精準(zhǔn)運(yùn)轉(zhuǎn),下圖展示典型交互鏈路:

圖片圖片

關(guān)鍵節(jié)點(diǎn)三要素:

  • 商品預(yù)配:提前在支付平臺(tái)創(chuàng)建商品ID并同步至業(yè)務(wù)數(shù)據(jù)庫(建議通過 Admin API 自動(dòng)化)
  • 支付憑證雙驗(yàn)證:客戶端獲取支付令牌后,需業(yè)務(wù)后臺(tái)二次驗(yàn)證(蘋果建議使用 AppStoreServerAPI)
  • 原始交易ID綁定:訂閱類訂單需持久化 original_transaction_id 作為續(xù)期憑證

由于業(yè)務(wù)需要不同的充值套餐和訂閱周期,所有我們還需要先提前在 Apple Store 及 Google Play 中配置商品,并且給商品創(chuàng)建一個(gè)唯一 ID,存儲(chǔ)在后臺(tái)數(shù)據(jù)庫中(這一步我們可以在運(yùn)營(yíng)后臺(tái)里調(diào)用 Apple Store 或者谷歌 Play 的接口,同時(shí)寫入到 DB)。

當(dāng)用戶想要獲取商品時(shí),客戶端首先到后臺(tái)拉取商品列表,然后用戶點(diǎn)擊充值/訂閱后,客戶端就帶著商品 ID 請(qǐng)求 Google Play/Apple Store 同時(shí)拉起支付頁面,當(dāng)用戶支付完成后,客戶端把產(chǎn)品ID、支付 Token、交易 ID 等信息傳入后臺(tái)并創(chuàng)建訂單。

需注意的是,原始交易 ID 可以管理訂閱訂單中的續(xù)訂狀態(tài),后臺(tái)需要存儲(chǔ)起來。

接著,業(yè)務(wù)后臺(tái)請(qǐng)求支付網(wǎng)關(guān)接口,來驗(yàn)證訂單的有效性,確認(rèn)無誤后開始下發(fā)用戶權(quán)益(如:充值后獲取 100 顆鉆石進(jìn)行主播打賞,或者成為尊貴的 VIP 用戶)。

3. 海外支付的要點(diǎn)及難點(diǎn)

一些背景

Google 和 Apple 未提供完整的流程和狀態(tài)支持文檔,中文資料亦不完整,因此我們以官方文檔為準(zhǔn),采用測(cè)試驅(qū)動(dòng)開發(fā)。

同時(shí),支付平臺(tái)服務(wù)端的接口支持較落后,我們盡量選用 SDK 進(jìn)行交互。由于 Google Play 和 Apple Store 的回調(diào)通知類型不一致,支付狀態(tài)設(shè)計(jì)成為難點(diǎn)。

支付狀態(tài)流轉(zhuǎn)

比如,Apple 訂閱的通知類型【NOTIFICATION_TYPE】分為以下幾種:

圖片圖片

Google 的通知類型包括:

● 續(xù)訂開始/續(xù)訂恢復(fù)

● 訂閱取消/續(xù)訂取消

● 訂閱下單

● 訂閱保留(相當(dāng)于停機(jī)保號(hào))

● 訂閱重新開始

● 訂閱到期

結(jié)合實(shí)際業(yè)務(wù),我們選用了都有的其中幾種支付狀態(tài),如:完成訂單、取消、續(xù)訂失敗、退訂、續(xù)訂成功等。

一次性商品的購買狀態(tài)扭轉(zhuǎn)比較簡(jiǎn)單:

圖片圖片

訂閱類商品更復(fù)雜一些:

圖片圖片

如上圖所示,在訂閱類支付時(shí)需要考慮用戶暫停/取消訂閱,也需要根據(jù)業(yè)務(wù)需要讓用戶自己覺得是否自動(dòng)續(xù)訂,自動(dòng)續(xù)訂時(shí)可能還要考慮用戶的賬戶余額是否充足等場(chǎng)景。

表結(jié)構(gòu)

商品表和訂單表記錄了業(yè)務(wù)中的商品列表和用戶購買狀態(tài)。商品表需提前在三方支付平臺(tái)上配置,訂單表記錄用戶購買的商品狀態(tài)和三方支付平臺(tái)的交易憑據(jù)。

商品表

以下是商品表的主要結(jié)構(gòu)(采用 Go 語言的結(jié)構(gòu)體形式展現(xiàn)):

type Product struct {
    ID                   uint           `gorm:"primaryKey NOT NULL AUTO_INCREMENT"`
    ProductId            string         `json:"product_id" gorm:"index:product_id_app_id_deleted_at;type:varchar(64) DEFAULT ''"`
    ProductType          int            `json:"product_type" gorm:"comment:商品類型,0.未知類型/1.消耗型購買/2.非消耗型購買/3.自動(dòng)訂閱/4.非自動(dòng)訂閱;type:tinyint(4) DEFAULT 0"`
    Name                 string         `json:"name" gorm:"comment:商品名稱;type:varchar(64) DEFAULT ''"`
    Description          string         `json:"description" gorm:"comment:商品描述;type:varchar(1024) DEFAULT ''"`
    Price                int            `json:"price" gorm:"comment:商品價(jià)格,精度2位小數(shù),用100倍存儲(chǔ);type:bigint DEFAULT 0"`
    TokenType            int            `json:"token_type" gorm:"comment:虛擬幣類型,0.鉆石;1.金幣;2.元寶;3.其它;type:tinyint(4) DEFAULT 0"`
    TokenQuantity        int            `json:"token_quantity" gorm:"comment:虛擬幣數(shù)量;type:int(11) DEFAULT 0"`
    SubscribeDurationDay int            `json:"subscribe_duration_day" gorm:"comment:會(huì)員訂閱時(shí)長(zhǎng)(天);type:int(11) DEFAULT 0"`
    Weight               int            `json:"weight" gorm:"comment:權(quán)重,排序時(shí)從大到小,客戶端根據(jù)此字段進(jìn)行商品排序;type:int(11) DEFAULT 0"`
    ImageURL             string         `json:"image_url" gorm:"comment:商品圖片URL;type:varchar(1024) DEFAULT ''"`
    IsAutoSubscribe      int            `json:"is_auto_subscribe" gorm:"comment:是否是自動(dòng)續(xù)費(fèi),0.未知/1.自動(dòng)續(xù)費(fèi)/2.非自動(dòng)續(xù)費(fèi);type:tinyint(2) DEFAULT 0"`
    Platform             int            `json:"platform" gorm:"comment:支付平臺(tái), 0-海外,1-微信支付,2-國(guó)內(nèi)支付渠道;type:tinyint(2) DEFAULT 0"`
}

商品表主要是記錄業(yè)務(wù)中的商品列表,需要提前在三方支付平臺(tái)上進(jìn)行配置,下單時(shí)客戶端需帶著商品 ID 請(qǐng)求后臺(tái)服務(wù)器。

訂單表

訂單表的定義如下所示(采用 Go 語言的結(jié)構(gòu)體形式展現(xiàn)):

type Order struct {
    ID                    uint           `gorm:"primaryKey NOT NULL AUTO_INCREMENT"`
    OrderId               string         `json:"order_id" gorm:"index:order_id_deleted_at;type:varchar(64) DEFAULT ''"`
    ProductId             string         `json:"product_id" gorm:"index:user_uuid_app_product_id_deleted_at;type:varchar(64) DEFAULT ''"`
    TransactionId         string         `json:"transaction_id" gorm:"comment:交易ID,訂閱/續(xù)訂時(shí)使用;type:varchar(64) DEFAULT ''"`
    OriginalTransactionId string         `json:"original_transaction_id" gorm:"comment:原始交易ID,訂閱/續(xù)訂時(shí)該ID一致;type:varchar(64) DEFAULT ''"`
    UserUuid              string         `json:"user_uuid" gorm:"index:user_uuid_app_product_id_deleted_at;comment:用戶的UUID;type:varchar(64) DEFAULT ''"`
    PayChannel            int            `json:"pay_channel" gorm:"comment:支付渠道,0/1/2,GooglePay/ApplePay/PayPal;type:tinyint DEFAULT 0"`
    PaymentState          int            `json:"payment_state" gorm:"comment:支付狀態(tài),-1:處理中 0:初始化 1:已完成 2 取消 3 續(xù)訂失敗 4 退款 5 續(xù)訂成功;type:tinyint DEFAULT 0"`
    RefundTime            string         `json:"refund_time" gorm:"comment:退款時(shí)間;type:varchar(32) DEFAULT ''"`
}

訂單主要記錄用戶購買的商品狀態(tài),比如權(quán)益下發(fā)到哪一步了,續(xù)訂套餐是否在續(xù)費(fèi)狀態(tài),以及三方支付平臺(tái)的一些交易憑據(jù)(如交易ID)等。

5. 常見問題

1)如何防止掉單

在支付系統(tǒng)中,最重要的是用戶權(quán)益。很多時(shí)候用戶明明已經(jīng)下單并且付錢了,但是 VIP 沒有充上,鉆石沒有到賬,是用戶無法接受的。

一個(gè)很常見的 Case 是:用戶付錢后,斷開網(wǎng)絡(luò)連接,這時(shí)后臺(tái)系統(tǒng)沒有收到消息,該怎么處理?

這里我們做了兩步來保證:

  1. 客戶端補(bǔ)償策略:采用本地事務(wù)日志+斷點(diǎn)續(xù)傳設(shè)計(jì)??蛻舳嗽趧澷~請(qǐng)求的 ACK 之前先調(diào)用后臺(tái)接口生成訂單,如果用戶在支付后突然斷網(wǎng),重新打開客戶端后會(huì)檢查當(dāng)前是否存在未確認(rèn)的劃賬請(qǐng)求,如果有就再調(diào)用一次后臺(tái)訂單再 ACK。同時(shí)后臺(tái)通過冪等性來保證用戶不會(huì)多次支付同一筆訂單;
  2. 業(yè)務(wù)系統(tǒng)雙保險(xiǎn)告警處理:業(yè)務(wù)平臺(tái)接收到支付網(wǎng)關(guān)回調(diào)時(shí),發(fā)現(xiàn)已有訂單就更新訂單狀態(tài);沒有訂單就發(fā)告警,進(jìn)行人工處理;

2)如何保證賬單和訂單正確性

在傳統(tǒng)的公司交易中,都會(huì)需要會(huì)計(jì)來對(duì)賬,將每月的賬單和收支金額總額對(duì)比,防止出現(xiàn)賬不對(duì)錢的壞賬。

所以,一方面為了保證訂單的有序性,我們?cè)跇I(yè)務(wù)系統(tǒng)禁止隨意扭轉(zhuǎn)訂單狀態(tài);另一方面我們?cè)谥Ц毒W(wǎng)關(guān)進(jìn)行每天的定時(shí)對(duì)賬:

  • 狀態(tài)機(jī)檢查裝置:每次觸發(fā)業(yè)務(wù)回調(diào)時(shí),業(yè)務(wù)后臺(tái)都會(huì)判斷數(shù)據(jù)庫狀態(tài)和支付平臺(tái)的后臺(tái)狀態(tài)一致性,若是不一致,則判斷狀態(tài)是否可以扭轉(zhuǎn),若是不能扭轉(zhuǎn)則告警出來;若是可以扭轉(zhuǎn)則更新 DB 里訂單的狀態(tài);
  • 服務(wù)端哨兵系統(tǒng):每小時(shí)掃描未完結(jié)訂單與支付平臺(tái)對(duì)賬。支付網(wǎng)關(guān)每天定時(shí)比較昨日數(shù)據(jù)庫和支付平臺(tái)后臺(tái)的交易狀態(tài)差異,有差錯(cuò)的部分進(jìn)行告警。

6. 小結(jié)

海外支付的接入涉及復(fù)雜的流程和細(xì)致的狀態(tài)管理,通過合理的系統(tǒng)設(shè)計(jì)和流程優(yōu)化,可以有效解決掉單和賬單對(duì)賬的問題,確保用戶權(quán)益得到保障。

責(zé)任編輯:武曉燕 來源: xin猿意碼
相關(guān)推薦

2018-08-29 07:52:20

Google Play支付購物

2020-08-26 07:37:25

Nacos微服務(wù)SpringBoot

2014-07-30 12:56:56

2013-07-29 11:23:46

信息圖App StoreGoogle Play

2014-07-04 16:47:57

Google PlayAndroid Wea

2024-04-24 13:45:00

2024-04-03 12:30:00

C++開發(fā)

2021-02-26 00:46:11

CIO數(shù)據(jù)決策數(shù)字化轉(zhuǎn)型

2023-11-01 15:32:58

2021-02-22 17:00:31

Service Mes微服務(wù)開發(fā)

2021-05-08 12:30:03

Pythonexe代碼

2023-05-24 10:06:42

多云實(shí)踐避坑

2021-05-07 21:53:44

Python 程序pyinstaller

2022-03-04 18:11:16

信服云

2013-08-01 10:22:28

Google Play應(yīng)用商店App Store

2024-08-26 08:29:55

2023-11-17 18:17:33

微信支付V3版本

2021-04-28 09:26:25

公有云DTS工具

2012-06-27 16:57:12

App StoreGoogle Play

2020-12-16 10:00:59

Serverless數(shù)字化云原生
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)