小程序支付及退款流程详解

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发起支付请求。支付请求涉及的参数包括appIdtimeStampnonceStrpackagesignTypepaySign。其中,appId为小程序的唯一标识,timeStamp为当前时间戳,nonceStr为随机字符串,package为固定值'prepay_id=' + prepayIdsignType为签名类型,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;

以上就是小程序支付及退款的详细流程,需要注意的是,在支付及退款的过程中,需要进行签名验证及证书验证,这是保障交易安全的重要措施。同时,小程序支付及退款的代码示例中使用的requestsignconvertToXML等函数需要自行实现,具体实现方法可以参考微信支付官方文档。