Skip to content

Instantly share code, notes, and snippets.

@guileen
Created April 15, 2015 03:28
Show Gist options
  • Save guileen/1e6b70c29682936e3262 to your computer and use it in GitHub Desktop.
Save guileen/1e6b70c29682936e3262 to your computer and use it in GitHub Desktop.
Alipay example
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 + '&notify_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