1. 小程序支付流程
微信小程序支付是指用户在使用小程序购买商品或服务时,通过微信支付完成支付流程并获得订单的过程。下面是小程序支付的详细流程:
1.1 预支付
当用户下单后,小程序需要生成一个订单并将该订单提交到服务端,然后服务端需要根据订单的信息向微信支付系统发起预支付请求。预支付请求需要携带以下信息:
商户号:商户号是微信支付分配的唯一标识,需要在申请支付接口时填写
订单号:商户系统内部订单号,需要在下单时生成
商品描述:商品或支付单简要描述,不超过128个字符
支付金额:支付金额,单位为分
终端IP:调用微信支付API的机器IP,需要获取真实的客户端IP
通知地址:接收微信支付异步通知的回调地址,必须为外网可访问的URL地址
交易类型:小程序支付的交易类型为JSAPI
openid:用户在小程序中的唯一标识,需要从用户授权登录后获取
提交预支付请求后,微信支付系统会返回一个预支付交易会话标识prepay_id
,该标识将用于之后的支付验证。预支付请求的代码示例:
const requestData = {
appid: '小程序的APPID',
mch_id: '微信支付分配的商户号',
nonce_str: '随机字符串,不长于32位',
sign_type: '签名类型,默认为MD5',
body: '商品描述',
out_trade_no: '商户订单号',
total_fee: '支付金额',
spbill_create_ip: '终端IP',
notify_url: '通知地址',
trade_type: 'JSAPI',
openid: '用户在小程序中的唯一标识'
};
const signedData = sign(requestData, '商户密钥');
const xmlData = convertToXML(signedData);
const response = await request('https://api.mch.weixin.qq.com/pay/unifiedorder', xmlData);
const responseData = convertToJSON(response);
const prepayId = responseData.prepay_id;
1.2 支付请求
获取到prepay_id
后,小程序需要在客户端调用微信支付API发起支付请求。支付请求涉及的参数包括appId
、timeStamp
、nonceStr
、package
、signType
和paySign
。其中,appId
为小程序的唯一标识,timeStamp
为当前时间戳,nonceStr
为随机字符串,package
为固定值'prepay_id=' + prepayId
,signType
为签名类型,paySign
为请求签名。
支付请求的代码示例:
const appId = '小程序的APPID';
const prepayId = '预支付交易会话标识';
const nonceStr = '随机字符串,不长于32位';
const timeStamp = String(Math.floor(Date.now() / 1000));
const paySign = generatePaySign(appId, timeStamp, nonceStr, `prepay_id=${prepayId}`, '签名类型', '商户密钥');
const requestData = {
timeStamp,
nonceStr,
package: `prepay_id=${prepayId}`,
signType: '签名类型',
paySign
};
wx.requestPayment({
...requestData,
success(res) {
// 请求成功回调函数
},
fail(res) {
// 请求失败回调函数
}
});
2. 小程序退款流程
小程序退款是指用户通过微信支付完成支付流程后,因某种原因需要退回支付金额的过程。下面是小程序退款的详细流程:
2.1 提交退款
当用户需要退款时,小程序需要将该订单的信息提交到服务端,并向微信支付系统发起退款请求。退款请求需要携带以下信息:
商户订单号:商户系统内部订单号,需要在下单时生成
微信订单号:微信支付系统内部的订单号,需要在微信支付结果通知中获取
退款金额:退款金额,单位为分
商户退款单号:商户系统内部的退款单号,需要在申请退款时生成,同一退款单号多次请求只退一笔
退款原因:退款原因,不超过80个字符
提交退款请求后,微信支付系统会返回一个退款受理结果。refund_id
。退款请求的代码示例:
const requestData = {
appid: '小程序的APPID',
mch_id: '微信支付分配的商户号',
nonce_str: '随机字符串,不长于32位',
sign_type: '签名类型,默认为MD5',
out_trade_no: '商户订单号',
out_refund_no: '商户退款单号',
total_fee: '订单金额',
refund_fee: '退款金额',
refund_desc: '退款原因'
};
const signedData = sign(requestData, '商户密钥');
const xmlData = convertToXML(signedData);
const response = await request('https://api.mch.weixin.qq.com/secapi/pay/refund', xmlData, {
cert: '商户证书',
key: '商户证书密钥'
});
const responseData = convertToJSON(response);
const refundId = responseData.refund_id;
2.2 退款查询
当提交退款请求后,小程序需要根据out_refund_no
向微信支付系统发起退款查询请求并获取退款结果。退款查询请求需要携带以下信息:
商户订单号:商户系统内部订单号,需要在下单时生成
微信订单号:微信支付系统内部的订单号,需要在微信支付结果通知中获取
商户退款单号:商户系统内部的退款单号,需要在申请退款时生成
微信退款单号:微信支付系统内部的退款单号,需要在退款结果中获取
退款渠道:退款渠道,有以下几种:原路退款、退回到余额、退回到银行卡,详见官方文档
退款状态:退款状态,有以下几种:退款成功、退款关闭、处理中、未确定,详见官方文档
退款查询请求的代码示例:
const requestData = {
appid: '小程序的APPID',
mch_id: '微信支付分配的商户号',
nonce_str: '随机字符串,不长于32位',
sign_type: '签名类型,默认为MD5',
out_trade_no: '商户订单号',
out_refund_no: '商户退款单号',
refund_id: '微信退款单号'
};
const signedData = sign(requestData, '商户密钥');
const xmlData = convertToXML(signedData);
const response = await request('https://api.mch.weixin.qq.com/pay/refundquery', xmlData);
const responseData = convertToJSON(response);
const refundStatus = responseData.refund_status_0;
以上就是小程序支付及退款的详细流程,需要注意的是,在支付及退款的过程中,需要进行签名验证及证书验证,这是保障交易安全的重要措施。同时,小程序支付及退款的代码示例中使用的request
、sign
、convertToXML
等函数需要自行实现,具体实现方法可以参考微信支付官方文档。