集成支付宝快捷支付小记。
客户端集成移动端支付宝快捷支付,iOS和Android端很方便,使用支付宝提供的sdk就可以了,要注意的地方就是:
基本上看着文档就可以很快完成集成测试。
当用户手机没有安装支付宝App,则会弹出安装支付宝App的弹窗,点确定就去下载支付宝App,点取消就弹出webview打开网页版支付宝结算。
服务端是用Ruby。
因为所有的支付请求都由客户端完成了,那么服务端只剩下了实现支付宝异步通知接口的任务。
异步通知接口有两步工作:RSA签名验证、Notify ID验证是否支付宝请求。
目前快捷支付的签名类型,只支持RSA, 所以服务端接收异步通知的接口Notify就只能用RSA来验证签名。支付RSA验证的逻辑是这样的(文档里也有描述,理解这个逻辑有助于顺利完成验证):
理解了RSA的加密解密逻辑,我们就了解了,服务端后台要验证来自于支付宝的异步通知POST请求,必须用支付宝的公钥了。
复制文档里支付宝的RSA公钥, 换行的部分用\n代替,如下:
-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRA\nFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQE\nB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5Ksi\nNG9zpgmLCUYuLkxpLQIDAQAB\n-----END PUBLIC KEY-----
然后,我们使用OpenSSL::PKey::RSA类:
rsa = OpenSSL::PKey::RSA.new(alipay_pub_key)
alipay_pub_key是上面的支付宝公钥。
一定要上面这种格式,或者你使用工具生成符合pem格式的pem文件,否则会报错。
然后我们就可以使用rsa的verify方法验证签名了:
rsa.verify('sha1', Base64.decode64(sign), rsa_string.force_encoding("utf-8"))
注意,这里的sign,是支付宝请求里的签名参数, 这里的sign一定要经过base64解码。rsa_string是根据支付宝文档生成的待签名字符串。
有的人可能不理解'sha1'。 这里sha1是签名算法,RSA是加密手段,加密了签名数据。 通过支付宝提供的java和php demo代码了解,支付宝使用的是sha1算法,所以这里需要用sha1算法来参与认证签名。用一句伪代码表示如下:
RSA_Private_key(sha1(rsa_string))
这样,你就可以完成RSA验证了。
这个很简单, 带上支付宝文档里提供的参数,给支付验证接口发个请求就可以了。
Ruby推荐使用ActiveMerchant,我把上面的验证过程写了个ActiveMerchant补丁,用起来很方便,毕竟ActiveMerchant帮你做了很多工作,这里就不分享了,大家可以自己去写。
最后,需要注意的地方:
今天把支付宝支付客户端RSA签名验证的过程,移到了服务端,这样做是为了更加安全,RSA的密钥就不必保存到客户端了。
增加一个RSA签名方法:
def rsa_sign(rsa_string)
pri = OpenSSL::PKey::RSA.new(alipay.private_key)
sign = pri.sign('sha1', rsa_string.force_encoding("utf-8"))
signature = CGI.escape(Base64.encode64(sign))
return signature
end
以及一个生成待签名字串的方法
def create_sign_string(sign_params)
sign_keys = sign_params.keys
origin_string = sign_keys.inject(''){|s, key|
if key.to_s == 'notify_url'
s += %Q{#{key}="#{URI.encode(sign_params[key], Regexp.new(/:\/\//))}"&}
else
s += %Q{#{key}="#{sign_params[key]}"&}
end
}
return origin_string
end
集成微信支付
转载:http://tao.logdown.com/posts/192524-integrate-paypal-express-payment