2014-08-29 67 views
1

我使用json_decode函數來解碼(並驗證從支付處理器發回)。 JSON對象收到看起來遵循json_decode保存類型

{ 
    "notification":{ 
     "version":6.0, 
     "attemptCount":0, 
     "role":"VENDOR", 
     ..... 
     "lineItems":[ 
     { 
      "itemNo":"1", 
      "productTitle":"A passed in title", 
      "shippable":false, 
      "recurring":false, 
      "customerProductAmount":1.00, 
      "customerTaxAmount":0.00 
     } 
     ] 
    }, 
    "verification":"9F6E504D" 
} 

驗證的工作原理如下,一個需要通知的節點,並附加密鑰。此字符串的SHA1哈希的前八個字符應與驗證節點的內容匹配。

但是,我注意到,雖然使用json_decode,雙值6.0,0.00等被截斷爲整數(6,0等)。這擾亂了字符串(無法生成正確的SHA1哈希)。請注意,我不能使用深度限制來防止解碼通知分支,因爲我需要支持PHP 5.0。我該如何解決這個問題。我寫的(缺陷)驗證碼:

public function IPN_Check(){ 
    $o = (json_decode($this->test_ipn)); 
    $validation_string = json_encode($o->notification); 
    } 
+0

是否有任何理由爲什麼你需要'6.0'反對到'6'? – 2014-08-29 13:08:42

+0

我不認爲有任何內置函數直接在JSON(或JSON字符串)中將double轉換爲int。恐怕你必須解碼你的JSON,解析數組來將double轉換爲有關值上的整數,然後將其重新編碼爲JSON以便稍後匹配你的哈希檢查。 – Sugar 2014-08-29 13:11:00

+0

6給出了一個不同於驗證的SHA1哈希值,比6.0 – 2014-08-29 13:11:58

回答

1

我試過如下:

<?php 

var_dump(json_decode(' 
{ 
    "notification":{ 
     "version":6.0, 
     "attemptCount":0 
    } 
} 
')); 

,並得到這樣的輸出:

object(stdClass)#1 (1) { 
    ["notification"]=> 
    object(stdClass)#2 (2) { 
    ["version"]=> 
    float(6) 
    ["attemptCount"]=> 
    int(0) 
    } 
} 

PHP確實讓float和INT之間的差異,也許你可以做一些像gettype($o->notification[$i]) == 'float'這樣的事情來檢查你是否需要使用字符串來添加一個零。

+0

儘管正常序列化是在PHP中存儲數據類型的優先方式。 Serialize是PHP特定的,並不輸出json(據我所知)。我特別需要輸出到json中來生成哈希。 – 2014-08-29 13:10:54

+0

更改了答案 – 2014-08-29 13:38:27

0

看起來像ClickBank,他們總是以相同的格式發送它,只有兩個頂級域「通知」和「驗證」。所以,你可以只使用substr從生JSON去除前16個字符({"notification":)和最後27個字符(,"verification":"XXXXXXXX"}),然後繼續從那裏:

$notification = substr($json, 16, -27); 
$verification = strtoupper(substr(hash('sha1', $notification . $secret), 0, 8));