最新更新時間:2021.12.10 版本說明
微信支付按天提供微信支付賬戶的資金流水賬單文件,服務商可以通過該接口獲取子商戶賬單文件的下載地址。文件內(nèi)包含子商戶資金操作相關的業(yè)務單號、收支金額、記賬時間等信息,供商戶進行核對。
? 資金賬單中的數(shù)據(jù)反映的是子商戶微信賬戶資金變動情況;
? 當日賬單在次日上午9點開始生成,建議商戶在上午10點以后獲取;
? 資金賬單中涉及金額的字段單位為“元”;
? 該接口只能下載三個月以內(nèi)的資金流水賬單。
? 需提前在【服務商平臺 -> 產(chǎn)品中心】開通“下載二級商戶資金賬單”產(chǎn)品權限。
適用對象:服務商 電商平臺
請求URL:https://api.mch.weixin.qq.com/v3/bill/sub-merchant-fundflowbill
請求方式:GET
path指該參數(shù)為路徑參數(shù)
query指該參數(shù)需在請求URL傳參
body指該參數(shù)需在請求JSON傳參
參數(shù)名 | 變量 | 類型[長度限制] | 必填 | 描述 |
---|---|---|---|---|
子商戶號 | sub_mchid | string[1, 32] | 是 | query下載指定子商戶的賬單。 示例值:19000000001 |
賬單日期 | bill_date | string[10, 10] | 是 | query格式y(tǒng)yyy-MM-dd 示例值:2019-06-11 |
資金賬戶類型 | account_type | string[1, 16] | 是 | query枚舉值: BASIC:基本賬戶 OPERATION:運營賬戶 FEES:手續(xù)費賬戶 示例值:BASIC |
加密算法 | algorithm | string[1, 31] | 是 | query枚舉值: AEAD_AES_256_GCM:AEAD_AES_256_GCM加密算法 SM4_GCM:SM4_GCM加密算法,密鑰長度128bit 示例值:AEAD_AES_256_GCM |
壓縮格式 | tar_type | string[1, 8] | 否 | query不填則以不壓縮的方式返回數(shù)據(jù)流 枚舉值: GZIP:返回格式為.gzip的壓縮包賬單 示例值:GZIP |
https://api.mch.weixin.qq.com/v3/bill/sub-merchant-fundflowbill?sub_mchid=19000000001&bill_date=2019-06-11&account_type=BASIC&algorithm=AEAD_AES_256_GCM&tar_type=GZIP
參數(shù)名 | 變量 | 類型[長度限制] | 必填 | 描述 |
---|---|---|---|---|
下載信息總數(shù) | download_bill_count | int | 是 | 下載信息總數(shù) 示例值:1 |
+下載信息明細 | download_bill_list | array | 是 | 下載信息明細 |
{
"download_bill_count": 1,
"download_bill_list": [
{
"bill_sequence": 1,
"download_url": "https://api.mch.weixin.qq.com/v3/bill/downloadurl?token=xxx",
"encrypt_key": "a0YK7p+9XaKzE9N4qtFfG/9za1oqKlLXXJWBkH+kX84onAs2Ol/E1fk+6S+FuBXczGDRU8I8D+6PfbwKYBGm0wANUTqHOSezzfbieIo2t51UIId7sP9SoN38W2+IcYDviIsu59KSdyiL3TY2xqZNT8UDcnMWzTNZdSv+CLsSgblB6OKGN9JONTadOFGfv1OKkTp86Li+X7S9bG62wsa572/5Rm4MmDCiKwY4bX2EynWQHBEOExD5URxT6/MX3F1D3BNYrE4fUu1F03k25xVlXnZDjksy6Rf3SCgadR+Cepc6mdfF9b2gTxNsJFMEdYXbqL0W1WQZ3UqSPQCguK6uLA==",
"hash_type": "SHA1",
"hash_value": "79bb0f45fc4c42234a918000b2668d689e2bde04",
"nonce": "a8607ef79034c49c"
}
]
}
賬單文件包括明細數(shù)據(jù)和匯總數(shù)據(jù)兩部分,每一部分都包含一行表頭和若干行具體數(shù)據(jù)。
明細數(shù)據(jù)每一行對應一筆資金操作,同時每一個數(shù)據(jù)前加入了字符,以避免數(shù)據(jù)被Excel按科學計數(shù)法處理。如需匯總金額等數(shù)據(jù),可以批量替換掉該字符。
當子商戶資金賬單文件太大(未壓縮情況下約大于16GB)時,微信支付會對賬單文件進行分割,此時接口會返回多個下載地址。商戶分別根據(jù)下載地址下載賬單文件并解密。解密后,將多個文件按賬單文件序號(變量名:bill_sequence)的順序合并為完整的資金賬單文件。
商戶需要注意,當返回多個下載地址時,商戶依然需要在下載地址有效時間內(nèi)發(fā)起下載請求。因此建議商戶獲取到下載地址后,并發(fā)請求下載。
子商戶資金賬單文件采用商戶指定的加密算法(支持AES-256-GCM算法和SM4-GCM算法)進行加密,商戶需要進行解密才能得到賬單明文。解密流程是:
步驟1 下載賬單文件,得到賬單文件密文ciphertext;
步驟2 使用商戶證書私鑰解密從接口獲取的加密密鑰(變量名:encrypt_key)得到密鑰明文key;
步驟3 利用步驟一、二中得到的賬單密文ciphertext,密鑰key和接口返回的隨機字符串nonce解密賬單,得到賬單明文。
GCM即可以進行加密,又可以對信息的完整性進行校驗,因此基于GCM加密的賬單,解密成功則表示賬單完整性校驗通過。
基于AES-256-GCM算法加密的賬單文件解密代碼示例
賬單文件解密代碼示例請參考[WechatPay-API-v3 證書和回調(diào)報文解密],注意:返回的賬單文件是二進制密文,需以字節(jié)數(shù)組形式處理,不需要進行Base64解碼。
下面對解密代碼中使用的參數(shù)進行說明:
{
// 密文
"ciphertext": "下載得到的賬單文件密文",
// 加密使用的密鑰
"key": "用商戶證書私鑰解密加密密鑰得到的明文",
// 加密使用的隨機字符串
"nonce": "接口返回的隨機字符串",
// 附加數(shù)據(jù)包(填空)
"associated_data": ""
}
基于SM4算法加密的賬單文件解密代碼示例
with open(r"./ciphertext", 'rb') as f:
ciphertext_tag_bytes = f.read()
ciphertext_tag_hex = binascii.b2a_hex(ciphertext_tag_bytes)
# 賬單密文最后16字節(jié)是消息驗證碼
ciphertext_bytes = binascii.unhexlify(ciphertext_tag_hex[:-32])
tag_bytes = binascii.unhexlify(ciphertext_tag_hex[-32:])
key="cbf063b0b33781c3"
key_bytes = str.encode(key)
iv="09ba90b74310"
iv_bytes = str.encode(iv)
aad = ''
# 賬單明文
decrypt_plain = SM4_GCM_Decrypt_NoPadding_NIST_SP800_38D(ciphertext_bytes, key_bytes, iv_bytes, aad, tag_bytes)
RSA-2048加解密
如果HTTP頭的Authorization的認證類型采用WECHATPAY2-SHA256-RSA2048, 則從接口獲取的加密密鑰(變量名:encrypt_key)是使用商戶證書公鑰進行RSA加密返回的密文,商戶需解密后才能得到密鑰原文。
解密流程如下:對encrypt_key先做Base64解碼,然后對解碼結果使用商戶證書私鑰進行RSA解密,指定填充方式為最優(yōu)非對稱加密填充(OAEP)。
下面我們使用命令行演示如何解密,更多的示例可以參考[WechatPay-API-v3 敏感信息加密]。
解密AES密鑰得到key:
# 解密AES密鑰得到key:
$ echo -n { encrypt_key } | openssl enc -A -base64 -d | openssl rsautl -decrypt -oaep -inkey {商戶證書私鑰文件}
SM2加解密
如果HTTP頭的Authorization的認證類型采用WECHATPAY2-SM2-WITH-SM3, 則從接口獲取的加密密鑰(變量名:encrypt_key)是使用SM2橢圓曲線公鑰密碼算法加密返回的密文,商戶需解密后才能得到密鑰原文。
解密流程如下:對encrypt_key先做Base64解碼,然后對解碼結果使用商戶證書私鑰進行SM2解密,密文格式是C1C3C2_ASN1。
# 解密AES密鑰得到key
SM2Init()
cipher = 'MIGKAiEA4FdfXZIG9oaS4v0CrCcFWAhQR0mR04cwZwFqP6lWwfACIQCGIdcc9PD9ZXmjvpyhbY0/lcww+UCp3+LP1yelYWpdbQQg5D4m4+JIyCyUwhwGuxMGPZR+bNmc2AVhlPQWj99WfT8EIOiAP7dYMFbc3HUHTt8F0RpGQns6zWhc3snUeMdkAWXF'
priv = "2f9f54d3a8793c50af8c61d10f88856cfcad6297f33b910b7f1093846083e835"
SM2CipherMode_C1C3C2_ASN1 = 0
decrypt_plain = SM2DecryptWithMode(base64.b64decode(cipher), priv, SM2CipherMode_C1C3C2_ASN1)
# 預期返回 SM2 Decrypt binary data, Plain is -------c6fafbae361863c146f0a1c27ff9c1a2
print("SM2 Decrypt binary data, Plain is -------"+decrypt_plain.decode('utf-8'))
狀態(tài)碼 | 錯誤碼 | 描述 | 解決方案 |
---|---|---|---|
500 | SYSTEM_ERROR | 系統(tǒng)錯誤 | 系統(tǒng)異常,請使用相同參數(shù)稍后重新調(diào)用 |
403 | NO_AUTH | 權限異常 | 請檢查sub_mchid是否為服務商的子商戶 |
403 | NO_AUTH | 權限異常 | 請電商平臺在產(chǎn)品中心開通下載二級商戶資金賬單產(chǎn)品權限 |
400 | PARAM_ERROR | 參數(shù)錯誤 | 請使用正確的參數(shù)重新調(diào)用 |
400 | INVALID_REQUEST | 參數(shù)錯誤 | 請檢查bill_date,僅支持下載3個月以內(nèi)的資金流水賬單 |
400 | NO_STATEMENT_EXIST | 請求的賬單文件不存在 | 請檢查二級商戶在指定日期是否有資金操作 |
400 | STATEMENT_CREATING | 賬單生成中 | 請先檢查二級商戶在指定日期內(nèi)是否有資金操作,若有,則在T+1日上午10點后再重新下載 |
429 | FREQUENCY_LIMITED | 請求過于頻繁 | 請降低調(diào)用頻率 |