获取开通服务商电子发票能力邀请链接
更新时间:2025.12.03服务商可通过此接口创建并获取开通服务商电子发票邀请链接,商户使用微信扫码/点击链接进行授权开通。
接口说明
支持商户:【普通服务商】
请求方式:【GET】/v3/new-tax-control-fapiao/fapiaomerchant/getspinviteurl
请求域名:【主域名】https://api.mch.weixin.qq.com 使用该域名将访问就近的接入点
【备域名】https://api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看
请求参数
Header HTTP头参数
Authorization 必填 string
请参考签名认证生成认证信息
Accept 必填 string
请设置为application/json
Wechatpay-Serial 必填 string
【微信支付公钥ID】或【微信支付平台证书序列号】 请求参数中的敏感字段,需要使用微信支付公钥加密(推荐),请参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引;也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引
query 查询参数
operation_type 必填 string
【操作类型】 商户接受请求后的操作类型
可选取值
AUTH_BINDING: 授权绑定
fapiao_mode 必填 array[string]
【开票模式】 邀请商户开通服务商电子发票的可选开票模式
可选取值
THIRD_OR_SELF_FAPIAO: 第三方/自建发票,即使用自有或其他第三方发票系统生成发票TENCENT_DIGITAL_TAX: 腾讯数电发票,即使用腾讯数电发票系统生成发票
fapiao_ability_type_list 选填 array[string]
【发票能力类型】 邀请商户开通的腾讯数电发票能力类型,可以选择多个。当开票模式为TENCENT_DIGITAL_TAX时必填
可选取值
BASE_ABILITY: 基础开票能力(适合餐饮、酒店等)REAL_ESTATE_ABILITY: 不动产租赁能力(适合停车场等)REFINED_OIL_ABILITY: 成品油能力(适合石油石化等行业)
invite_channel 选填 string(128)
【服务商邀请渠道】 服务商自定义的渠道信息,用于标识该邀请从哪个渠道发起
operate_user 选填 string
【操作人员】 服务商邀请操作人员信息,用于标识该邀请是哪个人员发起。
注意:该字段为密文字段,需要使用微信支付公钥加密(推荐),参考获取微信支付公钥ID说明以及微信支付公钥加密敏感信息指引;也可以使用微信支付平台证书公钥加密,参考获取平台证书序列号、平台证书加密敏感信息指引
invite_code 必填 string(128)
【服务商邀请code】 服务商邀请的唯一标识,由服务商生成,可根据邀请code查询邀请开通情况
sub_mchid 选填 string(32)
【受邀请商户号】 受服务商邀请开通电子发票能力的商户号,受邀商户号和受邀税号不能同时填
taxpayer_id 选填 string(20)
【受邀请商户税号】 受服务商邀请开通电子发票能力的税号,保证受邀请商户提交的商户信息与提交邀请的税号保持一致,受邀商户号和受邀税号不能同时填
请求示例
GET
1curl -X GET \ 2 https://api.mch.weixin.qq.com/v3/new-tax-control-fapiao/fapiaomerchant/getspinviteurl?operation_type=AUTH_BINDING&fapiao_mode=TENCENT_DIGITAL_TAX&fapiao_ability_type_list=BASE_ABILITY&invite_channel=miniprogram&operate_user=mI7HGEJ4Q2B91IGjHZu/Gthm87Szv0MK2AoC0/3ZMDgltMtdoY6O0qZ4F1iXiwCuqkkBe+9M4ggvdzRVVVB9s+zLEQ8nv74vsgl77MZx14nd5obtCcfAvPfDJob3oG7FqlThmYKJqjiOwBvvQse7p9R8onj/POzSrbM8re8ZYGp4LcehXopTLdk2ZVWRv8bnJgKZeY4vpMmq4xuRTYk6xNXvowBBKLu4oaNFNdBO3fip1a1rFW0vRw==&invite_code=code_20200101_123&sub_mchid=19998278783&taxpayer_id=202003261233701778 \ 3 -H "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"1900000001\",..." \ 4 -H "Accept: application/json" \ 5 -H "Wechatpay-Serial: 5157F09EFDC096DE15EBE81A47057A7232F1B8E1" 6
需配合微信支付工具库 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 GetSpInviteUrl { 26 private static String HOST = "https://api.mch.weixin.qq.com"; 27 private static String METHOD = "GET"; 28 private static String PATH = "/v3/new-tax-control-fapiao/fapiaomerchant/getspinviteurl"; 29 30 public static void main(String[] args) { 31 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 32 GetSpInviteUrl client = new GetSpInviteUrl( 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 GetSpInviteUrlRequest request = new GetSpInviteUrlRequest(); 41 request.operationType = InviteOperationType.AUTH_BINDING; 42 request.fapiaoMode = new ArrayList<>(); 43{ 44 request.fapiaoMode.add(InvoiceMode.THIRD_OR_SELF_FAPIAO); 45}; 46 request.fapiaoAbilityTypeList = new ArrayList<>(); 47{ 48 request.fapiaoAbilityTypeList.add(FapiaoAbilityType.BASE_ABILITY); 49}; 50 request.inviteChannel = "miniprogram"; 51 request.operateUser = "mI7HGEJ4Q2B91IGjHZu/Gthm87Szv0MK2AoC0/3ZMDgltMtdoY6O0qZ4F1iXiwCuqkkBe+9M4ggvdzRVVVB9s+zLEQ8nv74vsgl77MZx14nd5obtCcfAvPfDJob3oG7FqlThmYKJqjiOwBvvQse7p9R8onj/POzSrbM8re8ZYGp4LcehXopTLdk2ZVWRv8bnJgKZeY4vpMmq4xuRTYk6xNXvowBBKLu4oaNFNdBO3fip1a1rFW0vRw=="; 52 request.inviteCode = "code_20200101_123"; 53 request.subMchid = "19998278783"; 54 request.taxpayerId = "202003261233701778"; 55 try { 56 GetSpInviteUrlResp response = client.run(request); 57 // TODO: 请求成功,继续业务逻辑 58 System.out.println(response); 59 } catch (WXPayUtility.ApiException e) { 60 // TODO: 请求失败,根据状态码执行不同的逻辑 61 e.printStackTrace(); 62 } 63 } 64 65 public GetSpInviteUrlResp run(GetSpInviteUrlRequest request) { 66 String uri = PATH; 67 Map<String, Object> args = new HashMap<>(); 68 args.put("operation_type", request.operationType); 69 args.put("fapiao_mode", request.fapiaoMode); 70 args.put("fapiao_ability_type_list", request.fapiaoAbilityTypeList); 71 args.put("invite_channel", request.inviteChannel); 72 args.put("operate_user", request.operateUser); 73 args.put("invite_code", request.inviteCode); 74 args.put("sub_mchid", request.subMchid); 75 args.put("taxpayer_id", request.taxpayerId); 76 String queryString = WXPayUtility.urlEncode(args); 77 if (!queryString.isEmpty()) { 78 uri = uri + "?" + queryString; 79 } 80 81 Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); 82 reqBuilder.addHeader("Accept", "application/json"); 83 reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); 84 reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, null)); 85 reqBuilder.method(METHOD, null); 86 Request httpRequest = reqBuilder.build(); 87 88 // 发送HTTP请求 89 OkHttpClient client = new OkHttpClient.Builder().build(); 90 try (Response httpResponse = client.newCall(httpRequest).execute()) { 91 String respBody = WXPayUtility.extractBody(httpResponse); 92 if (httpResponse.code() >= 200 && httpResponse.code() < 300) { 93 // 2XX 成功,验证应答签名 94 WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, 95 httpResponse.headers(), respBody); 96 97 // 从HTTP应答报文构建返回数据 98 return WXPayUtility.fromJson(respBody, GetSpInviteUrlResp.class); 99 } else { 100 throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); 101 } 102 } catch (IOException e) { 103 throw new UncheckedIOException("Sending request to " + uri + " failed.", e); 104 } 105 } 106 107 private final String mchid; 108 private final String certificateSerialNo; 109 private final PrivateKey privateKey; 110 private final String wechatPayPublicKeyId; 111 private final PublicKey wechatPayPublicKey; 112 113 public GetSpInviteUrl(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { 114 this.mchid = mchid; 115 this.certificateSerialNo = certificateSerialNo; 116 this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath); 117 this.wechatPayPublicKeyId = wechatPayPublicKeyId; 118 this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); 119 } 120 121 public String encrypt(String plainText) { 122 return WXPayUtility.encrypt(this.wechatPayPublicKey, plainText); 123 } 124 125 public static class GetSpInviteUrlRequest { 126 @SerializedName("fapiao_mode") 127 @Expose(serialize = false) 128 public List<InvoiceMode> fapiaoMode = new ArrayList<InvoiceMode>(); 129 130 @SerializedName("fapiao_ability_type_list") 131 @Expose(serialize = false) 132 public List<FapiaoAbilityType> fapiaoAbilityTypeList; 133 134 @SerializedName("invite_channel") 135 @Expose(serialize = false) 136 public String inviteChannel; 137 138 @SerializedName("operate_user") 139 @Expose(serialize = false) 140 public String operateUser; 141 142 @SerializedName("invite_code") 143 @Expose(serialize = false) 144 public String inviteCode; 145 146 @SerializedName("sub_mchid") 147 @Expose(serialize = false) 148 public String subMchid; 149 150 @SerializedName("taxpayer_id") 151 @Expose(serialize = false) 152 public String taxpayerId; 153 154 @SerializedName("operation_type") 155 @Expose(serialize = false) 156 public InviteOperationType operationType; 157 } 158 159 public static class GetSpInviteUrlResp { 160 @SerializedName("invite_url") 161 public String inviteUrl; 162 163 @SerializedName("miniprogram_appid") 164 public String miniprogramAppid; 165 166 @SerializedName("miniprogram_path") 167 public String miniprogramPath; 168 } 169 170 public enum InvoiceMode { 171 @SerializedName("THIRD_OR_SELF_FAPIAO") 172 THIRD_OR_SELF_FAPIAO, 173 @SerializedName("TENCENT_DIGITAL_TAX") 174 TENCENT_DIGITAL_TAX 175 } 176 177 public enum FapiaoAbilityType { 178 @SerializedName("BASE_ABILITY") 179 BASE_ABILITY, 180 @SerializedName("REAL_ESTATE_ABILITY") 181 REAL_ESTATE_ABILITY, 182 @SerializedName("REFINED_OIL_ABILITY") 183 REFINED_OIL_ABILITY 184 } 185 186 public enum InviteOperationType { 187 @SerializedName("AUTH_BINDING") 188 AUTH_BINDING 189 } 190 191} 192
需配合微信支付工具库 wxpay_utility 使用,请参考Go
1package main 2 3import ( 4 "demo/wxpay_utility" // 引用微信支付工具库,参考 https://pay.weixin.qq.com/doc/v3/partner/4015119446 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/url" 9) 10 11func main() { 12 // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340 13 config, err := wxpay_utility.CreateMchConfig( 14 "19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340 15 "1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924 16 "/path/to/apiclient_key.pem", // 商户API证书私钥文件路径,本地文件路径 17 "PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589 18 "/path/to/wxp_pub.pem", // 微信支付公钥文件路径,本地文件路径 19 ) 20 if err != nil { 21 fmt.Println(err) 22 return 23 } 24 25 request := &GetSpInviteUrlRequest{ 26 OperationType: INVITEOPERATIONTYPE_AUTH_BINDING.Ptr(), 27 FapiaoMode: []InvoiceMode{INVOICEMODE_THIRD_OR_SELF_FAPIAO}, 28 FapiaoAbilityTypeList: []FapiaoAbilityType{FAPIAOABILITYTYPE_BASE_ABILITY}, 29 InviteChannel: wxpay_utility.String("miniprogram"), 30 OperateUser: wxpay_utility.String("mI7HGEJ4Q2B91IGjHZu/Gthm87Szv0MK2AoC0/3ZMDgltMtdoY6O0qZ4F1iXiwCuqkkBe+9M4ggvdzRVVVB9s+zLEQ8nv74vsgl77MZx14nd5obtCcfAvPfDJob3oG7FqlThmYKJqjiOwBvvQse7p9R8onj/POzSrbM8re8ZYGp4LcehXopTLdk2ZVWRv8bnJgKZeY4vpMmq4xuRTYk6xNXvowBBKLu4oaNFNdBO3fip1a1rFW0vRw=="), 31 InviteCode: wxpay_utility.String("code_20200101_123"), 32 SubMchid: wxpay_utility.String("19998278783"), 33 TaxpayerId: wxpay_utility.String("202003261233701778"), 34 } 35 36 response, err := GetSpInviteUrl(config, request) 37 if err != nil { 38 fmt.Printf("请求失败: %+v\n", err) 39 // TODO: 请求失败,根据状态码执行不同的处理 40 return 41 } 42 43 // TODO: 请求成功,继续业务逻辑 44 fmt.Printf("请求成功: %+v\n", response) 45} 46 47func GetSpInviteUrl(config *wxpay_utility.MchConfig, request *GetSpInviteUrlRequest) (response *GetSpInviteUrlResp, err error) { 48 const ( 49 host = "https://api.mch.weixin.qq.com" 50 method = "GET" 51 path = "/v3/new-tax-control-fapiao/fapiaomerchant/getspinviteurl" 52 ) 53 54 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path)) 55 if err != nil { 56 return nil, err 57 } 58 query := reqUrl.Query() 59 if request.OperationType != nil { 60 query.Add("operation_type", fmt.Sprintf("%v", *request.OperationType)) 61 } 62 if request.FapiaoMode != nil { 63 query.Add("fapiao_mode", fmt.Sprintf("%v", *request.FapiaoMode)) 64 } 65 if request.FapiaoAbilityTypeList != nil { 66 query.Add("fapiao_ability_type_list", fmt.Sprintf("%v", *request.FapiaoAbilityTypeList)) 67 } 68 if request.InviteChannel != nil { 69 query.Add("invite_channel", *request.InviteChannel) 70 } 71 if request.OperateUser != nil { 72 query.Add("operate_user", *request.OperateUser) 73 } 74 if request.InviteCode != nil { 75 query.Add("invite_code", *request.InviteCode) 76 } 77 if request.SubMchid != nil { 78 query.Add("sub_mchid", *request.SubMchid) 79 } 80 if request.TaxpayerId != nil { 81 query.Add("taxpayer_id", *request.TaxpayerId) 82 } 83 reqUrl.RawQuery = query.Encode() 84 httpRequest, err := http.NewRequest(method, reqUrl.String(), nil) 85 if err != nil { 86 return nil, err 87 } 88 httpRequest.Header.Set("Accept", "application/json") 89 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId()) 90 authorization, err := wxpay_utility.BuildAuthorization(config.MchId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), nil) 91 if err != nil { 92 return nil, err 93 } 94 httpRequest.Header.Set("Authorization", authorization) 95 96 client := &http.Client{} 97 httpResponse, err := client.Do(httpRequest) 98 if err != nil { 99 return nil, err 100 } 101 respBody, err := wxpay_utility.ExtractResponseBody(httpResponse) 102 if err != nil { 103 return nil, err 104 } 105 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 { 106 // 2XX 成功,验证应答签名 107 err = wxpay_utility.ValidateResponse( 108 config.WechatPayPublicKeyId(), 109 config.WechatPayPublicKey(), 110 &httpResponse.Header, 111 respBody, 112 ) 113 if err != nil { 114 return nil, err 115 } 116 response := &GetSpInviteUrlResp{} 117 if err := json.Unmarshal(respBody, response); err != nil { 118 return nil, err 119 } 120 121 return response, nil 122 } else { 123 return nil, wxpay_utility.NewApiException( 124 httpResponse.StatusCode, 125 httpResponse.Header, 126 respBody, 127 ) 128 } 129} 130 131type GetSpInviteUrlRequest struct { 132 FapiaoMode []InvoiceMode `json:"fapiao_mode,omitempty"` 133 FapiaoAbilityTypeList []FapiaoAbilityType `json:"fapiao_ability_type_list,omitempty"` 134 InviteChannel *string `json:"invite_channel,omitempty"` 135 OperateUser *string `json:"operate_user,omitempty"` 136 InviteCode *string `json:"invite_code,omitempty"` 137 SubMchid *string `json:"sub_mchid,omitempty"` 138 TaxpayerId *string `json:"taxpayer_id,omitempty"` 139 OperationType *InviteOperationType `json:"operation_type,omitempty"` 140} 141 142func (o *GetSpInviteUrlRequest) MarshalJSON() ([]byte, error) { 143 type Alias GetSpInviteUrlRequest 144 a := &struct { 145 FapiaoMode []InvoiceMode `json:"fapiao_mode,omitempty"` 146 FapiaoAbilityTypeList []FapiaoAbilityType `json:"fapiao_ability_type_list,omitempty"` 147 InviteChannel *string `json:"invite_channel,omitempty"` 148 OperateUser *string `json:"operate_user,omitempty"` 149 InviteCode *string `json:"invite_code,omitempty"` 150 SubMchid *string `json:"sub_mchid,omitempty"` 151 TaxpayerId *string `json:"taxpayer_id,omitempty"` 152 OperationType *InviteOperationType `json:"operation_type,omitempty"` 153 *Alias 154 }{ 155 // 序列化时移除非 Body 字段 156 FapiaoMode: nil, 157 FapiaoAbilityTypeList: nil, 158 InviteChannel: nil, 159 OperateUser: nil, 160 InviteCode: nil, 161 SubMchid: nil, 162 TaxpayerId: nil, 163 OperationType: nil, 164 Alias: (*Alias)(o), 165 } 166 return json.Marshal(a) 167} 168 169type GetSpInviteUrlResp struct { 170 InviteUrl *string `json:"invite_url,omitempty"` 171 MiniprogramAppid *string `json:"miniprogram_appid,omitempty"` 172 MiniprogramPath *string `json:"miniprogram_path,omitempty"` 173} 174 175type InvoiceMode string 176 177func (e InvoiceMode) Ptr() *InvoiceMode { 178 return &e 179} 180 181const ( 182 INVOICEMODE_THIRD_OR_SELF_FAPIAO InvoiceMode = "THIRD_OR_SELF_FAPIAO" 183 INVOICEMODE_TENCENT_DIGITAL_TAX InvoiceMode = "TENCENT_DIGITAL_TAX" 184) 185 186type FapiaoAbilityType string 187 188func (e FapiaoAbilityType) Ptr() *FapiaoAbilityType { 189 return &e 190} 191 192const ( 193 FAPIAOABILITYTYPE_BASE_ABILITY FapiaoAbilityType = "BASE_ABILITY" 194 FAPIAOABILITYTYPE_REAL_ESTATE_ABILITY FapiaoAbilityType = "REAL_ESTATE_ABILITY" 195 FAPIAOABILITYTYPE_REFINED_OIL_ABILITY FapiaoAbilityType = "REFINED_OIL_ABILITY" 196) 197 198type InviteOperationType string 199 200func (e InviteOperationType) Ptr() *InviteOperationType { 201 return &e 202} 203 204const ( 205 INVITEOPERATIONTYPE_AUTH_BINDING InviteOperationType = "AUTH_BINDING" 206) 207
应答参数
200 OK
invite_url 必填 string(1024)
【邀请开通二维码链接】 用于生成邀请二维码,商户使用微信扫描二维码进行授权开通电子发票能力
miniprogram_appid 必填 string(32)
【开通小程序AppID】 商户授权的小程序 AppID。与miniprogram_path 共同作为小程序跳转插件的参数,用于商户点击跳转授权小程序,开通服务商电子发票发票能力。参考:wx.navigateToMiniProgram
miniprogram_path 必填 string(1024)
【开通小程序跳转路径】 商户开通服务商电子发票小程序的页面路径,与 miniprogram_appid 共同作为小程序跳转插件的参数,用于商户点击跳转授权小程序,开通服务商电子发票发票能力。参考:wx.navigateToMiniProgram
应答示例
200 OK
1{ 2 "invite_url" : "https://wxacurl.cn?xxx=", 3 "miniprogram_appid" : "wxb1170446a4c0a5a2", 4 "miniprogram_path" : "pages/xxxPage" 5} 6
错误码
以下是本接口返回的错误码列表。详细错误码规则,请参考微信支付接口规则-错误码和错误提示

