一,支付宝开放平台账户申请
浏览器访问 https://open.alipay.com/develop/sandbox/account
第一次访问会让你填写申请信息注册开发者账号
1,什么是沙箱环境:
按照官方文档上来说,沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境,开发者在沙箱环境中调用接口无需具备所需的商业资质,无需绑定和开通产品,同时不会对生产环境中的数据造成任何影响.
2,当我们注册好沙箱环境开发者账号页面之后会自动给跳到这里来
注册成功之后会获取到两个值:
- APPID
- 支付宝网关地址
开发中需要用到
二,生成秘钥
秘钥用于以后对URL中添加的参数进行加密和校验.
1,下载秘钥生成器
浏览器访问地址:密钥工具下载 - 支付宝文档中心 (alipay.com)
windows平台的下载windows的,mac平台的下载mac的
2,使用秘钥生成器生成密钥
- 应用公钥
- 应用私钥
RSA2加密算法默认生成格式为PKCS8(Java适用),如果是非Java的话需要进行格式转换,转换成PKCS1,因为我使用了python代码所以需要先进行格式转换
测试应用公钥和私钥是否匹配
3,上传应用公钥并获得支付私钥
- 支付私钥
重新计入沙箱控制台
将应用公钥输入然后加签变更生成支付公钥
上面操作中共获取到三个秘钥:
- 应用公钥
- 应用私钥,对以后URL中传入的数据进行签名机密用
- 支付宝公钥(通过应用公钥生成),在页面支付成功后跳转回来时候,对支付宝给我们传的值进行校验.
4,下载支付宝沙箱app并登录沙箱买家账号
到沙箱控制台
划重点:支付宝沙箱钱包使用沙箱账号登录。
划重点:支付宝沙箱钱包使用沙箱账号登录。
划重点:支付宝沙箱钱包使用沙箱账号登录。
重要的事情说三遍,大家在登录的时候记得 不要直接用自己的账号登
沙箱账号在沙箱账号页签上有提供
三,支付API
参考文档:统一收单下单并支付页面接口 - 支付宝文档中心 (alipay.com)
支付API的方式就是将支付网关地址https://openapi-sandbox.dl.alipaydev.com/gateway.do?{按文档要求加入的参数,并对请求参数进行处理和签名} 得到的支付URL,当用户点击商品购买后就会跳转到这个支付URL上从而完成支付
四,生成签名
对请求参数进行签名,参考文档:签名 - 支付宝文档中心 (alipay.com)
五,代码封装
import datetime
import json
from base64 import encodebytes
from urllib.parse import quote_plus
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
class AliPay(object):
"""
支付宝接口
"""
def __init__(self, appid, app_notify_url, app_private_key_path,
alipay_public_key_path, return_url):
self.appid = appid
self.app_notify_url = app_notify_url
self.app_private_key_path = app_private_key_path
self.alipay_public_key_path = alipay_public_key_path
self.return_url = return_url
with open(self.app_private_key_path) as fp:
self.app_private_key = RSA.importKey(fp.read())
with open(self.alipay_public_key_path) as fp:
self.alipay_public_key = RSA.importKey(fp.read())
def direct_pay(self, subject, out_trade_no, total_amount, **kwargs):
print(self)
biz_content = {
'out_trade_no': out_trade_no,
'product_code': 'FAST_INSTANT_TRADE_PAY',
'total_amount': total_amount,
'subject': subject
}
biz_content.update(kwargs)
data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url)
return self.sign_data(data)
def build_body(self, method, biz_content, return_url=None):
print(self)
data = {
'app_id': self.appid,
'method': method,
'format': 'JSON',
'charset': 'utf-8',
'sign_type': 'RSA2',
'timestamp': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
'version': '1.0',
'biz_content': biz_content
}
if return_url:
data['notify_url'] = self.app_notify_url
data['return_url'] = self.return_url
return data
def sign_data(self, data):
print(self)
data.pop('sign', None)
# 排序后的字符串
unsigned_items = self.orderd_data(data)
unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items)
sign = self.sign(unsigned_string.encode('utf-8'))
quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items)
# 获取最终的订单信息字符串
signed_string = quoted_string + "&sign=" + quote_plus(sign)
return signed_string
def orderd_data(self, data):
print(self)
complex_keys = []
for key, value in data.items():
if isinstance(value, dict):
complex_keys.append(key)
# 将字典类型的数据dump出来
for key in complex_keys:
data[key] = json.dumps(data[key], separators=(',', ':'))
return sorted([(k, v) for k, v in data.items()])
def sign(self, unsigned_string):
# 开始计算签名
print(self)
key = self.app_private_key
signer = PKCS1_v1_5.new(key)
signature = signer.sign(SHA256.new(unsigned_string))
sign = encodebytes(signature).decode('utf-8').replace('\n', '')
return sign
def verify(self, params, sign):
print(self)
sign_string = self.sign_data(params)
if sign_string == sign:
return True
else:
return False
六,生成支付url进行支付测试
测试代码
import hashlib
import uuid
from alipay import AliPay
SECRET_KEY = 'ns*i&zys*@az$!iy1pk8fbj-^(ob!ptj^wv6bitj0=*hg66&#i'
ALI_GATEWAY = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do'
def md5(string):
"""MD5加密"""
hash_object = hashlib.md5(SECRET_KEY.encode('utf-8'))
hash_object.update(string.encode('utf-8'))
return hash_object.hexdigest()
def uid(string):
data = "{}-{}".format(uuid.uuid4(), string)
return md5(data)
order_id = uid("123")
total_price = 50
ali_pay = AliPay(
appid=你自己应用的appid,
app_notify_url=你自己的支付回调地址post请求,
return_url=支付成功之后get跳转地址,
app_private_key_path=应用公钥文件保存路径,
alipay_public_key_path=支付宝公钥文件保存路径
)
query_params = ali_pay.direct_pay(
subject="xx影视vip",
out_trade_no=order_id,
total_amount=total_price
)
pay_url = "{}?{}".format(ALI_GATEWAY, query_params)
最终拿到这个pay_url跳转支付页面,用我们之前下载好的沙箱支付宝进行支付测试就可以了,支付回调地址是我们对支付成功或者失败后所需要进行的操作,一般是对订单入库信息的修改,还有触发系统商品发放之类的...