支付宝移动支付,官方只提供了PHP示例,其他语言需要自己写。(汗,大阿里真是省事啊)
博主使用了python/django开发个服务器。
需求:移动端通过服务端API获取签名然后支付,即签名在服务端处理,客户端不保存。
1、需要使用RSA加密
import rsa #需要这个库
2、几个重要的参数,作为初始化
class Alipay(object):
## default value
service = "mobile.securitypay.pay"# api name, default value
_input_charset = "utf-8"
sign_type = "RSA"# only support RSA
payment_type = 1
# get value from settings.py
# partner id, len=16 (2088...)
partner = getattr(settings, "ALIPAY_PARTNER", None)
notify_url = getattr(settings, "ALIPAY_NOTIFY_URL", None)
# the account id of seller (email or phone or partner id)
seller_id = getattr(settings, "ALIPAY_SELLER_ID", None)
print partner, notify_url, seller_id
def __init__(self, out_trade_no, subject, body, total_fee):
# unique value, max=64
self.out_trade_no = out_trade_no
# order title/ trade keys, max=128
self.subject = subject
# the detail info of order, max=512
self.body = body
# the total pay fee
self.total_fee = total_fee
3、本地密匙pem文件的读取(文件与py同级)
path = os.path.dirname(__file__) priv_path = os.path.abspath(os.path.join(path, "rsa_private_key.pem")) pub_path_ali = os.path.abspath(os.path.join(path, "rsa_public_key_ali.pem")) pem = open(priv_path, "r").read() _private_rsa_key = rsa.PrivateKey.load_pkcs1(pem) pem = open(pub_path_ali, "r").read() _public_rsa_key_ali = rsa.PublicKey.load_pkcs1_openssl_pem(pem)
4、签名create_pay_url获取签名内容和签名结果(只添加了必须得数据)
def _build_sign_url(self):
url = ""
# static value
url = url + 'service="%s"' % self.service
url = url + '&_input_charset="%s"' % self._input_charset
url = url + '&payment_type="%d"' % self.payment_type
url = url + '&partner="%s"' % self.partner
url = url + '¬ify_url="%s"' % self.notify_url
url = url + '&seller_id="%s"' % self.seller_id
# init value
url = url + '&out_trade_no="%s"' % self.out_trade_no
url = url + '&subject="%s"' % self.subject
url = url + '&body="%s"' % self.body
url = url + '&total_fee="%0.2f"' % self.total_fee
# optional value
if hasattr(self, "it_b_pay"):
url = url + '&it_b_pay="%s"' % self.it_b_pay
return url
def _create_sign(self, content):
content = content.encode(self._input_charset)
sign = rsa.sign(content, _private_rsa_key, "SHA-1")
sign = base64.encodestring(sign).replace("\n", "")
return 'sign="%s"&sign_type="%s"' % (quote(sign), self.sign_type)
def create_pay_url(self):
content = self._build_sign_url()
sign_url = self._create_sign(content)
return "%s&%s" % (content, sign_url)
5、验证支付成功后支付宝通知(需要按照字母排序)
def notify_sign_value(request, content, key):
if key in request.POST:
value = request.POST[key]
print "key: ", key, "value: ", value
return "&%s=%s"%(key, value)
else:
return ""
def check_notify_sign(request):
"""
按照字母顺序排序,然后使用阿里云的公匙验证。
"""
content = ""
post_list = sorted(request.POST.iteritems(), key=lambda d:d[0], reverse=False)
for key_value in post_list:
if key_value[0] not in ["sign", "sign_type"]:
content = "%s&%s=%s"%(content, key_value[0], key_value[1])
#remove the first &
content = content[1:]
content = content.encode("utf-8")
try:
sign = request.POST["sign"]
sign = base64.decodestring(sign)
rsa.verify(content, sign, _public_rsa_key_ali)
return True
except Exception,e:
print "check_notify_sign error", e
return False
6、使用方法及源码可参照github
第一个开源代码