360SDK網游支付服務

2018-10-10 10:05 更新

1.流程介紹


                                             

blob.png

    1.   應用調用應用服務器進行下單;

    2.   應用調用360SDK支付接口;

    3.   360SDK展示支付頁面,引導用戶完成支付流程;

        a.   若調用接口時指定金額,則顯示固定金額支付界面;

        b.   若調用接口時不指定金額,則顯示不固定金額的支付界面;

    4.   支付結束或退出360SDK支付客戶端界面后,360SDK客戶端會返回支付結果給應用客戶端的支付模塊;

    5.   支付成功后,360服務器回調應用服務器上的通知接口,通知支付結果;

    6.   (應用服務器調用360服務器端訂單確認接口,驗證支付通知的合法性;


2.接口介紹


2.1 支付接口【客戶端調用】(必接)

功能說明:

    應用調用360SDK支付接口時,360SDK彈出支付選擇界面。用戶在界面上完成支付。

    關于應用方訂單號的問題:應用方需要生成自己的訂單號app_order_id,應用訂單號不能重復提交,并且一個應用訂單不管是否支付成功,都只能支付一次。這樣做是為了避免重復支付。通知應用方加錢時,會返回應用訂單號同時提供360訂單號。

    Access token由于與當前登錄用戶id綁定,因此可以加強支付安全性。但要注意token的時間期限(有效期為10小時)。過期后調用支付接口會失敗。游戲可以引導用戶重新登錄.

接口示例:

注意:

    1. 必選參數不能為空不能為0,否則支付失敗。

    2. 參數名,以ProtocolKeys中定義的常量為準。

    /**
     * 使用360SDK的支付接口
     *
     * @param isLandScape 是否橫屏顯示支付界面
     * @param isFixed 是否定額支付
     */
protected void doSdkPay(final boolean isLandScape, final boolean isFixed) {
 
        if(!isAccessTokenValid) {
            Toast.makeText(SdkUserBaseActivity.this, R.string.access_token_invalid, Toast.LENGTH_SHORT).show();
            return;
        }
        if(!isQTValid) {
            Toast.makeText(SdkUserBaseActivity.this, R.string.qt_invalid, Toast.LENGTH_SHORT).show();
            return;
        }
 
        // 支付基礎參數
        Intent intent = getPayIntent(isLandScape, isFixed);
 
        // 必需參數,使用360SDK的支付模塊。
        intent.putExtra(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_PAY);
 
        // 可選參數,登錄界面的背景圖片路徑,必須是本地圖片路徑
        intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTRUE, "");
 
        Matrix.invokeActivity(this, intent, mPayCallback);
    }
 
    /**
     * 生成調用360SDK支付接口基礎參數的Intent
     *
     * @param isLandScape 是否橫屏顯示登錄界面
     * @param isFixed     是否定額支付
     *
     * @return Intent
     */
    protected Intent getPayIntent(boolean isLandScape, boolean isFixed) {
 
        Bundle bundle = new Bundle();
 
        QihooPayInfo pay = getQihooPayInfo(isFixed);
 
        // 界面相關參數,360SDK界面是否以橫屏顯示。
        bundle.putBoolean(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape);
 
        // 可選參數,登錄界面的背景圖片路徑,必須是本地圖片路徑
        bundle.putString(ProtocolKeys.UI_BACKGROUND_PICTRUE, "");
 
        // *** 以下非界面相關參數 ***
        // 設置QihooPay中的參數。
        // 必需參數,用戶access token,要使用注意過期和刷新問題,最大64字符。
        bundle.putString(ProtocolKeys.ACCESS_TOKEN, pay.getAccessToken());
 
        // 必需參數,360賬號id。
        bundle.putString(ProtocolKeys.QIHOO_USER_ID, pay.getQihooUserId());
 
        // 必需參數,所購買商品金額, 以分為單位。金額大于等于100分,360SDK運行定額支付流程; 金額數為0,360SDK運行不定額支付流程。
        bundle.putString(ProtocolKeys.AMOUNT, pay.getMoneyAmount());
 
        // 必需參數,所購買商品名稱,應用指定,建議中文,最大10個中文字。
        bundle.putString(ProtocolKeys.PRODUCT_NAME, pay.getProductName());
 
        // 必需參數,購買商品的商品id,應用指定,最大16字符。
        bundle.putString(ProtocolKeys.PRODUCT_ID, pay.getProductId());
 
        // 必需參數,應用方提供的支付結果通知uri,最大255字符。360服務器將把支付接口回調給該uri,具體協議請查看文檔中,支付結果通知接口–應用服務器提供接口。
        bundle.putString(ProtocolKeys.NOTIFY_URI, pay.getNotifyUri());
 
        // 必需參數,游戲或應用名稱,最大16中文字。
        bundle.putString(ProtocolKeys.APP_NAME, pay.getAppName());
 
        // 必需參數,應用內的用戶名,如游戲角色名。 若應用內綁定360賬號和應用賬號,則可用360用戶名,最大16中文字。(充值不分區(qū)服,充到統一的用戶賬戶,各區(qū)服角色均可使用)。
        bundle.putString(ProtocolKeys.APP_USER_NAME, pay.getAppUserName());
 
        // 必需參數,應用內的用戶id。
        // 若應用內綁定360賬號和應用賬號,充值不分區(qū)服,充到統一的用戶賬戶,各區(qū)服角色均可使用,則可用360用戶ID最大32字符。
        bundle.putString(ProtocolKeys.APP_USER_ID, pay.getAppUserId());
 
        // 必需參數,應用訂單號,應用內必須唯一,最大32字符。
        bundle.putString(ProtocolKeys.APP_ORDER_ID, pay.getAppOrderId());
 
        // 可選參數,應用擴展信息1,原樣返回,最大255字符。
        bundle.putString(ProtocolKeys.APP_EXT_1, pay.getAppExt1());
 
        // 可選參數,應用擴展信息2,原樣返回,最大255字符。
        bundle.putString(ProtocolKeys.APP_EXT_2, pay.getAppExt2());
 
        Intent intent = new Intent(this, ContainerActivity.class);
        intent.putExtras(bundle);
 
        return intent;
    }


callback的 json數據格式:

成功返回

{error_code: 0, error_msg: "支付成功", content:""}

失敗返回

{error_code: 1, error_msg: "支付失敗", content:""}

取消返回

{error_code: -1, error_msg: "支付取消", content:""}

支付正在進行

{error_code: -2, error_msg: "正在進行", content:""}

access_token失效

{error_code: 4010201, error_msg: "token已失效", content:""}

QT失效

{error_code: 4009911, error_msg: "登錄已失效", content:""}


callback示例:

  /**
     * 支付的回調
     */
    protected IDispatcherCallback mPayCallback = new IDispatcherCallback() {
 
        @Override
        public void onFinished(String data) {
            Log.d(TAG, "mPayCallback, data is " + data);
            if(TextUtils.isEmpty(data)) {
                return;
            }
 
            boolean isCallbackParseOk = false;
            JSONObject jsonRes;
            try {
                jsonRes = new JSONObject(data);
                // error_code 狀態(tài)碼: 0 支付成功, -1 支付取消, 1 支付失敗, -2 支付進行中。
                // error_msg 狀態(tài)描述
                int errorCode = jsonRes.optInt("error_code");
                isCallbackParseOk = true;
                switch (errorCode) {
                    case 0:
                    case 1:
                    case -1:
                    case -2: {
                        isAccessTokenValid = true;
                        String errorMsg = jsonRes.optString("error_msg");
                        String text = getString(R.string.pay_callback_toast, errorCode, errorMsg);
                        Toast.makeText(SdkUserBaseActivity.this, text, Toast.LENGTH_SHORT).show();
 
                    }
                        break;
                    case 4010201:
                        isAccessTokenValid = false;
                        Toast.makeText(SdkUserBaseActivity.this, R.string.access_token_invalid, Toast.LENGTH_SHORT).show();
                        break;
                    case 4009911:
                        //QT失效
                        isQTValid = false;
                        Toast.makeText(SdkUserBaseActivity.this, R.string.qt_invalid, Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
 
            // 用于測試數據格式是否異常。
            if (!isCallbackParseOk) {
                Toast.makeText(SdkUserBaseActivity.this, getString(R.string.data_format_error),
                        Toast.LENGTH_LONG).show();
            }
        }
    };


2.2 支付結果通知接口–應用服務器提供接口, 由360服務器回調(必接)

    應用客戶端調用支付接口時, 需指定支付結果的通知回調地址notify_uri. 支付完成后, 360服務器會把支付結果以GET方式通知到此地址 (建議應用服務端接口同時支持GET和POST). 應用接收驗證參數后, 給用戶做游戲內充值.

    應用服務端通知接口在接收到通知消息后, 需回應ok(僅返回小寫ok這兩個字母,不要有其它輸出), 表示通知已經接收. 如果回應其他值或者不回應, 則被認為通知失敗, 360會嘗試多次通知. 這個機制用來避免掉單。

    應用應做好接收到多次通知的準備, 防止多次加錢. 同時, 需要特別注意的是, 回應的ok表示應用已經正常接到消息, 無需繼續(xù)發(fā)送通知. 它不表示訂單成功與否, 或者應用處理成功與否. 對于重復的通知, 應用可能發(fā)現訂單已經成功處理完畢, 無需繼續(xù)處理, 也要返回ok(僅返回小寫ok這兩個字母,不要有其它輸出). 否則, 360會認為未成功通知, 會繼續(xù)發(fā)送通知.

    支付結果通知的參數如下:

參數

必選

參數類型

最大長度

參數說明

是否參與簽名

app_key

Y

varchar

32

應用app key

Y

product_id

Y

varchar

36

應用自定義的商品id

Y

amount

Y

int unsigned

11

總價,以分為單位

Y

app_uid

Y

varchar

50

應用分配給用戶的id

Y

app_ext1

N

varchar

255

應用擴展信息1原樣返回

Y

app_ext2

N

varchar

255

應用擴展信息2原樣返回

Y

user_id

Y

bigint unsigned

20

360賬號id

Y

order_id

Y

bigint unsigned

20

360返回的支付訂單號

Y

gateway_flag

Y

varchar

16

如果支付返回成功,返回success

應用需要確認是success才給用戶加錢

Y

sign_type

Y

varchar

8

定值 md5

Y

app_order_id

N

varchar

64

應用訂單號

支付請求時傳遞,原樣返回

Y

sign_return

Y

varchar

32

應用回傳給訂單核實接口的參數

不加入簽名校驗計算

N

sign

Y

varchar

32

簽名

N

    應用接收到支付平臺回調的請求,參見附錄的簽名算法對參數進行簽名,然后和平臺傳遞的簽名sign比較,從而校驗平臺請求的合法性.

    通知消息樣例:

order_id=1211090012345678901&app_key=1234567890abcdefghijklmnopqrstuv&product_id=p1&amount=101&app_uid=123456789&app_ext1=XXX201211091985&app_order_id=order1234&user_id=987654321&sign_type=md5&gateway_flag=success&sign=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&sign_return=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

樣例的簽名字段排列 (列出來僅供參考, 請根據實際參數情況用程序排序產生, 不要寫死在程序里)

amount, app_ext1, app_key, app_order_id, app_uid, gateway_flag, order_id, product_id, sign_type, user_id


樣例的簽名串

101#XXX201211091985#1234567890abcdefghijklmnopqrstuv#order1234#123456789#success#1211090012345678901#p1#md5#987654321#
應用
app_secret


2.3 訂單核實接口– 服務器端接口應用服務器調用(選接)

1. 驗證接口地址為: http://mgame.#/pay/order_verify.json

2. 為了安全起見,驗證參數不需要傳client_id,client_secret參數,如果傳了服務端會報錯

3. 需要計算簽名

 

    為了防止偽造的支付成功通知應用可以使用本接口做通知數據的校驗.支付結果通知接口(4.2.2節(jié))收到的通知消息里的參數計算簽名后調用接口即可校驗數據是否正確.

 

接口地址:

    http://mgame.#/pay/order_verify.json?參數


參數說明:

blob.png

blob.png


參數均來自應用加錢接口收到的支付通知消息原樣提供即可。

 

如果參數提供正確訂單核實接口返回為json格式數據.

 

驗證成功返回

{"ret":"verified"}

驗證不成功返回

{"ret":"{錯誤信息}"}

 

返回結果中可能的錯誤信息包括

blob.png

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號