开具通用行业电子发票
更新时间:2025.09.08商户完成收款后,调用本接口开具通用行业电子发票并插入微信用户的卡包。请求的交易信息必须真实存在。
注意:本接口成功返回仅代表开票请求已被受理,当开票完成时,微信支付会根据商户配置的回调地址进行回调通知,商户也可以通过【查询电子发票】接口获取开票结果及开票信息。
接口说明
支持商户:【普通服务商】
请求方式:【POST】/v3/new-tax-control-fapiao/fapiao-applications/issue-general
请求域名:【主域名】https://api.mch.weixin.qq.com 使用该域名将访问就近的接入点
【备域名】https://api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看
请求参数
Header HTTP头参数
Authorization 必填 string
请参考签名认证生成认证信息
Accept 必填 string
请设置为application/json
Content-Type 必填 string
请设置为application/json
Wechatpay-Serial 必填 string
【微信支付公钥ID】或【微信支付平台证书序列号】 请求参数中的敏感字段,需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引;也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引
body 包体参数
sub_mchid 必填 string(32)
【子商户号】 微信支付分配的子商户号,服务商模式下必传
fapiao_apply_id 必填 string(32)
【发票申请单号】 发票申请单号,唯一标识一次开票行为。当需要开具交易信息为非微信支付渠道的发票时,为调用【获取用户抬头填写链接】接口时指定的发票申请单号
buyer_information 必填 object
【购买方信息】 购买方信息,即发票抬头。若商户使用微信官方抬头,可从【获取用户填写抬头信息】接口获取用户填写的抬头;也可自行收集发票抬头
属性 | |
type 必填 string 【购买方类型】 购买方类型 可选取值
name 必填 string(256) 【名称】 购买方名称 taxpayer_id 选填 string(32) 【纳税人识别号】 购买方纳税人识别号,购买方类型为ORGANIZATION时必填 address 选填 string(128) 【地址】 购买方地址 telephone 选填 string(32) 【电话】 购买方电话 bank_name 选填 string(128) 【开户银行名称】 购买方开户银行名称 bank_account 选填 string(32) 【银行账号】 购买方银行账号 phone 选填 string 【手机号】 用户手机号。注意:该字段为密文字段,作为请求字段需加密,使用微信支付公钥加密(推荐),参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引;也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引;作为响应字段需解密,参考如何使用API证书解密敏感字段 email 选填 string 【邮箱地址】 用户邮箱地址。注意:该字段为密文字段,作为请求字段需加密,使用微信支付公钥加密(推荐),参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引;也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引;作为响应字段需解密,参考如何使用API证书解密敏感字段 amount 选填 integer 【订单金额】 微信支付订单金额,仅在微信支付场景下有效,单位:分 out_trade_no 选填 string(32) 【商户订单号】 商户订单号,仅在微信支付场景下有效 fapiao_bill_type 选填 string 【开具的发票类型】 用户选择提交开具发票的类型 可选取值
user_apply_message 选填 string(100) 【留言信息】 用户申请开票时提交的留言信息 |
fapiao_information 必填 object
【需要开具的数电发票信息】 需要开具的通用行业数电发票信息
属性 | |||||||||
fapiao_id 必填 string(32) 【商户发票单号】 商户发票单号,唯一标识一张要开具的发票。只能是字母、数字、中划线-、下划线_、竖线|、星号*这些英文半角字符,且该单号在每个商户下必须唯一。当申请单下没有状态为开具中/已开具/冲红中的发票时,可以新增fapiao_id开票。1个fapiao_apply_id下最多支持5个fapiao_id total_amount 必填 integer 【总价税合计】 总价税合计,所有发票行单行金额合计的累加,展示在发票的价税合计处,单位:分 注意:所有发票的总价税合计之和不能超过交易的总金额 items 必填 array[object] 【发票行信息】 发票行信息
export_business_policy_code 选填 integer 【出口业务适用政策代码】 1:退税政策; 2:免税政策; 3:征税政策 vat_refund_levy_code 选填 integer 【增值税即征即退代码】 1:软件产品; 2:资源综合利用产品; 3:管道运输服务; 4:有形动产融资租赁服务; 5:有形动产融资性售后回租服务; 6:新型墙体材料; 7:风力发电产品; 8:光伏发电产品; 9:动漫软件产品; 10:飞机维修劳务; 11:黄金; 12:铂金 billing_person_id 必填 string(64) 【开票人ID】 开票人ID billing_person 选填 string(64) 【开票人名称】 开票人名称 fapiao_bill_type 必填 string 【发票类型】 商户提交申请开票的发票类型 可选取值
transaction_information 必填 array[object] 【交易信息】 发票对应的交易信息
remark 选填 string 【发票备注】 发票备注 |
请求示例
POST
1curl -X POST \ 2 https://api.mch.weixin.qq.com/v3/new-tax-control-fapiao/fapiao-applications/issue-general \ 3 -H "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"1900000001\",..." \ 4 -H "Accept: application/json" \ 5 -H "Wechatpay-Serial: 5157F09EFDC096DE15EBE81A47057A7232F1B8E1" \ 6 -H "Content-Type: application/json" \ 7 -d '{ 8 "sub_mchid" : "example_sub_mchid", 9 "fapiao_apply_id" : "example_fapiao_apply_id", 10 "buyer_information" : { 11 "type" : "INDIVIDUAL", 12 "name" : "深圳市南山区测试企业", 13 "taxpayer_id" : "202003261233701778", 14 "address" : "深圳市南山区深南大道10000号", 15 "telephone" : "075512345678", 16 "bank_name" : "测试银行", 17 "bank_account" : "62001234567890", 18 "phone" : "mI7HGEJ4Q2B91IGjHrl7FNN9QuFPDfzeXoaJM4B8ZghZPzXK+vNotEZu/Gthm87Szv0MK2AoC0/3ZMDgltMtdoY6O0qZ4F1iXiwCuqkkBe+9M4ggvdzpPGM+fyed2QU1seUGbii5RVVVB9s+zLEQ8nv74vsgl77MZx14nd5obtCcfAvPfDJob3oG7FqlThmYKJqjiOwBvvQse7p9R8onj/POzSrbM8re8ZYGp4LcehXopTLdk2ZVWRv8bnJgKZWArAcqMdahq4jY2UVYeY4vpMmq4xuRTYk6xNXvowBBKK2SX8SqM+jm1USyoBIazLu4oaNFNdBO3fip1a1rFW0vRw==", 19 "email" : "NzJy3r0Z2u2Vs5l+WSH0A3CZ1oGlCZ66aa2wUlMXNmACbd4wU8LqqYCuTG4cYWxrVUSmviV59/Uy9vLdIwuHZVrMalYAZGtb8inWGhDj3wUqQnPkmBKBVGIWG5Y6XJmMvpXW6rIKsdzxs8NwWj30cRNfjanLxiWc0aIgl8Knwo0JcxlcYLo38T9ntsrRkQZMQEWHaMYnzjp7ysLbp6yW83OZb/NwEufERBdPnIbDbVE7DUd5MGhvO+tlr2YC1b4VCsrDmjryuTD5nvYYCGHyfXW2CM23hZdBm9tPc+mU18Z9d4XkasnfsecGWd2ISkpPmnk3DtapnD64Nw8JyLtkgw==", 20 "amount" : 1000, 21 "out_trade_no" : "order_20200701_123456", 22 "fapiao_bill_type" : "COMM_FAPIAO", 23 "user_apply_message" : "用户留言" 24 }, 25 "fapiao_information" : { 26 "fapiao_id" : "20200701123456", 27 "total_amount" : 382895, 28 "items" : [ 29 { 30 "tax_code" : "3010101020203000000", 31 "goods_name" : "*xxx*服务", 32 "specification" : "米", 33 "unit" : "米", 34 "quantity" : 100000000, 35 "total_amount" : 429900, 36 "tax_rate" : 1300, 37 "discount" : false, 38 "preferential_policy_code" : 1 39 } 40 ], 41 "export_business_policy_code" : 1, 42 "vat_refund_levy_code" : 1, 43 "billing_person_id" : "128279891283", 44 "billing_person" : "example_billing_person", 45 "fapiao_bill_type" : "COMM_FAPIAO", 46 "transaction_information" : [ 47 { 48 "pay_channel" : "WECHAT_PAY", 49 "transaction_id" : "4200000008202508080512076713", 50 "out_trade_no" : "order_20200701_123456", 51 "amount" : 382895 52 } 53 ], 54 "remark" : "备注" 55 } 56 }' 57
需配合微信支付工具库 WXPayUtility 使用,请参考 Java
1package com.java.demo; 2 3import com.java.utils.WXPayUtility; // 引用微信支付工具库,参考:https://pay.weixin.qq.com/doc/v3/partner/4014985777 4 5import com.google.gson.annotations.SerializedName; 6import com.google.gson.annotations.Expose; 7import okhttp3.MediaType; 8import okhttp3.OkHttpClient; 9import okhttp3.Request; 10import okhttp3.RequestBody; 11import okhttp3.Response; 12 13import java.io.IOException; 14import java.io.UncheckedIOException; 15import java.security.PrivateKey; 16import java.security.PublicKey; 17import java.util.ArrayList; 18import java.util.HashMap; 19import java.util.List; 20import java.util.Map; 21 22/** 23 * 开具通用行业电子发票 24 */ 25public class IssueGeneralIndustryFapiaoApplications { 26 private static String HOST = "https://api.mch.weixin.qq.com"; 27 private static String METHOD = "POST"; 28 private static String PATH = "/v3/new-tax-control-fapiao/fapiao-applications/issue-general"; 29 30 public static void main(String[] args) { 31 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 32 IssueGeneralIndustryFapiaoApplications client = new IssueGeneralIndustryFapiaoApplications( 33 "19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340 34 "1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924 35 "/path/to/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径 36 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589 37 "/path/to/wxp_pub.pem" // 微信支付公钥文件路径,本地文件路径 38 ); 39 40 IssueGeneralFapiaoRequest request = new IssueGeneralFapiaoRequest(); 41 request.subMchid = "example_sub_mchid"; 42 request.fapiaoApplyId = "example_fapiao_apply_id"; 43 request.buyerInformation = new UserTitleEntity(); 44 request.buyerInformation.type = BuyerType.INDIVIDUAL; 45 request.buyerInformation.name = "深圳市南山区测试企业"; 46 request.buyerInformation.taxpayerId = "202003261233701778"; 47 request.buyerInformation.address = "深圳市南山区深南大道10000号"; 48 request.buyerInformation.telephone = "075512345678"; 49 request.buyerInformation.bankName = "测试银行"; 50 request.buyerInformation.bankAccount = "62001234567890"; 51 request.buyerInformation.phone = client.encrypt("phone"); 52 request.buyerInformation.email = client.encrypt("email"); 53 request.buyerInformation.amount = 1000L; 54 request.buyerInformation.outTradeNo = "order_20200701_123456"; 55 request.buyerInformation.fapiaoBillType = FapiaoBillType.COMM_FAPIAO; 56 request.buyerInformation.userApplyMessage = "用户留言"; 57 request.fapiaoInformation = new IssueGeneralFapiaoInfo(); 58 request.fapiaoInformation.fapiaoId = "20200701123456"; 59 request.fapiaoInformation.totalAmount = 382895L; 60 request.fapiaoInformation.items = new ArrayList<>(); 61 { 62 IssueGeneralFapiaoItem itemsItem = new IssueGeneralFapiaoItem(); 63 itemsItem.taxCode = "3010101020203000000"; 64 itemsItem.goodsName = "*xxx*服务"; 65 itemsItem.specification = "米"; 66 itemsItem.unit = "米"; 67 itemsItem.quantity = 100000000L; 68 itemsItem.totalAmount = 429900L; 69 itemsItem.taxRate = 1300L; 70 itemsItem.discount = false; 71 itemsItem.preferentialPolicyCode = 1L; 72 request.fapiaoInformation.items.add(itemsItem); 73 }; 74 request.fapiaoInformation.exportBusinessPolicyCode = 1L; 75 request.fapiaoInformation.vatRefundLevyCode = 1L; 76 request.fapiaoInformation.billingPersonId = "128279891283"; 77 request.fapiaoInformation.billingPerson = "example_billing_person"; 78 request.fapiaoInformation.fapiaoBillType = FapiaoBillType.COMM_FAPIAO; 79 request.fapiaoInformation.transactionInformation = new ArrayList<>(); 80 { 81 TransactionInfo transactionInformationItem = new TransactionInfo(); 82 transactionInformationItem.payChannel = PayChannel.WECHAT_PAY; 83 transactionInformationItem.transactionId = "4200000008202508080512076713"; 84 transactionInformationItem.outTradeNo = "order_20200701_123456"; 85 transactionInformationItem.amount = 382895L; 86 request.fapiaoInformation.transactionInformation.add(transactionInformationItem); 87 }; 88 request.fapiaoInformation.remark = "备注"; 89 try { 90 client.run(request); 91 } catch (WXPayUtility.ApiException e) { 92 // TODO: 请求失败,根据状态码执行不同的逻辑 93 e.printStackTrace(); 94 } 95 } 96 97 public void run(IssueGeneralFapiaoRequest request) { 98 String uri = PATH; 99 String reqBody = WXPayUtility.toJson(request); 100 101 Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); 102 reqBuilder.addHeader("Accept", "application/json"); 103 reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); 104 reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo,privateKey, METHOD, uri, reqBody)); 105 reqBuilder.addHeader("Content-Type", "application/json"); 106 RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody); 107 reqBuilder.method(METHOD, requestBody); 108 Request httpRequest = reqBuilder.build(); 109 110 // 发送HTTP请求 111 OkHttpClient client = new OkHttpClient.Builder().build(); 112 try (Response httpResponse = client.newCall(httpRequest).execute()) { 113 String respBody = WXPayUtility.extractBody(httpResponse); 114 if (httpResponse.code() >= 200 && httpResponse.code() < 300) { 115 // 2XX 成功,验证应答签名 116 WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, 117 httpResponse.headers(), respBody); 118 119 return; 120 } else { 121 throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); 122 } 123 } catch (IOException e) { 124 throw new UncheckedIOException("Sending request to " + uri + " failed.", e); 125 } 126 } 127 128 private final String mchid; 129 private final String certificateSerialNo; 130 private final PrivateKey privateKey; 131 private final String wechatPayPublicKeyId; 132 private final PublicKey wechatPayPublicKey; 133 134 public IssueGeneralIndustryFapiaoApplications(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { 135 this.mchid = mchid; 136 this.certificateSerialNo = certificateSerialNo; 137 this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath); 138 this.wechatPayPublicKeyId = wechatPayPublicKeyId; 139 this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); 140 } 141 142 public String encrypt(String plainText) { 143 return WXPayUtility.encrypt(this.wechatPayPublicKey, plainText); 144 } 145 146 public static class IssueGeneralFapiaoRequest { 147 @SerializedName("sub_mchid") 148 public String subMchid; 149 150 @SerializedName("fapiao_apply_id") 151 public String fapiaoApplyId; 152 153 @SerializedName("buyer_information") 154 public UserTitleEntity buyerInformation; 155 156 @SerializedName("fapiao_information") 157 public IssueGeneralFapiaoInfo fapiaoInformation; 158 } 159 160 public static class UserTitleEntity { 161 @SerializedName("type") 162 public BuyerType type; 163 164 @SerializedName("name") 165 public String name; 166 167 @SerializedName("taxpayer_id") 168 public String taxpayerId; 169 170 @SerializedName("address") 171 public String address; 172 173 @SerializedName("telephone") 174 public String telephone; 175 176 @SerializedName("bank_name") 177 public String bankName; 178 179 @SerializedName("bank_account") 180 public String bankAccount; 181 182 @SerializedName("phone") 183 public String phone; 184 185 @SerializedName("email") 186 public String email; 187 188 @SerializedName("amount") 189 public Long amount; 190 191 @SerializedName("out_trade_no") 192 public String outTradeNo; 193 194 @SerializedName("fapiao_bill_type") 195 public FapiaoBillType fapiaoBillType; 196 197 @SerializedName("user_apply_message") 198 public String userApplyMessage; 199 } 200 201 public static class IssueGeneralFapiaoInfo { 202 @SerializedName("fapiao_id") 203 public String fapiaoId; 204 205 @SerializedName("total_amount") 206 public Long totalAmount; 207 208 @SerializedName("items") 209 public List<IssueGeneralFapiaoItem> items = new ArrayList<IssueGeneralFapiaoItem>(); 210 211 @SerializedName("export_business_policy_code") 212 public Long exportBusinessPolicyCode; 213 214 @SerializedName("vat_refund_levy_code") 215 public Long vatRefundLevyCode; 216 217 @SerializedName("billing_person_id") 218 public String billingPersonId; 219 220 @SerializedName("billing_person") 221 public String billingPerson; 222 223 @SerializedName("fapiao_bill_type") 224 public FapiaoBillType fapiaoBillType; 225 226 @SerializedName("transaction_information") 227 public List<TransactionInfo> transactionInformation = new ArrayList<TransactionInfo>(); 228 229 @SerializedName("remark") 230 public String remark; 231 } 232 233 public enum BuyerType { 234 @SerializedName("INDIVIDUAL") 235 INDIVIDUAL, 236 @SerializedName("ORGANIZATION") 237 ORGANIZATION 238 } 239 240 public enum FapiaoBillType { 241 @SerializedName("COMM_FAPIAO") 242 COMM_FAPIAO, 243 @SerializedName("VAT_FAPIAO") 244 VAT_FAPIAO 245 } 246 247 public static class IssueGeneralFapiaoItem { 248 @SerializedName("tax_code") 249 public String taxCode; 250 251 @SerializedName("goods_name") 252 public String goodsName; 253 254 @SerializedName("specification") 255 public String specification; 256 257 @SerializedName("unit") 258 public String unit; 259 260 @SerializedName("quantity") 261 public Long quantity; 262 263 @SerializedName("total_amount") 264 public Long totalAmount; 265 266 @SerializedName("tax_rate") 267 public Long taxRate; 268 269 @SerializedName("discount") 270 public Boolean discount; 271 272 @SerializedName("preferential_policy_code") 273 public Long preferentialPolicyCode; 274 } 275 276 public static class TransactionInfo { 277 @SerializedName("pay_channel") 278 public PayChannel payChannel; 279 280 @SerializedName("transaction_id") 281 public String transactionId; 282 283 @SerializedName("out_trade_no") 284 public String outTradeNo; 285 286 @SerializedName("amount") 287 public Long amount; 288 } 289 290 public enum PayChannel { 291 @SerializedName("WECHAT_PAY") 292 WECHAT_PAY 293 } 294 295} 296
需配合微信支付工具库 wxpay_utility 使用,请参考 Go
1package main 2 3import ( 4 "bytes" 5 "demo/wxpay_utility" // 引用微信支付工具库,参考 https://pay.weixin.qq.com/doc/v3/partner/4015119446 6 "encoding/json" 7 "fmt" 8 "net/http" 9 "net/url" 10) 11 12func main() { 13 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 14 config, err := wxpay_utility.CreateMchConfig( 15 "19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340 16 "1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924 17 "/path/to/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径 18 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589 19 "/path/to/wxp_pub.pem", // 微信支付公钥文件路径,本地文件路径 20 ) 21 if err != nil { 22 fmt.Println(err) 23 return 24 } 25 26 request := &IssueGeneralFapiaoRequest{ 27 SubMchid: wxpay_utility.String("example_sub_mchid"), 28 FapiaoApplyId: wxpay_utility.String("example_fapiao_apply_id"), 29 BuyerInformation: &UserTitleEntity{ 30 Type: BUYERTYPE_INDIVIDUAL.Ptr(), 31 Name: wxpay_utility.String("深圳市南山区测试企业"), 32 TaxpayerId: wxpay_utility.String("202003261233701778"), 33 Address: wxpay_utility.String("深圳市南山区深南大道10000号"), 34 Telephone: wxpay_utility.String("075512345678"), 35 BankName: wxpay_utility.String("测试银行"), 36 BankAccount: wxpay_utility.String("62001234567890"), 37 Phone: wxpay_utility.String("mI7HGEJ4Q2B91IGjHrl7FNN9QuFPDfzeXoaJM4B8ZghZPzXK+vNotEZu/Gthm87Szv0MK2AoC0/3ZMDgltMtdoY6O0qZ4F1iXiwCuqkkBe+9M4ggvdzpPGM+fyed2QU1seUGbii5RVVVB9s+zLEQ8nv74vsgl77MZx14nd5obtCcfAvPfDJob3oG7FqlThmYKJqjiOwBvvQse7p9R8onj/POzSrbM8re8ZYGp4LcehXopTLdk2ZVWRv8bnJgKZWArAcqMdahq4jY2UVYeY4vpMmq4xuRTYk6xNXvowBBKK2SX8SqM+jm1USyoBIazLu4oaNFNdBO3fip1a1rFW0vRw=="), /*请传入 wxpay_utility.EncryptOAEPWithPublicKey 加密结果*/ 38 Email: wxpay_utility.String("NzJy3r0Z2u2Vs5l+WSH0A3CZ1oGlCZ66aa2wUlMXNmACbd4wU8LqqYCuTG4cYWxrVUSmviV59/Uy9vLdIwuHZVrMalYAZGtb8inWGhDj3wUqQnPkmBKBVGIWG5Y6XJmMvpXW6rIKsdzxs8NwWj30cRNfjanLxiWc0aIgl8Knwo0JcxlcYLo38T9ntsrRkQZMQEWHaMYnzjp7ysLbp6yW83OZb/NwEufERBdPnIbDbVE7DUd5MGhvO+tlr2YC1b4VCsrDmjryuTD5nvYYCGHyfXW2CM23hZdBm9tPc+mU18Z9d4XkasnfsecGWd2ISkpPmnk3DtapnD64Nw8JyLtkgw=="), /*请传入 wxpay_utility.EncryptOAEPWithPublicKey 加密结果*/ 39 Amount: wxpay_utility.Int64(1000), 40 OutTradeNo: wxpay_utility.String("order_20200701_123456"), 41 FapiaoBillType: FAPIAOBILLTYPE_COMM_FAPIAO.Ptr(), 42 UserApplyMessage: wxpay_utility.String("用户留言"), 43 }, 44 FapiaoInformation: &IssueGeneralFapiaoInfo{ 45 FapiaoId: wxpay_utility.String("20200701123456"), 46 TotalAmount: wxpay_utility.Int64(382895), 47 Items: []IssueGeneralFapiaoItem{IssueGeneralFapiaoItem{ 48 TaxCode: wxpay_utility.String("3010101020203000000"), 49 GoodsName: wxpay_utility.String("*xxx*服务"), 50 Specification: wxpay_utility.String("米"), 51 Unit: wxpay_utility.String("米"), 52 Quantity: wxpay_utility.Int64(100000000), 53 TotalAmount: wxpay_utility.Int64(429900), 54 TaxRate: wxpay_utility.Int64(1300), 55 Discount: wxpay_utility.Bool(false), 56 PreferentialPolicyCode: wxpay_utility.Int64(1), 57 }}, 58 ExportBusinessPolicyCode: wxpay_utility.Int64(1), 59 VatRefundLevyCode: wxpay_utility.Int64(1), 60 BillingPersonId: wxpay_utility.String("128279891283"), 61 BillingPerson: wxpay_utility.String("example_billing_person"), 62 FapiaoBillType: FAPIAOBILLTYPE_COMM_FAPIAO.Ptr(), 63 TransactionInformation: []TransactionInfo{TransactionInfo{ 64 PayChannel: PAYCHANNEL_WECHAT_PAY.Ptr(), 65 TransactionId: wxpay_utility.String("4200000008202508080512076713"), 66 OutTradeNo: wxpay_utility.String("order_20200701_123456"), 67 Amount: wxpay_utility.Int64(382895), 68 }}, 69 Remark: wxpay_utility.String("备注"), 70 }, 71 } 72 73 err = IssueGeneralIndustryFapiaoApplications(config, request) 74 if err != nil { 75 fmt.Printf("请求失败: %+v\n", err) 76 // TODO: 请求失败,根据状态码执行不同的处理 77 return 78 } 79 80 // TODO: 请求成功,继续业务逻辑 81 fmt.Println("请求成功") 82} 83 84func IssueGeneralIndustryFapiaoApplications(config *wxpay_utility.MchConfig, request *IssueGeneralFapiaoRequest) (err error) { 85 const ( 86 host = "https://api.mch.weixin.qq.com" 87 method = "POST" 88 path = "/v3/new-tax-control-fapiao/fapiao-applications/issue-general" 89 ) 90 91 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path)) 92 if err != nil { 93 return err 94 } 95 reqBody, err := json.Marshal(request) 96 if err != nil { 97 return err 98 } 99 httpRequest, err := http.NewRequest(method, reqUrl.String(), bytes.NewReader(reqBody)) 100 if err != nil { 101 return err 102 } 103 httpRequest.Header.Set("Accept", "application/json") 104 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId()) 105 httpRequest.Header.Set("Content-Type", "application/json") 106 authorization, err := wxpay_utility.BuildAuthorization(config.MchId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), reqBody) 107 if err != nil { 108 return err 109 } 110 httpRequest.Header.Set("Authorization", authorization) 111 112 client := &http.Client{} 113 httpResponse, err := client.Do(httpRequest) 114 if err != nil { 115 return err 116 } 117 respBody, err := wxpay_utility.ExtractResponseBody(httpResponse) 118 if err != nil { 119 return err 120 } 121 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 { 122 // 2XX 成功,验证应答签名 123 err = wxpay_utility.ValidateResponse( 124 config.WechatPayPublicKeyId(), 125 config.WechatPayPublicKey(), 126 &httpResponse.Header, 127 respBody, 128 ) 129 if err != nil { 130 return err 131 } 132 return nil 133 } else { 134 return wxpay_utility.NewApiException( 135 httpResponse.StatusCode, 136 httpResponse.Header, 137 respBody, 138 ) 139 } 140} 141 142type IssueGeneralFapiaoRequest struct { 143 SubMchid *string `json:"sub_mchid,omitempty"` 144 FapiaoApplyId *string `json:"fapiao_apply_id,omitempty"` 145 BuyerInformation *UserTitleEntity `json:"buyer_information,omitempty"` 146 FapiaoInformation *IssueGeneralFapiaoInfo `json:"fapiao_information,omitempty"` 147} 148 149type UserTitleEntity struct { 150 Type *BuyerType `json:"type,omitempty"` 151 Name *string `json:"name,omitempty"` 152 TaxpayerId *string `json:"taxpayer_id,omitempty"` 153 Address *string `json:"address,omitempty"` 154 Telephone *string `json:"telephone,omitempty"` 155 BankName *string `json:"bank_name,omitempty"` 156 BankAccount *string `json:"bank_account,omitempty"` 157 Phone *string `json:"phone,omitempty"` 158 Email *string `json:"email,omitempty"` 159 Amount *int64 `json:"amount,omitempty"` 160 OutTradeNo *string `json:"out_trade_no,omitempty"` 161 FapiaoBillType *FapiaoBillType `json:"fapiao_bill_type,omitempty"` 162 UserApplyMessage *string `json:"user_apply_message,omitempty"` 163} 164 165type IssueGeneralFapiaoInfo struct { 166 FapiaoId *string `json:"fapiao_id,omitempty"` 167 TotalAmount *int64 `json:"total_amount,omitempty"` 168 Items []IssueGeneralFapiaoItem `json:"items,omitempty"` 169 ExportBusinessPolicyCode *int64 `json:"export_business_policy_code,omitempty"` 170 VatRefundLevyCode *int64 `json:"vat_refund_levy_code,omitempty"` 171 BillingPersonId *string `json:"billing_person_id,omitempty"` 172 BillingPerson *string `json:"billing_person,omitempty"` 173 FapiaoBillType *FapiaoBillType `json:"fapiao_bill_type,omitempty"` 174 TransactionInformation []TransactionInfo `json:"transaction_information,omitempty"` 175 Remark *string `json:"remark,omitempty"` 176} 177 178type BuyerType string 179 180func (e BuyerType) Ptr() *BuyerType { 181 return &e 182} 183 184const ( 185 BUYERTYPE_INDIVIDUAL BuyerType = "INDIVIDUAL" 186 BUYERTYPE_ORGANIZATION BuyerType = "ORGANIZATION" 187) 188 189type FapiaoBillType string 190 191func (e FapiaoBillType) Ptr() *FapiaoBillType { 192 return &e 193} 194 195const ( 196 FAPIAOBILLTYPE_COMM_FAPIAO FapiaoBillType = "COMM_FAPIAO" 197 FAPIAOBILLTYPE_VAT_FAPIAO FapiaoBillType = "VAT_FAPIAO" 198) 199 200type IssueGeneralFapiaoItem struct { 201 TaxCode *string `json:"tax_code,omitempty"` 202 GoodsName *string `json:"goods_name,omitempty"` 203 Specification *string `json:"specification,omitempty"` 204 Unit *string `json:"unit,omitempty"` 205 Quantity *int64 `json:"quantity,omitempty"` 206 TotalAmount *int64 `json:"total_amount,omitempty"` 207 TaxRate *int64 `json:"tax_rate,omitempty"` 208 Discount *bool `json:"discount,omitempty"` 209 PreferentialPolicyCode *int64 `json:"preferential_policy_code,omitempty"` 210} 211 212type TransactionInfo struct { 213 PayChannel *PayChannel `json:"pay_channel,omitempty"` 214 TransactionId *string `json:"transaction_id,omitempty"` 215 OutTradeNo *string `json:"out_trade_no,omitempty"` 216 Amount *int64 `json:"amount,omitempty"` 217} 218 219type PayChannel string 220 221func (e PayChannel) Ptr() *PayChannel { 222 return &e 223} 224 225const ( 226 PAYCHANNEL_WECHAT_PAY PayChannel = "WECHAT_PAY" 227) 228
应答参数
无应答包体
应答示例
202 Accepted
1'无应答包体' 2
错误码
公共错误码
状态码 | 错误码 | 描述 | 解决方案 |
---|---|---|---|
400 | PARAM_ERROR | 参数错误 | 请根据错误提示正确传入参数 |
400 | INVALID_REQUEST | HTTP 请求不符合微信支付 APIv3 接口规则 | 请参阅 接口规则 |
401 | SIGN_ERROR | 验证不通过 | 请参阅 签名常见问题 |
500 | SYSTEM_ERROR | 系统异常,请稍后重试 | 请稍后重试 |
业务错误码
状态码 | 错误码 | 描述 | 解决方案 |
---|---|---|---|
400 | INVALID_REQUEST | 请求参数符合参数格式,但不符合业务规则 | 请使用正确的参数重新调用 |
400 | RESOURCE_ALREADY_EXISTS | 发票申请单已存在 | 请稍后调用【查询电子发票】接口获取开票结果 |
400 | INVALID_REQUEST | 当前发票开具中,不可申请重开发票 | 请在调用【查询电子发票】接口获取发票状态 |
400 | INVALID_REQUEST | 当前发票冲红中,不可申请重开发票 | 请在调用【查询电子发票】接口获取发票状态 |
400 | INVALID_REQUEST | 申请开票次数,超过最大限制 | 请在调用【查询电子发票】接口获取当前发票已冲红后,换发票申请单号重试开票 |
400 | INVALID_REQUEST | 开票请求已被受理,请调用【查询电子发票】接口获取开票结果 | 开票请求已被受理,请调用【查询电子发票】接口获取开票结果 |
400 | INVALID_REQUEST | 交易单已申请开票,两次申请的交易金额不相同 | 修改交易单金额重试 |
400 | INVALID_REQUEST | 交易可剩余开票金额不足 | 修改交易订单或者开票金额重试 |
403 | NO_AUTH | 商户乐企不动产租赁发票能力未授权 | 确认商户是否发起不动产租赁发票能力邀请授权,以及电子税局确认操作。确认无误,请稍后重试 |
403 | NO_AUTH | 商户无权限 | 请检查是否已经开通电子发票产品相关功能权限 |
403 | RULE_LIMIT | 商户尚未配置电子发票卡券模板信息 | 请先调用【创建电子发票卡券模板】接口成功后再重新调用 |
403 | RULE_LIMIT | 商户不可对该货物或应税劳务、服务编码开具发票 | 请检查参数中的货物或应税劳务、服务编码是否在【获取商品和服务税收分类对照表】接口返回的数据中 |
403 | RULE_LIMIT | 商户提交的购买方信息与用户填写的发票抬头不一致 | 请检查参数中的购买方信息与【获取用户填写抬头信息】接口返回的发票抬头信息是否一致 |
403 | RULE_LIMIT | 微信支付订单所属商户与当前商户不一致(仅微信支付场景) | 请检查微信支付订单号是否属于子商户 |
404 | RESOURCE_NOT_EXISTS | 用户尚未完成发票抬头填写(仅非微信支付场景) | 请在调用【获取用户填写抬头信息】接口成功后再以相同发票申请单号重新调用 |
429 | FREQUENCY_LIMITED | 频率超限 | 请降低请求接口频率 |