用Node.js開通微信支付功能

最新接收了微信公眾號開發(fā)的任務再扭,也是第一次接觸node.js,不過這一篇我暫時先不說node.js的使用蹂窖,由于接通微信支付的確是花費了我好多時間和精力虑省,為了下次能夠快速接通當然也和大家分享一下赌躺,特以此文記錄一下逾滥。

一.首先在微信公眾號后臺

設置 -- > 公眾號設置 --> 功能設置 -- > 網(wǎng)頁授權域名 (填寫微信公眾號菜單跳轉 到 自己的網(wǎng)站的域名 例如wx.mingrivr.com)

其中
設置 -- > 公眾號設置 --> 功能設置 -- > 業(yè)務域名 (最好也設置一下烘贴,這樣如果你的網(wǎng)站需要輸入的時候就不會出現(xiàn)紅色的提示框提示謹慎輸入的字樣)

另外切換到
微信支付 --> 開發(fā)配置 (將支付授權目錄精確到你要發(fā)起支付的請求界面的url地址禁添,并以“/” 結束)
然后添加測試的白名單
將測試的微信號添加上去

二.回到程序中來

支付流程:
選擇充值的金額之后 --> 告訴自家服務器 生成一個訂單號返回 --> 微信支付 --> 支付成功、失敗之后回調(diào) --> 告訴自家服務器 余額中充值 并返回結果 -- > 如果成功 結束 桨踪;不成功 微信原路退款

在node.js 工程中上荡,建議建立一個json文件存放關于wxpay配置的相關信息

{  
  "wxAppId" : "", // 公眾號后臺 開發(fā) --> 基本配置  中可以看到
  "wxAppSecret" : "",// 公眾號后臺 開發(fā) --> 基本配置  中可以看到
  "wxMchId" : "", // 支付商戶的id
  "wxPayKey" : ""http:// 支付商戶的密鑰
}

調(diào)起微信支付的時候主要就是下面一個方法

WeixinJSBridge.invoke(    'getBrandWCPayRequest',
 { 
  "appId" :paramObj.appId,     //公眾號名稱,由商戶傳入       
  "timeStamp":paramObj.timeStamp,         //時間戳馒闷,自1970年以來的秒數(shù)        
  "nonceStr" :paramObj.nonceStr, //隨機串        "package":paramObj.package,        
  "signType":paramObj.signType, //微信簽名方式:        
  "paySign":paramObj.paySign //微信簽名  
  }, 
 function(res){      
  if(res.err_msg == "get_brand_wcpay_request:ok" ) { 
        //支付成功的回調(diào) 微信團隊說不一定準確 哈哈哈
    }       
 if(res.err_msg == "get_brand_wcpay_request:cancel" || res.err_msg == "get_brand_wcpay_request:fail"){    
       //微信支付失敗或者取消的回調(diào)
     }   
 });

其實在你需要調(diào)起微信支付的頁面的js里面添加這個方法就能調(diào)起微信支付酪捡,重點來啦,你看到需要傳的參數(shù)了么纳账?雖然只有五個參數(shù)逛薇,但是步驟還真是不少?一起來看看吧疏虫!

一般為了安全起見永罚,獲取這些個參數(shù)放在后臺,我的程序中也就是node.js負責的這部分卧秘。也就是說客戶端發(fā)起一個請求的時候我在route中通知自家服務端呢袱,然后發(fā)起微信請求,獲取所需的參數(shù)之后傳回到客戶端發(fā)起微信支付翅敌,收到微信支付回調(diào)信息之后再發(fā)起請求告訴自家服務器支付結果羞福。

看一下node.js中關于微信支付的代碼吧

第一步.獲取code

請求 code 的目的就是獲取用戶的 openid(用戶相對于當前公眾號的唯一標識) 和access_token,請求的 API
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

1.  appid公眾號的 appid蚯涮,可以在公眾號中看到
2.  redirect_uri 自定義的微信回調(diào)地址治专, 微信會在你請求完上面的地址后跳轉到你定義的redirect_uri的地址卖陵, 帶著 code,此處的 redirect_url 需要 **url_encode** *php*张峰, 如果你的程序是 node 則需要使用 **encodeURLComponent(url)**編碼
3.  response_type=code泪蔫,這個沒什么好說的就是固定的
4.  scope=snsapi_userinfo,也可以選擇snsapi_base 就不會出現(xiàn)綠色的授權界面
5.  state=STATE 固定這樣寫就好喘批,詳細說明可以查看微信官網(wǎng)的說明
6.  wechat_redirect 固定這樣寫就好撩荣,詳細說明可以查看微信官網(wǎng)的說明
第二步.獲取access_token openid

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

1.  appid 微信公眾號 id,微信公眾號后臺獲取
2.  secret 微信公眾號的密鑰饶深, 微信公眾號后臺獲取
3.  code婿滓, 第一步獲取用到的 code
4.  grant_type=authorization_code 固定就好
第三步.先把需要獲取的簡單的幾個參數(shù)的方法展示一下

獲取隨機的NonceStr

voucherControl.createNonceStr = function(){   
 return Math.random().toString(36).substr(2, 15);
};
第四步.獲取prepay_id
voucherControl.getPrepayId = function(obj){ 
  // 生成統(tǒng)一下單接口參數(shù)   
 var UnifiedorderParams = {      
   appid : wxConfig.wxAppId,       
   body : obj.body,       
   mch_id : wxConfig.wxMchId,        
   nonce_str: voucherControl.createNonceStr(),       
   notify_url : obj.notify_url,// 微信付款后的回調(diào)地址       
   openid : openid,        
   out_trade_no : obj.out_trade_no,//new Date().getTime(), //訂單號                  
  spbill_create_ip : obj.spbill_create_ip,       
   total_fee : obj.total_fee,       
   trade_type : 'JSAPI',   
 };   
 // 返回 promise 對象    
return  new Promise(function (resolve, reject) {       
 // 獲取 sign 參數(shù)      
  UnifiedorderParams.sign = voucherControl.getSign(UnifiedorderParams);        
var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';       
 request.post(
{
url : url,
body:JSON.stringify(voucherControl.getUnifiedorderXmlParams(UnifiedorderParams))
},
 function (error, response, body) {                   
 var prepay_id = '';           
 if (!error && response.statusCode == 200) {              
 // 微信返回的數(shù)據(jù)為 xml 格式, 需要裝換為 json 數(shù)據(jù)粥喜, 便于使用            
xml2jsparseString(body, {async:true}, function (error, result) {  
prepay_id = result.xml.prepay_id[0];                
    // 放回數(shù)組的第一個元素                   
 resolve(prepay_id);               
 });           
 } else {         
       reject(body);            
}       
 });   
 })}
第五步.獲取sign

獲取微信支付的簽名

voucherControl.getSign = function(signParams){   
 // 按 key 值的ascll 排序   
  var keys = Object.keys(signParams);   
 keys = keys.sort();    
var newArgs = {};    
keys.forEach(function (val, key) {  
      if (signParams[val]){       
     newArgs[val] = signParams[val];     
   }  
  })    
var string = queryString.stringify(newArgs)+'&key='+wxConfig.wxPayKey;    
return crypto.createHash('md5').update(queryString.unescape(string), 'utf8').digest("hex").toUpperCase();
}
第六步.獲取將json數(shù)據(jù)變?yōu)閤ml數(shù)據(jù)(因為微信統(tǒng)一下單的時候body中傳數(shù)據(jù)必須為xml數(shù)據(jù))

獲取微信統(tǒng)一下單參數(shù)

voucherControl.getUnifiedorderXmlParams = function(obj){   
 var body = '<xml>' + 
  '<appid>'+wxConfig.wxAppId+'</appid>' +     
  '<body>'+obj.body+'</body>' +      
  '<mch_id>'+wxConfig.wxMchId+'</mch_id>' +            
  '<nonce_str>'+obj.nonce_str+'</nonce_str>' +          
  '<notify_url>'+obj.notify_url+'</notify_url>' +      
  '<openid>'+obj.openid+'</openid>' +          
  '<out_trade_no>'+obj.out_trade_no+'</out_trade_no>'+        
  '<spbill_create_ip>'+obj.spbill_create_ip+'</spbill_create_ip>' +          
  '<total_fee>'+obj.total_fee+'</total_fee>' +        
  '<trade_type>'+obj.trade_type+'</trade_type>' +     
  '<sign>'+obj.sign+'</sign>' +      
  '</xml>';   
 return body;
}
第七步.獲取微信支付的所有參數(shù)

微信支付的所有參數(shù) *
@param req 請求的資源, 獲取必要的數(shù)據(jù) *
@returns {{
appId: string,
timeStamp: Number,
nonceStr: *,
package: string,
signType: string,
paySign: *}}

voucherControl.getBrandWCPayParams = function(obj,callback ){  
  var prepay_id_promise = voucherControl.getPrepayId(obj);   
  prepay_id_promise.then(function (prepay_id) {     
  var prepay_id = prepay_id;        
  var wcPayParams = {            
    "appId" : wxConfig.wxAppId,     //公眾號名稱凸主,由商戶傳入           
    "timeStamp" : parseInt(new Date().getTime() / 1000).toString(), //時間戳,自1970年以來的秒數(shù)          
    "nonceStr" : voucherControl.createNonceStr(), //隨機串            // 通過統(tǒng)一下單接口獲取           
    "package" : "prepay_id="+prepay_id,           
    "signType" : "MD5",         //微信簽名方式:        };       
   wcPayParams.paySign = voucherControl.getSign(wcPayParams); //微信支付簽名         
      callback(null, wcPayParams);   
   },function (error) {       
      callback(error);    
  });
}
第八步.將微信支付取得的參數(shù)傳回客戶端去調(diào)用微信支付吧
voucherControl.getBrandWCPayParams(obj, function (error, responseData) {   
 if (error) {       
   callback(error);   
 } else {            
   callback(null, responseData);   
 }
});
第九步.支付完成的回調(diào)

微信支付完了后會在 h5 頁面的微信支付的回調(diào)函數(shù)里面放回值额湘,res.err_msg == "get_brand_wcpay_request:ok" 卿吐,這樣就是成功了, 但是不是就完事兒了呢 锋华? 也不是嗡官,為什么呢? 微信真的收到錢了么毯焕? 收到的錢是不是你傳遞給微信的值呢 衍腥?你還需要將支付的結果寫數(shù)據(jù)庫什么的,這些都是未知纳猫。還記的在統(tǒng)一下單接口中有個必須參數(shù)就是notify_url : NOTIFY_URL,// 微信付款后的回調(diào)地址
這個地址是用戶傳遞給微信的婆咸, 微信在收到用戶的付款后會以 post 的方式請求這個接口,微信會傳遞用戶付款的信息過來芜辕, 不過是 xml 格式的尚骄。類系這樣的 xml 格式:

<xml>
 <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
 <attach><![CDATA[支付測試]]></attach>
 <bank_type><![CDATA[CFT]]></bank_type> 
<fee_type><![CDATA[CNY]]></fee_type> 
<is_subscribe><![CDATA[Y]]></is_subscribe>
 <mch_id><![CDATA[10000100]]></mch_id> 
<nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str> 
<openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid> <out_trade_no><![CDATA[1409811653]]></out_trade_no> 
<result_code><![CDATA[SUCCESS]]></result_code>
 <return_code><![CDATA[SUCCESS]]></return_code> 
<sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign> <sub_mch_id><![CDATA[10000100]]></sub_mch_id> 
<time_end><![CDATA[20140903131540]]></time_end>
 <total_fee>1</total_fee> 
<trade_type><![CDATA[JSAPI]]></trade_type> 
<transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id></xml>

根據(jù)自己的業(yè)務邏輯解析這個 xml 格式的數(shù)據(jù)就好了。注意:這里你在獲取到數(shù)據(jù)后微信需要得到你的回應侵续, 如果你一直不回應微信倔丈, 微信會請求你好幾次, 這樣估計你的邏輯會有問題吧状蜗,所以你需要給微信返回 xml 的格式的 回應需五。

<xml> 
<return_code><![CDATA[SUCCESS]]></return_code>
 <return_msg><![CDATA[OK]]></return_msg>
</xml>
注意點:node ,express 框架開發(fā)轧坎, 如果你在微信的支付成功后的回調(diào)中沒有獲取到任何 xml 的值

你需要安裝一組件:body-parser-xml宏邮, 你可以使用 npm install body-parser-xml --save
安裝, 在 app.js 里面 require('body-parser-xml')(bodyParser);
,使用中間件的方式
// 解決微信支付通知回調(diào)數(shù)據(jù)

app.use(bodyParser.xml({
 limit: '2MB', // Reject payload bigger than 1 MB 
xmlParseOptions: { normalize: true, // Trim whitespace inside text nodes normalizeTags: true, // Transform tags to lowercase 
explicitArray: false // Only put nodes in array if >1
 }
}));

這樣你就可以正常的獲取到微信的 xml 數(shù)據(jù)了。

pay.getAccessToken({
    notify_url : 'http://demo.com/', //微信支付完成后的回調(diào) 
    out_trade_no : new Date().getTime(), //訂單號 
    attach : '名稱', body : '購買信息',
    total_fee : '1', // 此處的額度為分
    spbill_create_ip : req.connection.remoteAddress,
 }, function (error, responseData) {
     res.render('payment', { title : '微信支付',
     wxPayParams : JSON.stringify(responseData)
 }); 
});
最后我將node.js關于微信支付的代碼封裝成一個js

使用方法見js中的 useWxPay 方法蜀铲,將所需參數(shù)傳入就會得到微信下單的所有參數(shù)

/**
 * Created by haHa on 2016/11/21.
 * 微信支付的js文件
 */

var wxPayControl = module.exports;
var request = require("request");
var url = require('url');
var queryString = require('querystring');
var crypto = require('crypto');
var xml2jsparseString = require('xml2js').parseString;
var wxConfig = require('../z_configs/wxconfig.json');
/*
{
    "wxAppId" : "",//公眾號appid
    "wxAppSecret" : "",//公眾號appsecrect
    "wxMchId" : "",//商戶id
    "wxPayKey" : ""http://商戶密鑰
}
*/

var access_token;
var expires_in;
var refresh_token;
var openid = "";
var scope;


/*
  微信支付的js文件使用
 */
function useWxPay() {

    var notify_url = '你發(fā)起支付的頁面地址';
    var spbill_create_ip = getClienIp(req);
    var obj = {
        body : "明日VR-賬戶游戲幣充值", //描述微信支付的意義
        notify_url : notify_url,// 微信付款后的回調(diào)地址
        out_trade_no : data.orderNo,//new Date().getTime(), //訂單號
        spbill_create_ip :spbill_create_ip,
        total_fee : total_fee//金額
    }
    wxPayControl.getAccessToken(obj,wxCode,function (err,wxParam) {

    })
}

/**
 * 獲取客戶端的ip
 * req是發(fā)起請求的req
 */
getClienIp = function(req) {

    //固定ip
    return "139.224.53.144"

    //因為 輸出是 ::fffff:139.224.53.144 所以固定測試一下
    // return req.headers['x-forwarded-for'] ||
    //     req.connection.remoteAddress ||
    //     req.socket.remoteAddress ||
    //     req.connection.socket.remoteAddress;
};

/*
 第一步 獲取code
*/


/**
 * 獲取微信的 AccessToken 和 openid
 */
wxPayControl.getAccessToken = function(obj,wxCode,callback) {

    console.log("wecode ~~~");
    console.log(wxCode);
    var getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+wxConfig.wxAppId+"&secret="+wxConfig.wxAppSecret+"&code="+wxCode+"&grant_type=authorization_code";
    request.post({url : getAccessTokenUrl}, function (error, response, body) {
        console.log("微信支付 獲取accesstoken");
        console.log(body);
        if (!error && response.statusCode == 200){
            if (40029 == body.errcode) {
                callback(error, body);
            } else {
                body = JSON.parse(body);
                access_token = body.access_token;
                expires_in = body.expires_in;
                refresh_token = body.refresh_token;
                openid = body.openid;
                scope = body.scope;
                // 拼接微信的支付的參數(shù)
                getBrandWCPayParams(obj, function (error, responseData) {
                    if (error) {
                        callback(error);
                    } else {
                        console.log("微信支付的參數(shù)");
                        console.log(responseData);
                        callback(null, responseData);
                    }
                });
            }
        } else {
            callback(error);
        }
    });
}

/**
 * 獲取微信統(tǒng)一下單的接口數(shù)據(jù)
 */
function getPrepayId(obj){
    // 生成統(tǒng)一下單接口參數(shù)
    var UnifiedorderParams = {
        appid : wxConfig.wxAppId,
        body : obj.body,
        mch_id : wxConfig.wxMchId,
        nonce_str: createNonceStr(),
        notify_url : obj.notify_url,// 微信付款后的回調(diào)地址
        openid : openid,
        out_trade_no : obj.out_trade_no,//new Date().getTime(), //訂單號
        spbill_create_ip : obj.spbill_create_ip,
        total_fee : obj.total_fee,
        trade_type : 'JSAPI',

    };
    // 返回 promise 對象
    return  new Promise(function (resolve, reject) {
        // 獲取 sign 參數(shù)
        UnifiedorderParams.sign = getSign(UnifiedorderParams);
        var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        request.post({url : url, body:JSON.stringify(getUnifiedorderXmlParams(UnifiedorderParams))}, function (error, response, body) {
            console.log("微信下單返回數(shù)據(jù)");
            console.log(response);
            var prepay_id = '';
            if (!error && response.statusCode == 200) {
                // 微信返回的數(shù)據(jù)為 xml 格式, 需要裝換為 json 數(shù)據(jù)属百, 便于使用
                xml2jsparseString(body, {async:true}, function (error, result) {
                    prepay_id = result.xml.prepay_id[0];
                    // 放回數(shù)組的第一個元素
                    resolve(prepay_id);
                });
            } else {
                reject(body);
            }
        });
    })
}

/**
 * 微信支付的所有參數(shù)
 * @param req 請求的資源, 獲取必要的數(shù)據(jù)
 * @returns {{appId: string, timeStamp: Number, nonceStr: *, package: string, signType: string, paySign: *}}
 */
function getBrandWCPayParams(obj,callback ){
    var prepay_id_promise = getPrepayId(obj);
    prepay_id_promise.then(function (prepay_id) {
        var prepay_id = prepay_id;
        var wcPayParams = {
            "appId" : wxConfig.wxAppId,     //公眾號名稱记劝,由商戶傳入
            "timeStamp" : parseInt(new Date().getTime() / 1000).toString(),         //時間戳,自1970年以來的秒數(shù)
            "nonceStr" : createNonceStr(), //隨機串
            // 通過統(tǒng)一下單接口獲取
            "package" : "prepay_id="+prepay_id,
            "signType" : "MD5",         //微信簽名方式:
        };
        wcPayParams.paySign = getSign(wcPayParams); //微信支付簽名
        console.log(wcPayParams.paySign);
        console.log("微信支付的所有參數(shù)");
        console.log(wcPayParams);
        callback(null, wcPayParams);
    },function (error) {
        callback(error);
    });
}

/**
 * 獲取微信統(tǒng)一下單參數(shù)
 */
function getUnifiedorderXmlParams(obj){
    var body = '<xml>' +
        '<appid>'+wxConfig.wxAppId+'</appid>' +
        '<body>'+obj.body+'</body>' +
        '<mch_id>'+wxConfig.wxMchId+'</mch_id>' +
        '<nonce_str>'+obj.nonce_str+'</nonce_str>' +
        '<notify_url>'+obj.notify_url+'</notify_url>' +
        '<openid>'+obj.openid+'</openid>' +
        '<out_trade_no>'+obj.out_trade_no+'</out_trade_no>'+
        '<spbill_create_ip>'+obj.spbill_create_ip+'</spbill_create_ip>' +
        '<total_fee>'+obj.total_fee+'</total_fee>' +
        '<trade_type>'+obj.trade_type+'</trade_type>' +
        '<sign>'+obj.sign+'</sign>' +
        '</xml>';
    return body;
}

/**
 * 獲取微信支付的簽名
 * @param payParams
 */
function getSign(signParams){
    // 按 key 值的ascll 排序
    console.log('支付簽名');
    console.log(signParams);
    var keys = Object.keys(signParams);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function (val, key) {
        if (signParams[val]){
            newArgs[val] = signParams[val];
        }
    })
    var string = queryString.stringify(newArgs)+'&key='+wxConfig.wxPayKey;
    console.log(string);

    // 生成簽名
    return crypto.createHash('md5').update(queryString.unescape(string), 'utf8').digest("hex").toUpperCase();
}

/**
 * 獲取隨機的NonceStr
 */
function createNonceStr(){
    return Math.random().toString(36).substr(2, 15);
}

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末族扰,一起剝皮案震驚了整個濱河市厌丑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渔呵,老刑警劉巖怒竿,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扩氢,居然都是意外死亡耕驰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門录豺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朦肘,“玉大人,你說我怎么就攤上這事双饥∶娇伲” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵咏花,是天一觀的道長趴生。 經(jīng)常有香客問我,道長昏翰,這世上最難降的妖魔是什么苍匆? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮棚菊,結果婚禮上锉桑,老公的妹妹穿的比我還像新娘。我一直安慰自己窍株,他們只是感情好民轴,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著球订,像睡著了一般后裸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冒滩,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天微驶,我揣著相機與錄音,去河邊找鬼。 笑死因苹,一個胖子當著我的面吹牛苟耻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扶檐,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凶杖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了款筑?” 一聲冷哼從身側響起智蝠,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奈梳,沒想到半個月后杈湾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡攘须,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年漆撞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片于宙。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡叫挟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出限煞,到底是詐尸還是另有隱情抹恳,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布署驻,位于F島的核電站奋献,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏旺上。R本人自食惡果不足惜瓶蚂,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宣吱。 院中可真熱鬧窃这,春花似錦、人聲如沸征候。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疤坝。三九已至兆解,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跑揉,已是汗流浹背锅睛。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工埠巨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人现拒。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓辣垒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親印蔬。 傳聞我的和親對象是個殘疾皇子勋桶,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容