Created
April 15, 2015 03:28
-
-
Save guileen/1e6b70c29682936e3262 to your computer and use it in GitHub Desktop.
Alipay example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var alipayConfig = require('../../config').alipay | |
var request = require('co-request') | |
var fs = require('fs') | |
var alipayPubKey = fs.readFileSync(__dirname + '/../../alipay_certs/alipay_rsa_public_key.pem', 'utf8') | |
var crypto = require('crypto') | |
exports.verifySign = function(params) { | |
if(params.seller_email != alipayConfig.seller_email) | |
return false | |
var paramsToSign = [] | |
// remove sign && sign_type | |
for(var name in params) { | |
if(name != 'sign' && name != 'sign_type') { | |
paramsToSign.push(name + '=' + params[name]) | |
} | |
} | |
paramsToSign.sort() | |
var signStr = paramsToSign.join('&') | |
signStr = unescape(encodeURIComponent(signStr)) // force convert to utf8 | |
return crypto.createVerify('RSA-SHA1') | |
.update(signStr) | |
.verify(alipayPubKey, params.sign, 'base64') | |
} | |
exports.verifySignWap = function(params) { | |
var signStr = 'service=' + params.service + '&v=' + params.v + '&sec_id=' + params.sec_id + '¬ify_data=' + params.notify_data | |
if(params.sec_id == 'MD5') { | |
return crypto.createHash('md5').update(signStr + alipayConfig.key, 'utf8').digest('hex') == params.sign | |
} | |
return crypto.createVerify('RSA-SHA1') | |
.update(signStr) | |
.verify(alipayPubKey, params.sign, 'base64') | |
} | |
function jsonToXML(obj) { | |
var str = '' | |
for(var k in obj) { | |
var v = obj[k] | |
if(typeof v == 'object') { | |
v = jsonToXML(v) | |
} | |
str += '<'+k+'>'+v+'</'+k+'>' | |
} | |
return str | |
} | |
function getToken(res_xml) { | |
console.log('res_xml', res_xml) | |
var m = res_xml.match(/<request_token>(.*)<\/request_token>/) | |
return m && m[1] | |
} | |
function makeXML(params) { | |
return '<direct_trade_create_req>' + | |
'<subject>'+params.subject+'</subject>'+ | |
'<out_trade_no>'+params.out_trade_no + '</out_trade_no>' + | |
'<total_fee>'+params.total_fee+'</total_fee>'+ | |
'<seller_account_name>'+params.seller_account_name+'</seller_account_name>'+ | |
'<call_back_url>'+params.call_back_url+'</call_back_url>'+ | |
'<notify_url>'+params.notify_url+'</notify_url>'+ | |
'<out_user>'+params.out_user+'</out_user>'+ | |
'<merchant_url>'+params.merchant_url+'</merchant_url>'+ | |
'<pay_expire>'+params.pay_expire+'</pay_expire>'+ | |
'<agent_id>'+params.agent_id+'</agent_id>'+ | |
'</direct_trade_create_req>' // TODO | |
} | |
exports.createRedirectUrl = function*(params) { | |
var req_data = { | |
direct_trade_create_req:{ | |
subject: params.subject || '支付商品标题', | |
out_trade_no: params.out_trade_no, | |
total_fee: params.total_fee, | |
seller_account_name: alipayConfig.seller_email, | |
call_back_url: params.call_back_url, | |
notify_url: alipayConfig.notifyUrl, | |
out_user: params.out_user, | |
merchant_url: params.merchant_url, | |
pay_expire: params.pay_expire || 10, | |
agent_id: params.agent_id | |
} | |
} | |
console.log('params', params) | |
console.log('req_data', req_data) | |
var req_data_xml = jsonToXML(req_data) | |
var data = { | |
service: 'alipay.wap.trade.create.direct', | |
format: 'xml', | |
v: '2.0', | |
partner: alipayConfig.partner, | |
req_id: Date.now(), // uid | |
sec_id: 'MD5', // 0001: RSA , MD5: MD5 | |
req_data: req_data_xml, | |
sign: '1234' | |
} | |
data.sign = makeSign(data, alipayConfig.key) | |
var url = 'http://wappaygw.alipay.com/service/rest.htm' | |
console.log('qs', data) | |
var res = yield request.get({ | |
url: url, | |
qs: data | |
}) | |
console.log('err:'+res.statusCode) | |
console.log('resdata:'+res.body) | |
var body = {} | |
res.body.split('&').forEach(function(kv) { | |
kv = kv.split('=') | |
body[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]) | |
}) | |
console.log(body) | |
var token = getToken(body.res_data) | |
var r_url = 'http://wappaygw.alipay.com/service/rest.htm' | |
var req_data = jsonToXML({ | |
auth_and_execute_req : { | |
request_token : token | |
} | |
}) | |
var query = { | |
req_data: req_data, | |
service: 'alipay.wap.auth.authAndExecute', | |
sec_id: 'MD5', | |
partner: alipayConfig.partner, | |
format: 'xml', | |
v: '2.0' | |
} | |
query.sign = makeSign(query, alipayConfig.key) | |
var qs = [] | |
for(var k in query) { | |
qs.push(k + '=' + encodeURIComponent(query[k])) | |
} | |
return r_url + '?' + qs.join('&') | |
} | |
function makeSign(params, key) { | |
var arr = [] | |
for(var k in params) { | |
if(k == 'sign') continue | |
arr.push(k+'='+params[k]) | |
// arr.push(k+'='+encodeURIComponent(params[k])) | |
} | |
arr.sort() | |
var str = arr.join('&') | |
return crypto.createHash('md5').update(str + key, 'utf8').digest('hex') | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment