情景介绍:
大概一年前(具体时间记不太清了),产品说支付宝推出测试版的‘订单中心’的功能,能够根据历史账单中的支付记录回调到当初使用的应用(如下图),让公司尝试对接测试一下。
现在接入这个功能的公司越来越多,我们文档就按照支付官网提供的为标准。
简单的分为两部分来说明。
1, 获取素材图片id(商品文件上传接口)
在支付宝的‘订单中心’中,交易的每一笔订单都有一张需要用来展示的图片,需要先调用这个接口,上传图片,获取到对应的material_id参数。
但是这个接口出现了一个问题,关于图片数据最终应该如何上传。
如果按照文档中的描述,其实是有一点迷茫的
从参数格式来看,默认是JSON格式,POST请求。
然后发现公共请求参数中并没有像支付接口或者退款接口那样,有一个参数合集叫做biz_content。那先认为scene和file_content与其他参数是平级的。
file_content在这里按照文档描述,需要的是二进制数据。那这就很奇怪了,如果是json格式,某一个参数值是图片转换的二进制数据是不合理的,那就偏向form表单传输数据,毕竟form可以传输文件对象。
file_content传输文件对象,请求失败。
file_content传输二进制数据,请求失败。
file_content传输base64数据,请求失败。
场面一度非常尴尬。
那这个怎么办呢?去SDK里面看看?但是当时并没有python语言的SDK~(现在有了)
找‘大腿’技术总监帮忙从其他语言的SDK中,拿到了关于这一步的操作(展示的简化了一下,只留下了大概流程)。
url= 'https://openapi.alipay.com/gateway.do' # 请求链接
params= {
'app_id': app_id,
'method': 'alipay.merchant.item.file.upload',
'charset': 'utf-8',
'version': '1.0',
'sign_type': 'RSA2',
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'scene': 'SYNC_ORDER',}
params['sign'] = get_sign(app_public_key_path) # 获取加密后的签名(逻辑与支付一致)
multipart= {
k: (None, v) for k, v in params.items() # 参数格式处理,这里是最特殊的一步需要把所以参数的值改为元组并且第一个值为None
}content= Aliyun().get_file(image_key) # 获取图片二进制数据
basename= os.path.basename(image_path) # 获取基本名称
content_type, __= mimetypes.guess_type(image_path) # 通过文件名后缀判断图片类型multipart['file_content'] = (
basename, content, content_type # 参数拼接
)requests.post(url, files=multipart)
如果不看官方SDK,只看文档,楼主肯定不知道具体的参数值应该是这样的拼接方法~
到这里,我们就完成了第一步,拿到了图片在支付宝对应的素材id
2, 同步订单数据(订单数据同步接口)
这里直接上代码(一样是简洁版):
params= {
'app_id': appid,
'method': 'alipay.merchant.order.sync',
'charset': 'utf-8',
'version': '1.0',
'sign_type': 'RSA2',
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'biz_content': {
'out_biz_no': order_no,
'buyer_id': buyer_id,
'seller_id': appid,
'partner_id': pid,
'amount': amount,
'trade_no': trade_no,
'item_order_list': [{
'sku_id': out_biz_no,
'item_id': out_biz_no,
'unit_price': amount,
'quantity': 1,
'item_name': name,
'ext_info': [
{
'ext_key': 'image_material_id',
'ext_value': material_id,
}
]
}],
'ext_info': [
{
"ext_key": "tiny_app_id",
"ext_value": appid
},
{
"ext_key": "merchant_order_link_page",
"ext_value": path,
},
{
"ext_key": "merchant_order_status",
"ext_value": "MERCHANT_CONFIRMED",
}
]
}
}
params['sign'] = grt_sign(params, key)url= 'https://openapi.alipay.com/gateway.do'
requests.post(url=url, data=params)
请求参数中‘ext_info’可以额外添加的值过多,这里只列举最基本的几个(保证基本可用)更多的可以查看官方文档。
其中类似buyer_id,partner_id都是可以在支付宝的支付回调中找到对应值。
merchant_order_link_page的值是在跳转到小程序时,小程序对应的页面的路径(由前端提供)
merchant_order_status,tiny_app_id在最初对接时支付宝推荐使用的参数,具体原因不详(早期并未对这两个参数进行解释),且现官方文档中没有具体描述(tiny_app_id不加不影响正常接口调用,属于优化某种功能的参数)
以上