微信公众号支付
微信公众号支付流程图
统一下单
请求URL
post https://api.mch.weixin.qq.com/pay/unifiedorder请求参数示例
{
"appid":"******",
"mch_id":"*******",
"nonce_str":"vh8kxwau4cv4vwka5fxac6yo0geh77l9",
"sign":"26CC820F668E5A2D4E1C8060F48DD570",
"device_info":"",
"sign_type":"MD5",
"body":"麻婆豆腐双拼饭正餐",
"attach":"2306edb2-d336-4087-ab9a-6d81350efe76",
"out_trade_no":"1530759952567148993143",
"fee_type":"CNY",
"total_fee":"1200",
"spbill_create_ip":"49.4.160.199",
"time_start":"",
"time_expire":"",
"notify_url":"https://********.com/api/weixin/payResult",
"trade_type":"JSAPI",
"product_id":"f51c558d-4d80-4661-9b7f-10b7273358d4",
"openid":"oFTYt0l9wQDDhwmx1js_d1T6zZkw"
}
请求参数说明
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
公众账号ID | appid | 是 | String(32) | wxd678efh567hg6787 | 微信支付分配的公众账号ID(企业号corpid即为此appId) |
商户号 | mch_id | 是 | String(32) | 1230000109 | 微信支付分配的商户号 |
设备号 | device_info | 否 | String(32) | 013467007045764 | 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB" |
随机字符串 | nonce_str | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串,长度要求在32位以内。推荐随机数生成算法 |
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 通过签名算法计算得出的签名值,详见签名生成算法 |
签名类型 | sign_type | 否 | String(32) | MD5 | 签名类型,默认为MD5,支持HMAC-SHA256和MD5。 |
商品描述 | body | 是 | String(128) | 腾讯充值中心-QQ会员充值 | 商品简单描述,该字段请按照规范传递,具体请见参数规定 |
商品详情 | detail | 否 | String(6000) | 商品详细描述,对于使用单品优惠的商户,改字段必须按照规范上传,详见“单品优惠参数说明” | |
附加数据 | attach | 否 | String(127) | 深圳分店 | 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。 |
商户订单号 | out_trade_no | 是 | String(32) | 20150806125346 | 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|* 且在同一个商户号下唯一。详见商户订单号 |
标价币种 | fee_type | 否 | String(16) | CNY | 符合ISO 4217标准的三位字母代码,默认人民币:CNY,详细列表请参见货币类型 |
标价金额 | total_fee | 是 | Int | 88 | 订单总金额,单位为分,详见支付金额 |
终端IP | spbill_create_ip | 是 | String(16) | 123.12.12.123 | APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。 |
交易起始时间 | time_start | 否 | String(14) | 20091225091010 | 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则 |
交易结束时间 | time_expire | 否 | String(14) | 20091227091010 |
订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。订单失效时间是针对订单号而言的,由于在请求支付的时候有一个必传参数prepay_id只有两小时的有效期,所以在重入时间超过2小时的时候需要重新请求下单接口获取新的prepay_id。其他详见时间规则 建议:最短失效时间间隔大于1分钟 |
订单优惠标记 | goods_tag | 否 | String(32) | WXG | 订单优惠标记,使用代金券或立减优惠功能时需要的参数,说明详见代金券或立减优惠 |
通知地址 | notify_url | 是 | String(256) | http://www.weixin.qq.com/wxpay/pay.php | 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 |
交易类型 | trade_type | 是 | String(16) | JSAPI |
JSAPI 公众号支付 NATIVE 扫码支付 APP APP支付 说明详见参数规定 |
商品ID | product_id | 否 | String(32) | 12235413214070356458058 | trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。 |
指定支付方式 | limit_pay | 否 | String(32) | no_credit | 上传此参数no_credit--可限制用户不能使用信用卡支付 |
用户标识 | openid | 否 | String(128) | oUpF8uMuAJO_M2pxb1Q9zNjWeS6o | trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。openid如何获取,可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换 |
请求数据实体
public class RequestData {
private String appid; //微信支付分配的公众账号ID(企业号corpid即为此appId)
private String mch_id; //微信支付分配的商户号
private String nonce_str; //随机字符串,不长于32位。推荐随机数生成算法
private String sign; //通过签名算法计算得出的签名值,详见签名生成算法
}
public class UnifiedOrderReqData extends RequestData {
private String device_info = ""; //设备号,
private String sign_type = "MD5"; //签名
private String body = ""; //商品描述
private String attach = ""; //附加数据,附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。
private String out_trade_no = ""; //商户订单号
private String fee_type = "CNY"; //标价币种
private int total_fee = 0; //标价金额
private String spbill_create_ip = ""; //终端IP
private String time_start = ""; //交易开始时间yyyyMMddHHmmss
private String time_expire = ""; //交易结束时间yyyyMMddHHmmss 最短失效时间间隔必须大于5分钟
private String notify_url = ""; //通知地址
private String trade_type = "NATIVE"; //交易类型
private String product_id = ""; //商品ID
private String openid = ""; //trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。
}
返回结果
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[*********]]></appid>
<mch_id><![CDATA[*********]]></mch_id>
<nonce_str><![CDATA[6ekxnSXWqNR7ACg0]]></nonce_str>
<sign><![CDATA[8DD8E79CAE52E3DDB7D7B0DFB575078B]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx05104546699892691d3ce4c63046278833]]></prepay_id>
<trade_type><![CDATA[JSAPI]]></trade_type>
</xml>
返回结果实体类
public class UnifiedOrderResData {
private String return_code = "";//SUCCESS/FAIL 此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
private String return_msg = "";
//以下字段在return_code为SUCCESS的时候有返回
private String appid = "";
private String mch_id = "";
private String device_info = "";
private String nonce_str = "";
private String sign = "";
private String result_code = "";
private String err_code = "";
private String err_code_des = "";
//以下字段在return_code 和result_code都为SUCCESS的时候有返回
private String trade_type = "";
private String prepay_id = "";
private String code_url = "";
}
发起支付
微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验
wx.chooseWXPay({
timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '', // 支付签名随机串,不长于 32 位
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '', // 支付签名
success: function (res) {
// 支付成功后的回调函数
}
});
备注:prepay_id 通过微信支付统一下单接口拿到,paySign 采用统一的微信支付 Sign 签名生成方法,注意这里 appId 也要参与签名,appId 与 config 中传入的 appId 一致,即最后参与签名的参数有appId, timeStamp, nonceStr, package, signType支付结果通知
该链接是通过【统一下单API】中提交的参数notify_url设置,如果链接无法访问,商户将无法接收到微信通知。
通知url必须为直接可访问的url,不能携带参数。示例:notify_url:“https://pay.weixin.qq.com/api/weixin/payResult"
public class PayResultInputData {
private String return_code; //此字段是通信标识
private String return_msg; //返回信息,如非空,为错误原因
//以下字段在return_code为SUCCESS的时候有返回
private String appid;
private String mch_id;
private String device_info; //微信支付分配的终端设备号
private String nonce_str; //微信返回的随机字符串
private String sign;
private String sign_type;
private String result_code; //交易是否成功需要查看result_code来判断
private String err_code; //错误代码
private String err_code_des; //错误代码描述
private String openid; //用户标识
private String is_subscribe; //是否关注公众账号
private String trade_type; //交易类型
private String bank_type; //付款银行
private String total_fee; //订单金额,订单总金额,单位为分
private String settlement_total_fee ; //应结订单金额,应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
private String fee_type ; //货币种类
private String cash_fee ; //现金支付金额
private String cash_fee_type ; //现金支付货币类型
private String coupon_fee ; //总代金券金额
private String coupon_count ; //代金券使用数量
private String coupon_type_0 ; //代金券类型
private String coupon_id_0 ; //代金券ID
private String coupon_fee_0 ; //单个代金券支付金额
private String transaction_id ; //微信支付订单号
private String out_trade_no ; //商户订单号
private String attach ; //商家数据包
private String time_end ; //支付完成时间yyyyMMddHHmmss
}
支付结果查询
请求URL
post https://api.mch.weixin.qq.com/pay/orderquery
请求参数
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
公众账号ID | appid | 是 | String(32) | wxd678efh567hg6787 | 微信支付分配的公众账号ID(企业号corpid即为此appId) |
商户号 | mch_id | 是 | String(32) | 1230000109 | 微信支付分配的商户号 |
微信订单号 | transaction_id | 二选一 | String(32) | 1009660380201506130728806387 | 微信的订单号,建议优先使用 |
商户订单号 | out_trade_no | String(32) | 20150806125346 | 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。 详见商户订单号 | |
随机字符串 | nonce_str | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 随机字符串,不长于32位。推荐随机数生成算法 |
签名 | sign | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 通过签名算法计算得出的签名值,详见签名生成算法 |
签名类型 | sign_type | 否 | String(32) | HMAC-SHA256 | 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5 |
请求参数示例
<xml>
<appid>wx2421b1c4370ec43b</appid>
<mch_id>10000100</mch_id>
<nonce_str>ec2316275641faa3aacf3cc599e8730f</nonce_str>
<transaction_id>1008450740201411110005820873</transaction_id>
<sign>FDD167FAA73459FD921B144BAF4F4CA2</sign>
</xml>
请求数据实体
public class OrderQueryReqData extends RequestData{
private String transaction_id;//微信的订单号,建议优先使用
public OrderQueryReqData(String transaction_id) {
this.transaction_id = transaction_id;
this.setSign(Signature.getSign(toMap()));
}
}
返回结果
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
返回状态码 | return_code | 是 | String(16) | SUCCESS |
SUCCESS/FAIL 此字段是通信标识,非交易标识,交易是否成功需要查看trade_state来判断 |
返回信息 | return_msg | 是 | String(128) | OK |
当return_code为FAIL时返回信息为错误原因 ,例如 签名失败 参数格式校验错误 |
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
公众账号ID | appid | 是 | String(32) | wxd678efh567hg6787 | 微信分配的公众账号ID |
商户号 | mch_id | 是 | String(32) | 1230000109 | 微信支付分配的商户号 |
随机字符串 | nonce_str | 是 | String(32) | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串,不长于32位。推荐随机数生成算法 |
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名,详见签名生成算法 |
业务结果 | result_code | 是 | String(16) | SUCCESS | SUCCESS/FAIL |
错误代码 | err_code | 否 | String(32) | 当result_code为FAIL时返回错误代码,详细参见下文错误列表 | |
错误代码描述 | err_code_des | 否 | String(128) | 当result_code为FAIL时返回错误描述,详细参见下文错误列表 |
以下字段在return_code 、result_code、trade_state都为SUCCESS时有返回 ,如trade_state不为 SUCCESS,则只返回out_trade_no(必传)和attach(选传)
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
设备号 | device_info | 否 | String(32) | 013467007045764 | 微信支付分配的终端设备号, |
用户标识 | openid | 是 | String(128) | oUpF8uMuAJO_M2pxb1Q9zNjWeS6o | 用户在商户appid下的唯一标识 |
是否关注公众账号 | is_subscribe | 否 | String(1) | Y | 用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效 |
交易类型 | trade_type | 是 | String(16) | JSAPI | 调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP,MICROPAY,详细说明见参数规定 |
交易状态 | trade_state | 是 | String(32) | SUCCESS |
SUCCESS—支付成功 REFUND—转入退款 NOTPAY—未支付 CLOSED—已关闭 REVOKED—已撤销(刷卡支付) USERPAYING--用户支付中 PAYERROR--支付失败(其他原因,如银行返回失败) 支付状态机请见下单API页面 |
付款银行 | bank_type | 是 | String(16) | CMC | 银行类型,采用字符串类型的银行标识 |
标价金额 | total_fee | 是 | Int | 100 | 订单总金额,单位为分 |
应结订单金额 | settlement_total_fee | 否 | Int | 100 | 当订单使用了免充值型优惠券后返回该参数,应结订单金额=订单金额-免充值优惠券金额。 |
标价币种 | fee_type | 否 | String(8) | CNY | 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 |
现金支付金额 | cash_fee | 是 | Int | 100 | 现金支付金额订单现金支付金额,详见支付金额 |
现金支付币种 | cash_fee_type | 否 | String(16) | CNY | 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 |
代金券金额 | coupon_fee | 否 | Int | 100 | “代金券”金额<=订单金额,订单金额-“代金券”金额=现金支付金额,详见支付金额 |
代金券使用数量 | coupon_count | 否 | Int | 1 | 代金券使用数量 |
代金券类型 | coupon_type_$n | 否 | String | CASH |
CASH--充值代金券 NO_CASH---非充值优惠券 开通免充值券功能,并且订单使用了优惠券后有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_$0 |
代金券ID | coupon_id_$n | 否 | String(20) | 10000 | 代金券ID, $n为下标,从0开始编号 |
单个代金券支付金额 | coupon_fee_$n | 否 | Int | 100 | 单个代金券支付金额, $n为下标,从0开始编号 |
微信支付订单号 | transaction_id | 是 | String(32) | 1009660380201506130728806387 | 微信支付订单号 |
商户订单号 | out_trade_no | 是 | String(32) | 20150806125346 | 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。 |
附加数据 | attach | 否 | String(128) | 深圳分店 | 附加数据,原样返回 |
支付完成时间 | time_end | 是 | String(14) | 20141030133525 | 订单支付时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则 |
交易状态描述 | trade_state_desc | 是 | String(256) | 支付失败,请重新下单支付 | 对当前查询订单状态的描述和下一步操作的指引 |
返回数据实体
public class OrderQueryResData {
private String return_code; // SUCCESS/FAIL 此字段是通信标识,非交易标识,交易是否成功需要查看trade_state来判断
private String return_msg; //返回信息,如非空,为错误原因 签名失败 参数格式校验错误
//======以下字段在return_code为SUCCESS的时候有返回 ====
private String appid; //微信分配的公众账号ID
private String mch_id; //微信支付分配的商户号
private String nonce_str; //随机字符串,不长于32位。推荐随机数生成算法
private String sign; //签名,详见签名生成算法
private String result_code; //SUCCESS/FAIL
private String err_code; //错误码
private String err_code_des; //结果信息描述
//======以下字段在return_code 、result_code、trade_state都为SUCCESS时有返回 ,如trade_state不为 SUCCESS,则只返回out_trade_no(必传)和attach(选传)。====================
private String device_info; //微信支付分配的终端设备号,
private String openid; //用户在商户appid下的唯一标识
private String is_subscribe; //用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
private String trade_type; //调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP,MICROPAY,详细说明见参数规定
private String trade_state; //SUCCESS—支付成功 REFUND—转入退款 NOTPAY—未支付 CLOSED—已关闭 REVOKED—已撤销(刷卡支付) USERPAYING--用户支付中 PAYERROR--支付失败(其他原因,如银行返回失败)
private String bank_type; //银行类型,采用字符串类型的银行标识
private String total_fee; //订单总金额,单位为分
private String settlement_total_fee;//当订单使用了免充值型优惠券后返回该参数,应结订单金额=订单金额-免充值优惠券金额。
private String fee_type; //货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
private String cash_fee; //现金支付金额订单现金支付金额,详见支付金额
private String cash_fee_type; //货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
private String coupon_fee ; //“代金券”金额<=订单金额,订单金额-“代金券”金额=现金支付金额,详见支付金额
private String coupon_count; //代金券使用数量
private String coupon_type_0; // CASH--充值代金券 NO_CASH---非充值优惠券 开通免充值券功能,并且订单使用了优惠券后有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_$0
private String coupon_id_0; //代金券ID, $n为下标,从0开始编号
private String coupon_fee_0; //单个代金券支付金额, $n为下标,从0开始编号
private String transaction_id; //微信支付订单号
private String out_trade_no; //商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
private String attach; //深圳分店 附加数据,原样返回
private String time_end; //订单支付时间,格式为yyyyMMddHHmmss
private String trade_state_desc; //支付失败,请重新下单支付 对当前查询订单状态的描述和下一步操作的指引
}
微信公众号支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4
微信公众平台JS-JDK说明文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115