PYTHON

简介

为了提高客户的接入体验,特提供封装的开发SDK,使用本SDK将极大的简化开发者的工作,开发者将无需考虑通信、签名、验签等,只需要关注业务参数的拼装。

下载地址

SDK下载

版本记录

版本 日期 版本说明
v1.0.0 2021/06/01 初始版本

版本要求

此 SDK 目前只支持 Python3,请确保在 Python3 工程接入。

接入方法

下载 SDK

下载文件里包含 basepay_sdk 、 basepay_demo 两个目录。basepay_sdk 目录下为待添加到项目中的文件, basepay_demo 目录下为示例项目,供接入时参考使用。

导入第三方依赖库

在当前环境确保已经安装以下版本的依赖库:

pycryptodome==3.8.2
requests==2.22.0

使用方法

系统初始化

在使用 SDK 调用汇付接口前,请先进行商户配置,否则可能导致交易异常。

正常情况下只有一套商户配置,如有业务需求向汇付申请了多套配置信息,也可配置多个商户配置,并做好商户配置命名管理,配置名必须唯一

调用示例

'''
单套配置
默认为单商户配置,配置key默认为default,上送报文时无需指定配置key
'''
BasePay.init(
{
'product_id': demo_constants.DEMO_PRODUCT_ID,
"sys_id": demo_constants.DEMO_SYS_ID,
'rsa_private_key': demo_constants.RSA_PRIVATE_KEY,
'rsa_public_key': demo_constants.RSA_PUBLIC_KEY
})

'''
多套配置
如商户因特殊需要,申请多套配置,则需自行做好配置管理,上送报文时需明确指定使用哪套商户配置
'''
BasePay.init_with_multi_mer_configs(
{
    "merchantKey1" :
        {
            'product_id': demo_constants.DEMO_PRODUCT_ID1,
            "sys_id": demo_constants.DEMO_SYS_ID1,
            'rsa_private_key': demo_constants.RSA_PRIVATE_KEY1,
            'rsa_public_key': demo_constants.RSA_PUBLIC_KEY1
        },
    "merchantKey2" :
        {
            'product_id': demo_constants.DEMO_PRODUCT_ID2,
            "sys_id": demo_constants.DEMO_SYS_ID2,
            'rsa_private_key': demo_constants.RSA_PRIVATE_KEY2,
            'rsa_public_key': demo_constants.RSA_PUBLIC_KEY2
        },
    }
)

接口调用

接口调用均由 BasePayClient.post_request 方法发起,上传文件接口由 BasePayClient.upload_file 方法发起

@staticmethod
def post_request(func_code, request_params, merchant_key = 'default')

@staticmethod
def upload_file(func_code, request_params, request_file = None, merchant_key = 'default')

request_params 为请求报文体BODY中的 data - 「接口规则-参数规定-报文体」 ,需根据调用接口的API说明组装参数。

func_code 为请求接口的功能编码,请参考 交易接口功能编码商户管理接口功能编码

request_file 为需上传的文件。

merchant_key 为上一步初始化时配置的商户配置key。

接口调用实例

以下以聚合反扫接口为例,展示如何使用 SDK 来调用接口。

# 调试模式,默认False关闭,打开后输出日志供联调排查问题
BasePay.debug = False
# 生产模式,默认为True生产环境
BasePay.prod_mode = True


req_date = datetime.datetime.now().strftime('%Y%m%d')
now_datetime = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
req_seq_id = now_datetime + "01234567890"
# mer_ord_id = now_datetime + "1234567890"
mer_ord_id = req_seq_id;
time_expire = (datetime.datetime.now() + datetime.timedelta(minutes=2)).strftime('%Y%m%d%H%M%S')
request_param = {
    # 请求流水号,需保证当天商户下唯一,推荐采用日期时间+几位流水号的形式
    "req_seq_id" : req_seq_id,
    # 请求日期,请求接口的日期,因服务器时间可能有差异,允许前后1天
    "req_date": req_date,
    # 系统号,由汇付分配
    "sys_id": demo_constants.DEMO_SYS_ID,
    # 商户订单号,需保证商户下唯一,推荐采用日期时间+几位流水号的形式,可与req_seq_id相同
    "mer_ord_id": mer_ord_id,
    # 分配商户号
    "huifu_id": demo_constants.DEMO_HUIFU_ID,
    # 渠道号,若需使用自有渠道请联系业务对接人
    "bank_channel_no" : "",
    # 交易金额
    "trans_amt":"0.02",
    # 商品描述
    "goods_desc":"测试商品",
    # 付款二维码
    "auth_code" : '用户展示的付款码',
    # 设备信息
    "terminal_device_info": {
            "device_type":"4",
            "device_ip":"终端设备ip地址"
     },
    # 风控信息
    # 注意,风控信息为JSON字符串
    "risk_check_info" : json.dumps({
        "riskMngInfo" : {
            "subTradeType" : "4300"
        },
        "ipAddr":"139.207.19.246"
    }),
    # 异步通知地址
    "notify_url":"virgo://http://www.test.com/asynNotice",

    # 交易有效期
    "time_expire":time_expire,
    # 指定支付方式 是否禁止用户使用信用卡支付。默认不禁用,若禁止请填1
    "limit_pay":"1",
    # 延时标志 1为延迟 0为不延迟
    "is_delay_acct":"0",
    # 传入分帐遇到优惠的处理规则 1-按比例分 2-按顺序保障 3-只给交易商户
    "term_div_coupon_type":"3",
    # 分账串
    # 注意只有真实分账场景才需要传入分账串,请避免传入多个分账方为同一商户的分账串
    "acct_split_bunch":{
        "acct_infos" : [
            # 分账方1
            {
                'huifu_id':demo_constants.DEMO_HUIFU_ID,
                'div_amt':'0.01'
            },
            # 分账方2
            {
                "huifu_id":demo_constants.DEMO_DIV_HUIFU_ID,
                "div_amt":"0.01"
            }
        ]
    },
    # 商户私有域
    "mer_priv":"",
    # 微信扩展参数集合
    "wx_data":"",
    # 支付宝扩展参数集合
    "alipay_data":"",
    # 银联扩展参数集合
    "unionpay_data":"",
    # 手续费类型 01:标准费率线上,02:标准费率线下,03:非盈利费率,04:缴费费率,05:保险费率,06:行业活动费率,07:校园餐饮费率,08:K12中小幼费率
    # 不送时取业务入驻配置的默认费率
    "pay_scene":"02"
}

# 调用聚合反扫接口
try:
    post_result = BasePayClient.post_request('top.trans.authCodePay', request_param)
    # 如果需要套用指定配置调用接口,请参考以下
    # post_result = BasePayClient.post_request('top.trans.authCodePay', request_param, 'merchantKey2')
except Exception as e:
    print(str(e))
    sys.exit()

sub_resp_code = post_result.get('sub_resp_code', '')

if (sub_resp_code == '00000000'):
    print('处理成功')
    print('交易状态:' + post_result.get('trans_stat', ''))
    # 交易状态处理中后续可调用交易查询接口获取终态
elif (sub_resp_code == '00000100'):
    print('处理中')
    print('交易状态:' + post_result.get('trans_stat', ''))
    # 交易状态处理中后续可调用交易查询接口获取终态
else:
    print ('处理失败:' + post_result.get('sub_resp_desc', ''))